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