1 | //! Serializing Rust structures into TOML. |
2 | //! |
3 | //! This module contains all the Serde support for serializing Rust structures |
4 | //! into TOML documents (as strings). Note that some top-level functions here |
5 | //! are also provided at the top of the crate. |
6 | //! |
7 | //! Note that the TOML format has a restriction that if a table itself contains |
8 | //! tables, all keys with non-table values must be emitted first. This is |
9 | //! typically easy to ensure happens when you're defining a `struct` as you can |
10 | //! reorder the fields manually, but when working with maps (such as `BTreeMap` |
11 | //! or `HashMap`) this can lead to serialization errors. In those situations you |
12 | //! may use the `tables_last` function in this module like so: |
13 | //! |
14 | //! ```rust |
15 | //! # use serde_derive::Serialize; |
16 | //! # use std::collections::HashMap; |
17 | //! #[derive(Serialize)] |
18 | //! struct Manifest { |
19 | //! package: Package, |
20 | //! #[serde(serialize_with = "toml::ser::tables_last" )] |
21 | //! dependencies: HashMap<String, Dependency>, |
22 | //! } |
23 | //! # type Package = String; |
24 | //! # type Dependency = String; |
25 | //! # fn main() {} |
26 | //! ``` |
27 | |
28 | use std::cell::Cell; |
29 | use std::error; |
30 | use std::fmt::{self, Write}; |
31 | use std::marker; |
32 | use std::rc::Rc; |
33 | |
34 | use crate::datetime; |
35 | use serde::ser; |
36 | |
37 | /// Serialize the given data structure as a TOML byte vector. |
38 | /// |
39 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to |
40 | /// fail, if `T` contains a map with non-string keys, or if `T` attempts to |
41 | /// serialize an unsupported datatype such as an enum, tuple, or tuple struct. |
42 | pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>, Error> |
43 | where |
44 | T: ser::Serialize, |
45 | { |
46 | to_string(value).map(|e: String| e.into_bytes()) |
47 | } |
48 | |
49 | /// Serialize the given data structure as a String of TOML. |
50 | /// |
51 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to |
52 | /// fail, if `T` contains a map with non-string keys, or if `T` attempts to |
53 | /// serialize an unsupported datatype such as an enum, tuple, or tuple struct. |
54 | /// |
55 | /// # Examples |
56 | /// |
57 | /// ``` |
58 | /// use serde_derive::Serialize; |
59 | /// |
60 | /// #[derive(Serialize)] |
61 | /// struct Config { |
62 | /// database: Database, |
63 | /// } |
64 | /// |
65 | /// #[derive(Serialize)] |
66 | /// struct Database { |
67 | /// ip: String, |
68 | /// port: Vec<u16>, |
69 | /// connection_max: u32, |
70 | /// enabled: bool, |
71 | /// } |
72 | /// |
73 | /// let config = Config { |
74 | /// database: Database { |
75 | /// ip: "192.168.1.1" .to_string(), |
76 | /// port: vec![8001, 8002, 8003], |
77 | /// connection_max: 5000, |
78 | /// enabled: false, |
79 | /// }, |
80 | /// }; |
81 | /// |
82 | /// let toml = toml::to_string(&config).unwrap(); |
83 | /// println!("{}" , toml) |
84 | /// ``` |
85 | pub fn to_string<T: ?Sized>(value: &T) -> Result<String, Error> |
86 | where |
87 | T: ser::Serialize, |
88 | { |
89 | let mut dst: String = String::with_capacity(128); |
90 | value.serialize(&mut Serializer::new(&mut dst))?; |
91 | Ok(dst) |
92 | } |
93 | |
94 | /// Serialize the given data structure as a "pretty" String of TOML. |
95 | /// |
96 | /// This is identical to `to_string` except the output string has a more |
97 | /// "pretty" output. See `Serializer::pretty` for more details. |
98 | pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String, Error> |
99 | where |
100 | T: ser::Serialize, |
101 | { |
102 | let mut dst: String = String::with_capacity(128); |
103 | value.serialize(&mut Serializer::pretty(&mut dst))?; |
104 | Ok(dst) |
105 | } |
106 | |
107 | /// Errors that can occur when serializing a type. |
108 | #[derive (Debug, PartialEq, Eq, Clone)] |
109 | #[non_exhaustive ] |
110 | pub enum Error { |
111 | /// Indicates that a Rust type was requested to be serialized but it was not |
112 | /// supported. |
113 | /// |
114 | /// Currently the TOML format does not support serializing types such as |
115 | /// enums, tuples and tuple structs. |
116 | UnsupportedType, |
117 | |
118 | /// The key of all TOML maps must be strings, but serialization was |
119 | /// attempted where the key of a map was not a string. |
120 | KeyNotString, |
121 | |
122 | /// An error that we never omit but keep for backwards compatibility |
123 | #[doc (hidden)] |
124 | KeyNewline, |
125 | |
126 | /// An array had to be homogeneous, but now it is allowed to be heterogeneous. |
127 | #[doc (hidden)] |
128 | ArrayMixedType, |
129 | |
130 | /// All values in a TOML table must be emitted before further tables are |
131 | /// emitted. If a value is emitted *after* a table then this error is |
132 | /// generated. |
133 | ValueAfterTable, |
134 | |
135 | /// A serialized date was invalid. |
136 | DateInvalid, |
137 | |
138 | /// A serialized number was invalid. |
139 | NumberInvalid, |
140 | |
141 | /// None was attempted to be serialized, but it's not supported. |
142 | UnsupportedNone, |
143 | |
144 | /// A custom error which could be generated when serializing a particular |
145 | /// type. |
146 | Custom(String), |
147 | } |
148 | |
149 | #[derive (Debug, Default, Clone)] |
150 | /// Internal place for holding array settings |
151 | struct ArraySettings { |
152 | indent: usize, |
153 | trailing_comma: bool, |
154 | } |
155 | |
156 | impl ArraySettings { |
157 | fn pretty() -> ArraySettings { |
158 | ArraySettings { |
159 | indent: 4, |
160 | trailing_comma: true, |
161 | } |
162 | } |
163 | } |
164 | |
165 | #[derive (Debug, Default, Clone)] |
166 | /// String settings |
167 | struct StringSettings { |
168 | /// Whether to use literal strings when possible |
169 | literal: bool, |
170 | } |
171 | |
172 | impl StringSettings { |
173 | fn pretty() -> StringSettings { |
174 | StringSettings { literal: true } |
175 | } |
176 | } |
177 | |
178 | #[derive (Debug, Default, Clone)] |
179 | /// Internal struct for holding serialization settings |
180 | struct Settings { |
181 | array: Option<ArraySettings>, |
182 | string: Option<StringSettings>, |
183 | } |
184 | |
185 | /// Serialization implementation for TOML. |
186 | /// |
187 | /// This structure implements serialization support for TOML to serialize an |
188 | /// arbitrary type to TOML. Note that the TOML format does not support all |
189 | /// datatypes in Rust, such as enums, tuples, and tuple structs. These types |
190 | /// will generate an error when serialized. |
191 | /// |
192 | /// Currently a serializer always writes its output to an in-memory `String`, |
193 | /// which is passed in when creating the serializer itself. |
194 | pub struct Serializer<'a> { |
195 | dst: &'a mut String, |
196 | state: State<'a>, |
197 | settings: Rc<Settings>, |
198 | } |
199 | |
200 | #[derive (Debug, Copy, Clone)] |
201 | enum ArrayState { |
202 | Started, |
203 | StartedAsATable, |
204 | } |
205 | |
206 | #[derive (Debug, Clone)] |
207 | enum State<'a> { |
208 | Table { |
209 | key: &'a str, |
210 | parent: &'a State<'a>, |
211 | first: &'a Cell<bool>, |
212 | table_emitted: &'a Cell<bool>, |
213 | }, |
214 | Array { |
215 | parent: &'a State<'a>, |
216 | first: &'a Cell<bool>, |
217 | type_: &'a Cell<Option<ArrayState>>, |
218 | len: Option<usize>, |
219 | }, |
220 | End, |
221 | } |
222 | |
223 | #[doc (hidden)] |
224 | pub struct SerializeSeq<'a, 'b> { |
225 | ser: &'b mut Serializer<'a>, |
226 | first: Cell<bool>, |
227 | type_: Cell<Option<ArrayState>>, |
228 | len: Option<usize>, |
229 | } |
230 | |
231 | #[doc (hidden)] |
232 | pub enum SerializeTable<'a, 'b> { |
233 | Datetime(&'b mut Serializer<'a>), |
234 | Table { |
235 | ser: &'b mut Serializer<'a>, |
236 | key: String, |
237 | first: Cell<bool>, |
238 | table_emitted: Cell<bool>, |
239 | }, |
240 | } |
241 | |
242 | impl<'a> Serializer<'a> { |
243 | /// Creates a new serializer which will emit TOML into the buffer provided. |
244 | /// |
245 | /// The serializer can then be used to serialize a type after which the data |
246 | /// will be present in `dst`. |
247 | pub fn new(dst: &'a mut String) -> Serializer<'a> { |
248 | Serializer { |
249 | dst, |
250 | state: State::End, |
251 | settings: Rc::new(Settings::default()), |
252 | } |
253 | } |
254 | |
255 | /// Instantiate a "pretty" formatter |
256 | /// |
257 | /// By default this will use: |
258 | /// |
259 | /// - pretty strings: strings with newlines will use the `'''` syntax. See |
260 | /// `Serializer::pretty_string` |
261 | /// - pretty arrays: each item in arrays will be on a newline, have an indentation of 4 and |
262 | /// have a trailing comma. See `Serializer::pretty_array` |
263 | pub fn pretty(dst: &'a mut String) -> Serializer<'a> { |
264 | Serializer { |
265 | dst, |
266 | state: State::End, |
267 | settings: Rc::new(Settings { |
268 | array: Some(ArraySettings::pretty()), |
269 | string: Some(StringSettings::pretty()), |
270 | }), |
271 | } |
272 | } |
273 | |
274 | /// Enable or Disable pretty strings |
275 | /// |
276 | /// If enabled, literal strings will be used when possible and strings with |
277 | /// one or more newlines will use triple quotes (i.e.: `'''` or `"""`) |
278 | /// |
279 | /// # Examples |
280 | /// |
281 | /// Instead of: |
282 | /// |
283 | /// ```toml,ignore |
284 | /// single = "no newlines" |
285 | /// text = "\nfoo\nbar\n" |
286 | /// ``` |
287 | /// |
288 | /// You will have: |
289 | /// |
290 | /// ```toml,ignore |
291 | /// single = 'no newlines' |
292 | /// text = ''' |
293 | /// foo |
294 | /// bar |
295 | /// ''' |
296 | /// ``` |
297 | pub fn pretty_string(&mut self, value: bool) -> &mut Self { |
298 | Rc::get_mut(&mut self.settings).unwrap().string = if value { |
299 | Some(StringSettings::pretty()) |
300 | } else { |
301 | None |
302 | }; |
303 | self |
304 | } |
305 | |
306 | /// Enable or Disable Literal strings for pretty strings |
307 | /// |
308 | /// If enabled, literal strings will be used when possible and strings with |
309 | /// one or more newlines will use triple quotes (i.e.: `'''` or `"""`) |
310 | /// |
311 | /// If disabled, literal strings will NEVER be used and strings with one or |
312 | /// more newlines will use `"""` |
313 | /// |
314 | /// # Examples |
315 | /// |
316 | /// Instead of: |
317 | /// |
318 | /// ```toml,ignore |
319 | /// single = "no newlines" |
320 | /// text = "\nfoo\nbar\n" |
321 | /// ``` |
322 | /// |
323 | /// You will have: |
324 | /// |
325 | /// ```toml,ignore |
326 | /// single = "no newlines" |
327 | /// text = """ |
328 | /// foo |
329 | /// bar |
330 | /// """ |
331 | /// ``` |
332 | pub fn pretty_string_literal(&mut self, value: bool) -> &mut Self { |
333 | let use_default = if let Some(ref mut s) = Rc::get_mut(&mut self.settings).unwrap().string { |
334 | s.literal = value; |
335 | false |
336 | } else { |
337 | true |
338 | }; |
339 | |
340 | if use_default { |
341 | let mut string = StringSettings::pretty(); |
342 | string.literal = value; |
343 | Rc::get_mut(&mut self.settings).unwrap().string = Some(string); |
344 | } |
345 | self |
346 | } |
347 | |
348 | /// Enable or Disable pretty arrays |
349 | /// |
350 | /// If enabled, arrays will always have each item on their own line. |
351 | /// |
352 | /// Some specific features can be controlled via other builder methods: |
353 | /// |
354 | /// - `Serializer::pretty_array_indent`: set the indent to a value other |
355 | /// than 4. |
356 | /// - `Serializer::pretty_array_trailing_comma`: enable/disable the trailing |
357 | /// comma on the last item. |
358 | /// |
359 | /// # Examples |
360 | /// |
361 | /// Instead of: |
362 | /// |
363 | /// ```toml,ignore |
364 | /// array = ["foo", "bar"] |
365 | /// ``` |
366 | /// |
367 | /// You will have: |
368 | /// |
369 | /// ```toml,ignore |
370 | /// array = [ |
371 | /// "foo", |
372 | /// "bar", |
373 | /// ] |
374 | /// ``` |
375 | pub fn pretty_array(&mut self, value: bool) -> &mut Self { |
376 | Rc::get_mut(&mut self.settings).unwrap().array = if value { |
377 | Some(ArraySettings::pretty()) |
378 | } else { |
379 | None |
380 | }; |
381 | self |
382 | } |
383 | |
384 | /// Set the indent for pretty arrays |
385 | /// |
386 | /// See `Serializer::pretty_array` for more details. |
387 | pub fn pretty_array_indent(&mut self, value: usize) -> &mut Self { |
388 | let use_default = if let Some(ref mut a) = Rc::get_mut(&mut self.settings).unwrap().array { |
389 | a.indent = value; |
390 | false |
391 | } else { |
392 | true |
393 | }; |
394 | |
395 | if use_default { |
396 | let mut array = ArraySettings::pretty(); |
397 | array.indent = value; |
398 | Rc::get_mut(&mut self.settings).unwrap().array = Some(array); |
399 | } |
400 | self |
401 | } |
402 | |
403 | /// Specify whether to use a trailing comma when serializing pretty arrays |
404 | /// |
405 | /// See `Serializer::pretty_array` for more details. |
406 | pub fn pretty_array_trailing_comma(&mut self, value: bool) -> &mut Self { |
407 | let use_default = if let Some(ref mut a) = Rc::get_mut(&mut self.settings).unwrap().array { |
408 | a.trailing_comma = value; |
409 | false |
410 | } else { |
411 | true |
412 | }; |
413 | |
414 | if use_default { |
415 | let mut array = ArraySettings::pretty(); |
416 | array.trailing_comma = value; |
417 | Rc::get_mut(&mut self.settings).unwrap().array = Some(array); |
418 | } |
419 | self |
420 | } |
421 | |
422 | fn display<T: fmt::Display>(&mut self, t: T, type_: ArrayState) -> Result<(), Error> { |
423 | self.emit_key(type_)?; |
424 | write!(self.dst, " {}" , t).map_err(ser::Error::custom)?; |
425 | if let State::Table { .. } = self.state { |
426 | self.dst.push(' \n' ); |
427 | } |
428 | Ok(()) |
429 | } |
430 | |
431 | fn emit_key(&mut self, type_: ArrayState) -> Result<(), Error> { |
432 | self.array_type(type_)?; |
433 | let state = self.state.clone(); |
434 | self._emit_key(&state) |
435 | } |
436 | |
437 | // recursive implementation of `emit_key` above |
438 | fn _emit_key(&mut self, state: &State<'_>) -> Result<(), Error> { |
439 | match *state { |
440 | State::End => Ok(()), |
441 | State::Array { |
442 | parent, |
443 | first, |
444 | type_, |
445 | len, |
446 | } => { |
447 | assert!(type_.get().is_some()); |
448 | if first.get() { |
449 | self._emit_key(parent)?; |
450 | } |
451 | self.emit_array(first, len) |
452 | } |
453 | State::Table { |
454 | parent, |
455 | first, |
456 | table_emitted, |
457 | key, |
458 | } => { |
459 | if table_emitted.get() { |
460 | return Err(Error::ValueAfterTable); |
461 | } |
462 | if first.get() { |
463 | self.emit_table_header(parent)?; |
464 | first.set(false); |
465 | } |
466 | self.escape_key(key)?; |
467 | self.dst.push_str(" = " ); |
468 | Ok(()) |
469 | } |
470 | } |
471 | } |
472 | |
473 | fn emit_array(&mut self, first: &Cell<bool>, len: Option<usize>) -> Result<(), Error> { |
474 | match (len, &self.settings.array) { |
475 | (Some(0..=1), _) | (_, &None) => { |
476 | if first.get() { |
477 | self.dst.push('[' ) |
478 | } else { |
479 | self.dst.push_str(", " ) |
480 | } |
481 | } |
482 | (_, &Some(ref a)) => { |
483 | if first.get() { |
484 | self.dst.push_str("[ \n" ) |
485 | } else { |
486 | self.dst.push_str(", \n" ) |
487 | } |
488 | for _ in 0..a.indent { |
489 | self.dst.push(' ' ); |
490 | } |
491 | } |
492 | } |
493 | Ok(()) |
494 | } |
495 | |
496 | fn array_type(&mut self, type_: ArrayState) -> Result<(), Error> { |
497 | let prev = match self.state { |
498 | State::Array { type_, .. } => type_, |
499 | _ => return Ok(()), |
500 | }; |
501 | if prev.get().is_none() { |
502 | prev.set(Some(type_)); |
503 | } |
504 | Ok(()) |
505 | } |
506 | |
507 | fn escape_key(&mut self, key: &str) -> Result<(), Error> { |
508 | let ok = !key.is_empty() |
509 | && key |
510 | .chars() |
511 | .all(|c| matches!(c,'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '-' | '_' )); |
512 | if ok { |
513 | write!(self.dst, " {}" , key).map_err(ser::Error::custom)?; |
514 | } else { |
515 | self.emit_str(key, true)?; |
516 | } |
517 | Ok(()) |
518 | } |
519 | |
520 | fn emit_str(&mut self, value: &str, is_key: bool) -> Result<(), Error> { |
521 | #[derive (PartialEq)] |
522 | enum Type { |
523 | NewlineTripple, |
524 | OnelineTripple, |
525 | OnelineSingle, |
526 | } |
527 | |
528 | enum Repr { |
529 | /// represent as a literal string (using '') |
530 | Literal(String, Type), |
531 | /// represent the std way (using "") |
532 | Std(Type), |
533 | } |
534 | |
535 | fn do_pretty(value: &str) -> Repr { |
536 | // For doing pretty prints we store in a new String |
537 | // because there are too many cases where pretty cannot |
538 | // work. We need to determine: |
539 | // - if we are a "multi-line" pretty (if there are \n) |
540 | // - if ['''] appears if multi or ['] if single |
541 | // - if there are any invalid control characters |
542 | // |
543 | // Doing it any other way would require multiple passes |
544 | // to determine if a pretty string works or not. |
545 | let mut out = String::with_capacity(value.len() * 2); |
546 | let mut ty = Type::OnelineSingle; |
547 | // found consecutive single quotes |
548 | let mut max_found_singles = 0; |
549 | let mut found_singles = 0; |
550 | let mut can_be_pretty = true; |
551 | |
552 | for ch in value.chars() { |
553 | if can_be_pretty { |
554 | if ch == ' \'' { |
555 | found_singles += 1; |
556 | if found_singles >= 3 { |
557 | can_be_pretty = false; |
558 | } |
559 | } else { |
560 | if found_singles > max_found_singles { |
561 | max_found_singles = found_singles; |
562 | } |
563 | found_singles = 0 |
564 | } |
565 | match ch { |
566 | ' \t' => {} |
567 | ' \n' => ty = Type::NewlineTripple, |
568 | // Escape codes are needed if any ascii control |
569 | // characters are present, including \b \f \r. |
570 | c if c <= ' \u{1f}' || c == ' \u{7f}' => can_be_pretty = false, |
571 | _ => {} |
572 | } |
573 | out.push(ch); |
574 | } else { |
575 | // the string cannot be represented as pretty, |
576 | // still check if it should be multiline |
577 | if ch == ' \n' { |
578 | ty = Type::NewlineTripple; |
579 | } |
580 | } |
581 | } |
582 | if can_be_pretty && found_singles > 0 && value.ends_with(' \'' ) { |
583 | // We cannot escape the ending quote so we must use """ |
584 | can_be_pretty = false; |
585 | } |
586 | if !can_be_pretty { |
587 | debug_assert!(ty != Type::OnelineTripple); |
588 | return Repr::Std(ty); |
589 | } |
590 | if found_singles > max_found_singles { |
591 | max_found_singles = found_singles; |
592 | } |
593 | debug_assert!(max_found_singles < 3); |
594 | if ty == Type::OnelineSingle && max_found_singles >= 1 { |
595 | // no newlines, but must use ''' because it has ' in it |
596 | ty = Type::OnelineTripple; |
597 | } |
598 | Repr::Literal(out, ty) |
599 | } |
600 | |
601 | let repr = if !is_key && self.settings.string.is_some() { |
602 | match (&self.settings.string, do_pretty(value)) { |
603 | (&Some(StringSettings { literal: false, .. }), Repr::Literal(_, ty)) => { |
604 | Repr::Std(ty) |
605 | } |
606 | (_, r) => r, |
607 | } |
608 | } else { |
609 | Repr::Std(Type::OnelineSingle) |
610 | }; |
611 | match repr { |
612 | Repr::Literal(literal, ty) => { |
613 | // A pretty string |
614 | match ty { |
615 | Type::NewlineTripple => self.dst.push_str("''' \n" ), |
616 | Type::OnelineTripple => self.dst.push_str("'''" ), |
617 | Type::OnelineSingle => self.dst.push(' \'' ), |
618 | } |
619 | self.dst.push_str(&literal); |
620 | match ty { |
621 | Type::OnelineSingle => self.dst.push(' \'' ), |
622 | _ => self.dst.push_str("'''" ), |
623 | } |
624 | } |
625 | Repr::Std(ty) => { |
626 | match ty { |
627 | Type::NewlineTripple => self.dst.push_str(" \"\"\"\n" ), |
628 | // note: OnelineTripple can happen if do_pretty wants to do |
629 | // '''it's one line''' |
630 | // but settings.string.literal == false |
631 | Type::OnelineSingle | Type::OnelineTripple => self.dst.push('"' ), |
632 | } |
633 | for ch in value.chars() { |
634 | match ch { |
635 | ' \u{8}' => self.dst.push_str(" \\b" ), |
636 | ' \u{9}' => self.dst.push_str(" \\t" ), |
637 | ' \u{a}' => match ty { |
638 | Type::NewlineTripple => self.dst.push(' \n' ), |
639 | Type::OnelineSingle => self.dst.push_str(" \\n" ), |
640 | _ => unreachable!(), |
641 | }, |
642 | ' \u{c}' => self.dst.push_str(" \\f" ), |
643 | ' \u{d}' => self.dst.push_str(" \\r" ), |
644 | ' \u{22}' => self.dst.push_str(" \\\"" ), |
645 | ' \u{5c}' => self.dst.push_str(" \\\\" ), |
646 | c if c <= ' \u{1f}' || c == ' \u{7f}' => { |
647 | write!(self.dst, " \\u {:04X}" , ch as u32).map_err(ser::Error::custom)?; |
648 | } |
649 | ch => self.dst.push(ch), |
650 | } |
651 | } |
652 | match ty { |
653 | Type::NewlineTripple => self.dst.push_str(" \"\"\"" ), |
654 | Type::OnelineSingle | Type::OnelineTripple => self.dst.push('"' ), |
655 | } |
656 | } |
657 | } |
658 | Ok(()) |
659 | } |
660 | |
661 | fn emit_table_header(&mut self, state: &State<'_>) -> Result<(), Error> { |
662 | let array_of_tables = match *state { |
663 | State::End => return Ok(()), |
664 | State::Array { .. } => true, |
665 | _ => false, |
666 | }; |
667 | |
668 | // Unlike [..]s, we can't omit [[..]] ancestors, so be sure to emit table |
669 | // headers for them. |
670 | let mut p = state; |
671 | if let State::Array { first, parent, .. } = *state { |
672 | if first.get() { |
673 | p = parent; |
674 | } |
675 | } |
676 | while let State::Table { first, parent, .. } = *p { |
677 | p = parent; |
678 | if !first.get() { |
679 | break; |
680 | } |
681 | if let State::Array { |
682 | parent: &State::Table { .. }, |
683 | .. |
684 | } = *parent |
685 | { |
686 | self.emit_table_header(parent)?; |
687 | break; |
688 | } |
689 | } |
690 | |
691 | match *state { |
692 | State::Table { first, .. } => { |
693 | if !first.get() { |
694 | // Newline if we are a table that is not the first |
695 | // table in the document. |
696 | self.dst.push(' \n' ); |
697 | } |
698 | } |
699 | State::Array { parent, first, .. } => { |
700 | if !first.get() { |
701 | // Always newline if we are not the first item in the |
702 | // table-array |
703 | self.dst.push(' \n' ); |
704 | } else if let State::Table { first, .. } = *parent { |
705 | if !first.get() { |
706 | // Newline if we are not the first item in the document |
707 | self.dst.push(' \n' ); |
708 | } |
709 | } |
710 | } |
711 | _ => {} |
712 | } |
713 | self.dst.push('[' ); |
714 | if array_of_tables { |
715 | self.dst.push('[' ); |
716 | } |
717 | self.emit_key_part(state)?; |
718 | if array_of_tables { |
719 | self.dst.push(']' ); |
720 | } |
721 | self.dst.push_str("] \n" ); |
722 | Ok(()) |
723 | } |
724 | |
725 | fn emit_key_part(&mut self, key: &State<'_>) -> Result<bool, Error> { |
726 | match *key { |
727 | State::Array { parent, .. } => self.emit_key_part(parent), |
728 | State::End => Ok(true), |
729 | State::Table { |
730 | key, |
731 | parent, |
732 | table_emitted, |
733 | .. |
734 | } => { |
735 | table_emitted.set(true); |
736 | let first = self.emit_key_part(parent)?; |
737 | if !first { |
738 | self.dst.push('.' ); |
739 | } |
740 | self.escape_key(key)?; |
741 | Ok(false) |
742 | } |
743 | } |
744 | } |
745 | } |
746 | |
747 | macro_rules! serialize_float { |
748 | ($this:expr, $v:expr) => {{ |
749 | $this.emit_key(ArrayState::Started)?; |
750 | match ($v.is_sign_negative(), $v.is_nan(), $v == 0.0) { |
751 | (true, true, _) => write!($this.dst, "-nan" ), |
752 | (false, true, _) => write!($this.dst, "nan" ), |
753 | (true, false, true) => write!($this.dst, "-0.0" ), |
754 | (false, false, true) => write!($this.dst, "0.0" ), |
755 | (_, false, false) => write!($this.dst, "{}" , $v).and_then(|_| { |
756 | if $v % 1.0 == 0.0 { |
757 | write!($this.dst, ".0" ) |
758 | } else { |
759 | Ok(()) |
760 | } |
761 | }), |
762 | } |
763 | .map_err(ser::Error::custom)?; |
764 | |
765 | if let State::Table { .. } = $this.state { |
766 | $this.dst.push_str(" \n" ); |
767 | } |
768 | return Ok(()); |
769 | }}; |
770 | } |
771 | |
772 | impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> { |
773 | type Ok = (); |
774 | type Error = Error; |
775 | type SerializeSeq = SerializeSeq<'a, 'b>; |
776 | type SerializeTuple = SerializeSeq<'a, 'b>; |
777 | type SerializeTupleStruct = SerializeSeq<'a, 'b>; |
778 | type SerializeTupleVariant = SerializeSeq<'a, 'b>; |
779 | type SerializeMap = SerializeTable<'a, 'b>; |
780 | type SerializeStruct = SerializeTable<'a, 'b>; |
781 | type SerializeStructVariant = ser::Impossible<(), Error>; |
782 | |
783 | fn serialize_bool(self, v: bool) -> Result<(), Self::Error> { |
784 | self.display(v, ArrayState::Started) |
785 | } |
786 | |
787 | fn serialize_i8(self, v: i8) -> Result<(), Self::Error> { |
788 | self.display(v, ArrayState::Started) |
789 | } |
790 | |
791 | fn serialize_i16(self, v: i16) -> Result<(), Self::Error> { |
792 | self.display(v, ArrayState::Started) |
793 | } |
794 | |
795 | fn serialize_i32(self, v: i32) -> Result<(), Self::Error> { |
796 | self.display(v, ArrayState::Started) |
797 | } |
798 | |
799 | fn serialize_i64(self, v: i64) -> Result<(), Self::Error> { |
800 | self.display(v, ArrayState::Started) |
801 | } |
802 | |
803 | fn serialize_u8(self, v: u8) -> Result<(), Self::Error> { |
804 | self.display(v, ArrayState::Started) |
805 | } |
806 | |
807 | fn serialize_u16(self, v: u16) -> Result<(), Self::Error> { |
808 | self.display(v, ArrayState::Started) |
809 | } |
810 | |
811 | fn serialize_u32(self, v: u32) -> Result<(), Self::Error> { |
812 | self.display(v, ArrayState::Started) |
813 | } |
814 | |
815 | fn serialize_u64(self, v: u64) -> Result<(), Self::Error> { |
816 | self.display(v, ArrayState::Started) |
817 | } |
818 | |
819 | fn serialize_f32(self, v: f32) -> Result<(), Self::Error> { |
820 | serialize_float!(self, v) |
821 | } |
822 | |
823 | fn serialize_f64(self, v: f64) -> Result<(), Self::Error> { |
824 | serialize_float!(self, v) |
825 | } |
826 | |
827 | fn serialize_char(self, v: char) -> Result<(), Self::Error> { |
828 | let mut buf = [0; 4]; |
829 | self.serialize_str(v.encode_utf8(&mut buf)) |
830 | } |
831 | |
832 | fn serialize_str(self, value: &str) -> Result<(), Self::Error> { |
833 | self.emit_key(ArrayState::Started)?; |
834 | self.emit_str(value, false)?; |
835 | if let State::Table { .. } = self.state { |
836 | self.dst.push(' \n' ); |
837 | } |
838 | Ok(()) |
839 | } |
840 | |
841 | fn serialize_bytes(self, value: &[u8]) -> Result<(), Self::Error> { |
842 | use serde::ser::Serialize; |
843 | value.serialize(self) |
844 | } |
845 | |
846 | fn serialize_none(self) -> Result<(), Self::Error> { |
847 | Err(Error::UnsupportedNone) |
848 | } |
849 | |
850 | fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Self::Error> |
851 | where |
852 | T: ser::Serialize, |
853 | { |
854 | value.serialize(self) |
855 | } |
856 | |
857 | fn serialize_unit(self) -> Result<(), Self::Error> { |
858 | Err(Error::UnsupportedType) |
859 | } |
860 | |
861 | fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> { |
862 | Err(Error::UnsupportedType) |
863 | } |
864 | |
865 | fn serialize_unit_variant( |
866 | self, |
867 | _name: &'static str, |
868 | _variant_index: u32, |
869 | variant: &'static str, |
870 | ) -> Result<(), Self::Error> { |
871 | self.serialize_str(variant) |
872 | } |
873 | |
874 | fn serialize_newtype_struct<T: ?Sized>( |
875 | self, |
876 | _name: &'static str, |
877 | value: &T, |
878 | ) -> Result<(), Self::Error> |
879 | where |
880 | T: ser::Serialize, |
881 | { |
882 | value.serialize(self) |
883 | } |
884 | |
885 | fn serialize_newtype_variant<T: ?Sized>( |
886 | self, |
887 | _name: &'static str, |
888 | _variant_index: u32, |
889 | _variant: &'static str, |
890 | _value: &T, |
891 | ) -> Result<(), Self::Error> |
892 | where |
893 | T: ser::Serialize, |
894 | { |
895 | Err(Error::UnsupportedType) |
896 | } |
897 | |
898 | fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { |
899 | self.array_type(ArrayState::Started)?; |
900 | Ok(SerializeSeq { |
901 | ser: self, |
902 | first: Cell::new(true), |
903 | type_: Cell::new(None), |
904 | len, |
905 | }) |
906 | } |
907 | |
908 | fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { |
909 | self.serialize_seq(Some(len)) |
910 | } |
911 | |
912 | fn serialize_tuple_struct( |
913 | self, |
914 | _name: &'static str, |
915 | len: usize, |
916 | ) -> Result<Self::SerializeTupleStruct, Self::Error> { |
917 | self.serialize_seq(Some(len)) |
918 | } |
919 | |
920 | fn serialize_tuple_variant( |
921 | self, |
922 | _name: &'static str, |
923 | _variant_index: u32, |
924 | _variant: &'static str, |
925 | len: usize, |
926 | ) -> Result<Self::SerializeTupleVariant, Self::Error> { |
927 | self.serialize_seq(Some(len)) |
928 | } |
929 | |
930 | fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { |
931 | self.array_type(ArrayState::StartedAsATable)?; |
932 | Ok(SerializeTable::Table { |
933 | ser: self, |
934 | key: String::new(), |
935 | first: Cell::new(true), |
936 | table_emitted: Cell::new(false), |
937 | }) |
938 | } |
939 | |
940 | fn serialize_struct( |
941 | self, |
942 | name: &'static str, |
943 | _len: usize, |
944 | ) -> Result<Self::SerializeStruct, Self::Error> { |
945 | if name == datetime::NAME { |
946 | self.array_type(ArrayState::Started)?; |
947 | Ok(SerializeTable::Datetime(self)) |
948 | } else { |
949 | self.array_type(ArrayState::StartedAsATable)?; |
950 | Ok(SerializeTable::Table { |
951 | ser: self, |
952 | key: String::new(), |
953 | first: Cell::new(true), |
954 | table_emitted: Cell::new(false), |
955 | }) |
956 | } |
957 | } |
958 | |
959 | fn serialize_struct_variant( |
960 | self, |
961 | _name: &'static str, |
962 | _variant_index: u32, |
963 | _variant: &'static str, |
964 | _len: usize, |
965 | ) -> Result<Self::SerializeStructVariant, Self::Error> { |
966 | Err(Error::UnsupportedType) |
967 | } |
968 | } |
969 | |
970 | impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> { |
971 | type Ok = (); |
972 | type Error = Error; |
973 | |
974 | fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> |
975 | where |
976 | T: ser::Serialize, |
977 | { |
978 | value.serialize(&mut Serializer { |
979 | dst: &mut *self.ser.dst, |
980 | state: State::Array { |
981 | parent: &self.ser.state, |
982 | first: &self.first, |
983 | type_: &self.type_, |
984 | len: self.len, |
985 | }, |
986 | settings: self.ser.settings.clone(), |
987 | })?; |
988 | self.first.set(false); |
989 | Ok(()) |
990 | } |
991 | |
992 | fn end(self) -> Result<(), Error> { |
993 | match self.type_.get() { |
994 | Some(ArrayState::StartedAsATable) => return Ok(()), |
995 | Some(ArrayState::Started) => match (self.len, &self.ser.settings.array) { |
996 | (Some(0..=1), _) | (_, &None) => { |
997 | self.ser.dst.push(']' ); |
998 | } |
999 | (_, &Some(ref a)) => { |
1000 | if a.trailing_comma { |
1001 | self.ser.dst.push(',' ); |
1002 | } |
1003 | self.ser.dst.push_str(" \n]" ); |
1004 | } |
1005 | }, |
1006 | None => { |
1007 | assert!(self.first.get()); |
1008 | self.ser.emit_key(ArrayState::Started)?; |
1009 | self.ser.dst.push_str("[]" ) |
1010 | } |
1011 | } |
1012 | if let State::Table { .. } = self.ser.state { |
1013 | self.ser.dst.push(' \n' ); |
1014 | } |
1015 | Ok(()) |
1016 | } |
1017 | } |
1018 | |
1019 | impl<'a, 'b> ser::SerializeTuple for SerializeSeq<'a, 'b> { |
1020 | type Ok = (); |
1021 | type Error = Error; |
1022 | |
1023 | fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> |
1024 | where |
1025 | T: ser::Serialize, |
1026 | { |
1027 | ser::SerializeSeq::serialize_element(self, value) |
1028 | } |
1029 | |
1030 | fn end(self) -> Result<(), Error> { |
1031 | ser::SerializeSeq::end(self) |
1032 | } |
1033 | } |
1034 | |
1035 | impl<'a, 'b> ser::SerializeTupleVariant for SerializeSeq<'a, 'b> { |
1036 | type Ok = (); |
1037 | type Error = Error; |
1038 | |
1039 | fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> |
1040 | where |
1041 | T: ser::Serialize, |
1042 | { |
1043 | ser::SerializeSeq::serialize_element(self, value) |
1044 | } |
1045 | |
1046 | fn end(self) -> Result<(), Error> { |
1047 | ser::SerializeSeq::end(self) |
1048 | } |
1049 | } |
1050 | |
1051 | impl<'a, 'b> ser::SerializeTupleStruct for SerializeSeq<'a, 'b> { |
1052 | type Ok = (); |
1053 | type Error = Error; |
1054 | |
1055 | fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> |
1056 | where |
1057 | T: ser::Serialize, |
1058 | { |
1059 | ser::SerializeSeq::serialize_element(self, value) |
1060 | } |
1061 | |
1062 | fn end(self) -> Result<(), Error> { |
1063 | ser::SerializeSeq::end(self) |
1064 | } |
1065 | } |
1066 | |
1067 | impl<'a, 'b> ser::SerializeMap for SerializeTable<'a, 'b> { |
1068 | type Ok = (); |
1069 | type Error = Error; |
1070 | |
1071 | fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Error> |
1072 | where |
1073 | T: ser::Serialize, |
1074 | { |
1075 | match *self { |
1076 | SerializeTable::Datetime(_) => panic!(), // shouldn't be possible |
1077 | SerializeTable::Table { ref mut key, .. } => { |
1078 | key.truncate(0); |
1079 | *key = input.serialize(StringExtractor)?; |
1080 | } |
1081 | } |
1082 | Ok(()) |
1083 | } |
1084 | |
1085 | fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> |
1086 | where |
1087 | T: ser::Serialize, |
1088 | { |
1089 | match *self { |
1090 | SerializeTable::Datetime(_) => panic!(), // shouldn't be possible |
1091 | SerializeTable::Table { |
1092 | ref mut ser, |
1093 | ref key, |
1094 | ref first, |
1095 | ref table_emitted, |
1096 | .. |
1097 | } => { |
1098 | let res = value.serialize(&mut Serializer { |
1099 | dst: &mut *ser.dst, |
1100 | state: State::Table { |
1101 | key, |
1102 | parent: &ser.state, |
1103 | first, |
1104 | table_emitted, |
1105 | }, |
1106 | settings: ser.settings.clone(), |
1107 | }); |
1108 | match res { |
1109 | Ok(()) => first.set(false), |
1110 | Err(Error::UnsupportedNone) => {} |
1111 | Err(e) => return Err(e), |
1112 | } |
1113 | } |
1114 | } |
1115 | Ok(()) |
1116 | } |
1117 | |
1118 | fn end(self) -> Result<(), Error> { |
1119 | match self { |
1120 | SerializeTable::Datetime(_) => panic!(), // shouldn't be possible |
1121 | SerializeTable::Table { ser, first, .. } => { |
1122 | if first.get() { |
1123 | let state = ser.state.clone(); |
1124 | ser.emit_table_header(&state)?; |
1125 | } |
1126 | } |
1127 | } |
1128 | Ok(()) |
1129 | } |
1130 | } |
1131 | |
1132 | impl<'a, 'b> ser::SerializeStruct for SerializeTable<'a, 'b> { |
1133 | type Ok = (); |
1134 | type Error = Error; |
1135 | |
1136 | fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> |
1137 | where |
1138 | T: ser::Serialize, |
1139 | { |
1140 | match *self { |
1141 | SerializeTable::Datetime(ref mut ser) => { |
1142 | if key == datetime::FIELD { |
1143 | value.serialize(DateStrEmitter(*ser))?; |
1144 | } else { |
1145 | return Err(Error::DateInvalid); |
1146 | } |
1147 | } |
1148 | SerializeTable::Table { |
1149 | ref mut ser, |
1150 | ref first, |
1151 | ref table_emitted, |
1152 | .. |
1153 | } => { |
1154 | let res = value.serialize(&mut Serializer { |
1155 | dst: &mut *ser.dst, |
1156 | state: State::Table { |
1157 | key, |
1158 | parent: &ser.state, |
1159 | first, |
1160 | table_emitted, |
1161 | }, |
1162 | settings: ser.settings.clone(), |
1163 | }); |
1164 | match res { |
1165 | Ok(()) => first.set(false), |
1166 | Err(Error::UnsupportedNone) => {} |
1167 | Err(e) => return Err(e), |
1168 | } |
1169 | } |
1170 | } |
1171 | Ok(()) |
1172 | } |
1173 | |
1174 | fn end(self) -> Result<(), Error> { |
1175 | match self { |
1176 | SerializeTable::Datetime(_) => {} |
1177 | SerializeTable::Table { ser, first, .. } => { |
1178 | if first.get() { |
1179 | let state = ser.state.clone(); |
1180 | ser.emit_table_header(&state)?; |
1181 | } |
1182 | } |
1183 | } |
1184 | Ok(()) |
1185 | } |
1186 | } |
1187 | |
1188 | struct DateStrEmitter<'a, 'b>(&'b mut Serializer<'a>); |
1189 | |
1190 | impl<'a, 'b> ser::Serializer for DateStrEmitter<'a, 'b> { |
1191 | type Ok = (); |
1192 | type Error = Error; |
1193 | type SerializeSeq = ser::Impossible<(), Error>; |
1194 | type SerializeTuple = ser::Impossible<(), Error>; |
1195 | type SerializeTupleStruct = ser::Impossible<(), Error>; |
1196 | type SerializeTupleVariant = ser::Impossible<(), Error>; |
1197 | type SerializeMap = ser::Impossible<(), Error>; |
1198 | type SerializeStruct = ser::Impossible<(), Error>; |
1199 | type SerializeStructVariant = ser::Impossible<(), Error>; |
1200 | |
1201 | fn serialize_bool(self, _v: bool) -> Result<(), Self::Error> { |
1202 | Err(Error::DateInvalid) |
1203 | } |
1204 | |
1205 | fn serialize_i8(self, _v: i8) -> Result<(), Self::Error> { |
1206 | Err(Error::DateInvalid) |
1207 | } |
1208 | |
1209 | fn serialize_i16(self, _v: i16) -> Result<(), Self::Error> { |
1210 | Err(Error::DateInvalid) |
1211 | } |
1212 | |
1213 | fn serialize_i32(self, _v: i32) -> Result<(), Self::Error> { |
1214 | Err(Error::DateInvalid) |
1215 | } |
1216 | |
1217 | fn serialize_i64(self, _v: i64) -> Result<(), Self::Error> { |
1218 | Err(Error::DateInvalid) |
1219 | } |
1220 | |
1221 | fn serialize_u8(self, _v: u8) -> Result<(), Self::Error> { |
1222 | Err(Error::DateInvalid) |
1223 | } |
1224 | |
1225 | fn serialize_u16(self, _v: u16) -> Result<(), Self::Error> { |
1226 | Err(Error::DateInvalid) |
1227 | } |
1228 | |
1229 | fn serialize_u32(self, _v: u32) -> Result<(), Self::Error> { |
1230 | Err(Error::DateInvalid) |
1231 | } |
1232 | |
1233 | fn serialize_u64(self, _v: u64) -> Result<(), Self::Error> { |
1234 | Err(Error::DateInvalid) |
1235 | } |
1236 | |
1237 | fn serialize_f32(self, _v: f32) -> Result<(), Self::Error> { |
1238 | Err(Error::DateInvalid) |
1239 | } |
1240 | |
1241 | fn serialize_f64(self, _v: f64) -> Result<(), Self::Error> { |
1242 | Err(Error::DateInvalid) |
1243 | } |
1244 | |
1245 | fn serialize_char(self, _v: char) -> Result<(), Self::Error> { |
1246 | Err(Error::DateInvalid) |
1247 | } |
1248 | |
1249 | fn serialize_str(self, value: &str) -> Result<(), Self::Error> { |
1250 | self.0.display(value, ArrayState::Started)?; |
1251 | Ok(()) |
1252 | } |
1253 | |
1254 | fn serialize_bytes(self, _value: &[u8]) -> Result<(), Self::Error> { |
1255 | Err(Error::DateInvalid) |
1256 | } |
1257 | |
1258 | fn serialize_none(self) -> Result<(), Self::Error> { |
1259 | Err(Error::DateInvalid) |
1260 | } |
1261 | |
1262 | fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<(), Self::Error> |
1263 | where |
1264 | T: ser::Serialize, |
1265 | { |
1266 | Err(Error::DateInvalid) |
1267 | } |
1268 | |
1269 | fn serialize_unit(self) -> Result<(), Self::Error> { |
1270 | Err(Error::DateInvalid) |
1271 | } |
1272 | |
1273 | fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> { |
1274 | Err(Error::DateInvalid) |
1275 | } |
1276 | |
1277 | fn serialize_unit_variant( |
1278 | self, |
1279 | _name: &'static str, |
1280 | _variant_index: u32, |
1281 | _variant: &'static str, |
1282 | ) -> Result<(), Self::Error> { |
1283 | Err(Error::DateInvalid) |
1284 | } |
1285 | |
1286 | fn serialize_newtype_struct<T: ?Sized>( |
1287 | self, |
1288 | _name: &'static str, |
1289 | _value: &T, |
1290 | ) -> Result<(), Self::Error> |
1291 | where |
1292 | T: ser::Serialize, |
1293 | { |
1294 | Err(Error::DateInvalid) |
1295 | } |
1296 | |
1297 | fn serialize_newtype_variant<T: ?Sized>( |
1298 | self, |
1299 | _name: &'static str, |
1300 | _variant_index: u32, |
1301 | _variant: &'static str, |
1302 | _value: &T, |
1303 | ) -> Result<(), Self::Error> |
1304 | where |
1305 | T: ser::Serialize, |
1306 | { |
1307 | Err(Error::DateInvalid) |
1308 | } |
1309 | |
1310 | fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { |
1311 | Err(Error::DateInvalid) |
1312 | } |
1313 | |
1314 | fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { |
1315 | Err(Error::DateInvalid) |
1316 | } |
1317 | |
1318 | fn serialize_tuple_struct( |
1319 | self, |
1320 | _name: &'static str, |
1321 | _len: usize, |
1322 | ) -> Result<Self::SerializeTupleStruct, Self::Error> { |
1323 | Err(Error::DateInvalid) |
1324 | } |
1325 | |
1326 | fn serialize_tuple_variant( |
1327 | self, |
1328 | _name: &'static str, |
1329 | _variant_index: u32, |
1330 | _variant: &'static str, |
1331 | _len: usize, |
1332 | ) -> Result<Self::SerializeTupleVariant, Self::Error> { |
1333 | Err(Error::DateInvalid) |
1334 | } |
1335 | |
1336 | fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { |
1337 | Err(Error::DateInvalid) |
1338 | } |
1339 | |
1340 | fn serialize_struct( |
1341 | self, |
1342 | _name: &'static str, |
1343 | _len: usize, |
1344 | ) -> Result<Self::SerializeStruct, Self::Error> { |
1345 | Err(Error::DateInvalid) |
1346 | } |
1347 | |
1348 | fn serialize_struct_variant( |
1349 | self, |
1350 | _name: &'static str, |
1351 | _variant_index: u32, |
1352 | _variant: &'static str, |
1353 | _len: usize, |
1354 | ) -> Result<Self::SerializeStructVariant, Self::Error> { |
1355 | Err(Error::DateInvalid) |
1356 | } |
1357 | } |
1358 | |
1359 | struct StringExtractor; |
1360 | |
1361 | impl ser::Serializer for StringExtractor { |
1362 | type Ok = String; |
1363 | type Error = Error; |
1364 | type SerializeSeq = ser::Impossible<String, Error>; |
1365 | type SerializeTuple = ser::Impossible<String, Error>; |
1366 | type SerializeTupleStruct = ser::Impossible<String, Error>; |
1367 | type SerializeTupleVariant = ser::Impossible<String, Error>; |
1368 | type SerializeMap = ser::Impossible<String, Error>; |
1369 | type SerializeStruct = ser::Impossible<String, Error>; |
1370 | type SerializeStructVariant = ser::Impossible<String, Error>; |
1371 | |
1372 | fn serialize_bool(self, _v: bool) -> Result<String, Self::Error> { |
1373 | Err(Error::KeyNotString) |
1374 | } |
1375 | |
1376 | fn serialize_i8(self, _v: i8) -> Result<String, Self::Error> { |
1377 | Err(Error::KeyNotString) |
1378 | } |
1379 | |
1380 | fn serialize_i16(self, _v: i16) -> Result<String, Self::Error> { |
1381 | Err(Error::KeyNotString) |
1382 | } |
1383 | |
1384 | fn serialize_i32(self, _v: i32) -> Result<String, Self::Error> { |
1385 | Err(Error::KeyNotString) |
1386 | } |
1387 | |
1388 | fn serialize_i64(self, _v: i64) -> Result<String, Self::Error> { |
1389 | Err(Error::KeyNotString) |
1390 | } |
1391 | |
1392 | fn serialize_u8(self, _v: u8) -> Result<String, Self::Error> { |
1393 | Err(Error::KeyNotString) |
1394 | } |
1395 | |
1396 | fn serialize_u16(self, _v: u16) -> Result<String, Self::Error> { |
1397 | Err(Error::KeyNotString) |
1398 | } |
1399 | |
1400 | fn serialize_u32(self, _v: u32) -> Result<String, Self::Error> { |
1401 | Err(Error::KeyNotString) |
1402 | } |
1403 | |
1404 | fn serialize_u64(self, _v: u64) -> Result<String, Self::Error> { |
1405 | Err(Error::KeyNotString) |
1406 | } |
1407 | |
1408 | fn serialize_f32(self, _v: f32) -> Result<String, Self::Error> { |
1409 | Err(Error::KeyNotString) |
1410 | } |
1411 | |
1412 | fn serialize_f64(self, _v: f64) -> Result<String, Self::Error> { |
1413 | Err(Error::KeyNotString) |
1414 | } |
1415 | |
1416 | fn serialize_char(self, _v: char) -> Result<String, Self::Error> { |
1417 | Err(Error::KeyNotString) |
1418 | } |
1419 | |
1420 | fn serialize_str(self, value: &str) -> Result<String, Self::Error> { |
1421 | Ok(value.to_string()) |
1422 | } |
1423 | |
1424 | fn serialize_bytes(self, _value: &[u8]) -> Result<String, Self::Error> { |
1425 | Err(Error::KeyNotString) |
1426 | } |
1427 | |
1428 | fn serialize_none(self) -> Result<String, Self::Error> { |
1429 | Err(Error::KeyNotString) |
1430 | } |
1431 | |
1432 | fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<String, Self::Error> |
1433 | where |
1434 | T: ser::Serialize, |
1435 | { |
1436 | Err(Error::KeyNotString) |
1437 | } |
1438 | |
1439 | fn serialize_unit(self) -> Result<String, Self::Error> { |
1440 | Err(Error::KeyNotString) |
1441 | } |
1442 | |
1443 | fn serialize_unit_struct(self, _name: &'static str) -> Result<String, Self::Error> { |
1444 | Err(Error::KeyNotString) |
1445 | } |
1446 | |
1447 | fn serialize_unit_variant( |
1448 | self, |
1449 | _name: &'static str, |
1450 | _variant_index: u32, |
1451 | _variant: &'static str, |
1452 | ) -> Result<String, Self::Error> { |
1453 | Err(Error::KeyNotString) |
1454 | } |
1455 | |
1456 | fn serialize_newtype_struct<T: ?Sized>( |
1457 | self, |
1458 | _name: &'static str, |
1459 | value: &T, |
1460 | ) -> Result<String, Self::Error> |
1461 | where |
1462 | T: ser::Serialize, |
1463 | { |
1464 | value.serialize(self) |
1465 | } |
1466 | |
1467 | fn serialize_newtype_variant<T: ?Sized>( |
1468 | self, |
1469 | _name: &'static str, |
1470 | _variant_index: u32, |
1471 | _variant: &'static str, |
1472 | _value: &T, |
1473 | ) -> Result<String, Self::Error> |
1474 | where |
1475 | T: ser::Serialize, |
1476 | { |
1477 | Err(Error::KeyNotString) |
1478 | } |
1479 | |
1480 | fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { |
1481 | Err(Error::KeyNotString) |
1482 | } |
1483 | |
1484 | fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { |
1485 | Err(Error::KeyNotString) |
1486 | } |
1487 | |
1488 | fn serialize_tuple_struct( |
1489 | self, |
1490 | _name: &'static str, |
1491 | _len: usize, |
1492 | ) -> Result<Self::SerializeTupleStruct, Self::Error> { |
1493 | Err(Error::KeyNotString) |
1494 | } |
1495 | |
1496 | fn serialize_tuple_variant( |
1497 | self, |
1498 | _name: &'static str, |
1499 | _variant_index: u32, |
1500 | _variant: &'static str, |
1501 | _len: usize, |
1502 | ) -> Result<Self::SerializeTupleVariant, Self::Error> { |
1503 | Err(Error::KeyNotString) |
1504 | } |
1505 | |
1506 | fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { |
1507 | Err(Error::KeyNotString) |
1508 | } |
1509 | |
1510 | fn serialize_struct( |
1511 | self, |
1512 | _name: &'static str, |
1513 | _len: usize, |
1514 | ) -> Result<Self::SerializeStruct, Self::Error> { |
1515 | Err(Error::KeyNotString) |
1516 | } |
1517 | |
1518 | fn serialize_struct_variant( |
1519 | self, |
1520 | _name: &'static str, |
1521 | _variant_index: u32, |
1522 | _variant: &'static str, |
1523 | _len: usize, |
1524 | ) -> Result<Self::SerializeStructVariant, Self::Error> { |
1525 | Err(Error::KeyNotString) |
1526 | } |
1527 | } |
1528 | |
1529 | impl fmt::Display for Error { |
1530 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1531 | match *self { |
1532 | Error::UnsupportedType => "unsupported Rust type" .fmt(f), |
1533 | Error::KeyNotString => "map key was not a string" .fmt(f), |
1534 | Error::ValueAfterTable => "values must be emitted before tables" .fmt(f), |
1535 | Error::DateInvalid => "a serialized date was invalid" .fmt(f), |
1536 | Error::NumberInvalid => "a serialized number was invalid" .fmt(f), |
1537 | Error::UnsupportedNone => "unsupported None value" .fmt(f), |
1538 | Error::Custom(ref s: &String) => s.fmt(f), |
1539 | Error::KeyNewline => unreachable!(), |
1540 | Error::ArrayMixedType => unreachable!(), |
1541 | } |
1542 | } |
1543 | } |
1544 | |
1545 | impl error::Error for Error {} |
1546 | |
1547 | impl ser::Error for Error { |
1548 | fn custom<T: fmt::Display>(msg: T) -> Error { |
1549 | Error::Custom(msg.to_string()) |
1550 | } |
1551 | } |
1552 | |
1553 | enum Category { |
1554 | Primitive, |
1555 | Array, |
1556 | Table, |
1557 | } |
1558 | |
1559 | /// Convenience function to serialize items in a map in an order valid with |
1560 | /// TOML. |
1561 | /// |
1562 | /// TOML carries the restriction that keys in a table must be serialized last if |
1563 | /// their value is a table itself. This isn't always easy to guarantee, so this |
1564 | /// helper can be used like so: |
1565 | /// |
1566 | /// ```rust |
1567 | /// # use serde_derive::Serialize; |
1568 | /// # use std::collections::HashMap; |
1569 | /// #[derive(Serialize)] |
1570 | /// struct Manifest { |
1571 | /// package: Package, |
1572 | /// #[serde(serialize_with = "toml::ser::tables_last" )] |
1573 | /// dependencies: HashMap<String, Dependency>, |
1574 | /// } |
1575 | /// # type Package = String; |
1576 | /// # type Dependency = String; |
1577 | /// # fn main() {} |
1578 | /// ``` |
1579 | pub fn tables_last<'a, I, K, V, S>(data: &'a I, serializer: S) -> Result<S::Ok, S::Error> |
1580 | where |
1581 | &'a I: IntoIterator<Item = (K, V)>, |
1582 | K: ser::Serialize, |
1583 | V: ser::Serialize, |
1584 | S: ser::Serializer, |
1585 | { |
1586 | use serde::ser::SerializeMap; |
1587 | |
1588 | let mut map: ::SerializeMap = serializer.serialize_map(len:None)?; |
1589 | for (k: K, v: V) in data { |
1590 | if let Category::Primitive = v.serialize(serializer:Categorize::new())? { |
1591 | map.serialize_entry(&k, &v)?; |
1592 | } |
1593 | } |
1594 | for (k: K, v: V) in data { |
1595 | if let Category::Array = v.serialize(serializer:Categorize::new())? { |
1596 | map.serialize_entry(&k, &v)?; |
1597 | } |
1598 | } |
1599 | for (k: K, v: V) in data { |
1600 | if let Category::Table = v.serialize(serializer:Categorize::new())? { |
1601 | map.serialize_entry(&k, &v)?; |
1602 | } |
1603 | } |
1604 | map.end() |
1605 | } |
1606 | |
1607 | struct Categorize<E>(marker::PhantomData<E>); |
1608 | |
1609 | impl<E> Categorize<E> { |
1610 | fn new() -> Self { |
1611 | Categorize(marker::PhantomData) |
1612 | } |
1613 | } |
1614 | |
1615 | impl<E: ser::Error> ser::Serializer for Categorize<E> { |
1616 | type Ok = Category; |
1617 | type Error = E; |
1618 | type SerializeSeq = Self; |
1619 | type SerializeTuple = Self; |
1620 | type SerializeTupleStruct = Self; |
1621 | type SerializeTupleVariant = Self; |
1622 | type SerializeMap = Self; |
1623 | type SerializeStruct = Self; |
1624 | type SerializeStructVariant = ser::Impossible<Category, E>; |
1625 | |
1626 | fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> { |
1627 | Ok(Category::Primitive) |
1628 | } |
1629 | |
1630 | fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> { |
1631 | Ok(Category::Primitive) |
1632 | } |
1633 | |
1634 | fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> { |
1635 | Ok(Category::Primitive) |
1636 | } |
1637 | |
1638 | fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> { |
1639 | Ok(Category::Primitive) |
1640 | } |
1641 | |
1642 | fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> { |
1643 | Ok(Category::Primitive) |
1644 | } |
1645 | |
1646 | fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> { |
1647 | Ok(Category::Primitive) |
1648 | } |
1649 | |
1650 | fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> { |
1651 | Ok(Category::Primitive) |
1652 | } |
1653 | |
1654 | fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> { |
1655 | Ok(Category::Primitive) |
1656 | } |
1657 | |
1658 | fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> { |
1659 | Ok(Category::Primitive) |
1660 | } |
1661 | |
1662 | fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> { |
1663 | Ok(Category::Primitive) |
1664 | } |
1665 | |
1666 | fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> { |
1667 | Ok(Category::Primitive) |
1668 | } |
1669 | |
1670 | fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> { |
1671 | Ok(Category::Primitive) |
1672 | } |
1673 | |
1674 | fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> { |
1675 | Ok(Category::Primitive) |
1676 | } |
1677 | |
1678 | fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> { |
1679 | Ok(Category::Array) |
1680 | } |
1681 | |
1682 | fn serialize_none(self) -> Result<Self::Ok, Self::Error> { |
1683 | Err(ser::Error::custom("unsupported" )) |
1684 | } |
1685 | |
1686 | fn serialize_some<T: ?Sized + ser::Serialize>(self, v: &T) -> Result<Self::Ok, Self::Error> { |
1687 | v.serialize(self) |
1688 | } |
1689 | |
1690 | fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { |
1691 | Err(ser::Error::custom("unsupported" )) |
1692 | } |
1693 | |
1694 | fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> { |
1695 | Err(ser::Error::custom("unsupported" )) |
1696 | } |
1697 | |
1698 | fn serialize_unit_variant( |
1699 | self, |
1700 | _: &'static str, |
1701 | _: u32, |
1702 | _: &'static str, |
1703 | ) -> Result<Self::Ok, Self::Error> { |
1704 | Err(ser::Error::custom("unsupported" )) |
1705 | } |
1706 | |
1707 | fn serialize_newtype_struct<T: ?Sized + ser::Serialize>( |
1708 | self, |
1709 | _: &'static str, |
1710 | v: &T, |
1711 | ) -> Result<Self::Ok, Self::Error> { |
1712 | v.serialize(self) |
1713 | } |
1714 | |
1715 | fn serialize_newtype_variant<T: ?Sized + ser::Serialize>( |
1716 | self, |
1717 | _: &'static str, |
1718 | _: u32, |
1719 | _: &'static str, |
1720 | _: &T, |
1721 | ) -> Result<Self::Ok, Self::Error> { |
1722 | Err(ser::Error::custom("unsupported" )) |
1723 | } |
1724 | |
1725 | fn serialize_seq(self, _: Option<usize>) -> Result<Self, Self::Error> { |
1726 | Ok(self) |
1727 | } |
1728 | |
1729 | fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> { |
1730 | Ok(self) |
1731 | } |
1732 | |
1733 | fn serialize_tuple_struct( |
1734 | self, |
1735 | _: &'static str, |
1736 | _: usize, |
1737 | ) -> Result<Self::SerializeTupleStruct, Self::Error> { |
1738 | Ok(self) |
1739 | } |
1740 | |
1741 | fn serialize_tuple_variant( |
1742 | self, |
1743 | _: &'static str, |
1744 | _: u32, |
1745 | _: &'static str, |
1746 | _: usize, |
1747 | ) -> Result<Self::SerializeTupleVariant, Self::Error> { |
1748 | Ok(self) |
1749 | } |
1750 | |
1751 | fn serialize_map(self, _: Option<usize>) -> Result<Self, Self::Error> { |
1752 | Ok(self) |
1753 | } |
1754 | |
1755 | fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self, Self::Error> { |
1756 | Ok(self) |
1757 | } |
1758 | |
1759 | fn serialize_struct_variant( |
1760 | self, |
1761 | _: &'static str, |
1762 | _: u32, |
1763 | _: &'static str, |
1764 | _: usize, |
1765 | ) -> Result<Self::SerializeStructVariant, Self::Error> { |
1766 | Err(ser::Error::custom("unsupported" )) |
1767 | } |
1768 | } |
1769 | |
1770 | impl<E: ser::Error> ser::SerializeSeq for Categorize<E> { |
1771 | type Ok = Category; |
1772 | type Error = E; |
1773 | |
1774 | fn serialize_element<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1775 | Ok(()) |
1776 | } |
1777 | |
1778 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1779 | Ok(Category::Array) |
1780 | } |
1781 | } |
1782 | |
1783 | impl<E: ser::Error> ser::SerializeTuple for Categorize<E> { |
1784 | type Ok = Category; |
1785 | type Error = E; |
1786 | |
1787 | fn serialize_element<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1788 | Ok(()) |
1789 | } |
1790 | |
1791 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1792 | Ok(Category::Array) |
1793 | } |
1794 | } |
1795 | |
1796 | impl<E: ser::Error> ser::SerializeTupleVariant for Categorize<E> { |
1797 | type Ok = Category; |
1798 | type Error = E; |
1799 | |
1800 | fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1801 | Ok(()) |
1802 | } |
1803 | |
1804 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1805 | Ok(Category::Array) |
1806 | } |
1807 | } |
1808 | |
1809 | impl<E: ser::Error> ser::SerializeTupleStruct for Categorize<E> { |
1810 | type Ok = Category; |
1811 | type Error = E; |
1812 | |
1813 | fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1814 | Ok(()) |
1815 | } |
1816 | |
1817 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1818 | Ok(Category::Array) |
1819 | } |
1820 | } |
1821 | |
1822 | impl<E: ser::Error> ser::SerializeMap for Categorize<E> { |
1823 | type Ok = Category; |
1824 | type Error = E; |
1825 | |
1826 | fn serialize_key<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1827 | Ok(()) |
1828 | } |
1829 | |
1830 | fn serialize_value<T: ?Sized + ser::Serialize>(&mut self, _: &T) -> Result<(), Self::Error> { |
1831 | Ok(()) |
1832 | } |
1833 | |
1834 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1835 | Ok(Category::Table) |
1836 | } |
1837 | } |
1838 | |
1839 | impl<E: ser::Error> ser::SerializeStruct for Categorize<E> { |
1840 | type Ok = Category; |
1841 | type Error = E; |
1842 | |
1843 | fn serialize_field<T: ?Sized>(&mut self, _: &'static str, _: &T) -> Result<(), Self::Error> |
1844 | where |
1845 | T: ser::Serialize, |
1846 | { |
1847 | Ok(()) |
1848 | } |
1849 | |
1850 | fn end(self) -> Result<Self::Ok, Self::Error> { |
1851 | Ok(Category::Table) |
1852 | } |
1853 | } |
1854 | |