actix_prost_build/
helpers.rs

1use syn::{GenericArgument, Path, PathArguments, PathSegment};
2
3pub fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> {
4    fn extract_type_path(ty: &syn::Type) -> Option<&Path> {
5        match *ty {
6            syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
7            _ => None,
8        }
9    }
10
11    fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
12        let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
13            acc.push_str(&v.ident.to_string());
14            acc.push('|');
15            acc
16        });
17        vec!["Option|", "std|option|Option|", "core|option|Option|"]
18            .into_iter()
19            .find(|s| &idents_of_path == s)
20            .and_then(|_| path.segments.last())
21    }
22
23    extract_type_path(ty)
24        .and_then(|path| extract_option_segment(path))
25        .and_then(|path_seg| {
26            let type_params = &path_seg.arguments;
27            // It should have only on angle-bracketed param ("<String>"):
28            match *type_params {
29                PathArguments::AngleBracketed(ref params) => params.args.first(),
30                _ => None,
31            }
32        })
33        .and_then(|generic_arg| match *generic_arg {
34            GenericArgument::Type(ref ty) => Some(ty),
35            _ => None,
36        })
37}