use std::mem::transmute;
use crate::error::GCPluginABIError;
use gc_abi_sys::{eGCLogLevel, eGCLogLevel_CRITICAL, eGCLogLevel_DEBUG, eGCLogLevel_ERROR, eGCLogLevel_INFO, eGCLogLevel_WARNING};
#[repr(u32)]
#[derive(PartialEq, Debug, Clone, Copy, Eq, PartialOrd, Ord)]
pub enum GCLogLevel {
DEBUG = eGCLogLevel_DEBUG,
INFO = eGCLogLevel_INFO,
WARNING = eGCLogLevel_WARNING,
ERROR = eGCLogLevel_ERROR,
CRITICAL = eGCLogLevel_CRITICAL,
}
impl GCLogLevel {
pub fn from_c(c_value: eGCLogLevel) -> Result<GCLogLevel, GCPluginABIError> {
if c_value <= eGCLogLevel_DEBUG {
Ok(unsafe { transmute::<u32, GCLogLevel>(c_value) })
} else {
Err(GCPluginABIError::ErrorInvalidLogLevel(c_value))
}
}
pub fn into_c(self) -> eGCLogLevel {
self as eGCLogLevel
}
}
impl From<log::LevelFilter> for GCLogLevel {
fn from(level: log::LevelFilter) -> Self {
match level {
log::LevelFilter::Debug | log::LevelFilter::Trace => GCLogLevel::DEBUG,
log::LevelFilter::Info => GCLogLevel::INFO,
log::LevelFilter::Warn => GCLogLevel::WARNING,
log::LevelFilter::Error => GCLogLevel::ERROR,
log::LevelFilter::Off => GCLogLevel::CRITICAL,
}
}
}
impl From<GCLogLevel> for log::LevelFilter {
fn from(level: GCLogLevel) -> Self {
match level {
GCLogLevel::DEBUG => log::LevelFilter::Debug,
GCLogLevel::INFO => log::LevelFilter::Info,
GCLogLevel::WARNING => log::LevelFilter::Warn,
GCLogLevel::ERROR => log::LevelFilter::Error,
GCLogLevel::CRITICAL => log::LevelFilter::Off,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_conversion_from_u32() {
let error = 4;
let error = GCLogLevel::from_c(error);
assert_eq!(error.unwrap(), GCLogLevel::DEBUG);
}
#[test]
fn test_conversion_from_u32_invalid() {
let error = 5;
let error = GCLogLevel::from_c(error);
assert!(error.is_err());
}
#[test]
fn test_debug_higher_level() {
assert_eq!(
gc_abi_sys::eGCLogLevel_DEBUG,
4,
"The value of eGCLogLevel_DEBUG has changed, the conversion might need to be updated if there are levels bigger then 4"
);
}
}