corepack/
map_serializer.rs

1//! The serializer that formats maps correctly for messagepack.
2//
3// This Source Code Form is subject to the terms of the Mozilla Public License,
4// v. 2.0. If a copy of the MPL was not distributed with this file, You can
5// obtain one at https://mozilla.org/MPL/2.0/.
6#[cfg(feature = "alloc")]
7use alloc::vec::Vec;
8
9use serde::ser::{Serialize, SerializeMap, SerializeStruct, SerializeStructVariant};
10
11use byteorder::{ByteOrder, BigEndian};
12
13use ser::Serializer;
14
15use defs::*;
16use error::Error;
17
18pub struct MapSerializer<'a, F: 'a + FnMut(&[u8]) -> Result<(), Error>> {
19    count: usize,
20    size: Option<usize>,
21    buffer: Vec<u8>,
22    output: &'a mut F,
23}
24
25impl<'a, F: 'a + FnMut(&[u8]) -> Result<(), Error>> MapSerializer<'a, F> {
26    pub fn new(output: &'a mut F) -> MapSerializer<'a, F> {
27        MapSerializer {
28            count: 0,
29            size: None,
30            buffer: vec![],
31            output: output,
32        }
33    }
34
35    pub fn hint_size(&mut self, size: Option<usize>) -> Result<(), Error> {
36        self.size = size;
37
38        if let Some(size) = self.size {
39            // output this now because we know it
40            self.output_map_header(size)
41        } else {
42            Ok(())
43        }
44    }
45
46    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
47        where T: ?Sized + Serialize
48    {
49        self.count += 1;
50
51        if self.should_serialize_directly() {
52            self.serialize_directly(value)
53        } else {
54            self.serialize_into_buffer(value)
55        }
56    }
57
58    fn finish(mut self) -> Result<(), Error> {
59        if let Some(size) = self.size {
60            self.check_item_count_matches_size(size * 2)?;
61            Ok(())
62        } else {
63            let count = self.get_item_count()?;
64            self.output_map_header(count)?;
65            (self.output)(&*self.buffer)
66        }
67    }
68
69    fn output_map_header(&mut self, size: usize) -> Result<(), Error> {
70        if size <= MAX_FIXMAP {
71            (self.output)(&[size as u8 | FIXMAP_MASK])
72        } else if size <= MAX_MAP16 {
73            let mut buf = [MAP16; U16_BYTES + 1];
74            BigEndian::write_u16(&mut buf[1..], size as u16);
75            (self.output)(&buf)
76        } else if size <= MAX_MAP32 {
77            let mut buf = [MAP32; U32_BYTES + 1];
78            BigEndian::write_u32(&mut buf[1..], size as u32);
79            (self.output)(&buf)
80        } else {
81            Err(Error::TooBig)
82        }
83    }
84
85    fn get_item_count(&self) -> Result<usize, Error> {
86        if self.count % 1 != 0 {
87            Err(Error::BadLength)
88        } else {
89            Ok(self.count / 2)
90        }
91    }
92
93    fn check_item_count_matches_size(&self, size: usize) -> Result<(), Error> {
94        if size != self.count {
95            Err(Error::BadLength)
96        } else {
97            Ok(())
98        }
99    }
100
101    fn should_serialize_directly(&mut self) -> bool {
102        self.size.is_some()
103    }
104
105    fn serialize_into_buffer<T>(&mut self, value: &T) -> Result<(), Error>
106        where T: ?Sized + Serialize
107    {
108        let mut target = Serializer::new(|bytes| {
109            self.buffer.extend_from_slice(bytes);
110            Ok(())
111        });
112
113        value.serialize(&mut target)
114    }
115
116    fn serialize_directly<T>(&mut self, value: &T) -> Result<(), Error>
117        where T: ?Sized + Serialize
118    {
119        let mut target = Serializer::new(|bytes| (self.output)(bytes));
120
121        value.serialize(&mut target)
122    }
123}
124
125impl<'a, F: 'a + FnMut(&[u8]) -> Result<(), Error>> SerializeMap for MapSerializer<'a, F> {
126    type Ok = ();
127    type Error = Error;
128
129    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Error>
130        where T: ?Sized + Serialize
131    {
132        MapSerializer::serialize_element(self, key)
133    }
134
135    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Error>
136        where T: ?Sized + Serialize
137    {
138        MapSerializer::serialize_element(self, value)
139    }
140
141    fn end(self) -> Result<(), Error> {
142        MapSerializer::finish(self)
143    }
144}
145
146impl<'a, F: 'a + FnMut(&[u8]) -> Result<(), Error>> SerializeStruct for MapSerializer<'a, F> {
147    type Ok = ();
148    type Error = Error;
149
150    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
151        where T: ?Sized + Serialize
152    {
153        MapSerializer::serialize_entry(self, key, value)
154    }
155
156    fn end(self) -> Result<(), Error> {
157        MapSerializer::finish(self)
158    }
159}
160
161impl<'a, F: 'a + FnMut(&[u8]) -> Result<(), Error>> SerializeStructVariant
162    for MapSerializer<'a, F> {
163    type Ok = ();
164    type Error = Error;
165
166    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
167        where T: ?Sized + Serialize
168    {
169        MapSerializer::serialize_entry(self, key, value)
170    }
171
172    fn end(self) -> Result<(), Error> {
173        MapSerializer::finish(self)
174    }
175}