From be6d0213d237fba15b408c7aca190e1ebdce49ca Mon Sep 17 00:00:00 2001 From: glendc Date: Mon, 15 Apr 2024 22:14:18 +0200 Subject: [PATCH] support any in fuzzing + bugfix ref issue --- fuzz/fuzz_targets/fuzz_employee_db.rs | 11 +++++-- src/lib.rs | 33 +++++++++++++++++++ venndb-macros/src/generate_db.rs | 4 +-- .../fails/any_filter_no_trait_impl.stderr | 21 ++++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/fuzz/fuzz_targets/fuzz_employee_db.rs b/fuzz/fuzz_targets/fuzz_employee_db.rs index e4f94a9..1070b1d 100644 --- a/fuzz/fuzz_targets/fuzz_employee_db.rs +++ b/fuzz/fuzz_targets/fuzz_employee_db.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::arbitrary::{self, Arbitrary}; use libfuzzer_sys::fuzz_target; -use venndb::VennDB; +use venndb::{Any, VennDB}; #[derive(Clone, Debug, Arbitrary, VennDB)] pub struct Employee { @@ -13,7 +13,7 @@ pub struct Employee { alive: Option, #[venndb(filter)] faction: Faction, - #[venndb(filter)] + #[venndb(filter, any)] planet: Option, } @@ -25,10 +25,17 @@ pub enum Faction { #[derive(Clone, Debug, Arbitrary, PartialEq, Eq, Hash)] pub enum Planet { + Any, Earth, Mars, } +impl Any for Planet { + fn is_any(&self) -> bool { + self == &Planet::Any + } +} + fuzz_target!(|rows: Vec| { let _ = EmployeeDB::from_rows(rows); }); diff --git a/src/lib.rs b/src/lib.rs index 39591d0..95b2c33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,39 @@ pub trait Any { fn is_any(&self) -> bool; } +impl Any for &T { + fn is_any(&self) -> bool { + T::is_any(*self) + } +} + +impl Any for Option { + fn is_any(&self) -> bool { + match self { + Some(value) => value.is_any(), + None => false, + } + } +} + +impl Any for std::sync::Arc { + fn is_any(&self) -> bool { + T::is_any(&**self) + } +} + +impl Any for std::rc::Rc { + fn is_any(&self) -> bool { + T::is_any(&**self) + } +} + +impl Any for Box { + fn is_any(&self) -> bool { + T::is_any(&**self) + } +} + #[doc(hidden)] pub mod __internal { //! Hidden thirdparty dependencies for venndb, diff --git a/venndb-macros/src/generate_db.rs b/venndb-macros/src/generate_db.rs index 084d603..0aef4fe 100644 --- a/venndb-macros/src/generate_db.rs +++ b/venndb-macros/src/generate_db.rs @@ -418,7 +418,7 @@ fn generate_db_struct_method_append( }; let is_any_value = if field.optional { quote! { - data.#name.map(|v| ::venndb::Any::is_any(&v)).unwrap_or_default() + data.#name.as_ref().map(|v| ::venndb::Any::is_any(v)).unwrap_or_default() } } else { quote! { @@ -761,7 +761,7 @@ fn generate_query_struct_impl( let value_filter = match field.filter_any_name() { Some(name) => { quote! { - if ::venndb::Any::is_any(value) { + if ::venndb::Any::is_any(&value) { filter &= &self.db.#name; } else { #value_filter diff --git a/venndb-usage/tests/fails/any_filter_no_trait_impl.stderr b/venndb-usage/tests/fails/any_filter_no_trait_impl.stderr index ac6b6fc..b689940 100644 --- a/venndb-usage/tests/fails/any_filter_no_trait_impl.stderr +++ b/venndb-usage/tests/fails/any_filter_no_trait_impl.stderr @@ -4,4 +4,25 @@ error[E0277]: the trait bound `Department: venndb::Any` is not satisfied 3 | #[derive(Debug, VennDB)] | ^^^^^^ the trait `venndb::Any` is not implemented for `Department` | + = help: the following other types implement trait `venndb::Any`: + Box + Rc + Arc + Option + &T + = note: this error originates in the derive macro `VennDB` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `Department: venndb::Any` is not satisfied + --> tests/fails/any_filter_no_trait_impl.rs:3:17 + | +3 | #[derive(Debug, VennDB)] + | ^^^^^^ the trait `venndb::Any` is not implemented for `Department`, which is required by `&Department: venndb::Any` + | + = help: the following other types implement trait `venndb::Any`: + Box + Rc + Arc + Option + &T + = note: required for `&Department` to implement `venndb::Any` = note: this error originates in the derive macro `VennDB` (in Nightly builds, run with -Z macro-backtrace for more info)