1 use super::Error;
2 
3 /// Serialization for TOML [values][crate::Value].
4 ///
5 /// This structure implements serialization support for TOML to serialize an
6 /// arbitrary type to TOML. Note that the TOML format does not support all
7 /// datatypes in Rust, such as enums, tuples, and tuple structs. These types
8 /// will generate an error when serialized.
9 ///
10 /// Currently a serializer always writes its output to an in-memory `String`,
11 /// which is passed in when creating the serializer itself.
12 ///
13 /// # Examples
14 ///
15 /// ```
16 /// use serde::Serialize;
17 ///
18 /// #[derive(Serialize)]
19 /// struct Config {
20 ///     database: Database,
21 /// }
22 ///
23 /// #[derive(Serialize)]
24 /// struct Database {
25 ///     ip: String,
26 ///     port: Vec<u16>,
27 ///     connection_max: u32,
28 ///     enabled: bool,
29 /// }
30 ///
31 /// let config = Config {
32 ///     database: Database {
33 ///         ip: "192.168.1.1".to_string(),
34 ///         port: vec![8001, 8002, 8003],
35 ///         connection_max: 5000,
36 ///         enabled: false,
37 ///     },
38 /// };
39 ///
40 /// let value = serde::Serialize::serialize(
41 ///     &config,
42 ///     toml_edit::ser::ValueSerializer::new()
43 /// ).unwrap();
44 /// println!("{}", value)
45 /// ```
46 #[derive(Default)]
47 #[non_exhaustive]
48 pub struct ValueSerializer {}
49 
50 impl ValueSerializer {
51     /// Creates a new serializer generate a TOML document.
new() -> Self52     pub fn new() -> Self {
53         Self {}
54     }
55 }
56 
57 impl serde::ser::Serializer for ValueSerializer {
58     type Ok = crate::Value;
59     type Error = Error;
60     type SerializeSeq = super::SerializeValueArray;
61     type SerializeTuple = super::SerializeValueArray;
62     type SerializeTupleStruct = super::SerializeValueArray;
63     type SerializeTupleVariant = super::SerializeTupleVariant;
64     type SerializeMap = super::SerializeMap;
65     type SerializeStruct = super::SerializeMap;
66     type SerializeStructVariant = super::SerializeStructVariant;
67 
serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>68     fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
69         Ok(v.into())
70     }
71 
serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>72     fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
73         self.serialize_i64(v as i64)
74     }
75 
serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>76     fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
77         self.serialize_i64(v as i64)
78     }
79 
serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>80     fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
81         self.serialize_i64(v as i64)
82     }
83 
serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>84     fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
85         Ok(v.into())
86     }
87 
serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>88     fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
89         self.serialize_i64(v as i64)
90     }
91 
serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>92     fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
93         self.serialize_i64(v as i64)
94     }
95 
serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>96     fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
97         self.serialize_i64(v as i64)
98     }
99 
serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>100     fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
101         let v: i64 = v
102             .try_into()
103             .map_err(|_err| Error::OutOfRange(Some("u64")))?;
104         self.serialize_i64(v)
105     }
106 
serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>107     fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
108         self.serialize_f64(v as f64)
109     }
110 
serialize_f64(self, mut v: f64) -> Result<Self::Ok, Self::Error>111     fn serialize_f64(self, mut v: f64) -> Result<Self::Ok, Self::Error> {
112         // Discard sign of NaN when serialized using Serde.
113         //
114         // In all likelihood the sign of NaNs is not meaningful in the user's
115         // program. Ending up with `-nan` in the TOML document would usually be
116         // surprising and undesirable, when the sign of the NaN was not
117         // intentionally controlled by the caller, or may even be
118         // nondeterministic if it comes from arithmetic operations or a cast.
119         if v.is_nan() {
120             v = v.copysign(1.0);
121         }
122         Ok(v.into())
123     }
124 
serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>125     fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
126         let mut buf = [0; 4];
127         self.serialize_str(v.encode_utf8(&mut buf))
128     }
129 
serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>130     fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
131         Ok(v.into())
132     }
133 
serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error>134     fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
135         use serde::ser::Serialize;
136         value.serialize(self)
137     }
138 
serialize_none(self) -> Result<Self::Ok, Self::Error>139     fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
140         Err(Error::UnsupportedNone)
141     }
142 
serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> where T: serde::ser::Serialize,143     fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
144     where
145         T: serde::ser::Serialize,
146     {
147         value.serialize(self)
148     }
149 
serialize_unit(self) -> Result<Self::Ok, Self::Error>150     fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
151         Err(Error::UnsupportedType(Some("unit")))
152     }
153 
serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error>154     fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
155         Err(Error::UnsupportedType(Some(name)))
156     }
157 
serialize_unit_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, ) -> Result<Self::Ok, Self::Error>158     fn serialize_unit_variant(
159         self,
160         _name: &'static str,
161         _variant_index: u32,
162         variant: &'static str,
163     ) -> Result<Self::Ok, Self::Error> {
164         self.serialize_str(variant)
165     }
166 
serialize_newtype_struct<T: ?Sized>( self, _name: &'static str, value: &T, ) -> Result<Self::Ok, Self::Error> where T: serde::ser::Serialize,167     fn serialize_newtype_struct<T: ?Sized>(
168         self,
169         _name: &'static str,
170         value: &T,
171     ) -> Result<Self::Ok, Self::Error>
172     where
173         T: serde::ser::Serialize,
174     {
175         value.serialize(self)
176     }
177 
serialize_newtype_variant<T: ?Sized>( self, _name: &'static str, _variant_index: u32, variant: &'static str, value: &T, ) -> Result<Self::Ok, Self::Error> where T: serde::ser::Serialize,178     fn serialize_newtype_variant<T: ?Sized>(
179         self,
180         _name: &'static str,
181         _variant_index: u32,
182         variant: &'static str,
183         value: &T,
184     ) -> Result<Self::Ok, Self::Error>
185     where
186         T: serde::ser::Serialize,
187     {
188         let value = value.serialize(self)?;
189         let mut table = crate::InlineTable::new();
190         table.insert(variant, value);
191         Ok(table.into())
192     }
193 
serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>194     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
195         let serializer = match len {
196             Some(len) => super::SerializeValueArray::with_capacity(len),
197             None => super::SerializeValueArray::new(),
198         };
199         Ok(serializer)
200     }
201 
serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error>202     fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
203         self.serialize_seq(Some(len))
204     }
205 
serialize_tuple_struct( self, _name: &'static str, len: usize, ) -> Result<Self::SerializeTupleStruct, Self::Error>206     fn serialize_tuple_struct(
207         self,
208         _name: &'static str,
209         len: usize,
210     ) -> Result<Self::SerializeTupleStruct, Self::Error> {
211         self.serialize_seq(Some(len))
212     }
213 
serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, len: usize, ) -> Result<Self::SerializeTupleVariant, Self::Error>214     fn serialize_tuple_variant(
215         self,
216         _name: &'static str,
217         _variant_index: u32,
218         variant: &'static str,
219         len: usize,
220     ) -> Result<Self::SerializeTupleVariant, Self::Error> {
221         Ok(super::SerializeTupleVariant::tuple(variant, len))
222     }
223 
serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error>224     fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
225         let serializer = match len {
226             Some(len) => super::SerializeMap::table_with_capacity(len),
227             None => super::SerializeMap::table(),
228         };
229         Ok(serializer)
230     }
231 
serialize_struct( self, name: &'static str, len: usize, ) -> Result<Self::SerializeStruct, Self::Error>232     fn serialize_struct(
233         self,
234         name: &'static str,
235         len: usize,
236     ) -> Result<Self::SerializeStruct, Self::Error> {
237         if name == toml_datetime::__unstable::NAME {
238             Ok(super::SerializeMap::datetime())
239         } else {
240             self.serialize_map(Some(len))
241         }
242     }
243 
serialize_struct_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, len: usize, ) -> Result<Self::SerializeStructVariant, Self::Error>244     fn serialize_struct_variant(
245         self,
246         _name: &'static str,
247         _variant_index: u32,
248         variant: &'static str,
249         len: usize,
250     ) -> Result<Self::SerializeStructVariant, Self::Error> {
251         Ok(super::SerializeStructVariant::struct_(variant, len))
252     }
253 }
254