1#[macro_export]
39macro_rules! feattle_enum {
40 (
41 $(#[$enum_meta:meta])*
42 $visibility:vis enum $name:ident {
43 $(
44 $(#[$variant_meta:meta])*
45 $variant:ident
46 ),+ $(,)?
47 }
48 ) => {
49 #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
50 $(#[$enum_meta])*
51 $visibility enum $name {
52 $(
53 $(#[$variant_meta])*
54 $variant
55 ),+
56 }
57
58 impl ::std::str::FromStr for $name {
59 type Err = $crate::__internal::ParseError;
60 fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
61 match s {
62 $(
63 stringify!($variant) => ::std::result::Result::Ok(Self::$variant)
64 ),+,
65 _ => ::std::result::Result::Err($crate::__internal::ParseError)
66 }
67 }
68 }
69
70 impl ::std::fmt::Display for $name {
71 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
72 let as_str = match self {
73 $(
74 Self::$variant => stringify!($variant)
75 ),+
76 };
77 ::std::write!(f, "{}", as_str)
78 }
79 }
80
81 impl $name {
82 const VARIANTS: &'static [&'static str] = &[
83 $(
84 stringify!($variant)
85 ),+
86 ];
87 }
88
89 impl $crate::FeattleStringValue for $name {
90 fn serialized_string_format() -> $crate::StringFormat {
91 let variants = Self::VARIANTS.join(", ");
92 $crate::StringFormat {
93 kind: $crate::StringFormatKind::Choices(&Self::VARIANTS),
94 tag: format!("enum {{{}}}", variants),
95 }
96 }
97 }
98 }
99}
100
101#[macro_export]
102#[doc(hidden)]
103macro_rules! __init_field {
104 ($default:expr) => {
105 $default
106 };
107 () => {
108 Default::default()
109 };
110}
111
112#[macro_export]
117macro_rules! feattles {
118 (
119 $(#[$meta:meta])*
120 $visibility:vis struct $name:ident {
121 $(
122 $(#[doc=$description:tt])*
123 $key:ident: $type:ty $(= $default:expr)?
124 ),*
125 $(,)?
126 }
127) => {
128 use $crate::__internal;
129
130 $(#[$meta])*
131 #[derive(Debug)]
132 $visibility struct $name(__internal::FeattlesImpl<__Feattles>);
133
134 impl __internal::FeattlesPrivate for $name {
135 type FeattleStruct = __Feattles;
136
137 fn _read(
138 &self,
139 ) -> __internal::RwLockReadGuard<'_, __internal::InnerFeattles<Self::FeattleStruct>>
140 {
141 self.0.inner_feattles.read()
142 }
143
144 fn _write(
145 &self,
146 ) -> __internal::RwLockWriteGuard<'_, __internal::InnerFeattles<Self::FeattleStruct>>
147 {
148 self.0.inner_feattles.write()
149 }
150 }
151
152 impl __internal::Feattles for $name {
153 fn new(persistence: __internal::Arc<dyn __internal::Persist>) -> Self {
154 $name(__internal::FeattlesImpl::new(
155 persistence,
156 __Feattles {
157 $(
158 $key: __internal::Feattle::new(
159 stringify!($key),
160 concat!($($description),*).trim(),
161 $crate::__init_field!($($default)?),
162 )
163 ),*
164 },
165 ))
166 }
167
168 fn persistence(&self) -> &__internal::Arc<dyn __internal::Persist> {
169 &self.0.persistence
170 }
171
172 fn keys(&self) -> &'static [&'static str] {
173 &[$(stringify!($key)),*]
174 }
175
176 fn definition(&self, key: &str) -> Option<__internal::FeattleDefinition> {
177 use __internal::FeattlesPrivate;
178 let inner = self._read();
179 match key {
180 $(stringify!($key) => Some(inner.feattles_struct.$key.definition()),)*
181 _ => None,
182 }
183 }
184 }
185
186 impl $name {
187 $(
188 pub fn $key(&self) -> __internal::MappedRwLockReadGuard<$type> {
189 __internal::RwLockReadGuard::map(self.0.inner_feattles.read(), |inner| {
190 inner.feattles_struct.$key.value()
191 })
192 }
193 )*
194 }
195
196 #[derive(Debug)]
197 pub struct __Feattles {
198 $($key: __internal::Feattle<$type>),*
199 }
200
201 impl __internal::FeattlesStruct for __Feattles {
202 fn try_update(
203 &mut self,
204 key: &str,
205 value: Option<__internal::CurrentValue>,
206 ) -> Result<Option<__internal::CurrentValue>, __internal::FromJsonError> {
207 match key {
208 $(stringify!($key) => self.$key.try_update(value),)*
209 _ => unreachable!(),
210 }
211 }
212 }
213 }
214}