kcl_derive_docs/unbox.rs
1// Unbox a Vec<Box<T>> to Vec<T>.
2// Unbox a Box<T> to T.
3pub(crate) fn unbox(t: syn::Type) -> syn::Type {
4 unbox_inner(unbox_vec(t))
5}
6
7// Unbox a syn::Type that is boxed to the inner object.
8fn unbox_inner(t: syn::Type) -> syn::Type {
9 match t {
10 syn::Type::Path(syn::TypePath { ref path, .. }) => {
11 let path = &path.segments;
12 if path.len() == 1 {
13 let seg = &path[0];
14 if seg.ident == "Box" {
15 if let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { args, .. }) =
16 &seg.arguments
17 {
18 if args.len() == 1 {
19 let mut args = args.iter();
20 let ok = args.next().unwrap();
21 if let syn::GenericArgument::Type(ty) = ok {
22 return ty.clone();
23 }
24 }
25 }
26 }
27 }
28 }
29 _ => {
30 return t;
31 }
32 }
33 t
34}
35
36// For a Vec<Box<T>> return Vec<T>.
37// For a Vec<T> return Vec<T>.
38fn unbox_vec(t: syn::Type) -> syn::Type {
39 match t {
40 syn::Type::Path(syn::TypePath { ref path, .. }) => {
41 let path = &path.segments;
42 if path.len() == 1 {
43 let seg = &path[0];
44 if seg.ident == "Vec" {
45 if let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { args, .. }) =
46 &seg.arguments
47 {
48 if args.len() == 1 {
49 let mut args = args.iter();
50 let ok = args.next().unwrap();
51 if let syn::GenericArgument::Type(ty) = ok {
52 let unboxed = unbox(ty.clone());
53 // Wrap it back in a vec.
54 let wrapped = syn::Type::Path(syn::TypePath {
55 qself: None,
56 path: syn::Path {
57 leading_colon: None,
58 segments: {
59 let mut segments = syn::punctuated::Punctuated::new();
60 segments.push_value(syn::PathSegment {
61 ident: syn::Ident::new("Vec", proc_macro2::Span::call_site()),
62 arguments: syn::PathArguments::AngleBracketed(
63 syn::AngleBracketedGenericArguments {
64 colon2_token: None,
65 lt_token: syn::token::Lt::default(),
66 args: {
67 let mut args = syn::punctuated::Punctuated::new();
68 args.push_value(syn::GenericArgument::Type(unboxed));
69 args
70 },
71 gt_token: syn::token::Gt::default(),
72 },
73 ),
74 });
75 segments
76 },
77 },
78 });
79 return wrapped;
80 }
81 }
82 }
83 }
84 }
85 }
86 _ => {
87 return t;
88 }
89 }
90 t
91}