1
//! Roundtrip serde Options module.
2

            
3
use alloc::string::String;
4
use core::fmt;
5

            
6
use serde::{de, ser};
7
use serde_derive::{Deserialize, Serialize};
8

            
9
use crate::{
10
    de::Deserializer,
11
    error::{Result, SpannedResult},
12
    extensions::Extensions,
13
    ser::{PrettyConfig, Serializer},
14
};
15

            
16
#[cfg(feature = "std")]
17
use {
18
    crate::error::{Position, Span, SpannedError},
19
    alloc::vec::Vec,
20
    std::io,
21
};
22

            
23
/// Roundtrip serde options.
24
///
25
/// # Examples
26
///
27
/// ```
28
/// use ron::{Options, extensions::Extensions};
29
///
30
/// let ron = Options::default()
31
///     .with_default_extension(Extensions::IMPLICIT_SOME);
32
///
33
/// let de: Option<i32> = ron.from_str("42").unwrap();
34
/// let ser = ron.to_string(&de).unwrap();
35
///
36
/// assert_eq!(ser, "42");
37
/// ```
38
#[derive(Clone, Debug, Serialize, Deserialize)] // GRCOV_EXCL_LINE
39
#[serde(default)]
40
#[non_exhaustive]
41
pub struct Options {
42
    /// Extensions that are enabled by default during serialization and
43
    ///  deserialization.
44
    /// During serialization, these extensions do NOT have to be explicitly
45
    ///  enabled in the parsed RON.
46
    /// During deserialization, these extensions are used, but their explicit
47
    ///  activation is NOT included in the output RON.
48
    /// No extensions are enabled by default.
49
    pub default_extensions: Extensions,
50
    /// Default recursion limit that is checked during serialization and
51
    ///  deserialization.
52
    /// If set to `None`, infinite recursion is allowed and stack overflow
53
    ///  errors can crash the serialization or deserialization process.
54
    /// Defaults to `Some(128)`, i.e. 128 recursive calls are allowed.
55
    pub recursion_limit: Option<usize>,
56
}
57

            
58
impl Default for Options {
59
693742
    fn default() -> Self {
60
693742
        Self {
61
693742
            default_extensions: Extensions::empty(),
62
693742
            recursion_limit: Some(128),
63
693742
        }
64
693742
    }
65
}
66

            
67
impl Options {
68
    #[must_use]
69
    /// Enable `default_extension` by default during serialization and deserialization.
70
2780
    pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
71
2780
        self.default_extensions |= default_extension;
72
2780
        self
73
2780
    }
74

            
75
    #[must_use]
76
    /// Do NOT enable `default_extension` by default during serialization and deserialization.
77
1112
    pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
78
1112
        self.default_extensions &= !default_extension;
79
1112
        self
80
1112
    }
81

            
82
    #[must_use]
83
    /// Set a maximum recursion limit during serialization and deserialization.
84
16
    pub fn with_recursion_limit(mut self, recursion_limit: usize) -> Self {
85
16
        self.recursion_limit = Some(recursion_limit);
86
16
        self
87
16
    }
88

            
89
    #[must_use]
90
    /// Disable the recursion limit during serialization and deserialization.
91
    ///
92
    /// If you expect to handle highly recursive datastructures, consider wrapping
93
    /// `ron` with [`serde_stacker`](https://docs.rs/serde_stacker/latest/serde_stacker/).
94
8
    pub fn without_recursion_limit(mut self) -> Self {
95
8
        self.recursion_limit = None;
96
8
        self
97
8
    }
98
}
99

            
100
impl Options {
101
    /// A convenience function for building a deserializer
102
    /// and deserializing a value of type `T` from a reader.
103
    #[cfg(feature = "std")]
104
324
    pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T>
105
324
    where
106
324
        R: io::Read,
107
324
        T: de::DeserializeOwned,
108
    {
109
324
        self.from_reader_seed(rdr, core::marker::PhantomData)
110
324
    }
111

            
112
    /// A convenience function for building a deserializer
113
    /// and deserializing a value of type `T` from a string.
114
25892
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
25892
    where
116
25892
        T: de::Deserialize<'a>,
117
    {
118
25892
        self.from_str_seed(s, core::marker::PhantomData)
119
25892
    }
120

            
121
    /// A convenience function for building a deserializer
122
    /// and deserializing a value of type `T` from bytes.
123
340
    pub fn from_bytes<'a, T>(&self, s: &'a [u8]) -> SpannedResult<T>
124
340
    where
125
340
        T: de::Deserialize<'a>,
126
    {
127
340
        self.from_bytes_seed(s, core::marker::PhantomData)
128
340
    }
129

            
130
    /// A convenience function for building a deserializer
131
    /// and deserializing a value of type `T` from a reader
132
    /// and a seed.
133
    // FIXME: panic is not actually possible, remove once utf8_chunks is stabilized
134
    #[allow(clippy::missing_panics_doc)]
135
    #[cfg(feature = "std")]
136
324
    pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
137
324
    where
138
324
        R: io::Read,
139
324
        S: for<'a> de::DeserializeSeed<'a, Value = T>,
140
    {
141
324
        let mut bytes = Vec::new();
142

            
143
324
        let io_err = if let Err(err) = rdr.read_to_end(&mut bytes) {
144
12
            err
145
        } else {
146
312
            return self.from_bytes_seed(&bytes, seed);
147
        };
148

            
149
        // Try to compute a good error position for the I/O error
150
        // FIXME: use [`utf8_chunks`](https://github.com/rust-lang/rust/issues/99543) once stabilised
151
        #[allow(clippy::expect_used)]
152
12
        let valid_input = match core::str::from_utf8(&bytes) {
153
8
            Ok(valid_input) => valid_input,
154
4
            Err(err) => core::str::from_utf8(&bytes[..err.valid_up_to()])
155
4
                .expect("source is valid up to error"),
156
        };
157

            
158
12
        Err(SpannedError {
159
12
            code: io_err.into(),
160
12
            span: Span {
161
12
                start: Position { line: 1, col: 1 },
162
12
                end: Position::from_src_end(valid_input),
163
12
            },
164
12
        })
165
324
    }
166

            
167
    /// A convenience function for building a deserializer
168
    /// and deserializing a value of type `T` from a string
169
    /// and a seed.
170
25908
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
25908
    where
172
25908
        S: de::DeserializeSeed<'a, Value = T>,
173
    {
174
25908
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175

            
176
25885
        let value = seed
177
25885
            .deserialize(&mut deserializer)
178
25885
            .map_err(|e| deserializer.span_error(e))?;
179

            
180
23508
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
181

            
182
23432
        Ok(value)
183
25908
    }
184

            
185
    /// A convenience function for building a deserializer
186
    /// and deserializing a value of type `T` from bytes
187
    /// and a seed.
188
652
    pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
189
652
    where
190
652
        S: de::DeserializeSeed<'a, Value = T>,
191
    {
192
652
        let mut deserializer = Deserializer::from_bytes_with_options(s, self)?;
193

            
194
614
        let value = seed
195
614
            .deserialize(&mut deserializer)
196
614
            .map_err(|e| deserializer.span_error(e))?;
197

            
198
352
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
199

            
200
352
        Ok(value)
201
652
    }
202

            
203
    /// Serializes `value` into `writer`.
204
    ///
205
    /// This function does not generate any newlines or nice formatting;
206
    /// if you want that, you can use
207
    /// [`to_writer_pretty`][Self::to_writer_pretty] instead.
208
360
    pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
209
360
    where
210
360
        W: fmt::Write,
211
360
        T: ?Sized + ser::Serialize,
212
    {
213
360
        let mut s = Serializer::with_options(writer, None, self)?;
214
360
        value.serialize(&mut s)
215
360
    }
216

            
217
    /// Serializes `value` into `writer` in a pretty way.
218
360
    pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
219
360
    where
220
360
        W: fmt::Write,
221
360
        T: ?Sized + ser::Serialize,
222
    {
223
360
        let mut s = Serializer::with_options(writer, Some(config), self)?;
224
360
        value.serialize(&mut s)
225
360
    }
226

            
227
    /// Serializes `value` into `writer`.
228
    ///
229
    /// This function does not generate any newlines or nice formatting;
230
    /// if you want that, you can use
231
    /// [`to_io_writer_pretty`][Self::to_io_writer_pretty] instead.
232
    #[cfg(feature = "std")]
233
    pub fn to_io_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
234
    where
235
        W: io::Write,
236
        T: ?Sized + ser::Serialize,
237
    {
238
        let mut adapter = Adapter {
239
            writer,
240
            error: Ok(()),
241
        };
242
        let result = self.to_writer(&mut adapter, value);
243
        adapter.error?;
244
        result
245
    }
246

            
247
    /// Serializes `value` into `writer` in a pretty way.
248
    #[cfg(feature = "std")]
249
    pub fn to_io_writer_pretty<W, T>(
250
        &self,
251
        writer: W,
252
        value: &T,
253
        config: PrettyConfig,
254
    ) -> Result<()>
255
    where
256
        W: io::Write,
257
        T: ?Sized + ser::Serialize,
258
    {
259
        let mut adapter = Adapter {
260
            writer,
261
            error: Ok(()),
262
        };
263
        let result = self.to_writer_pretty(&mut adapter, value, config);
264
        adapter.error?;
265
        result
266
    }
267

            
268
    /// Serializes `value` and returns it as string.
269
    ///
270
    /// This function does not generate any newlines or nice formatting;
271
    /// if you want that, you can use
272
    /// [`to_string_pretty`][Self::to_string_pretty] instead.
273
1692
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
1692
    where
275
1692
        T: ?Sized + ser::Serialize,
276
    {
277
1692
        let mut output = String::new();
278
1692
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
1692
        value.serialize(&mut s)?;
280
1568
        Ok(output)
281
1692
    }
282

            
283
    /// Serializes `value` in the recommended RON layout in a pretty way.
284
1396
    pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
285
1396
    where
286
1396
        T: ?Sized + ser::Serialize,
287
    {
288
1396
        let mut output = String::new();
289
1396
        let mut s = Serializer::with_options(&mut output, Some(config), self)?;
290
1384
        value.serialize(&mut s)?;
291
1366
        Ok(output)
292
1396
    }
293
}
294

            
295
// Adapter from io::Write to fmt::Write that keeps the error
296
#[cfg(feature = "std")]
297
struct Adapter<W: io::Write> {
298
    writer: W,
299
    error: io::Result<()>,
300
}
301

            
302
#[cfg(feature = "std")]
303
impl<T: io::Write> fmt::Write for Adapter<T> {
304
    fn write_str(&mut self, s: &str) -> fmt::Result {
305
        match self.writer.write_all(s.as_bytes()) {
306
            Ok(()) => Ok(()),
307
            Err(e) => {
308
                self.error = Err(e);
309
                Err(fmt::Error)
310
            }
311
        }
312
    }
313
}