diff options
| author | Fuwn <[email protected]> | 2023-04-27 05:52:31 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2023-04-27 05:52:31 +0000 |
| commit | 2afebbc1f8fa218bb3eae271391b707d14778fc7 (patch) | |
| tree | ce226b86a871110dc86484a2fd9a01db4d501eae /rossweisse/src/implementations/router/fields.rs | |
| parent | docs(readme): add information about examples (diff) | |
| download | windmark-2afebbc1f8fa218bb3eae271391b707d14778fc7.tar.xz windmark-2afebbc1f8fa218bb3eae271391b707d14778fc7.zip | |
feat(rossweisse): initial implementation of struct router framework
Diffstat (limited to 'rossweisse/src/implementations/router/fields.rs')
| -rw-r--r-- | rossweisse/src/implementations/router/fields.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/rossweisse/src/implementations/router/fields.rs b/rossweisse/src/implementations/router/fields.rs new file mode 100644 index 0000000..e1a92b9 --- /dev/null +++ b/rossweisse/src/implementations/router/fields.rs @@ -0,0 +1,86 @@ +// This file is part of Windmark <https://github.com/gemrest/windmark>. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// Copyright (C) 2022-2023 Fuwn <[email protected]> +// SPDX-License-Identifier: GPL-3.0-only + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +pub fn fields(arguments: TokenStream, item: syn::ItemStruct) -> TokenStream { + let field_initializers = + parse_macro_input!(arguments as super::parser::FieldInitializers); + let router_identifier = item.ident; + let named_fields = match item.fields { + syn::Fields::Named(fields) => fields, + _ => + panic!( + "`#[rossweisse::router]` can only be used on `struct`s with named \ + fields" + ), + }; + let mut default_expressions = vec![]; + let new_method_fields = named_fields.named.iter().map(|field| { + let name = &field.ident; + let initialiser = field_initializers + .0 + .iter() + .find(|initialiser| initialiser.ident == name.clone().unwrap()) + .map(|initialiser| &initialiser.expr) + .unwrap_or_else(|| { + default_expressions.push({ + let default_expression: syn::Expr = + syn::parse_quote! { ::std::default::Default::default() }; + + default_expression + }); + + default_expressions.last().unwrap() + }); + + quote! { + #name: #initialiser, + } + }); + let new_methods = quote! { + fn _new() -> Self { + Self { + #(#new_method_fields)* + router: ::windmark::Router::new(), + } + } + + pub async fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> { + self.router.run().await + } + + pub fn router(&mut self) -> &mut ::windmark::Router { + &mut self.router + } + }; + let output_fields = named_fields.named; + let output = quote! { + struct #router_identifier { + #output_fields + router: ::windmark::Router, + } + + impl #router_identifier { + #new_methods + } + }; + + output.into() +} |