113 lines
2.8 KiB
Rust
113 lines
2.8 KiB
Rust
|
|
use darling::{
|
||
|
|
util::{Override, SpannedValue},
|
||
|
|
FromAttributes,
|
||
|
|
};
|
||
|
|
|
||
|
|
use quote::quote;
|
||
|
|
use syn::{parse::Parser, Attribute, Lit};
|
||
|
|
|
||
|
|
use Override::{Explicit, Inherit};
|
||
|
|
|
||
|
|
#[derive(FromAttributes, Default)]
|
||
|
|
#[darling(attributes(test_attr))]
|
||
|
|
struct SpannedValueOverPrimitive {
|
||
|
|
string: SpannedValue<String>,
|
||
|
|
optional_int: Option<SpannedValue<u64>>,
|
||
|
|
override_literal: Override<SpannedValue<Lit>>,
|
||
|
|
optional_override_char: Option<Override<SpannedValue<char>>>,
|
||
|
|
}
|
||
|
|
|
||
|
|
macro_rules! test_cases {
|
||
|
|
($(
|
||
|
|
$name:ident : #[test_attr($($tok:tt)*)] => $result:ident $( {
|
||
|
|
string: $string:expr,
|
||
|
|
int: $int:expr,
|
||
|
|
literal: $literal:pat,
|
||
|
|
char: $char:expr,
|
||
|
|
} )?;
|
||
|
|
)*) => {$(
|
||
|
|
#[test]
|
||
|
|
fn $name() {
|
||
|
|
let quoted = quote! {
|
||
|
|
#[test_attr(
|
||
|
|
$($tok)*
|
||
|
|
)]
|
||
|
|
};
|
||
|
|
|
||
|
|
let attrs = Attribute::parse_outer
|
||
|
|
.parse2(quoted)
|
||
|
|
.expect("failed to parse tokens as an attribute list");
|
||
|
|
|
||
|
|
let result = SpannedValueOverPrimitive::from_attributes(&attrs);
|
||
|
|
|
||
|
|
test_case_result!(result, $result $({
|
||
|
|
string: $string,
|
||
|
|
int: $int,
|
||
|
|
literal: $literal,
|
||
|
|
char: $char,
|
||
|
|
})?);
|
||
|
|
}
|
||
|
|
)*}
|
||
|
|
}
|
||
|
|
|
||
|
|
macro_rules! test_case_result {
|
||
|
|
($value:expr, Err) => {
|
||
|
|
assert!($value.is_err())
|
||
|
|
};
|
||
|
|
|
||
|
|
($value:expr, Ok{
|
||
|
|
string: $string:expr,
|
||
|
|
int: $int:expr,
|
||
|
|
literal: $literal:pat,
|
||
|
|
char: $char:expr,
|
||
|
|
}) => {{
|
||
|
|
let out = $value.expect("failed to parse with from_attributes");
|
||
|
|
|
||
|
|
assert_eq!(out.string.as_ref(), $string);
|
||
|
|
assert_eq!(out.optional_int.map(|i| *i.as_ref()), $int);
|
||
|
|
assert!(matches!(out.override_literal, $literal));
|
||
|
|
assert_eq!(
|
||
|
|
out.optional_override_char.map(|c| match c {
|
||
|
|
Inherit => Inherit,
|
||
|
|
Explicit(value) => Explicit(*value.as_ref()),
|
||
|
|
}),
|
||
|
|
$char
|
||
|
|
)
|
||
|
|
}};
|
||
|
|
}
|
||
|
|
|
||
|
|
test_cases! {
|
||
|
|
basic: #[test_attr(
|
||
|
|
string = "Hello",
|
||
|
|
optional_int = 23,
|
||
|
|
override_literal = "foo",
|
||
|
|
optional_override_char = 'c'
|
||
|
|
)] => Ok{
|
||
|
|
string: "Hello",
|
||
|
|
int: Some(23),
|
||
|
|
literal: Explicit(_),
|
||
|
|
char: Some(Override::Explicit('c')),
|
||
|
|
};
|
||
|
|
|
||
|
|
omit_optionals: #[test_attr(
|
||
|
|
string = "Hello",
|
||
|
|
override_literal = "foo",
|
||
|
|
)] => Ok{
|
||
|
|
string: "Hello",
|
||
|
|
int: None,
|
||
|
|
literal: Explicit(_),
|
||
|
|
char: None,
|
||
|
|
};
|
||
|
|
|
||
|
|
omit_overrides: #[test_attr(
|
||
|
|
string = "Hello",
|
||
|
|
override_literal,
|
||
|
|
optional_override_char,
|
||
|
|
)] => Ok{
|
||
|
|
string: "Hello",
|
||
|
|
int: None,
|
||
|
|
literal: Inherit,
|
||
|
|
char: Some(Inherit),
|
||
|
|
};
|
||
|
|
}
|