refac: some cosmetic changes

This commit is contained in:
Dmitriy Pleshevskiy 2021-04-22 23:39:32 +03:00
parent c21f265eea
commit 13e200eedf
4 changed files with 60 additions and 41 deletions

View file

@ -2,14 +2,14 @@ use crate::utils::SupportedBox;
use proc_macro2::TokenStream as TokenStream2; use proc_macro2::TokenStream as TokenStream2;
use syn::{Attribute, Expr, Ident, Type}; use syn::{Attribute, Expr, Ident, Type};
pub struct RootNamespace { pub(crate) struct RootNamespace {
pub name: Option<Ident>, pub name: Option<Ident>,
pub variables: Vec<Variable>, pub variables: Vec<Variable>,
pub namespaces: Vec<Namespace>, pub namespaces: Vec<Namespace>,
pub meta: Vec<Attribute>, pub meta: Vec<Attribute>,
} }
pub struct Namespace { pub(crate) struct Namespace {
pub name: Ident, pub name: Ident,
pub variables: Vec<Variable>, pub variables: Vec<Variable>,
pub namespaces: Vec<Namespace>, pub namespaces: Vec<Namespace>,
@ -17,7 +17,7 @@ pub struct Namespace {
pub meta: Vec<Attribute>, pub meta: Vec<Attribute>,
} }
pub struct Variable { pub(crate) struct Variable {
pub is_static: bool, pub is_static: bool,
pub name: Ident, pub name: Ident,
pub ty: Type, pub ty: Type,

View file

@ -138,8 +138,8 @@ impl ToTokens for Variable {
}} }}
} else if let Some(initial) = &self.initial { } else if let Some(initial) = &self.initial {
match self.supported_box.clone() { match self.supported_box.clone() {
Some(SupportedBox::Vec(sep)) => { Some(SupportedBox::Vec(params)) => {
let sep = &sep.unwrap_or_else(|| String::from(",")); let sep = &params.sep();
quote!(::itconfig::get_vec_env_or_set_default(#env_name, #sep, #initial)) quote!(::itconfig::get_vec_env_or_set_default(#env_name, #sep, #initial))
} }
_ => quote!(::itconfig::get_env_or_set_default(#env_name, #initial)), _ => quote!(::itconfig::get_env_or_set_default(#env_name, #initial)),
@ -149,12 +149,12 @@ impl ToTokens for Variable {
Some(SupportedBox::Option) => { Some(SupportedBox::Option) => {
quote!(::itconfig::maybe_get_env(#env_name)) quote!(::itconfig::maybe_get_env(#env_name))
} }
Some(SupportedBox::OptionVec(sep)) => { Some(SupportedBox::OptionVec(params)) => {
let sep = &sep.unwrap_or_else(|| String::from(",")); let sep = &params.sep();
quote!(::itconfig::maybe_get_vec_env(#env_name, #sep)) quote!(::itconfig::maybe_get_vec_env(#env_name, #sep))
} }
Some(SupportedBox::Vec(sep)) => { Some(SupportedBox::Vec(params)) => {
let sep = &sep.unwrap_or_else(|| String::from(",")); let sep = &params.sep();
quote!(::itconfig::get_vec_env_or_panic(#env_name, #sep)) quote!(::itconfig::get_vec_env_or_panic(#env_name, #sep))
} }
None => { None => {

View file

@ -1,5 +1,5 @@
use crate::ast::*; use crate::ast::*;
use crate::utils::{maybe_supported_box, SupportedBox}; use crate::utils::{maybe_supported_box, SupportedBox, VecBoxParams};
use proc_macro2::{Ident, Span, TokenStream as TokenStream2}; use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
use quote::quote; use quote::quote;
use syn::ext::IdentExt; use syn::ext::IdentExt;
@ -60,7 +60,8 @@ fn parse_namespace_content(
for attr in attributes { for attr in attributes {
if attr.path.is_ident("env_prefix") { if attr.path.is_ident("env_prefix") {
namespace.env_prefix = parse_attribute(attr, "env_prefix", &namespace.env_prefix)?; let env_prefix = parse_attribute(attr, "env_prefix", &namespace.env_prefix)?;
namespace.env_prefix = Some(env_prefix);
} else { } else {
namespace.meta.push(attr); namespace.meta.push(attr);
} }
@ -72,12 +73,14 @@ fn parse_namespace_content(
for attr in attributes { for attr in attributes {
if attr.path.is_ident("env_name") { if attr.path.is_ident("env_name") {
variable.env_name = parse_attribute(attr, "env_name", &variable.env_name)?; let env_name = parse_attribute(attr, "env_name", &variable.env_name)?;
variable.env_name = Some(env_name);
} else { } else {
match variable.supported_box { match variable.supported_box {
Some(SupportedBox::Vec(current_sep)) if attr.path.is_ident("sep") => { Some(SupportedBox::Vec(params)) if attr.path.is_ident("sep") => {
let sep = parse_attribute(attr, "sep", &current_sep)?; let sep = parse_attribute(attr, "sep", &params.sep_opt())?;
variable.supported_box = Some(SupportedBox::Vec(sep)); variable.supported_box =
Some(SupportedBox::Vec(VecBoxParams::new(Some(sep))));
} }
_ => variable.meta.push(attr), _ => variable.meta.push(attr),
} }
@ -90,11 +93,7 @@ fn parse_namespace_content(
Ok(()) Ok(())
} }
fn parse_attribute( fn parse_attribute(attr: Attribute, name: &'static str, var: &Option<String>) -> Result<String> {
attr: Attribute,
name: &'static str,
var: &Option<String>,
) -> Result<Option<String>> {
if var.is_some() { if var.is_some() {
let message = format!("You cannot use {} meta twice", &name); let message = format!("You cannot use {} meta twice", &name);
return Err(Error::new_spanned(attr, message)); return Err(Error::new_spanned(attr, message));
@ -104,7 +103,7 @@ fn parse_attribute(
Meta::NameValue(MetaNameValue { Meta::NameValue(MetaNameValue {
lit: Lit::Str(lit_str), lit: Lit::Str(lit_str),
.. ..
}) => Ok(Some(lit_str.value())), }) => Ok(lit_str.value()),
_ => { _ => {
let message = format!("expected #[{} = \"...\"]", &name); let message = format!("expected #[{} = \"...\"]", &name);
Err(Error::new_spanned(attr, message)) Err(Error::new_spanned(attr, message))

View file

@ -5,14 +5,34 @@ use syn::{GenericArgument, Path, PathArguments, Type};
const OPTION_PATH_IDENTS: &[&str] = &["Option|", "std|option|Option|", "core|option|Option|"]; const OPTION_PATH_IDENTS: &[&str] = &["Option|", "std|option|Option|", "core|option|Option|"];
const VEC_PATH_IDENTS: &[&str] = &["Vec|", "std|vec|Vec|"]; const VEC_PATH_IDENTS: &[&str] = &["Vec|", "std|vec|Vec|"];
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub enum SupportedBox { pub(crate) struct VecBoxParams(Option<String>);
Vec(Option<String>),
Option, impl VecBoxParams {
OptionVec(Option<String>), #[inline]
pub(crate) fn new(sep: Option<String>) -> Self {
VecBoxParams(sep)
}
#[inline]
pub(crate) fn sep_opt(&self) -> Option<String> {
self.0.clone()
}
#[inline]
pub(crate) fn sep(&self) -> String {
self.0.clone().unwrap_or_else(|| String::from(","))
}
} }
pub fn vec_to_token_stream_2<T>(input: &[T]) -> Vec<TokenStream2> #[derive(Debug, Clone)]
pub(crate) enum SupportedBox {
Vec(VecBoxParams),
Option,
OptionVec(VecBoxParams),
}
pub(crate) fn vec_to_token_stream_2<T>(input: &[T]) -> Vec<TokenStream2>
where where
T: ToTokens, T: ToTokens,
{ {
@ -38,27 +58,27 @@ fn is_vec_path_ident(path_ident: &str) -> bool {
VEC_PATH_IDENTS.iter().any(|s| path_ident == *s) VEC_PATH_IDENTS.iter().any(|s| path_ident == *s)
} }
pub fn maybe_supported_box(ty: &Type) -> Option<SupportedBox> { pub(crate) fn maybe_supported_box(ty: &Type) -> Option<SupportedBox> {
match ty { match ty {
Type::Path(ty_path) if ty_path.qself.is_none() => { Type::Path(ty_path) if ty_path.qself.is_none() => {
let ty_path_ident = path_ident(&ty_path.path); let ty_path_ident = path_ident(&ty_path.path);
if is_option_path_ident(&ty_path_ident) { if is_option_path_ident(&ty_path_ident) {
match &ty_path.path.segments.iter().last().unwrap().arguments { if let PathArguments::AngleBracketed(params) =
PathArguments::AngleBracketed(params) => match params.args.first() { &ty_path.path.segments.iter().last().unwrap().arguments
Some(GenericArgument::Type(Type::Path(inner_ty_path))) => { {
let ty_path_ident = path_ident(&inner_ty_path.path); if let Some(GenericArgument::Type(Type::Path(inner_ty_path))) =
if is_vec_path_ident(&ty_path_ident) { params.args.first()
Some(SupportedBox::OptionVec(None)) {
} else { let ty_path_ident = path_ident(&inner_ty_path.path);
Some(SupportedBox::Option) if is_vec_path_ident(&ty_path_ident) {
} return Some(SupportedBox::OptionVec(Default::default()));
} }
_ => Some(SupportedBox::Option), }
},
_ => Some(SupportedBox::Option),
} }
Some(SupportedBox::Option)
} else if is_vec_path_ident(&ty_path_ident) { } else if is_vec_path_ident(&ty_path_ident) {
Some(SupportedBox::Vec(None)) Some(SupportedBox::Vec(Default::default()))
} else { } else {
None None
} }