diff --git a/core/src/core/engine.rs b/core/src/core/engine.rs index dbdb01b..2d0dc08 100644 --- a/core/src/core/engine.rs +++ b/core/src/core/engine.rs @@ -41,7 +41,7 @@ impl crate::profiler::Profiler for Engine { todo!() } - fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &F) { + fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &FieldSet) { todo!() } } @@ -51,7 +51,7 @@ impl crate::trace::Tracer for Engine { todo!() } - fn span_create(&self, callsite: NonZeroU32, fields: &F) -> NonZeroU32 { + fn span_create(&self, callsite: NonZeroU32, fields: &FieldSet) -> NonZeroU32 { todo!() } @@ -59,7 +59,7 @@ impl crate::trace::Tracer for Engine { todo!() } - fn span_record(&self, id: NonZeroU32, fields: &F) { + fn span_record(&self, id: NonZeroU32, fields: &FieldSet) { todo!() } @@ -69,7 +69,7 @@ impl crate::trace::Tracer for Engine { } impl crate::logger::Logger for Engine { - fn log(&self, callsite: &'static crate::logger::Callsite, msg: Arguments, fields: &F) { + fn log(&self, callsite: &'static crate::logger::Callsite, msg: Arguments, fields: &FieldSet) { todo!() } } diff --git a/core/src/field.rs b/core/src/field.rs index a67b48d..58cf638 100644 --- a/core/src/field.rs +++ b/core/src/field.rs @@ -28,114 +28,101 @@ use std::fmt::Debug; -pub trait Visitor { - fn visit_int(&mut self, name: &str, value: i64) { - self.visit_debug(name, &value); - } +pub enum FieldValue<'a> { + Int(i64), + UInt(u64), + Float(f32), + Double(f64), + String(&'a str), + Debug(&'a dyn Debug) +} - fn visit_uint(&mut self, name: &str, value: u64) { - self.visit_debug(name, &value); - } +pub struct Field<'a> { + name: &'a str, + value: FieldValue<'a> +} - fn visit_float(&mut self, name: &str, value: f32) { - self.visit_debug(name, &value); +impl<'a> Field<'a> { + pub fn new(name: &'a str, value: impl Into>) -> Self { + Self { + name, + value: value.into() + } } - fn visit_double(&mut self, name: &str, value: f64) { - self.visit_debug(name, &value); + pub fn new_debug(name: &'a str, value: &'a dyn Debug) -> Self { + Self { + name, + value: FieldValue::Debug(value) + } } - fn visit_string(&mut self, name: &str, value: &str) { - self.visit_debug(name, &value); + pub fn name(&self) -> &str { + self.name } - fn visit_debug(&mut self, name: &str, debug: &T); -} - -pub trait FieldSet { - fn record(&self, visitor: &mut V); -} - -impl FieldSet for () { - fn record(&self, _: &mut V) { + pub fn value(&self) -> &FieldValue<'a> { + &self.value } } -macro_rules! impl_tuple_fieldset { - ($(($($id: tt: $name: ident),*)),*) => { +macro_rules! impl_into_field_value { + // Would've preferred expr, but turns out expr is useless in macros, so let's not use it. + ($($t: ty => $func: ident),*) => { $( - impl<$($name: FieldSet),*> FieldSet for ($($name),*) { - fn record(&self, visitor: &mut V) { - $( - self.$id.record(visitor); - )* + impl<'a> From<$t> for FieldValue<'a> { + fn from(value: $t) -> Self { + FieldValue::$func(value as _) } } )* }; } -impl_tuple_fieldset!{ - (0: T, 1: T1), - (0: T, 1: T1, 2: T2), - (0: T, 1: T1, 2: T2, 3: T3), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8), - (0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9) +impl_into_field_value! { + u8 => UInt, + u16 => UInt, + u32 => UInt, + u64 => UInt, + i8 => Int, + i16 => Int, + i32 => Int, + i64 => Int, + f32 => Float, + f64 => Double } -macro_rules! impl_fieldset { - // Would've preferred expr, but turns out expr is useless in macros, so let's not use it. - ($($t: ty => $func: ident),*) => { - $( - impl FieldSet for (&str, $t) { - fn record(&self, visitor: &mut V) { - let (name, value) = self; - visitor.$func(name, *value as _); - } - } - )* - }; +impl<'a> From<&'a str> for FieldValue<'a> { + fn from(value: &'a str) -> Self { + Self::String(value) + } } -impl_fieldset! { - u8 => visit_uint, - u16 => visit_uint, - u32 => visit_uint, - u64 => visit_uint, - i8 => visit_int, - i16 => visit_int, - i32 => visit_int, - i64 => visit_int, - f32 => visit_float, - f64 => visit_double, - &str => visit_string -} +pub struct FieldSet<'a>(&'a [Field<'a>]); -pub struct D(pub T); +impl<'a> FieldSet<'a> { + pub fn new(fields: &'a [Field<'a>]) -> Self { + Self(fields) + } -impl FieldSet for (&str, D) { - fn record(&self, visitor: &mut V) { - visitor.visit_debug(self.0, &self.1.0); + pub fn iter(&self) -> impl Iterator> { + self.0.iter() } } #[macro_export] macro_rules! field { - ($name: ident) => {(stringify!($name), $name)}; - (?$name: ident) => {(stringify!($name), $crate::field::D($name))}; - ($name: ident = $value: expr) => {(stringify!($name), $value)}; - ($name: ident = ?$value: expr) => {(stringify!($name), $crate::field::D($value))}; + ($name: ident) => {$crate::field::Field::new(stringify!($name), $name)}; + (?$name: ident) => {$crate::field::Field::new_debug(stringify!($name), &$name)}; + ($name: ident = $value: expr) => {$crate::field::Field::new(stringify!($name), $value)}; + ($name: ident = ?$value: expr) => {$crate::field::Field::new_debug(stringify!($name), &$value)}; } #[macro_export] macro_rules! fields { ($({$($field: tt)*})*) => { - ($( + $crate::field::FieldSet::new(&[$( field!($($field)*), - )*) + )*]) }; } diff --git a/core/src/logger.rs b/core/src/logger.rs index c250c5c..577e116 100644 --- a/core/src/logger.rs +++ b/core/src/logger.rs @@ -45,7 +45,7 @@ impl Callsite { } pub trait Logger { - fn log(&self, callsite: &'static Callsite, msg: Arguments, fields: &F); + fn log(&self, callsite: &'static Callsite, msg: Arguments, fields: &FieldSet); } #[cfg(test)] diff --git a/core/src/macros.rs b/core/src/macros.rs index a938a1e..dca8f96 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -33,7 +33,7 @@ macro_rules! log { static _CALLSITE: $crate::logger::Callsite = $crate::logger::Callsite::new(bp3d_logger::Location::new(module_path!(), file!(), line!()), $level); use $crate::logger::Logger; $crate::core::ENGINE.get().map(|v| - v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$($crate::field!($($field)*),)*) + v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$crate::field::FieldSet::new(&[$($crate::field!($($field)*),)*])) ); } }; @@ -42,7 +42,7 @@ macro_rules! log { static _CALLSITE: $crate::logger::Callsite = $crate::logger::Callsite::new(bp3d_logger::Location::new(module_path!(), file!(), line!()), $level); use $crate::logger::Logger; $crate::core::ENGINE.get().map(|v| - v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &()) + v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$crate::field::FieldSet::new(&[])) ); } }; diff --git a/core/src/profiler/interface.rs b/core/src/profiler/interface.rs index 1d5aee7..d0027e4 100644 --- a/core/src/profiler/interface.rs +++ b/core/src/profiler/interface.rs @@ -32,9 +32,10 @@ use crate::profiler::section::Section; pub trait Profiler { fn section_register(&self, section: &'static Section) -> NonZeroU32; - fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &F); + fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &FieldSet); } extern "Rust" { pub fn profiler_section_register(section: &'static Section) -> NonZeroU32; + pub fn profiler_section_record(id: NonZeroU32, start: u64, end: u64, fields: &FieldSet); } diff --git a/core/src/profiler/section.rs b/core/src/profiler/section.rs index 45c96ba..e7f9864 100644 --- a/core/src/profiler/section.rs +++ b/core/src/profiler/section.rs @@ -50,13 +50,13 @@ thread_local! { static CUR_TIME: Instant = Instant::now(); } -pub struct Entered { +pub struct Entered<'a> { id: NonZeroU32, start: u64, - fields: F + fields: FieldSet<'a> } -impl Drop for Entered { +impl<'a> Drop for Entered<'a> { fn drop(&mut self) { let end = CUR_TIME.with(|v| v.elapsed().as_nanos() as _); let engine = unsafe { crate::core::ENGINE.get().unwrap_unchecked() }; @@ -108,7 +108,7 @@ impl Section { self.id.get_or_init(|| crate::core::ENGINE.get().map(|v| v.section_register(self))) } - pub fn enter(&'static self, fields: F) -> Option> { + pub fn enter<'a>(&'static self, fields: FieldSet<'a>) -> Option> { let id = self.get_id(); id.map(|id| Entered { id, @@ -121,7 +121,6 @@ impl Section { #[cfg(test)] mod tests { use crate::{field, fields, location}; - use crate::field::D; use crate::profiler::profiler_section_register; use crate::profiler::section::{Level, Section}; @@ -138,7 +137,7 @@ mod tests { #[test] fn basic() { static SECTION: Section = Section::new("api_test", location!(), Level::Event); - unsafe { profiler_section_register(&SECTION) }; + //unsafe { profiler_section_register(&SECTION) }; } #[test] @@ -146,12 +145,12 @@ mod tests { static SECTION: Section = Section::new("api_test", location!(), Level::Event); static SECTION2: Section = Section::new("api_test2", location!(), Level::Event) .set_parent(&SECTION); - assert!(SECTION.enter(()).is_none()); + /*assert!(SECTION.enter([]).is_none()); assert!(SECTION.enter(("test", 42)).is_none()); assert!(SECTION.enter(("test", "test 123")).is_none()); assert!(SECTION.enter(("test", 42.42)).is_none()); - assert!(SECTION.enter(("test", D(Level::Event))).is_none()); - assert!(SECTION.enter((("test", D(Level::Event)), ("test2", 42))).is_none()); + assert!(SECTION.enter(("test", Level::Event)).is_none()); + assert!(SECTION.enter((("test", Level::Event), ("test2", 42))).is_none());*/ let value = 32; let str = "this is a test"; let lvl = Level::Event; diff --git a/core/src/trace/interface.rs b/core/src/trace/interface.rs index d7d586d..c78f393 100644 --- a/core/src/trace/interface.rs +++ b/core/src/trace/interface.rs @@ -32,8 +32,8 @@ use crate::trace::span::Callsite; pub trait Tracer { fn register_callsite(&self, callsite: &'static Callsite) -> NonZeroU32; - fn span_create(&self, callsite: NonZeroU32, fields: &F) -> NonZeroU32; + fn span_create(&self, callsite: NonZeroU32, fields: &FieldSet) -> NonZeroU32; fn span_enter(&self, id: NonZeroU32); - fn span_record(&self, id: NonZeroU32, fields: &F); + fn span_record(&self, id: NonZeroU32, fields: &FieldSet); fn span_exit(&self, id: NonZeroU32); } diff --git a/core/src/trace/span.rs b/core/src/trace/span.rs index a3a90c6..d9e4076 100644 --- a/core/src/trace/span.rs +++ b/core/src/trace/span.rs @@ -57,7 +57,7 @@ pub struct Span { } impl Span { - pub fn new(callsite: &'static Callsite, fields: &F) -> Self { + pub fn new(callsite: &'static Callsite, fields: &FieldSet) -> Self { let id = callsite.get_id() .map(|cid| crate::core::ENGINE.get().map(|v| v.span_create(cid, fields))) .flatten(); @@ -66,7 +66,7 @@ impl Span { } } - pub fn record(&self, fields: &F) { + pub fn record(&self, fields: &FieldSet) { if let Some(id) = self.id { unsafe { crate::core::ENGINE.get().unwrap_unchecked().span_record(id, fields) }; }