#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GuestLogFilter {
Off,
Error,
Warn,
Info,
Debug,
Trace,
}
impl From<GuestLogFilter> for tracing_core::LevelFilter {
fn from(filter: GuestLogFilter) -> Self {
match filter {
GuestLogFilter::Off => tracing_core::LevelFilter::OFF,
GuestLogFilter::Error => tracing_core::LevelFilter::ERROR,
GuestLogFilter::Warn => tracing_core::LevelFilter::WARN,
GuestLogFilter::Info => tracing_core::LevelFilter::INFO,
GuestLogFilter::Debug => tracing_core::LevelFilter::DEBUG,
GuestLogFilter::Trace => tracing_core::LevelFilter::TRACE,
}
}
}
impl From<GuestLogFilter> for log::LevelFilter {
fn from(filter: GuestLogFilter) -> Self {
match filter {
GuestLogFilter::Off => log::LevelFilter::Off,
GuestLogFilter::Error => log::LevelFilter::Error,
GuestLogFilter::Warn => log::LevelFilter::Warn,
GuestLogFilter::Info => log::LevelFilter::Info,
GuestLogFilter::Debug => log::LevelFilter::Debug,
GuestLogFilter::Trace => log::LevelFilter::Trace,
}
}
}
impl From<tracing_core::LevelFilter> for GuestLogFilter {
fn from(value: tracing_core::LevelFilter) -> Self {
match value {
tracing_core::LevelFilter::OFF => Self::Off,
tracing_core::LevelFilter::ERROR => Self::Error,
tracing_core::LevelFilter::WARN => Self::Warn,
tracing_core::LevelFilter::INFO => Self::Info,
tracing_core::LevelFilter::DEBUG => Self::Debug,
tracing_core::LevelFilter::TRACE => Self::Trace,
}
}
}
impl TryFrom<u64> for GuestLogFilter {
type Error = ();
fn try_from(value: u64) -> Result<Self, <GuestLogFilter as TryFrom<u64>>::Error> {
match value {
0 => Ok(Self::Off),
1 => Ok(Self::Error),
2 => Ok(Self::Warn),
3 => Ok(Self::Info),
4 => Ok(Self::Debug),
5 => Ok(Self::Trace),
_ => Err(()),
}
}
}
impl From<GuestLogFilter> for u64 {
fn from(value: GuestLogFilter) -> Self {
match value {
GuestLogFilter::Off => 0,
GuestLogFilter::Error => 1,
GuestLogFilter::Warn => 2,
GuestLogFilter::Info => 3,
GuestLogFilter::Debug => 4,
GuestLogFilter::Trace => 5,
}
}
}
#[cfg(test)]
mod tests {
use super::GuestLogFilter;
#[test]
fn guest_log_filter_u64_roundtrip() {
let variants = [
GuestLogFilter::Off,
GuestLogFilter::Error,
GuestLogFilter::Warn,
GuestLogFilter::Info,
GuestLogFilter::Debug,
GuestLogFilter::Trace,
];
for variant in variants {
let as_u64: u64 = variant.into();
let back =
GuestLogFilter::try_from(as_u64).expect("conversion from u64 should succeed");
assert_eq!(variant, back);
}
}
#[test]
fn guest_log_filter_tracing_roundtrip() {
let variants = [
GuestLogFilter::Off,
GuestLogFilter::Error,
GuestLogFilter::Warn,
GuestLogFilter::Info,
GuestLogFilter::Debug,
GuestLogFilter::Trace,
];
for variant in variants {
let tracing_filter: tracing_core::LevelFilter = variant.into();
let back: GuestLogFilter = tracing_filter.into();
assert_eq!(variant, back);
}
}
#[test]
fn guest_log_filter_log_conversion() {
let variants = [
GuestLogFilter::Off,
GuestLogFilter::Error,
GuestLogFilter::Warn,
GuestLogFilter::Info,
GuestLogFilter::Debug,
GuestLogFilter::Trace,
];
let log_variants = [
log::LevelFilter::Off,
log::LevelFilter::Error,
log::LevelFilter::Warn,
log::LevelFilter::Info,
log::LevelFilter::Debug,
log::LevelFilter::Trace,
];
for (variant, log_variant) in variants.into_iter().zip(log_variants) {
let log_filter = log::LevelFilter::from(variant);
assert_eq!(log_filter, log_variant);
}
}
#[test]
fn guest_log_filter_try_from_u64_rejects_invalid() {
assert!(GuestLogFilter::try_from(u64::MAX).is_err());
assert!(GuestLogFilter::try_from(6).is_err());
}
}