learn how workspaces + proc macros work & restructure everything
This commit is contained in:
11
macro/Cargo.toml
Normal file
11
macro/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "iris-macro"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.42"
|
||||
syn = { version = "2.0.111", features = ["full"] }
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
72
macro/src/lib.rs
Normal file
72
macro/src/lib.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
Block, Ident, Signature, Token, Visibility,
|
||||
parse::{Parse, ParseStream, Result},
|
||||
parse_macro_input,
|
||||
};
|
||||
|
||||
struct Input {
|
||||
vis: Visibility,
|
||||
name: Ident,
|
||||
fns: Vec<InputFn>,
|
||||
}
|
||||
|
||||
struct InputFn {
|
||||
sig: Signature,
|
||||
body: Block,
|
||||
}
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let vis = input.parse()?;
|
||||
let name = input.parse()?;
|
||||
input.parse::<Token![;]>()?;
|
||||
let mut fns = Vec::new();
|
||||
while !input.is_empty() {
|
||||
let sig = input.parse()?;
|
||||
let body = input.parse()?;
|
||||
fns.push(InputFn { sig, body })
|
||||
}
|
||||
if !input.is_empty() {
|
||||
input.error("function expected");
|
||||
}
|
||||
Ok(Input { vis, name, fns })
|
||||
}
|
||||
}
|
||||
|
||||
// pub trait $name<W: WidgetLike<Tag>, Tag> {
|
||||
// $(
|
||||
// fn $fn $(<$($T $(: $TT $(+ $TL)?)?,)*>)?($self $(, $arg: $ty)*) -> $ret;
|
||||
// )*
|
||||
// }
|
||||
//
|
||||
// impl<W: WidgetLike<Tag>, Tag> $name<W, Tag> for W {
|
||||
// $(
|
||||
// fn $fn $(<$($T $(: $TT $(+ $TL)?)?,)*>)?($self $(, $arg: $ty)*) -> $ret {
|
||||
// $code
|
||||
// }
|
||||
// )*
|
||||
// }
|
||||
|
||||
#[proc_macro]
|
||||
pub fn widget_trait(input: TokenStream) -> TokenStream {
|
||||
let Input { vis, name, fns } = parse_macro_input!(input as Input);
|
||||
|
||||
let sigs: Vec<_> = fns.iter().map(|f| f.sig.clone()).collect();
|
||||
let impls: Vec<_> = fns
|
||||
.iter()
|
||||
.map(|InputFn { sig, body }| quote! { #sig #body })
|
||||
.collect();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#vis trait #name<WL: WidgetLike<Tag>, Tag> {
|
||||
#(#sigs;)*
|
||||
}
|
||||
|
||||
impl<WL: WidgetLike<Tag>, Tag> #name<WL, Tag> for WL {
|
||||
#(#impls)*
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user