1*7b32f508SLoGin use std::{collections::BTreeMap, fmt::Debug, fs::File, io::Write, path::PathBuf}; 2*7b32f508SLoGin 3*7b32f508SLoGin use log::error; 4*7b32f508SLoGin 5*7b32f508SLoGin use crate::constant::CMD_ARGS; 6*7b32f508SLoGin 7*7b32f508SLoGin /// 日志集合 8*7b32f508SLoGin /// 9*7b32f508SLoGin /// 所有的日志都会被存到这个集合中, 以便于进行各种操作 10*7b32f508SLoGin /// 11*7b32f508SLoGin /// 日志集合的后端可以在日志插入前后做一些操作(需要实现[`LogSetBackend`]) 12*7b32f508SLoGin #[derive(Debug)] 13*7b32f508SLoGin #[allow(dead_code)] 14*7b32f508SLoGin pub struct LogSet<K, V> { 15*7b32f508SLoGin inner: BTreeMap<K, V>, 16*7b32f508SLoGin backend: Box<dyn LogSetBackend<K, V>>, 17*7b32f508SLoGin name: String, 18*7b32f508SLoGin file_path: PathBuf, 19*7b32f508SLoGin log_file: Option<File>, 20*7b32f508SLoGin } 21*7b32f508SLoGin 22*7b32f508SLoGin #[allow(dead_code)] 23*7b32f508SLoGin impl<K: Ord, V: Clone + PartialEq + Debug> LogSet<K, V> { new(name: String, backend: Option<Box<dyn LogSetBackend<K, V>>>) -> Self24*7b32f508SLoGin pub fn new(name: String, backend: Option<Box<dyn LogSetBackend<K, V>>>) -> Self { 25*7b32f508SLoGin let mut file_path = CMD_ARGS.read().unwrap().as_ref().unwrap().log_dir.clone(); 26*7b32f508SLoGin file_path.push(format!("{}-{}.log", name, std::process::id())); 27*7b32f508SLoGin 28*7b32f508SLoGin let log_file = File::create(&file_path).expect("Failed to create log file."); 29*7b32f508SLoGin 30*7b32f508SLoGin Self { 31*7b32f508SLoGin inner: BTreeMap::new(), 32*7b32f508SLoGin backend: backend.unwrap_or_else(|| Box::new(DefaultBackend::new())), 33*7b32f508SLoGin name, 34*7b32f508SLoGin file_path, 35*7b32f508SLoGin log_file: Some(log_file), 36*7b32f508SLoGin } 37*7b32f508SLoGin } 38*7b32f508SLoGin insert(&mut self, key: K, value: V)39*7b32f508SLoGin pub fn insert(&mut self, key: K, value: V) { 40*7b32f508SLoGin let cloned_value = value.clone(); 41*7b32f508SLoGin self.backend.before_insert(&self.name, &value); 42*7b32f508SLoGin 43*7b32f508SLoGin let prev = self.inner.insert(key, value); 44*7b32f508SLoGin if let Some(prev) = prev { 45*7b32f508SLoGin if prev.ne(&cloned_value) { 46*7b32f508SLoGin error!( 47*7b32f508SLoGin "LogSet::insert(): prev != cloned_value: prev: {:?}, cloned_value: {:?}", 48*7b32f508SLoGin prev, cloned_value 49*7b32f508SLoGin ); 50*7b32f508SLoGin } 51*7b32f508SLoGin } else { 52*7b32f508SLoGin self.log_file 53*7b32f508SLoGin .as_mut() 54*7b32f508SLoGin .map(|f| writeln!(f, "{:?}", cloned_value).ok()); 55*7b32f508SLoGin } 56*7b32f508SLoGin 57*7b32f508SLoGin self.backend.after_insert(&self.name, &cloned_value); 58*7b32f508SLoGin } 59*7b32f508SLoGin file_path(&self) -> &PathBuf60*7b32f508SLoGin pub fn file_path(&self) -> &PathBuf { 61*7b32f508SLoGin &self.file_path 62*7b32f508SLoGin } 63*7b32f508SLoGin len(&self) -> usize64*7b32f508SLoGin pub fn len(&self) -> usize { 65*7b32f508SLoGin self.inner.len() 66*7b32f508SLoGin } 67*7b32f508SLoGin get(&self, key: &K) -> Option<&V>68*7b32f508SLoGin pub fn get(&self, key: &K) -> Option<&V> { 69*7b32f508SLoGin self.inner.get(key) 70*7b32f508SLoGin } 71*7b32f508SLoGin get_mut(&mut self, key: &K) -> Option<&mut V>72*7b32f508SLoGin pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { 73*7b32f508SLoGin self.inner.get_mut(key) 74*7b32f508SLoGin } 75*7b32f508SLoGin remove(&mut self, key: &K) -> Option<V>76*7b32f508SLoGin pub fn remove(&mut self, key: &K) -> Option<V> { 77*7b32f508SLoGin self.inner.remove(key) 78*7b32f508SLoGin } 79*7b32f508SLoGin clear(&mut self)80*7b32f508SLoGin pub fn clear(&mut self) { 81*7b32f508SLoGin self.inner.clear(); 82*7b32f508SLoGin } 83*7b32f508SLoGin iter(&self) -> impl Iterator<Item = (&K, &V)>84*7b32f508SLoGin pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> { 85*7b32f508SLoGin self.inner.iter() 86*7b32f508SLoGin } 87*7b32f508SLoGin contains_key(&self, key: &K) -> bool88*7b32f508SLoGin pub fn contains_key(&self, key: &K) -> bool { 89*7b32f508SLoGin self.inner.contains_key(key) 90*7b32f508SLoGin } 91*7b32f508SLoGin } 92*7b32f508SLoGin 93*7b32f508SLoGin /// 日志集合的后端, 用于在日志插入前后做一些操作 94*7b32f508SLoGin pub trait LogSetBackend<K, V>: Debug { before_insert(&mut self, _log_set_name: &str, _log: &V)95*7b32f508SLoGin fn before_insert(&mut self, _log_set_name: &str, _log: &V) {} 96*7b32f508SLoGin after_insert(&mut self, _log_set_name: &str, _log: &V)97*7b32f508SLoGin fn after_insert(&mut self, _log_set_name: &str, _log: &V) {} 98*7b32f508SLoGin } 99*7b32f508SLoGin 100*7b32f508SLoGin #[derive(Debug)] 101*7b32f508SLoGin struct DefaultBackend(()); 102*7b32f508SLoGin 103*7b32f508SLoGin impl DefaultBackend { new() -> Self104*7b32f508SLoGin pub const fn new() -> Self { 105*7b32f508SLoGin Self(()) 106*7b32f508SLoGin } 107*7b32f508SLoGin } 108*7b32f508SLoGin 109*7b32f508SLoGin impl<K, V> LogSetBackend<K, V> for DefaultBackend { before_insert(&mut self, _log_set_name: &str, _log: &V)110*7b32f508SLoGin fn before_insert(&mut self, _log_set_name: &str, _log: &V) {} 111*7b32f508SLoGin after_insert(&mut self, _log_set_name: &str, _log: &V)112*7b32f508SLoGin fn after_insert(&mut self, _log_set_name: &str, _log: &V) {} 113*7b32f508SLoGin } 114