diff --git a/Cargo.lock b/Cargo.lock index 96211a0..4e5ce2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -972,6 +972,15 @@ dependencies = [ "tengri_tui", ] +[[package]] +name = "tengri_proc" +version = "0.13.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tengri_tui" version = "0.13.0" diff --git a/Cargo.toml b/Cargo.toml index daeb8ce..4a6d408 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace.package] version = "0.13.0" +edition = "2024" [workspace] resolver = "2" @@ -8,7 +9,8 @@ members = [ "./input", "./output", "./tui", - "./dsl" + "./dsl", + "./proc", ] [profile.release] diff --git a/dsl/Cargo.toml b/dsl/Cargo.toml index 94238a8..3609ada 100644 --- a/dsl/Cargo.toml +++ b/dsl/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tengri_dsl" -edition = "2024" description = "UI metaframework, tiny S-expression-based DSL." version = { workspace = true } +edition = { workspace = true } [dependencies] konst = { version = "0.3.16", features = [ "rust_1_83" ] } diff --git a/input/Cargo.toml b/input/Cargo.toml index a3ca0ce..3b7772f 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tengri_input" -edition = "2024" description = "UI metaframework, input layer." version = { workspace = true } +edition = { workspace = true } [dependencies] tengri_dsl = { optional = true, path = "../dsl" } diff --git a/output/Cargo.toml b/output/Cargo.toml index b208a5b..2505df5 100644 --- a/output/Cargo.toml +++ b/output/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tengri_output" -edition = "2024" description = "UI metaframework, output layer." version = { workspace = true } +edition = { workspace = true } [dependencies] tengri_dsl = { optional = true, path = "../dsl" } diff --git a/proc/Cargo.toml b/proc/Cargo.toml new file mode 100644 index 0000000..2462993 --- /dev/null +++ b/proc/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "tengri_proc" +description = "UI metaframework, procedural macros." +version = { workspace = true } +edition = { workspace = true } + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "2", features = ["full"] } +quote = { version = "1" } +proc-macro2 = { version = "1", features = ["span-locations"] } diff --git a/proc/src/lib.rs b/proc/src/lib.rs new file mode 100644 index 0000000..0709e4b --- /dev/null +++ b/proc/src/lib.rs @@ -0,0 +1,26 @@ +extern crate proc_macro; +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2}; + +mod proc_view; + +#[proc_macro_attribute] +pub fn view (meta: TokenStream, item: TokenStream) -> TokenStream { + self::proc_view::view_impl(meta.into(), item.into()).into() + //for attr in syn::parse_macro_input!(meta as syn::MetaList).iter() { + //} + //let item = syn::parse_macro_input!(item as syn::ItemImpl); + //let output = "TuiOut"; + //let target = "Tek"; + //let define = "self.config.view"; + //let expose = vec![]; + //let output = format!( + //"::tengri_dsl::view!({}:|self:{}|self.size.of(::tengri_dsl::View(self,{}));{{{}}});", + //output, + //target, + //define, + //expose.iter().fold(String::new(), |acc, (key, value)|format!("{acc},{key}=>{value}")), + //); + //let output = ""; + //output.parse().unwrap() +} diff --git a/proc/src/proc_view.rs b/proc/src/proc_view.rs new file mode 100644 index 0000000..b9737d1 --- /dev/null +++ b/proc/src/proc_view.rs @@ -0,0 +1,80 @@ +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2}; + +pub(crate) fn view_impl (meta: TokenStream, item: TokenStream) -> TokenStream { + let ViewMeta { output, define, attrs } = syn::parse_macro_input!(meta as ViewMeta); + let ViewItem { target, mapped, items } = syn::parse_macro_input!(item as ViewItem); + quote::quote! { + #attrs + impl #target { + #items + } + impl ::tengri::Content<#output> for #target { + fn content (&self) -> impl Render<#output> { + self.size.of(::tengri::View(self, #define)) + } + } + impl<'a> ::tengri::ViewContext<'a, #output> for #target { + fn get_content_sym (&'a self, value: &Value<'a>) -> Option> { + match value { + #mapped + _ => panic!("expected Sym(content), got: {value:?}") + } + //if let Value::Sym(s) = value { + //match *s { + //$($sym => Some($body.boxed()),)* + //_ => None + //} + //} else { + //panic!("expected Sym(content), got: {value:?}") + //} + } + } + }.into() +} + +struct ViewMeta { + attrs: &'static str, + output: &'static str, + define: &'static str, +} + +impl syn::parse::Parse for ViewMeta { + fn parse (input: syn::parse::ParseStream) -> syn::parse::Result { + Ok(Self { + attrs: "", + output: "", + define: "", + }) + } +} + +struct ViewItem { + items: &'static str, + target: &'static str, + mapped: &'static str, +} + +impl syn::parse::Parse for ViewItem { + fn parse (input: syn::parse::ParseStream) -> syn::parse::Result { + Ok(Self { + items: "", + target: "", + mapped: "", + }) + } +} + +#[cfg(test)] #[test] fn test_view () { + + let _: syn::ItemImpl = syn::parse_quote! { + #[tengri::view(Tui)] + impl SomeView { + #[tengri::view(":view")] + fn view (&self) -> impl Content + use<'_> { + "view" + } + } + }; + +} diff --git a/tui/Cargo.toml b/tui/Cargo.toml index e005d37..5bf0dc2 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tengri_tui" -edition = "2024" description = "UI metaframework, Ratatui backend." version = { workspace = true } +edition = { workspace = true } [dependencies] palette = { version = "0.7.6", features = [ "random" ] }