1use quote::format_ident;
4use syn::{GenericParam, Generics, Ident, TypeParamBound};
5
6pub trait ToIdent {
8 fn as_ident(&self) -> Ident;
10}
11impl<T: AsRef<str>> ToIdent for T {
12 fn as_ident(&self) -> Ident {
13 format_ident!("{}", self.as_ref())
14 }
15}
16
17pub fn add_trait_bounds(mut generics: Generics, bounds: TypeParamBound) -> Generics {
19 for param in &mut generics.params {
20 if let GenericParam::Type(ref mut type_param) = *param {
21 type_param.bounds.push(bounds.clone());
22 }
23 }
24 generics
25}
26
27pub fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> {
31 use syn::{GenericArgument, Path, PathArguments, PathSegment};
32
33 fn extract_type_path(ty: &syn::Type) -> Option<&Path> {
35 match *ty {
36 syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
37 _ => None,
38 }
39 }
40
41 fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
43 let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
44 acc.push_str(&v.ident.to_string());
45 acc.push('|');
46 acc
47 });
48 ["Option|", "std|option|Option|", "core|option|Option|"]
49 .into_iter()
50 .find(|s| idents_of_path == *s)
51 .and_then(|_| path.segments.last())
52 }
53
54 extract_type_path(ty)
55 .and_then(|path| extract_option_segment(path))
56 .and_then(|path_seg| {
57 let type_params = &path_seg.arguments;
58 match *type_params {
60 PathArguments::AngleBracketed(ref params) => params.args.first(),
61 _ => None,
62 }
63 })
64 .and_then(|generic_arg| match *generic_arg {
65 GenericArgument::Type(ref ty) => Some(ty),
66 _ => None,
67 })
68}