sftp_protocol/packet/
write.rs1use super::kind::PacketType;
2use super::PayloadTrait;
3
4#[derive(Eq, PartialEq, Nom, Serialize)]
5#[nom(BigEndian)]
6#[cfg_attr(test, derive(test_strategy::Arbitrary))]
7pub struct Write {
8	pub id: u32,
9	#[nom(Parse(crate::util::parse_uuid))]
10	#[serde(serialize_with = "crate::util::serialize_uuid")]
11	#[cfg_attr(test, strategy(crate::util::arbitrary_uuid()))]
12	pub handle: uuid::Uuid,
13	pub offset: u64,
14	#[nom(Parse(crate::util::parse_u8_vec))]
15	#[serde(serialize_with = "crate::util::vec_with_u32_length")]
16	pub data: Vec<u8>,
17}
18
19impl PayloadTrait for Write {
20	const Type: PacketType = PacketType::Write;
21	fn binsize(&self) -> u32 {
22		4 + (4 + 36) + 8 + (4 + self.data.len() as u32)
23	}
24}
25
26impl From<Write> for super::Payload {
27	fn from(p: Write) -> Self {
28		Self::Write(p)
29	}
30}
31
32impl std::fmt::Debug for Write {
33	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34		f.debug_struct("Write")
35			.field("id", &self.id)
36			.field("handle", &self.handle)
37			.field("offset", &self.offset)
38			.field("data", &format!("[u8; {}]", self.data.len()))
39			.finish()
40	}
41}
42
43#[cfg(test)]
44mod tests {
45	use test_strategy::proptest;
46	use crate::parser::encode;
47	use crate::parser::Parser;
48	use super::*;
49
50	#[proptest]
51	fn roundtrip_whole(input: Write) {
52		let mut stream = Parser::default();
53		let packet = input.into_packet();
54		stream.write(&encode(&packet)).unwrap();
55		assert_eq!(stream.get_packet(), Ok(Some(packet)));
56		assert_eq!(stream.get_packet(), Ok(None));
57	}
58}
59