1use serde::ser::{self, Serialize};
7
8use crate::serde_impls::{ATOM, REST, VALUE};
9use crate::{Node, SerializeError, Value};
10
11pub fn to_node<T: Serialize + ?Sized>(value: &T) -> Result<Node, SerializeError> {
13 Ok(match value.serialize(NodeSerializer)? {
14 Item::One(node) => node,
15 Item::Splice(items) => Node::list(items),
16 })
17}
18
19pub fn to_string<T: Serialize + ?Sized>(value: &T) -> Result<String, SerializeError> {
21 to_node(value).map(|node| node.to_string())
22}
23
24enum Item {
26 One(Node),
27 Splice(Vec<Node>),
28}
29
30fn one(node: Node) -> Result<Item, SerializeError> {
31 Ok(Item::One(node))
32}
33
34struct NodeSerializer;
35
36macro_rules! serialize_display {
37 ($($method:ident: $t:ty),* $(,)?) => {$(
38 fn $method(self, v: $t) -> Result<Item, SerializeError> {
39 one(Node::atom(v.to_string()))
40 }
41 )*};
42}
43
44impl ser::Serializer for NodeSerializer {
45 type Ok = Item;
46 type Error = SerializeError;
47 type SerializeSeq = List;
48 type SerializeTuple = List;
49 type SerializeTupleStruct = List;
50 type SerializeTupleVariant = List;
51 type SerializeMap = Map;
52 type SerializeStruct = List;
53 type SerializeStructVariant = List;
54
55 fn serialize_bool(self, v: bool) -> Result<Item, SerializeError> {
56 one(Node::from(v))
57 }
58
59 serialize_display! {
60 serialize_i8: i8,
61 serialize_i16: i16,
62 serialize_i32: i32,
63 serialize_i64: i64,
64 serialize_i128: i128,
65 serialize_u8: u8,
66 serialize_u16: u16,
67 serialize_u32: u32,
68 serialize_u64: u64,
69 serialize_u128: u128,
70 serialize_f32: f32,
71 serialize_f64: f64,
72 }
73
74 fn serialize_char(self, v: char) -> Result<Item, SerializeError> {
75 one(Node::string(v))
76 }
77
78 fn serialize_str(self, v: &str) -> Result<Item, SerializeError> {
79 one(Node::string(v))
80 }
81
82 fn serialize_bytes(self, _v: &[u8]) -> Result<Item, SerializeError> {
83 Err(SerializeError::new(
84 "byte arrays are not supported: write binary data as a `#base64:` atom",
85 ))
86 }
87
88 fn serialize_none(self) -> Result<Item, SerializeError> {
89 one(Node::atom(""))
90 }
91
92 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Item, SerializeError> {
93 value.serialize(self)
94 }
95
96 fn serialize_unit(self) -> Result<Item, SerializeError> {
97 one(Node::atom(""))
98 }
99
100 fn serialize_unit_struct(self, _name: &'static str) -> Result<Item, SerializeError> {
101 one(Node::atom(""))
102 }
103
104 fn serialize_unit_variant(
105 self,
106 _name: &'static str,
107 index: u32,
108 _variant: &'static str,
109 ) -> Result<Item, SerializeError> {
110 one(Node::from(index))
111 }
112
113 fn serialize_newtype_struct<T: Serialize + ?Sized>(
114 self,
115 name: &'static str,
116 value: &T,
117 ) -> Result<Item, SerializeError> {
118 match name {
119 REST => match to_node(value)?.into_list() {
120 Some(items) => Ok(Item::Splice(items)),
121 None => Err(SerializeError::new("a rest must serialize as a sequence")),
122 },
123 ATOM => match to_node(value)?.into_value() {
124 Value::Str(s) | Value::Atom(s) => one(Node::atom(s)),
125 Value::List(_) => Err(SerializeError::new("an atom must serialize as a string")),
126 },
127 _ => value.serialize(self),
128 }
129 }
130
131 fn serialize_newtype_variant<T: Serialize + ?Sized>(
132 self,
133 name: &'static str,
134 index: u32,
135 _variant: &'static str,
136 value: &T,
137 ) -> Result<Item, SerializeError> {
138 if name == VALUE {
139 return value.serialize(self);
140 }
141 one(Node::list([Node::from(index), to_node(value)?]))
142 }
143
144 fn serialize_seq(self, len: Option<usize>) -> Result<List, SerializeError> {
145 Ok(List::with_capacity(len.unwrap_or(0)))
146 }
147
148 fn serialize_tuple(self, len: usize) -> Result<List, SerializeError> {
149 Ok(List::with_capacity(len))
150 }
151
152 fn serialize_tuple_struct(
153 self,
154 _name: &'static str,
155 len: usize,
156 ) -> Result<List, SerializeError> {
157 Ok(List::with_capacity(len))
158 }
159
160 fn serialize_tuple_variant(
161 self,
162 _name: &'static str,
163 index: u32,
164 _variant: &'static str,
165 len: usize,
166 ) -> Result<List, SerializeError> {
167 Ok(List::tagged(index, len))
168 }
169
170 fn serialize_map(self, len: Option<usize>) -> Result<Map, SerializeError> {
171 Ok(Map {
172 items: Vec::with_capacity(len.unwrap_or(0)),
173 key: None,
174 })
175 }
176
177 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<List, SerializeError> {
178 Ok(List::with_capacity(len))
179 }
180
181 fn serialize_struct_variant(
182 self,
183 _name: &'static str,
184 index: u32,
185 _variant: &'static str,
186 len: usize,
187 ) -> Result<List, SerializeError> {
188 Ok(List::tagged(index, len))
189 }
190}
191
192struct List {
193 items: Vec<Node>,
194}
195
196impl List {
197 fn with_capacity(len: usize) -> Self {
198 List {
199 items: Vec::with_capacity(len),
200 }
201 }
202
203 fn tagged(index: u32, len: usize) -> Self {
204 let mut list = List::with_capacity(len + 1);
205 list.items.push(Node::from(index));
206 list
207 }
208
209 fn push<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), SerializeError> {
210 match value.serialize(NodeSerializer)? {
211 Item::One(node) => self.items.push(node),
212 Item::Splice(items) => self.items.extend(items),
213 }
214 Ok(())
215 }
216
217 fn finish(self) -> Result<Item, SerializeError> {
218 one(Node::list(self.items))
219 }
220}
221
222macro_rules! impl_list {
223 ($($trait:ident :: $method:ident($($key:ident: $key_ty:ty)?)),* $(,)?) => {$(
224 impl ser::$trait for List {
225 type Ok = Item;
226 type Error = SerializeError;
227
228 fn $method<T: Serialize + ?Sized>(
229 &mut self,
230 $($key: $key_ty,)?
231 value: &T,
232 ) -> Result<(), SerializeError> {
233 self.push(value)
234 }
235
236 fn end(self) -> Result<Item, SerializeError> {
237 self.finish()
238 }
239 }
240 )*};
241}
242
243impl_list! {
244 SerializeSeq::serialize_element(),
245 SerializeTuple::serialize_element(),
246 SerializeTupleStruct::serialize_field(),
247 SerializeTupleVariant::serialize_field(),
248}
249
250impl ser::SerializeStruct for List {
251 type Ok = Item;
252 type Error = SerializeError;
253
254 fn serialize_field<T: Serialize + ?Sized>(
255 &mut self,
256 _key: &'static str,
257 value: &T,
258 ) -> Result<(), SerializeError> {
259 self.push(value)
260 }
261
262 fn skip_field(&mut self, _key: &'static str) -> Result<(), SerializeError> {
264 self.items.push(Node::atom(""));
265 Ok(())
266 }
267
268 fn end(self) -> Result<Item, SerializeError> {
269 self.finish()
270 }
271}
272
273impl ser::SerializeStructVariant for List {
274 type Ok = Item;
275 type Error = SerializeError;
276
277 fn serialize_field<T: Serialize + ?Sized>(
278 &mut self,
279 _key: &'static str,
280 value: &T,
281 ) -> Result<(), SerializeError> {
282 self.push(value)
283 }
284
285 fn skip_field(&mut self, _key: &'static str) -> Result<(), SerializeError> {
286 self.items.push(Node::atom(""));
287 Ok(())
288 }
289
290 fn end(self) -> Result<Item, SerializeError> {
291 self.finish()
292 }
293}
294
295struct Map {
297 items: Vec<Node>,
298 key: Option<Node>,
299}
300
301impl ser::SerializeMap for Map {
302 type Ok = Item;
303 type Error = SerializeError;
304
305 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), SerializeError> {
306 self.key = Some(to_node(key)?);
307 Ok(())
308 }
309
310 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), SerializeError> {
311 let key = self
312 .key
313 .take()
314 .ok_or_else(|| SerializeError::new("map value written before its key"))?;
315 self.items.push(Node::list([key, to_node(value)?]));
316 Ok(())
317 }
318
319 fn end(self) -> Result<Item, SerializeError> {
320 one(Node::list(self.items))
321 }
322}