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(not(no_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(not(no_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(not(no_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(not(no_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(not(no_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