1use alloc::string::String;
4use core::fmt;
5
6use serde::{de, ser};
7use serde_derive::{Deserialize, Serialize};
8
9use crate::{
10 de::Deserializer,
11 error::{Result, SpannedResult},
12 extensions::Extensions,
13 ser::{PrettyConfig, Serializer},
14};
15
16#[cfg(feature = "std")]
17use {
18 crate::error::{Position, Span, SpannedError},
19 alloc::vec::Vec,
20 std::io,
21};
22
23#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)]
40#[non_exhaustive]
41pub struct Options {
42 pub default_extensions: Extensions,
50 pub recursion_limit: Option<usize>,
56}
57
58impl Default for Options {
59 fn default() -> Self {
60 Self {
61 default_extensions: Extensions::empty(),
62 recursion_limit: Some(128),
63 }
64 }
65}
66
67impl Options {
68 #[must_use]
69 pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
71 self.default_extensions |= default_extension;
72 self
73 }
74
75 #[must_use]
76 pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
78 self.default_extensions &= !default_extension;
79 self
80 }
81
82 #[must_use]
83 pub fn with_recursion_limit(mut self, recursion_limit: usize) -> Self {
85 self.recursion_limit = Some(recursion_limit);
86 self
87 }
88
89 #[must_use]
90 pub fn without_recursion_limit(mut self) -> Self {
95 self.recursion_limit = None;
96 self
97 }
98}
99
100impl Options {
101 #[cfg(feature = "std")]
104 pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T>
105 where
106 R: io::Read,
107 T: de::DeserializeOwned,
108 {
109 self.from_reader_seed(rdr, core::marker::PhantomData)
110 }
111
112 pub fn from_str<'a, T>(&self, s: &'a str) -> SpannedResult<T>
115 where
116 T: de::Deserialize<'a>,
117 {
118 self.from_str_seed(s, core::marker::PhantomData)
119 }
120
121 pub fn from_bytes<'a, T>(&self, s: &'a [u8]) -> SpannedResult<T>
124 where
125 T: de::Deserialize<'a>,
126 {
127 self.from_bytes_seed(s, core::marker::PhantomData)
128 }
129
130 #[allow(clippy::missing_panics_doc)]
135 #[cfg(feature = "std")]
136 pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
137 where
138 R: io::Read,
139 S: for<'a> de::DeserializeSeed<'a, Value = T>,
140 {
141 let mut bytes = Vec::new();
142
143 let io_err = if let Err(err) = rdr.read_to_end(&mut bytes) {
144 err
145 } else {
146 return self.from_bytes_seed(&bytes, seed);
147 };
148
149 #[allow(clippy::expect_used)]
152 let valid_input = match core::str::from_utf8(&bytes) {
153 Ok(valid_input) => valid_input,
154 Err(err) => core::str::from_utf8(&bytes[..err.valid_up_to()])
155 .expect("source is valid up to error"),
156 };
157
158 Err(SpannedError {
159 code: io_err.into(),
160 span: Span {
161 start: Position { line: 1, col: 1 },
162 end: Position::from_src_end(valid_input),
163 },
164 })
165 }
166
167 pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
171 where
172 S: de::DeserializeSeed<'a, Value = T>,
173 {
174 let mut deserializer = Deserializer::from_str_with_options(s, self)?;
175
176 let value = seed
177 .deserialize(&mut deserializer)
178 .map_err(|e| deserializer.span_error(e))?;
179
180 deserializer.end().map_err(|e| deserializer.span_error(e))?;
181
182 Ok(value)
183 }
184
185 pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
189 where
190 S: de::DeserializeSeed<'a, Value = T>,
191 {
192 let mut deserializer = Deserializer::from_bytes_with_options(s, self)?;
193
194 let value = seed
195 .deserialize(&mut deserializer)
196 .map_err(|e| deserializer.span_error(e))?;
197
198 deserializer.end().map_err(|e| deserializer.span_error(e))?;
199
200 Ok(value)
201 }
202
203 pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
209 where
210 W: fmt::Write,
211 T: ?Sized + ser::Serialize,
212 {
213 let mut s = Serializer::with_options(writer, None, self)?;
214 value.serialize(&mut s)
215 }
216
217 pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
219 where
220 W: fmt::Write,
221 T: ?Sized + ser::Serialize,
222 {
223 let mut s = Serializer::with_options(writer, Some(config), self)?;
224 value.serialize(&mut s)
225 }
226
227 #[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 #[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 pub fn to_string<T>(&self, value: &T) -> Result<String>
274 where
275 T: ?Sized + ser::Serialize,
276 {
277 let mut output = String::new();
278 let mut s = Serializer::with_options(&mut output, None, self)?;
279 value.serialize(&mut s)?;
280 Ok(output)
281 }
282
283 pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
285 where
286 T: ?Sized + ser::Serialize,
287 {
288 let mut output = String::new();
289 let mut s = Serializer::with_options(&mut output, Some(config), self)?;
290 value.serialize(&mut s)?;
291 Ok(output)
292 }
293}
294
295#[cfg(feature = "std")]
297struct Adapter<W: io::Write> {
298 writer: W,
299 error: io::Result<()>,
300}
301
302#[cfg(feature = "std")]
303impl<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}