xmtp_proto/
proto_cache.rs1use prost::Message;
4use prost_types::{FileDescriptorSet, MethodDescriptorProto, ServiceDescriptorProto};
5use std::borrow::Cow;
6use std::collections::HashMap;
7use std::sync::LazyLock;
8
9type Cache = HashMap<(Cow<'static, str>, Cow<'static, str>), Cow<'static, str>>;
10
11pub static METHOD_LOOKUP: LazyLock<Cache> = LazyLock::new(|| {
13 let pnq = |package: &str,
14 service: &ServiceDescriptorProto,
15 method: &MethodDescriptorProto|
16 -> String {
17 String::new() + "/" + package + "." + service.name() + "/" + method.name()
18 };
19 let mut map = HashMap::new();
20 let descriptors: FileDescriptorSet =
21 Message::decode(crate::FILE_DESCRIPTOR_SET).expect("static decode must always succeed");
22 let mut dcs = descriptors.file.iter();
23 loop {
24 let Some(fd) = dcs.next() else {
25 break map;
26 };
27 let Some(ref package) = fd.package else {
28 continue;
29 };
30 for service in fd.service.iter() {
31 for method in service.method.iter() {
32 let Some(input_t) = method.input_type().split('.').next_back() else {
33 continue;
34 };
35 map.insert(
36 (Cow::Owned(package.clone()), Cow::Owned(input_t.to_string())),
37 Cow::Owned(pnq(package, service, method)),
38 );
39 }
40 }
41 }
42});
43
44pub fn path_and_query<Type: prost::Name>() -> Cow<'static, str> {
45 METHOD_LOOKUP
46 .get(&(Cow::Borrowed(Type::PACKAGE), Cow::Borrowed(Type::NAME)))
47 .cloned()
48 .unwrap_or(Cow::Owned(String::new()))
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[xmtp_common::test]
56 fn method_lookup() {
57 println!("{:#?}", METHOD_LOOKUP.iter().collect::<Vec<_>>());
58 }
59}