From 27b28644eae5861005bba60895cb4a13dca49a89 Mon Sep 17 00:00:00 2001 From: Vance Longwill <4891589+VanceLongwill@users.noreply.github.com> Date: Wed, 13 Mar 2024 23:28:03 +0300 Subject: [PATCH] Add basic #[expunge(default)] shorthand (#10) --- expunge/tests/expunge.rs | 112 ++++++++++++++++++++++++++++++++++++++ expunge_derive/src/lib.rs | 4 ++ 2 files changed, 116 insertions(+) diff --git a/expunge/tests/expunge.rs b/expunge/tests/expunge.rs index ba54919..56045e9 100644 --- a/expunge/tests/expunge.rs +++ b/expunge/tests/expunge.rs @@ -417,6 +417,95 @@ fn it_works_enum() { assert_eq!(SensitiveItem::ZeroizableString("99".to_string()), expunged); } +#[test] +fn it_works_enum_all() { + #[derive(PartialEq, Debug, Clone, Expunge)] + enum SensitiveNested { + Name(#[expunge] String, i32), + } + + #[derive(Clone, Debug, PartialEq)] + struct UnitStruct; + + impl Expunge for UnitStruct { + fn expunge(self) -> Self + where + Self: Sized, + { + self + } + } + + #[derive(PartialEq, Debug, Clone, Expunge)] + #[expunge(all)] + enum SensitiveItem { + Name(String, i32), + DateOfBirth(String), + BankDetails { + account_number: i32, + }, + Location(Location), + Nested(SensitiveNested, i32), + LocationHistory(Vec), + WithUnit(i32, UnitStruct), + #[expunge(as = i32::MAX, zeroize)] + Zeroizable(i32), + #[expunge(as = "99".to_string(), zeroize)] + ZeroizableString(String), + } + + #[derive(PartialEq, Debug, Clone, Expunge, Default)] + struct Location { + #[expunge] + city: String, + } + + let item = SensitiveItem::Name("Bob".to_string(), 1); + + let expunged = item.expunge(); + + assert_eq!(SensitiveItem::Name("".to_string(), 0), expunged); + + let item = SensitiveItem::BankDetails { + account_number: 123, + }; + let expunged = item.expunge(); + assert_eq!(SensitiveItem::BankDetails { account_number: 0 }, expunged); + + let new_york = Location { + city: "New York".to_string(), + }; + let item = SensitiveItem::Location(new_york.clone()); + + let expunged = item.expunge(); + assert_eq!(SensitiveItem::Location(Location::default()), expunged); + + let item = SensitiveItem::Nested(SensitiveNested::Name("Alice".to_string(), 1), 99); + let expunged = item.expunge(); + assert_eq!( + SensitiveItem::Nested(SensitiveNested::Name("".to_string(), 1), 0), + expunged + ); + + let boston = Location { + city: "Boston".to_string(), + }; + let item = SensitiveItem::LocationHistory(vec![new_york, boston]); + let expunged = item.expunge(); + assert_eq!( + SensitiveItem::LocationHistory(vec![Location::default(), Location::default()],), + expunged + ); + + let item = SensitiveItem::Zeroizable(12309812); + let expunged = item.expunge(); + assert_eq!(SensitiveItem::Zeroizable(2147483647), expunged); + + let item = SensitiveItem::ZeroizableString("my_password".to_string()); + let expunged = item.expunge(); + assert_eq!(SensitiveItem::ZeroizableString("99".to_string()), expunged); +} + #[test] fn it_returns_boxed() { #[derive(Expunge)] @@ -431,3 +520,26 @@ fn it_returns_boxed() { let _: Box = location.expunge(); } + +#[test] +fn it_expunges_default() { + #[derive(Default)] + struct SomeData { + pub name: String, + } + + #[derive(Expunge)] + struct Person { + #[expunge(default)] + data: SomeData, + } + + let p = Person { + data: SomeData { + name: "John Smith".to_string(), + }, + }; + + + assert_eq!(String::default(), p.expunge().data.name); +} diff --git a/expunge_derive/src/lib.rs b/expunge_derive/src/lib.rs index 64d6109..1b8a404 100644 --- a/expunge_derive/src/lib.rs +++ b/expunge_derive/src/lib.rs @@ -167,6 +167,7 @@ const ALL: &str = "all"; const IGNORE: &str = "ignore"; const ZEROIZE: &str = "zeroize"; const SLOG: &str = "slog"; +const DEFAULT: &str = "default"; fn parse_attributes( span: Span, @@ -273,6 +274,9 @@ fn parse_attributes( format!("the `{SLOG}` feature must be enabled"), )) } + } else if meta.path.is_ident(DEFAULT) { + builder.expunge_as = Some(quote!{ Default::default() }); + Ok(()) } else { Err(syn::Error::new( meta.path.span(),