diff options
Diffstat (limited to 'vendor/clap_derive/src/utils/ty.rs')
-rw-r--r-- | vendor/clap_derive/src/utils/ty.rs | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/vendor/clap_derive/src/utils/ty.rs b/vendor/clap_derive/src/utils/ty.rs index 0bcb59f27..9349bc29d 100644 --- a/vendor/clap_derive/src/utils/ty.rs +++ b/vendor/clap_derive/src/utils/ty.rs @@ -7,12 +7,15 @@ use syn::{ PathSegment, Type, TypePath, }; -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Ty { + Unit, Vec, + VecVec, Option, OptionOption, OptionVec, + OptionVecVec, Other, } @@ -21,13 +24,15 @@ impl Ty { use self::Ty::*; let t = |kind| Sp::new(kind, ty.span()); - if is_generic_ty(ty, "Vec") { - t(Vec) + if is_unit_ty(ty) { + t(Unit) + } else if let Some(vt) = get_vec_ty(ty, Vec, VecVec) { + t(vt) } else if let Some(subty) = subty_if_name(ty, "Option") { if is_generic_ty(subty, "Option") { t(OptionOption) - } else if is_generic_ty(subty, "Vec") { - t(OptionVec) + } else if let Some(vt) = get_vec_ty(subty, OptionVec, OptionVecVec) { + t(vt) } else { t(Option) } @@ -35,15 +40,32 @@ impl Ty { t(Other) } } + + pub fn as_str(&self) -> &'static str { + match self { + Self::Unit => "()", + Self::Vec => "Vec<T>", + Self::Option => "Option<T>", + Self::OptionOption => "Option<Option<T>>", + Self::OptionVec => "Option<Vec<T>>", + Self::VecVec => "Vec<Vec<T>>", + Self::OptionVecVec => "Option<Vec<Vec<T>>>", + Self::Other => "...other...", + } + } } pub fn inner_type(field_ty: &syn::Type) -> &syn::Type { let ty = Ty::from_syn_ty(field_ty); match *ty { Ty::Vec | Ty::Option => sub_type(field_ty).unwrap_or(field_ty), - Ty::OptionOption | Ty::OptionVec => { + Ty::OptionOption | Ty::OptionVec | Ty::VecVec => { sub_type(field_ty).and_then(sub_type).unwrap_or(field_ty) } + Ty::OptionVecVec => sub_type(field_ty) + .and_then(sub_type) + .and_then(sub_type) + .unwrap_or(field_ty), _ => field_ty, } } @@ -111,9 +133,33 @@ fn is_generic_ty(ty: &syn::Type, name: &str) -> bool { subty_if_name(ty, name).is_some() } +fn is_unit_ty(ty: &syn::Type) -> bool { + if let syn::Type::Tuple(tuple) = ty { + tuple.elems.is_empty() + } else { + false + } +} + fn only_one<I, T>(mut iter: I) -> Option<T> where I: Iterator<Item = T>, { iter.next().filter(|_| iter.next().is_none()) } + +#[cfg(feature = "unstable-v5")] +fn get_vec_ty(ty: &Type, vec_ty: Ty, vecvec_ty: Ty) -> Option<Ty> { + subty_if_name(ty, "Vec").map(|subty| { + if is_generic_ty(subty, "Vec") { + vecvec_ty + } else { + vec_ty + } + }) +} + +#[cfg(not(feature = "unstable-v5"))] +fn get_vec_ty(ty: &Type, vec_ty: Ty, _vecvec_ty: Ty) -> Option<Ty> { + is_generic_ty(ty, "Vec").then_some(vec_ty) +} |