1use 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#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)]
32#[non_exhaustive]
33pub struct Options {
34    pub default_extensions: Extensions,
42    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    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    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    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    pub fn without_recursion_limit(mut self) -> Self {
87        self.recursion_limit = None;
88        self
89    }
90}
91
92impl Options {
93    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    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    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    #[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        #[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    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    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    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    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    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    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    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    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
280struct 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}