1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
// Copyright (c) The debug-ignore Contributors
// SPDX-License-Identifier: MIT OR Apache-2.0
//! This library contains `DebugIgnore`, a newtype wrapper that causes a field to be skipped while
//! printing out `Debug` output.
//!
//! # Examples
//!
//! ```rust
//! use debug_ignore::DebugIgnore;
//!
//! // Some structs have many fields with large `Debug` implementations.
//! #[derive(Debug)]
//! struct InnerStructWithLotsOfDebugInfo {
//! field: &'static str,
//! // ...
//! }
//!
//! #[derive(Debug)]
//! pub struct PublicStruct {
//! inner: DebugIgnore<InnerStructWithLotsOfDebugInfo>,
//! }
//!
//! impl PublicStruct {
//! pub fn new() -> Self {
//! Self {
//! // DebugIgnore<T> has a `From<T>` impl for the inner type; you can also construct
//! // one explicitly.
//! inner: InnerStructWithLotsOfDebugInfo { field: "field", /* ... */ }.into(),
//! }
//! }
//! }
//!
//! let x = PublicStruct::new();
//! assert_eq!(format!("{:?}", x), "PublicStruct { inner: ... }");
//!
//! // Fields within inner can still be accessed through the Deref impl.
//! assert_eq!(x.inner.field, "field");
//! ```
//!
//! # Why?
//!
//! Some structs have many fields with large `Debug` implementations. It can be really annoying to
//! go through a ton of usually irrelevant `Debug` output.
//!
//! `DebugIgnore` is a zero-cost, zero-compile-time way to achieve a `Debug` impl that skips over a
//! field.
//!
//! # Optional features
//!
//! `serde`: `serde` support with `#[serde(transparent)]`.
//!
//! # Rust version support
//!
//! The MSRV is **Rust 1.34** though this crate likely builds with older versions. This crate is
//! too trivial to require anything more recent.
//!
//! Optional features may require newer versions of Rust.
//!
//! # Alternatives
//!
//! * Implement `Debug` by hand.
//! * [`derivative`](https://crates.io/crates/derivative) has greater control over the behavior of
//! `Debug` impls, at the cost of a compile-time proc-macro dependency.
#![no_std]
use core::{
fmt,
ops::{Deref, DerefMut},
str::FromStr,
};
/// A newtype wrapper that causes the field within to be ignored while printing out `Debug` output.
///
/// For more, see the [crate documentation](self).
#[derive(Copy, Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct DebugIgnore<T: ?Sized>(pub T);
/// The point of this struct.
impl<T: ?Sized> fmt::Debug for DebugIgnore<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "...")
}
}
// ---
// Other trait impls
// ---
impl<T> From<T> for DebugIgnore<T> {
#[inline]
fn from(t: T) -> Self {
Self(t)
}
}
impl<T: ?Sized> Deref for DebugIgnore<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: ?Sized> DerefMut for DebugIgnore<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: FromStr> FromStr for DebugIgnore<T> {
type Err = T::Err;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(DebugIgnore)
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for DebugIgnore<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: ?Sized, Q: ?Sized> AsRef<Q> for DebugIgnore<T>
where
T: AsRef<Q>,
{
#[inline]
fn as_ref(&self) -> &Q {
self.0.as_ref()
}
}