fieldwork/
method.rs

1use proc_macro2::Span;
2use syn::{Error, Path, spanned::Spanned};
3
4#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
5#[repr(u8)]
6pub(crate) enum Method {
7    Get,
8    Set,
9    With,
10    GetMut,
11    Without,
12    Take,
13}
14
15macro_rules! with_methods {
16    ($macro:ident!($($inner:literal,)*)) => {
17        $macro!($($inner,)* "get", "set", "with", "get_mut", "without", "take", )
18    };
19}
20pub(crate) use with_methods;
21
22impl Method {
23    pub(crate) const fn all() -> &'static [Method] {
24        &[
25            Self::Get,
26            Self::GetMut,
27            Self::Set,
28            Self::With,
29            Self::Without,
30            Self::Take,
31        ]
32    }
33
34    pub(crate) fn from_str_with_span(s: &str, span: Span) -> syn::Result<Self> {
35        match s {
36            "get" => Ok(Self::Get),
37            "set" => Ok(Self::Set),
38            "with" => Ok(Self::With),
39            "get_mut" => Ok(Self::GetMut),
40            "without" => Ok(Self::Without),
41            "take" => Ok(Self::Take),
42            _ => Err(Error::new(span, "unrecognized method")),
43        }
44    }
45}
46
47impl TryFrom<&Path> for Method {
48    type Error = Error;
49
50    fn try_from(path: &Path) -> Result<Self, Self::Error> {
51        if path.is_ident("get") {
52            Ok(Self::Get)
53        } else if path.is_ident("set") {
54            Ok(Self::Set)
55        } else if path.is_ident("with") {
56            Ok(Self::With)
57        } else if path.is_ident("get_mut") {
58            Ok(Self::GetMut)
59        } else if path.is_ident("without") {
60            Ok(Self::Without)
61        } else if path.is_ident("take") {
62            Ok(Self::Take)
63        } else {
64            Err(Error::new(path.span(), "unrecognized method"))
65        }
66    }
67}
68
69#[derive(Debug)]
70pub(crate) struct MethodSettings<T>([Option<T>; 6]);
71
72impl<T> Default for MethodSettings<T> {
73    fn default() -> Self {
74        Self(Default::default())
75    }
76}
77
78impl<T> MethodSettings<T> {
79    fn iter(&self) -> impl Iterator<Item = Option<&T>> {
80        self.0.iter().map(|x| x.as_ref())
81    }
82
83    pub(crate) fn is_empty(&self) -> bool {
84        self.iter().all(|x| x.is_none())
85    }
86
87    pub(crate) fn contains(&self, method: Method) -> bool {
88        self.0[method as usize].is_some()
89    }
90
91    pub(crate) fn insert(&mut self, method: Method, setting: T) {
92        self.0[method as usize] = Some(setting);
93    }
94
95    pub(crate) fn retrieve(&self, method: Method) -> Option<&T> {
96        self.0[method as usize].as_ref()
97    }
98}