use std::{
error::Error,
ffi::CString,
fmt::{Display, Formatter, Result as FmtResult},
};
use slog::{Drain, Level, OwnedKVList, Record};
use crate::get_callback;
fn basic_log<S>(ai_id: i32, message: S) -> Result<(), Box<dyn Error>>
where
S: Into<Vec<u8>>,
{
let log_func = get_callback!(ai_id, Log_log)?;
let c_message = CString::new(message)?;
Ok(unsafe { log_func(ai_id, c_message.as_ptr()) })
}
fn basic_exception_log<S>(
ai_id: i32,
message: S,
level: i32,
die: bool,
) -> Result<(), Box<dyn Error>>
where
S: Into<Vec<u8>>,
{
let log_exception_func = get_callback!(ai_id, Log_exception)?;
let c_message = CString::new(message)?;
Ok(unsafe { log_exception_func(ai_id, c_message.as_ptr(), level, die) })
}
pub struct AILogger {
ai_id: i32,
level: Level,
file_info: bool,
}
impl AILogger {
pub fn new(ai_id: i32) -> Self {
Self {
ai_id,
level: Level::Warning,
file_info: false,
}
}
pub fn with_level(self, level: Level) -> Self {
Self { level, ..self }
}
pub fn with_file_info(self, file_info: bool) -> Self {
Self { file_info, ..self }
}
}
#[derive(Copy, Clone, Debug)]
pub struct AILoggerOk {}
#[derive(Copy, Clone, Debug)]
pub struct AILoggerErr {}
impl Error for AILoggerErr {}
impl Display for AILoggerErr {
fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
write!(fmt, "{:?}", self)
}
}
impl Drain for AILogger {
type Ok = AILoggerOk;
type Err = AILoggerErr;
fn log(&self, record: &Record, values: &OwnedKVList) -> Result<Self::Ok, Self::Err> {
let message = if self.file_info {
format!(
"{} [{}::{} ({}:{})]: {}",
record.level().to_string(),
record.module(),
record.function(),
record.file(),
record.line(),
record.msg()
)
} else {
format!("{}: {}", record.level().to_string(), record.msg())
};
if record.level() < self.level {
match record.level() {
Level::Debug | Level::Trace | Level::Info => {
basic_log(self.ai_id, message).unwrap()
}
Level::Warning => basic_exception_log(self.ai_id, message, 3, false).unwrap(),
Level::Error => basic_exception_log(self.ai_id, message, 6, false).unwrap(),
Level::Critical => basic_exception_log(self.ai_id, message, 9, true).unwrap(),
}
}
Ok(AILoggerOk {})
}
}