vercel_rpc_cli/parser/
types.rs1use syn::{Fields, FieldsNamed, Type};
2
3use super::serde as serde_attr;
4use crate::model::{FieldDef, RustType};
5
6pub fn extract_rust_type(ty: &Type) -> RustType {
11 match ty {
12 Type::Path(type_path) => {
13 let segment = type_path
14 .path
15 .segments
16 .last()
17 .expect("Type::Path always has at least one segment");
18 let name = segment.ident.to_string();
19 let generics = extract_generic_args(&segment.arguments);
20
21 if generics.is_empty() {
22 RustType::simple(name)
23 } else {
24 RustType::with_generics(name, generics)
25 }
26 }
27
28 Type::Reference(type_ref) => extract_rust_type(&type_ref.elem),
29
30 Type::Tuple(tuple) => {
31 if tuple.elems.is_empty() {
32 RustType::simple("()")
33 } else {
34 let inner: Vec<RustType> = tuple.elems.iter().map(extract_rust_type).collect();
35 RustType::with_generics("tuple", inner)
36 }
37 }
38
39 Type::Array(array) => {
40 let elem = extract_rust_type(&array.elem);
41 RustType::with_generics("Array", vec![elem])
42 }
43
44 Type::Slice(slice) => {
45 let elem = extract_rust_type(&slice.elem);
46 RustType::with_generics("Array", vec![elem])
47 }
48
49 _ => {
50 let token_str = quote::quote!(#ty).to_string();
51 RustType::simple(token_str)
52 }
53 }
54}
55
56fn extract_generic_args(arguments: &syn::PathArguments) -> Vec<RustType> {
58 match arguments {
59 syn::PathArguments::AngleBracketed(args) => args
60 .args
61 .iter()
62 .filter_map(|arg| match arg {
63 syn::GenericArgument::Type(ty) => Some(extract_rust_type(ty)),
64 _ => None,
65 })
66 .collect(),
67 _ => vec![],
68 }
69}
70
71pub fn extract_struct_fields(fields: &Fields) -> Vec<FieldDef> {
74 match fields {
75 Fields::Named(FieldsNamed { named, .. }) => named
76 .iter()
77 .filter_map(|f| {
78 let name = f.ident.as_ref()?.to_string();
79 let ty = extract_rust_type(&f.ty);
80 let rename = serde_attr::parse_rename(&f.attrs);
81 let skip = serde_attr::is_skipped(&f.attrs);
82 let has_default = serde_attr::has_default(&f.attrs);
83 Some(FieldDef {
84 name,
85 ty,
86 rename,
87 skip,
88 has_default,
89 })
90 })
91 .collect(),
92 _ => vec![],
93 }
94}