summaryrefslogtreecommitdiff
path: root/derive/src/lib.rs
diff options
context:
space:
mode:
authoreichlan <eichlan@jotunn.office.penny-arcade.com>2026-06-23 15:31:51 -0700
committereichlan <eichlan@jotunn.office.penny-arcade.com>2026-06-23 15:31:51 -0700
commit062048ef6e3e060bcf841ea2ec92e026f09d8da0 (patch)
tree22f7dad062b16f25fcfa1a28af13ac2937348ef0 /derive/src/lib.rs
parent7c299c86bbac76ec2ac199d68eb4dda093a64e3a (diff)
downloadcrimtag-062048ef6e3e060bcf841ea2ec92e026f09d8da0.tar.gz
crimtag-062048ef6e3e060bcf841ea2ec92e026f09d8da0.tar.bz2
crimtag-062048ef6e3e060bcf841ea2ec92e026f09d8da0.tar.xz
crimtag-062048ef6e3e060bcf841ea2ec92e026f09d8da0.zip
Roorganized into workspace and packages.
This is to accomidate a new proc_macro package, which can't have anything else in it.
Diffstat (limited to 'derive/src/lib.rs')
-rw-r--r--derive/src/lib.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/derive/src/lib.rs b/derive/src/lib.rs
new file mode 100644
index 0000000..f9c9180
--- /dev/null
+++ b/derive/src/lib.rs
@@ -0,0 +1,75 @@
1extern crate proc_macro;
2use proc_macro::{TokenStream,TokenTree,Ident,Delimiter};
3
4#[proc_macro_derive(CrimtagMappable)]
5pub fn derive_crimtag_mappable(s: TokenStream) -> TokenStream {
6 let mut i = s.into_iter();
7 while let Some(t) = i.next() {
8 if let TokenTree::Ident(ident) = t &&
9 ident.to_string() == "struct" {
10 break;
11 }
12 }
13 let name = if let Some(TokenTree::Ident(ident)) = i.next() {
14 ident.to_string()
15 } else {
16 panic!("No name found in struct.");
17 };
18
19 // TODO: Expand this to include the generic parameters and the where? at
20 // least the parameters.
21 println!("struct name: {:?}", name);
22
23 let mut newfunc = format!(
24r#"impl<'a> crimtag::MappedStructure<'a> for {} {{
25 fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> {{
26 match id {{
27"#, name);
28
29 // We're going to cheat. Every field name is followed directly by a colon,
30 // so all we really need to do is hunt for colons and then take the
31 // previous item.
32
33 while let Some(n) = i.next() {
34 if let TokenTree::Group(g) = &n &&
35 g.delimiter() == Delimiter::Brace {
36 // Operate on the struct members.
37 let mut gi = g.stream().into_iter();
38 let mut cur = 0usize;
39 let mut tok = [gi.next(), gi.next()];
40 loop {
41 if let Some(TokenTree::Punct(ch)) = &tok[(cur+1)%2] &&
42 ch.as_char() == ':' &&
43 let Some(TokenTree::Ident(id)) = &tok[cur] {
44 println!("!!!!!!!!!! -> {}", id);
45 newfunc.push_str(&format!(
46r#" "{}" => Some(self.{}.into()),
47"#, id, id));
48 }
49 println!(" - {:?} {:?}", tok[cur], tok[(cur+1)%2] );
50 // Update next.
51 if let Some(ni) = gi.next() {
52 tok[cur].replace( ni );
53 cur = (cur+1)%2;
54 } else {
55 break;
56 }
57 }
58 }
59 }
60
61 newfunc.push_str(
62r#" _ => None,
63 }
64 }
65}"#);
66
67 println!();
68 println!();
69 println!("{}", newfunc);
70 println!();
71 println!();
72
73 newfunc.parse().unwrap()
74}
75