1use std::{ops::Deref, sync::Arc};
2
3use crate::{SearchError, ast::PropertyValue, search::DisplayContext};
4
5pub trait PropertyTracer: Send + Sync {
12 fn on_found(&self, name: &str, value: &PropertyValue, context: DisplayContext);
13 fn on_error(&self, error: SearchError);
14}
15
16pub trait ClonablePropertyTracer: PropertyTracer + Clone {}
17impl<T: PropertyTracer + Clone> ClonablePropertyTracer for T {}
18
19impl<T: ?Sized + PropertyTracer> PropertyTracer for Arc<T> {
20 fn on_found(&self, name: &str, value: &PropertyValue, context: DisplayContext) {
21 self.deref().on_found(name, value, context)
22 }
23
24 fn on_error(&self, error: SearchError) {
25 self.deref().on_error(error);
26 }
27}
28#[derive(Clone)]
32pub struct NullTracer();
33impl PropertyTracer for NullTracer {
34 fn on_found(&self, _name: &str, _value: &PropertyValue, _context: DisplayContext) {}
35 fn on_error(&self, _error: SearchError) {}
36}
37
38#[cfg(feature = "log")]
39pub(crate) mod log {
40 use super::*;
41
42 #[derive(Clone)]
46 pub struct LogTracer {
47 pub success_level: ::log::Level,
48 pub error_level: ::log::Level,
49 }
50 impl LogTracer {
51 pub fn single_level(level: ::log::Level) -> Self {
52 LogTracer {
53 success_level: level,
54 error_level: level,
55 }
56 }
57 }
58
59 impl PropertyTracer for LogTracer {
60 fn on_found(&self, name: &str, value: &PropertyValue, context: DisplayContext) {
61 ::log::log!(
62 self.success_level,
63 "Found property: {name} = {}\n\t{context}\n\torigin: {}",
64 value.value,
65 value.origin
66 );
67 }
68
69 fn on_error(&self, error: SearchError) {
70 match error {
71 SearchError::MissingPropertyError { name, context } => {
72 ::log::log!(self.error_level, "Property not found: {name}\n\t{context}");
73 }
74 SearchError::EmptyPropertyError { name, context } => {
75 ::log::log!(
76 self.error_level,
77 "Empty property found: {name}\n\t{context}"
78 );
79 }
80 SearchError::AmbiguousPropertyError {
81 count,
82 name,
83 context,
84 } => {
85 ::log::log!(
86 self.error_level,
87 "Ambiguous property found ({count} values): {name}\n\t{context}"
88 );
89 }
90 }
91 }
92 }
93}