roam_types/services.rs
1use facet::{Facet, Shape};
2
3/// Static descriptor for a roam RPC service.
4///
5/// Contains the service name and all method descriptors. Built once per service
6/// via OnceLock in macro-generated code.
7pub struct ServiceDescriptor {
8 /// Service name (e.g., "Calculator").
9 pub service_name: &'static str,
10
11 /// All methods in this service.
12 pub methods: &'static [&'static MethodDescriptor],
13
14 /// Documentation string, if any.
15 pub doc: Option<&'static str>,
16}
17
18impl ServiceDescriptor {
19 /// Look up a method descriptor by method ID.
20 pub fn by_id(&self, method_id: MethodId) -> Option<&'static MethodDescriptor> {
21 self.methods.iter().find(|m| m.id == method_id).copied()
22 }
23}
24
25/// Static descriptor for a single RPC method.
26///
27/// Contains static metadata needed for dispatching and calling this method.
28pub struct MethodDescriptor {
29 /// Method ID (hash of service name, method name, arg shapes, return shape).
30 pub id: MethodId,
31
32 /// Service name (e.g., "Calculator").
33 pub service_name: &'static str,
34
35 /// Method name (e.g., "add").
36 pub method_name: &'static str,
37
38 /// Arguments in declaration order.
39 pub args: &'static [ArgDescriptor],
40
41 /// Return type shape.
42 pub return_shape: &'static Shape,
43
44 /// Documentation string, if any.
45 pub doc: Option<&'static str>,
46}
47
48impl std::fmt::Debug for MethodDescriptor {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 f.debug_struct("MethodDescriptor")
51 .field("id", &self.id)
52 .field("service_name", &self.service_name)
53 .field("method_name", &self.method_name)
54 .finish_non_exhaustive()
55 }
56}
57
58declare_id!(
59 /// A unique method identifier — hash of service name, method name, arg shapes, return shape
60 MethodId, u64
61);
62
63/// Descriptor for a single RPC method argument.
64///
65/// Contains metadata about an argument including its name, shape, and
66/// whether it's a channel type (Rx/Tx).
67#[derive(Debug)]
68pub struct ArgDescriptor {
69 /// Argument name (e.g., "user_id", "stream").
70 pub name: &'static str,
71
72 /// Argument type shape.
73 pub shape: &'static Shape,
74}
75
76impl ServiceDescriptor {
77 /// An empty service descriptor for dispatchers that don't serve any methods.
78 pub const EMPTY: ServiceDescriptor = ServiceDescriptor {
79 service_name: "<Empty>",
80 methods: &[],
81 doc: None,
82 };
83}