Skip to main content

libvirt_xdr/
ser.rs

1//! XDR Serializer implementation.
2
3use crate::error::{Error, Result};
4use serde::{ser, Serialize};
5
6/// XDR Serializer.
7pub struct XdrSerializer {
8    output: Vec<u8>,
9}
10
11impl XdrSerializer {
12    /// Create a new XDR serializer.
13    pub fn new() -> Self {
14        Self { output: Vec::new() }
15    }
16
17    /// Create a new XDR serializer with a capacity hint.
18    pub fn with_capacity(capacity: usize) -> Self {
19        Self {
20            output: Vec::with_capacity(capacity),
21        }
22    }
23
24    /// Get the serialized bytes.
25    pub fn into_bytes(self) -> Vec<u8> {
26        self.output
27    }
28
29    /// Write padding bytes for 4-byte alignment.
30    fn write_padding(&mut self, len: usize) {
31        let padding = (4 - (len % 4)) % 4;
32        self.output.extend(std::iter::repeat(0u8).take(padding));
33    }
34}
35
36impl Default for XdrSerializer {
37    fn default() -> Self {
38        Self::new()
39    }
40}
41
42/// Special serializer for fixed-length opaque that writes bytes without length prefix.
43struct FixedOpaqueSerializer<'a> {
44    output: &'a mut Vec<u8>,
45}
46
47impl<'a> ser::Serializer for &'a mut FixedOpaqueSerializer<'a> {
48    type Ok = ();
49    type Error = Error;
50    type SerializeSeq = ser::Impossible<(), Error>;
51    type SerializeTuple = ser::Impossible<(), Error>;
52    type SerializeTupleStruct = ser::Impossible<(), Error>;
53    type SerializeTupleVariant = ser::Impossible<(), Error>;
54    type SerializeMap = ser::Impossible<(), Error>;
55    type SerializeStruct = ser::Impossible<(), Error>;
56    type SerializeStructVariant = ser::Impossible<(), Error>;
57
58    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
59        // Write raw bytes without length prefix
60        self.output.extend_from_slice(v);
61        // Add padding for 4-byte alignment
62        let padding = (4 - (v.len() % 4)) % 4;
63        self.output.extend(std::iter::repeat(0u8).take(padding));
64        Ok(())
65    }
66
67    // All other methods are unsupported - we only expect serialize_bytes
68    fn serialize_bool(self, _: bool) -> Result<()> { Err(Error::Message("unsupported".into())) }
69    fn serialize_i8(self, _: i8) -> Result<()> { Err(Error::Message("unsupported".into())) }
70    fn serialize_i16(self, _: i16) -> Result<()> { Err(Error::Message("unsupported".into())) }
71    fn serialize_i32(self, _: i32) -> Result<()> { Err(Error::Message("unsupported".into())) }
72    fn serialize_i64(self, _: i64) -> Result<()> { Err(Error::Message("unsupported".into())) }
73    fn serialize_u8(self, _: u8) -> Result<()> { Err(Error::Message("unsupported".into())) }
74    fn serialize_u16(self, _: u16) -> Result<()> { Err(Error::Message("unsupported".into())) }
75    fn serialize_u32(self, _: u32) -> Result<()> { Err(Error::Message("unsupported".into())) }
76    fn serialize_u64(self, _: u64) -> Result<()> { Err(Error::Message("unsupported".into())) }
77    fn serialize_f32(self, _: f32) -> Result<()> { Err(Error::Message("unsupported".into())) }
78    fn serialize_f64(self, _: f64) -> Result<()> { Err(Error::Message("unsupported".into())) }
79    fn serialize_char(self, _: char) -> Result<()> { Err(Error::Message("unsupported".into())) }
80    fn serialize_str(self, _: &str) -> Result<()> { Err(Error::Message("unsupported".into())) }
81    fn serialize_none(self) -> Result<()> { Err(Error::Message("unsupported".into())) }
82    fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<()> { Err(Error::Message("unsupported".into())) }
83    fn serialize_unit(self) -> Result<()> { Err(Error::Message("unsupported".into())) }
84    fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Err(Error::Message("unsupported".into())) }
85    fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> { Err(Error::Message("unsupported".into())) }
86    fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _: &'static str, _: &T) -> Result<()> { Err(Error::Message("unsupported".into())) }
87    fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _: &'static str, _: u32, _: &'static str, _: &T) -> Result<()> { Err(Error::Message("unsupported".into())) }
88    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> { Err(Error::Message("unsupported".into())) }
89    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> { Err(Error::Message("unsupported".into())) }
90    fn serialize_tuple_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeTupleStruct> { Err(Error::Message("unsupported".into())) }
91    fn serialize_tuple_variant(self, _: &'static str, _: u32, _: &'static str, _: usize) -> Result<Self::SerializeTupleVariant> { Err(Error::Message("unsupported".into())) }
92    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> { Err(Error::Message("unsupported".into())) }
93    fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> { Err(Error::Message("unsupported".into())) }
94    fn serialize_struct_variant(self, _: &'static str, _: u32, _: &'static str, _: usize) -> Result<Self::SerializeStructVariant> { Err(Error::Message("unsupported".into())) }
95}
96
97impl<'a> ser::Serializer for &'a mut XdrSerializer {
98    type Ok = ();
99    type Error = Error;
100
101    type SerializeSeq = Self;
102    type SerializeTuple = Self;
103    type SerializeTupleStruct = Self;
104    type SerializeTupleVariant = Self;
105    type SerializeMap = Self;
106    type SerializeStruct = Self;
107    type SerializeStructVariant = Self;
108
109    fn serialize_bool(self, v: bool) -> Result<()> {
110        self.serialize_u32(if v { 1 } else { 0 })
111    }
112
113    fn serialize_i8(self, v: i8) -> Result<()> {
114        self.serialize_i32(v as i32)
115    }
116
117    fn serialize_i16(self, v: i16) -> Result<()> {
118        self.serialize_i32(v as i32)
119    }
120
121    fn serialize_i32(self, v: i32) -> Result<()> {
122        self.output.extend_from_slice(&v.to_be_bytes());
123        Ok(())
124    }
125
126    fn serialize_i64(self, v: i64) -> Result<()> {
127        self.output.extend_from_slice(&v.to_be_bytes());
128        Ok(())
129    }
130
131    fn serialize_u8(self, v: u8) -> Result<()> {
132        self.serialize_u32(v as u32)
133    }
134
135    fn serialize_u16(self, v: u16) -> Result<()> {
136        self.serialize_u32(v as u32)
137    }
138
139    fn serialize_u32(self, v: u32) -> Result<()> {
140        self.output.extend_from_slice(&v.to_be_bytes());
141        Ok(())
142    }
143
144    fn serialize_u64(self, v: u64) -> Result<()> {
145        self.output.extend_from_slice(&v.to_be_bytes());
146        Ok(())
147    }
148
149    fn serialize_f32(self, v: f32) -> Result<()> {
150        self.output.extend_from_slice(&v.to_be_bytes());
151        Ok(())
152    }
153
154    fn serialize_f64(self, v: f64) -> Result<()> {
155        self.output.extend_from_slice(&v.to_be_bytes());
156        Ok(())
157    }
158
159    fn serialize_char(self, v: char) -> Result<()> {
160        self.serialize_u32(v as u32)
161    }
162
163    fn serialize_str(self, v: &str) -> Result<()> {
164        let bytes = v.as_bytes();
165        self.serialize_u32(bytes.len() as u32)?;
166        self.output.extend_from_slice(bytes);
167        self.write_padding(bytes.len());
168        Ok(())
169    }
170
171    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
172        self.serialize_u32(v.len() as u32)?;
173        self.output.extend_from_slice(v);
174        self.write_padding(v.len());
175        Ok(())
176    }
177
178    fn serialize_none(self) -> Result<()> {
179        self.serialize_u32(0)
180    }
181
182    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
183        self.serialize_u32(1)?;
184        value.serialize(self)
185    }
186
187    fn serialize_unit(self) -> Result<()> {
188        Ok(())
189    }
190
191    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
192        Ok(())
193    }
194
195    fn serialize_unit_variant(
196        self,
197        _name: &'static str,
198        variant_index: u32,
199        _variant: &'static str,
200    ) -> Result<()> {
201        self.serialize_i32(variant_index as i32)
202    }
203
204    fn serialize_newtype_struct<T: ?Sized + Serialize>(
205        self,
206        name: &'static str,
207        value: &T,
208    ) -> Result<()> {
209        if name == "FixedOpaque16" {
210            // Special handling: inner value will call serialize_bytes,
211            // but we override to not write length prefix
212            let mut fixed_ser = FixedOpaqueSerializer { output: &mut self.output };
213            value.serialize(&mut fixed_ser)
214        } else {
215            value.serialize(self)
216        }
217    }
218
219    fn serialize_newtype_variant<T: ?Sized + Serialize>(
220        self,
221        _name: &'static str,
222        variant_index: u32,
223        _variant: &'static str,
224        value: &T,
225    ) -> Result<()> {
226        self.serialize_i32(variant_index as i32)?;
227        value.serialize(self)
228    }
229
230    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
231        if let Some(len) = len {
232            self.serialize_u32(len as u32)?;
233        }
234        Ok(self)
235    }
236
237    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
238        Ok(self)
239    }
240
241    fn serialize_tuple_struct(
242        self,
243        _name: &'static str,
244        _len: usize,
245    ) -> Result<Self::SerializeTupleStruct> {
246        Ok(self)
247    }
248
249    fn serialize_tuple_variant(
250        self,
251        _name: &'static str,
252        variant_index: u32,
253        _variant: &'static str,
254        _len: usize,
255    ) -> Result<Self::SerializeTupleVariant> {
256        self.serialize_i32(variant_index as i32)?;
257        Ok(self)
258    }
259
260    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
261        if let Some(len) = len {
262            self.serialize_u32(len as u32)?;
263        }
264        Ok(self)
265    }
266
267    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
268        Ok(self)
269    }
270
271    fn serialize_struct_variant(
272        self,
273        _name: &'static str,
274        variant_index: u32,
275        _variant: &'static str,
276        _len: usize,
277    ) -> Result<Self::SerializeStructVariant> {
278        self.serialize_i32(variant_index as i32)?;
279        Ok(self)
280    }
281}
282
283impl<'a> ser::SerializeSeq for &'a mut XdrSerializer {
284    type Ok = ();
285    type Error = Error;
286
287    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
288        value.serialize(&mut **self)
289    }
290
291    fn end(self) -> Result<()> {
292        Ok(())
293    }
294}
295
296impl<'a> ser::SerializeTuple for &'a mut XdrSerializer {
297    type Ok = ();
298    type Error = Error;
299
300    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
301        value.serialize(&mut **self)
302    }
303
304    fn end(self) -> Result<()> {
305        Ok(())
306    }
307}
308
309impl<'a> ser::SerializeTupleStruct for &'a mut XdrSerializer {
310    type Ok = ();
311    type Error = Error;
312
313    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
314        value.serialize(&mut **self)
315    }
316
317    fn end(self) -> Result<()> {
318        Ok(())
319    }
320}
321
322impl<'a> ser::SerializeTupleVariant for &'a mut XdrSerializer {
323    type Ok = ();
324    type Error = Error;
325
326    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
327        value.serialize(&mut **self)
328    }
329
330    fn end(self) -> Result<()> {
331        Ok(())
332    }
333}
334
335impl<'a> ser::SerializeMap for &'a mut XdrSerializer {
336    type Ok = ();
337    type Error = Error;
338
339    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
340        key.serialize(&mut **self)
341    }
342
343    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
344        value.serialize(&mut **self)
345    }
346
347    fn end(self) -> Result<()> {
348        Ok(())
349    }
350}
351
352impl<'a> ser::SerializeStruct for &'a mut XdrSerializer {
353    type Ok = ();
354    type Error = Error;
355
356    fn serialize_field<T: ?Sized + Serialize>(
357        &mut self,
358        _key: &'static str,
359        value: &T,
360    ) -> Result<()> {
361        value.serialize(&mut **self)
362    }
363
364    fn end(self) -> Result<()> {
365        Ok(())
366    }
367}
368
369impl<'a> ser::SerializeStructVariant for &'a mut XdrSerializer {
370    type Ok = ();
371    type Error = Error;
372
373    fn serialize_field<T: ?Sized + Serialize>(
374        &mut self,
375        _key: &'static str,
376        value: &T,
377    ) -> Result<()> {
378        value.serialize(&mut **self)
379    }
380
381    fn end(self) -> Result<()> {
382        Ok(())
383    }
384}
385
386#[cfg(test)]
387mod tests {
388    use super::*;
389    use serde::Serialize;
390
391    fn to_bytes<T: Serialize>(value: &T) -> Result<Vec<u8>> {
392        crate::to_bytes(value)
393    }
394
395    #[test]
396    fn test_serialize_i32() {
397        assert_eq!(to_bytes(&42i32).unwrap(), vec![0, 0, 0, 42]);
398        assert_eq!(to_bytes(&-1i32).unwrap(), vec![255, 255, 255, 255]);
399    }
400
401    #[test]
402    fn test_serialize_u32() {
403        assert_eq!(to_bytes(&42u32).unwrap(), vec![0, 0, 0, 42]);
404        assert_eq!(to_bytes(&0xFFFFFFFFu32).unwrap(), vec![255, 255, 255, 255]);
405    }
406
407    #[test]
408    fn test_serialize_i64() {
409        assert_eq!(
410            to_bytes(&42i64).unwrap(),
411            vec![0, 0, 0, 0, 0, 0, 0, 42]
412        );
413    }
414
415    #[test]
416    fn test_serialize_bool() {
417        assert_eq!(to_bytes(&true).unwrap(), vec![0, 0, 0, 1]);
418        assert_eq!(to_bytes(&false).unwrap(), vec![0, 0, 0, 0]);
419    }
420
421    #[test]
422    fn test_serialize_string() {
423        // "hi" -> length 2 + "hi" + 2 bytes padding
424        assert_eq!(to_bytes(&"hi").unwrap(), vec![0, 0, 0, 2, b'h', b'i', 0, 0]);
425
426        // "test" -> length 4 + "test" (already aligned)
427        assert_eq!(
428            to_bytes(&"test").unwrap(),
429            vec![0, 0, 0, 4, b't', b'e', b's', b't']
430        );
431    }
432
433    #[test]
434    fn test_serialize_vec() {
435        let v: Vec<i32> = vec![1, 2, 3];
436        assert_eq!(
437            to_bytes(&v).unwrap(),
438            vec![
439                0, 0, 0, 3, // length
440                0, 0, 0, 1, // 1
441                0, 0, 0, 2, // 2
442                0, 0, 0, 3, // 3
443            ]
444        );
445    }
446
447    #[test]
448    fn test_serialize_option() {
449        let some: Option<i32> = Some(42);
450        let none: Option<i32> = None;
451
452        assert_eq!(
453            to_bytes(&some).unwrap(),
454            vec![0, 0, 0, 1, 0, 0, 0, 42]
455        );
456        assert_eq!(to_bytes(&none).unwrap(), vec![0, 0, 0, 0]);
457    }
458
459    #[test]
460    fn test_serialize_struct() {
461        #[derive(Serialize)]
462        struct Point {
463            x: i32,
464            y: i32,
465        }
466
467        let p = Point { x: 10, y: 20 };
468        assert_eq!(
469            to_bytes(&p).unwrap(),
470            vec![0, 0, 0, 10, 0, 0, 0, 20]
471        );
472    }
473}
474