serde_java_properties/ser/
mod.rs

1//! Serialization
2
3use std::{error, fmt, io};
4
5use encoding_rs::Encoding;
6use java_properties::PropertiesError;
7use serde::{
8    ser::{self, Impossible},
9    Serialize,
10};
11
12use self::string::StringSerializer;
13
14mod string;
15
16pub use java_properties::LineEnding;
17
18/// Serialize a structure to a properties file
19pub struct Serializer<W: io::Write> {
20    inner: java_properties::PropertiesWriter<W>,
21}
22
23impl<W: io::Write> Serializer<W> {
24    /// Set the KV separator
25    ///
26    /// This method returns an error if the separator is not valid. A separator is
27    /// valid if is non-empty and consists only of whitespace characters, except
28    /// a single `:` or `=` character.
29    pub fn set_kv_separator(&mut self, separator: &str) -> Result<(), Error> {
30        self.inner.set_kv_separator(separator)?;
31        Ok(())
32    }
33
34    /// Set the line ending to `\n`, `\r` or `\r\n`.
35    pub fn set_line_ending(&mut self, line_ending: LineEnding) {
36        self.inner.set_line_ending(line_ending);
37    }
38
39    /// Create a serializer from a [`io::Write`] implementation
40    pub fn from_writer(writer: W) -> Self {
41        Self {
42            inner: java_properties::PropertiesWriter::new(writer),
43        }
44    }
45
46    /// Create a serializer from a [`io::Write`] implementation with a specificed encoding
47    pub fn from_writer_with_encoding(writer: W, encoding: &'static Encoding) -> Self {
48        Self {
49            inner: java_properties::PropertiesWriter::new_with_encoding(writer, encoding),
50        }
51    }
52}
53
54/// A serialization error
55#[derive(Debug)]
56#[non_exhaustive]
57pub enum Error {
58    /// A properties error
59    Properties(PropertiesError),
60    /// A message from [serde]
61    Custom {
62        /// The message text
63        msg: String,
64    },
65    /// Not a map
66    NotAMap,
67    /// Serialization not supported
68    NotSupported,
69}
70
71impl From<PropertiesError> for Error {
72    fn from(e: PropertiesError) -> Self {
73        Self::Properties(e)
74    }
75}
76
77impl fmt::Display for Error {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        match self {
80            Self::Properties(e) => e.fmt(f),
81            Self::Custom { msg } => write!(f, "Serialization error: {}", msg),
82            Self::NotAMap => write!(f, "Can only serialize a map-like structure to properties"),
83            Self::NotSupported => write!(f, "Not supported"),
84        }
85    }
86}
87
88impl error::Error for Error {}
89
90impl ser::Error for Error {
91    fn custom<T>(msg: T) -> Self
92    where
93        T: fmt::Display,
94    {
95        Self::Custom {
96            msg: msg.to_string(),
97        }
98    }
99}
100
101impl<W: io::Write> ser::SerializeStruct for Serializer<W> {
102    type Ok = ();
103
104    type Error = Error;
105
106    fn serialize_field<T: ?Sized>(
107        &mut self,
108        key: &'static str,
109        value: &T,
110    ) -> Result<(), Self::Error>
111    where
112        T: Serialize,
113    {
114        let value = value.serialize(StringSerializer)?;
115        self.inner.write(key, &value)?;
116        Ok(())
117    }
118
119    fn end(self) -> Result<Self::Ok, Self::Error> {
120        Ok(())
121    }
122}
123
124impl<W: io::Write> ser::SerializeStructVariant for Serializer<W> {
125    type Ok = ();
126
127    type Error = Error;
128
129    fn serialize_field<T: ?Sized>(
130        &mut self,
131        key: &'static str,
132        value: &T,
133    ) -> Result<(), Self::Error>
134    where
135        T: Serialize,
136    {
137        let value = value.serialize(StringSerializer)?;
138        self.inner.write(key, &value)?;
139        Ok(())
140    }
141
142    fn end(self) -> Result<Self::Ok, Self::Error> {
143        Ok(())
144    }
145}
146
147/// A struct to serialize a map
148pub struct MapSerializer<W: io::Write> {
149    inner: java_properties::PropertiesWriter<W>,
150    key: Option<String>,
151}
152
153impl<W: io::Write> ser::SerializeMap for MapSerializer<W> {
154    type Ok = ();
155
156    type Error = Error;
157
158    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
159    where
160        T: Serialize,
161    {
162        let str = T::serialize(key, string::StringSerializer)?;
163        self.key = Some(str);
164        Ok(())
165    }
166
167    /// Panics is `serialize_key` wasn't called before successfully
168    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
169    where
170        T: Serialize,
171    {
172        let key = self.key.take().unwrap();
173        let value = value.serialize(StringSerializer)?;
174        self.inner.write(&key, &value)?;
175        Ok(())
176    }
177
178    fn end(self) -> Result<Self::Ok, Self::Error> {
179        Ok(())
180    }
181}
182
183macro_rules! not_a_map {
184    ($($fn_name:ident: $ty:ty),*) => {
185        $(
186            fn $fn_name(self, _v: $ty) -> Result<Self::Ok, Self::Error> {
187                Err(Error::NotAMap)
188            }
189        )*
190    };
191}
192
193impl<W: io::Write> ser::Serializer for Serializer<W> {
194    type Ok = ();
195
196    type Error = Error;
197
198    type SerializeSeq = Impossible<(), Error>;
199
200    type SerializeTuple = Impossible<(), Error>;
201
202    type SerializeTupleStruct = Impossible<(), Error>;
203
204    type SerializeTupleVariant = Impossible<(), Error>;
205
206    type SerializeMap = MapSerializer<W>;
207
208    type SerializeStruct = Self;
209
210    type SerializeStructVariant = Self;
211
212    not_a_map!(
213        serialize_bool: bool,
214        serialize_i8: i8,
215        serialize_i16: i16,
216        serialize_i32: i32,
217        serialize_i64: i64,
218        serialize_i128: i128,
219        serialize_u8: u8,
220        serialize_u16: u16,
221        serialize_u32: u32,
222        serialize_u64: u64,
223        serialize_u128: u128,
224        serialize_f32: f32,
225        serialize_f64: f64,
226        serialize_str: &str,
227        serialize_char: char,
228        serialize_bytes: &[u8]
229    );
230
231    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
232        Ok(())
233    }
234
235    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
236    where
237        T: Serialize,
238    {
239        value.serialize(self)
240    }
241
242    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
243        Ok(())
244    }
245
246    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
247        Ok(())
248    }
249
250    fn serialize_unit_variant(
251        self,
252        _name: &'static str,
253        _variant_index: u32,
254        _variant: &'static str,
255    ) -> Result<Self::Ok, Self::Error> {
256        Ok(())
257    }
258
259    fn serialize_newtype_struct<T: ?Sized>(
260        self,
261        _name: &'static str,
262        value: &T,
263    ) -> Result<Self::Ok, Self::Error>
264    where
265        T: Serialize,
266    {
267        value.serialize(self)
268    }
269
270    fn serialize_newtype_variant<T: ?Sized>(
271        self,
272        _name: &'static str,
273        _variant_index: u32,
274        _variant: &'static str,
275        value: &T,
276    ) -> Result<Self::Ok, Self::Error>
277    where
278        T: Serialize,
279    {
280        value.serialize(self)
281    }
282
283    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
284        Err(Error::NotAMap)
285    }
286
287    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
288        Err(Error::NotAMap)
289    }
290
291    fn serialize_tuple_struct(
292        self,
293        _name: &'static str,
294        _len: usize,
295    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
296        Err(Error::NotAMap)
297    }
298
299    fn serialize_tuple_variant(
300        self,
301        _name: &'static str,
302        _variant_index: u32,
303        _variant: &'static str,
304        _len: usize,
305    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
306        Err(Error::NotAMap)
307    }
308
309    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
310        Ok(MapSerializer {
311            inner: self.inner,
312            key: None,
313        })
314    }
315
316    fn serialize_struct(
317        self,
318        _name: &'static str,
319        _len: usize,
320    ) -> Result<Self::SerializeStruct, Self::Error> {
321        Ok(self)
322    }
323
324    fn serialize_struct_variant(
325        self,
326        _name: &'static str,
327        _variant_index: u32,
328        _variant: &'static str,
329        _len: usize,
330    ) -> Result<Self::SerializeStructVariant, Self::Error> {
331        Ok(self)
332    }
333}