Add derive macro under feature

This commit is contained in:
soup 2024-06-09 19:24:50 -04:00
parent f19cccd2f8
commit bb83d8e272
No known key found for this signature in database
7 changed files with 239 additions and 2 deletions

102
Cargo.lock generated
View file

@ -4,4 +4,104 @@ version = 3
[[package]]
name = "newt"
version = "0.2.0"
version = "0.3.1"
dependencies = [
"newt-derive",
"newt-derive-core",
]
[[package]]
name = "newt-derive"
version = "0.1.0"
dependencies = [
"newt-derive-core",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "newt-derive-core"
version = "0.1.0"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"

View file

@ -1,6 +1,23 @@
[package]
name = "newt"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
[workspace]
resolver = "2"
members = ["derive", "derive/core"]
[workspace.dependencies]
proc-macro-error = "1.0"
proc-macro2 = "1"
syn = { version = "2", features = ["full"] }
quote = "1"
[dependencies]
newt-derive = { path = "derive", optional = true }
[dev-dependencies]
newt-derive-core = { path = "derive/core" }
[features]
derive = ["dep:newt-derive"]

15
derive/Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "newt-derive"
version = "0.1.0"
edition = "2021"
[dependencies]
proc-macro-error = { workspace = true }
proc-macro2 = { workspace = true }
syn = { workspace = true }
quote = { workspace = true }
newt-derive-core = { path = "./core" }
[lib]
proc-macro = true

10
derive/core/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "newt-derive-core"
version = "0.1.0"
edition = "2021"
[dependencies]
proc-macro-error = { workspace = true }
proc-macro2 = { workspace = true }
syn = { workspace = true }
quote = { workspace = true }

83
derive/core/src/lib.rs Normal file
View file

@ -0,0 +1,83 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Fields, ItemStruct};
pub fn lookup_core(input: TokenStream) -> TokenStream {
let input: ItemStruct = match syn::parse2(input) {
Ok(i) => i,
Err(e) => return e.to_compile_error(),
};
let struct_name = input.ident;
let (ipl, ty, _) = input.generics.split_for_impl();
match input.fields {
Fields::Named(n) => {
let mut exprs = Vec::new();
for field in n.named {
let ident = field.ident.expect("named field should have name");
let ident_str = format!(r#"{ident}"#);
exprs.push(quote! {
#ident_str => Some(&self.#ident),
});
}
let output = quote! {
impl #ipl #struct_name #ty {
fn __lookup(&self, name: &str) -> Option<&dyn ::newt::Value> {
match name {
#(#exprs)*
_ => None,
}
}
}
};
output
},
Fields::Unnamed(_u) => {
todo!()
},
Fields::Unit => quote! {
todo!()
},
}
}
#[cfg(test)]
mod test {
use quote::quote;
use crate::lookup_core;
macro_rules! go {
($in:expr, $exp:expr $(,)?) => {
assert_eq!(lookup_core($in).to_string(), $exp.to_string());
};
}
#[test]
pub fn named_fields_struct() {
go! {
quote! {
#[derive(Lookup)]
struct Test {
foo: String,
bar: String,
}
},
quote! {
impl Test {
fn __lookup(&self, name: &str) -> Option<&dyn ::newt::Value> {
match name {
"foo" => Some(&self.foo),
"bar" => Some(&self.bar),
_ => None,
}
}
}
},
};
}
}

9
derive/src/lib.rs Normal file
View file

@ -0,0 +1,9 @@
use newt_derive_core::lookup_core;
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
#[proc_macro_error]
#[proc_macro_derive(Lookup)]
pub fn lookup(input: TokenStream) -> TokenStream {
lookup_core(input.into()).into()
}

View file

@ -478,3 +478,6 @@ macro_rules! values {
]
}}
}
#[cfg(feature = "derive")]
pub use newt_derive::Lookup;