edgedb_sdk/
log.rs

1//! Logging for WebAsssembly application
2//!
3//! This module is mostly re-export of the [`log`](mod@log) crate. The most
4//! important exception is that logging is expected to be controlled from host.
5//! So logger and max-level changes are allowed via this API.
6//!
7#![cfg_attr(feature="host", allow(dead_code))]
8
9pub use log::{debug, error, info, log, log_enabled, trace, warn};
10pub use log::{Record, RecordBuilder, Metadata, MetadataBuilder};
11pub use log::{Level, LevelFilter, STATIC_MAX_LEVEL};
12pub use log::{logger, max_level};
13
14#[allow(dead_code)]
15#[allow(unused_parens)]
16// wit_bindgen_rust::import!("../wit/edgedb_log_v1.wit");
17mod edgedb_log_v1 {
18  #[repr(u8)]
19  #[derive(Clone, Copy, PartialEq, Eq)]
20  pub enum Level{
21    Error,
22    Warn,
23    Info,
24    Debug,
25    Trace,
26  }
27  impl std::fmt::Debug for Level {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29      match self {
30        Level::Error => {
31          f.debug_tuple("Level::Error").finish()
32        }
33        Level::Warn => {
34          f.debug_tuple("Level::Warn").finish()
35        }
36        Level::Info => {
37          f.debug_tuple("Level::Info").finish()
38        }
39        Level::Debug => {
40          f.debug_tuple("Level::Debug").finish()
41        }
42        Level::Trace => {
43          f.debug_tuple("Level::Trace").finish()
44        }
45      }
46    }
47  }
48  #[derive(Clone)]
49  pub struct LogRecord<'a,> {
50    pub level: Level,
51    pub target: &'a  str,
52    pub module_path: Option<&'a  str>,
53    pub file: Option<&'a  str>,
54    pub line: Option<u32>,
55    pub message: &'a  str,
56  }
57  impl<'a,> std::fmt::Debug for LogRecord<'a,> {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59      f.debug_struct("LogRecord").field("level", &self.level).field("target", &self.target).field("module-path", &self.module_path).field("file", &self.file).field("line", &self.line).field("message", &self.message).finish()}
60  }
61  pub fn log(item: LogRecord<'_,>,) -> (){
62    unsafe {
63      let LogRecord{ level:level0, target:target0, module_path:module_path0, file:file0, line:line0, message:message0, } = item;
64      let vec1 = target0;
65      let ptr1 = vec1.as_ptr() as i32;
66      let len1 = vec1.len() as i32;
67      let (result3_0,result3_1,result3_2,) = match module_path0{
68        None => { (0i32, 0i32, 0i32)}
69        Some(e) => { {
70          let vec2 = e;
71          let ptr2 = vec2.as_ptr() as i32;
72          let len2 = vec2.len() as i32;
73          
74          (1i32, ptr2, len2)
75        }}
76      };
77      let (result5_0,result5_1,result5_2,) = match file0{
78        None => { (0i32, 0i32, 0i32)}
79        Some(e) => { {
80          let vec4 = e;
81          let ptr4 = vec4.as_ptr() as i32;
82          let len4 = vec4.len() as i32;
83          
84          (1i32, ptr4, len4)
85        }}
86      };
87      let (result6_0,result6_1,) = match line0{
88        None => { (0i32, 0i32)}
89        Some(e) => { (1i32, crate::bindgen::as_i32(e))}
90      };
91      let vec7 = message0;
92      let ptr7 = vec7.as_ptr() as i32;
93      let len7 = vec7.len() as i32;
94      #[link(wasm_import_module = "edgedb_log_v1")]
95      extern "C" {
96        #[cfg_attr(target_arch = "wasm32", link_name = "log")]
97        #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb_log_v1_log")]
98        fn wit_import(_: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, );
99      }
100      wit_import(level0 as i32, ptr1, len1, result3_0, result3_1, result3_2, result5_0, result5_1, result5_2, result6_0, result6_1, ptr7, len7);
101      ()
102    }
103  }
104  pub fn max_level() -> Option<Level>{
105    unsafe {
106      let ptr0 = RET_AREA.as_mut_ptr() as i32;
107      #[link(wasm_import_module = "edgedb_log_v1")]
108      extern "C" {
109        #[cfg_attr(target_arch = "wasm32", link_name = "max-level")]
110        #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb_log_v1_max-level")]
111        fn wit_import(_: i32, );
112      }
113      wit_import(ptr0);
114      match *((ptr0 + 0) as *const i32) {
115        0 => None,
116        1 => Some(match *((ptr0 + 8) as *const i32) {
117          0 => Level::Error,
118          1 => Level::Warn,
119          2 => Level::Info,
120          3 => Level::Debug,
121          4 => Level::Trace,
122          _ => panic!("invalid enum discriminant"),
123        }),
124        _ => panic!("invalid enum discriminant"),
125      }
126    }
127  }
128  static mut RET_AREA: [i64; 2] = [0; 2];
129}
130
131use edgedb_log_v1 as v1;
132
133static mut LOGGER: HostLogger = HostLogger {
134    max_level: log::STATIC_MAX_LEVEL,
135};
136
137struct HostLogger {
138    max_level: log::LevelFilter,
139}
140
141impl From<log::Level> for v1::Level {
142    fn from(value: log::Level) -> v1::Level {
143        use v1::Level as T;
144        use log::Level as S;
145
146        match value {
147            S::Error => T::Error,
148            S::Warn => T::Warn,
149            S::Debug => T::Debug,
150            S::Info => T::Info,
151            S::Trace => T::Trace,
152        }
153    }
154}
155
156fn convert_filter(value: Option<v1::Level>) -> log::LevelFilter {
157    use log::LevelFilter as T;
158    use v1::Level as S;
159
160    match value {
161        None => T::Off,
162        Some(S::Error) => T::Error,
163        Some(S::Warn) => T::Warn,
164        Some(S::Debug) => T::Debug,
165        Some(S::Info) => T::Info,
166        Some(S::Trace) => T::Trace,
167    }
168}
169
170#[cfg(not(feature="host"))]
171pub(crate) fn init() {
172    let level = convert_filter(v1::max_level());
173    unsafe {
174        // not sure if safe all all platforms
175        LOGGER.max_level = level;
176
177        log::set_logger(&LOGGER).expect("init_logging");
178    }
179    log::set_max_level(level);
180}
181
182impl log::Log for HostLogger {
183    fn enabled(&self, metadata: &Metadata) -> bool {
184        metadata.level() <= self.max_level
185    }
186
187    fn log(&self, record: &Record) {
188        if self.enabled(record.metadata()) {
189            v1::log(v1::LogRecord {
190                target: record.target(),
191                level: record.level().into(),
192                message: &record.args().to_string(),
193                line: record.line(),
194                file: record.file(),
195                module_path: record.module_path(),
196            });
197        }
198    }
199
200    fn flush(&self) {}
201}