serde_state/lib.rs
1// Copyright 2017 Serde Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8#![allow(deprecated)] // For try!
9
10//! # serde_state
11//!
12//! `serde_state` is a crate which extends the normal `Deserialize` and `Serialize` traits to allow
13//! state to be passed to every value which is serialized or deserialized.
14//!
15//! ## Example
16//!
17//! ```
18//! extern crate serde_json;
19//! extern crate serde_state as serde;
20//! #[macro_use]
21//! extern crate serde_derive;
22//! #[macro_use]
23//! extern crate serde_derive_state;
24//!
25//! use std::borrow::BorrowMut;
26//! use std::cell::Cell;
27//! use serde::ser::{Serialize, Serializer, SerializeState};
28//! use serde::de::{Deserialize, Deserializer, DeserializeState};
29//!
30//! #[derive(Deserialize, Serialize)]
31//! struct Inner;
32//!
33//! impl SerializeState<Cell<i32>> for Inner {
34//!
35//! fn serialize_state<S>(&self, serializer: S, seed: &Cell<i32>) -> Result<S::Ok, S::Error>
36//! where
37//! S: Serializer,
38//! {
39//! seed.set(seed.get() + 1);
40//! self.serialize(serializer)
41//! }
42//! }
43//!
44//! impl<'de, S> DeserializeState<'de, S> for Inner where S: BorrowMut<i32> {
45//!
46//! fn deserialize_state<D>(seed: &mut S, deserializer: D) -> Result<Self, D::Error>
47//! where
48//! D: Deserializer<'de>,
49//! {
50//! *seed.borrow_mut() += 1;
51//! Self::deserialize(deserializer)
52//! }
53//! }
54//!
55//! #[derive(SerializeState, DeserializeState)]
56//!
57//! // `serialize_state` or `deserialize_state` is necessary to tell the derived implementation which
58//! // seed that is passed
59//! #[serde(serialize_state = "Cell<i32>")]
60//!
61//! // `de_parameters` can be used to specify additional type parameters for the derived instance
62//! #[serde(de_parameters = "S")]
63//! #[serde(bound(deserialize = "S: BorrowMut<i32>"))]
64//! #[serde(deserialize_state = "S")]
65//! struct Struct {
66//! // The `serialize_state` attribute must be specified to use seeded serialization
67//! #[serde(serialize_state)]
68//! // The `deserialize_state` attribute must be specified to use seeded deserialization
69//! #[serde(deserialize_state)]
70//! value: Inner,
71//!
72//! // The `seed` attribute can be used to specify `deserialize_state` and `serialize_state`
73//! // simultaneously
74//! #[serde(state)]
75//! value2: Inner,
76//!
77//! // If no attributes are specified then normal serialization and/or deserialization is used
78//! value3: Inner,
79//!
80//! // The `[de]serialize_state_with` attribute can be used to specify a custom function which
81//! // does the serialization or deserialization
82//! #[serde(serialize_state_with = "serialize_inner")]
83//! value4: Inner,
84//! }
85//!
86//! fn serialize_inner<S>(self_: &Inner, serializer: S, seed: &Cell<i32>) -> Result<S::Ok, S::Error>
87//! where S: Serializer
88//! {
89//! seed.set(seed.get() + 10);
90//! self_.serialize(serializer)
91//! }
92//!
93//! fn main() {
94//! let s = Struct {
95//! value: Inner,
96//! value2: Inner,
97//! value3: Inner,
98//! value4: Inner,
99//! };
100//!
101//! let mut buffer = Vec::new();
102//! {
103//! let mut serializer = serde_json::Serializer::pretty(&mut buffer);
104//! let seed = Cell::new(0);
105//! s.serialize_state(&mut serializer, &seed).unwrap();
106//! assert_eq!(seed.get(), 12);
107//! }
108//! {
109//! let mut deserializer = serde_json::Deserializer::from_slice(&buffer);
110//! let mut seed = 0;
111//! Struct::deserialize_state(&mut seed, &mut deserializer).unwrap();
112//! assert_eq!(seed, 2);
113//! }
114//! }
115//!
116//! ```
117
118////////////////////////////////////////////////////////////////////////////////
119
120// Serde types in rustdoc of other crates get linked to here.
121#![doc(html_root_url = "https://docs.rs/serde/1.0.8")]
122// Support using Serde without the standard library!
123#![cfg_attr(not(feature = "std"), no_std)]
124// Unstable functionality only if the user asks for it. For tracking and
125// discussion of these features please refer to this issue:
126//
127// https://github.com/serde-rs/serde/issues/812
128#![cfg_attr(feature = "unstable", feature(never_type))]
129// Whitelisted clippy lints.
130#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
131#![cfg_attr(feature = "cargo-clippy", allow(linkedlist))]
132#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
133#![cfg_attr(feature = "cargo-clippy", allow(zero_prefixed_literal))]
134// Blacklisted Rust lints.
135#![deny(missing_docs, unused_imports)]
136
137////////////////////////////////////////////////////////////////////////////////
138
139#[cfg(feature = "alloc")]
140extern crate alloc;
141
142#[cfg(all(feature = "unstable", feature = "std"))]
143extern crate core;
144
145#[macro_use]
146extern crate serde;
147
148/// A facade around all the types we need from the `std`, `core`, `alloc`, and
149/// `collections` crates. This avoids elaborate import wrangling having to
150/// happen in every module.
151mod lib {
152 mod core {
153 #[cfg(not(feature = "std"))]
154 pub use core::*;
155 #[cfg(feature = "std")]
156 pub use std::*;
157 }
158
159 pub use self::core::{cmp, iter, mem, ops, slice, str};
160 pub use self::core::{f32, f64};
161 pub use self::core::{i16, i32, i64, i8, isize};
162 pub use self::core::{u16, u32, u64, u8, usize};
163
164 pub use self::core::cell::{Cell, RefCell};
165 pub use self::core::clone::{self, Clone};
166 pub use self::core::convert::{self, From, Into};
167 pub use self::core::default::{self, Default};
168 pub use self::core::fmt::{self, Debug, Display};
169 pub use self::core::marker::{self, PhantomData};
170 pub use self::core::option::{self, Option};
171 pub use self::core::result::{self, Result};
172
173 #[cfg(all(feature = "alloc", not(feature = "std")))]
174 pub use collections::borrow::{Cow, ToOwned};
175 #[cfg(feature = "std")]
176 pub use std::borrow::{Cow, ToOwned};
177
178 #[cfg(all(feature = "alloc", not(feature = "std")))]
179 pub use collections::string::{String, ToString};
180 #[cfg(feature = "std")]
181 pub use std::string::String;
182
183 #[cfg(all(feature = "alloc", not(feature = "std")))]
184 pub use collections::vec::Vec;
185 #[cfg(feature = "std")]
186 pub use std::vec::Vec;
187
188 #[cfg(all(feature = "alloc", not(feature = "std")))]
189 pub use alloc::boxed::Box;
190 #[cfg(feature = "std")]
191 pub use std::boxed::Box;
192
193 #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
194 pub use alloc::rc::Rc;
195 #[cfg(all(feature = "rc", feature = "std"))]
196 pub use std::rc::Rc;
197
198 #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
199 pub use alloc::arc::Arc;
200 #[cfg(all(feature = "rc", feature = "std"))]
201 pub use std::sync::Arc;
202
203 #[cfg(all(feature = "alloc", not(feature = "std")))]
204 pub use collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
205 #[cfg(feature = "std")]
206 pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
207
208 #[cfg(feature = "std")]
209 pub use std::{error, net};
210
211 #[cfg(feature = "std")]
212 pub use std::collections::{HashMap, HashSet};
213 #[cfg(feature = "std")]
214 pub use std::ffi::{CStr, CString, OsStr, OsString};
215 #[cfg(feature = "std")]
216 pub use std::hash::{BuildHasher, Hash};
217 #[cfg(feature = "std")]
218 pub use std::io::Write;
219 #[cfg(feature = "std")]
220 pub use std::path::{Path, PathBuf};
221 #[cfg(feature = "std")]
222 pub use std::sync::{Mutex, RwLock};
223 #[cfg(feature = "std")]
224 pub use std::time::Duration;
225}
226
227////////////////////////////////////////////////////////////////////////////////
228
229pub mod de;
230pub mod ser;
231
232#[doc(hidden)]
233pub mod private;
234
235#[doc(hidden)]
236pub use serde::*;
237
238#[doc(inline)]
239pub use de::{Deserialize, DeserializeState, Deserializer};
240#[doc(inline)]
241pub use ser::{Serialize, SerializeState, Serializer};