ron/
options.rs

1//! Roundtrip serde Options module.
2
3use std::{fmt, io};
4
5use serde::{de, ser};
6use serde_derive::{Deserialize, Serialize};
7
8use crate::{
9    de::Deserializer,
10    error::{Position, Result, SpannedError, SpannedResult},
11    extensions::Extensions,
12    ser::{PrettyConfig, Serializer},
13};
14
15/// Roundtrip serde options.
16///
17/// # Examples
18///
19/// ```
20/// use ron::{Options, extensions::Extensions};
21///
22/// let ron = Options::default()
23///     .with_default_extension(Extensions::IMPLICIT_SOME);
24///
25/// let de: Option<i32> = ron.from_str("42").unwrap();
26/// let ser = ron.to_string(&de).unwrap();
27///
28/// assert_eq!(ser, "42");
29/// ```
30#[derive(Clone, Debug, Serialize, Deserialize)] // GRCOV_EXCL_LINE
31#[serde(default)]
32#[non_exhaustive]
33pub struct Options {
34    /// Extensions that are enabled by default during serialization and
35    ///  deserialization.
36    /// During serialization, these extensions do NOT have to be explicitly
37    ///  enabled in the parsed RON.
38    /// During deserialization, these extensions are used, but their explicit
39    ///  activation is NOT included in the output RON.
40    /// No extensions are enabled by default.
41    pub default_extensions: Extensions,
42    /// Default recursion limit that is checked during serialization and
43    ///  deserialization.
44    /// If set to `None`, infinite recursion is allowed and stack overflow
45    ///  errors can crash the serialization or deserialization process.
46    /// Defaults to `Some(128)`, i.e. 128 recursive calls are allowed.
47    pub recursion_limit: Option<usize>,
48}
49
50impl Default for Options {
51    fn default() -> Self {
52        Self {
53            default_extensions: Extensions::empty(),
54            recursion_limit: Some(128),
55        }
56    }
57}
58
59impl Options {
60    #[must_use]
61    /// Enable `default_extension` by default during serialization and deserialization.
62    pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
63        self.default_extensions |= default_extension;
64        self
65    }
66
67    #[must_use]
68    /// Do NOT enable `default_extension` by default during serialization and deserialization.
69    pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
70        self.default_extensions &= !default_extension;
71        self
72    }
73
74    #[must_use]
75    /// Set a maximum recursion limit during serialization and deserialization.
76    pub fn with_recursion_limit(mut self, recursion_limit: usize) -> Self {
77        self.recursion_limit = Some(recursion_limit);
78        self
79    }
80
81    #[must_use]
82    /// Disable the recursion limit during serialization and deserialization.
83    ///
84    /// If you expect to handle highly recursive datastructures, consider wrapping
85    /// `ron` with [`serde_stacker`](https://docs.rs/serde_stacker/latest/serde_stacker/).
86    pub fn without_recursion_limit(mut self) -> Self {
87        self.recursion_limit = None;
88        self
89    }
90}
91
92impl Options {
93    /// A convenience function for building a deserializer
94    /// and deserializing a value of type `T` from a reader.
95    pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T>
96    where
97        R: io::Read,
98        T: de::DeserializeOwned,
99    {
100        self.from_reader_seed(rdr, std::marker::PhantomData)
101    }
102
103    /// A convenience function for building a deserializer
104    /// and deserializing a value of type `T` from a string.
105    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
106    where
107        T: de::Deserialize<'a>,
108    {
109        self.from_str_seed(s, std::marker::PhantomData)
110    }
111
112    /// A convenience function for building a deserializer
113    /// and deserializing a value of type `T` from bytes.
114    pub fn from_bytes<'a, T>(&self, s: &'a [u8]) -> SpannedResult<T>
115    where
116        T: de::Deserialize<'a>,
117    {
118        self.from_bytes_seed(s, std::marker::PhantomData)
119    }
120
121    /// A convenience function for building a deserializer
122    /// and deserializing a value of type `T` from a reader
123    /// and a seed.
124    // FIXME: panic is not actually possible, remove once utf8_chunks is stabilized
125    #[allow(clippy::missing_panics_doc)]
126    pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
127    where
128        R: io::Read,
129        S: for<'a> de::DeserializeSeed<'a, Value = T>,
130    {
131        let mut bytes = Vec::new();
132
133        let io_err = if let Err(err) = rdr.read_to_end(&mut bytes) {
134            err
135        } else {
136            return self.from_bytes_seed(&bytes, seed);
137        };
138
139        // Try to compute a good error position for the I/O error
140        // FIXME: use [`utf8_chunks`](https://github.com/rust-lang/rust/issues/99543) once stabilised
141        #[allow(clippy::expect_used)]
142        let valid_input = match std::str::from_utf8(&bytes) {
143            Ok(valid_input) => valid_input,
144            Err(err) => std::str::from_utf8(&bytes[..err.valid_up_to()])
145                .expect("source is valid up to error"),
146        };
147
148        Err(SpannedError {
149            code: io_err.into(),
150            position: Position::from_src_end(valid_input),
151        })
152    }
153
154    /// A convenience function for building a deserializer
155    /// and deserializing a value of type `T` from a string
156    /// and a seed.
157    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
158    where
159        S: de::DeserializeSeed<'a, Value = T>,
160    {
161        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
162
163        let value = seed
164            .deserialize(&mut deserializer)
165            .map_err(|e| deserializer.span_error(e))?;
166
167        deserializer.end().map_err(|e| deserializer.span_error(e))?;
168
169        Ok(value)
170    }
171
172    /// A convenience function for building a deserializer
173    /// and deserializing a value of type `T` from bytes
174    /// and a seed.
175    pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
176    where
177        S: de::DeserializeSeed<'a, Value = T>,
178    {
179        let mut deserializer = Deserializer::from_bytes_with_options(s, self)?;
180
181        let value = seed
182            .deserialize(&mut deserializer)
183            .map_err(|e| deserializer.span_error(e))?;
184
185        deserializer.end().map_err(|e| deserializer.span_error(e))?;
186
187        Ok(value)
188    }
189
190    /// Serializes `value` into `writer`.
191    ///
192    /// This function does not generate any newlines or nice formatting;
193    /// if you want that, you can use
194    /// [`to_writer_pretty`][Self::to_writer_pretty] instead.
195    pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
196    where
197        W: fmt::Write,
198        T: ?Sized + ser::Serialize,
199    {
200        let mut s = Serializer::with_options(writer, None, self)?;
201        value.serialize(&mut s)
202    }
203
204    /// Serializes `value` into `writer` in a pretty way.
205    pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
206    where
207        W: fmt::Write,
208        T: ?Sized + ser::Serialize,
209    {
210        let mut s = Serializer::with_options(writer, Some(config), self)?;
211        value.serialize(&mut s)
212    }
213
214    /// Serializes `value` into `writer`.
215    ///
216    /// This function does not generate any newlines or nice formatting;
217    /// if you want that, you can use
218    /// [`to_io_writer_pretty`][Self::to_io_writer_pretty] instead.
219    pub fn to_io_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
220    where
221        W: io::Write,
222        T: ?Sized + ser::Serialize,
223    {
224        let mut adapter = Adapter {
225            writer,
226            error: Ok(()),
227        };
228        let result = self.to_writer(&mut adapter, value);
229        adapter.error?;
230        result
231    }
232
233    /// Serializes `value` into `writer` in a pretty way.
234    pub fn to_io_writer_pretty<W, T>(
235        &self,
236        writer: W,
237        value: &T,
238        config: PrettyConfig,
239    ) -> Result<()>
240    where
241        W: io::Write,
242        T: ?Sized + ser::Serialize,
243    {
244        let mut adapter = Adapter {
245            writer,
246            error: Ok(()),
247        };
248        let result = self.to_writer_pretty(&mut adapter, value, config);
249        adapter.error?;
250        result
251    }
252
253    /// Serializes `value` and returns it as string.
254    ///
255    /// This function does not generate any newlines or nice formatting;
256    /// if you want that, you can use
257    /// [`to_string_pretty`][Self::to_string_pretty] instead.
258    pub fn to_string<T>(&self, value: &T) -> Result<String>
259    where
260        T: ?Sized + ser::Serialize,
261    {
262        let mut output = String::new();
263        let mut s = Serializer::with_options(&mut output, None, self)?;
264        value.serialize(&mut s)?;
265        Ok(output)
266    }
267
268    /// Serializes `value` in the recommended RON layout in a pretty way.
269    pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
270    where
271        T: ?Sized + ser::Serialize,
272    {
273        let mut output = String::new();
274        let mut s = Serializer::with_options(&mut output, Some(config), self)?;
275        value.serialize(&mut s)?;
276        Ok(output)
277    }
278}
279
280// Adapter from io::Write to fmt::Write that keeps the error
281struct Adapter<W: io::Write> {
282    writer: W,
283    error: io::Result<()>,
284}
285
286impl<T: io::Write> fmt::Write for Adapter<T> {
287    fn write_str(&mut self, s: &str) -> fmt::Result {
288        match self.writer.write_all(s.as_bytes()) {
289            Ok(()) => Ok(()),
290            Err(e) => {
291                self.error = Err(e);
292                Err(fmt::Error)
293            }
294        }
295    }
296}