datex_core/global/protocol_structures/
block_header.rs1use super::serializable::Serializable;
2use crate::values::core_values::endpoint::Endpoint;
3use binrw::{BinRead, BinWrite};
4use modular_bitfield::{Specifier, bitfield, prelude::B43};
5use strum_macros::Display;
6
7#[derive(Debug, Display, PartialEq, Clone, Copy, Default, Specifier)]
9#[cfg_attr(feature = "debug", derive(serde::Serialize, serde::Deserialize))]
10#[bits = 4]
11pub enum BlockType {
12 #[default]
13 Request = 0,
14 Response = 1,
15 Hello = 2,
16 Trace = 3,
17 TraceBack = 4,
18}
19
20impl BlockType {
21 pub fn is_response(&self) -> bool {
22 matches!(self, BlockType::Response | BlockType::TraceBack)
23 }
24}
25
26#[bitfield]
30#[derive(BinWrite, BinRead, Clone, Copy, Debug, PartialEq)]
31#[bw(map = |&x| Self::into_bytes(x))]
32#[br(map = Self::from_bytes)]
33#[brw(little)]
34pub struct FlagsAndTimestamp {
35 pub block_type: BlockType,
36 pub has_side_effects: bool,
37 pub has_only_data: bool,
38 pub is_end_of_section: bool,
39 pub is_end_of_context: bool,
40 pub has_lifetime: bool,
41 pub has_represented_by: bool,
42 pub has_iv: bool,
43 pub is_compressed: bool,
44 pub is_signature_in_last_subblock: bool,
45
46 #[allow(unused)]
47 unused_0: bool,
48 #[allow(unused)]
49 unused_1: bool,
50 #[allow(unused)]
51 unused_2: bool,
52 #[allow(unused)]
53 unused_3: bool,
54 #[allow(unused)]
55 unused_4: bool,
56 #[allow(unused)]
57 unused_5: bool,
58 #[allow(unused)]
59 unused_6: bool,
60 #[allow(unused)]
61 unused_7: bool,
62
63 pub creation_timestamp: B43,
64}
65
66#[cfg(feature = "debug")]
67mod flags_and_timestamp_serde {
68 use super::*;
69 use serde::{Deserialize, Deserializer, Serialize, Serializer};
70
71 #[derive(Serialize, Deserialize)]
72 struct FlagsHelper {
73 block_type: BlockType,
74 has_side_effects: bool,
75 has_only_data: bool,
76 is_end_of_section: bool,
77 is_end_of_context: bool,
78 has_lifetime: bool,
79 has_represented_by: bool,
80 has_iv: bool,
81 is_compressed: bool,
82 is_signature_in_last_subblock: bool,
83 creation_timestamp: u64,
84 }
85
86 impl Serialize for FlagsAndTimestamp {
87 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88 where
89 S: Serializer,
90 {
91 let helper = FlagsHelper {
92 block_type: self.block_type(),
93 has_side_effects: self.has_side_effects(),
94 has_only_data: self.has_only_data(),
95 is_end_of_section: self.is_end_of_section(),
96 is_end_of_context: self.is_end_of_context(),
97 has_lifetime: self.has_lifetime(),
98 has_represented_by: self.has_represented_by(),
99 has_iv: self.has_iv(),
100 is_compressed: self.is_compressed(),
101 is_signature_in_last_subblock: self
102 .is_signature_in_last_subblock(),
103 creation_timestamp: self.creation_timestamp(),
104 };
105 helper.serialize(serializer)
106 }
107 }
108
109 impl<'de> Deserialize<'de> for FlagsAndTimestamp {
110 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111 where
112 D: Deserializer<'de>,
113 {
114 let helper = FlagsHelper::deserialize(deserializer)?;
115 Ok(FlagsAndTimestamp::new()
116 .with_block_type(helper.block_type)
117 .with_has_side_effects(helper.has_side_effects)
118 .with_has_only_data(helper.has_only_data)
119 .with_is_end_of_section(helper.is_end_of_section)
120 .with_is_end_of_context(helper.is_end_of_context)
121 .with_has_lifetime(helper.has_lifetime)
122 .with_has_represented_by(helper.has_represented_by)
123 .with_has_iv(helper.has_iv)
124 .with_is_compressed(helper.is_compressed)
125 .with_is_signature_in_last_subblock(
126 helper.is_signature_in_last_subblock,
127 )
128 .with_creation_timestamp(helper.creation_timestamp))
129 }
130 }
131}
132
133impl Default for FlagsAndTimestamp {
134 fn default() -> Self {
135 FlagsAndTimestamp::new()
136 .with_block_type(BlockType::Request)
137 .with_has_side_effects(true)
138 .with_has_only_data(false)
139 .with_is_end_of_section(true)
140 .with_is_end_of_context(true)
141 .with_has_lifetime(false)
142 .with_has_represented_by(false)
143 .with_has_iv(false)
144 .with_is_compressed(false)
145 .with_is_signature_in_last_subblock(false)
146 }
147}
148
149#[cfg_attr(feature = "debug", derive(serde::Serialize, serde::Deserialize))]
152#[derive(Debug, Clone, Default, BinWrite, BinRead, PartialEq)]
153#[brw(little)]
154pub struct BlockHeader {
155 pub context_id: u32,
158 pub section_index: u16,
162 pub block_number: u16,
168
169 pub flags_and_timestamp: FlagsAndTimestamp,
170
171 #[brw(if(flags_and_timestamp.has_lifetime()))]
172 pub lifetime: Option<u32>,
173
174 #[brw(if(flags_and_timestamp.has_represented_by()))]
175 pub represented_by: Option<Endpoint>,
176
177 #[brw(if(flags_and_timestamp.has_iv()))]
178 pub iv: Option<[u8; 16]>,
179}
180
181impl Serializable for BlockHeader {}