use quote::quote;
use syn::DeriveInput;
pub(crate) fn expand(input: &DeriveInput) -> proc_macro2::TokenStream {
let ident = &input.ident;
let (_, original_ty_generics, _) = input.generics.split_for_impl();
let mut from_env_generics = input.generics.clone();
let from_env_where = from_env_generics.make_where_clause();
from_env_where.predicates.push(syn::parse_quote! {
#ident #original_ty_generics: ::core::str::FromStr
});
from_env_where.predicates.push(syn::parse_quote! {
<#ident #original_ty_generics as ::core::str::FromStr>::Err:
::std::error::Error + ::core::marker::Send + ::core::marker::Sync + 'static
});
let (from_env_impl_generics, from_env_ty_generics, from_env_where_clause) =
from_env_generics.split_for_impl();
let documented_impl = if cfg!(feature = "docs") {
let mut documented_generics = input.generics.clone();
documented_generics
.make_where_clause()
.predicates
.push(syn::parse_quote! {
#ident #original_ty_generics: ::core::fmt::Display
});
let (documented_impl_generics, documented_ty_generics, documented_where_clause) =
documented_generics.split_for_impl();
quote! {
#[automatically_derived]
impl #documented_impl_generics ::confroid::Documented
for #ident #documented_ty_generics #documented_where_clause
{
fn doc_fields() -> ::core::option::Option<
::std::vec::Vec<::confroid::FieldDoc>
> {
::core::option::Option::None
}
}
}
} else {
quote! {}
};
quote! {
#[automatically_derived]
impl #from_env_impl_generics ::confroid::FromEnv
for #ident #from_env_ty_generics #from_env_where_clause
{
fn from_env(
ctx: &::confroid::Ctx,
env: &::confroid::Env,
) -> ::confroid::Result<Self> {
match env.get(&ctx.var) {
::core::option::Option::None =>
::core::result::Result::Err(
::confroid::ConfroidError::EnvVarNotFound {
var_name: ctx.var.clone(),
field: ctx.path.clone(),
}
),
::core::option::Option::Some(__raw) =>
__raw.parse::<Self>().map_err(|__error| {
::confroid::ConfroidError::EnvVarInvalid {
var_name: ctx.var.clone(),
field: ctx.path.clone(),
value: __raw.to_string(),
parser_error: ::std::boxed::Box::new(__error),
}
}),
}
}
fn is_present(ctx: &::confroid::Ctx, env: &::confroid::Env) -> bool {
env.get(&ctx.var).is_some()
}
}
#documented_impl
}
}