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