serenity_voice_model/
binary.rs1use crate::opcode::Opcode;
9use crate::payload::*;
10
11#[derive(Debug)]
13pub enum BinaryError {
14 InsufficientData,
16 InvalidOpcode(u8),
18 InvalidOperationType(u8),
20 ParseError(String),
22}
23
24impl std::fmt::Display for BinaryError {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 match self {
27 Self::InsufficientData => write!(f, "Insufficient data to parse binary message"),
28 Self::InvalidOpcode(op) => write!(f, "Invalid opcode: {}", op),
29 Self::InvalidOperationType(op) => write!(f, "Invalid operation type: {}", op),
30 Self::ParseError(msg) => write!(f, "Parse error: {}", msg),
31 }
32 }
33}
34
35impl std::error::Error for BinaryError {}
36
37fn read_u16(data: &[u8]) -> Result<u16, BinaryError> {
39 if data.len() < 2 {
40 return Err(BinaryError::InsufficientData);
41 }
42 Ok(u16::from_be_bytes([data[0], data[1]]))
43}
44
45pub fn deserialize_binary_event(data: &[u8]) -> Result<crate::Event, BinaryError> {
47 if data.len() < 1 {
51 return Err(BinaryError::InsufficientData);
52 }
53
54 let opcode = data[0];
55
56 #[cfg(debug_assertions)]
58 eprintln!(
59 "[DAVE Binary] Received {} bytes: opcode={}, data={:02X?}",
60 data.len(),
61 opcode,
62 &data[..data.len().min(16)]
63 );
64
65 match opcode {
66 25 => {
67 let external_sender = data[1..].to_vec();
69 Ok(crate::Event::DaveMlsExternalSender(DaveMlsExternalSender {
70 external_sender,
71 }))
72 },
73 27 => {
74 if data.len() < 2 {
76 return Err(BinaryError::InsufficientData);
77 }
78 let operation_type = match data[1] {
79 0 => DaveMlsProposalsOperationType::Append,
80 1 => DaveMlsProposalsOperationType::Revoke,
81 other => return Err(BinaryError::InvalidOperationType(other)),
82 };
83 let proposals = data[2..].to_vec();
84 Ok(crate::Event::DaveMlsProposals(DaveMlsProposals {
85 operation_type,
86 proposals,
87 }))
88 },
89 29 => {
90 if data.len() < 3 {
92 return Err(BinaryError::InsufficientData);
93 }
94 let transition_id = read_u16(&data[1..3])?;
95 let commit_message = data[3..].to_vec();
96 Ok(crate::Event::DaveMlsAnnounceCommitTransition(DaveMlsAnnounceCommitTransition {
97 transition_id,
98 commit_message,
99 }))
100 },
101 30 => {
102 if data.len() < 3 {
104 return Err(BinaryError::InsufficientData);
105 }
106 let transition_id = read_u16(&data[1..3])?;
107 let welcome = data[3..].to_vec();
108 Ok(crate::Event::DaveMlsWelcome(DaveMlsWelcome {
109 transition_id,
110 welcome,
111 }))
112 },
113 other => {
115 #[cfg(debug_assertions)]
116 eprintln!(
117 "[DAVE Binary] Skipping unknown opcode {}: {:02X?}",
118 other,
119 &data[..data.len().min(32)]
120 );
121
122 Err(BinaryError::InvalidOpcode(other))
123 },
124 }
125}
126
127pub fn serialize_binary_event(event: &crate::Event) -> Result<Vec<u8>, BinaryError> {
129 match event {
130 crate::Event::DaveMlsKeyPackage(payload) => {
131 let mut data = Vec::with_capacity(1 + payload.key_package.len());
133 data.push(Opcode::DaveMlsKeyPackage as u8);
134 data.extend_from_slice(&payload.key_package);
135 Ok(data)
136 },
137 crate::Event::DaveMlsCommitWelcome(payload) => {
138 let mut data = Vec::with_capacity(
141 1 + payload.commit.len() + payload.welcome.as_ref().map_or(0, |w| w.len()),
142 );
143 data.push(Opcode::DaveMlsCommitWelcome as u8);
144 data.extend_from_slice(&payload.commit);
145
146 if let Some(welcome) = &payload.welcome {
147 data.extend_from_slice(welcome);
148 }
149 Ok(data)
150 },
151 _ => Err(BinaryError::ParseError("Event is not a binary DAVE opcode".to_string())),
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn test_deserialize_external_sender() {
161 let data = vec![
162 25, 0xDE, 0xAD, 0xBE, 0xEF, ];
165
166 let event = deserialize_binary_event(&data).unwrap();
167 match event {
168 crate::Event::DaveMlsExternalSender(payload) => {
169 assert_eq!(payload.external_sender, vec![0xDE, 0xAD, 0xBE, 0xEF]);
170 },
171 _ => panic!("Wrong event type"),
172 }
173 }
174
175 #[test]
176 fn test_deserialize_proposals() {
177 let data = vec![
178 27, 0, 0xCA, 0xFE, ];
182
183 let event = deserialize_binary_event(&data).unwrap();
184 match event {
185 crate::Event::DaveMlsProposals(payload) => {
186 assert!(matches!(payload.operation_type, DaveMlsProposalsOperationType::Append));
187 assert_eq!(payload.proposals, vec![0xCA, 0xFE]);
188 },
189 _ => panic!("Wrong event type"),
190 }
191 }
192
193 #[test]
194 fn test_serialize_key_package() {
195 let event = crate::Event::DaveMlsKeyPackage(DaveMlsKeyPackage {
196 key_package: vec![0xAA, 0xBB, 0xCC],
197 });
198
199 let data = serialize_binary_event(&event).unwrap();
200 assert_eq!(data, vec![26, 0xAA, 0xBB, 0xCC]);
201 }
202
203 #[test]
204 fn test_serialize_commit_welcome() {
205 let event = crate::Event::DaveMlsCommitWelcome(DaveMlsCommitWelcome {
206 commit: vec![0x11, 0x22],
207 welcome: Some(vec![0x33, 0x44]),
208 });
209
210 let data = serialize_binary_event(&event).unwrap();
211 assert_eq!(data, vec![28, 0x11, 0x22, 0x33, 0x44]);
212 }
213}