mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
shorten dbg-pls to 16 lines
This commit is contained in:
parent
1ec9a9df34
commit
6ca7ab5734
13 changed files with 4 additions and 973 deletions
54
Cargo.lock
generated
54
Cargo.lock
generated
|
|
@ -5,13 +5,6 @@ version = 3
|
|||
[[package]]
|
||||
name = "dbg-pls"
|
||||
version = "0.2.2"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"ryu",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dilaria"
|
||||
|
|
@ -19,50 +12,3 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"dbg-pls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
|
|
|||
|
|
@ -7,19 +7,3 @@ description = "Syntax aware pretty-printing debugging"
|
|||
license = "MIT"
|
||||
repository = "https://github.com/conradludgate/dbg-pls"
|
||||
readme = "README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1", features = ["full"] }
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
itoa = "1"
|
||||
ryu = "1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for list-like structures.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
///
|
||||
/// struct Foo(Vec<i32>);
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter<'_>) {
|
||||
/// f.debug_list().entries(&self.0).finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let value = Foo(vec![10, 11]);
|
||||
/// assert_eq!(format!("{}", pretty(&value)), "[10, 11]");
|
||||
/// ```
|
||||
pub struct DebugList<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
expr: syn::ExprArray,
|
||||
}
|
||||
|
||||
impl<'a> DebugList<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>) -> Self {
|
||||
DebugList {
|
||||
formatter,
|
||||
expr: syn::ExprArray {
|
||||
attrs: vec![],
|
||||
bracket_token: syn::token::Bracket::default(),
|
||||
elems: syn::punctuated::Punctuated::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a new entry to the list output.
|
||||
#[must_use]
|
||||
pub fn entry(mut self, entry: &dyn DebugPls) -> Self {
|
||||
self.expr.elems.push(Formatter::process(entry));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds all the entries to the list output.
|
||||
#[must_use]
|
||||
pub fn entries<D, I>(mut self, entries: I) -> Self
|
||||
where
|
||||
D: DebugPls,
|
||||
I: IntoIterator<Item = D>,
|
||||
{
|
||||
self.extend(entries);
|
||||
self
|
||||
}
|
||||
|
||||
/// Closes off the list
|
||||
pub fn finish(self) {
|
||||
self.formatter.write_expr(self.expr);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'f, D: DebugPls> Extend<D> for DebugList<'f> {
|
||||
fn extend<T: IntoIterator<Item = D>>(&mut self, iter: T) {
|
||||
self.expr
|
||||
.elems
|
||||
.extend(iter.into_iter().map(|entry| Formatter::process(&entry)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
use std::iter::FromIterator;
|
||||
|
||||
use syn::punctuated::Punctuated;
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for maps.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
/// use std::collections::BTreeMap;
|
||||
///
|
||||
/// struct Foo(BTreeMap<String, i32>);
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter) {
|
||||
/// f.debug_map().entries(&self.0).finish()
|
||||
/// }
|
||||
/// }
|
||||
/// let mut value = Foo(BTreeMap::from([
|
||||
/// ("Hello".to_string(), 5),
|
||||
/// ("World".to_string(), 10),
|
||||
/// ]));
|
||||
/// assert_eq!(
|
||||
/// format!("{}", pretty(&value)),
|
||||
/// "{
|
||||
/// [\"Hello\"] = 5;
|
||||
/// [\"World\"] = 10;
|
||||
/// }",
|
||||
/// );
|
||||
/// ```
|
||||
pub struct DebugMap<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
set: syn::Block,
|
||||
key: Option<syn::Expr>,
|
||||
}
|
||||
|
||||
impl<'a> DebugMap<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>) -> Self {
|
||||
DebugMap {
|
||||
formatter,
|
||||
set: syn::Block {
|
||||
brace_token: syn::token::Brace::default(),
|
||||
stmts: vec![],
|
||||
},
|
||||
key: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the key part to the map output.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `key` must be called before `value` and each call to `key` must be followed
|
||||
/// by a corresponding call to `value`. Otherwise this method will panic.
|
||||
#[must_use]
|
||||
pub fn key(mut self, key: &dyn DebugPls) -> Self {
|
||||
if self.key.replace(Formatter::process(key)).is_some() {
|
||||
panic!("attempted to begin a new map entry without completing the previous one");
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds the value part to the map output.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `key` must be called before `value` and each call to `key` must be followed
|
||||
/// by a corresponding call to `value`. Otherwise this method will panic.
|
||||
#[must_use]
|
||||
pub fn value(mut self, value: &dyn DebugPls) -> Self {
|
||||
let key = self
|
||||
.key
|
||||
.take()
|
||||
.expect("attempted to format a map value before its key");
|
||||
let value = Formatter::process(value);
|
||||
let entry = syn::ExprAssign {
|
||||
attrs: vec![],
|
||||
left: Box::new(
|
||||
syn::ExprArray {
|
||||
attrs: vec![],
|
||||
bracket_token: syn::token::Bracket::default(),
|
||||
elems: Punctuated::from_iter([key]),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
eq_token: syn::token::Eq::default(),
|
||||
right: Box::new(value),
|
||||
};
|
||||
self.set
|
||||
.stmts
|
||||
.push(syn::Stmt::Semi(entry.into(), syn::token::Semi::default()));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds the entry to the map output.
|
||||
#[must_use]
|
||||
pub fn entry(self, key: &dyn DebugPls, value: &dyn DebugPls) -> Self {
|
||||
self.key(key).value(value)
|
||||
}
|
||||
|
||||
/// Adds all the entries to the map output.
|
||||
#[must_use]
|
||||
pub fn entries<K, V, I>(self, entries: I) -> Self
|
||||
where
|
||||
K: DebugPls,
|
||||
V: DebugPls,
|
||||
I: IntoIterator<Item = (K, V)>,
|
||||
{
|
||||
entries
|
||||
.into_iter()
|
||||
.fold(self, |f, (key, value)| f.entry(&key, &value))
|
||||
}
|
||||
|
||||
/// Closes off the map.
|
||||
pub fn finish(self) {
|
||||
self.formatter.write_expr(syn::ExprBlock {
|
||||
attrs: vec![],
|
||||
label: None,
|
||||
block: self.set,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for sets.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
/// use std::collections::BTreeSet;
|
||||
///
|
||||
/// struct Foo(BTreeSet<String>);
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter) {
|
||||
/// f.debug_set().entries(&self.0).finish()
|
||||
/// }
|
||||
/// }
|
||||
/// let mut value = Foo(BTreeSet::from([
|
||||
/// "Hello".to_string(),
|
||||
/// "World".to_string(),
|
||||
/// ]));
|
||||
/// assert_eq!(
|
||||
/// format!("{}", pretty(&value)),
|
||||
/// "{
|
||||
/// \"Hello\";
|
||||
/// \"World\"
|
||||
/// }",
|
||||
/// );
|
||||
/// ```
|
||||
pub struct DebugSet<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
set: syn::Block,
|
||||
}
|
||||
|
||||
impl<'a> DebugSet<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>) -> Self {
|
||||
DebugSet {
|
||||
formatter,
|
||||
set: syn::Block {
|
||||
brace_token: syn::token::Brace::default(),
|
||||
stmts: vec![],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the entry to the set output.
|
||||
#[must_use]
|
||||
pub fn entry(mut self, value: &dyn DebugPls) -> Self {
|
||||
let expr = Formatter::process(value);
|
||||
self.set
|
||||
.stmts
|
||||
.push(syn::Stmt::Semi(expr, syn::token::Semi::default()));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds all the entries to the set output.
|
||||
#[must_use]
|
||||
pub fn entries<V, I>(self, entries: I) -> Self
|
||||
where
|
||||
V: DebugPls,
|
||||
I: IntoIterator<Item = V>,
|
||||
{
|
||||
entries.into_iter().fold(self, |f, entry| f.entry(&entry))
|
||||
}
|
||||
|
||||
/// Closes off the set.
|
||||
pub fn finish(mut self) {
|
||||
// remove the last semicolon
|
||||
if let Some(syn::Stmt::Semi(entry, _)) = self.set.stmts.pop() {
|
||||
self.set.stmts.push(syn::Stmt::Expr(entry));
|
||||
}
|
||||
|
||||
self.formatter.write_expr(syn::ExprBlock {
|
||||
attrs: vec![],
|
||||
label: None,
|
||||
block: self.set,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
use syn::__private::Span;
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for structs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
///
|
||||
/// struct Foo {
|
||||
/// bar: i32,
|
||||
/// baz: String,
|
||||
/// }
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter) {
|
||||
/// f.debug_struct("Foo")
|
||||
/// .field("bar", &self.bar)
|
||||
/// .field("baz", &self.baz)
|
||||
/// .finish()
|
||||
/// }
|
||||
/// }
|
||||
/// let value = Foo {
|
||||
/// bar: 10,
|
||||
/// baz: "Hello World".to_string(),
|
||||
/// };
|
||||
/// assert_eq!(
|
||||
/// format!("{}", pretty(&value)),
|
||||
/// "Foo { bar: 10, baz: \"Hello World\" }",
|
||||
/// );
|
||||
/// ```
|
||||
pub struct DebugStruct<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
expr: syn::ExprStruct,
|
||||
}
|
||||
|
||||
impl<'a> DebugStruct<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>, name: &str) -> Self {
|
||||
DebugStruct {
|
||||
formatter,
|
||||
expr: syn::ExprStruct {
|
||||
attrs: vec![],
|
||||
path: syn::Ident::new(name, Span::call_site()).into(),
|
||||
brace_token: syn::token::Brace::default(),
|
||||
fields: syn::punctuated::Punctuated::new(),
|
||||
dot2_token: None,
|
||||
rest: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the field to the struct output.
|
||||
#[must_use]
|
||||
pub fn field(mut self, name: &str, value: &dyn DebugPls) -> Self {
|
||||
self.expr.fields.push(syn::FieldValue {
|
||||
expr: Formatter::process(value),
|
||||
attrs: vec![],
|
||||
member: syn::Member::Named(syn::Ident::new(name, Span::call_site())),
|
||||
colon_token: Some(syn::token::Colon::default()),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Closes off the struct.
|
||||
pub fn finish(self) {
|
||||
self.formatter.write_expr(self.expr);
|
||||
}
|
||||
|
||||
/// Closes off the struct with `..`.
|
||||
pub fn finish_non_exhaustive(mut self) {
|
||||
self.expr.dot2_token = Some(syn::token::Dot2::default());
|
||||
self.finish();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for tuples.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
///
|
||||
/// struct Foo(i32, String);
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter) {
|
||||
/// f.debug_tuple()
|
||||
/// .field(&self.0)
|
||||
/// .field(&self.1)
|
||||
/// .finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let value = Foo(10, "Hello".to_string());
|
||||
/// assert_eq!(format!("{}", pretty(&value)), "(10, \"Hello\")");
|
||||
/// ```
|
||||
pub struct DebugTuple<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
expr: syn::ExprTuple,
|
||||
}
|
||||
|
||||
impl<'a> DebugTuple<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>) -> Self {
|
||||
DebugTuple {
|
||||
formatter,
|
||||
expr: syn::ExprTuple {
|
||||
attrs: vec![],
|
||||
paren_token: syn::token::Paren::default(),
|
||||
elems: syn::punctuated::Punctuated::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the field to the tuple output.
|
||||
#[must_use]
|
||||
pub fn field(mut self, value: &dyn DebugPls) -> Self {
|
||||
self.expr.elems.push(Formatter::process(value));
|
||||
self
|
||||
}
|
||||
|
||||
/// Closes off the tuple.
|
||||
pub fn finish(self) {
|
||||
self.formatter.write_expr(self.expr);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
use syn::__private::Span;
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
|
||||
/// A helper designed to assist with creation of
|
||||
/// [`DebugPls`] implementations for tuple structs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use dbg_pls::{pretty, DebugPls, Formatter};
|
||||
///
|
||||
/// struct Foo(i32, String);
|
||||
///
|
||||
/// impl DebugPls for Foo {
|
||||
/// fn fmt(&self, f: Formatter) {
|
||||
/// f.debug_tuple_struct("Foo")
|
||||
/// .field(&self.0)
|
||||
/// .field(&self.1)
|
||||
/// .finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let value = Foo(10, "Hello".to_string());
|
||||
/// assert_eq!(format!("{}", pretty(&value)), "Foo(10, \"Hello\")");
|
||||
/// ```
|
||||
pub struct DebugTupleStruct<'a> {
|
||||
formatter: Formatter<'a>,
|
||||
expr: syn::ExprCall,
|
||||
}
|
||||
|
||||
impl<'a> DebugTupleStruct<'a> {
|
||||
pub(crate) fn new(formatter: Formatter<'a>, name: &str) -> Self {
|
||||
DebugTupleStruct {
|
||||
formatter,
|
||||
expr: syn::ExprCall {
|
||||
attrs: vec![],
|
||||
func: Box::new(syn::Expr::Path(syn::ExprPath {
|
||||
attrs: vec![],
|
||||
qself: None,
|
||||
path: syn::Ident::new(name, Span::call_site()).into(),
|
||||
})),
|
||||
paren_token: syn::token::Paren::default(),
|
||||
args: syn::punctuated::Punctuated::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the field to the tuple struct output.
|
||||
#[must_use]
|
||||
pub fn field(mut self, value: &dyn DebugPls) -> Self {
|
||||
self.expr.args.push(Formatter::process(value));
|
||||
self
|
||||
}
|
||||
|
||||
/// Closes off the tuple struct.
|
||||
pub fn finish(self) {
|
||||
self.formatter.write_expr(self.expr);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
mod std;
|
||||
mod syn_impls;
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
mod collections;
|
||||
|
||||
use std::{
|
||||
ops::ControlFlow,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex, MutexGuard, TryLockError},
|
||||
task::Poll,
|
||||
};
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
use syn::__private::Span;
|
||||
|
||||
impl<T: ?Sized + DebugPls> DebugPls for Box<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
DebugPls::fmt(&**self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DebugPls + ?Sized> DebugPls for &'a D {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
D::fmt(self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + DebugPls> DebugPls for Rc<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
DebugPls::fmt(&**self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + DebugPls> DebugPls for Arc<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
DebugPls::fmt(&**self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + DebugPls> DebugPls for MutexGuard<'_, T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
DebugPls::fmt(&**self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + DebugPls> DebugPls for Mutex<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
let d = f.debug_struct("Mutex");
|
||||
match self.try_lock() {
|
||||
Ok(guard) => d.field("data", &&*guard),
|
||||
Err(TryLockError::Poisoned(err)) => d.field("data", &&**err.get_ref()),
|
||||
Err(TryLockError::WouldBlock) => d.field("data", &"<locked>"),
|
||||
}
|
||||
.field("poisoned", &self.is_poisoned())
|
||||
.finish_non_exhaustive();
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! debug_integers {
|
||||
($($T:ident)*) => {$(
|
||||
impl DebugPls for $T {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
let mut buf = itoa::Buffer::new();
|
||||
f.write_expr(syn::ExprLit {
|
||||
attrs: vec![],
|
||||
lit: syn::LitInt::new(buf.format(*self), Span::call_site()).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
debug_integers! {
|
||||
i8 i16 i32 i64 i128 isize
|
||||
u8 u16 u32 u64 u128 usize
|
||||
}
|
||||
|
||||
macro_rules! debug_floats {
|
||||
($ty:ident) => {
|
||||
impl DebugPls for $ty {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
let mut buf = ryu::Buffer::new();
|
||||
f.write_expr(syn::ExprLit {
|
||||
attrs: vec![],
|
||||
lit: syn::LitFloat::new(buf.format(*self), Span::call_site()).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
debug_floats! { f32 }
|
||||
debug_floats! { f64 }
|
||||
|
||||
impl DebugPls for bool {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
true => f.debug_ident("true"),
|
||||
false => f.debug_ident("false"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls> DebugPls for [D] {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls, const N: usize> DebugPls for [D; N] {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for str {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.write_expr(syn::ExprLit {
|
||||
attrs: vec![],
|
||||
lit: syn::LitStr::new(self, Span::call_site()).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for String {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
DebugPls::fmt(self.as_str(), f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DebugPls, E: DebugPls> DebugPls for Result<T, E> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
Ok(t) => f.debug_tuple_struct("Ok").field(t).finish(),
|
||||
Err(e) => f.debug_tuple_struct("Err").field(e).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: DebugPls, C: DebugPls> DebugPls for ControlFlow<B, C> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
ControlFlow::Break(b) => f.debug_tuple_struct("Break").field(b).finish(),
|
||||
ControlFlow::Continue(c) => f.debug_tuple_struct("Continue").field(c).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DebugPls> DebugPls for Option<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
Some(t) => f.debug_tuple_struct("Some").field(t).finish(),
|
||||
None => f.debug_ident("None"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DebugPls> DebugPls for Poll<T> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
Poll::Ready(t) => f.debug_tuple_struct("Ready").field(t).finish(),
|
||||
Poll::Pending => f.debug_ident("Pending"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
|
||||
impl<K: DebugPls, V: DebugPls, S: ::std::hash::BuildHasher> DebugPls for HashMap<K, V, S> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_map().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: DebugPls, V: DebugPls> DebugPls for BTreeMap<K, V> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_map().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: DebugPls, S: ::std::hash::BuildHasher> DebugPls for HashSet<V, S> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_set().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: DebugPls> DebugPls for BTreeSet<V> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_set().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls> DebugPls for Vec<D> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls> DebugPls for VecDeque<D> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls> DebugPls for LinkedList<D> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DebugPls> DebugPls for BinaryHeap<D> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_list().entries(self).finish();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
use syn::{
|
||||
punctuated::{Pair, Punctuated},
|
||||
token::{Bracket, Comma},
|
||||
Attribute, Expr, ExprArray, ExprLit, Lit, LitInt, LitStr,
|
||||
};
|
||||
|
||||
use crate::{DebugPls, Formatter};
|
||||
|
||||
impl DebugPls for Expr {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
Expr::Array(val0) => f.debug_tuple_struct("Array").field(val0).finish(),
|
||||
// Expr::Assign(val0) => f.debug_tuple_struct("Assign").field(val0).finish(),
|
||||
// Expr::AssignOp(val0) => f.debug_tuple_struct("AssignOp").field(val0).finish(),
|
||||
// Expr::Async(val0) => f.debug_tuple_struct("Async").field(val0).finish(),
|
||||
// Expr::Await(val0) => f.debug_tuple_struct("Await").field(val0).finish(),
|
||||
// Expr::Binary(val0) => f.debug_tuple_struct("Binary").field(val0).finish(),
|
||||
// Expr::Block(val0) => f.debug_tuple_struct("Block").field(val0).finish(),
|
||||
// Expr::Box(val0) => f.debug_tuple_struct("Box").field(val0).finish(),
|
||||
// Expr::Break(val0) => f.debug_tuple_struct("Break").field(val0).finish(),
|
||||
// Expr::Call(val0) => f.debug_tuple_struct("Call").field(val0).finish(),
|
||||
// Expr::Cast(val0) => f.debug_tuple_struct("Cast").field(val0).finish(),
|
||||
// Expr::Closure(val0) => f.debug_tuple_struct("Closure").field(val0).finish(),
|
||||
// Expr::Continue(val0) => f.debug_tuple_struct("Continue").field(val0).finish(),
|
||||
// Expr::Field(val0) => f.debug_tuple_struct("Field").field(val0).finish(),
|
||||
// Expr::ForLoop(val0) => f.debug_tuple_struct("ForLoop").field(val0).finish(),
|
||||
// Expr::Group(val0) => f.debug_tuple_struct("Group").field(val0).finish(),
|
||||
// Expr::If(val0) => f.debug_tuple_struct("If").field(val0).finish(),
|
||||
// Expr::Index(val0) => f.debug_tuple_struct("Index").field(val0).finish(),
|
||||
// Expr::Let(val0) => f.debug_tuple_struct("Let").field(val0).finish(),
|
||||
Expr::Lit(val0) => f.debug_tuple_struct("Lit").field(val0).finish(),
|
||||
// Expr::Loop(val0) => f.debug_tuple_struct("Loop").field(val0).finish(),
|
||||
// Expr::Macro(val0) => f.debug_tuple_struct("Macro").field(val0).finish(),
|
||||
// Expr::Match(val0) => f.debug_tuple_struct("Match").field(val0).finish(),
|
||||
// Expr::MethodCall(val0) => f.debug_tuple_struct("MethodCall").field(val0).finish(),
|
||||
// Expr::Paren(val0) => f.debug_tuple_struct("Paren").field(val0).finish(),
|
||||
// Expr::Path(val0) => f.debug_tuple_struct("Path").field(val0).finish(),
|
||||
// Expr::Range(val0) => f.debug_tuple_struct("Range").field(val0).finish(),
|
||||
// Expr::Reference(val0) => f.debug_tuple_struct("Reference").field(val0).finish(),
|
||||
// Expr::Repeat(val0) => f.debug_tuple_struct("Repeat").field(val0).finish(),
|
||||
// Expr::Return(val0) => f.debug_tuple_struct("Return").field(val0).finish(),
|
||||
// Expr::Struct(val0) => f.debug_tuple_struct("Struct").field(val0).finish(),
|
||||
// Expr::Try(val0) => f.debug_tuple_struct("Try").field(val0).finish(),
|
||||
// Expr::TryBlock(val0) => f.debug_tuple_struct("TryBlock").field(val0).finish(),
|
||||
// Expr::Tuple(val0) => f.debug_tuple_struct("Tuple").field(val0).finish(),
|
||||
// Expr::Type(val0) => f.debug_tuple_struct("Type").field(val0).finish(),
|
||||
// Expr::Unary(val0) => f.debug_tuple_struct("Unary").field(val0).finish(),
|
||||
// Expr::Unsafe(val0) => f.debug_tuple_struct("Unsafe").field(val0).finish(),
|
||||
// Expr::Verbatim(val0) => f.debug_tuple_struct("Verbatim").field(val0).finish(),
|
||||
// Expr::While(val0) => f.debug_tuple_struct("While").field(val0).finish(),
|
||||
// Expr::Yield(val0) => f.debug_tuple_struct("Yield").field(val0).finish(),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for ExprArray {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_struct("ExprArray")
|
||||
.field("attrs", &self.attrs)
|
||||
.field("bracket_token", &self.bracket_token)
|
||||
.field("elems", &self.elems)
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for ExprLit {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_struct("ExprLit")
|
||||
.field("attrs", &self.attrs)
|
||||
.field("lit", &self.lit)
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for Lit {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
match self {
|
||||
Lit::Str(v0) => f.debug_tuple_struct("Str").field(v0).finish(),
|
||||
// Lit::ByteStr(v0) => f.debug_tuple_struct("ByteStr").field(v0).finish(),
|
||||
// Lit::Byte(v0) => f.debug_tuple_struct("Byte").field(v0).finish(),
|
||||
// Lit::Char(v0) => f.debug_tuple_struct("Char").field(v0).finish(),
|
||||
Lit::Int(v0) => f.debug_tuple_struct("Int").field(v0).finish(),
|
||||
// Lit::Float(v0) => f.debug_tuple_struct("Float").field(v0).finish(),
|
||||
// Lit::Bool(v0) => f.debug_tuple_struct("Bool").field(v0).finish(),
|
||||
// Lit::Verbatim(v0) => f.debug_tuple_struct("Verbatim").field(v0).finish(),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for LitStr {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_struct("LitStr")
|
||||
.field("value", &self.value())
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for LitInt {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_struct("LitInt")
|
||||
.field("value", &self.base10_digits())
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for Attribute {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_struct("Attribute").finish_non_exhaustive();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DebugPls, P: DebugPls> DebugPls for Punctuated<T, P> {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
self.pairs()
|
||||
.fold(f.debug_list(), |f, pair| match pair {
|
||||
Pair::Punctuated(t, p) => f.entry(t).entry(p),
|
||||
Pair::End(t) => f.entry(t),
|
||||
})
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! debug_units {
|
||||
($($T:ident),*) => {$(
|
||||
impl DebugPls for $T {
|
||||
fn fmt(&self, f: Formatter<'_>) {
|
||||
f.debug_ident(stringify!($T))
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
debug_units![Comma, Bracket];
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::color;
|
||||
|
||||
#[test]
|
||||
fn pretty_colors() {
|
||||
let code = r#"
|
||||
[
|
||||
"Hello, World! I am a long string",
|
||||
420,
|
||||
"Wait, you can't mix and match types in arrays, is this python?",
|
||||
69,
|
||||
"Nice."
|
||||
]
|
||||
"#;
|
||||
let expr: syn::Expr = syn::parse_str(code).unwrap();
|
||||
println!("{}", color(&expr));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +1,15 @@
|
|||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use syn::__private::{Span, TokenStream2};
|
||||
|
||||
mod impls;
|
||||
|
||||
mod debug_list;
|
||||
mod debug_map;
|
||||
mod debug_set;
|
||||
mod debug_struct;
|
||||
mod debug_tuple;
|
||||
mod debug_tuple_struct;
|
||||
pub use debug_list::DebugList;
|
||||
pub use debug_map::DebugMap;
|
||||
pub use debug_set::DebugSet;
|
||||
pub use debug_struct::DebugStruct;
|
||||
pub use debug_tuple::DebugTuple;
|
||||
pub use debug_tuple_struct::DebugTupleStruct;
|
||||
|
||||
pub trait DebugPls {
|
||||
fn fmt(&self, f: Formatter<'_>);
|
||||
}
|
||||
|
||||
pub struct Formatter<'a> {
|
||||
expr: &'a mut syn::Expr,
|
||||
_expr: &'a (),
|
||||
}
|
||||
|
||||
impl<'a> Formatter<'a> {
|
||||
pub(crate) fn process(value: &dyn DebugPls) -> syn::Expr {
|
||||
let mut expr = syn::Expr::Verbatim(TokenStream2::new());
|
||||
value.fmt(Formatter { expr: &mut expr });
|
||||
expr
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_expr(self, expr: impl Into<syn::Expr>) {
|
||||
*self.expr = expr.into();
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_struct(self, name: &str) -> DebugStruct<'a> {
|
||||
DebugStruct::new(self, name)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_tuple(self) -> DebugTuple<'a> {
|
||||
DebugTuple::new(self)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_tuple_struct(self, name: &str) -> DebugTupleStruct<'a> {
|
||||
DebugTupleStruct::new(self, name)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_list(self) -> DebugList<'a> {
|
||||
DebugList::new(self)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_map(self) -> DebugMap<'a> {
|
||||
DebugMap::new(self)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn debug_set(self) -> DebugSet<'a> {
|
||||
DebugSet::new(self)
|
||||
}
|
||||
|
||||
pub fn debug_ident(self, name: &str) {
|
||||
let path: syn::Path = syn::Ident::new(name, Span::call_site()).into();
|
||||
self.write_expr(syn::ExprPath {
|
||||
attrs: vec![],
|
||||
qself: None,
|
||||
path,
|
||||
});
|
||||
impl<'a, D: DebugPls + ?Sized> DebugPls for &'a D {
|
||||
fn fmt(&self, _: Formatter<'_>) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue