1use crate::RpcService;
2
3use core::fmt;
4
5const TAB: &str = " ";
6
7#[derive(Copy, Clone)]
8#[repr(transparent)]
9pub struct RpcMethodDefines<'a> {
11 pub service: &'a RpcService,
13}
14
15impl<'a> fmt::Display for RpcMethodDefines<'a> {
16 #[inline]
17 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
18 fmt.write_str("#[rustfmt::skip]\n")?;
19
20 for method in self.service.methods.iter() {
21 let method = method.name.as_str();
22 let name = method.to_uppercase();
23 fmt.write_fmt(format_args!("\npub const {name}: &str = \"{method}\";"))?;
24 }
25
26 Ok(())
27 }
28}
29
30#[derive(Copy, Clone)]
31pub struct RpcServiceImplDefines<'a> {
98 pub service: &'a RpcService,
100 pub extra_args: &'a [(&'a str, &'a str)],
107 pub on_invalid_request_cb: &'a str,
115 pub is_size_prefixed: bool,
119 pub default_message_limit: &'a str,
121}
122
123impl<'a> fmt::Display for RpcServiceImplDefines<'a> {
124 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
125 let (parse_method, finish_method) = if self.is_size_prefixed {
126 ("size_prefixed_root_with_opts", "finish_size_prefixed")
127 } else {
128 ("root_with_opts", "finish")
129 };
130 let default_message_limit = self.default_message_limit;
131 let on_invalid_request_cb = self.on_invalid_request_cb;
132
133 fmt.write_str("//Generated by flatbuffers-tools\n")?;
134
135 for method in self.service.methods.iter() {
136 let method = method.name.as_str();
137 fmt.write_fmt(format_args!("mod {method};\n"))?;
138 fmt.write_fmt(format_args!("pub use {method}::{method};\n"))?;
139 }
140
141 fmt.write_str("\n#[rustfmt::skip]\n")?;
143 fmt.write_str("pub async fn dispatch(")?;
144 for arg in self.extra_args.iter() {
145 let name = arg.0;
146 let typ = arg.1;
147 fmt.write_fmt(format_args!("{name}: {typ},"))?;
148 }
149 fmt.write_str("method: &str, input: &[u8], builder: &mut flatbuffers::FlatBufferBuilder<'_>) -> Option<Result<(), ()>> {\n")?;
150
151 for method in self.service.methods.iter() {
153 let define_name = method.name.to_uppercase();
155 let method = method.name.as_str();
156 fmt.write_fmt(format_args!(
157 "{TAB}const {define_name}: u128 = xxhash_rust::const_xxh3::xxh3_128(b\"{method}\");\n"
158 ))?;
159 }
160
161 fmt.write_fmt(format_args!(
163 r#"
164 const OPTIONS: flatbuffers::VerifierOptions = flatbuffers::VerifierOptions {{
165 max_depth: 64,
166 max_tables: 100,
167 max_apparent_size: {default_message_limit},
168 ignore_missing_null_terminator: false,
169 }};
170 "#
171 ))?;
172 fmt.write_fmt(format_args!(
174 "match xxhash_rust::xxh3::xxh3_128(method.as_bytes()) {{\n"
175 ))?;
176
177 for method in self.service.methods.iter() {
178 assert_eq!(
179 method.arguments.len(),
180 1,
181 "We require all RPC methods to have 1 argument"
182 );
183 let argument = &method.arguments[0];
184 let method = method.name.as_str();
185 let define_name = method.to_uppercase();
186 fmt.write_fmt(format_args!("{TAB}{TAB}{define_name} => match flatbuffers::{parse_method}::<crate::interface::{argument}>(&OPTIONS, input) {{\n"))?;
188 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}Ok(req) => match {method}(req, builder"))?;
190 for arg in self.extra_args.iter() {
192 let name = arg.0;
193 fmt.write_str(",")?;
194 fmt.write_str(name)?;
195 }
196 fmt.write_str(").await {\n")?;
198
199 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}Ok(response) => {{\n"))?;
201 fmt.write_fmt(format_args!(
202 "{TAB}{TAB}{TAB}{TAB}{TAB}let result = response.finish();\n"
203 ))?;
204 fmt.write_fmt(format_args!(
205 "{TAB}{TAB}{TAB}{TAB}{TAB}builder.{finish_method}(result, None);\n"
206 ))?;
207 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}{TAB}Some(Ok(()))\n"))?;
208 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}}}\n"))?;
209 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}Err(error) => {{\n"))?;
211 fmt.write_fmt(format_args!(
212 "{TAB}{TAB}{TAB}{TAB}{TAB}let result = error.to_interface(builder);\n"
213 ))?;
214 fmt.write_fmt(format_args!(
215 "{TAB}{TAB}{TAB}{TAB}{TAB}builder.{finish_method}(result, None);\n"
216 ))?;
217 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}{TAB}Some(Err(()))\n"))?;
218 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}{TAB}}}\n"))?;
219
220 fmt.write_fmt(format_args!("{TAB}{TAB}{TAB}}}\n"))?;
221 fmt.write_fmt(format_args!(
223 "{TAB}{TAB}{TAB}Err(error) => {on_invalid_request_cb}(builder, error),\n"
224 ))?;
225 fmt.write_fmt(format_args!("{TAB}{TAB}}}\n"))?;
226 }
227 fmt.write_fmt(format_args!("{TAB}{TAB}_ => None,\n"))?;
228 fmt.write_fmt(format_args!("{TAB}}}\n"))?;
229
230 fmt.write_str("}")
232 }
233}