witchcraft_log_util/
filter.rs1use sequence_trie::SequenceTrie;
17use witchcraft_log::{LevelFilter, Metadata};
18
19pub struct Filter {
25 trie: SequenceTrie<String, LevelFilter>,
26}
27
28impl Filter {
29 #[inline]
31 pub fn builder() -> Builder {
32 Builder {
33 filter: Filter {
34 trie: SequenceTrie::new(),
35 },
36 root: LevelFilter::Error,
37 }
38 }
39
40 pub fn enabled(&self, metadata: &Metadata<'_>) -> bool {
42 metadata.level()
43 <= *self
44 .trie
45 .get_ancestor(metadata.target().split("::"))
46 .unwrap()
47 }
48
49 pub fn max_level(&self) -> LevelFilter {
51 self.trie.values().max().copied().unwrap()
52 }
53}
54
55pub struct Builder {
57 filter: Filter,
58 root: LevelFilter,
59}
60
61impl Builder {
62 #[inline]
66 pub fn level(mut self, level: LevelFilter) -> Self {
67 self.root = level;
68 self
69 }
70
71 #[inline]
73 pub fn target_level(mut self, target: &str, level: LevelFilter) -> Self {
74 self.filter.trie.insert(target.split("::"), level);
75 self
76 }
77
78 #[inline]
80 pub fn build(mut self) -> Filter {
81 self.filter.trie.insert_owned([], self.root);
82 self.filter
83 }
84}
85
86#[cfg(test)]
87mod test {
88 use witchcraft_log::Level;
89
90 use super::*;
91
92 #[test]
93 fn empty() {
94 let filter = Filter::builder().build();
95
96 assert!(
97 filter.enabled(
98 &Metadata::builder()
99 .level(Level::Error)
100 .target("foo")
101 .build()
102 )
103 );
104
105 assert!(!filter.enabled(&Metadata::builder().level(Level::Warn).target("foo").build()));
106 }
107
108 #[test]
109 fn nonempty() {
110 let filter = Filter::builder()
111 .level(LevelFilter::Warn)
112 .target_level("foo", LevelFilter::Debug)
113 .target_level("foo::bar", LevelFilter::Off)
114 .build();
115
116 assert!(
117 filter.enabled(
118 &Metadata::builder()
119 .level(Level::Error)
120 .target("bar")
121 .build()
122 )
123 );
124 assert!(!filter.enabled(&Metadata::builder().level(Level::Info).target("bar").build()));
125
126 assert!(filter.enabled(&Metadata::builder().level(Level::Info).target("foo").build()));
127 assert!(
128 !filter.enabled(
129 &Metadata::builder()
130 .level(Level::Trace)
131 .target("foo")
132 .build()
133 )
134 );
135
136 assert!(
137 !filter.enabled(
138 &Metadata::builder()
139 .level(Level::Fatal)
140 .target("foo::bar")
141 .build()
142 )
143 );
144
145 assert!(
146 filter.enabled(
147 &Metadata::builder()
148 .level(Level::Fatal)
149 .target("foo::buz")
150 .build()
151 )
152 );
153 }
154}