diff --git a/example/src/application/simple.rs b/example/src/application/simple.rs index 1635cc2..d94236b 100644 --- a/example/src/application/simple.rs +++ b/example/src/application/simple.rs @@ -10,6 +10,10 @@ pub fn contacts() -> impl Stream> { futures::stream::iter(vec![Ok(data::Contact::default())]) } +/// +/// This is a docblock that was written in Rust and +/// will be added to the generated Dart code. +/// #[async_dart(namespace = "accounts")] pub async fn contact(user_id: String) -> Result { println!("async {:?}", thread::current().id()); diff --git a/membrane/src/generators/functions.rs b/membrane/src/generators/functions.rs index bd86557..fe99ef4 100644 --- a/membrane/src/generators/functions.rs +++ b/membrane/src/generators/functions.rs @@ -254,6 +254,7 @@ trait Callable { impl Callable for Ffi { fn begin(&mut self) -> &mut Self { self.output += &self.fun.begin(); + self.output += self.fun.docblock; self } @@ -434,6 +435,7 @@ impl Callable for Ffi { impl Callable for Web { fn begin(&mut self) -> &mut Self { self.output += &self.fun.begin(); + self.output += self.fun.docblock; self } diff --git a/membrane/src/lib.rs b/membrane/src/lib.rs index 6eab25e..86b4504 100644 --- a/membrane/src/lib.rs +++ b/membrane/src/lib.rs @@ -206,6 +206,7 @@ pub struct Function { pub dart_transforms: &'static str, pub dart_inner_args: &'static str, pub location: SourceCodeLocation, + pub docblock: &'static str, } #[doc(hidden)] diff --git a/membrane/tests/integration_tests.rs b/membrane/tests/integration_tests.rs index 6f29a9f..86d4dd5 100644 --- a/membrane/tests/integration_tests.rs +++ b/membrane/tests/integration_tests.rs @@ -58,11 +58,25 @@ mod test { let api = read_to_string(path.join("lib/src").join("accounts_ffi.dart")).unwrap(); assert!(api.contains("@immutable\nclass AccountsApi {")); - assert!(api.contains("Future contact({required String userId}) async {")); + assert_contains_part( + &api, + "/// +/// This is a docblock that was written in Rust and +/// will be added to the generated Dart code. +/// +Future contact({required String userId}) async {", + ); let web_api = read_to_string(path.join("lib/src").join("accounts_web.dart")).unwrap(); assert!(web_api.contains("@immutable\nclass AccountsApi {")); - assert!(web_api.contains("Future contact({required String userId}) async {")); + assert_contains_part( + &web_api, + "/// +/// This is a docblock that was written in Rust and +/// will be added to the generated Dart code. +/// +Future contact({required String userId}) async {", + ); let dart_type = read_to_string( path diff --git a/membrane_macro/src/lib.rs b/membrane_macro/src/lib.rs index 337f425..3945708 100644 --- a/membrane_macro/src/lib.rs +++ b/membrane_macro/src/lib.rs @@ -3,6 +3,7 @@ use membrane_types::c::CHeaderTypes; use membrane_types::dart::{DartArgs, DartParams, DartTransforms}; use membrane_types::heck::ToLowerCamelCase; use membrane_types::rust::{flatten_types, RustArgs, RustExternParams, RustTransforms}; +use membrane_types::syn::Attribute; use membrane_types::{proc_macro2, quote, syn, Input, OutputStyle}; use options::{extract_options, Options}; use proc_macro::TokenStream; @@ -23,12 +24,28 @@ struct ReprDart { output_style: OutputStyle, output: syn::Type, error: syn::Type, + docblock: String, } impl Parse for ReprDart { fn parse(input: ParseStream) -> Result { let arg_buffer; + let docblock = input + .call(Attribute::parse_outer)? + .iter() + .map(|x| Ok(x.meta.require_name_value()?)) + .map(|x: Result<&MetaNameValue>| Ok(x?.value.clone())) + .filter_map(|x: Result| match x { + Ok(syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(comment), + .. + })) => Some(Ok(format!("/// {}\n", &comment.value()))), + _ => None, + }) + .collect::>>()? + .join(""); + input.parse::()?; if input.peek(Token![async]) { input.parse::()?; @@ -50,6 +67,7 @@ impl Parse for ReprDart { output_style, output: ret_type, error: err_type, + docblock, }) } } @@ -144,6 +162,7 @@ fn to_token_stream( output, error, inputs, + docblock, .. } = repr_dart; @@ -367,6 +386,7 @@ fn to_token_stream( dart_inner_args: #dart_inner_args, output: "", location: #debug_location, + docblock: #docblock, }, namespace: #namespace, trace: |