tusks_lib/parsing/attribute/
parse.rs1use syn::{Ident, LitBool, LitInt, LitStr, Token, parenthesized, parse::{Parse, ParseStream}};
2
3use crate::parsing::attribute::models::{TasksConfig, TusksAttr};
4
5impl Parse for TusksAttr {
6 fn parse(input: ParseStream) -> syn::Result<Self> {
24 let mut attr = TusksAttr::default();
25
26 while !input.is_empty() {
27 let ident: Ident = input.parse()?;
28
29 match ident.to_string().as_str() {
30 "debug" => attr.debug = parse_bool_flag(input)?,
31 "root" => attr.root = parse_bool_flag(input)?,
32 "derive_debug_for_parameters" => {
33 attr.derive_debug_for_parameters = parse_bool_flag(input)?
34 }
35 "tasks" => attr.tasks = Some(parse_nested_config(input)?),
36 other => return Err(unknown_attribute_error(&ident, other)),
37 }
38
39 parse_trailing_comma(input)?;
40 }
41
42 Ok(attr)
43 }
44}
45
46impl Parse for TasksConfig {
47 fn parse(input: ParseStream) -> syn::Result<Self> {
66 let mut config = TasksConfig::default();
67
68 while !input.is_empty() {
69 let ident: Ident = input.parse()?;
70 input.parse::<Token![=]>()?;
71
72 match ident.to_string().as_str() {
73 "max_groupsize" => config.max_groupsize = parse_usize(input)?,
74 "max_depth" => config.max_depth = parse_usize(input)?,
75 "separator" => config.separator = parse_string(input)?,
76 other => return Err(unknown_parameter_error(&ident, other)),
77 }
78
79 parse_trailing_comma(input)?;
80 }
81
82 Ok(config)
83 }
84}
85
86fn parse_bool_flag(input: ParseStream) -> syn::Result<bool> {
90 if input.peek(Token![=]) {
91 input.parse::<Token![=]>()?;
92 let value: LitBool = input.parse()?;
93 Ok(value.value)
94 } else {
95 Ok(true)
96 }
97}
98
99fn parse_nested_config<T: Parse>(input: ParseStream) -> syn::Result<T> {
101 let content;
102 parenthesized!(content in input);
103 content.parse::<T>()
104}
105
106fn parse_trailing_comma(input: ParseStream) -> syn::Result<()> {
108 if !input.is_empty() {
109 input.parse::<Token![,]>()?;
110 }
111 Ok(())
112}
113
114fn parse_usize(input: ParseStream) -> syn::Result<usize> {
116 let value: LitInt = input.parse()?;
117 value.base10_parse()
118}
119
120fn parse_string(input: ParseStream) -> syn::Result<String> {
122 let value: LitStr = input.parse()?;
123 Ok(value.value())
124}
125
126fn unknown_attribute_error(ident: &Ident, name: &str) -> syn::Error {
128 syn::Error::new(
129 ident.span(),
130 format!("unknown tusks attribute: {}", name)
131 )
132}
133
134fn unknown_parameter_error(ident: &Ident, name: &str) -> syn::Error {
136 syn::Error::new(
137 ident.span(),
138 format!("unknown tasks parameter: {}", name)
139 )
140}