Skip to content

Commit d37e21e

Browse files
fix: strip options from range error type (#71)
1 parent 9f7dae7 commit d37e21e

4 files changed

Lines changed: 28 additions & 2 deletions

File tree

deny.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ all-features = true
44
[advisories]
55
ignore = [
66
{ id = "RUSTSEC-2024-0436", reason = "No maintained version available for `paste`." },
7+
{ id = "RUSTSEC-2025-0141", reason = "No maintained version available for `bincode`." },
78
]
89

910
[bans]

packages/fortifier-macros-tests/tests/validations/range/options_pass.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ struct RangeData {
1818
exclusive_min_max: usize,
1919
#[validate(range(min = 1, exclusive_max = 7))]
2020
min_exclusive_max: usize,
21+
22+
#[validate(range(min = 1))]
23+
one_option: Option<usize>,
24+
#[validate(range(min = 1))]
25+
two_options: Option<Option<usize>>,
2126
}
2227

2328
fn main() {
@@ -30,6 +35,9 @@ fn main() {
3035
exclusive_min_exclusive_max: 1,
3136
exclusive_min_max: 2,
3237
min_exclusive_max: 2,
38+
39+
one_option: Some(1),
40+
two_options: Some(Some(1)),
3341
};
3442

3543
assert_eq!(

packages/fortifier-macros/src/util.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ pub fn path_to_string(path: &Path) -> String {
2222

2323
pub fn is_option_path(path: &Path) -> bool {
2424
let path_string = path_to_string(path);
25-
path_string == "Option" || path_string == "std::option::Option"
25+
path_string == "Option"
26+
|| path_string == "option::Option"
27+
|| path_string == "std::option::Option"
2628
}
2729

2830
pub fn count_options(r#type: &Type) -> usize {
@@ -38,3 +40,17 @@ pub fn count_options(r#type: &Type) -> usize {
3840
0
3941
}
4042
}
43+
44+
pub fn strip_options(r#type: &Type) -> &Type {
45+
if let Type::Path(r#type) = r#type
46+
&& let Some(segment) = r#type.path.segments.last()
47+
&& let PathArguments::AngleBracketed(arguments) = &segment.arguments
48+
&& arguments.args.len() == 1
49+
&& is_option_path(&r#type.path)
50+
&& let Some(GenericArgument::Type(argument_type)) = arguments.args.first()
51+
{
52+
strip_options(argument_type)
53+
} else {
54+
r#type
55+
}
56+
}

packages/fortifier-macros/src/validations/range.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use syn::{Expr, Ident, Result, Type, meta::ParseNestedMeta};
44

55
use crate::{
66
generics::Generic,
7+
util::strip_options,
78
validation::{Execution, Validation},
89
};
910

@@ -66,7 +67,7 @@ impl Validation for Range {
6667
}
6768

6869
fn error_type(&self) -> TokenStream {
69-
let r#type = &self.r#type;
70+
let r#type = strip_options(&self.r#type);
7071

7172
quote!(::fortifier::RangeError<#r#type>)
7273
}

0 commit comments

Comments
 (0)