1use core::fmt;
13use core::marker::PhantomData;
14
15use io::Write;
16use serde::de::{SeqAccess, Unexpected, Visitor};
17use serde::ser::SerializeSeq;
18use serde::{Deserializer, Serializer};
19
20use super::encode::Error as ConsensusError;
21use super::{Decodable, Encodable};
22use crate::consensus::{DecodeError, IterReader};
23
24pub struct Hex<Case = hex::Lower>(PhantomData<Case>)
26where
27 Case: hex::Case;
28
29impl<C: hex::Case> Default for Hex<C> {
30 fn default() -> Self { Hex(Default::default()) }
31}
32
33impl<C: hex::Case> ByteEncoder for Hex<C> {
34 type Encoder = hex::Encoder<C>;
35}
36
37pub mod hex {
39 use core::fmt;
40 use core::marker::PhantomData;
41
42 use hex::buf_encoder::BufEncoder;
43
44 pub trait Case: sealed::Case {}
48 impl<T: sealed::Case> Case for T {}
49
50 pub enum Lower {}
52 pub enum Upper {}
54
55 mod sealed {
56 pub trait Case {
57 const INTERNAL_CASE: hex::Case;
59 }
60
61 impl Case for super::Lower {
62 const INTERNAL_CASE: hex::Case = hex::Case::Lower;
63 }
64
65 impl Case for super::Upper {
66 const INTERNAL_CASE: hex::Case = hex::Case::Upper;
67 }
68 }
69
70 const HEX_BUF_SIZE: usize = 512;
72
73 pub struct Encoder<C: Case>(BufEncoder<{ HEX_BUF_SIZE }>, PhantomData<C>);
76
77 impl<C: Case> From<super::Hex<C>> for Encoder<C> {
78 fn from(_: super::Hex<C>) -> Self { Encoder(BufEncoder::new(), Default::default()) }
79 }
80
81 impl<C: Case> super::EncodeBytes for Encoder<C> {
82 fn encode_chunk<W: fmt::Write>(&mut self, writer: &mut W, mut bytes: &[u8]) -> fmt::Result {
83 while !bytes.is_empty() {
84 if self.0.is_full() {
85 self.flush(writer)?;
86 }
87 bytes = self.0.put_bytes_min(bytes, C::INTERNAL_CASE);
88 }
89 Ok(())
90 }
91
92 fn flush<W: fmt::Write>(&mut self, writer: &mut W) -> fmt::Result {
93 writer.write_str(self.0.as_str())?;
94 self.0.clear();
95 Ok(())
96 }
97 }
98
99 #[derive(Debug, Clone, PartialEq, Eq)]
103 pub struct DecodeInitError(hex::OddLengthStringError);
104
105 #[derive(Debug, Clone, PartialEq, Eq)]
107 pub struct DecodeError(hex::InvalidCharError);
108
109 pub struct Decoder<'a>(hex::HexSliceToBytesIter<'a>);
111
112 impl<'a> Decoder<'a> {
113 fn new(s: &'a str) -> Result<Self, DecodeInitError> {
114 match hex::HexToBytesIter::new(s) {
115 Ok(iter) => Ok(Decoder(iter)),
116 Err(error) => Err(DecodeInitError(error)),
117 }
118 }
119 }
120
121 impl<'a> Iterator for Decoder<'a> {
122 type Item = Result<u8, DecodeError>;
123
124 fn next(&mut self) -> Option<Self::Item> {
125 self.0.next().map(|result| result.map_err(DecodeError))
126 }
127 }
128
129 impl<'a, C: Case> super::ByteDecoder<'a> for super::Hex<C> {
130 type InitError = DecodeInitError;
131 type DecodeError = DecodeError;
132 type Decoder = Decoder<'a>;
133
134 fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError> { Decoder::new(s) }
135 }
136
137 impl super::IntoDeError for DecodeInitError {
138 fn into_de_error<E: serde::de::Error>(self) -> E {
139 E::invalid_length(self.0.length(), &"an even number of ASCII-encoded hex digits")
140 }
141 }
142
143 impl super::IntoDeError for DecodeError {
144 fn into_de_error<E: serde::de::Error>(self) -> E {
145 use serde::de::Unexpected;
146
147 const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit";
148
149 match self.0.invalid_char() {
150 c if c.is_ascii() => E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR),
151 c => E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR),
152 }
153 }
154 }
155}
156
157struct DisplayWrapper<'a, T: 'a + Encodable, E>(&'a T, PhantomData<E>);
158
159impl<'a, T: 'a + Encodable, E: ByteEncoder> fmt::Display for DisplayWrapper<'a, T, E> {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 let mut writer = IoWrapper::<'_, _, E::Encoder>::new(f, E::default().into());
162 self.0.consensus_encode(&mut writer).map_err(|error| {
163 #[cfg(debug_assertions)]
164 {
165 if error.kind() != io::ErrorKind::Other
166 || error.get_ref().is_some()
167 || !writer.writer.was_error
168 {
169 panic!(
170 "{} returned an unexpected error: {:?}",
171 core::any::type_name::<T>(),
172 error
173 );
174 }
175 }
176 fmt::Error
177 })?;
178 let result = writer.actually_flush();
179 if result.is_err() {
180 writer.writer.assert_was_error::<E>();
181 }
182 result
183 }
184}
185
186struct ErrorTrackingWriter<W: fmt::Write> {
187 writer: W,
188 #[cfg(debug_assertions)]
189 was_error: bool,
190}
191
192impl<W: fmt::Write> ErrorTrackingWriter<W> {
193 fn new(writer: W) -> Self {
194 ErrorTrackingWriter {
195 writer,
196 #[cfg(debug_assertions)]
197 was_error: false,
198 }
199 }
200
201 #[track_caller]
202 fn assert_no_error(&self, fun: &str) {
203 #[cfg(debug_assertions)]
204 {
205 if self.was_error {
206 panic!("`{}` called on errored writer", fun);
207 }
208 }
209 }
210
211 fn assert_was_error<Offender>(&self) {
212 #[cfg(debug_assertions)]
213 {
214 if !self.was_error {
215 panic!("{} returned an error unexpectedly", core::any::type_name::<Offender>());
216 }
217 }
218 }
219
220 fn set_error(&mut self, was: bool) {
221 #[cfg(debug_assertions)]
222 {
223 self.was_error |= was;
224 }
225 }
226
227 fn check_err<T, E>(&mut self, result: Result<T, E>) -> Result<T, E> {
228 self.set_error(result.is_err());
229 result
230 }
231}
232
233impl<W: fmt::Write> fmt::Write for ErrorTrackingWriter<W> {
234 fn write_str(&mut self, s: &str) -> fmt::Result {
235 self.assert_no_error("write_str");
236 let result = self.writer.write_str(s);
237 self.check_err(result)
238 }
239
240 fn write_char(&mut self, c: char) -> fmt::Result {
241 self.assert_no_error("write_char");
242 let result = self.writer.write_char(c);
243 self.check_err(result)
244 }
245}
246
247struct IoWrapper<'a, W: fmt::Write, E: EncodeBytes> {
248 writer: ErrorTrackingWriter<&'a mut W>,
249 encoder: E,
250}
251
252impl<'a, W: fmt::Write, E: EncodeBytes> IoWrapper<'a, W, E> {
253 fn new(writer: &'a mut W, encoder: E) -> Self {
254 IoWrapper { writer: ErrorTrackingWriter::new(writer), encoder }
255 }
256
257 fn actually_flush(&mut self) -> fmt::Result { self.encoder.flush(&mut self.writer) }
258}
259
260impl<'a, W: fmt::Write, E: EncodeBytes> Write for IoWrapper<'a, W, E> {
261 fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
262 match self.encoder.encode_chunk(&mut self.writer, bytes) {
263 Ok(()) => Ok(bytes.len()),
264 Err(fmt::Error) => {
265 self.writer.assert_was_error::<E>();
266 Err(io::Error::from(io::ErrorKind::Other))
267 }
268 }
269 }
270 fn flush(&mut self) -> io::Result<()> { Ok(()) }
272}
273
274pub trait ByteEncoder: Default {
279 type Encoder: EncodeBytes + From<Self>;
281}
282
283pub trait EncodeBytes {
288 fn encode_chunk<W: fmt::Write>(&mut self, writer: &mut W, bytes: &[u8]) -> fmt::Result;
292
293 fn flush<W: fmt::Write>(&mut self, writer: &mut W) -> fmt::Result;
295}
296
297pub trait ByteDecoder<'a> {
302 type InitError: IntoDeError + fmt::Debug;
306
307 type DecodeError: IntoDeError + fmt::Debug;
311
312 type Decoder: Iterator<Item = Result<u8, Self::DecodeError>>;
314
315 fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError>;
317}
318
319pub trait IntoDeError {
321 fn into_de_error<E: serde::de::Error>(self) -> E;
323}
324
325struct BinWriter<S: SerializeSeq> {
326 serializer: S,
327 error: Option<S::Error>,
328}
329
330impl<S: SerializeSeq> Write for BinWriter<S> {
331 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.write_all(buf).map(|_| buf.len()) }
332
333 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
334 for byte in buf {
335 if let Err(error) = self.serializer.serialize_element(byte) {
336 self.error = Some(error);
337 return Err(io::ErrorKind::Other.into());
338 }
339 }
340 Ok(())
341 }
342
343 fn flush(&mut self) -> io::Result<()> { Ok(()) }
344}
345
346struct DisplayExpected<D: fmt::Display>(D);
347
348impl<D: fmt::Display> serde::de::Expected for DisplayExpected<D> {
349 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
350 fmt::Display::fmt(&self.0, formatter)
351 }
352}
353
354fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
356 match error {
357 ConsensusError::Io(error) => panic!("unexpected IO error {:?}", error),
358 ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!(
359 "the requested allocation of {} items exceeds maximum of {}",
360 requested, max
361 )),
362 ConsensusError::InvalidChecksum { expected, actual } => E::invalid_value(
363 Unexpected::Bytes(&actual),
364 &DisplayExpected(format_args!(
365 "checksum {:02x}{:02x}{:02x}{:02x}",
366 expected[0], expected[1], expected[2], expected[3]
367 )),
368 ),
369 ConsensusError::NonMinimalVarInt =>
370 E::custom(format_args!("compact size was not encoded minimally")),
371 ConsensusError::ParseFailed(msg) => E::custom(msg),
372 ConsensusError::UnsupportedSegwitFlag(flag) =>
373 E::invalid_value(Unexpected::Unsigned(flag.into()), &"segwit version 1 flag"),
374 }
375}
376
377impl<E> DecodeError<E>
378where
379 E: serde::de::Error,
380{
381 fn unify(self) -> E {
382 match self {
383 DecodeError::Other(error) => error,
384 DecodeError::TooManyBytes => E::custom(format_args!("got more bytes than expected")),
385 DecodeError::Consensus(error) => consensus_error_into_serde(error),
386 }
387 }
388}
389
390impl<E> IntoDeError for DecodeError<E>
391where
392 E: IntoDeError,
393{
394 fn into_de_error<DE: serde::de::Error>(self) -> DE {
395 match self {
396 DecodeError::Other(error) => error.into_de_error(),
397 DecodeError::TooManyBytes => DE::custom(format_args!("got more bytes than expected")),
398 DecodeError::Consensus(error) => consensus_error_into_serde(error),
399 }
400 }
401}
402
403pub struct With<E>(PhantomData<E>);
420
421impl<E> With<E> {
422 pub fn serialize<T: Encodable, S: Serializer>(
424 value: &T,
425 serializer: S,
426 ) -> Result<S::Ok, S::Error>
427 where
428 E: ByteEncoder,
429 {
430 if serializer.is_human_readable() {
431 serializer.collect_str(&DisplayWrapper::<'_, _, E>(value, Default::default()))
432 } else {
433 let serializer = serializer.serialize_seq(None)?;
434 let mut writer = BinWriter { serializer, error: None };
435
436 let result = value.consensus_encode(&mut writer);
437 match (result, writer.error) {
438 (Ok(_), None) => writer.serializer.end(),
439 (Ok(_), Some(error)) =>
440 panic!("{} silently ate an IO error: {:?}", core::any::type_name::<T>(), error),
441 (Err(io_error), Some(ser_error))
442 if io_error.kind() == io::ErrorKind::Other && io_error.get_ref().is_none() =>
443 Err(ser_error),
444 (Err(io_error), ser_error) => panic!(
445 "{} returned an unexpected IO error: {:?} serialization error: {:?}",
446 core::any::type_name::<T>(),
447 io_error,
448 ser_error
449 ),
450 }
451 }
452 }
453
454 pub fn deserialize<'d, T: Decodable, D: Deserializer<'d>>(
456 deserializer: D,
457 ) -> Result<T, D::Error>
458 where
459 for<'a> E: ByteDecoder<'a>,
460 {
461 if deserializer.is_human_readable() {
462 deserializer.deserialize_str(HRVisitor::<_, E>(Default::default()))
463 } else {
464 deserializer.deserialize_seq(BinVisitor(Default::default()))
465 }
466 }
467}
468
469struct HRVisitor<T: Decodable, D: for<'a> ByteDecoder<'a>>(PhantomData<fn() -> (T, D)>);
470
471impl<'de, T: Decodable, D: for<'a> ByteDecoder<'a>> Visitor<'de> for HRVisitor<T, D> {
472 type Value = T;
473
474 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
475 formatter.write_str("bytes encoded as a hex string")
476 }
477
478 fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<T, E> {
479 let decoder = D::from_str(s).map_err(IntoDeError::into_de_error)?;
480 IterReader::new(decoder).decode().map_err(IntoDeError::into_de_error)
481 }
482}
483
484struct BinVisitor<T: Decodable>(PhantomData<fn() -> T>);
485
486impl<'de, T: Decodable> Visitor<'de> for BinVisitor<T> {
487 type Value = T;
488
489 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
490 formatter.write_str("a sequence of bytes")
491 }
492
493 fn visit_seq<S: SeqAccess<'de>>(self, s: S) -> Result<T, S::Error> {
494 IterReader::new(SeqIterator(s, Default::default())).decode().map_err(DecodeError::unify)
495 }
496}
497
498struct SeqIterator<'a, S: serde::de::SeqAccess<'a>>(S, PhantomData<&'a ()>);
499
500impl<'a, S: serde::de::SeqAccess<'a>> Iterator for SeqIterator<'a, S> {
501 type Item = Result<u8, S::Error>;
502
503 fn next(&mut self) -> Option<Self::Item> { self.0.next_element::<u8>().transpose() }
504}