#[macro_export]
macro_rules! feattle_enum {
(
$(#[$enum_meta:meta])*
$visibility:vis enum $name:ident {
$(
$(#[$variant_meta:meta])*
$variant:ident
),+ $(,)?
}
) => {
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
$(#[$enum_meta])*
$visibility enum $name {
$(
$(#[$variant_meta])*
$variant
),+
}
impl ::std::str::FromStr for $name {
type Err = $crate::__internal::ParseError;
fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
match s {
$(
stringify!($variant) => ::std::result::Result::Ok(Self::$variant)
),+,
_ => ::std::result::Result::Err($crate::__internal::ParseError)
}
}
}
impl ::std::fmt::Display for $name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
let as_str = match self {
$(
Self::$variant => stringify!($variant)
),+
};
::std::write!(f, "{}", as_str)
}
}
impl $name {
const VARIANTS: &'static [&'static str] = &[
$(
stringify!($variant)
),+
];
}
impl $crate::FeattleStringValue for $name {
fn serialized_string_format() -> $crate::StringFormat {
let variants = Self::VARIANTS.join(", ");
$crate::StringFormat {
kind: $crate::StringFormatKind::Choices(&Self::VARIANTS),
tag: format!("enum {{{}}}", variants),
}
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __init_field {
($default:expr) => {
$default
};
() => {
Default::default()
};
}
#[macro_export]
macro_rules! feattles {
(
$(#[$meta:meta])*
$visibility:vis struct $name:ident {
$(
$(#[doc=$description:tt])*
$key:ident: $type:ty $(= $default:expr)?
),*
$(,)?
}
) => {
mod __feattles {
use ::feattle_core::__internal;
use super::*;
$(#[$meta])*
#[derive(Debug)]
pub struct $name<P>(__internal::FeattlesImpl<P, __Feattles>);
impl<P: __internal::Persist> __internal::FeattlesPrivate<P> for $name<P> {
type FeattleStruct = __Feattles;
fn _read(
&self,
) -> __internal::RwLockReadGuard<'_, __internal::InnerFeattles<Self::FeattleStruct>>
{
self.0.inner_feattles.read()
}
fn _write(
&self,
) -> __internal::RwLockWriteGuard<'_, __internal::InnerFeattles<Self::FeattleStruct>>
{
self.0.inner_feattles.write()
}
}
impl<P: __internal::Persist> __internal::Feattles<P> for $name<P> {
fn new(persistence: P) -> Self {
$name(__internal::FeattlesImpl::new(
persistence,
__Feattles {
$(
$key: __internal::Feattle::new(
stringify!($key),
concat!($($description),*).trim(),
$crate::__init_field!($($default)?),
)
),*
},
))
}
fn persistence(&self) -> &P {
&self.0.persistence
}
fn keys(&self) -> &'static [&'static str] {
&[$(stringify!($key)),*]
}
fn definition(&self, key: &str) -> Option<__internal::FeattleDefinition> {
use __internal::FeattlesPrivate;
let inner = self._read();
match key {
$(stringify!($key) => Some(inner.feattles_struct.$key.definition()),)*
_ => None,
}
}
}
impl<P: __internal::Persist> $name<P> {
$(
pub fn $key(&self) -> __internal::MappedRwLockReadGuard<$type> {
__internal::RwLockReadGuard::map(self.0.inner_feattles.read(), |inner| {
inner.feattles_struct.$key.value()
})
}
)*
}
pub struct __Feattles {
$($key: __internal::Feattle<$type>),*
}
impl __internal::FeattlesStruct for __Feattles {
fn try_update(
&mut self,
key: &str,
value: Option<__internal::CurrentValue>,
) -> Result<Option<__internal::CurrentValue>, __internal::FromJsonError> {
match key {
$(stringify!($key) => self.$key.try_update(value),)*
_ => unreachable!(),
}
}
}
}
$visibility use __feattles::$name;
}
}