ferroui_splat/logging/
default_log_manager.rs1use super::{
4 IFullLogger, ILogManager, ILogger, LoggingException, MemoizingMRUCache, NullLogger,
5 WrappingFullLogger, WrappingPrefixLogger,
6};
7use crate::service_location::{IReadonlyDependencyResolver, ReadonlyDependencyResolverExt};
8use std::rc::Rc;
9
10const LOGGER_CACHE_SIZE: usize = 64;
11
12pub struct DefaultLogManager {
16 logger_cache: MemoizingMRUCache<&'static str, Rc<dyn IFullLogger>>,
17 null_logger: Rc<dyn IFullLogger>,
18}
19
20impl DefaultLogManager {
21 pub fn new(dependency_resolver: Rc<dyn IReadonlyDependencyResolver>) -> Self {
25 let logger_cache = MemoizingMRUCache::new(
26 move |type_name: &&'static str, _context| -> Rc<dyn IFullLogger> {
27 match dependency_resolver.get_service::<dyn ILogger>() {
28 None => std::panic::panic_any(LoggingException::with_message(
29 "Couldn't find an ILogger. This should never happen, your dependency resolver is probably broken.",
30 )),
31 Some(logger) => Rc::new(WrappingFullLogger::new(Rc::new(WrappingPrefixLogger::new(
32 logger, *type_name,
33 )))),
34 }
35 },
36 LOGGER_CACHE_SIZE,
37 );
38 Self { logger_cache, null_logger: Rc::new(WrappingFullLogger::new(Rc::new(NullLogger::new()))) }
39 }
40}
41
42impl ILogManager for DefaultLogManager {
43 fn get_logger(&self, type_name: &'static str) -> Rc<dyn IFullLogger> {
44 if type_name == std::any::type_name::<MemoizingMRUCache<&'static str, Rc<dyn IFullLogger>>>() {
46 return self.null_logger.clone();
47 }
48 self.logger_cache.get(type_name)
49 }
50}