]> git.proxmox.com Git - rustc.git/blame - vendor/tracing/tests/support/field.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / vendor / tracing / tests / support / field.rs
CommitLineData
f035d41b
XL
1use tracing::{
2 callsite,
3 callsite::Callsite,
4 field::{self, Field, Value, Visit},
5 metadata::Kind,
6};
7
8use std::{collections::HashMap, fmt};
9
10#[derive(Default, Debug, Eq, PartialEq)]
11pub struct Expect {
12 fields: HashMap<String, MockValue>,
13 only: bool,
14}
15
16#[derive(Debug)]
17pub struct MockField {
18 name: String,
19 value: MockValue,
20}
21
c295e0f8 22#[derive(Debug)]
f035d41b 23pub enum MockValue {
c295e0f8 24 F64(f64),
f035d41b
XL
25 I64(i64),
26 U64(u64),
27 Bool(bool),
28 Str(String),
29 Debug(String),
30 Any,
31}
32
c295e0f8
XL
33impl Eq for MockValue {}
34
35impl PartialEq for MockValue {
36 fn eq(&self, other: &Self) -> bool {
37 use MockValue::*;
38
39 match (self, other) {
40 (F64(a), F64(b)) => {
41 debug_assert!(!a.is_nan());
42 debug_assert!(!b.is_nan());
43
44 a.eq(b)
45 }
46 (I64(a), I64(b)) => a.eq(b),
47 (U64(a), U64(b)) => a.eq(b),
48 (Bool(a), Bool(b)) => a.eq(b),
49 (Str(a), Str(b)) => a.eq(b),
50 (Debug(a), Debug(b)) => a.eq(b),
51 (Any, _) => true,
52 (_, Any) => true,
53 _ => false,
54 }
55 }
56}
57
f035d41b
XL
58pub fn mock<K>(name: K) -> MockField
59where
60 String: From<K>,
61{
62 MockField {
63 name: name.into(),
64 value: MockValue::Any,
65 }
66}
67
c295e0f8
XL
68pub fn msg(message: impl fmt::Display) -> MockField {
69 MockField {
70 name: "message".to_string(),
71 value: MockValue::Debug(message.to_string()),
72 }
73}
74
f035d41b
XL
75impl MockField {
76 /// Expect a field with the given name and value.
77 pub fn with_value(self, value: &dyn Value) -> Self {
78 Self {
79 value: MockValue::from(value),
80 ..self
81 }
82 }
83
84 pub fn and(self, other: MockField) -> Expect {
85 Expect {
86 fields: HashMap::new(),
87 only: false,
88 }
89 .and(self)
90 .and(other)
91 }
92
93 pub fn only(self) -> Expect {
94 Expect {
95 fields: HashMap::new(),
96 only: true,
97 }
98 .and(self)
99 }
100}
101
17df50a5
XL
102impl From<MockField> for Expect {
103 fn from(field: MockField) -> Self {
f035d41b
XL
104 Expect {
105 fields: HashMap::new(),
106 only: false,
107 }
17df50a5 108 .and(field)
f035d41b
XL
109 }
110}
111
112impl Expect {
113 pub fn and(mut self, field: MockField) -> Self {
114 self.fields.insert(field.name, field.value);
115 self
116 }
117
118 /// Indicates that no fields other than those specified should be expected.
119 pub fn only(self) -> Self {
120 Self { only: true, ..self }
121 }
122
c295e0f8
XL
123 fn compare_or_panic(
124 &mut self,
125 name: &str,
126 value: &dyn Value,
127 ctx: &str,
128 subscriber_name: &str,
129 ) {
f035d41b
XL
130 let value = value.into();
131 match self.fields.remove(name) {
132 Some(MockValue::Any) => {}
133 Some(expected) => assert!(
134 expected == value,
c295e0f8
XL
135 "\n[{}] expected `{}` to contain:\n\t`{}{}`\nbut got:\n\t`{}{}`",
136 subscriber_name,
f035d41b
XL
137 ctx,
138 name,
139 expected,
140 name,
141 value
142 ),
143 None if self.only => panic!(
c295e0f8
XL
144 "[{}]expected `{}` to contain only:\n\t`{}`\nbut got:\n\t`{}{}`",
145 subscriber_name, ctx, self, name, value
f035d41b
XL
146 ),
147 _ => {}
148 }
149 }
150
c295e0f8
XL
151 pub fn checker<'a>(&'a mut self, ctx: &'a str, subscriber_name: &'a str) -> CheckVisitor<'a> {
152 CheckVisitor {
153 expect: self,
154 ctx,
155 subscriber_name,
156 }
f035d41b
XL
157 }
158
159 pub fn is_empty(&self) -> bool {
160 self.fields.is_empty()
161 }
162}
163
164impl fmt::Display for MockValue {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 match self {
c295e0f8 167 MockValue::F64(v) => write!(f, "f64 = {:?}", v),
f035d41b
XL
168 MockValue::I64(v) => write!(f, "i64 = {:?}", v),
169 MockValue::U64(v) => write!(f, "u64 = {:?}", v),
170 MockValue::Bool(v) => write!(f, "bool = {:?}", v),
171 MockValue::Str(v) => write!(f, "&str = {:?}", v),
172 MockValue::Debug(v) => write!(f, "&fmt::Debug = {:?}", v),
173 MockValue::Any => write!(f, "_ = _"),
174 }
175 }
176}
177
178pub struct CheckVisitor<'a> {
179 expect: &'a mut Expect,
c295e0f8
XL
180 ctx: &'a str,
181 subscriber_name: &'a str,
f035d41b
XL
182}
183
184impl<'a> Visit for CheckVisitor<'a> {
c295e0f8
XL
185 fn record_f64(&mut self, field: &Field, value: f64) {
186 self.expect
187 .compare_or_panic(field.name(), &value, self.ctx, self.subscriber_name)
188 }
189
f035d41b
XL
190 fn record_i64(&mut self, field: &Field, value: i64) {
191 self.expect
c295e0f8 192 .compare_or_panic(field.name(), &value, self.ctx, self.subscriber_name)
f035d41b
XL
193 }
194
195 fn record_u64(&mut self, field: &Field, value: u64) {
196 self.expect
c295e0f8 197 .compare_or_panic(field.name(), &value, self.ctx, self.subscriber_name)
f035d41b
XL
198 }
199
200 fn record_bool(&mut self, field: &Field, value: bool) {
201 self.expect
c295e0f8 202 .compare_or_panic(field.name(), &value, self.ctx, self.subscriber_name)
f035d41b
XL
203 }
204
205 fn record_str(&mut self, field: &Field, value: &str) {
206 self.expect
c295e0f8 207 .compare_or_panic(field.name(), &value, self.ctx, self.subscriber_name)
f035d41b
XL
208 }
209
210 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
c295e0f8
XL
211 self.expect.compare_or_panic(
212 field.name(),
213 &field::debug(value),
214 self.ctx,
215 self.subscriber_name,
216 )
f035d41b
XL
217 }
218}
219
220impl<'a> CheckVisitor<'a> {
221 pub fn finish(self) {
222 assert!(
223 self.expect.fields.is_empty(),
c295e0f8
XL
224 "[{}] {}missing {}",
225 self.subscriber_name,
f035d41b
XL
226 self.expect,
227 self.ctx
228 );
229 }
230}
231
232impl<'a> From<&'a dyn Value> for MockValue {
233 fn from(value: &'a dyn Value) -> Self {
234 struct MockValueBuilder {
235 value: Option<MockValue>,
236 }
237
238 impl Visit for MockValueBuilder {
c295e0f8
XL
239 fn record_f64(&mut self, _: &Field, value: f64) {
240 self.value = Some(MockValue::F64(value));
241 }
242
f035d41b
XL
243 fn record_i64(&mut self, _: &Field, value: i64) {
244 self.value = Some(MockValue::I64(value));
245 }
246
247 fn record_u64(&mut self, _: &Field, value: u64) {
248 self.value = Some(MockValue::U64(value));
249 }
250
251 fn record_bool(&mut self, _: &Field, value: bool) {
252 self.value = Some(MockValue::Bool(value));
253 }
254
255 fn record_str(&mut self, _: &Field, value: &str) {
256 self.value = Some(MockValue::Str(value.to_owned()));
257 }
258
259 fn record_debug(&mut self, _: &Field, value: &dyn fmt::Debug) {
260 self.value = Some(MockValue::Debug(format!("{:?}", value)));
261 }
262 }
263
264 let fake_field = callsite!(name: "fake", kind: Kind::EVENT, fields: fake_field)
265 .metadata()
266 .fields()
267 .field("fake_field")
268 .unwrap();
269 let mut builder = MockValueBuilder { value: None };
270 value.record(&fake_field, &mut builder);
271 builder
272 .value
273 .expect("finish called before a value was recorded")
274 }
275}
276
277impl fmt::Display for Expect {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 write!(f, "fields ")?;
280 let entries = self
281 .fields
282 .iter()
283 .map(|(k, v)| (field::display(k), field::display(v)));
284 f.debug_map().entries(entries).finish()
285 }
286}