utility_macros_internals/
option.rs

1use syn::{parse_quote, PathArguments, Type};
2
3pub fn is_option(ty: &Type) -> bool {
4    match ty {
5        Type::Path(type_path) => {
6            let path = &type_path.path;
7            let segments = &path.segments;
8            if segments.len() == 1 {
9                let segment = &segments[0];
10                if segment.ident == "Option" {
11                    return true;
12                }
13            }
14        }
15        _ => {}
16    }
17    false
18}
19
20pub fn as_option(ty: &Type) -> Type {
21    if is_option(ty) {
22        return ty.clone();
23    }
24
25    parse_quote!(Option<#ty>)
26}
27
28pub fn as_required(ty: &Type) -> Type {
29    if !is_option(ty) {
30        return ty.clone();
31    }
32
33    let Type::Path(ty) = ty else {
34        panic!("Expected Type::Path")
35    };
36
37    let segments = &ty.path.segments;
38    if segments.len() != 1 {
39        panic!("Expected single segment")
40    }
41
42    let PathArguments::AngleBracketed(args) = &segments[0].arguments else {
43        panic!("Expected angle bracketed arguments")
44    };
45
46    let required_ty = args.args.iter().next().expect("Expected argument");
47    parse_quote!(#required_ty)
48}