amaru_protocols/protocol_messages/
version_data.rs1use std::fmt::Display;
16
17use amaru_kernel::{NetworkMagic, cbor};
18
19use crate::protocol_messages::version_number::VersionNumber;
20
21#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
22pub struct VersionData {
23 network_magic: NetworkMagic,
24 initiator_only_diffusion_mode: bool,
25 peer_sharing: u8,
27 query: bool,
28}
29
30pub const PEER_SHARING_DISABLED: u8 = 0;
31pub const PEER_SHARING_ENABLED: u8 = 1;
32
33impl VersionData {
34 pub fn new(
35 network_magic: NetworkMagic,
36 initiator_only_diffusion_mode: bool,
37 peer_sharing: u8,
38 query: bool,
39 ) -> Self {
40 VersionData { network_magic, initiator_only_diffusion_mode, peer_sharing, query }
41 }
42}
43
44impl Display for VersionData {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 write!(
47 f,
48 "{{ network_magic: {}, initiator_only_diffusion_mode: {}, peer_sharing: {}, query: {} }}",
49 self.network_magic, self.initiator_only_diffusion_mode, self.peer_sharing, self.query
50 )
51 }
52}
53
54impl<T: AsRef<VersionNumber>> cbor::Encode<T> for VersionData {
55 fn encode<W: cbor::encode::Write>(
56 &self,
57 e: &mut cbor::Encoder<W>,
58 ctx: &mut T,
59 ) -> Result<(), cbor::encode::Error<W::Error>> {
60 if ctx.as_ref().has_query_and_peer_sharing() {
61 e.array(4)?
62 .encode(self.network_magic)?
63 .bool(self.initiator_only_diffusion_mode)?
64 .u8(self.peer_sharing)?
65 .bool(self.query)?;
66 } else {
67 e.array(2)?.encode(self.network_magic)?.bool(self.initiator_only_diffusion_mode)?;
68 }
69 Ok(())
70 }
71}
72
73impl<'b, T: AsRef<VersionNumber>> cbor::Decode<'b, T> for VersionData {
74 fn decode(d: &mut cbor::Decoder<'b>, ctx: &mut T) -> Result<Self, cbor::decode::Error> {
75 if ctx.as_ref().has_query_and_peer_sharing() {
76 let len = d.array()?;
77 cbor::check_tagged_array_length(0, len, 4)?;
78 let network_magic = d.decode()?;
79 let initiator_only_diffusion_mode = d.bool()?;
80 let peer_sharing = d.u8()?;
81 let query = d.bool()?;
82 Ok(Self { network_magic, initiator_only_diffusion_mode, peer_sharing, query })
83 } else {
84 let len = d.array()?;
85 cbor::check_tagged_array_length(0, len, 2)?;
86 let network_magic = d.decode()?;
87 let initiator_only_diffusion_mode = d.bool()?;
88 Ok(Self { network_magic, initiator_only_diffusion_mode, peer_sharing: 0, query: false })
89 }
90 }
91}
92
93#[cfg(test)]
94pub(crate) mod tests {
95 use amaru_kernel::any_network_magic;
96 use proptest::{prelude::any, prop_compose, strategy::Strategy};
97
98 use super::*;
99
100 prop_compose! {
101 pub fn any_version_data()(network_magic in any_network_magic(),
102 initiator_only_diffusion_mode in any::<bool>(),
103 peer_sharing in any::<bool>().prop_map(|b| if b { 1 } else { 0 }),
104 query in any::<bool>()) -> VersionData {
105 VersionData::new(network_magic, initiator_only_diffusion_mode, peer_sharing, query)
106 }
107 }
108}