kanamaru_build/prost/
generator.rs1use proc_macro2::TokenStream;
2use prost_build::ServiceGenerator as SVCGen;
3use quote::ToTokens;
4
5use super::{codegen::CodegenResponderBuilder, ProstBuilder};
6
7pub struct ServiceGenerator {
8 builder: ProstBuilder,
9 responder: TokenStream,
10}
11
12impl ServiceGenerator {
13 pub fn new(builder: ProstBuilder) -> Self {
14 Self {
15 builder,
16 responder: TokenStream::new(),
17 }
18 }
19}
20
21impl SVCGen for ServiceGenerator {
22 fn generate(&mut self, service: prost_build::Service, _buf: &mut String) {
23 let responder = CodegenResponderBuilder {
24 service: &service,
25 emit_package: self.builder.emit_package,
26 proto_path: &self.builder.proto_path,
27 compile_well_known_types: self.builder.compile_well_known_types,
28 use_arc_self: self.builder.use_arc_self,
29 generate_default_stubs: self.builder.generate_default_stubs,
30 attributes: &self.builder.responder_attributes,
31 disabled_comments: &self.builder.disable_comments,
32 };
33
34 self.responder.extend(responder.into_token_stream());
35 }
36 fn finalize(&mut self, buf: &mut String) {
37 if !self.responder.is_empty() {
38 let responder = &self.responder;
39
40 let responder_service = quote::quote! {
41 #responder
42 };
43
44 let ast: syn::File = syn::parse2(responder_service).expect("not a valid tokenstream");
45 let code = prettyplease::unparse(&ast);
46 buf.push_str(&code);
47
48 self.responder = TokenStream::default();
49 }
50 }
51}