From e619345766e98578929061e566178010c171df48 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 22 Dec 2016 13:49:53 +0100 Subject: [PATCH] Initial stab at macros 1.1 --- .gitignore | 2 ++ Cargo.toml | 2 ++ askama/Cargo.toml | 8 ++++++++ askama/src/lib.rs | 26 ++++++++++++++++++++++++++ askama_codegen/Cargo.toml | 11 +++++++++++ askama_codegen/src/lib.rs | 31 +++++++++++++++++++++++++++++++ askama_test/Cargo.toml | 9 +++++++++ askama_test/tests/simple.rs | 18 ++++++++++++++++++ 8 files changed, 107 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 askama/Cargo.toml create mode 100644 askama/src/lib.rs create mode 100644 askama_codegen/Cargo.toml create mode 100644 askama_codegen/src/lib.rs create mode 100644 askama_test/Cargo.toml create mode 100644 askama_test/tests/simple.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..3f15138ad --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["askama", "askama_codegen", "askama_test"] diff --git a/askama/Cargo.toml b/askama/Cargo.toml new file mode 100644 index 000000000..4cbfbe117 --- /dev/null +++ b/askama/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "askama" +version = "0.1.0" +authors = ["Dirkjan Ochtman "] +workspace = ".." + +[dependencies] +askama_codegen = { path = "../askama_codegen" } diff --git a/askama/src/lib.rs b/askama/src/lib.rs new file mode 100644 index 000000000..93b785476 --- /dev/null +++ b/askama/src/lib.rs @@ -0,0 +1,26 @@ +#![feature(proc_macro)] + +#[macro_use] +extern crate askama_codegen; + +pub trait Template { + fn render(&self) -> String; +} + +#[cfg(test)] +mod tests { + + extern crate askama; + + #[derive(Template)] + struct TestTemplate { + var: String, + } + + #[test] + fn it_works() { + let s = TestTemplate { var: "foo".to_string() }.render(); + assert_eq!(s, "hello world, foo"); + } + +} diff --git a/askama_codegen/Cargo.toml b/askama_codegen/Cargo.toml new file mode 100644 index 000000000..29043aa99 --- /dev/null +++ b/askama_codegen/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "askama_codegen" +version = "0.1.0" +authors = ["Dirkjan Ochtman "] + +[dependencies] +syn = "0.10" +quote = "0.3" + +[lib] +proc-macro = true diff --git a/askama_codegen/src/lib.rs b/askama_codegen/src/lib.rs new file mode 100644 index 000000000..6d7170ebe --- /dev/null +++ b/askama_codegen/src/lib.rs @@ -0,0 +1,31 @@ +#![feature(proc_macro, proc_macro_lib)] + +extern crate proc_macro; +#[macro_use] +extern crate quote; +extern crate syn; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Template, attributes(template))] +pub fn derive_template(input: TokenStream) -> TokenStream { + let source = input.to_string(); + + let ast = syn::parse_macro_input(&source).unwrap(); + let _ctx = match ast.body { + syn::Body::Struct(ref data) => data, + _ => panic!("#[derive(Template)] can only be used with structs"), + }; + + let name = &ast.ident; + let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); + let expanded = quote! { + impl #impl_generics askama::Template for #name #ty_generics #where_clause { + fn render(&self) -> String { + "hello world, bar".to_string() + } + } + }; + + expanded.parse().unwrap() +} diff --git a/askama_test/Cargo.toml b/askama_test/Cargo.toml new file mode 100644 index 000000000..8d01793f5 --- /dev/null +++ b/askama_test/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "askama_test" +version = "0.1.0" +authors = ["Dirkjan Ochtman "] +workspace = ".." + +[dependencies] +askama_codegen = { path = "../askama_codegen" } +askama = { path = "../askama" } diff --git a/askama_test/tests/simple.rs b/askama_test/tests/simple.rs new file mode 100644 index 000000000..f7beb806a --- /dev/null +++ b/askama_test/tests/simple.rs @@ -0,0 +1,18 @@ +#![feature(proc_macro)] + +#[macro_use] +extern crate askama_codegen; +extern crate askama; + +use askama::Template; + +#[derive(Template)] +struct TestTemplate { + var: String, +} + +#[test] +fn it_works() { + let s = TestTemplate { var: "foo".to_string() }.render(); + assert_eq!(s, "hello world, foo"); +}