From 2d3ea4487a991c724dd792419a557185469234aa Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sun, 5 Jan 2025 10:53:57 +0100 Subject: [PATCH] Convert trace config to marker types --- crates/musli/src/context/default_context.rs | 59 +++++---- crates/musli/src/context/mod.rs | 9 +- crates/musli/src/context/trace.rs | 130 ++++++++++++++------ 3 files changed, 128 insertions(+), 70 deletions(-) diff --git a/crates/musli/src/context/default_context.rs b/crates/musli/src/context/default_context.rs index 4a555d657..80ee8df3a 100644 --- a/crates/musli/src/context/default_context.rs +++ b/crates/musli/src/context/default_context.rs @@ -4,36 +4,36 @@ use core::fmt; use crate::alloc::System; use crate::{Allocator, Context}; -use super::{ErrorMarker, Errors, NoTrace, Report, Trace, WithTrace}; +use super::{ErrorMarker, Errors, NoTrace, Report, Trace, TraceConfig, TraceImpl}; /// The default context which uses an allocator to track the location of errors. /// -/// This uses the provided allocator to allocate memory for the collected -/// diagnostics. The allocator to use can be provided using [`new_in`]. +/// This is typically constructed using [`new`] and by default uses the +/// [`System`] allocator to allocate memory. To customized the allocator to use +/// [`new_in`] can be used during construction. /// /// The default constructor is only available when the `alloc` feature is /// enabled, and will use the [`System`] allocator. /// +/// [`new`]: super::new /// [`new_in`]: super::new_in -pub struct DefaultContext +pub struct DefaultContext where - A: Allocator, - T: Trace, + A: Clone + Allocator, + B: TraceConfig, { alloc: A, - trace: T, + trace: B::Impl, } #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] impl DefaultContext { - /// Construct a new fully featured context which uses the [`System`] - /// allocator for memory. - /// - /// [`System`]: crate::alloc::System + /// Construct the default context which uses the [`System`] allocator for + /// memory. #[inline] pub fn new() -> Self { - Self::new_in(crate::alloc::System::new()) + Self::new_in(System::new()) } } @@ -53,10 +53,9 @@ where /// configurable number of diagnostics. #[inline] pub(super) fn new_in(alloc: A) -> Self { - Self { - alloc, - trace: NoTrace::new(), - } + let trace = NoTrace::new_in(alloc.clone()); + + Self { alloc, trace } } /// Unwrap the error marker or panic if there is no error. @@ -66,7 +65,7 @@ where } } -impl DefaultContext> +impl DefaultContext where A: Clone + Allocator, { @@ -98,7 +97,7 @@ where impl DefaultContext where A: Clone + Allocator, - B: Trace, + B: TraceConfig, { /// Enable tracing through the current allocator `A`. /// @@ -112,8 +111,8 @@ where /// [`errors`]: DefaultContext::errors /// [`Disabled`]: crate::alloc::Disabled #[inline] - pub fn with_trace(self) -> DefaultContext> { - let trace = WithTrace::new_in(self.alloc.clone()); + pub fn with_trace(self) -> DefaultContext { + let trace = Trace::new_in(self.alloc.clone()); DefaultContext { alloc: self.alloc, @@ -125,10 +124,10 @@ where impl Context for &DefaultContext where A: Clone + Allocator, - B: Trace, + B: TraceConfig, { type Error = ErrorMarker; - type Mark = B::Mark; + type Mark = <::Impl as TraceImpl>::Mark; type Allocator = A; #[inline] @@ -146,7 +145,7 @@ where where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { - self.trace.custom(&self.alloc, message); + self.trace.custom(&self.alloc, &message); ErrorMarker } @@ -155,7 +154,7 @@ where where T: fmt::Display, { - self.trace.message(&self.alloc, message); + self.trace.message(&self.alloc, &message); ErrorMarker } @@ -164,7 +163,7 @@ where where T: fmt::Display, { - self.trace.marked_message(&self.alloc, mark, message); + self.trace.marked_message(&self.alloc, mark, &message); ErrorMarker } @@ -173,7 +172,7 @@ where where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { - self.trace.marked_custom(&self.alloc, mark, message); + self.trace.marked_custom(&self.alloc, mark, &message); ErrorMarker } @@ -192,7 +191,7 @@ where where T: fmt::Display, { - self.trace.enter_named_field(name, field); + self.trace.enter_named_field(name, &field); } #[inline] @@ -200,7 +199,7 @@ where where T: fmt::Display, { - self.trace.enter_unnamed_field(index, name); + self.trace.enter_unnamed_field(index, &name); } #[inline] @@ -233,7 +232,7 @@ where where T: fmt::Display, { - self.trace.enter_variant(name, tag); + self.trace.enter_variant(name, &tag); } #[inline] @@ -256,7 +255,7 @@ where where T: fmt::Display, { - self.trace.enter_map_key(&self.alloc, field); + self.trace.enter_map_key(&self.alloc, &field); } #[inline] diff --git a/crates/musli/src/context/mod.rs b/crates/musli/src/context/mod.rs index dcb1b30e7..06350e026 100644 --- a/crates/musli/src/context/mod.rs +++ b/crates/musli/src/context/mod.rs @@ -7,7 +7,7 @@ use self::access::{Access, Shared}; mod trace; #[doc(inline)] -pub use self::trace::{Error, Errors, NoTrace, Report, Trace, WithTrace}; +pub use self::trace::{Error, Errors, NoTrace, Report, Trace, TraceConfig, TraceImpl}; mod error_marker; #[doc(inline)] @@ -68,7 +68,7 @@ use crate::Allocator; /// assert_eq!(string, "42"); /// # Ok::<_, musli::context::ErrorMarker>(()) /// ``` -/// +#[inline] pub fn new_in(alloc: A) -> DefaultContext where A: Clone + Allocator, @@ -76,9 +76,7 @@ where DefaultContext::new_in(alloc) } -/// Construct a new default context using the static [`System`] allocator. -/// -/// [`System`]: crate::alloc::System +/// Construct a new default context using the [`System`] allocator. /// /// # Examples /// @@ -96,6 +94,7 @@ where /// ``` #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] +#[inline] pub fn new() -> DefaultContext { DefaultContext::new() } diff --git a/crates/musli/src/context/trace.rs b/crates/musli/src/context/trace.rs index 86d954054..870013d24 100644 --- a/crates/musli/src/context/trace.rs +++ b/crates/musli/src/context/trace.rs @@ -2,6 +2,7 @@ use core::cell::{Cell, UnsafeCell}; use core::fmt; +use core::marker::PhantomData; use core::mem::take; use core::ops::Range; use core::slice; @@ -15,18 +16,34 @@ mod sealed { use crate::alloc::Allocator; pub trait Sealed {} - impl Sealed for super::WithTrace where A: Allocator {} + impl Sealed for super::WithTraceImpl where A: Allocator {} + impl Sealed for super::NoTraceImpl where A: Allocator {} + impl Sealed for super::Trace {} impl Sealed for super::NoTrace {} } +/// Trait for marker types indicating the tracing configuration. +pub trait TraceConfig: self::sealed::Sealed { + #[doc(hidden)] + type Impl: TraceImpl + where + A: Clone + Allocator; + + #[doc(hidden)] + fn new_in(alloc: A) -> Self::Impl + where + A: Clone + Allocator; +} + /// The trait governing tracing in a default context. -pub trait Trace +pub trait TraceImpl where Self: Sized + self::sealed::Sealed, - A: Allocator, { #[doc(hidden)] type Mark; + #[doc(hidden)] + type Allocator: Allocator; #[doc(hidden)] fn clear(&self); @@ -38,32 +55,32 @@ where fn mark(&self) -> Self::Mark; #[doc(hidden)] - fn custom(&self, alloc: &A, message: T) + fn custom(&self, alloc: &Self::Allocator, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug; #[doc(hidden)] - fn message(&self, alloc: &A, message: T) + fn message(&self, alloc: &Self::Allocator, message: &T) where T: fmt::Display; #[doc(hidden)] - fn marked_message(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_message(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: fmt::Display; #[doc(hidden)] - fn marked_custom(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_custom(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug; #[doc(hidden)] - fn enter_named_field(&self, name: &'static str, field: T) + fn enter_named_field(&self, name: &'static str, field: &T) where T: fmt::Display; #[doc(hidden)] - fn enter_unnamed_field(&self, index: u32, name: T) + fn enter_unnamed_field(&self, index: u32, name: &T) where T: fmt::Display; @@ -83,7 +100,7 @@ where fn leave_enum(&self); #[doc(hidden)] - fn enter_variant(&self, name: &'static str, _: T) + fn enter_variant(&self, name: &'static str, _: &T) where T: fmt::Display; @@ -97,7 +114,7 @@ where fn leave_sequence_index(&self); #[doc(hidden)] - fn enter_map_key(&self, alloc: &A, field: T) + fn enter_map_key(&self, alloc: &Self::Allocator, field: &T) where T: fmt::Display; @@ -105,9 +122,28 @@ where fn leave_map_key(&self); } +/// Marker type indicating that tracing is enabled. +#[non_exhaustive] +pub struct Trace; + +impl TraceConfig for Trace { + type Impl + = WithTraceImpl + where + A: Clone + Allocator; + + #[inline] + fn new_in(alloc: A) -> Self::Impl + where + A: Clone + Allocator, + { + WithTraceImpl::new_in(alloc) + } +} + /// Trace configuration indicating that tracing is enabled through the allocator /// `A`. -pub struct WithTrace +pub struct WithTraceImpl where A: Allocator, { @@ -120,7 +156,7 @@ where access: Access, } -impl WithTrace +impl WithTraceImpl where A: Clone + Allocator, { @@ -220,11 +256,12 @@ where } } -impl Trace for WithTrace +impl TraceImpl for WithTraceImpl where A: Clone + Allocator, { type Mark = usize; + type Allocator = A; #[inline] fn clear(&self) { @@ -249,7 +286,7 @@ where } #[inline] - fn custom(&self, alloc: &A, message: T) + fn custom(&self, alloc: &Self::Allocator, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { @@ -259,7 +296,7 @@ where } #[inline] - fn message(&self, alloc: &A, message: T) + fn message(&self, alloc: &Self::Allocator, message: &T) where T: fmt::Display, { @@ -269,7 +306,7 @@ where } #[inline] - fn marked_message(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_message(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: fmt::Display, { @@ -279,7 +316,7 @@ where } #[inline] - fn marked_custom(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_custom(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { @@ -289,7 +326,7 @@ where } #[inline] - fn enter_named_field(&self, name: &'static str, _: T) + fn enter_named_field(&self, name: &'static str, _: &T) where T: fmt::Display, { @@ -297,7 +334,7 @@ where } #[inline] - fn enter_unnamed_field(&self, index: u32, _: T) + fn enter_unnamed_field(&self, index: u32, _: &T) where T: fmt::Display, { @@ -338,7 +375,7 @@ where } #[inline] - fn enter_variant(&self, name: &'static str, _: T) { + fn enter_variant(&self, name: &'static str, _: &T) { self.push_path(Step::Variant(name)); } @@ -358,7 +395,7 @@ where } #[inline] - fn enter_map_key(&self, alloc: &A, field: T) + fn enter_map_key(&self, alloc: &Self::Allocator, field: &T) where T: fmt::Display, { @@ -373,18 +410,21 @@ where } } -/// Trace configuration indicating that tracing is fully disabled. -#[non_exhaustive] -pub struct NoTrace { +pub struct NoTraceImpl { /// Simple indicator whether an error has or has not occured. error: Cell, + _marker: PhantomData, } -impl NoTrace { +impl NoTraceImpl +where + A: Allocator, +{ #[inline] pub(super) const fn new() -> Self { Self { error: Cell::new(false), + _marker: PhantomData, } } @@ -398,11 +438,31 @@ impl NoTrace { } } -impl Trace for NoTrace +/// Trace configuration indicating that tracing is fully disabled. +#[non_exhaustive] +pub struct NoTrace; + +impl TraceConfig for NoTrace { + type Impl + = NoTraceImpl + where + A: Clone + Allocator; + + #[inline] + fn new_in(_: A) -> Self::Impl + where + A: Clone + Allocator, + { + NoTraceImpl::new() + } +} + +impl TraceImpl for NoTraceImpl where A: Allocator, { type Mark = usize; + type Allocator = A; #[inline] fn clear(&self) {} @@ -418,7 +478,7 @@ where } #[inline] - fn custom(&self, alloc: &A, message: T) + fn custom(&self, alloc: &Self::Allocator, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { @@ -427,7 +487,7 @@ where } #[inline] - fn message(&self, alloc: &A, message: T) + fn message(&self, alloc: &Self::Allocator, message: &T) where T: fmt::Display, { @@ -436,7 +496,7 @@ where } #[inline] - fn marked_message(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_message(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: fmt::Display, { @@ -446,7 +506,7 @@ where } #[inline] - fn marked_custom(&self, alloc: &A, mark: &Self::Mark, message: T) + fn marked_custom(&self, alloc: &Self::Allocator, mark: &Self::Mark, message: &T) where T: 'static + Send + Sync + fmt::Display + fmt::Debug, { @@ -456,7 +516,7 @@ where } #[inline] - fn enter_named_field(&self, name: &'static str, field: T) + fn enter_named_field(&self, name: &'static str, field: &T) where T: fmt::Display, { @@ -465,7 +525,7 @@ where } #[inline] - fn enter_unnamed_field(&self, index: u32, field: T) + fn enter_unnamed_field(&self, index: u32, field: &T) where T: fmt::Display, { @@ -493,7 +553,7 @@ where fn leave_enum(&self) {} #[inline] - fn enter_variant(&self, name: &'static str, variant: T) + fn enter_variant(&self, name: &'static str, variant: &T) where T: fmt::Display, { @@ -513,7 +573,7 @@ where fn leave_sequence_index(&self) {} #[inline] - fn enter_map_key(&self, alloc: &A, field: T) + fn enter_map_key(&self, alloc: &Self::Allocator, field: &T) where T: fmt::Display, {