pgp/packet/
mod_detection_code.rs1use std::io::{self, BufRead};
2
3use crate::{
4 errors::Result,
5 packet::{PacketHeader, PacketTrait},
6 parsing_reader::BufReadParsing,
7 ser::Serialize,
8};
9
10#[derive(derive_more::Debug, Clone, PartialEq, Eq)]
22#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
23pub struct ModDetectionCode {
24 packet_header: PacketHeader,
25 #[debug("{}", hex::encode(hash))]
27 hash: [u8; 20],
28}
29
30impl ModDetectionCode {
31 pub fn try_from_reader<B: BufRead>(packet_header: PacketHeader, mut input: B) -> Result<Self> {
33 let hash = input.read_array::<20>()?;
34
35 Ok(ModDetectionCode {
36 packet_header,
37 hash,
38 })
39 }
40}
41
42impl Serialize for ModDetectionCode {
43 fn to_writer<W: io::Write>(&self, writer: &mut W) -> Result<()> {
44 writer.write_all(&self.hash[..])?;
45 Ok(())
46 }
47
48 fn write_len(&self) -> usize {
49 self.hash.len()
50 }
51}
52
53impl PacketTrait for ModDetectionCode {
54 fn packet_header(&self) -> &PacketHeader {
55 &self.packet_header
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use proptest::prelude::*;
62
63 use super::*;
64
65 proptest! {
66 #[test]
67 fn write_len(packet: ModDetectionCode) {
68 let mut buf = Vec::new();
69 packet.to_writer(&mut buf).unwrap();
70 prop_assert_eq!(buf.len(), packet.write_len());
71 }
72
73 #[test]
74 fn packet_roundtrip(packet: ModDetectionCode) {
75 let mut buf = Vec::new();
76 packet.to_writer(&mut buf).unwrap();
77 let new_packet = ModDetectionCode::try_from_reader(packet.packet_header, &mut &buf[..]).unwrap();
78 prop_assert_eq!(packet, new_packet);
79 }
80 }
81}