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}