1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! RpcRequest trait for type-safe RPC calls
//!
//! This module defines the `RpcRequest` trait which associates RPC Request types with their
//! corresponding Response types. This enables compile-time type safety for client-side
//! RPC calls through type inference.
//!
//! # Design Rationale
//!
//! Without the RpcRequest trait, client code must manually:
//! 1. Encode the request into bytes
//! 2. Specify the route_key as a string (prone to typos)
//! 3. Manually decode the response (can use wrong type)
//!
//! With the RpcRequest trait, the framework can provide type-safe APIs:
//! ```rust,ignore
//! // Type-safe: compiler infers EchoResponse from EchoRequest::Response
//! let response: EchoResponse = ctx.call(target, request).await?;
//! ```
//!
//! # Implementation
//!
//! The RpcRequest trait is implemented by the code generator for each protobuf message
//! that represents an RPC request:
//!
//! ```rust,ignore
//! impl RpcRequest for EchoRequest {
//! type Response = EchoResponse;
//! }
//! ```
//!
//! # Placement in actr-protocol
//!
//! This trait is placed in actr-protocol (not actr-framework) because:
//! - It's a pure type-level association with no async methods
//! - It only depends on prost::Message and standard traits
//! - It can be independently tested without runtime dependencies
//! - It follows the "data definition layer" principle of actr-protocol
use Message as ProstMessage;
use cratePayloadType;
/// Associates an RPC Request type with its Response type for type-safe RPC calls.
///
/// This trait is only implemented for RPC request messages, not for:
/// - RPC response messages (EchoResponse, etc.)
/// - Streaming data (StreamChunk, MediaFrame)
/// - Other protobuf messages
///
/// # Type Safety
///
/// The RpcRequest trait enables the framework to provide compile-time guarantees that:
/// - The correct response type is used when decoding RPC responses
/// - Type inference works seamlessly for `ctx.call<R: RpcRequest>(...)` APIs
/// - Mismatched request/response pairs are caught at compile time
///
/// # Example
///
/// ```rust,ignore
/// use actr_protocol::RpcRequest;
/// use prost::Message as ProstMessage;
///
/// #[derive(Clone, PartialEq, ProstMessage)]
/// pub struct EchoRequest {
/// #[prost(string, tag = "1")]
/// pub message: String,
/// }
///
/// #[derive(Clone, PartialEq, ProstMessage)]
/// pub struct EchoResponse {
/// #[prost(string, tag = "1")]
/// pub reply: String,
/// }
///
/// // Generated by actr-cli codegen
/// impl RpcRequest for EchoRequest {
/// type Response = EchoResponse;
/// }
/// ```
///
/// # Usage in Client Code
///
/// ```rust,ignore
/// use actr_framework::Context;
///
/// async fn call_echo_service<C: Context>(
/// ctx: &C,
/// target: &Dest,
/// message: String
/// ) -> ActorResult<String> {
/// let request = EchoRequest { message };
///
/// // Type inference: compiler knows Response = EchoResponse
/// let response = ctx.call(target, request).await?;
///
/// Ok(response.reply)
/// }
/// ```