Skip to content

Commit fdacd37

Browse files
committed
Implemented custom placeholder.
Replaced type info with default placeholder.
1 parent 2c03d7b commit fdacd37

File tree

3 files changed

+127
-35
lines changed

3 files changed

+127
-35
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ repository = "https://github.com/dimpolo/partialdebug/"
88
license = "MIT OR Apache-2.0"
99

1010
[dependencies]
11-
partialdebug-derive = "0.0.1"
11+
partialdebug-derive = {path = "partialdebug-derive"} # TODO change back

partialdebug-derive/src/lib.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use proc_macro::TokenStream;
22

33
use quote::{quote, ToTokens};
4+
use syn::parse::{Parse, ParseStream};
45
use syn::*;
56

67
#[proc_macro_derive(NonExhaustivePartialDebug)]
@@ -49,13 +50,20 @@ pub fn derive_non_exhaustive(input: TokenStream) -> TokenStream {
4950
TokenStream::from(expanded)
5051
}
5152

52-
#[proc_macro_derive(TypeInfoPartialDebug)]
53-
pub fn derive_type_info(input: TokenStream) -> TokenStream {
53+
#[proc_macro_derive(PlaceholderPartialDebug, attributes(placeholder))]
54+
pub fn derive_placeholder(input: TokenStream) -> TokenStream {
5455
let input = parse_macro_input!(input as ItemStruct);
55-
let name = input.ident;
56+
let placeholder = match get_placeholder(&input) {
57+
Ok(placeholder) => placeholder,
58+
Err(err) => {
59+
return err.to_compile_error().into();
60+
}
61+
};
62+
63+
let name = &input.ident;
5664
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
5765

58-
let fields = match input.fields {
66+
let fields = match &input.fields {
5967
Fields::Named(FieldsNamed { named, .. }) => named,
6068
Fields::Unnamed(_) => unimplemented!(),
6169
Fields::Unit => unimplemented!(),
@@ -66,11 +74,14 @@ pub fn derive_type_info(input: TokenStream) -> TokenStream {
6674
let mut type_name = field.ty.to_token_stream().to_string();
6775
type_name.retain(|c| !c.is_whitespace()); // remove whitespace
6876

77+
// type name or given placeholder string
78+
let placeholder_string = placeholder.as_ref().unwrap_or(&type_name);
79+
6980
quote! {
7081
.field(
7182
stringify!(#name),
7283
match ::partialdebug::AsDebug::as_debug(&self.#name){
73-
None => &::partialdebug::Placeholder(#type_name),
84+
None => &::partialdebug::Placeholder(#placeholder_string),
7485
Some(field) => field,
7586
},
7687
)
@@ -91,3 +102,35 @@ pub fn derive_type_info(input: TokenStream) -> TokenStream {
91102

92103
TokenStream::from(expanded)
93104
}
105+
106+
struct Placeholder(String);
107+
108+
impl Parse for Placeholder {
109+
fn parse(input: ParseStream) -> Result<Self> {
110+
input.parse::<Token![=]>()?;
111+
Ok(Placeholder(input.parse::<LitStr>()?.value()))
112+
}
113+
}
114+
115+
/// Tries to parse a placeholder string if there is one
116+
fn get_placeholder(input: &ItemStruct) -> Result<Option<String>> {
117+
let placeholders: Vec<_> = input
118+
.attrs
119+
.iter()
120+
.filter(|attribute| attribute.path.is_ident("placeholder"))
121+
.collect();
122+
123+
if placeholders.len() > 1 {
124+
return Err(Error::new_spanned(
125+
placeholders[1],
126+
"More than one placeholder attribute",
127+
));
128+
}
129+
130+
placeholders
131+
.first()
132+
.map(|attribute| {
133+
parse2::<Placeholder>(attribute.tokens.clone()).map(|placeholder| placeholder.0)
134+
})
135+
.transpose()
136+
}

src/lib.rs

Lines changed: 78 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,106 @@
1+
//! ```
2+
//! # #[allow(dead_code)]
3+
//! struct DNA {
4+
//! sequence: &'static str,
5+
//! }
6+
//! ```
7+
//!
18
//! # Non Exhaustive
29
//!
310
//! ```
411
//! #![feature(debug_non_exhaustive)]
5-
//!
612
//! use partialdebug::non_exhaustive::PartialDebug;
713
//!
8-
//! #[allow(dead_code)]
9-
//! struct DNA {
10-
//! sequence: &'static str,
11-
//! }
12-
//!
14+
//! # #[allow(dead_code)]
15+
//! # struct DNA {
16+
//! # sequence: &'static str,
17+
//! # }
18+
//! #
1319
//! #[derive(PartialDebug)]
1420
//! struct Dog {
1521
//! legs: usize,
1622
//! eyes: usize,
1723
//! dna: DNA,
1824
//! }
1925
//!
20-
//! let dog = Dog {
21-
//! legs: 4,
22-
//! eyes: 2,
23-
//! dna: DNA {
24-
//! sequence: "GACCCCGATTTGA",
25-
//! },
26-
//! };
27-
//! assert_eq!(format!("{:?}", dog), "Dog { legs: 4, eyes: 2, .. }");
26+
//! # impl Dog {
27+
//! # fn new() -> Dog {
28+
//! # Dog {
29+
//! # legs: 4,
30+
//! # eyes: 2,
31+
//! # dna: DNA {
32+
//! # sequence: "",
33+
//! # },
34+
//! # }
35+
//! # }
36+
//! # }
37+
//! #
38+
//! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, .. }");
2839
//! ```
2940
//!
30-
//! # Type Info
41+
//! # Placeholder with Type Info
3142
//!
3243
//! ```
33-
//! use partialdebug::type_info::PartialDebug;
44+
//! use partialdebug::placeholder::PartialDebug;
3445
//!
35-
//! #[allow(dead_code)]
36-
//! struct DNA {
37-
//! sequence: &'static str,
46+
//! # #[allow(dead_code)]
47+
//! # struct DNA {
48+
//! # sequence: &'static str,
49+
//! # }
50+
//! #
51+
//! #[derive(PartialDebug)]
52+
//! struct Dog {
53+
//! legs: usize,
54+
//! eyes: usize,
55+
//! dna: DNA,
3856
//! }
3957
//!
58+
//! # impl Dog {
59+
//! # fn new() -> Dog {
60+
//! # Dog {
61+
//! # legs: 4,
62+
//! # eyes: 2,
63+
//! # dna: DNA {
64+
//! # sequence: "",
65+
//! # },
66+
//! # }
67+
//! # }
68+
//! # }
69+
//! #
70+
//! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: DNA }");
71+
//! ```
72+
//!
73+
//! # Placeholder with Custom Text
74+
//!
75+
//! ```
76+
//! use partialdebug::placeholder::PartialDebug;
77+
//!
78+
//! # #[allow(dead_code)]
79+
//! # struct DNA {
80+
//! # sequence: &'static str,
81+
//! # }
82+
//! #
4083
//! #[derive(PartialDebug)]
84+
//! #[placeholder = "Unknown"]
4185
//! struct Dog {
4286
//! legs: usize,
4387
//! eyes: usize,
4488
//! dna: DNA,
4589
//! }
4690
//!
47-
//! let dog = Dog {
48-
//! legs: 4,
49-
//! eyes: 2,
50-
//! dna: DNA {
51-
//! sequence: "GACCCCGATTTGA",
52-
//! },
53-
//! };
54-
//! assert_eq!(format!("{:?}", dog), "Dog { legs: 4, eyes: 2, dna: DNA }");
91+
//! # impl Dog {
92+
//! # fn new() -> Dog {
93+
//! # Dog {
94+
//! # legs: 4,
95+
//! # eyes: 2,
96+
//! # dna: DNA {
97+
//! # sequence: "",
98+
//! # },
99+
//! # }
100+
//! # }
101+
//! # }
102+
//! #
103+
//! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: Unknown }");
55104
//! ```
56105
57106
#![allow(incomplete_features)]
@@ -87,6 +136,6 @@ pub mod non_exhaustive {
87136
pub use partialdebug_derive::NonExhaustivePartialDebug as PartialDebug;
88137
}
89138

90-
pub mod type_info {
91-
pub use partialdebug_derive::TypeInfoPartialDebug as PartialDebug;
139+
pub mod placeholder {
140+
pub use partialdebug_derive::PlaceholderPartialDebug as PartialDebug;
92141
}

0 commit comments

Comments
 (0)