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 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> {
|
pub(super) fn implement(item: ItemFn, args: &[Meta]) -> Result<TokenStream> {
|
||||||
let Meta::List(MetaList {
|
let generics = get_named_generics(args, "generics")?;
|
||||||
path,
|
let receiver = get_receiver(args)?;
|
||||||
..
|
let params = get_named_generics(args, "params")?;
|
||||||
}) = &args
|
|
||||||
.first()
|
|
||||||
.expect("missing path to trait or item to implement")
|
|
||||||
else {
|
|
||||||
panic!("invalid path to item for implement");
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = item;
|
let input = item;
|
||||||
let out = quote! {
|
let out = quote! {
|
||||||
impl #path {
|
impl #generics #receiver #params {
|
||||||
#input
|
#input
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(out.into())
|
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> {
|
pub(crate) fn get_named_string(args: &[Meta], name: &str) -> Option<String> {
|
||||||
args.iter().find_map(|arg| {
|
args.iter().find_map(|arg| {
|
||||||
|
|
Loading…
Add table
Reference in a new issue