diff --git a/core/src/ambient.rs b/core/src/ambient.rs index efb599c..3de1d9f 100644 --- a/core/src/ambient.rs +++ b/core/src/ambient.rs @@ -10,13 +10,13 @@ use crate::{ }; #[derive(Debug, Clone, Copy)] -pub struct Ambient +pub struct Ambient { target: TTarget, filter: TFilter, ctxt: TCtxt, clock: TClock, - gen_id: TGenId, + id_gen: TIdGen, } impl Default for Ambient { @@ -32,23 +32,23 @@ impl Ambient { filter: Empty, ctxt: Empty, clock: Empty, - gen_id: Empty, + id_gen: Empty, } } } -impl Ambient { +impl Ambient { pub fn target(&self) -> &TTarget { &self.target } - pub fn with_target(self, target: U) -> Ambient { + pub fn with_target(self, target: U) -> Ambient { Ambient { target, filter: self.filter, ctxt: self.ctxt, clock: self.clock, - gen_id: self.gen_id, + id_gen: self.id_gen, } } @@ -56,13 +56,13 @@ impl Ambient(self, filter: U) -> Ambient { + pub fn with_filter(self, filter: U) -> Ambient { Ambient { target: self.target, filter, ctxt: self.ctxt, clock: self.clock, - gen_id: self.gen_id, + id_gen: self.id_gen, } } @@ -70,13 +70,13 @@ impl Ambient(self, ctxt: U) -> Ambient { + pub fn with_ctxt(self, ctxt: U) -> Ambient { Ambient { target: self.target, filter: self.filter, ctxt, clock: self.clock, - gen_id: self.gen_id, + id_gen: self.id_gen, } } @@ -84,33 +84,33 @@ impl Ambient(self, clock: U) -> Ambient { + pub fn with_clock(self, clock: U) -> Ambient { Ambient { target: self.target, filter: self.filter, ctxt: self.ctxt, clock, - gen_id: self.gen_id, + id_gen: self.id_gen, } } - pub fn gen_id(&self) -> &TGenId { - &self.gen_id + pub fn id_gen(&self) -> &TIdGen { + &self.id_gen } - pub fn with_gen_id(self, gen_id: U) -> Ambient { + pub fn with_id_gen(self, id_gen: U) -> Ambient { Ambient { target: self.target, filter: self.filter, ctxt: self.ctxt, clock: self.clock, - gen_id, + id_gen, } } } -impl Target - for Ambient +impl Target + for Ambient { fn event(&self, evt: &Event

) { self.target.event(evt) @@ -121,16 +121,16 @@ impl Target } } -impl Filter - for Ambient +impl Filter + for Ambient { fn matches(&self, evt: &Event

) -> bool { self.filter.matches(evt) } } -impl Ctxt - for Ambient +impl Ctxt + for Ambient { type CurrentProps = TCtxt::CurrentProps; type LocalFrame = TCtxt::LocalFrame; @@ -156,29 +156,31 @@ impl Ctxt } } -impl Clock - for Ambient +impl Clock + for Ambient { fn now(&self) -> Option { self.clock.now() } } -impl IdGen - for Ambient +impl IdGen + for Ambient { fn new_trace_id(&self) -> Option { - self.gen_id.new_trace_id() + self.id_gen.new_trace_id() } fn new_span_id(&self) -> Option { - self.gen_id.new_span_id() + self.id_gen.new_span_id() } } #[cfg(not(feature = "std"))] -pub fn get() -> Option<&'static Ambient> -{ +pub type Get = Option<&'static Ambient>; + +#[cfg(not(feature = "std"))] +pub fn get() -> Get { None::<&'static Ambient> } @@ -279,15 +281,15 @@ mod std_support { >, > = OnceLock::new(); - pub fn init( - ambient: Ambient, + pub fn init( + ambient: Ambient, ) -> Option< Ambient< &'static TTarget, &'static TFilter, &'static TCtxt, &'static TClock, - &'static TGenId, + &'static TIdGen, >, > where @@ -296,7 +298,7 @@ mod std_support { TCtxt: Ctxt + Send + Sync + 'static, TCtxt::LocalFrame: Send + 'static, TClock: Clock + Send + Sync + 'static, - TGenId: IdGen + Send + Sync + 'static, + TIdGen: IdGen + Send + Sync + 'static, { AMBIENT .set(Ambient { @@ -304,7 +306,7 @@ mod std_support { filter: Box::new(ambient.filter), ctxt: Box::new(ambient.ctxt), clock: Box::new(ambient.clock), - gen_id: Box::new(ambient.gen_id), + id_gen: Box::new(ambient.id_gen), }) .ok()?; @@ -315,11 +317,11 @@ mod std_support { filter: ambient.filter.as_any().downcast_ref()?, ctxt: ambient.ctxt.as_any().downcast_ref()?, clock: ambient.clock.as_any().downcast_ref()?, - gen_id: ambient.gen_id.as_any().downcast_ref()?, + id_gen: ambient.id_gen.as_any().downcast_ref()?, }) } - pub fn get() -> Option< + pub type Get = Option< Ambient< &'static (dyn ErasedTarget + Send + Sync), &'static (dyn ErasedFilter + Send + Sync), @@ -327,7 +329,9 @@ mod std_support { &'static (dyn ErasedClock + Send + Sync), &'static (dyn ErasedIdGen + Send + Sync), >, - > { + >; + + pub fn get() -> Get { let ambient = AMBIENT.get()?; Some(Ambient { @@ -335,7 +339,7 @@ mod std_support { filter: ambient.filter.as_super(), ctxt: ambient.ctxt.as_super(), clock: ambient.clock.as_super(), - gen_id: ambient.gen_id.as_super(), + id_gen: ambient.id_gen.as_super(), }) } } diff --git a/core/src/event.rs b/core/src/event.rs index ff1c8d9..d063864 100644 --- a/core/src/event.rs +++ b/core/src/event.rs @@ -4,11 +4,11 @@ use core::{ }; use crate::{ - empty::Empty, + extent::Extent, key::{Key, ToKey}, props::{ByRef, Chain, ErasedProps, Props}, template::{Render, Template}, - time::{Clock, Timer, Timestamp}, + time::Timestamp, value::{ToValue, Value}, well_known::{MSG_KEY, TPL_KEY, TSS_KEY, TS_KEY}, }; @@ -20,52 +20,6 @@ pub struct Event<'a, P> { props: P, } -pub trait Extent { - fn extent(&self) -> Option>; -} - -impl<'a, T: Extent + ?Sized> Extent for &'a T { - fn extent(&self) -> Option> { - (**self).extent() - } -} - -impl Extent for Empty { - fn extent(&self) -> Option> { - None - } -} - -impl<'a, P> Extent for Event<'a, P> { - fn extent(&self) -> Option> { - self.extent().cloned() - } -} - -impl Extent for Timestamp { - fn extent(&self) -> Option> { - Some(*self..*self) - } -} - -impl Extent for Range { - fn extent(&self) -> Option> { - Some(self.clone()) - } -} - -impl Extent for Timer { - fn extent(&self) -> Option> { - self.extent() - } -} - -impl Extent for Option { - fn extent(&self) -> Option> { - self.as_ref().and_then(|ts| ts.extent()) - } -} - impl<'a, P: Props> fmt::Debug for Event<'a, P> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut f = f.debug_struct("Event"); diff --git a/core/src/extent.rs b/core/src/extent.rs new file mode 100644 index 0000000..1c1a4ee --- /dev/null +++ b/core/src/extent.rs @@ -0,0 +1,52 @@ +use crate::{ + empty::Empty, + event::Event, + time::{Clock, Timer, Timestamp}, +}; +use core::ops::Range; + +pub trait Extent { + fn extent(&self) -> Option>; +} + +impl<'a, T: Extent + ?Sized> Extent for &'a T { + fn extent(&self) -> Option> { + (**self).extent() + } +} + +impl Extent for Empty { + fn extent(&self) -> Option> { + None + } +} + +impl<'a, P> Extent for Event<'a, P> { + fn extent(&self) -> Option> { + self.extent().cloned() + } +} + +impl Extent for Timestamp { + fn extent(&self) -> Option> { + Some(*self..*self) + } +} + +impl Extent for Range { + fn extent(&self) -> Option> { + Some(self.clone()) + } +} + +impl Extent for Timer { + fn extent(&self) -> Option> { + self.extent() + } +} + +impl Extent for Option { + fn extent(&self) -> Option> { + self.as_ref().and_then(|ts| ts.extent()) + } +} diff --git a/core/src/id.rs b/core/src/id.rs index bec8c7a..4f8aa86 100644 --- a/core/src/id.rs +++ b/core/src/id.rs @@ -9,7 +9,7 @@ use core::{ str::FromStr, }; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct TraceId(NonZeroU128); impl fmt::Debug for TraceId { @@ -28,7 +28,7 @@ impl FromStr for TraceId { type Err = ParseIdError; fn from_str(s: &str) -> Result { - todo!() + Self::try_from_hex_slice(s.as_bytes()) } } @@ -66,15 +66,44 @@ impl TraceId { for i in 0..src.len() { let b = src[i]; - dst[i * 2] = HEX[(b >> 4) as usize]; - dst[i * 2 + 1] = HEX[(b & 0x0f) as usize]; + dst[i * 2] = HEX_ENCODE_TABLE[(b >> 4) as usize]; + dst[i * 2 + 1] = HEX_ENCODE_TABLE[(b & 0x0f) as usize]; } dst } + + pub fn try_from_hex_slice(hex: &[u8]) -> Result { + let hex: &[u8; 32] = hex.try_into().map_err(|_| ParseIdError {})?; + + let mut dst = [0; 16]; + + let mut i = 0; + while i < 16 { + // Convert a two-char hex value (like `A8`) + // into a byte (like `10101000`) + let h1 = HEX_DECODE_TABLE[hex[i * 2] as usize]; + let h2 = HEX_DECODE_TABLE[hex[i * 2 + 1] as usize]; + + // We use `0xff` as a sentinel value to indicate + // an invalid hex character sequence (like the letter `G`) + if h1 | h2 == 0xff { + return Err(ParseIdError {}); + } + + // The upper nibble needs to be shifted into position + // to produce the final byte value + dst[i] = SHL4_TABLE[h1 as usize] | h2; + i += 1; + } + + Ok(TraceId::new( + NonZeroU128::new(u128::from_be_bytes(dst)).ok_or_else(|| ParseIdError {})?, + )) + } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct SpanId(NonZeroU64); impl fmt::Debug for SpanId { @@ -93,7 +122,7 @@ impl FromStr for SpanId { type Err = ParseIdError; fn from_str(s: &str) -> Result { - todo!() + Self::try_from_hex_slice(s.as_bytes()) } } @@ -131,18 +160,89 @@ impl SpanId { for i in 0..src.len() { let b = src[i]; - dst[i * 2] = HEX[(b >> 4) as usize]; - dst[i * 2 + 1] = HEX[(b & 0x0f) as usize]; + dst[i * 2] = HEX_ENCODE_TABLE[(b >> 4) as usize]; + dst[i * 2 + 1] = HEX_ENCODE_TABLE[(b & 0x0f) as usize]; } dst } + + pub fn try_from_hex_slice(hex: &[u8]) -> Result { + let hex: &[u8; 16] = hex.try_into().map_err(|_| ParseIdError {})?; + + let mut dst = [0; 8]; + + let mut i = 0; + while i < 8 { + // Convert a two-char hex value (like `A8`) + // into a byte (like `10101000`) + let h1 = HEX_DECODE_TABLE[hex[i * 2] as usize]; + let h2 = HEX_DECODE_TABLE[hex[i * 2 + 1] as usize]; + + // We use `0xff` as a sentinel value to indicate + // an invalid hex character sequence (like the letter `G`) + if h1 | h2 == 0xff { + return Err(ParseIdError {}); + } + + // The upper nibble needs to be shifted into position + // to produce the final byte value + dst[i] = SHL4_TABLE[h1 as usize] | h2; + i += 1; + } + + Ok(SpanId::new( + NonZeroU64::new(u64::from_be_bytes(dst)).ok_or_else(|| ParseIdError {})?, + )) + } } -const HEX: [u8; 16] = [ +/* +Original implementation: https://github.com/uuid-rs/uuid/blob/main/src/parser.rs + +Licensed under Apache 2.0 +*/ + +const HEX_ENCODE_TABLE: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f', ]; +const HEX_DECODE_TABLE: &[u8; 256] = &{ + let mut buf = [0; 256]; + let mut i: u8 = 0; + + loop { + buf[i as usize] = match i { + b'0'..=b'9' => i - b'0', + b'a'..=b'f' => i - b'a' + 10, + b'A'..=b'F' => i - b'A' + 10, + _ => 0xff, + }; + + if i == 255 { + break buf; + } + + i += 1 + } +}; + +const SHL4_TABLE: &[u8; 256] = &{ + let mut buf = [0; 256]; + let mut i: u8 = 0; + + loop { + buf[i as usize] = i.wrapping_shl(4); + + if i == 255 { + break buf; + } + + i += 1; + } +}; + +#[derive(Debug)] pub struct ParseIdError {} pub trait IdGen { @@ -243,3 +343,30 @@ impl<'a> IdGen for dyn ErasedIdGen + Send + Sync + 'a { (self as &(dyn ErasedIdGen + 'a)).new_span_id() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn span_id_roundtrip() { + let id = SpanId::new(NonZeroU64::new(u64::MAX / 2).unwrap()); + + let fmt = id.to_string(); + + let parsed: SpanId = fmt.parse().unwrap(); + + assert_eq!(id, parsed, "{}", fmt); + } + + #[test] + fn trace_id_roundtrip() { + let id = TraceId::new(NonZeroU128::new(u128::MAX / 2).unwrap()); + + let fmt = id.to_string(); + + let parsed: TraceId = fmt.parse().unwrap(); + + assert_eq!(id, parsed, "{}", fmt); + } +} diff --git a/core/src/level.rs b/core/src/level.rs index f5ae2f3..2698b86 100644 --- a/core/src/level.rs +++ b/core/src/level.rs @@ -1,7 +1,7 @@ use crate::value::{ToValue, Value}; use core::{fmt, str::FromStr}; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Level { Debug, Info, @@ -30,10 +30,45 @@ impl FromStr for Level { type Err = ParseLevelError; fn from_str(s: &str) -> Result { - todo!() + let lvl = s.as_bytes(); + + match lvl.get(0) { + Some(b'I') | Some(b'i') => parse(lvl, b"INFORMATION", Level::Info), + Some(b'D') | Some(b'd') => parse(lvl, b"DEBUG", Level::Debug), + Some(b'E') | Some(b'e') => parse(lvl, b"ERROR", Level::Error), + Some(b'W') | Some(b'w') => parse(lvl, b"WARNING", Level::Warn), + Some(_) => Err(ParseLevelError {}), + None => Err(ParseLevelError {}), + } + } +} + +fn parse( + mut input: &[u8], + mut expected_uppercase: &[u8], + ok: Level, +) -> Result { + // Assume the first character has already been matched + input = &input[1..]; + expected_uppercase = &expected_uppercase[1..]; + + while let Some(b) = input.get(0) { + let Some(e) = expected_uppercase.get(0) else { + return Err(ParseLevelError {}); + }; + + if b.to_ascii_uppercase() != *e { + return Err(ParseLevelError {}); + } + + expected_uppercase = &expected_uppercase[1..]; + input = &input[1..]; } + + Ok(ok) } +#[derive(Debug)] pub struct ParseLevelError {} impl Default for Level { @@ -55,3 +90,19 @@ impl<'v> Value<'v> { .or_else(|| self.parse()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn level_roundtrip() { + for lvl in [Level::Info, Level::Debug, Level::Warn, Level::Error] { + let fmt = lvl.to_string(); + + let parsed: Level = fmt.parse().unwrap(); + + assert_eq!(lvl, parsed, "{}", fmt); + } + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index f86b09a..ab35d6b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,6 +9,7 @@ pub mod ambient; pub mod ctxt; pub mod empty; pub mod event; +pub mod extent; pub mod filter; pub mod id; pub mod key; diff --git a/core/src/template.rs b/core/src/template.rs index 16ea112..7217b34 100644 --- a/core/src/template.rs +++ b/core/src/template.rs @@ -13,6 +13,8 @@ pub struct Template<'a>(TemplateKind<'a>); enum TemplateKind<'a> { Literal([Part<'a>; 1]), Parts(&'a [Part<'a>]), + #[cfg(feature = "alloc")] + Owned(Box<[Part<'static>]>), } impl<'a> TemplateKind<'a> { @@ -20,6 +22,8 @@ impl<'a> TemplateKind<'a> { match self { TemplateKind::Literal(ref parts) => parts, TemplateKind::Parts(parts) => parts, + #[cfg(feature = "alloc")] + TemplateKind::Owned(parts) => parts, } } } @@ -36,20 +40,22 @@ impl<'a> fmt::Display for Template<'a> { } } -impl<'a> Template<'a> { - pub fn new(parts: &'static [Part<'static>]) -> Template<'a> { +impl Template<'static> { + pub fn new(parts: &'static [Part<'static>]) -> Self { Template(TemplateKind::Parts(parts)) } - pub fn new_ref(parts: &'a [Part<'a>]) -> Template<'a> { - Template(TemplateKind::Parts(parts)) + pub fn literal(text: &'static str) -> Self { + Template(TemplateKind::Literal([Part::text(text)])) } +} - pub fn literal(text: &'static str) -> Template<'a> { - Template(TemplateKind::Literal([Part::text(text)])) +impl<'a> Template<'a> { + pub fn new_ref(parts: &'a [Part<'a>]) -> Self { + Template(TemplateKind::Parts(parts)) } - pub fn literal_ref(text: &'a str) -> Template<'a> { + pub fn literal_ref(text: &'a str) -> Self { Template(TemplateKind::Literal([Part::text_ref(text)])) } @@ -57,6 +63,8 @@ impl<'a> Template<'a> { match self.0 { TemplateKind::Literal([ref part]) => Template(TemplateKind::Literal([part.by_ref()])), TemplateKind::Parts(parts) => Template(TemplateKind::Parts(parts)), + #[cfg(feature = "alloc")] + TemplateKind::Owned(ref parts) => Template(TemplateKind::Parts(parts)), } } @@ -214,8 +222,8 @@ impl<'a, P: Props> fmt::Debug for Render<'a, P> { #[derive(Clone)] pub struct Part<'a>(PartKind<'a>); -impl<'a> Part<'a> { - pub fn text(text: &'static str) -> Part<'a> { +impl Part<'static> { + pub fn text(text: &'static str) -> Self { Part(PartKind::Text { value: text as *const str, value_static: Some(text), @@ -225,17 +233,7 @@ impl<'a> Part<'a> { }) } - pub fn text_ref(text: &'a str) -> Part<'a> { - Part(PartKind::Text { - value: text as *const str, - value_static: None, - #[cfg(feature = "alloc")] - value_owned: None, - _marker: PhantomData, - }) - } - - pub fn hole(label: &'static str) -> Part<'a> { + pub fn hole(label: &'static str) -> Self { Part(PartKind::Hole { label: label as *const str, label_static: Some(label), @@ -245,8 +243,20 @@ impl<'a> Part<'a> { _marker: PhantomData, }) } +} + +impl<'a> Part<'a> { + pub fn text_ref(text: &'a str) -> Self { + Part(PartKind::Text { + value: text as *const str, + value_static: None, + #[cfg(feature = "alloc")] + value_owned: None, + _marker: PhantomData, + }) + } - pub fn hole_ref(label: &'a str) -> Part<'a> { + pub fn hole_ref(label: &'a str) -> Self { Part(PartKind::Hole { label: label as *const str, label_static: None, @@ -293,10 +303,6 @@ impl<'a> Part<'a> { } } - fn to_owned(&self) -> Part<'static> { - todo!() - } - pub fn with_formatter(self, formatter: Formatter) -> Self { match self.0 { #[cfg(not(feature = "alloc"))] @@ -391,14 +397,14 @@ enum PartKind<'a> { value: *const str, value_static: Option<&'static str>, #[cfg(feature = "alloc")] - value_owned: Option, + value_owned: Option>, _marker: PhantomData<&'a str>, }, Hole { label: *const str, label_static: Option<&'static str>, #[cfg(feature = "alloc")] - label_owned: Option, + label_owned: Option>, formatter: Option, _marker: PhantomData<&'a str>, }, @@ -406,7 +412,81 @@ enum PartKind<'a> { impl<'a> Clone for PartKind<'a> { fn clone(&self) -> Self { - todo!() + match self { + #[cfg(feature = "alloc")] + PartKind::Text { + value, + value_static, + value_owned, + _marker, + } => match value_owned { + Some(value_owned) => { + let value_owned = value_owned.clone(); + + PartKind::Text { + value: &*value_owned as *const str, + value_static: None, + value_owned: Some(value_owned), + _marker: PhantomData, + } + } + None => PartKind::Text { + value: *value, + value_static: *value_static, + value_owned: None, + _marker: PhantomData, + }, + }, + #[cfg(not(feature = "alloc"))] + PartKind::Text { + value, + value_static, + _marker, + } => PartKind::Text { + value: *value, + value_static: *value_static, + _marker: PhantomData, + }, + #[cfg(feature = "alloc")] + PartKind::Hole { + label, + label_static, + label_owned, + ref formatter, + _marker, + } => match label_owned { + Some(label_owned) => { + let label_owned = label_owned.clone(); + + PartKind::Hole { + label: &*label_owned as *const str, + label_static: None, + label_owned: Some(label_owned), + formatter: formatter.clone(), + _marker: PhantomData, + } + } + None => PartKind::Hole { + label: *label, + label_static: *label_static, + label_owned: None, + formatter: formatter.clone(), + _marker: PhantomData, + }, + }, + #[cfg(not(feature = "alloc"))] + PartKind::Hole { + label, + label_static, + ref formatter, + _marker, + } => PartKind::Hole { + label: *label, + label_static: *label_static, + formatter: formatter.clone(), + _marker: PhantomData, + }, + } } } @@ -414,23 +494,100 @@ impl<'a> Clone for PartKind<'a> { mod alloc_support { use super::*; - pub struct OwnedTemplate(Vec>); + impl Template<'static> { + pub fn new_owned(parts: impl Into]>>) -> Self { + let parts = parts.into(); + + Template(TemplateKind::Owned(parts)) + } + } impl<'a> Template<'a> { - pub fn to_owned(&self) -> OwnedTemplate { - let mut parts = Vec::new(); + pub fn to_owned(&self) -> Template<'static> { + match self.0 { + TemplateKind::Owned(ref parts) => Template::new_owned(parts.clone()), + ref parts => { + let mut dst = Vec::new(); + + for part in parts.parts() { + dst.push(part.to_owned()); + } - for part in self.0.parts() { - parts.push(part.to_owned()); + Template::new_owned(dst) + } } + } + } + + impl Part<'static> { + pub fn text_owned(text: impl Into>) -> Self { + let value_owned = text.into(); + + Part(PartKind::Text { + value: &*value_owned as *const str, + value_static: None, + value_owned: Some(value_owned), + _marker: PhantomData, + }) + } - OwnedTemplate(parts) + pub fn hole_owned(label: impl Into>) -> Self { + let label_owned = label.into(); + + Part(PartKind::Hole { + label: &*label_owned as *const str, + label_static: None, + label_owned: Some(label_owned), + formatter: None, + _marker: PhantomData, + }) } } - impl OwnedTemplate { - pub fn by_ref(&self) -> Template { - Template(TemplateKind::Parts(&self.0)) + impl<'a> Part<'a> { + fn to_owned(&self) -> Part<'static> { + match self.0 { + PartKind::Text { + value_static: Some(value), + .. + } => Part::text(value), + PartKind::Text { value, .. } => { + let value_owned = unsafe { (*value).to_owned().into_boxed_str() }; + + Part(PartKind::Text { + value: &*value_owned as *const str, + value_static: None, + value_owned: Some(value_owned), + _marker: PhantomData, + }) + } + PartKind::Hole { + label_static: Some(label), + ref formatter, + .. + } => Part(PartKind::Hole { + label, + label_static: Some(label), + label_owned: None, + formatter: formatter.clone(), + _marker: PhantomData, + }), + PartKind::Hole { + label, + ref formatter, + .. + } => { + let label_owned = unsafe { (*label).to_owned().into_boxed_str() }; + + Part(PartKind::Hole { + label: &*label_owned as *const str, + label_static: None, + label_owned: Some(label_owned), + formatter: formatter.clone(), + _marker: PhantomData, + }) + } + } } } } diff --git a/core/src/time.rs b/core/src/time.rs index ade2eaa..8e64a4e 100644 --- a/core/src/time.rs +++ b/core/src/time.rs @@ -119,16 +119,16 @@ mod internal { fn dispatch_now(&self) -> Option; } - pub trait SealedTime { + pub trait SealedClock { fn erase_clock(&self) -> crate::internal::Erased<&dyn DispatchClock>; } } -pub trait ErasedClock: internal::SealedTime {} +pub trait ErasedClock: internal::SealedClock {} impl ErasedClock for T {} -impl internal::SealedTime for T { +impl internal::SealedClock for T { fn erase_clock(&self) -> crate::internal::Erased<&dyn internal::DispatchClock> { crate::internal::Erased(self) } @@ -189,7 +189,7 @@ fn parse_rfc3339(fmt: &str) -> Result { Licensed under Apache 2.0 */ - + if fmt.len() > 30 || fmt.len() < 19 { unimplemented!("invalid len {}", fmt.len()); } diff --git a/src/lib.rs b/src/lib.rs index 4d8b436..b5e3167 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,16 +18,16 @@ pub use emit_core::{ pub mod local_frame; pub use self::{ - ctxt::{Ctxt, ErasedCtxt}, + ctxt::Ctxt, event::Event, - filter::{ErasedFilter, Filter}, - id::{ErasedIdGen, IdGen, SpanId, TraceId}, + filter::Filter, + id::{IdGen, SpanId, TraceId}, key::Key, level::Level, props::Props, - target::{ErasedTarget, Target}, + target::Target, template::Template, - time::{Clock, ErasedClock, Timer, Timestamp}, + time::{Clock, Timer, Timestamp}, value::Value, well_known::WellKnown, }; @@ -89,45 +89,30 @@ pub fn emit(evt: &Event) { ); } -pub type Ambient = Option< - emit_core::ambient::Ambient< - &'static (dyn ErasedTarget + Send + Sync), - &'static (dyn ErasedFilter + Send + Sync), - &'static (dyn ErasedCtxt + Send + Sync), - &'static (dyn ErasedClock + Send + Sync), - &'static (dyn ErasedIdGen + Send + Sync), - >, ->; +pub type With = LocalFrame; -pub type With = LocalFrame; - -pub type StartTimer = Timer; - -#[track_caller] -pub fn ambient() -> Ambient { - emit_core::ambient::get() -} +pub type StartTimer = Timer; #[track_caller] pub fn with(props: impl Props) -> With { - base_with(ambient(), props) + base_with(emit_core::ambient::get(), props) } #[track_caller] pub fn start_timer() -> StartTimer { - Timer::start(ambient()) + Timer::start(emit_core::ambient::get()) } #[track_caller] pub fn new_span_id() -> Option { - ambient().new_span_id() + emit_core::ambient::get().new_span_id() } #[track_caller] pub fn current_span_id() -> Option { let mut span_id = None; - ambient().with_current(|ctxt| { + emit_core::ambient::get().with_current(|ctxt| { span_id = ctxt.span_id(); }); @@ -136,14 +121,14 @@ pub fn current_span_id() -> Option { #[track_caller] pub fn new_trace_id() -> Option { - ambient().new_trace_id() + emit_core::ambient::get().new_trace_id() } #[track_caller] pub fn current_trace_id() -> Option { let mut trace_id = None; - ambient().with_current(|ctxt| { + emit_core::ambient::get().with_current(|ctxt| { trace_id = ctxt.trace_id(); }); diff --git a/src/local_frame.rs b/src/local_frame.rs index 871d7d0..290c2e5 100644 --- a/src/local_frame.rs +++ b/src/local_frame.rs @@ -1,11 +1,11 @@ -use emit_core::{ctxt::Ctxt, props::Props}; -use std::{ +use core::{ future::Future, marker::PhantomData, mem, pin::Pin, task::{Context, Poll}, }; +use emit_core::{ctxt::Ctxt, props::Props}; pub struct LocalFrame { scope: mem::ManuallyDrop, diff --git a/src/macro_hooks.rs b/src/macro_hooks.rs index 9c4227a..d8b842c 100644 --- a/src/macro_hooks.rs +++ b/src/macro_hooks.rs @@ -3,7 +3,7 @@ use core::{any::Any, fmt, future::Future, ops::ControlFlow}; use emit_core::{ ambient, ctxt::Ctxt, - event::Extent, + extent::Extent, filter::Filter, id::{SpanId, TraceId}, key::ToKey, diff --git a/src/platform.rs b/src/platform.rs index 0aaec1f..59044ab 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -16,25 +16,25 @@ pub(crate) mod thread_local_ctxt; pub(crate) mod rng; #[cfg(feature = "std")] -type DefaultTime = system_clock::SystemClock; +type DefaultClock = system_clock::SystemClock; #[cfg(not(feature = "std"))] -type DefaultTime = Empty; +type DefaultClock = Empty; #[cfg(feature = "rng")] type DefaultIdGen = rng::Rng; #[cfg(not(feature = "rng"))] -type DefaultGenId = Empty; +type DefaultIdGen = Empty; #[cfg(feature = "std")] pub(crate) type DefaultCtxt = thread_local_ctxt::ThreadLocalCtxt; pub(crate) struct Platform { #[cfg(not(feature = "std"))] - pub(crate) clock: DefaultTime, + pub(crate) clock: DefaultClock, #[cfg(feature = "std")] pub(crate) clock: Box, #[cfg(not(feature = "std"))] - pub(crate) gen_id: DefaultIdGen, + pub(crate) id_gen: DefaultIdGen, #[cfg(feature = "std")] pub(crate) id_gen: Box, } @@ -49,9 +49,9 @@ impl Platform { pub fn new() -> Self { Platform { #[cfg(not(feature = "std"))] - clock: DefaultTime::default(), + clock: DefaultClock::default(), #[cfg(feature = "std")] - clock: Box::new(DefaultTime::default()), + clock: Box::new(DefaultClock::default()), #[cfg(not(feature = "std"))] id_gen: DefaultIdGen::default(), #[cfg(feature = "std")] diff --git a/src/setup.rs b/src/setup.rs index 4643696..7b127b1 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -10,6 +10,10 @@ use emit_core::{ use crate::platform::{DefaultCtxt, Platform}; +pub fn setup() -> Setup { + Setup::default() +} + type DefaultTarget = Empty; type DefaultFilter = Empty; @@ -85,7 +89,7 @@ where .with_filter(self.filter) .with_ctxt(self.ctxt) .with_clock(self.platform.clock) - .with_gen_id(self.platform.id_gen), + .with_id_gen(self.platform.id_gen), ) .expect("already initialized");