ssh_packet/crypto/
lengthed.rs1use std::{io, ops::Deref};
2
3use binrw::{
4 meta::{ReadEndian, WriteEndian},
5 BinRead, BinWrite,
6};
7
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
10pub struct Lengthed<T>(pub T);
11
12impl<T> Deref for Lengthed<T> {
13 type Target = T;
14
15 fn deref(&self) -> &Self::Target {
16 &self.0
17 }
18}
19
20impl<T> From<T> for Lengthed<T> {
21 fn from(value: T) -> Self {
22 Self(value)
23 }
24}
25
26impl<T> BinRead for Lengthed<T>
27where
28 T: BinRead,
29{
30 type Args<'a> = T::Args<'a>;
31
32 fn read_options<R: std::io::Read + std::io::Seek>(
33 reader: &mut R,
34 endian: binrw::Endian,
35 args: Self::Args<'_>,
36 ) -> binrw::BinResult<Self> {
37 let size = u32::read_be(reader)?;
38 let len = (size as usize).min(crate::PACKET_MAX_SIZE);
39
40 let mut buf = Vec::with_capacity(len);
41 reader.read_exact(&mut buf[..len])?;
42
43 T::read_options(&mut io::Cursor::new(&buf), endian, args).map(Self)
44 }
45}
46
47impl<T> ReadEndian for Lengthed<T>
48where
49 T: ReadEndian,
50{
51 const ENDIAN: binrw::meta::EndianKind = T::ENDIAN;
52}
53
54impl<T> BinWrite for Lengthed<T>
55where
56 T: BinWrite,
57{
58 type Args<'a> = T::Args<'a>;
59
60 fn write_options<W: std::io::Write + std::io::Seek>(
61 &self,
62 writer: &mut W,
63 endian: binrw::Endian,
64 args: Self::Args<'_>,
65 ) -> binrw::BinResult<()> {
66 let mut buf = Vec::with_capacity(crate::PACKET_MAX_SIZE);
67 self.0
68 .write_options(&mut io::Cursor::new(&mut buf), endian, args)?;
69
70 let len = buf.len();
71 let size: u32 = len.min(crate::PACKET_MAX_SIZE) as u32;
72
73 size.write_be(writer)?;
74 Ok(writer.write_all(&buf)?)
75 }
76}
77
78impl<T> WriteEndian for Lengthed<T>
79where
80 T: WriteEndian,
81{
82 const ENDIAN: binrw::meta::EndianKind = T::ENDIAN;
83}