Skip to content

Commit

Permalink
refactor: omit spans from debug prints
Browse files Browse the repository at this point in the history
Spans are rarely useful in the `Debug` representation of a struct and
clutter the snapshots a lot. A custom derive macro mimics the stdlib's
macro but filters out any fields that use the `Span` struct.
  • Loading branch information
dnaka91 committed Dec 25, 2023
1 parent 9200cf3 commit 5b79acb
Show file tree
Hide file tree
Showing 29 changed files with 142 additions and 2,872 deletions.
130 changes: 130 additions & 0 deletions crates/stef-derive/src/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use proc_macro2::{Literal, Span, TokenStream};
use quote::quote;
use syn::{spanned::Spanned, Data, DeriveInput, Field, Fields, Ident, Type, TypePath};

macro_rules! bail {
($tokens:expr, $($arg:tt)*) => {
return Err(syn::Error::new($tokens.span(), format!($($arg)*)))
};
}

pub fn expand(derive: DeriveInput) -> syn::Result<TokenStream> {
let ident = &derive.ident;
let generics = &derive.generics;
let name = Literal::string(&ident.to_string());

match derive.data {
Data::Struct(data) => {
let fields= expand_fields(name, &data.fields);

Ok(quote! {
impl #generics ::core::fmt::Debug for #ident #generics {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Self #fields
}
}
}
})
}
Data::Enum(data) => {
let variants = data.variants.iter().map(|variant| {
let ident = &variant.ident;
let fields = expand_fields(Literal::string(&ident.to_string()), &variant.fields);

quote! {
Self::#ident #fields
}
});

Ok(quote! {
impl #generics ::core::fmt::Debug for #ident #generics {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
#(#variants,)*
}
}
}
})
}
Data::Union(_) => bail!(derive, "unions not supported"),
}
}

fn expand_fields(name: Literal, fields: &Fields) -> TokenStream {
match fields {
Fields::Named(fields) => {
let names = fields.named.iter().map(|field| {
let ident = field.ident.as_ref().unwrap();
if filter_span(&field.ty) {
quote! { #ident: _ }
} else {
quote! { #ident }
}
});

let fields = fields
.named
.iter()
.filter(|&field| !filter_span(&field.ty))
.map(expand_named_field);

quote! {
{#(#names,)*} => f.debug_struct(#name)
#(#fields)*
.finish()
}
}
Fields::Unnamed(fields) => {
let names = fields.unnamed.iter().enumerate().map(|(i, field)| {
if filter_span(&field.ty) {
quote! { _ }
} else {
let ident = Ident::new(&format!("n{i}"), Span::call_site());
quote! { #ident }
}
});

let fields = fields
.unnamed
.iter()
.enumerate()
.filter(|(_, field)| !filter_span(&field.ty))
.map(expand_unnamed_field);

quote! {
(#(#names,)*) => f.debug_tuple(#name)
#(#fields)*
.finish()
}
}
Fields::Unit => quote! { => f.write_str(#name) },
}
}

fn expand_named_field(field: &Field) -> TokenStream {
let ident = field.ident.as_ref().unwrap();
let name = Literal::string(&ident.to_string());

quote! {
.field(#name, &#ident)
}
}

fn expand_unnamed_field((i, _field): (usize, &Field)) -> TokenStream {
let ident = Ident::new(&format!("n{i}"), Span::call_site());

quote! {
.field(&#ident)
}
}

fn filter_span(ty: &Type) -> bool {
let Type::Path(TypePath { path, .. }) = ty else {
return false;
};

path.segments
.last()
.map_or(false, |segment| segment.ident == "Span")
}
11 changes: 11 additions & 0 deletions crates/stef-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use syn::{parse_macro_input, DeriveInput};
mod attributes;
mod cause;
mod error;
mod debug;

#[proc_macro_derive(ParserError, attributes(err, rename))]
pub fn parser_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand All @@ -30,3 +31,13 @@ pub fn parser_error_cause(input: proc_macro::TokenStream) -> proc_macro::TokenSt
Err(e) => e.into_compile_error().into(),
}
}

#[proc_macro_derive(Debug)]
pub fn debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);

match debug::expand(input) {
Ok(expanded) => expanded.into(),
Err(e) => e.into_compile_error().into(),
}
}
1 change: 1 addition & 0 deletions crates/stef-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::{

pub use miette::{Diagnostic, LabeledSpan};
use miette::{IntoDiagnostic, NamedSource, Result};
use stef_derive::Debug;
use winnow::Parser;

use self::error::ParseSchemaError;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,17 @@ Schema {
[
CommentLine {
value: "Sample type alias.",
span: Span {
start: 0,
end: 22,
},
},
],
),
name: Name {
value: "Sample",
span: Span {
start: 28,
end: 34,
},
},
generics: Generics(
[],
),
target: Type {
value: U32,
span: Span {
start: 37,
end: 40,
},
},
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ Schema {
value: Int(
1,
),
span: Span {
start: 17,
end: 18,
},
},
),
},
Expand All @@ -44,10 +40,6 @@ Schema {
value: Int(
100,
),
span: Span {
start: 26,
end: 29,
},
},
),
},
Expand All @@ -58,10 +50,6 @@ Schema {
),
name: Name {
value: "Sample",
span: Span {
start: 39,
end: 45,
},
},
generics: Generics(
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,13 @@ Schema {
value: String(
"don't use",
),
span: Span {
start: 15,
end: 26,
},
},
),
},
],
),
name: Name {
value: "Sample",
span: Span {
start: 35,
end: 41,
},
},
generics: Generics(
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ Schema {
),
name: Name {
value: "Sample",
span: Span {
start: 21,
end: 27,
},
},
generics: Generics(
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ Schema {
value: String(
"don't use",
),
span: Span {
start: 15,
end: 26,
},
},
),
},
Expand All @@ -52,10 +48,6 @@ Schema {
value: Int(
100,
),
span: Span {
start: 69,
end: 72,
},
},
),
},
Expand All @@ -66,10 +58,6 @@ Schema {
value: Int(
200,
),
span: Span {
start: 80,
end: 83,
},
},
),
},
Expand All @@ -87,10 +75,6 @@ Schema {
),
name: Name {
value: "Sample",
span: Span {
start: 111,
end: 117,
},
},
generics: Generics(
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ Schema {
value: String(
"don't use",
),
span: Span {
start: 13,
end: 24,
},
},
),
},
Expand All @@ -52,10 +48,6 @@ Schema {
value: Int(
100,
),
span: Span {
start: 59,
end: 62,
},
},
),
},
Expand All @@ -66,10 +58,6 @@ Schema {
value: Int(
200,
),
span: Span {
start: 67,
end: 70,
},
},
),
},
Expand All @@ -87,10 +75,6 @@ Schema {
),
name: Name {
value: "Sample",
span: Span {
start: 91,
end: 97,
},
},
generics: Generics(
[],
Expand Down
Loading

0 comments on commit 5b79acb

Please sign in to comment.