1use std::os::raw::c_char;
2
3use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
4use obs_sys::{_bindgen_ty_1, blog, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARNING};
5
6pub struct Logger {
24 max_level: LevelFilter,
25 promote_debug: bool,
26}
27
28impl Default for Logger {
29 fn default() -> Self {
30 Self {
31 max_level: LevelFilter::Trace,
32 promote_debug: false,
33 }
34 }
35}
36
37impl Logger {
38 #[must_use = "You must call init() to begin logging"]
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn init(self) -> Result<(), SetLoggerError> {
48 log::set_max_level(self.max_level);
49 log::set_boxed_logger(Box::new(self))?;
50 Ok(())
51 }
52
53 #[must_use = "You must call init() to begin logging"]
55 pub fn with_promote_debug(mut self, promote_debug: bool) -> Self {
56 self.promote_debug = promote_debug;
57 self
58 }
59
60 #[must_use = "You must call init() to begin logging"]
62 pub fn with_max_level(mut self, max_level: LevelFilter) -> Self {
63 self.max_level = max_level;
64 self
65 }
66}
67
68impl Log for Logger {
69 fn enabled(&self, metadata: &Metadata) -> bool {
70 self.max_level >= metadata.level()
71 }
72
73 fn log(&self, record: &Record) {
74 if !self.enabled(record.metadata()) {
75 return;
76 }
77 let level = record.level();
78 let native_level = to_native_level(level, self.promote_debug);
79 let target = if !record.target().is_empty() {
80 record.target()
81 } else {
82 record.module_path().unwrap_or_default()
83 };
84
85 let line = if self.promote_debug && level <= Level::Debug {
86 format!("({}) [{}] {}\0", level, target, record.args())
87 } else {
88 format!("[{}] {}\0", target, record.args())
89 };
90
91 unsafe {
92 blog(
93 native_level as i32,
94 "%s\0".as_ptr() as *const c_char,
95 line.as_ptr() as *const c_char,
96 );
97 }
98 }
99
100 fn flush(&self) {
101 }
103}
104
105fn to_native_level(level: Level, promote_debug: bool) -> _bindgen_ty_1 {
106 match level {
107 Level::Error => LOG_ERROR,
108 Level::Warn => LOG_WARNING,
109 Level::Info => LOG_INFO,
110 _ => {
111 if promote_debug {
112 LOG_INFO
115 } else {
116 LOG_DEBUG
117 }
118 }
119 }
120}