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_string<T>(&self, value: &T) -> Result<String>
220 where
221 T: ?Sized + ser::Serialize,
222 {
223 let mut output = String::new();
224 let mut s = Serializer::with_options(&mut output, None, self)?;
225 value.serialize(&mut s)?;
226 Ok(output)
227 }
228
229 pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
231 where
232 T: ?Sized + ser::Serialize,
233 {
234 let mut output = String::new();
235 let mut s = Serializer::with_options(&mut output, Some(config), self)?;
236 value.serialize(&mut s)?;
237 Ok(output)
238 }
239}