🏗️ Elegant & Highly Performant Async Gemini Server Framework for the Modern Age
async framework gemini-protocol protocol gemini rust
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(rossweisse): initial implementation of struct router framework

Fuwn 2afebbc1 7488876b

+472
+6
Cargo.toml
··· 1 1 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 2 2 3 + [workspace] 4 + members = ["rossweisse"] 5 + 3 6 [package] 4 7 name = "windmark" 5 8 version = "0.3.6" ··· 45 48 tree_magic = { version = "0.2.3", optional = true } # MIME 46 49 47 50 paste = "1.0.12" # Token Pasting 51 + 52 + [dev-dependencies] 53 + rossweisse = { version = "*", path = "./rossweisse" }
+3
Makefile.toml
··· 1 + [config] 2 + default_to_workspace = false 3 + 1 4 [tasks.fmt] 2 5 args = ["fmt"] 3 6 command = "cargo"
+49
examples/struct_router.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + //! `cargo run --example struct_router` 19 + 20 + use rossweisse::route; 21 + 22 + #[rossweisse::router] 23 + struct Router { 24 + _phantom: (), 25 + } 26 + 27 + #[rossweisse::router] 28 + impl Router { 29 + #[route] 30 + pub fn index( 31 + _context: windmark::context::RouteContext, 32 + ) -> windmark::Response { 33 + windmark::Response::success("Hello, World!") 34 + } 35 + } 36 + 37 + #[windmark::main] 38 + async fn main() -> Result<(), Box<dyn std::error::Error>> { 39 + { 40 + let mut router = Router::new(); 41 + 42 + router.router().set_private_key_file("windmark_private.pem"); 43 + router.router().set_certificate_file("windmark_public.pem"); 44 + 45 + router 46 + } 47 + .run() 48 + .await 49 + }
+16
rossweisse/Cargo.toml
··· 1 + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 2 + 3 + [package] 4 + name = "rossweisse" 5 + version = "0.0.0" 6 + authors = ["Fuwn <contact@fuwn.me>"] 7 + edition = "2021" 8 + license = "GPL-3.0-only" 9 + 10 + [lib] 11 + proc-macro = true 12 + 13 + [dependencies] 14 + quote = "1.0.26" # Quasi-quoting 15 + syn = "2.0.15" # Source Code Parsing 16 + proc-macro2 = "1.0.56" # `proc-macro` Wrapper
+22
rossweisse/src/implementations.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + mod route; 19 + mod router; 20 + 21 + pub use route::route; 22 + pub use router::{fields, methods};
+22
rossweisse/src/implementations/route.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + use proc_macro::TokenStream; 19 + 20 + pub fn route(_arguments: TokenStream, item: syn::ItemFn) -> TokenStream { 21 + quote::quote! { #item }.into() 22 + }
+23
rossweisse/src/implementations/router.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + mod fields; 19 + mod methods; 20 + mod parser; 21 + 22 + pub use fields::fields; 23 + pub use methods::methods;
+86
rossweisse/src/implementations/router/fields.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + use proc_macro::TokenStream; 19 + use quote::quote; 20 + use syn::parse_macro_input; 21 + 22 + pub fn fields(arguments: TokenStream, item: syn::ItemStruct) -> TokenStream { 23 + let field_initializers = 24 + parse_macro_input!(arguments as super::parser::FieldInitializers); 25 + let router_identifier = item.ident; 26 + let named_fields = match item.fields { 27 + syn::Fields::Named(fields) => fields, 28 + _ => 29 + panic!( 30 + "`#[rossweisse::router]` can only be used on `struct`s with named \ 31 + fields" 32 + ), 33 + }; 34 + let mut default_expressions = vec![]; 35 + let new_method_fields = named_fields.named.iter().map(|field| { 36 + let name = &field.ident; 37 + let initialiser = field_initializers 38 + .0 39 + .iter() 40 + .find(|initialiser| initialiser.ident == name.clone().unwrap()) 41 + .map(|initialiser| &initialiser.expr) 42 + .unwrap_or_else(|| { 43 + default_expressions.push({ 44 + let default_expression: syn::Expr = 45 + syn::parse_quote! { ::std::default::Default::default() }; 46 + 47 + default_expression 48 + }); 49 + 50 + default_expressions.last().unwrap() 51 + }); 52 + 53 + quote! { 54 + #name: #initialiser, 55 + } 56 + }); 57 + let new_methods = quote! { 58 + fn _new() -> Self { 59 + Self { 60 + #(#new_method_fields)* 61 + router: ::windmark::Router::new(), 62 + } 63 + } 64 + 65 + pub async fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> { 66 + self.router.run().await 67 + } 68 + 69 + pub fn router(&mut self) -> &mut ::windmark::Router { 70 + &mut self.router 71 + } 72 + }; 73 + let output_fields = named_fields.named; 74 + let output = quote! { 75 + struct #router_identifier { 76 + #output_fields 77 + router: ::windmark::Router, 78 + } 79 + 80 + impl #router_identifier { 81 + #new_methods 82 + } 83 + }; 84 + 85 + output.into() 86 + }
+66
rossweisse/src/implementations/router/methods.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + use proc_macro::TokenStream; 19 + 20 + pub fn methods(_arguments: TokenStream, item: syn::ItemImpl) -> TokenStream { 21 + let routes = item 22 + .items 23 + .iter() 24 + .filter_map(|item| { 25 + if let syn::ImplItem::Fn(method) = item { 26 + if method 27 + .attrs 28 + .iter() 29 + .any(|attribute| attribute.path().is_ident("route")) 30 + { 31 + Some(method.sig.ident.clone()) 32 + } else { 33 + None 34 + } 35 + } else { 36 + None 37 + } 38 + }) 39 + .collect::<Vec<_>>(); 40 + let (implementation_generics, type_generics, where_clause) = 41 + item.generics.split_for_impl(); 42 + let name = &item.self_ty; 43 + let route_paths = routes 44 + .iter() 45 + .map(|route| format!("/{}", route)) 46 + .collect::<Vec<_>>(); 47 + 48 + quote::quote! { 49 + #item 50 + 51 + impl #implementation_generics #name #type_generics #where_clause { 52 + pub fn new() -> Self { 53 + let mut router = Self::_new(); 54 + 55 + #( 56 + router.router.mount(#route_paths, |context| { 57 + Self::#routes(context) 58 + }); 59 + )* 60 + 61 + router 62 + } 63 + } 64 + } 65 + .into() 66 + }
+21
rossweisse/src/implementations/router/parser.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + mod field_initializer; 19 + mod field_initializers; 20 + 21 + pub use field_initializers::FieldInitializers;
+39
rossweisse/src/implementations/router/parser/field_initializer.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + use syn::parse; 19 + 20 + pub struct FieldInitializer { 21 + pub ident: syn::Ident, 22 + #[allow(unused)] 23 + eq_token: syn::Token![=], 24 + pub expr: syn::Expr, 25 + } 26 + 27 + impl parse::Parse for FieldInitializer { 28 + fn parse(input: parse::ParseStream<'_>) -> syn::Result<Self> { 29 + let ident = input.parse()?; 30 + let eq_token = input.parse()?; 31 + let expr = input.parse()?; 32 + 33 + Ok(Self { 34 + ident, 35 + eq_token, 36 + expr, 37 + }) 38 + } 39 + }
+28
rossweisse/src/implementations/router/parser/field_initializers.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + use syn::parse; 19 + 20 + use super::field_initializer::FieldInitializer; 21 + 22 + pub struct FieldInitializers(pub Vec<FieldInitializer>); 23 + 24 + impl parse::Parse for FieldInitializers { 25 + fn parse(input: parse::ParseStream<'_>) -> syn::Result<Self> { 26 + Ok(Self(syn::punctuated::Punctuated::<FieldInitializer, syn::Token![,]>::parse_terminated(input)?.into_iter().collect())) 27 + } 28 + }
+91
rossweisse/src/lib.rs
··· 1 + // This file is part of Windmark <https://github.com/gemrest/windmark>. 2 + // 3 + // This program is free software: you can redistribute it and/or modify 4 + // it under the terms of the GNU General Public License as published by 5 + // the Free Software Foundation, version 3. 6 + // 7 + // This program is distributed in the hope that it will be useful, but 8 + // WITHOUT ANY WARRANTY; without even the implied warranty of 9 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 + // General Public License for more details. 11 + // 12 + // You should have received a copy of the GNU General Public License 13 + // along with this program. If not, see <http://www.gnu.org/licenses/>. 14 + // 15 + // Copyright (C) 2022-2023 Fuwn <contact@fuwn.me> 16 + // SPDX-License-Identifier: GPL-3.0-only 17 + 18 + #![deny( 19 + clippy::all, 20 + clippy::nursery, 21 + clippy::pedantic, 22 + future_incompatible, 23 + nonstandard_style, 24 + rust_2018_idioms, 25 + unsafe_code, 26 + unused, 27 + warnings 28 + )] 29 + #![recursion_limit = "128"] 30 + 31 + mod implementations; 32 + 33 + use proc_macro::TokenStream; 34 + use syn::Item; 35 + 36 + /// Marks a `struct` as a router or marks an `impl` block as a router 37 + /// implementation 38 + /// 39 + /// # Examples 40 + /// 41 + /// ```rust 42 + /// #[rossweisse::router] 43 + /// struct Router { 44 + /// _phantom: (), 45 + /// } 46 + /// 47 + /// #[rossweisse::router] 48 + /// impl Router { 49 + /// #[route] 50 + /// pub fn index( 51 + /// _context: windmark::context::RouteContext, 52 + /// ) -> windmark::Response { 53 + /// windmark::Response::success("Hello, World!") 54 + /// } 55 + /// } 56 + /// ``` 57 + #[proc_macro_attribute] 58 + pub fn router(arguments: TokenStream, item: TokenStream) -> TokenStream { 59 + let output = match syn::parse::<Item>(item.clone()) { 60 + Ok(Item::Struct(item)) => implementations::fields(arguments, item), 61 + Ok(Item::Impl(item)) => implementations::methods(arguments, item), 62 + _ => panic!("`#[rossweisse::router]` can only be used on `struct`s"), 63 + }; 64 + 65 + output.into() 66 + } 67 + 68 + /// Marks a method of a router implementation as a route to mount 69 + /// 70 + /// # Examples 71 + /// 72 + /// ```rust 73 + /// #[rossweisse::router] 74 + /// impl Router { 75 + /// #[route] 76 + /// pub fn index( 77 + /// _context: windmark::context::RouteContext, 78 + /// ) -> windmark::Response { 79 + /// windmark::Response::success("Hello, World!") 80 + /// } 81 + /// } 82 + /// ``` 83 + #[proc_macro_attribute] 84 + pub fn route(arguments: TokenStream, item: TokenStream) -> TokenStream { 85 + let output = match syn::parse::<Item>(item.clone()) { 86 + Ok(Item::Fn(item)) => implementations::route(arguments, item), 87 + _ => panic!("`#[rossweisse::route]` can only be used on `fn`s"), 88 + }; 89 + 90 + output.into() 91 + }