use proc_macro2::TokenStream;
use quote::quote;
use syn::{Ident, TypeGenerics};
fn slot(
is_generic: bool,
accessor: TokenStream,
returned: TokenStream,
initializer: TokenStream,
stored: TokenStream,
documentation: &str,
) -> TokenStream {
if is_generic {
return quote! {
#[doc = #documentation]
fn #accessor() -> &'static #returned {
static REGISTRY: ::dynamic_config::Registry = ::dynamic_config::Registry::new();
REGISTRY.entry::<Self, #returned>()
}
};
}
quote! {
#[doc = #documentation]
fn #accessor() -> &'static #returned {
static SLOT: #stored = #initializer;
&SLOT
}
}
}
pub(super) fn remote_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_remote),
quote!(::dynamic_config::Remote),
quote!(::dynamic_config::Remote::new()),
quote!(::dynamic_config::Remote),
"The remote store's document, layered over the files.",
)
}
pub(super) fn aliases_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_aliases),
quote!(::dynamic_config::Aliases),
quote!(::dynamic_config::Aliases::new()),
quote!(::dynamic_config::Aliases),
"Old key paths that still resolve.",
)
}
pub(super) fn bindings_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_env_bindings),
quote!(::dynamic_config::EnvBindings),
quote!(::dynamic_config::EnvBindings::new()),
quote!(::dynamic_config::EnvBindings),
"Fields bound to environment variables by name.",
)
}
pub(super) fn flags_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_flags),
quote!(::dynamic_config::Layer),
quote!(::dynamic_config::Layer::new()),
quote!(::dynamic_config::Layer),
"Values from the command line, layered over the environment.",
)
}
pub(super) fn cell_slot(
is_generic: bool,
name: &Ident,
type_generics: &TypeGenerics<'_>,
) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_cell),
quote!(::dynamic_config::ConfigCell<Self>),
quote!(::dynamic_config::ConfigCell::<#name #type_generics>::new()),
quote!(::dynamic_config::ConfigCell<#name #type_generics>),
"Process-wide storage for the current snapshot.",
)
}
pub(super) fn configured_slot(
is_generic: bool,
name: &Ident,
type_generics: &TypeGenerics<'_>,
) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_configured),
quote!(::dynamic_config::Configured<Self>),
quote!(::dynamic_config::Configured::<#name #type_generics>::new()),
quote!(::dynamic_config::Configured<#name #type_generics>),
"The builder this type was configured with, remembered at `init`.",
)
}
pub(super) fn defaults_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_defaults),
quote!(::dynamic_config::Layer),
quote!(::dynamic_config::Layer::new()),
quote!(::dynamic_config::Layer),
"Values consulted only when no file or variable supplies a key.",
)
}
pub(super) fn overrides_slot(is_generic: bool) -> TokenStream {
slot(
is_generic,
quote!(dynamic_config_overrides),
quote!(::dynamic_config::Layer),
quote!(::dynamic_config::Layer::new()),
quote!(::dynamic_config::Layer),
"Values that win over the files and the environment alike.",
)
}
pub(super) fn layer_setters() -> TokenStream {
quote! {
pub fn set_default<__DynamicConfigValue>(
path: &str,
value: __DynamicConfigValue,
) -> ::core::result::Result<(), ::dynamic_config::Error>
where
__DynamicConfigValue: ::dynamic_config::__private::serde::Serialize,
{
Self::dynamic_config_defaults().set(path, value)
}
pub fn set_override<__DynamicConfigValue>(
path: &str,
value: __DynamicConfigValue,
) -> ::core::result::Result<(), ::dynamic_config::Error>
where
__DynamicConfigValue: ::dynamic_config::__private::serde::Serialize,
{
Self::dynamic_config_overrides().set(path, value)
}
}
}
pub(super) fn defaults_and_flag_setters() -> TokenStream {
quote! {
pub fn set_defaults<__DynamicConfigDefaults>(
value: &__DynamicConfigDefaults,
) -> ::core::result::Result<(), ::dynamic_config::Error>
where
__DynamicConfigDefaults: ::dynamic_config::__private::serde::Serialize,
{
Self::dynamic_config_defaults().set_struct(value)
}
pub fn set_flag<__DynamicConfigValue>(
path: &str,
value: ::core::option::Option<__DynamicConfigValue>,
) -> ::core::result::Result<(), ::dynamic_config::Error>
where
__DynamicConfigValue: ::dynamic_config::__private::serde::Serialize,
{
match value {
::core::option::Option::Some(value) => {
Self::dynamic_config_flags().set(path, value)
}
::core::option::Option::None => ::core::result::Result::Ok(()),
}
}
pub fn set_assignments<__DynamicConfigItems, __DynamicConfigItem>(
assignments: __DynamicConfigItems,
) -> ::core::result::Result<(), ::dynamic_config::Error>
where
__DynamicConfigItems: ::core::iter::IntoIterator<Item = __DynamicConfigItem>,
__DynamicConfigItem: ::core::convert::AsRef<str>,
{
Self::dynamic_config_flags().set_assignments(assignments)
}
}
}
pub(super) fn binding_methods() -> TokenStream {
quote! {
pub fn alias(
from: &str,
to: &str,
) -> ::core::result::Result<(), ::dynamic_config::Error> {
Self::dynamic_config_aliases().add(from, to)
}
pub fn clear_aliases() {
Self::dynamic_config_aliases().clear();
}
pub fn bind_env(
path: &str,
variable: &str,
) -> ::core::result::Result<(), ::dynamic_config::Error> {
Self::dynamic_config_env_bindings().bind(path, variable)
}
pub fn clear_env_bindings() {
Self::dynamic_config_env_bindings().clear();
}
}
}
pub(super) fn clear_flags_method() -> TokenStream {
quote! {
pub fn clear_flags() {
Self::dynamic_config_flags().clear();
}
}
}
pub(super) fn clear_layer_methods() -> TokenStream {
quote! {
pub fn clear_defaults() {
Self::dynamic_config_defaults().clear();
}
pub fn clear_overrides() {
Self::dynamic_config_overrides().clear();
}
}
}