1use crate::error::{Error, Result};
4use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
5
6pub struct XdrDeserializer<'de> {
8 input: &'de [u8],
9 pos: usize,
10}
11
12impl<'de> XdrDeserializer<'de> {
13 pub fn new(input: &'de [u8]) -> Self {
15 Self { input, pos: 0 }
16 }
17
18 pub fn remaining(&self) -> usize {
20 self.input.len() - self.pos
21 }
22
23 fn read_bytes(&mut self, n: usize) -> Result<&'de [u8]> {
25 if self.pos + n > self.input.len() {
26 return Err(Error::Eof);
27 }
28 let bytes = &self.input[self.pos..self.pos + n];
29 self.pos += n;
30 Ok(bytes)
31 }
32
33 fn skip_padding(&mut self, len: usize) -> Result<()> {
35 let padding = (4 - (len % 4)) % 4;
36 if padding > 0 {
37 self.read_bytes(padding)?;
38 }
39 Ok(())
40 }
41
42 fn read_i32(&mut self) -> Result<i32> {
43 let bytes = self.read_bytes(4)?;
44 Ok(i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
45 }
46
47 fn read_u32(&mut self) -> Result<u32> {
48 let bytes = self.read_bytes(4)?;
49 Ok(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
50 }
51
52 fn read_i64(&mut self) -> Result<i64> {
53 let bytes = self.read_bytes(8)?;
54 Ok(i64::from_be_bytes([
55 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
56 ]))
57 }
58
59 fn read_u64(&mut self) -> Result<u64> {
60 let bytes = self.read_bytes(8)?;
61 Ok(u64::from_be_bytes([
62 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
63 ]))
64 }
65}
66
67impl<'de, 'a> de::Deserializer<'de> for &'a mut XdrDeserializer<'de> {
68 type Error = Error;
69
70 fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
71 Err(Error::Message(
72 "XDR does not support deserialize_any".to_string(),
73 ))
74 }
75
76 fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
77 let v = self.read_u32()?;
78 match v {
79 0 => visitor.visit_bool(false),
80 1 => visitor.visit_bool(true),
81 _ => Err(Error::InvalidBool(v)),
82 }
83 }
84
85 fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
86 visitor.visit_i8(self.read_i32()? as i8)
87 }
88
89 fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
90 visitor.visit_i16(self.read_i32()? as i16)
91 }
92
93 fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
94 visitor.visit_i32(self.read_i32()?)
95 }
96
97 fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
98 visitor.visit_i64(self.read_i64()?)
99 }
100
101 fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
102 visitor.visit_u8(self.read_u32()? as u8)
103 }
104
105 fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
106 visitor.visit_u16(self.read_u32()? as u16)
107 }
108
109 fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
110 visitor.visit_u32(self.read_u32()?)
111 }
112
113 fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
114 visitor.visit_u64(self.read_u64()?)
115 }
116
117 fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
118 let bytes = self.read_bytes(4)?;
119 let v = f32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
120 visitor.visit_f32(v)
121 }
122
123 fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
124 let bytes = self.read_bytes(8)?;
125 let v = f64::from_be_bytes([
126 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
127 ]);
128 visitor.visit_f64(v)
129 }
130
131 fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
132 let v = self.read_u32()?;
133 match char::from_u32(v) {
134 Some(c) => visitor.visit_char(c),
135 None => Err(Error::Message(format!("invalid char: {}", v))),
136 }
137 }
138
139 fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
140 let len = self.read_u32()? as usize;
141 let bytes = self.read_bytes(len)?;
142 self.skip_padding(len)?;
143 let s = std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
144 visitor.visit_borrowed_str(s)
145 }
146
147 fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
148 let len = self.read_u32()? as usize;
149 let bytes = self.read_bytes(len)?;
150 self.skip_padding(len)?;
151 let s = std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
152 visitor.visit_string(s.to_string())
153 }
154
155 fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
156 let len = self.read_u32()? as usize;
157 let bytes = self.read_bytes(len)?;
158 self.skip_padding(len)?;
159 visitor.visit_borrowed_bytes(bytes)
160 }
161
162 fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
163 let len = self.read_u32()? as usize;
164 let bytes = self.read_bytes(len)?;
165 self.skip_padding(len)?;
166 visitor.visit_byte_buf(bytes.to_vec())
167 }
168
169 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
170 let present = self.read_u32()?;
171 match present {
172 0 => visitor.visit_none(),
173 1 => visitor.visit_some(self),
174 _ => Err(Error::Message(format!(
175 "invalid option discriminant: {}",
176 present
177 ))),
178 }
179 }
180
181 fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
182 visitor.visit_unit()
183 }
184
185 fn deserialize_unit_struct<V: Visitor<'de>>(
186 self,
187 _name: &'static str,
188 visitor: V,
189 ) -> Result<V::Value> {
190 visitor.visit_unit()
191 }
192
193 fn deserialize_newtype_struct<V: Visitor<'de>>(
194 self,
195 name: &'static str,
196 visitor: V,
197 ) -> Result<V::Value> {
198 if name == "FixedOpaque16" {
200 let bytes = self.read_bytes(16)?;
201 return visitor.visit_bytes(bytes);
203 }
204 visitor.visit_newtype_struct(self)
205 }
206
207 fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
208 let len = self.read_u32()? as usize;
209 visitor.visit_seq(SeqAccessor::new(self, len))
210 }
211
212 fn deserialize_tuple<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
213 visitor.visit_seq(SeqAccessor::new(self, len))
214 }
215
216 fn deserialize_tuple_struct<V: Visitor<'de>>(
217 self,
218 _name: &'static str,
219 len: usize,
220 visitor: V,
221 ) -> Result<V::Value> {
222 visitor.visit_seq(SeqAccessor::new(self, len))
223 }
224
225 fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
226 let len = self.read_u32()? as usize;
227 visitor.visit_map(MapAccessor::new(self, len))
228 }
229
230 fn deserialize_struct<V: Visitor<'de>>(
231 self,
232 _name: &'static str,
233 fields: &'static [&'static str],
234 visitor: V,
235 ) -> Result<V::Value> {
236 visitor.visit_seq(SeqAccessor::new(self, fields.len()))
237 }
238
239 fn deserialize_enum<V: Visitor<'de>>(
240 self,
241 _name: &'static str,
242 _variants: &'static [&'static str],
243 visitor: V,
244 ) -> Result<V::Value> {
245 visitor.visit_enum(EnumAccessor::new(self))
246 }
247
248 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
249 let variant_index = self.read_i32()?;
250 visitor.visit_u32(variant_index as u32)
251 }
252
253 fn deserialize_ignored_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
254 Err(Error::Message(
255 "XDR does not support deserialize_ignored_any".to_string(),
256 ))
257 }
258}
259
260struct SeqAccessor<'a, 'de: 'a> {
261 de: &'a mut XdrDeserializer<'de>,
262 remaining: usize,
263}
264
265impl<'a, 'de> SeqAccessor<'a, 'de> {
266 fn new(de: &'a mut XdrDeserializer<'de>, len: usize) -> Self {
267 Self { de, remaining: len }
268 }
269}
270
271impl<'de, 'a> SeqAccess<'de> for SeqAccessor<'a, 'de> {
272 type Error = Error;
273
274 fn next_element_seed<T: DeserializeSeed<'de>>(
275 &mut self,
276 seed: T,
277 ) -> Result<Option<T::Value>> {
278 if self.remaining == 0 {
279 return Ok(None);
280 }
281 self.remaining -= 1;
282 seed.deserialize(&mut *self.de).map(Some)
283 }
284}
285
286struct MapAccessor<'a, 'de: 'a> {
287 de: &'a mut XdrDeserializer<'de>,
288 remaining: usize,
289}
290
291impl<'a, 'de> MapAccessor<'a, 'de> {
292 fn new(de: &'a mut XdrDeserializer<'de>, len: usize) -> Self {
293 Self { de, remaining: len }
294 }
295}
296
297impl<'de, 'a> MapAccess<'de> for MapAccessor<'a, 'de> {
298 type Error = Error;
299
300 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
301 if self.remaining == 0 {
302 return Ok(None);
303 }
304 self.remaining -= 1;
305 seed.deserialize(&mut *self.de).map(Some)
306 }
307
308 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
309 seed.deserialize(&mut *self.de)
310 }
311}
312
313struct EnumAccessor<'a, 'de: 'a> {
314 de: &'a mut XdrDeserializer<'de>,
315}
316
317impl<'a, 'de> EnumAccessor<'a, 'de> {
318 fn new(de: &'a mut XdrDeserializer<'de>) -> Self {
319 Self { de }
320 }
321}
322
323impl<'de, 'a> de::EnumAccess<'de> for EnumAccessor<'a, 'de> {
324 type Error = Error;
325 type Variant = Self;
326
327 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
328 let val = seed.deserialize(&mut *self.de)?;
329 Ok((val, self))
330 }
331}
332
333impl<'de, 'a> de::VariantAccess<'de> for EnumAccessor<'a, 'de> {
334 type Error = Error;
335
336 fn unit_variant(self) -> Result<()> {
337 Ok(())
338 }
339
340 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
341 seed.deserialize(&mut *self.de)
342 }
343
344 fn tuple_variant<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
345 de::Deserializer::deserialize_tuple(&mut *self.de, len, visitor)
346 }
347
348 fn struct_variant<V: Visitor<'de>>(
349 self,
350 fields: &'static [&'static str],
351 visitor: V,
352 ) -> Result<V::Value> {
353 de::Deserializer::deserialize_struct(&mut *self.de, "", fields, visitor)
354 }
355}
356
357#[cfg(test)]
358mod tests {
359 use super::*;
360 use serde::Deserialize;
361
362 fn from_bytes<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
363 crate::from_bytes(bytes)
364 }
365
366 #[test]
367 fn test_deserialize_i32() {
368 assert_eq!(from_bytes::<i32>(&[0, 0, 0, 42]).unwrap(), 42);
369 assert_eq!(from_bytes::<i32>(&[255, 255, 255, 255]).unwrap(), -1);
370 }
371
372 #[test]
373 fn test_deserialize_u32() {
374 assert_eq!(from_bytes::<u32>(&[0, 0, 0, 42]).unwrap(), 42);
375 assert_eq!(
376 from_bytes::<u32>(&[255, 255, 255, 255]).unwrap(),
377 0xFFFFFFFF
378 );
379 }
380
381 #[test]
382 fn test_deserialize_i64() {
383 assert_eq!(
384 from_bytes::<i64>(&[0, 0, 0, 0, 0, 0, 0, 42]).unwrap(),
385 42
386 );
387 }
388
389 #[test]
390 fn test_deserialize_bool() {
391 assert!(from_bytes::<bool>(&[0, 0, 0, 1]).unwrap());
392 assert!(!from_bytes::<bool>(&[0, 0, 0, 0]).unwrap());
393 assert!(from_bytes::<bool>(&[0, 0, 0, 2]).is_err());
394 }
395
396 #[test]
397 fn test_deserialize_string() {
398 assert_eq!(
399 from_bytes::<String>(&[0, 0, 0, 2, b'h', b'i', 0, 0]).unwrap(),
400 "hi"
401 );
402 assert_eq!(
403 from_bytes::<String>(&[0, 0, 0, 4, b't', b'e', b's', b't']).unwrap(),
404 "test"
405 );
406 }
407
408 #[test]
409 fn test_deserialize_vec() {
410 let bytes = [
411 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, ];
416 assert_eq!(from_bytes::<Vec<i32>>(&bytes).unwrap(), vec![1, 2, 3]);
417 }
418
419 #[test]
420 fn test_deserialize_option() {
421 assert_eq!(
422 from_bytes::<Option<i32>>(&[0, 0, 0, 1, 0, 0, 0, 42]).unwrap(),
423 Some(42)
424 );
425 assert_eq!(
426 from_bytes::<Option<i32>>(&[0, 0, 0, 0]).unwrap(),
427 None
428 );
429 }
430
431 #[test]
432 fn test_deserialize_struct() {
433 #[derive(Debug, PartialEq, Deserialize)]
434 struct Point {
435 x: i32,
436 y: i32,
437 }
438
439 let bytes = [0, 0, 0, 10, 0, 0, 0, 20];
440 assert_eq!(
441 from_bytes::<Point>(&bytes).unwrap(),
442 Point { x: 10, y: 20 }
443 );
444 }
445
446 #[test]
447 fn test_roundtrip() {
448 use serde::Serialize;
449
450 #[derive(Debug, PartialEq, Serialize, Deserialize)]
451 struct TestStruct {
452 name: String,
453 value: i32,
454 items: Vec<u32>,
455 optional: Option<i64>,
456 }
457
458 let original = TestStruct {
459 name: "test".to_string(),
460 value: -42,
461 items: vec![1, 2, 3],
462 optional: Some(12345),
463 };
464
465 let bytes = crate::to_bytes(&original).unwrap();
466 let decoded: TestStruct = crate::from_bytes(&bytes).unwrap();
467
468 assert_eq!(original, decoded);
469 }
470}