bevy_yoetz_macros/suggestion/
field.rs

1use syn::Error;
2
3use crate::util::{ApplyMeta, AttrArg};
4
5#[derive(PartialEq, Eq, Clone, Copy)]
6pub enum FieldRole {
7    Key,
8    Input,
9    State,
10}
11
12#[derive(Default)]
13pub struct FieldConfig {
14    pub role: Option<FieldRole>,
15}
16
17impl ApplyMeta for FieldConfig {
18    fn apply_meta(&mut self, expr: AttrArg) -> Result<(), Error> {
19        match expr.name().to_string().as_str() {
20            role @ ("key" | "input" | "state") => match expr {
21                AttrArg::Flag(_) => {
22                    if self.role.is_some() {
23                        return Err(Error::new_spanned(&expr, "field role given more than once"));
24                    }
25                    self.role = Some(match role {
26                        "key" => FieldRole::Key,
27                        "input" => FieldRole::Input,
28                        "state" => FieldRole::State,
29                        _ => panic!("Already filtered for one of these three"),
30                    });
31                    Ok(())
32                }
33                _ => Err(expr.incorrect_type()),
34            },
35            _ => Err(expr.unknown_name()),
36        }
37    }
38}
39
40impl FieldConfig {
41    pub fn new_for(field: &mut syn::Field) -> Result<Self, Error> {
42        let mut result = Self::default();
43        for attr in field.attrs.drain(..) {
44            if attr.path().is_ident("yoetz") {
45                result.apply_attr(&attr)?;
46            }
47        }
48
49        if result.role.is_none() {
50            return Err(Error::new_spanned(&field, "YoetzSuggestion variant fields must be `#[yoets(<role>)]`, where <role> is key, input or state"));
51        }
52
53        Ok(result)
54    }
55}