1
//! Roundtrip serde Options module.
2

            
3
use std::{fmt, io};
4

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

            
8
use 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]
33
pub 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

            
50
impl Default for Options {
51
679843
    fn default() -> Self {
52
679843
        Self {
53
679843
            default_extensions: Extensions::empty(),
54
679843
            recursion_limit: Some(128),
55
679843
        }
56
679843
    }
57
}
58

            
59
impl Options {
60
    #[must_use]
61
    /// Enable `default_extension` by default during serialization and deserialization.
62
2740
    pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
63
2740
        self.default_extensions |= default_extension;
64
2740
        self
65
2740
    }
66

            
67
    #[must_use]
68
    /// Do NOT enable `default_extension` by default during serialization and deserialization.
69
1096
    pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
70
1096
        self.default_extensions &= !default_extension;
71
1096
        self
72
1096
    }
73

            
74
    #[must_use]
75
    /// Set a maximum recursion limit during serialization and deserialization.
76
16
    pub fn with_recursion_limit(mut self, recursion_limit: usize) -> Self {
77
16
        self.recursion_limit = Some(recursion_limit);
78
16
        self
79
16
    }
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
8
    pub fn without_recursion_limit(mut self) -> Self {
87
8
        self.recursion_limit = None;
88
8
        self
89
8
    }
90
}
91

            
92
impl Options {
93
    /// A convenience function for building a deserializer
94
    /// and deserializing a value of type `T` from a reader.
95
296
    pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T>
96
296
    where
97
296
        R: io::Read,
98
296
        T: de::DeserializeOwned,
99
296
    {
100
296
        self.from_reader_seed(rdr, std::marker::PhantomData)
101
296
    }
102

            
103
    /// A convenience function for building a deserializer
104
    /// and deserializing a value of type `T` from a string.
105
25604
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
106
25604
    where
107
25604
        T: de::Deserialize<'a>,
108
25604
    {
109
25604
        self.from_str_seed(s, std::marker::PhantomData)
110
25604
    }
111

            
112
    /// A convenience function for building a deserializer
113
    /// and deserializing a value of type `T` from bytes.
114
312
    pub fn from_bytes<'a, T>(&self, s: &'a [u8]) -> SpannedResult<T>
115
312
    where
116
312
        T: de::Deserialize<'a>,
117
312
    {
118
312
        self.from_bytes_seed(s, std::marker::PhantomData)
119
312
    }
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
296
    pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
127
296
    where
128
296
        R: io::Read,
129
296
        S: for<'a> de::DeserializeSeed<'a, Value = T>,
130
296
    {
131
296
        let mut bytes = Vec::new();
132

            
133
296
        let io_err = if let Err(err) = rdr.read_to_end(&mut bytes) {
134
12
            err
135
        } else {
136
284
            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
12
        let valid_input = match std::str::from_utf8(&bytes) {
143
8
            Ok(valid_input) => valid_input,
144
4
            Err(err) => std::str::from_utf8(&bytes[..err.valid_up_to()])
145
4
                .expect("source is valid up to error"),
146
        };
147

            
148
12
        Err(SpannedError {
149
12
            code: io_err.into(),
150
12
            position: Position::from_src_end(valid_input),
151
12
        })
152
296
    }
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
25620
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
158
25620
    where
159
25620
        S: de::DeserializeSeed<'a, Value = T>,
160
25620
    {
161
25620
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
162

            
163
25600
        let value = seed
164
25600
            .deserialize(&mut deserializer)
165
25600
            .map_err(|e| deserializer.span_error(e))?;
166

            
167
23260
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
168

            
169
23184
        Ok(value)
170
25620
    }
171

            
172
    /// A convenience function for building a deserializer
173
    /// and deserializing a value of type `T` from bytes
174
    /// and a seed.
175
596
    pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
176
596
    where
177
596
        S: de::DeserializeSeed<'a, Value = T>,
178
596
    {
179
596
        let mut deserializer = Deserializer::from_bytes_with_options(s, self)?;
180

            
181
564
        let value = seed
182
564
            .deserialize(&mut deserializer)
183
564
            .map_err(|e| deserializer.span_error(e))?;
184

            
185
352
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
186

            
187
352
        Ok(value)
188
596
    }
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
360
    pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
196
360
    where
197
360
        W: fmt::Write,
198
360
        T: ?Sized + ser::Serialize,
199
360
    {
200
360
        let mut s = Serializer::with_options(writer, None, self)?;
201
360
        value.serialize(&mut s)
202
360
    }
203

            
204
    /// Serializes `value` into `writer` in a pretty way.
205
360
    pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
206
360
    where
207
360
        W: fmt::Write,
208
360
        T: ?Sized + ser::Serialize,
209
360
    {
210
360
        let mut s = Serializer::with_options(writer, Some(config), self)?;
211
360
        value.serialize(&mut s)
212
360
    }
213

            
214
    /// Serializes `value` and returns it as string.
215
    ///
216
    /// This function does not generate any newlines or nice formatting;
217
    /// if you want that, you can use
218
    /// [`to_string_pretty`][Self::to_string_pretty] instead.
219
1692
    pub fn to_string<T>(&self, value: &T) -> Result<String>
220
1692
    where
221
1692
        T: ?Sized + ser::Serialize,
222
1692
    {
223
1692
        let mut output = String::new();
224
1692
        let mut s = Serializer::with_options(&mut output, None, self)?;
225
1692
        value.serialize(&mut s)?;
226
1568
        Ok(output)
227
1692
    }
228

            
229
    /// Serializes `value` in the recommended RON layout in a pretty way.
230
1396
    pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
231
1396
    where
232
1396
        T: ?Sized + ser::Serialize,
233
1396
    {
234
1396
        let mut output = String::new();
235
1396
        let mut s = Serializer::with_options(&mut output, Some(config), self)?;
236
1384
        value.serialize(&mut s)?;
237
1366
        Ok(output)
238
1396
    }
239
}