tui_logger/config/
level_config.rs

1use std::collections::hash_map::Iter;
2use std::collections::hash_map::Keys;
3use std::collections::HashMap;
4
5use log::LevelFilter;
6
7/// LevelConfig stores the relation target->LevelFilter in a hash table.
8///
9/// The table supports copying from the logger system LevelConfig to
10/// a widget's LevelConfig. In order to detect changes, the generation
11/// of the hash table is compared with any previous copied table.
12/// On every change the generation is incremented.
13#[derive(Default)]
14pub struct LevelConfig {
15    config: HashMap<String, LevelFilter>,
16    generation: u64,
17    origin_generation: u64,
18    default_display_level: Option<LevelFilter>,
19}
20impl LevelConfig {
21    /// Create an empty LevelConfig.
22    pub fn new() -> LevelConfig {
23        LevelConfig {
24            config: HashMap::new(),
25            generation: 0,
26            origin_generation: 0,
27            default_display_level: None,
28        }
29    }
30    /// Set for a given target the LevelFilter in the table and update the generation.
31    pub fn set(&mut self, target: &str, level: LevelFilter) {
32        if let Some(lev) = self.config.get_mut(target) {
33            if *lev != level {
34                *lev = level;
35                self.generation += 1;
36            }
37            return;
38        }
39        self.config.insert(target.to_string(), level);
40        self.generation += 1;
41    }
42    /// Set default display level filter for new targets - independent from recording
43    pub fn set_default_display_level(&mut self, level: LevelFilter) {
44        self.default_display_level = Some(level);
45    }
46    /// Get default display level filter for new targets - independent from recording
47    pub fn get_default_display_level(&self) -> Option<LevelFilter> {
48        self.default_display_level
49    }
50    /// Retrieve an iter for all the targets stored in the hash table.
51    pub fn keys(&self) -> Keys<'_, String, LevelFilter> {
52        self.config.keys()
53    }
54    /// Get the levelfilter for a given target.
55    pub fn get(&self, target: &str) -> Option<LevelFilter> {
56        self.config.get(target).cloned()
57    }
58    /// Retrieve an iterator through all entries of the table.
59    pub fn iter(&self) -> Iter<'_, String, LevelFilter> {
60        self.config.iter()
61    }
62    /// Merge an origin LevelConfig into this one.
63    ///
64    /// The origin table defines the maximum levelfilter.
65    /// If this table has a higher levelfilter, then it will be reduced.
66    /// Unknown targets will be copied to this table.
67    pub(crate) fn merge(&mut self, origin: &LevelConfig) {
68        if self.origin_generation != origin.generation {
69            for (target, origin_levelfilter) in origin.iter() {
70                if let Some(levelfilter) = self.get(target) {
71                    if levelfilter <= *origin_levelfilter {
72                        continue;
73                    }
74                }
75                let levelfilter = self
76                    .default_display_level
77                    .map(|lvl| {
78                        if lvl > *origin_levelfilter {
79                            *origin_levelfilter
80                        } else {
81                            lvl
82                        }
83                    })
84                    .unwrap_or(*origin_levelfilter);
85                self.set(target, levelfilter);
86            }
87            self.generation = origin.generation;
88        }
89    }
90}