value_bag/
test.rs

1//! Test support for inspecting values.
2
3use crate::{
4    internal,
5    std::{fmt, str, string::String},
6    visit::Visit,
7    Error, ValueBag,
8};
9
10#[cfg(test)]
11pub(crate) trait IntoValueBag<'v> {
12    fn into_value_bag(self) -> ValueBag<'v>;
13}
14
15#[cfg(test)]
16impl<'v, T> IntoValueBag<'v> for T
17where
18    T: Into<ValueBag<'v>>,
19{
20    fn into_value_bag(self) -> ValueBag<'v> {
21        self.into()
22    }
23}
24
25/**
26A tokenized representation of the captured value for testing.
27*/
28#[derive(Debug, PartialEq)]
29#[non_exhaustive]
30pub enum TestToken {
31    U64(u64),
32    I64(i64),
33    F64(f64),
34    U128(u128),
35    I128(i128),
36    Char(char),
37    Bool(bool),
38    Str(String),
39    None,
40
41    #[cfg(feature = "error")]
42    Error,
43
44    #[cfg(feature = "sval2")]
45    Sval {
46        version: u32,
47    },
48
49    #[cfg(feature = "serde1")]
50    Serde {
51        version: u32,
52    },
53
54    #[cfg(feature = "seq")]
55    Seq,
56
57    Poisoned(String),
58}
59
60impl<'v> ValueBag<'v> {
61    /**
62    Convert the value bag into a token for testing.
63
64    This _isn't_ a general-purpose API for working with values outside of testing.
65    */
66    pub fn to_test_token(&self) -> TestToken {
67        struct TestVisitor(Option<TestToken>);
68
69        impl<'v> internal::InternalVisitor<'v> for TestVisitor {
70            fn fill(&mut self, v: &dyn crate::fill::Fill) -> Result<(), Error> {
71                v.fill(crate::fill::Slot::new(self))
72            }
73
74            fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error> {
75                self.0 = Some(TestToken::Str(format!("{:?}", v)));
76                Ok(())
77            }
78
79            fn display(&mut self, v: &dyn fmt::Display) -> Result<(), Error> {
80                self.0 = Some(TestToken::Str(format!("{}", v)));
81                Ok(())
82            }
83
84            fn u64(&mut self, v: u64) -> Result<(), Error> {
85                self.0 = Some(TestToken::U64(v));
86                Ok(())
87            }
88
89            fn i64(&mut self, v: i64) -> Result<(), Error> {
90                self.0 = Some(TestToken::I64(v));
91                Ok(())
92            }
93
94            fn u128(&mut self, v: &u128) -> Result<(), Error> {
95                self.0 = Some(TestToken::U128(*v));
96                Ok(())
97            }
98
99            fn i128(&mut self, v: &i128) -> Result<(), Error> {
100                self.0 = Some(TestToken::I128(*v));
101                Ok(())
102            }
103
104            fn f64(&mut self, v: f64) -> Result<(), Error> {
105                self.0 = Some(TestToken::F64(v));
106                Ok(())
107            }
108
109            fn bool(&mut self, v: bool) -> Result<(), Error> {
110                self.0 = Some(TestToken::Bool(v));
111                Ok(())
112            }
113
114            fn char(&mut self, v: char) -> Result<(), Error> {
115                self.0 = Some(TestToken::Char(v));
116                Ok(())
117            }
118
119            fn str(&mut self, v: &str) -> Result<(), Error> {
120                self.0 = Some(TestToken::Str(v.into()));
121                Ok(())
122            }
123
124            fn none(&mut self) -> Result<(), Error> {
125                self.0 = Some(TestToken::None);
126                Ok(())
127            }
128
129            #[cfg(feature = "error")]
130            fn error(&mut self, _: &dyn internal::error::Error) -> Result<(), Error> {
131                self.0 = Some(TestToken::Error);
132                Ok(())
133            }
134
135            #[cfg(feature = "sval2")]
136            fn sval2(&mut self, _: &dyn internal::sval::v2::Value) -> Result<(), Error> {
137                self.0 = Some(TestToken::Sval { version: 2 });
138                Ok(())
139            }
140
141            #[cfg(feature = "serde1")]
142            fn serde1(&mut self, _: &dyn internal::serde::v1::Serialize) -> Result<(), Error> {
143                self.0 = Some(TestToken::Serde { version: 1 });
144                Ok(())
145            }
146
147            #[cfg(feature = "seq")]
148            fn seq(&mut self, _: &dyn internal::seq::Seq) -> Result<(), Error> {
149                self.0 = Some(TestToken::Seq);
150                Ok(())
151            }
152
153            fn poisoned(&mut self, msg: &'static str) -> Result<(), Error> {
154                self.0 = Some(TestToken::Poisoned(msg.into()));
155                Ok(())
156            }
157        }
158
159        let mut visitor = TestVisitor(None);
160        self.internal_visit(&mut visitor).unwrap();
161
162        visitor.0.unwrap()
163    }
164}
165
166pub(crate) struct TestVisit {
167    pub i64: i64,
168    pub u64: u64,
169    pub i128: i128,
170    pub u128: u128,
171    pub f64: f64,
172    pub bool: bool,
173    pub str: &'static str,
174    pub borrowed_str: &'static str,
175    pub char: char,
176}
177
178impl Default for TestVisit {
179    fn default() -> Self {
180        TestVisit {
181            i64: -42,
182            u64: 42,
183            i128: -42,
184            u128: 42,
185            f64: 11.0,
186            bool: true,
187            str: "some string",
188            borrowed_str: "some borrowed string",
189            char: 'n',
190        }
191    }
192}
193
194impl<'v> Visit<'v> for TestVisit {
195    fn visit_any(&mut self, v: ValueBag) -> Result<(), Error> {
196        panic!("unexpected value: {}", v)
197    }
198
199    fn visit_i64(&mut self, v: i64) -> Result<(), Error> {
200        assert_eq!(self.i64, v);
201        Ok(())
202    }
203
204    fn visit_u64(&mut self, v: u64) -> Result<(), Error> {
205        assert_eq!(self.u64, v);
206        Ok(())
207    }
208
209    fn visit_i128(&mut self, v: i128) -> Result<(), Error> {
210        assert_eq!(self.i128, v);
211        Ok(())
212    }
213
214    fn visit_u128(&mut self, v: u128) -> Result<(), Error> {
215        assert_eq!(self.u128, v);
216        Ok(())
217    }
218
219    fn visit_f64(&mut self, v: f64) -> Result<(), Error> {
220        assert_eq!(self.f64, v);
221        Ok(())
222    }
223
224    fn visit_bool(&mut self, v: bool) -> Result<(), Error> {
225        assert_eq!(self.bool, v);
226        Ok(())
227    }
228
229    fn visit_str(&mut self, v: &str) -> Result<(), Error> {
230        assert_eq!(self.str, v);
231        Ok(())
232    }
233
234    fn visit_borrowed_str(&mut self, v: &'v str) -> Result<(), Error> {
235        assert_eq!(self.borrowed_str, v);
236        Ok(())
237    }
238
239    fn visit_char(&mut self, v: char) -> Result<(), Error> {
240        assert_eq!(self.char, v);
241        Ok(())
242    }
243
244    #[cfg(feature = "error")]
245    fn visit_error(&mut self, err: &(dyn crate::std::error::Error + 'static)) -> Result<(), Error> {
246        assert!(err.downcast_ref::<crate::std::io::Error>().is_some());
247        Ok(())
248    }
249
250    #[cfg(feature = "error")]
251    fn visit_borrowed_error(
252        &mut self,
253        err: &'v (dyn crate::std::error::Error + 'static),
254    ) -> Result<(), Error> {
255        assert!(err.downcast_ref::<crate::std::io::Error>().is_some());
256        Ok(())
257    }
258}