use proc_macro2::TokenStream as TokenStream2;
use quote::{quote};
use syn::{
GenericArgument,
PathArguments,
Type,
};
pub fn strip_arc(ty: &Type) -> TokenStream2 {
let path = match ty {
Type::Path(tp) => &tp.path,
_ => return quote! { #ty },
};
let segs = &path.segments;
if segs.len() == 1 && segs[0].ident == "Arc" {
if let PathArguments::AngleBracketed(ab) = &segs[0].arguments {
if ab.args.len() == 1 {
if let GenericArgument::Type(inner) = &ab.args[0] {
return quote! { #inner };
}
}
}
}
quote! { #ty }
}
pub fn camel_to_snake(s: &str) -> String {
let mut result = String::new();
for (i, ch) in s.chars().enumerate() {
if ch.is_uppercase() && i != 0 {
result.push('_');
}
result.push(ch.to_lowercase().next().unwrap());
}
result
}
pub fn camel_to_screaming_snake(s: &str) -> String {
camel_to_snake(s).to_uppercase()
}
pub fn extract_option_inner(ty: &Type) -> Option<Type> {
if let Type::Path(type_path) = ty {
if let Some(segment) = type_path.path.segments.last() {
if segment.ident == "Option" {
if let PathArguments::AngleBracketed(args) = &segment.arguments {
if let Some(GenericArgument::Type(inner_ty)) = args.args.first() {
return Some(inner_ty.clone());
}
}
}
}
}
None
}
pub fn is_option_type(ty: &Type) -> bool {
extract_option_inner(ty).is_some()
}