parse generics for implement macro
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
ca82b59c6f
commit
7a3cc3941e
2 changed files with 29 additions and 15 deletions
|
@ -1,26 +1,32 @@
|
|||
use proc_macro::TokenStream;
|
||||
use proc_macro::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{ItemFn, Meta, MetaList};
|
||||
use syn::{Error, ItemFn, Meta, Path};
|
||||
use utils::get_named_generics;
|
||||
|
||||
use crate::Result;
|
||||
use crate::{utils, Result};
|
||||
|
||||
pub(super) fn implement(item: ItemFn, args: &[Meta]) -> Result<TokenStream> {
|
||||
let Meta::List(MetaList {
|
||||
path,
|
||||
..
|
||||
}) = &args
|
||||
.first()
|
||||
.expect("missing path to trait or item to implement")
|
||||
else {
|
||||
panic!("invalid path to item for implement");
|
||||
};
|
||||
|
||||
let generics = get_named_generics(args, "generics")?;
|
||||
let receiver = get_receiver(args)?;
|
||||
let params = get_named_generics(args, "params")?;
|
||||
let input = item;
|
||||
let out = quote! {
|
||||
impl #path {
|
||||
impl #generics #receiver #params {
|
||||
#input
|
||||
}
|
||||
};
|
||||
|
||||
Ok(out.into())
|
||||
}
|
||||
|
||||
fn get_receiver(args: &[Meta]) -> Result<Path> {
|
||||
let receiver = &args
|
||||
.first()
|
||||
.ok_or_else(|| Error::new(Span::call_site().into(), "Missing required argument to receiver"))?;
|
||||
|
||||
let Meta::Path(receiver) = receiver else {
|
||||
return Err(Error::new(Span::call_site().into(), "First argument is not path to receiver"));
|
||||
};
|
||||
|
||||
Ok(receiver.clone())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
use syn::{Expr, Lit, Meta};
|
||||
use syn::{parse_str, Expr, Generics, Lit, Meta};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
pub(crate) fn get_named_generics(args: &[Meta], name: &str) -> Result<Generics> {
|
||||
const DEFAULT: &str = "<>";
|
||||
|
||||
parse_str::<Generics>(&get_named_string(args, name).unwrap_or_else(|| DEFAULT.to_owned()))
|
||||
}
|
||||
|
||||
pub(crate) fn get_named_string(args: &[Meta], name: &str) -> Option<String> {
|
||||
args.iter().find_map(|arg| {
|
||||
|
|
Loading…
Add table
Reference in a new issue