1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use if_chain::if_chain; use syn::{ Attribute, Data, Fields, FieldsNamed, GenericArgument, Generics, Meta, MetaNameValue, Path, PathArguments, PathSegment, Type, TypeParam, TypePath, }; pub fn is_option_type(ty: &Type) -> bool { match last_path_segment(&ty) { std::option::Option::Some(path_seg) => path_seg.ident == "Option", std::option::Option::None => false, } } pub fn is_vec_type(ty: &Type) -> bool { match last_path_segment(&ty) { std::option::Option::Some(path_seg) => path_seg.ident == "Vec", std::option::Option::None => false, } } pub fn is_int_type(ty: &Type) -> bool { match last_path_segment(&ty) { std::option::Option::Some(path_seg) => matches!( path_seg.ident.to_string().as_str(), "u128" | "u64" | "u32" | "u8" | "i128" | "i64" | "i32" | "i8" ), std::option::Option::None => false, } } pub fn extract_inner_type(ty: &Type) -> &GenericArgument { match last_path_segment(&ty) { std::option::Option::Some(PathSegment { ident: _, arguments: PathArguments::AngleBracketed(ref gen_arg), }) => gen_arg.args.first(), _ => std::option::Option::None, } .expect("invalid option type") } pub fn last_path_segment(ty: &Type) -> std::option::Option<&PathSegment> { match *ty { Type::Path(TypePath { qself: std::option::Option::None, path: Path { segments: ref seg, leading_colon: _, }, }) => seg.last(), _ => std::option::Option::None, } } pub fn extract_struct_fields(data: &Data) -> &FieldsNamed { match *data { Data::Struct(ref data) => match data.fields { Fields::Named(ref fields) => fields, _ => panic!("invalid fields"), }, _ => panic!("invalid data"), } } pub fn count_generics_types(Generics { params, .. }: &Generics) -> u64 { params .iter() .map(|param| match param { syn::GenericParam::Type(_) => 1, _ => 0, }) .sum() } pub fn extract_generics_names(Generics { params, .. }: &Generics) -> Vec<String> { params .iter() .filter_map(|param| match param { syn::GenericParam::Type(TypeParam { ident, .. }) => Some(ident.to_string()), _ => None, }) .collect() } pub fn extract_doc_attr(attrs: &[Attribute]) -> std::option::Option<Attribute> { attrs.iter().find_map(|attr| { if_chain! { if let Ok( Meta::NameValue( MetaNameValue { path, ..} ) ) = attr.parse_meta(); if path.get_ident()? == "doc"; then { std::option::Option::Some(attr.clone()) } else { std::option::Option::None } } }) }