Coverage Report

Created: 2025-08-03 06:42

/src/ron/src/options.rs
Line
Count
Source (jump to first uncovered line)
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
4.56M
    fn default() -> Self {
60
4.56M
        Self {
61
4.56M
            default_extensions: Extensions::empty(),
62
4.56M
            recursion_limit: Some(128),
63
4.56M
        }
64
4.56M
    }
65
}
66
67
impl Options {
68
    #[must_use]
69
    /// Enable `default_extension` by default during serialization and deserialization.
70
0
    pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
71
0
        self.default_extensions |= default_extension;
72
0
        self
73
0
    }
74
75
    #[must_use]
76
    /// Do NOT enable `default_extension` by default during serialization and deserialization.
77
0
    pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
78
0
        self.default_extensions &= !default_extension;
79
0
        self
80
0
    }
81
82
    #[must_use]
83
    /// Set a maximum recursion limit during serialization and deserialization.
84
16.8k
    pub fn with_recursion_limit(mut self, recursion_limit: usize) -> Self {
85
16.8k
        self.recursion_limit = Some(recursion_limit);
86
16.8k
        self
87
16.8k
    }
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
0
    pub fn without_recursion_limit(mut self) -> Self {
95
0
        self.recursion_limit = None;
96
0
        self
97
0
    }
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
0
    pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T>
105
0
    where
106
0
        R: io::Read,
107
0
        T: de::DeserializeOwned,
108
0
    {
109
0
        self.from_reader_seed(rdr, core::marker::PhantomData)
110
0
    }
111
112
    /// A convenience function for building a deserializer
113
    /// and deserializing a value of type `T` from a string.
114
132k
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
132k
    where
116
132k
        T: de::Deserialize<'a>,
117
132k
    {
118
132k
        self.from_str_seed(s, core::marker::PhantomData)
119
132k
    }
<ron::options::Options>::from_str::<ron::value::Value>
Line
Count
Source
114
10.7k
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
10.7k
    where
116
10.7k
        T: de::Deserialize<'a>,
117
10.7k
    {
118
10.7k
        self.from_str_seed(s, core::marker::PhantomData)
119
10.7k
    }
<ron::options::Options>::from_str::<serde::de::ignored_any::IgnoredAny>
Line
Count
Source
114
77.4k
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
77.4k
    where
116
77.4k
        T: de::Deserialize<'a>,
117
77.4k
    {
118
77.4k
        self.from_str_seed(s, core::marker::PhantomData)
119
77.4k
    }
<ron::options::Options>::from_str::<ron::value::Value>
Line
Count
Source
114
15.0k
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
15.0k
    where
116
15.0k
        T: de::Deserialize<'a>,
117
15.0k
    {
118
15.0k
        self.from_str_seed(s, core::marker::PhantomData)
119
15.0k
    }
<ron::options::Options>::from_str::<alloc::string::String>
Line
Count
Source
114
29.6k
    pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115
29.6k
    where
116
29.6k
        T: de::Deserialize<'a>,
117
29.6k
    {
118
29.6k
        self.from_str_seed(s, core::marker::PhantomData)
119
29.6k
    }
120
121
    /// A convenience function for building a deserializer
122
    /// and deserializing a value of type `T` from bytes.
123
0
    pub fn from_bytes<'a, T>(&self, s: &'a [u8]) -> SpannedResult<T>
124
0
    where
125
0
        T: de::Deserialize<'a>,
126
0
    {
127
0
        self.from_bytes_seed(s, core::marker::PhantomData)
128
0
    }
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
0
    pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
137
0
    where
138
0
        R: io::Read,
139
0
        S: for<'a> de::DeserializeSeed<'a, Value = T>,
140
0
    {
141
0
        let mut bytes = Vec::new();
142
143
0
        let io_err = if let Err(err) = rdr.read_to_end(&mut bytes) {
144
0
            err
145
        } else {
146
0
            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
0
        let valid_input = match core::str::from_utf8(&bytes) {
153
0
            Ok(valid_input) => valid_input,
154
0
            Err(err) => core::str::from_utf8(&bytes[..err.valid_up_to()])
155
0
                .expect("source is valid up to error"),
156
        };
157
158
0
        Err(SpannedError {
159
0
            code: io_err.into(),
160
0
            span: Span {
161
0
                start: Position { line: 1, col: 1 },
162
0
                end: Position::from_src_end(valid_input),
163
0
            },
164
0
        })
165
0
    }
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
132k
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
132k
    where
172
132k
        S: de::DeserializeSeed<'a, Value = T>,
173
132k
    {
174
132k
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176
132k
        let value = seed
177
132k
            .deserialize(&mut deserializer)
178
132k
            .map_err(|e| deserializer.span_error(e))?;
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>::{closure#0}
Line
Count
Source
178
6.84k
            .map_err(|e| deserializer.span_error(e))?;
Unexecuted instantiation: <ron::options::Options>::from_str_seed::<core::marker::PhantomData<serde::de::ignored_any::IgnoredAny>, serde::de::ignored_any::IgnoredAny>::{closure#0}
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>::{closure#0}
Line
Count
Source
178
134
            .map_err(|e| deserializer.span_error(e))?;
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<alloc::string::String>, alloc::string::String>::{closure#0}
Line
Count
Source
178
562
            .map_err(|e| deserializer.span_error(e))?;
179
180
124k
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>::{closure#1}
Line
Count
Source
180
856
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
Unexecuted instantiation: <ron::options::Options>::from_str_seed::<core::marker::PhantomData<serde::de::ignored_any::IgnoredAny>, serde::de::ignored_any::IgnoredAny>::{closure#1}
Unexecuted instantiation: <ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>::{closure#1}
Unexecuted instantiation: <ron::options::Options>::from_str_seed::<core::marker::PhantomData<alloc::string::String>, alloc::string::String>::{closure#1}
181
182
124k
        Ok(value)
183
132k
    }
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>
Line
Count
Source
170
10.7k
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
10.7k
    where
172
10.7k
        S: de::DeserializeSeed<'a, Value = T>,
173
10.7k
    {
174
10.7k
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176
10.2k
        let value = seed
177
10.2k
            .deserialize(&mut deserializer)
178
10.2k
            .map_err(|e| deserializer.span_error(e))?;
179
180
3.40k
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
181
182
2.54k
        Ok(value)
183
10.7k
    }
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<serde::de::ignored_any::IgnoredAny>, serde::de::ignored_any::IgnoredAny>
Line
Count
Source
170
77.4k
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
77.4k
    where
172
77.4k
        S: de::DeserializeSeed<'a, Value = T>,
173
77.4k
    {
174
77.4k
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176
77.4k
        let value = seed
177
77.4k
            .deserialize(&mut deserializer)
178
77.4k
            .map_err(|e| deserializer.span_error(e))?;
179
180
77.4k
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
181
182
77.4k
        Ok(value)
183
77.4k
    }
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<ron::value::Value>, ron::value::Value>
Line
Count
Source
170
15.0k
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
15.0k
    where
172
15.0k
        S: de::DeserializeSeed<'a, Value = T>,
173
15.0k
    {
174
15.0k
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176
15.0k
        let value = seed
177
15.0k
            .deserialize(&mut deserializer)
178
15.0k
            .map_err(|e| deserializer.span_error(e))?;
179
180
14.9k
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
181
182
14.9k
        Ok(value)
183
15.0k
    }
<ron::options::Options>::from_str_seed::<core::marker::PhantomData<alloc::string::String>, alloc::string::String>
Line
Count
Source
170
29.6k
    pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171
29.6k
    where
172
29.6k
        S: de::DeserializeSeed<'a, Value = T>,
173
29.6k
    {
174
29.6k
        let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176
29.6k
        let value = seed
177
29.6k
            .deserialize(&mut deserializer)
178
29.6k
            .map_err(|e| deserializer.span_error(e))?;
179
180
29.1k
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
181
182
29.1k
        Ok(value)
183
29.6k
    }
184
185
    /// A convenience function for building a deserializer
186
    /// and deserializing a value of type `T` from bytes
187
    /// and a seed.
188
0
    pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
189
0
    where
190
0
        S: de::DeserializeSeed<'a, Value = T>,
191
0
    {
192
0
        let mut deserializer = Deserializer::from_bytes_with_options(s, self)?;
193
194
0
        let value = seed
195
0
            .deserialize(&mut deserializer)
196
0
            .map_err(|e| deserializer.span_error(e))?;
197
198
0
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
199
200
0
        Ok(value)
201
0
    }
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
0
    pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
209
0
    where
210
0
        W: fmt::Write,
211
0
        T: ?Sized + ser::Serialize,
212
0
    {
213
0
        let mut s = Serializer::with_options(writer, None, self)?;
214
0
        value.serialize(&mut s)
215
0
    }
216
217
    /// Serializes `value` into `writer` in a pretty way.
218
0
    pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
219
0
    where
220
0
        W: fmt::Write,
221
0
        T: ?Sized + ser::Serialize,
222
0
    {
223
0
        let mut s = Serializer::with_options(writer, Some(config), self)?;
224
0
        value.serialize(&mut s)
225
0
    }
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
0
    pub fn to_io_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
234
0
    where
235
0
        W: io::Write,
236
0
        T: ?Sized + ser::Serialize,
237
0
    {
238
0
        let mut adapter = Adapter {
239
0
            writer,
240
0
            error: Ok(()),
241
0
        };
242
0
        let result = self.to_writer(&mut adapter, value);
243
0
        adapter.error?;
244
0
        result
245
0
    }
246
247
    /// Serializes `value` into `writer` in a pretty way.
248
    #[cfg(feature = "std")]
249
0
    pub fn to_io_writer_pretty<W, T>(
250
0
        &self,
251
0
        writer: W,
252
0
        value: &T,
253
0
        config: PrettyConfig,
254
0
    ) -> Result<()>
255
0
    where
256
0
        W: io::Write,
257
0
        T: ?Sized + ser::Serialize,
258
0
    {
259
0
        let mut adapter = Adapter {
260
0
            writer,
261
0
            error: Ok(()),
262
0
        };
263
0
        let result = self.to_writer_pretty(&mut adapter, value, config);
264
0
        adapter.error?;
265
0
        result
266
0
    }
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
4.29M
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
4.29M
    where
275
4.29M
        T: ?Sized + ser::Serialize,
276
4.29M
    {
277
4.29M
        let mut output = String::new();
278
4.29M
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
4.29M
        value.serialize(&mut s)?;
280
4.29M
        Ok(output)
281
4.29M
    }
<ron::options::Options>::to_string::<ron::value::Value>
Line
Count
Source
273
2.54k
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
2.54k
    where
275
2.54k
        T: ?Sized + ser::Serialize,
276
2.54k
    {
277
2.54k
        let mut output = String::new();
278
2.54k
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
2.54k
        value.serialize(&mut s)?;
280
2.54k
        Ok(output)
281
2.54k
    }
Unexecuted instantiation: <ron::options::Options>::to_string::<_>
<ron::options::Options>::to_string::<dyn erased_serde::ser::Serialize>
Line
Count
Source
273
348k
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
348k
    where
275
348k
        T: ?Sized + ser::Serialize,
276
348k
    {
277
348k
        let mut output = String::new();
278
348k
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
348k
        value.serialize(&mut s)?;
280
348k
        Ok(output)
281
348k
    }
<ron::options::Options>::to_string::<arbitrary::typed_data::BorrowedTypedSerdeData>
Line
Count
Source
273
29.7k
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
29.7k
    where
275
29.7k
        T: ?Sized + ser::Serialize,
276
29.7k
    {
277
29.7k
        let mut output = String::new();
278
29.7k
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
29.7k
        value.serialize(&mut s)?;
280
29.6k
        Ok(output)
281
29.7k
    }
<ron::options::Options>::to_string::<&str>
Line
Count
Source
273
3.42M
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
3.42M
    where
275
3.42M
        T: ?Sized + ser::Serialize,
276
3.42M
    {
277
3.42M
        let mut output = String::new();
278
3.42M
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
3.42M
        value.serialize(&mut s)?;
280
3.42M
        Ok(output)
281
3.42M
    }
<ron::options::Options>::to_string::<str>
Line
Count
Source
273
489k
    pub fn to_string<T>(&self, value: &T) -> Result<String>
274
489k
    where
275
489k
        T: ?Sized + ser::Serialize,
276
489k
    {
277
489k
        let mut output = String::new();
278
489k
        let mut s = Serializer::with_options(&mut output, None, self)?;
279
489k
        value.serialize(&mut s)?;
280
489k
        Ok(output)
281
489k
    }
282
283
    /// Serializes `value` in the recommended RON layout in a pretty way.
284
16.8k
    pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
285
16.8k
    where
286
16.8k
        T: ?Sized + ser::Serialize,
287
16.8k
    {
288
16.8k
        let mut output = String::new();
289
16.8k
        let mut s = Serializer::with_options(&mut output, Some(config), self)?;
290
16.8k
        value.serialize(&mut s)?;
291
15.0k
        Ok(output)
292
16.8k
    }
Unexecuted instantiation: <ron::options::Options>::to_string_pretty::<_>
<ron::options::Options>::to_string_pretty::<arbitrary::typed_data::TypedSerdeData>
Line
Count
Source
284
16.8k
    pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
285
16.8k
    where
286
16.8k
        T: ?Sized + ser::Serialize,
287
16.8k
    {
288
16.8k
        let mut output = String::new();
289
16.8k
        let mut s = Serializer::with_options(&mut output, Some(config), self)?;
290
16.8k
        value.serialize(&mut s)?;
291
15.0k
        Ok(output)
292
16.8k
    }
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
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
305
0
        match self.writer.write_all(s.as_bytes()) {
306
0
            Ok(()) => Ok(()),
307
0
            Err(e) => {
308
0
                self.error = Err(e);
309
0
                Err(fmt::Error)
310
            }
311
        }
312
0
    }
313
}