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