1#![feature(format_args_capture)]
2
3use std::fmt::Write;
4
5pub struct Generator;
6
7impl prost_build::ServiceGenerator for Generator {
8 fn generate(&mut self, service: Service, buf: &mut String) {
9 for m in service.methods {
10 eprintln!("{:?}", m);
11 let outtype = if m.output_proto_type == ".google.protobuf.Empty" {
12 "()".to_string()
13 } else {
14 format!("Result<{}, ()>", m.output_type)
15 };
16
17 let intype = if m.input_proto_type == ".google.protobuf.Empty" {
18 "()".to_string()
19 } else {
20 m.input_type
21 };
22
23 let (out_read, out_write) = if m.output_proto_type == ".google.protobuf.Empty" {
25 ("()".to_string(), "()".to_string())
26 } else {
27 (format!("Ok(<{}>::decode(b).unwrap())", m.output_type),
28 format!("let a: &{o} = res.as_ref().unwrap(); a.encode(b).unwrap()", o = m.output_type)
29 )
30 };
31
32
33 let svc_spec = format!("{}.{}.{}", service.package, service.name, m.name);
34 let svc_id = crc64::crc64(0, svc_spec.as_bytes());
35
36
37 write!(buf, r#"
38use quix::derive::*;
39pub struct {name}(pub {input});
40
41impl actix::Message for {name} {{
42 type Result = {res};
43}}
44
45impl quix::derive::Service for {name} {{
46 const NAME: &'static str = "{svc_spec}";
47 const ID: u64 = {svc_id};
48 fn write(&self, b: &mut impl bytes::BufMut) -> Result<(), ()> {{
49 prost::Message::encode(&self.0, b).map_err(|_| ())
50 }}
51 fn read(b: impl bytes::Buf) -> Result<Self, ()> {{
52 Ok(Self(prost::Message::decode(b).map_err(|_| ())?))
53 }}
54
55 fn read_result(b: impl bytes::Buf) -> Result<Self::Result, ()> {{
56 Ok({out_read})
57 }}
58
59 fn write_result(res: &Self::Result, b: &mut impl bytes::BufMut) -> Result<(), ()> {{
60 {out_write};
61 Ok(())
62 }}
63}}
64
65impl From<{input}> for {name} {{
66 fn from(a: {input}) -> Self {{
67 Self(a)
68 }}
69}}
70
71impl Into<{input}> for {name} {{
72 fn into(self) -> {input} {{
73 self.0
74 }}
75}}
76
77impl ::core::ops::Deref for {name} {{
78 type Target = {input};
79 fn deref(&self) -> &Self::Target {{
80 &self.0
81 }}
82}}
83impl ::core::ops::DerefMut for {name} {{
84 fn deref_mut(&mut self) -> &mut Self::Target {{
85 &mut self.0
86 }}
87}}
88 "#,
89 name = m.proto_name,
90 res = outtype,
91 input = intype
92 ).unwrap();
93 }
94 }
95}
96
97pub use prost_build::*;
98