diff --git a/deny.toml b/deny.toml index 5b4584e..7716577 100644 --- a/deny.toml +++ b/deny.toml @@ -4,6 +4,7 @@ all-features = true [advisories] ignore = [ { id = "RUSTSEC-2024-0436", reason = "No maintained version available for `paste`." }, + { id = "RUSTSEC-2025-0141", reason = "No maintained version available for `bincode`." }, ] [bans] diff --git a/packages/fortifier-macros-tests/tests/validations/range/options_pass.rs b/packages/fortifier-macros-tests/tests/validations/range/options_pass.rs index 8515df8..ae3167c 100644 --- a/packages/fortifier-macros-tests/tests/validations/range/options_pass.rs +++ b/packages/fortifier-macros-tests/tests/validations/range/options_pass.rs @@ -18,6 +18,11 @@ struct RangeData { exclusive_min_max: usize, #[validate(range(min = 1, exclusive_max = 7))] min_exclusive_max: usize, + + #[validate(range(min = 1))] + one_option: Option, + #[validate(range(min = 1))] + two_options: Option>, } fn main() { @@ -30,6 +35,9 @@ fn main() { exclusive_min_exclusive_max: 1, exclusive_min_max: 2, min_exclusive_max: 2, + + one_option: Some(1), + two_options: Some(Some(1)), }; assert_eq!( diff --git a/packages/fortifier-macros/src/util.rs b/packages/fortifier-macros/src/util.rs index 0416526..ef71f23 100644 --- a/packages/fortifier-macros/src/util.rs +++ b/packages/fortifier-macros/src/util.rs @@ -22,7 +22,9 @@ pub fn path_to_string(path: &Path) -> String { pub fn is_option_path(path: &Path) -> bool { let path_string = path_to_string(path); - path_string == "Option" || path_string == "std::option::Option" + path_string == "Option" + || path_string == "option::Option" + || path_string == "std::option::Option" } pub fn count_options(r#type: &Type) -> usize { @@ -38,3 +40,17 @@ pub fn count_options(r#type: &Type) -> usize { 0 } } + +pub fn strip_options(r#type: &Type) -> &Type { + if let Type::Path(r#type) = r#type + && let Some(segment) = r#type.path.segments.last() + && let PathArguments::AngleBracketed(arguments) = &segment.arguments + && arguments.args.len() == 1 + && is_option_path(&r#type.path) + && let Some(GenericArgument::Type(argument_type)) = arguments.args.first() + { + strip_options(argument_type) + } else { + r#type + } +} diff --git a/packages/fortifier-macros/src/validations/range.rs b/packages/fortifier-macros/src/validations/range.rs index d3d7ef7..7dd3eee 100644 --- a/packages/fortifier-macros/src/validations/range.rs +++ b/packages/fortifier-macros/src/validations/range.rs @@ -4,6 +4,7 @@ use syn::{Expr, Ident, Result, Type, meta::ParseNestedMeta}; use crate::{ generics::Generic, + util::strip_options, validation::{Execution, Validation}, }; @@ -66,7 +67,7 @@ impl Validation for Range { } fn error_type(&self) -> TokenStream { - let r#type = &self.r#type; + let r#type = strip_options(&self.r#type); quote!(::fortifier::RangeError<#r#type>) }