1#![cfg_attr(not(feature = "std"), no_std)]
104
105#[cfg(feature = "alloc")]
106extern crate alloc;
107
108mod buffer;
109mod config;
110pub mod de;
111pub mod docs;
112mod error;
113mod format;
114mod io;
115pub mod ser;
116#[cfg(feature = "alloc")]
117pub mod value;
118
119#[allow(unused_imports, reason = "Different feature sets")]
120use ::serde::{Deserialize, Serialize, de::DeserializeOwned};
121#[cfg(feature = "std")]
122use ::std::io::{Read, Write};
123
124#[cfg(feature = "alloc")]
125pub use self::value::{from_value, from_value_with_config, to_value, to_value_with_config};
126pub use self::{config::Config, de::Deserializer, error::Error, ser::Serializer};
127
128pub type Result<T, E = Error> = ::core::result::Result<T, E>;
130
131#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
134pub fn to_slice_with_config<'buf, T>(
135 value: &T,
136 buffer: &'buf mut [u8],
137 config: Config,
138) -> Result<&'buf mut [u8]>
139where
140 T: Serialize,
141{
142 let remaining = if let Some(max) = config.max_size {
143 let mut ser = Serializer::new(io::SizeLimit::new(&mut *buffer, max.into()))
144 .use_indices(config.use_indices);
145 value.serialize(&mut ser)?;
146 ser.into_output().into_inner().len()
147 } else {
148 let mut ser = Serializer::new(&mut *buffer).use_indices(config.use_indices);
149 value.serialize(&mut ser)?;
150 ser.into_output().len()
151 };
152
153 let used = buffer.len() - remaining;
154 Ok(buffer.split_at_mut(used).0)
155}
156
157pub fn to_slice<'buf, T>(value: &T, buffer: &'buf mut [u8]) -> Result<&'buf mut [u8]>
159where
160 T: Serialize,
161{
162 to_slice_with_config(value, buffer, Config::default())
163}
164
165#[cfg(feature = "alloc")]
167#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
168pub fn to_vec_with_config<T>(value: &T, config: Config) -> Result<::alloc::vec::Vec<u8>>
169where
170 T: Serialize,
171{
172 if let Some(max) = config.max_size {
173 let mut ser = Serializer::new(io::SizeLimit::new(::alloc::vec::Vec::new(), max.into()))
174 .use_indices(config.use_indices);
175 value.serialize(&mut ser)?;
176 Ok(ser.into_output().into_inner())
177 } else {
178 let mut ser = Serializer::new(::alloc::vec::Vec::new()).use_indices(config.use_indices);
179 value.serialize(&mut ser)?;
180 Ok(ser.into_output())
181 }
182}
183
184#[cfg(feature = "alloc")]
186pub fn to_vec<T>(value: &T) -> Result<::alloc::vec::Vec<u8>>
187where
188 T: Serialize,
189{
190 to_vec_with_config(value, Config::default())
191}
192
193#[cfg(feature = "heapless")]
195#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
196pub fn to_heapless_vec_with_config<const N: usize, T>(
197 value: &T,
198 config: Config,
199) -> Result<::heapless::Vec<u8, N>>
200where
201 T: Serialize,
202{
203 if let Some(max) = config.max_size {
204 let mut ser = Serializer::new(io::SizeLimit::new(::heapless::Vec::new(), max.into()))
205 .use_indices(config.use_indices);
206 value.serialize(&mut ser)?;
207 Ok(ser.into_output().into_inner())
208 } else {
209 let mut ser = Serializer::new(::heapless::Vec::new()).use_indices(config.use_indices);
210 value.serialize(&mut ser)?;
211 Ok(ser.into_output())
212 }
213}
214
215#[cfg(feature = "heapless")]
217pub fn to_heapless_vec<const N: usize, T>(value: &T) -> Result<::heapless::Vec<u8, N>>
218where
219 T: Serialize,
220{
221 to_heapless_vec_with_config(value, Config::default())
222}
223
224#[cfg(feature = "std")]
226#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
227pub fn to_writer_with_config<T, W>(value: &T, writer: W, config: Config) -> Result<()>
228where
229 T: Serialize,
230 W: Write,
231{
232 if let Some(max) = config.max_size {
233 let mut ser = Serializer::new(io::SizeLimit::new(io::IoWriter::new(writer), max.into()))
234 .use_indices(config.use_indices);
235 value.serialize(&mut ser)?;
236 } else {
237 let mut ser = Serializer::new(io::IoWriter::new(writer)).use_indices(config.use_indices);
238 value.serialize(&mut ser)?;
239 }
240 Ok(())
241}
242
243#[cfg(feature = "std")]
245pub fn to_writer<T, W>(value: &T, writer: W) -> Result<()>
246where
247 T: Serialize,
248 W: Write,
249{
250 to_writer_with_config(value, writer, Config::default())
251}
252
253#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
255pub fn from_slice_with_config<'de, T>(bytes: &'de [u8], config: Config) -> Result<T>
256where
257 T: Deserialize<'de>,
258{
259 let error_on_excess = config.error_on_excess_data;
260
261 let (value, peek) = if let Some(max) = config.max_size {
262 let mut de = Deserializer::new(io::SizeLimit::new(bytes, max.into()));
264 (T::deserialize(&mut de)?, io::Input::peek_byte(&mut de.into_input()))
265 } else {
266 let mut de = Deserializer::new(bytes);
268 (T::deserialize(&mut de)?, io::Input::peek_byte(&mut de.into_input()))
269 };
270
271 if error_on_excess && peek.is_ok() {
272 return Err(Error::ExcessData);
273 }
274
275 Ok(value)
276}
277
278pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T>
280where
281 T: Deserialize<'de>,
282{
283 from_slice_with_config(bytes, Config::default())
284}
285
286#[cfg(feature = "std")]
288#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all, fields(config)))]
289pub fn from_reader_with_config<R, T>(reader: R, config: Config) -> Result<T>
290where
291 R: Read,
292 T: DeserializeOwned,
293{
294 let error_on_excess = config.error_on_excess_data;
295
296 let (value, peek) = if let Some(max) = config.max_size {
297 let mut de = Deserializer::new(io::SizeLimit::new(io::IoReader::new(reader), max.into()))
299 .with_buffer(Vec::new());
300 (T::deserialize(&mut de)?, io::Input::peek_byte(&mut de.into_input()))
301 } else {
302 let mut de = Deserializer::new(io::IoReader::new(reader)).with_buffer(Vec::new());
304 (T::deserialize(&mut de)?, io::Input::peek_byte(&mut de.into_input()))
305 };
306
307 if error_on_excess && peek.is_ok() {
308 return Err(Error::ExcessData);
309 }
310
311 Ok(value)
312}
313
314#[cfg(feature = "std")]
316pub fn from_reader<R, T>(reader: R) -> Result<T>
317where
318 R: Read,
319 T: DeserializeOwned,
320{
321 from_reader_with_config(reader, Config::default())
322}
323
324#[cfg(test)]
325mod tests;