wip: first commit
This commit is contained in:
commit
98448060b9
24 changed files with 709 additions and 0 deletions
57
src/lib.rs
Normal file
57
src/lib.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
mod manifest;
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
use quote::quote;
|
||||
use crate::manifest::impl_vite_manifest_macro;
|
||||
|
||||
/// Example of [function-like procedural macro][1].
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros
|
||||
#[proc_macro]
|
||||
pub fn my_macro(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
let tokens = quote! {
|
||||
#input
|
||||
|
||||
struct Hello;
|
||||
};
|
||||
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
/// Example of user-defined [derive mode macro][1]
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#derive-mode-macros
|
||||
#[proc_macro_derive(ViteManifest, attributes(root))]
|
||||
pub fn vite_manifest(input: TokenStream) -> TokenStream {
|
||||
let ast = syn::parse_macro_input!(input as DeriveInput);
|
||||
|
||||
impl_vite_manifest_macro(&ast)
|
||||
}
|
||||
|
||||
/// Example of user-defined [procedural macro attribute][1].
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros
|
||||
#[proc_macro_attribute]
|
||||
pub fn root(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
|
||||
let tokens = quote! {
|
||||
struct #name {
|
||||
root: String,
|
||||
}
|
||||
|
||||
impl Default for #name {
|
||||
fn default() -> Self {
|
||||
#name { root: String::new() }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tokens.into()
|
||||
}
|
||||
44
src/manifest.rs
Normal file
44
src/manifest.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{Attribute, Expr, Lit, Meta};
|
||||
|
||||
fn get_attr(path: &str, attrs: &Vec<Attribute>) -> Option<Lit> {
|
||||
let attr = attrs.iter().find(|&a| a.path().is_ident(path))?;
|
||||
|
||||
match &attr.meta {
|
||||
Meta::Path(_) => None,
|
||||
Meta::List(_) => None,
|
||||
Meta::NameValue(nv) => {
|
||||
if let Expr::Lit(expr) = &nv.value {
|
||||
return Some(expr.lit.clone());
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn impl_vite_manifest_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
|
||||
let attr = ast
|
||||
.attrs
|
||||
.iter()
|
||||
.find(|&a| a.path().is_ident("root"))
|
||||
.unwrap();
|
||||
|
||||
let value = if let Lit::Str(lit) = get_attr("root", &ast.attrs).unwrap() {
|
||||
lit.value()
|
||||
} else {
|
||||
panic!("root attribute must be a string literal")
|
||||
};
|
||||
|
||||
let gen = quote! {
|
||||
impl #name {
|
||||
pub fn get_root(&self) -> &str {
|
||||
#value
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gen.into()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue