use heck::ToSnakeCase;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput};
use crate::attrs;
fn override_name(attrs: &[syn::Attribute]) -> syn::Result<Option<String>> {
for item in attrs::parse(attrs)? {
if item.key == "iden" {
return item.str_value().map(Some);
}
}
Ok(None)
}
pub(crate) fn expand(input: DeriveInput) -> syn::Result<TokenStream> {
let ident = &input.ident;
let body = match &input.data {
Data::Struct(_) => {
let name =
override_name(&input.attrs)?.unwrap_or_else(|| ident.to_string().to_snake_case());
quote! { #name }
}
Data::Enum(e) => {
let arms = e.variants.iter().map(|v| {
let vi = &v.ident;
let name = override_name(&v.attrs)
.unwrap_or(None)
.unwrap_or_else(|| vi.to_string().to_snake_case());
quote! { Self::#vi => #name, }
});
quote! { match self { #(#arms)* } }
}
Data::Union(_) => return Err(syn::Error::new_spanned(ident, "unions are not supported")),
};
Ok(impl_iden(ident, body))
}
pub(crate) fn impl_iden(ident: &syn::Ident, as_str_body: TokenStream) -> TokenStream {
quote! {
impl ::turso_orm::entity::IdenStatic for #ident {
fn as_str(&self) -> &'static str {
#as_str_body
}
}
impl ::turso_orm::sql::Iden for #ident {
fn as_str(&self) -> &str {
<Self as ::turso_orm::entity::IdenStatic>::as_str(self)
}
}
impl ::turso_orm::__private::IntoIden for #ident {
fn into_iden(self) -> ::turso_orm::__private::Ident {
::turso_orm::__private::Ident::new_static(<Self as ::turso_orm::entity::IdenStatic>::as_str(&self))
}
}
}
}