Skip to main content

toolkit_contract/
descriptor.rs

1use serde::{Deserialize, Serialize};
2
3use crate::ir::contract::{Idempotency, MethodKind};
4
5/// Operational classification of a contract trait.
6///
7/// Encoded in the trait name suffix per PRD #1536 D2/D6:
8/// - `Api` — module **provides** the contract; remote-capable.
9/// - `Embedded` — module **provides** the contract; always in-process.
10/// - `Backend` — module **requires** the contract; remote-capable.
11/// - `Extension` — module **requires** the contract; always in-process.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13pub enum ContractKind {
14    /// Provided contract, remote-capable.
15    Api,
16    /// Provided contract, always local.
17    Embedded,
18    /// Required contract (consumed by the module), remote-capable.
19    Backend,
20    /// Required contract (consumed by the module), always local.
21    Extension,
22}
23
24impl ContractKind {
25    /// Whether this kind permits a transport projection (`*Rest`, `*Grpc`).
26    #[must_use]
27    pub const fn is_remote_capable(self) -> bool {
28        matches!(self, ContractKind::Api | ContractKind::Backend)
29    }
30
31    /// Human-readable name suitable for diagnostics and trait-suffix matching.
32    #[must_use]
33    pub const fn suffix(self) -> &'static str {
34        match self {
35            ContractKind::Api => "Api",
36            ContractKind::Embedded => "Embedded",
37            ContractKind::Backend => "Backend",
38            ContractKind::Extension => "Extension",
39        }
40    }
41}
42
43/// Compile-time static metadata for a contract.
44pub struct ContractDescriptor {
45    /// Gear name.
46    pub gear: &'static str,
47    /// Contract name, usually the SDK trait name.
48    pub contract: &'static str,
49    /// Compatibility service name for old service-hub call sites.
50    pub service: &'static str,
51    /// API version.
52    pub version: &'static str,
53    /// Operational classification of this contract.
54    pub kind: ContractKind,
55    /// Method descriptors for all methods in this contract.
56    pub methods: &'static [MethodDescriptor],
57}
58
59impl ContractDescriptor {
60    /// Compatibility accessor for old service-oriented call sites.
61    #[must_use]
62    pub const fn service(&self) -> &'static str {
63        self.service
64    }
65
66    /// Whether the contract permits remote dispatch.
67    #[must_use]
68    pub const fn is_remote_capable(&self) -> bool {
69        self.kind.is_remote_capable()
70    }
71}
72
73/// Static metadata for a single method within a contract.
74pub struct MethodDescriptor {
75    /// Method name.
76    pub name: &'static str,
77    /// Unary or streaming.
78    pub kind: MethodKind,
79    /// Idempotency classification for retry decisions.
80    pub idempotency: Idempotency,
81    /// Input type name for diagnostics and logging.
82    pub input_type: &'static str,
83    /// Output type name for diagnostics and logging.
84    pub output_type: &'static str,
85}
86
87pub type ServiceDescriptor = ContractDescriptor;