use syn::{Attribute, Meta, Result};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum InputStrategy {
Auto,
StatefulTree,
BruteForce,
}
impl InputStrategy {
pub fn parse(input: Vec<Attribute>) -> Result<Self> {
match input.len() {
0 => Ok(InputStrategy::Auto),
1 => {
if let Meta::Path(strategy_ident) = &input[0].meta {
match strategy_ident.get_ident() {
Some(ident) if ident == "Auto" => Ok(InputStrategy::Auto),
Some(ident) if ident == "StatefulTree" => Ok(InputStrategy::StatefulTree),
Some(ident) if ident == "BruteForce" => Ok(InputStrategy::BruteForce),
_ => Err(syn::Error::new_spanned(
strategy_ident,
"Invalid strategy name",
)),
}
} else {
Err(syn::Error::new_spanned(
&input[0],
"Invalid stratety declaration",
))
}
}
_ => Err(syn::Error::new_spanned(
&input[1],
"Only one attribute allowed",
)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use quote::format_ident;
use syn::{Attribute, parse_quote};
fn attr_from_ident(ident: &str) -> Attribute {
let ident = format_ident!("{}", ident);
parse_quote!(#[#ident])
}
#[test]
fn test_parse_empty_vec_returns_auto() {
let attrs: Vec<Attribute> = vec![];
let result = InputStrategy::parse(attrs).unwrap();
assert_eq!(result, InputStrategy::Auto);
}
#[test]
fn test_parse_auto() {
let attrs = vec![attr_from_ident("Auto")];
let result = InputStrategy::parse(attrs).unwrap();
assert_eq!(result, InputStrategy::Auto);
}
#[test]
fn test_parse_stateful_tree() {
let attrs = vec![attr_from_ident("StatefulTree")];
let result = InputStrategy::parse(attrs).unwrap();
assert_eq!(result, InputStrategy::StatefulTree);
}
#[test]
fn test_parse_brute_force() {
let attrs = vec![attr_from_ident("BruteForce")];
let result = InputStrategy::parse(attrs).unwrap();
assert_eq!(result, InputStrategy::BruteForce);
}
#[test]
fn test_parse_invalid_strategy_name() {
let attrs = vec![attr_from_ident("UnknownStrategy")];
let result = InputStrategy::parse(attrs);
assert!(result.is_err());
let err_msg = format!("{}", result.unwrap_err());
assert!(err_msg.contains("Invalid strategy name"));
}
#[test]
fn test_parse_invalid_meta_type() {
let attr: Attribute = parse_quote!(#[strategy = "Auto"]);
let attrs = vec![attr];
let result = InputStrategy::parse(attrs);
assert!(result.is_err());
let err_msg = format!("{}", result.unwrap_err());
assert!(err_msg.contains("Invalid stratety declaration"));
}
#[test]
fn test_parse_multiple_attributes() {
let attrs = vec![attr_from_ident("Auto"), attr_from_ident("StatefulTree")];
let result = InputStrategy::parse(attrs);
assert!(result.is_err());
let err_msg = format!("{}", result.unwrap_err());
assert!(err_msg.contains("Only one attribute allowed"));
}
}