1 use crate::de::Deserializer;
2 use crate::ser::Serializer;
3 use crate::token::Token;
4 use serde::{Deserialize, Serialize};
5 use std::fmt::Debug;
6 
7 /// Runs both `assert_ser_tokens` and `assert_de_tokens`.
8 ///
9 /// ```
10 /// # use serde_derive::{Deserialize, Serialize};
11 /// # use serde_test::{assert_tokens, Token};
12 /// #
13 /// #[derive(Serialize, Deserialize, PartialEq, Debug)]
14 /// struct S {
15 ///     a: u8,
16 ///     b: u8,
17 /// }
18 ///
19 /// let s = S { a: 0, b: 0 };
20 /// assert_tokens(
21 ///     &s,
22 ///     &[
23 ///         Token::Struct { name: "S", len: 2 },
24 ///         Token::Str("a"),
25 ///         Token::U8(0),
26 ///         Token::Str("b"),
27 ///         Token::U8(0),
28 ///         Token::StructEnd,
29 ///     ],
30 /// );
31 /// ```
32 #[cfg_attr(not(no_track_caller), track_caller)]
assert_tokens<'de, T>(value: &T, tokens: &'de [Token]) where T: Serialize + Deserialize<'de> + PartialEq + Debug,33 pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
34 where
35     T: Serialize + Deserialize<'de> + PartialEq + Debug,
36 {
37     assert_ser_tokens(value, tokens);
38     assert_de_tokens(value, tokens);
39 }
40 
41 /// Asserts that `value` serializes to the given `tokens`.
42 ///
43 /// ```
44 /// # use serde_derive::{Deserialize, Serialize};
45 /// # use serde_test::{assert_ser_tokens, Token};
46 /// #
47 /// #[derive(Serialize, Deserialize, PartialEq, Debug)]
48 /// struct S {
49 ///     a: u8,
50 ///     b: u8,
51 /// }
52 ///
53 /// let s = S { a: 0, b: 0 };
54 /// assert_ser_tokens(
55 ///     &s,
56 ///     &[
57 ///         Token::Struct { name: "S", len: 2 },
58 ///         Token::Str("a"),
59 ///         Token::U8(0),
60 ///         Token::Str("b"),
61 ///         Token::U8(0),
62 ///         Token::StructEnd,
63 ///     ],
64 /// );
65 /// ```
66 #[cfg_attr(not(no_track_caller), track_caller)]
assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token]) where T: Serialize,67 pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
68 where
69     T: Serialize,
70 {
71     let mut ser = Serializer::new(tokens);
72     match value.serialize(&mut ser) {
73         Ok(_) => {}
74         Err(err) => panic!("value failed to serialize: {}", err),
75     }
76 
77     if ser.remaining() > 0 {
78         panic!("{} remaining tokens", ser.remaining());
79     }
80 }
81 
82 /// Asserts that `value` serializes to the given `tokens`, and then yields
83 /// `error`.
84 ///
85 /// ```
86 /// use serde_derive::Serialize;
87 /// use serde_test::{assert_ser_tokens_error, Token};
88 /// use std::sync::{Arc, Mutex};
89 /// use std::thread;
90 ///
91 /// #[derive(Serialize)]
92 /// struct Example {
93 ///     lock: Arc<Mutex<u32>>,
94 /// }
95 ///
96 /// fn main() {
97 ///     let example = Example {
98 ///         lock: Arc::new(Mutex::new(0)),
99 ///     };
100 ///     let lock = example.lock.clone();
101 ///
102 ///     let thread = thread::spawn(move || {
103 ///         // This thread will acquire the mutex first, unwrapping the result
104 ///         // of `lock` because the lock has not been poisoned.
105 ///         let _guard = lock.lock().unwrap();
106 ///
107 ///         // This panic while holding the lock (`_guard` is in scope) will
108 ///         // poison the mutex.
109 ///         panic!()
110 ///     });
111 ///     thread.join();
112 ///
113 ///     let expected = &[
114 ///         Token::Struct {
115 ///             name: "Example",
116 ///             len: 1,
117 ///         },
118 ///         Token::Str("lock"),
119 ///     ];
120 ///     let error = "lock poison error while serializing";
121 ///     assert_ser_tokens_error(&example, expected, error);
122 /// }
123 /// ```
124 #[cfg_attr(not(no_track_caller), track_caller)]
assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str) where T: Serialize,125 pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
126 where
127     T: Serialize,
128 {
129     let mut ser = Serializer::new(tokens);
130     match value.serialize(&mut ser) {
131         Ok(_) => panic!("value serialized successfully"),
132         Err(e) => assert_eq!(e, *error),
133     }
134 
135     if ser.remaining() > 0 {
136         panic!("{} remaining tokens", ser.remaining());
137     }
138 }
139 
140 /// Asserts that the given `tokens` deserialize into `value`.
141 ///
142 /// ```
143 /// # use serde_derive::{Deserialize, Serialize};
144 /// # use serde_test::{assert_de_tokens, Token};
145 /// #
146 /// #[derive(Serialize, Deserialize, PartialEq, Debug)]
147 /// struct S {
148 ///     a: u8,
149 ///     b: u8,
150 /// }
151 ///
152 /// let s = S { a: 0, b: 0 };
153 /// assert_de_tokens(
154 ///     &s,
155 ///     &[
156 ///         Token::Struct { name: "S", len: 2 },
157 ///         Token::Str("a"),
158 ///         Token::U8(0),
159 ///         Token::Str("b"),
160 ///         Token::U8(0),
161 ///         Token::StructEnd,
162 ///     ],
163 /// );
164 /// ```
165 #[cfg_attr(not(no_track_caller), track_caller)]
assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token]) where T: Deserialize<'de> + PartialEq + Debug,166 pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
167 where
168     T: Deserialize<'de> + PartialEq + Debug,
169 {
170     let mut de = Deserializer::new(tokens);
171     let mut deserialized_val = match T::deserialize(&mut de) {
172         Ok(v) => {
173             assert_eq!(v, *value);
174             v
175         }
176         Err(e) => panic!("tokens failed to deserialize: {}", e),
177     };
178     if de.remaining() > 0 {
179         panic!("{} remaining tokens", de.remaining());
180     }
181 
182     // Do the same thing for deserialize_in_place. This isn't *great* because a
183     // no-op impl of deserialize_in_place can technically succeed here. Still,
184     // this should catch a lot of junk.
185     let mut de = Deserializer::new(tokens);
186     match T::deserialize_in_place(&mut de, &mut deserialized_val) {
187         Ok(()) => {
188             assert_eq!(deserialized_val, *value);
189         }
190         Err(e) => panic!("tokens failed to deserialize_in_place: {}", e),
191     }
192     if de.remaining() > 0 {
193         panic!("{} remaining tokens", de.remaining());
194     }
195 }
196 
197 /// Asserts that the given `tokens` yield `error` when deserializing.
198 ///
199 /// ```
200 /// # use serde_derive::{Deserialize, Serialize};
201 /// # use serde_test::{assert_de_tokens_error, Token};
202 /// #
203 /// #[derive(Serialize, Deserialize, PartialEq, Debug)]
204 /// #[serde(deny_unknown_fields)]
205 /// struct S {
206 ///     a: u8,
207 ///     b: u8,
208 /// }
209 ///
210 /// assert_de_tokens_error::<S>(
211 ///     &[
212 ///         Token::Struct { name: "S", len: 2 },
213 ///         Token::Str("x"),
214 ///     ],
215 ///     "unknown field `x`, expected `a` or `b`",
216 /// );
217 /// ```
218 #[cfg_attr(not(no_track_caller), track_caller)]
assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str) where T: Deserialize<'de>,219 pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
220 where
221     T: Deserialize<'de>,
222 {
223     let mut de = Deserializer::new(tokens);
224     match T::deserialize(&mut de) {
225         Ok(_) => panic!("tokens deserialized successfully"),
226         Err(e) => assert_eq!(e, *error),
227     }
228 
229     // There may be one token left if a peek caused the error
230     de.next_token_opt();
231 
232     if de.remaining() > 0 {
233         panic!("{} remaining tokens", de.remaining());
234     }
235 }
236