serde-with-env 0.1.0

This crate provide a way to get value from env after standard serde deserialization.
Documentation
use syn::{Attribute, ExprLit, LitStr};

pub enum EnvAttrOp {
    Or,
    Only,
    Over,
}
pub struct EnvAttr {
    pub name: LitStr,
    pub default: Option<ExprLit>,
    pub convert: Option<LitStr>,
    pub op: EnvAttrOp,
}

pub fn get_env_attr(attrs: &Vec<Attribute>) -> Option<Result<EnvAttr, syn::Error>> {
    let mut maybe_attr: Option<Result<EnvAttr, syn::Error>> = None;
    let mut maybe_default: Option<ExprLit> = None;
    let mut maybe_convert: Option<LitStr> = None;

    for attr in attrs {
        if attr.path().is_ident("with_env") {
            let result = attr.parse_nested_meta(|meta| {
                if meta.path.is_ident("default") {
                    _ = meta
                        .value()
                        .and_then(|value| value.parse::<ExprLit>())
                        .map(|value| maybe_default = Some(value));
                }

                if meta.path.is_ident("convert") {
                    _ = meta
                        .value()
                        .and_then(|value| value.parse::<LitStr>())
                        .map(|value| maybe_convert = Some(value));
                }


                let mut op = None;

                if meta.path.is_ident("or") {
                    op = Some(EnvAttrOp::Or);
                }
                if meta.path.is_ident("only") {
                    op = Some(EnvAttrOp::Only);
                }
                if meta.path.is_ident("over") {
                    op = Some(EnvAttrOp::Over);
                }

                if let Some(op) = op {
                    meta.value()
                        .and_then(|value| value.parse::<LitStr>())
                        .map(|value| {
                            maybe_attr = Some(Ok(EnvAttr {
                                name: value,
                                default: None,
                                convert: None,
                                op,
                            }));

                            ()
                        })
                } else {
                    Ok(())
                }
            });

            if let Err(err) = result {
                maybe_attr = Some(Err(err))
            }
        }
    }
    if let Some(maybe_default) = maybe_default
        && let Some(Ok(attr)) = &mut maybe_attr
    {
        attr.default = Some(maybe_default);
    }

    if let Some(maybe_convert) = maybe_convert
        && let Some(Ok(attr)) = &mut maybe_attr
    {
        attr.convert = Some(maybe_convert);
    }

    maybe_attr
}