From c13e72a424f99504a32cbe4cb0ac86612ff84456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AsPulse=20/=20=E3=81=82=E3=81=99=E3=81=B1=E3=82=8B?= Date: Mon, 4 Nov 2024 20:13:56 +0900 Subject: [PATCH 1/5] identext --- servify_macro/src/util/ident_ext.rs | 12 ++++++++++++ servify_macro/src/util/mod.rs | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 servify_macro/src/util/ident_ext.rs diff --git a/servify_macro/src/util/ident_ext.rs b/servify_macro/src/util/ident_ext.rs new file mode 100644 index 0000000..5e3431c --- /dev/null +++ b/servify_macro/src/util/ident_ext.rs @@ -0,0 +1,12 @@ +use proc_macro2::Span; +use syn::Ident; + +pub(crate) trait IdentExt { + fn new_with_call_site(name: &str) -> Ident; +} + +impl IdentExt for Ident { + fn new_with_call_site(name: &str) -> Ident { + Ident::new(name, Span::call_site()) + } +} diff --git a/servify_macro/src/util/mod.rs b/servify_macro/src/util/mod.rs index b1f3fab..3dc489e 100644 --- a/servify_macro/src/util/mod.rs +++ b/servify_macro/src/util/mod.rs @@ -1,2 +1,3 @@ -pub mod return_type_ext; -pub mod type_path_ext; +pub(crate) mod ident_ext; +pub(crate) mod return_type_ext; +pub(crate) mod type_path_ext; From e1e9595ff7e8a306815e40afd7b031d1bd20c41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AsPulse=20/=20=E3=81=82=E3=81=99=E3=81=B1=E3=82=8B?= Date: Mon, 4 Nov 2024 20:14:07 +0900 Subject: [PATCH 2/5] generate module --- Cargo.lock | 65 +++++++++++++++++++ servify_macro/Cargo.toml | 2 + servify_macro/src/export_macro/mod.rs | 49 ++++++++++++++ ...o__tests__snapshot_export_all_written.snap | 5 ++ servify_macro/src/export_macro/tests.rs | 22 +++++++ servify_macro/src/lib.rs | 16 ++++- 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 servify_macro/src/export_macro/mod.rs create mode 100644 servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap create mode 100644 servify_macro/src/export_macro/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 7f2140d..6bf3894 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,24 +44,66 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys", +] + [[package]] name = "diff" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "gimli" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +[[package]] +name = "insta" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "similar", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "memchr" version = "2.7.4" @@ -120,6 +162,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rust-format" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e7c00b6c3bf5e38a880eec01d7e829d12ca682079f8238a464def3c4b31627" + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -140,12 +188,20 @@ name = "servify_macro" version = "0.1.0" dependencies = [ "case", + "insta", "pretty_assertions", "proc-macro2", "quote", + "rust-format", "syn", ] +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "syn" version = "2.0.77" @@ -185,6 +241,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" diff --git a/servify_macro/Cargo.toml b/servify_macro/Cargo.toml index 2f182a8..874c0a5 100644 --- a/servify_macro/Cargo.toml +++ b/servify_macro/Cargo.toml @@ -19,4 +19,6 @@ quote = "1.0.37" syn = { version = "2.0.77", features = ["full"] } [dev-dependencies] +insta = "1.41.1" pretty_assertions = "1.4.1" +rust-format = "0.3.4" diff --git a/servify_macro/src/export_macro/mod.rs b/servify_macro/src/export_macro/mod.rs new file mode 100644 index 0000000..0545f29 --- /dev/null +++ b/servify_macro/src/export_macro/mod.rs @@ -0,0 +1,49 @@ +mod tests; + +use proc_macro2::TokenStream; +use quote::quote; +use syn::parse::{Parse, ParseStream}; +use syn::{Ident, TypePath}; + +use crate::util::ident_ext::IdentExt as _; + +/// Represents the arguments of the `#[servify::export]` attribute. +pub(crate) struct ServifyExportArgs { + /// The path to the service module. + service_module: TypePath, +} + +impl Parse for ServifyExportArgs { + fn parse(input: ParseStream) -> syn::Result { + let service_module = input.parse()?; + Ok(Self { service_module }) + } +} + +/// Represents the `#[servify::export]` content. +pub(crate) struct ServifyExport { + fn_name: Ident, +} + +impl Parse for ServifyExport { + fn parse(input: ParseStream) -> syn::Result { + Ok(Self { + fn_name: input.parse()?, + }) + } +} + +impl ServifyExport { + pub(crate) fn to_tokens(self, args: ServifyExportArgs) -> TokenStream { + let ServifyExportArgs { service_module } = args; + let ServifyExport { fn_name } = self; + + let service_module_name = &service_module.path.segments.last().unwrap().ident; + + let mod_name = Ident::new_with_call_site(&format!("{service_module_name}_{fn_name}")); + + quote! { + mod #mod_name { } + } + } +} diff --git a/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap new file mode 100644 index 0000000..c6f699c --- /dev/null +++ b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap @@ -0,0 +1,5 @@ +--- +source: servify_macro/src/export_macro/tests.rs +expression: formatted +--- +mod counter_get {} diff --git a/servify_macro/src/export_macro/tests.rs b/servify_macro/src/export_macro/tests.rs new file mode 100644 index 0000000..91a0cf6 --- /dev/null +++ b/servify_macro/src/export_macro/tests.rs @@ -0,0 +1,22 @@ +#![cfg(test)] +use insta::assert_snapshot; +use quote::quote; +use rust_format::{Formatter, RustFmt}; + +use crate::export_macro::{ServifyExport, ServifyExportArgs}; + +#[test] +fn test_snapshot_export_all_written() { + let attr = quote! { super::counter }; + let input = quote! { get }; + + let args = syn::parse2::(attr).unwrap(); + let export = syn::parse2::(input).unwrap(); + + let generated = export.to_tokens(args).to_string(); + + let formatted = RustFmt::default() + .format_str(generated) + .expect("Failed to format"); + assert_snapshot!(formatted); +} diff --git a/servify_macro/src/lib.rs b/servify_macro/src/lib.rs index 83c8c0a..57db8bb 100644 --- a/servify_macro/src/lib.rs +++ b/servify_macro/src/lib.rs @@ -1 +1,15 @@ -mod util; +use proc_macro::TokenStream; + +use export_macro::ServifyExport; +use export_macro::ServifyExportArgs; + +pub(crate) mod export_macro; +pub(crate) mod util; + +#[proc_macro_attribute] +pub fn export(attr: TokenStream, item: TokenStream) -> TokenStream { + let attr = syn::parse_macro_input!(attr as ServifyExportArgs); + syn::parse_macro_input!(item as ServifyExport) + .to_tokens(attr) + .into() +} From 73cc0271f6e54268ba8177ebf414b4afc46fb032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AsPulse=20/=20=E3=81=82=E3=81=99=E3=81=B1=E3=82=8B?= Date: Mon, 4 Nov 2024 21:48:22 +0900 Subject: [PATCH 3/5] add errors and tests --- servify_macro/Cargo.toml | 1 + servify_macro/src/export_macro/args.rs | 10 +++ servify_macro/src/export_macro/errors.rs | 8 ++ servify_macro/src/export_macro/mod.rs | 76 +++++++++++-------- ...o__tests__snapshot_export_all_written.snap | 4 +- ...ests__snapshot_export_unwanted_struct.snap | 5 ++ servify_macro/src/export_macro/tests.rs | 65 +++++++++++++--- servify_macro/src/export_macro/to_token.rs | 24 ++++++ 8 files changed, 148 insertions(+), 45 deletions(-) create mode 100644 servify_macro/src/export_macro/args.rs create mode 100644 servify_macro/src/export_macro/errors.rs create mode 100644 servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_unwanted_struct.snap create mode 100644 servify_macro/src/export_macro/to_token.rs diff --git a/servify_macro/Cargo.toml b/servify_macro/Cargo.toml index 874c0a5..192f8ce 100644 --- a/servify_macro/Cargo.toml +++ b/servify_macro/Cargo.toml @@ -22,3 +22,4 @@ syn = { version = "2.0.77", features = ["full"] } insta = "1.41.1" pretty_assertions = "1.4.1" rust-format = "0.3.4" +thiserror = "1.0.67" diff --git a/servify_macro/src/export_macro/args.rs b/servify_macro/src/export_macro/args.rs new file mode 100644 index 0000000..d185ed1 --- /dev/null +++ b/servify_macro/src/export_macro/args.rs @@ -0,0 +1,10 @@ +use syn::parse::{Parse, ParseStream}; + +/// Represents the arguments of the `#[servify::export]` attribute. +pub(crate) struct ServifyExportArgs {} + +impl Parse for ServifyExportArgs { + fn parse(_input: ParseStream) -> syn::Result { + Ok(Self {}) + } +} diff --git a/servify_macro/src/export_macro/errors.rs b/servify_macro/src/export_macro/errors.rs new file mode 100644 index 0000000..0cc5c37 --- /dev/null +++ b/servify_macro/src/export_macro/errors.rs @@ -0,0 +1,8 @@ +pub(super) const ERR_MULTIPLE_FN_IN_EXPORT: &str = + "Within the servify::export macro, only one function can be exported in one impl block"; + +pub(super) const ERR_NO_FN_IN_EXPORT: &str = + "Within the servify::export macro, one function must be exported in one impl block"; + +pub(super) const ERR_UNEXPECTED_ITEM_IN_EXPORT: &str = + "Supported items within the servify::export macro are only exporting function, associated function, associated constants, and Request struct"; diff --git a/servify_macro/src/export_macro/mod.rs b/servify_macro/src/export_macro/mod.rs index 0545f29..a10f691 100644 --- a/servify_macro/src/export_macro/mod.rs +++ b/servify_macro/src/export_macro/mod.rs @@ -1,49 +1,61 @@ +mod args; +mod errors; mod tests; +mod to_token; -use proc_macro2::TokenStream; -use quote::quote; +use proc_macro2::Span; use syn::parse::{Parse, ParseStream}; -use syn::{Ident, TypePath}; +use syn::{braced, Ident, ImplItemFn, Token, TypePath}; -use crate::util::ident_ext::IdentExt as _; +use crate::export_macro::errors::{ + ERR_MULTIPLE_FN_IN_EXPORT, ERR_NO_FN_IN_EXPORT, ERR_UNEXPECTED_ITEM_IN_EXPORT, +}; -/// Represents the arguments of the `#[servify::export]` attribute. -pub(crate) struct ServifyExportArgs { - /// The path to the service module. - service_module: TypePath, -} - -impl Parse for ServifyExportArgs { - fn parse(input: ParseStream) -> syn::Result { - let service_module = input.parse()?; - Ok(Self { service_module }) - } -} +pub(crate) use self::args::ServifyExportArgs; /// Represents the `#[servify::export]` content. pub(crate) struct ServifyExport { + service_module_path: TypePath, + fn_item: ImplItemFn, fn_name: Ident, } impl Parse for ServifyExport { fn parse(input: ParseStream) -> syn::Result { - Ok(Self { - fn_name: input.parse()?, - }) - } -} - -impl ServifyExport { - pub(crate) fn to_tokens(self, args: ServifyExportArgs) -> TokenStream { - let ServifyExportArgs { service_module } = args; - let ServifyExport { fn_name } = self; - - let service_module_name = &service_module.path.segments.last().unwrap().ident; + let content; + let mut fn_item = None; + + // Parse head impl block + let _: Token![impl] = input.parse()?; + let module_path: TypePath = input.parse()?; + braced!(content in input); + + // Parse all items in the export block + while !content.is_empty() { + if let Ok(item) = content.parse::() { + if fn_item.is_some() { + return Err(syn::Error::new_spanned(item, ERR_MULTIPLE_FN_IN_EXPORT)); + } + + fn_item.replace(item); + continue; + } + + // Error if there is any other item in the export block + return Err(syn::Error::new_spanned( + content.parse::()?, + ERR_UNEXPECTED_ITEM_IN_EXPORT, + )); + } - let mod_name = Ident::new_with_call_site(&format!("{service_module_name}_{fn_name}")); + // Ensure that there is a function in the export block + let fn_item = + fn_item.ok_or_else(|| syn::Error::new(Span::call_site(), ERR_NO_FN_IN_EXPORT))?; - quote! { - mod #mod_name { } - } + Ok(Self { + service_module_path: module_path, + fn_name: fn_item.sig.ident.clone(), + fn_item, + }) } } diff --git a/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap index c6f699c..774040f 100644 --- a/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap +++ b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_all_written.snap @@ -1,5 +1,5 @@ --- source: servify_macro/src/export_macro/tests.rs -expression: formatted +expression: "test(quote! {},\n quote! {\n impl super::counter\n {\n pub fn increment(&mut self, amount: u32) -> u32\n { self.count += amount; self.amount }\n }\n }).unwrap()" --- -mod counter_get {} +mod counter_increment {} diff --git a/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_unwanted_struct.snap b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_unwanted_struct.snap new file mode 100644 index 0000000..3242da1 --- /dev/null +++ b/servify_macro/src/export_macro/snapshots/servify_macro__export_macro__tests__snapshot_export_unwanted_struct.snap @@ -0,0 +1,5 @@ +--- +source: servify_macro/src/export_macro/tests.rs +expression: "test(quote! {},\n quote! {\n impl super::counter\n {\n pub fn increment(&mut self, amount: u32) -> u32\n { self.count += amount; self.amount } struct\n ThisMustBeUnexpected {};\n }\n }).unwrap_err()" +--- +Failed to parse item: :: core :: compile_error ! { "Supported items within the servify::export macro are only exporting function, associated function, associated constants, and Request struct" } diff --git a/servify_macro/src/export_macro/tests.rs b/servify_macro/src/export_macro/tests.rs index 91a0cf6..8c8a21b 100644 --- a/servify_macro/src/export_macro/tests.rs +++ b/servify_macro/src/export_macro/tests.rs @@ -1,22 +1,65 @@ #![cfg(test)] use insta::assert_snapshot; +use proc_macro2::TokenStream; use quote::quote; use rust_format::{Formatter, RustFmt}; +use thiserror::Error; use crate::export_macro::{ServifyExport, ServifyExportArgs}; -#[test] -fn test_snapshot_export_all_written() { - let attr = quote! { super::counter }; - let input = quote! { get }; +#[derive(Debug, Error)] +enum Error { + #[error("Failed to parse args: {0}")] + ParseArgs(TokenStream), + #[error("Failed to parse item: {0}")] + ParseItem(TokenStream), + #[error("Failed to format: {0}")] + RustFmt(#[from] rust_format::Error), +} + +fn test(args: TokenStream, item: TokenStream) -> Result { + let args = syn::parse2::(args) + .map_err(|e| e.to_compile_error()) + .map_err(Error::ParseArgs)?; + let item = syn::parse2::(item) + .map_err(|e| e.to_compile_error()) + .map_err(Error::ParseItem)?; + + let generated = item.to_tokens(args).to_string(); - let args = syn::parse2::(attr).unwrap(); - let export = syn::parse2::(input).unwrap(); + let formatted = RustFmt::default().format_str(generated)?; + Ok(formatted) +} - let generated = export.to_tokens(args).to_string(); +#[test] +fn test_snapshot_export_all_written() { + assert_snapshot!(test( + quote! {}, + quote! { + impl super::counter { + pub fn increment(&mut self, amount: u32) -> u32 { + self.count += amount; + self.amount + } + } + } + ) + .unwrap()); +} - let formatted = RustFmt::default() - .format_str(generated) - .expect("Failed to format"); - assert_snapshot!(formatted); +#[test] +fn test_snapshot_export_unwanted_struct() { + assert_snapshot!(test( + quote! {}, + quote! { + impl super::counter { + pub fn increment(&mut self, amount: u32) -> u32 { + self.count += amount; + self.amount + } + struct ThisMustBeUnexpected { }; + } + } + ) + .unwrap_err()); } diff --git a/servify_macro/src/export_macro/to_token.rs b/servify_macro/src/export_macro/to_token.rs new file mode 100644 index 0000000..6e36b84 --- /dev/null +++ b/servify_macro/src/export_macro/to_token.rs @@ -0,0 +1,24 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::Ident; + +use crate::util::ident_ext::IdentExt as _; + +use super::{ServifyExport, ServifyExportArgs}; + +impl ServifyExport { + pub(crate) fn to_tokens(self, args: ServifyExportArgs) -> TokenStream { + let ServifyExport { + service_module_path, + fn_item, + fn_name, + } = self; + + let service_name = &service_module_path.path.segments.last().unwrap().ident; + let mod_name = Ident::new_with_call_site(&format!("{service_name}_{fn_name}")); + + quote! { + mod #mod_name { } + } + } +} From 5e27446c4c49358cdfbf4404c88f08ed2e3f766a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AsPulse=20/=20=E3=81=82=E3=81=99=E3=81=B1=E3=82=8B?= Date: Mon, 4 Nov 2024 22:00:32 +0900 Subject: [PATCH 4/5] fix error message --- Cargo.lock | 25 ++++++++++++++++++++++-- servify_macro/src/export_macro/errors.rs | 6 +++--- servify_macro/src/export_macro/mod.rs | 2 ++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bf3894..95b7a9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,6 +194,7 @@ dependencies = [ "quote", "rust-format", "syn", + "thiserror", ] [[package]] @@ -204,15 +205,35 @@ checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio" version = "1.40.0" diff --git a/servify_macro/src/export_macro/errors.rs b/servify_macro/src/export_macro/errors.rs index 0cc5c37..080145a 100644 --- a/servify_macro/src/export_macro/errors.rs +++ b/servify_macro/src/export_macro/errors.rs @@ -1,8 +1,8 @@ pub(super) const ERR_MULTIPLE_FN_IN_EXPORT: &str = - "Within the servify::export macro, only one function can be exported in one impl block"; + "Only one function can be exported in one impl block with servify::export"; pub(super) const ERR_NO_FN_IN_EXPORT: &str = - "Within the servify::export macro, one function must be exported in one impl block"; + "One function must be exported in one impl block with servify::export"; pub(super) const ERR_UNEXPECTED_ITEM_IN_EXPORT: &str = - "Supported items within the servify::export macro are only exporting function, associated function, associated constants, and Request struct"; + "Supported items are only exporting function, associated function, associated constants, and Request struct"; diff --git a/servify_macro/src/export_macro/mod.rs b/servify_macro/src/export_macro/mod.rs index a10f691..851b787 100644 --- a/servify_macro/src/export_macro/mod.rs +++ b/servify_macro/src/export_macro/mod.rs @@ -52,6 +52,8 @@ impl Parse for ServifyExport { let fn_item = fn_item.ok_or_else(|| syn::Error::new(Span::call_site(), ERR_NO_FN_IN_EXPORT))?; + // TODO: combine multiple error + Ok(Self { service_module_path: module_path, fn_name: fn_item.sig.ident.clone(), From bcadb837036d7d82caa7c080cbc533412637cced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AsPulse=20/=20=E3=81=82=E3=81=99=E3=81=B1=E3=82=8B?= Date: Mon, 4 Nov 2024 22:16:40 +0900 Subject: [PATCH 5/5] fix typo --- servify_macro/src/export_macro/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servify_macro/src/export_macro/errors.rs b/servify_macro/src/export_macro/errors.rs index 080145a..896621c 100644 --- a/servify_macro/src/export_macro/errors.rs +++ b/servify_macro/src/export_macro/errors.rs @@ -5,4 +5,4 @@ pub(super) const ERR_NO_FN_IN_EXPORT: &str = "One function must be exported in one impl block with servify::export"; pub(super) const ERR_UNEXPECTED_ITEM_IN_EXPORT: &str = - "Supported items are only exporting function, associated function, associated constants, and Request struct"; + "Supported items are only exporting function, associated function, associated constants, and Request struct";