quix_build/
lib.rs

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            // TODO: Fix this crap
24            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