test_case_core/
modifier.rs
1use std::collections::HashSet;
2use std::fmt::{Debug, Formatter};
3use syn::parse::{Parse, ParseStream};
4use syn::token::Bracket;
5use syn::{bracketed, parse_quote, Attribute, LitStr};
6
7mod kw {
8 syn::custom_keyword!(inconclusive);
9 syn::custom_keyword!(ignore);
10}
11
12#[derive(Clone, PartialEq, Eq, Hash)]
13pub enum Modifier {
14 Inconclusive,
15 InconclusiveWithReason(LitStr),
16}
17
18impl Debug for Modifier {
19 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20 match self {
21 Modifier::Inconclusive | Modifier::InconclusiveWithReason(_) => {
22 write!(f, "inconclusive")
23 }
24 }
25 }
26}
27
28impl Parse for Modifier {
29 fn parse(input: ParseStream) -> syn::Result<Self> {
30 if input.peek(kw::inconclusive) {
31 let _: kw::inconclusive = input.parse()?;
32 Self::parse_inconclusive(input)
33 } else if input.peek(kw::ignore) {
34 let _: kw::ignore = input.parse()?;
35 Self::parse_inconclusive(input)
36 } else {
37 Err(syn::Error::new(input.span(), "unknown modifier keyword"))
38 }
39 }
40}
41
42impl Modifier {
43 pub fn parse_inconclusive(input: ParseStream) -> syn::Result<Self> {
44 if input.peek(Bracket) {
45 let content;
46 let _: Bracket = bracketed!(content in input);
47 let reason: LitStr = content.parse()?;
48 Ok(Self::InconclusiveWithReason(reason))
49 } else {
50 Ok(Self::Inconclusive)
51 }
52 }
53
54 pub fn attribute(&self) -> Attribute {
55 match self {
56 Modifier::Inconclusive => parse_quote! { #[ignore] },
57 Modifier::InconclusiveWithReason(r) => parse_quote! { #[ignore = #r] },
58 }
59 }
60}
61
62pub fn parse_kws(input: ParseStream) -> HashSet<Modifier> {
63 let mut kws = HashSet::new();
64 while let Ok(kw) = Modifier::parse(input) {
65 kws.insert(kw);
66 }
67 kws
68}