Merge pull request #1503 from valentinewallace/2022-05-onion-msgs
[rust-lightning] / lightning / src / util / ser.rs
index e60f133f5e1638c085e4476d706c8bea32193998..ecf85839a5a8e19ebfed3f8e87b8b5832427e4a5 100644 (file)
@@ -136,6 +136,13 @@ impl<R: Read> Read for FixedLengthReader<R> {
        }
 }
 
+impl<R: Read> LengthRead for FixedLengthReader<R> {
+       #[inline]
+       fn total_bytes(&self) -> u64 {
+               self.total_bytes
+       }
+}
+
 /// A Read which tracks whether any bytes have been read at all. This allows us to distinguish
 /// between "EOF reached before we started" and "EOF reached mid-read".
 pub(crate) struct ReadTrackingReader<R: Read> {
@@ -222,6 +229,29 @@ pub trait ReadableArgs<P>
        fn read<R: Read>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
 }
 
+/// A std::io::Read that also provides the total bytes available to read.
+pub(crate) trait LengthRead: Read {
+       /// The total number of bytes available to read.
+       fn total_bytes(&self) -> u64;
+}
+
+/// A trait that various higher-level rust-lightning types implement allowing them to be read in
+/// from a Read given some additional set of arguments which is required to deserialize, requiring
+/// the implementer to provide the total length of the read.
+pub(crate) trait LengthReadableArgs<P> where Self: Sized
+{
+       /// Reads a Self in from the given LengthRead
+       fn read<R: LengthRead>(reader: &mut R, params: P) -> Result<Self, DecodeError>;
+}
+
+/// A trait that various higher-level rust-lightning types implement allowing them to be read in
+/// from a Read, requiring the implementer to provide the total length of the read.
+pub(crate) trait LengthReadable where Self: Sized
+{
+       /// Reads a Self in from the given LengthRead
+       fn read<R: LengthRead>(reader: &mut R) -> Result<Self, DecodeError>;
+}
+
 /// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read
 ///
 /// (C-not exported) as we only export serialization to/from byte arrays instead
@@ -246,6 +276,12 @@ impl<T: Readable> Readable for OptionDeserWrapper<T> {
                Ok(Self(Some(Readable::read(reader)?)))
        }
 }
+/// When handling default_values, we want to map the default-value T directly
+/// to a OptionDeserWrapper<T> in a way that works for `field: T = t;` as
+/// well. Thus, we assume `Into<T> for T` does nothing and use that.
+impl<T: Readable> From<T> for OptionDeserWrapper<T> {
+       fn from(t: T) -> OptionDeserWrapper<T> { OptionDeserWrapper(Some(t)) }
+}
 
 /// Wrapper to write each element of a Vec with no length prefix
 pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec<T>);