use proc_macro2::TokenStream;
use quote::quote;
use syn::{Ident, Visibility};
use crate::schema::types::{SchemaType, StructSchema};
use super::util::make_ident;
pub fn struct_def(
vis: &Visibility,
name: &Ident,
schema: &StructSchema,
embedded: bool,
) -> TokenStream {
let fields = schema.fields.iter().map(|f| {
let field_ident = make_ident(&f.rust_name);
let ty = schema_type_tokens(&f.ty, embedded);
quote! { pub #field_ident: #ty }
});
if embedded {
quote! {
#[derive(Debug, Clone, Copy)]
#vis struct #name {
#(#fields,)*
}
}
} else {
quote! {
#[derive(Debug, Clone)]
#vis struct #name {
#(#fields,)*
}
}
}
}
pub fn schema_type_tokens(ty: &SchemaType, embedded: bool) -> TokenStream {
match ty {
SchemaType::Bool => quote! { bool },
SchemaType::Integer => quote! { i64 },
SchemaType::Float => quote! { f64 },
SchemaType::Str => {
if embedded {
quote! { &'static str }
} else {
quote! { ::std::string::String }
}
},
SchemaType::Optional(inner) => {
let inner_ts = schema_type_tokens(inner, embedded);
quote! { ::std::option::Option<#inner_ts> }
},
SchemaType::Array(inner) => {
let inner_ts = schema_type_tokens(inner, embedded);
if embedded {
quote! { &'static [#inner_ts] }
} else {
quote! { ::std::vec::Vec<#inner_ts> }
}
},
SchemaType::Struct(nested) => {
let _ = nested;
if embedded {
quote! { &'static str }
} else {
quote! { ::std::string::String }
}
},
}
}