use syn::{Attribute, Block, ItemFn, Signature, Visibility};
pub struct GenericsFn {
#[allow(dead_code)]
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub sig: Signature,
pub block: Block,
}
impl From<ItemFn> for GenericsFn {
fn from(item: ItemFn) -> Self {
GenericsFn {
attrs: item.attrs,
vis: item.vis,
sig: item.sig,
block: *item.block,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use syn::{parse_quote, ItemFn};
#[test]
fn test_from_item_fn() {
let func: ItemFn = parse_quote! {
pub fn test_func(x: i32, y: String) -> i32 {
x + 1
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "test_func");
assert_eq!(generics_fn.sig.inputs.len(), 2);
assert!(matches!(generics_fn.vis, Visibility::Public(_)));
}
#[test]
fn test_from_private_function() {
let func: ItemFn = parse_quote! {
fn private_func() {
println!("private");
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "private_func");
assert_eq!(generics_fn.sig.inputs.len(), 0);
assert!(matches!(generics_fn.vis, Visibility::Inherited));
}
#[test]
fn test_from_function_with_attributes() {
let func: ItemFn = parse_quote! {
#[inline]
#[allow(dead_code)]
pub fn attributed_func(x: i32) -> i32 {
x * 2
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "attributed_func");
assert_eq!(generics_fn.attrs.len(), 2);
}
#[test]
fn test_from_function_with_complex_signature() {
let func: ItemFn = parse_quote! {
pub async fn complex_func<T: Clone>(
x: T,
y: &str,
z: Option<i32>
) -> Result<T, String>
where
T: std::fmt::Debug
{
Ok(x)
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "complex_func");
assert_eq!(generics_fn.sig.inputs.len(), 3);
assert!(generics_fn.sig.asyncness.is_some());
assert!(!generics_fn.sig.generics.params.is_empty());
}
#[test]
fn test_from_function_no_return_type() {
let func: ItemFn = parse_quote! {
fn void_func(x: i32) {
println!("{}", x);
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "void_func");
assert!(matches!(generics_fn.sig.output, syn::ReturnType::Default));
}
#[test]
fn test_from_function_with_return_type() {
let func: ItemFn = parse_quote! {
fn returning_func() -> String {
"hello".to_string()
}
};
let generics_fn = GenericsFn::from(func);
assert_eq!(generics_fn.sig.ident.to_string(), "returning_func");
assert!(matches!(
generics_fn.sig.output,
syn::ReturnType::Type(_, _)
));
}
}