amethystate 0.26.0

A state manager for Rust applications
Documentation
//! Showing a value whose type may or may not be showable.
//!
//! A declared field holds whatever its type is, and nothing requires that type
//! to implement `Debug`. Generated code still has to print it - in the struct's
//! own `Debug`, and in [`FieldView::value`](crate::observability::FieldView).
//!
//! The pick happens at compile time and costs nothing at runtime. An inherent
//! method on `Shown<T>` is reached before one on `&Shown<T>`, so a `T` that
//! implements `Debug` takes the first and everything else falls to the second -
//! which is how a trait bound is asked about without a `where` clause to say it
//! in.
//!
//! Everything here is `doc(hidden)`. It is public because an expansion lands in
//! the caller's crate and has to name it; the two traits mean nothing written
//! by hand, and nothing outside a generated `Debug` should be reading them.

use std::fmt;

/// What stands in for a value whose type cannot be printed.
#[doc(hidden)]
pub struct Opaque;

impl fmt::Debug for Opaque {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("<opaque>")
    }
}

/// The one that stands in for every value that cannot be printed.
///
/// A `static` rather than a temporary, because what is handed back outlives
/// the `Shown` that was asked.
static OPAQUE: Opaque = Opaque;

/// A value being asked whether it can be shown.
#[doc(hidden)]
pub struct Shown<'a, T>(pub &'a T);

#[doc(hidden)]
pub trait ShownByDebug<'a> {
    fn shown(&self) -> &'a dyn fmt::Debug;
}

impl<'a, T: fmt::Debug> ShownByDebug<'a> for Shown<'a, T> {
    fn shown(&self) -> &'a dyn fmt::Debug {
        self.0
    }
}

#[doc(hidden)]
pub trait ShownAsOpaque<'a> {
    fn shown(&self) -> &'a dyn fmt::Debug;
}

impl<'a, T> ShownAsOpaque<'a> for &Shown<'a, T> {
    fn shown(&self) -> &'a dyn fmt::Debug {
        &OPAQUE
    }
}