1pub mod encode;
10pub mod params;
11#[cfg(feature = "serde")]
12pub mod serde;
13#[cfg(feature = "bitcoinconsensus")]
14pub mod validation;
15
16use core::fmt;
17
18use internals::write_err;
19use io::{BufRead, Read};
20
21use crate::consensus;
22
23#[rustfmt::skip] #[doc(inline)]
25pub use self::{
26 encode::{deserialize, deserialize_partial, serialize, Decodable, Encodable, ReadExt, WriteExt},
27 params::Params,
28};
29
30#[cfg(feature = "bitcoinconsensus")]
31#[doc(inline)]
32pub use self::validation::{
33 verify_script, verify_script_with_flags, verify_transaction, verify_transaction_with_flags,
34};
35
36struct IterReader<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> {
37 iterator: core::iter::Fuse<I>,
38 buf: Option<u8>,
39 error: Option<E>,
40}
41
42impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
43 pub(crate) fn new(iterator: I) -> Self {
44 IterReader { iterator: iterator.fuse(), buf: None, error: None }
45 }
46
47 fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> {
48 let result = T::consensus_decode(&mut self);
49 match (result, self.error) {
50 (Ok(_), None) if self.iterator.next().is_some() => Err(DecodeError::TooManyBytes),
51 (Ok(value), None) => Ok(value),
52 (Ok(_), Some(error)) => panic!("{} silently ate the error: {:?}", core::any::type_name::<T>(), error),
53
54 (Err(consensus::encode::Error::Io(io_error)), Some(de_error)) if io_error.kind() == io::ErrorKind::Other && io_error.get_ref().is_none() => Err(DecodeError::Other(de_error)),
55 (Err(consensus_error), None) => Err(DecodeError::Consensus(consensus_error)),
56 (Err(consensus::encode::Error::Io(io_error)), de_error) => panic!("Unexpected IO error {:?} returned from {}::consensus_decode(), deserialization error: {:?}", io_error, core::any::type_name::<T>(), de_error),
57 (Err(consensus_error), Some(de_error)) => panic!("{} should've returned `Other` IO error because of deserialization error {:?} but it returned consensus error {:?} instead", core::any::type_name::<T>(), de_error, consensus_error),
58 }
59 }
60}
61
62impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> Read for IterReader<E, I> {
63 fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
64 let mut count = 0;
65 if buf.is_empty() {
66 return Ok(0);
67 }
68
69 if let Some(first) = self.buf.take() {
70 buf[0] = first;
71 buf = &mut buf[1..];
72 count += 1;
73 }
74 for (dst, src) in buf.iter_mut().zip(&mut self.iterator) {
75 match src {
76 Ok(byte) => *dst = byte,
77 Err(error) => {
78 self.error = Some(error);
79 return Err(io::ErrorKind::Other.into());
80 }
81 }
82 count += 1;
84 }
85 Ok(count)
86 }
87}
88
89impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> BufRead for IterReader<E, I> {
90 fn fill_buf(&mut self) -> Result<&[u8], io::Error> {
91 if let Some(ref byte) = self.buf {
93 Ok(core::slice::from_ref(byte))
94 } else {
95 match self.iterator.next() {
96 Some(Ok(byte)) => {
97 self.buf = Some(byte);
98 Ok(core::slice::from_ref(self.buf.as_ref().expect("we've just filled it")))
99 }
100 Some(Err(error)) => {
101 self.error = Some(error);
102 Err(io::ErrorKind::Other.into())
103 }
104 None => Ok(&[]),
105 }
106 }
107 }
108
109 fn consume(&mut self, len: usize) {
110 debug_assert!(len <= 1);
111 if len > 0 {
112 self.buf = None;
113 }
114 }
115}
116
117#[derive(Debug)]
119pub enum DecodeError<E> {
120 TooManyBytes,
122 Consensus(consensus::encode::Error),
124 Other(E),
126}
127
128internals::impl_from_infallible!(DecodeError<E>);
129
130impl<E: fmt::Debug> fmt::Display for DecodeError<E> {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 use DecodeError::*;
133
134 match *self {
135 TooManyBytes =>
136 write!(f, "attempted to decode object from an iterator that yielded too many bytes"),
137 Consensus(ref e) => write_err!(f, "invalid consensus encoding"; e),
138 Other(ref other) => write!(f, "other decoding error: {:?}", other),
139 }
140 }
141}
142
143#[cfg(feature = "std")]
144impl<E: fmt::Debug> std::error::Error for DecodeError<E> {
145 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
146 use DecodeError::*;
147
148 match *self {
149 TooManyBytes => None,
150 Consensus(ref e) => Some(e),
151 Other(_) => None, }
153 }
154}