use syn::{Error, Ident, PathArguments, Result, Type};
pub fn extract_ident_from_type(ty: &Type) -> Result<Ident> {
match ty {
Type::Path(type_path) => {
if type_path.qself.is_some() {
return Err(Error::new_spanned(
type_path,
"Type must be a simple identifier, not a qualified path.",
));
}
if type_path.path.segments.len() != 1 {
return Err(Error::new_spanned(
&type_path.path,
"Type must be a simple identifier, not a module path (e.g., use 'MyType', not 'crate::MyType').",
));
}
let segment = type_path.path.segments.first().unwrap();
if !matches!(segment.arguments, PathArguments::None) {
return Err(Error::new_spanned(
&type_path.path,
"Type must not have generic parameters (e.g., use 'MyType', not 'MyType<T>').",
));
}
Ok(segment.ident.clone())
}
_ => Err(Error::new_spanned(
ty,
"Type must be a simple struct identifier. References, tuples, slices, or pointers are not allowed.",
)),
}
}
pub fn has_attr(attrs: &[syn::Attribute], name: &str) -> bool {
attrs.iter().any(|a| {
if a.path().is_ident(name) {
return true;
}
if a.path().segments.len() == 2
&& a.path().segments[0].ident == "pyroduct"
&& a.path().segments[1].ident == name
{
return true;
}
false
})
}