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