hyperi_rustlib/transport/grpc/config.rs
1// Project: hyperi-rustlib
2// File: src/transport/grpc/config.rs
3// Purpose: gRPC transport configuration
4// Language: Rust
5//
6// License: BUSL-1.1
7// Copyright: (c) 2026 HYPERI PTY LIMITED
8
9use serde::{Deserialize, Serialize};
10
11/// gRPC transport configuration.
12///
13/// Supports client mode (sending), server mode (receiving), or both.
14///
15/// # Client mode
16///
17/// Set `endpoint` to connect to a remote DFE gRPC server.
18///
19/// # Server mode
20///
21/// Set `listen` to accept incoming Push RPCs.
22///
23/// # Both
24///
25/// Set both for bidirectional communication (e.g., a relay node).
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(default)]
28pub struct GrpcConfig {
29 /// Server listen address (e.g., "0.0.0.0:6000").
30 /// When set, the transport accepts incoming Push RPCs.
31 pub listen: Option<String>,
32
33 /// Client endpoint URI (e.g., "http://dfe-loader:6000").
34 /// When set, the transport can send messages to a remote server.
35 pub endpoint: Option<String>,
36
37 /// Receive buffer size (messages buffered from incoming RPCs).
38 pub recv_buffer_size: usize,
39
40 /// Receive timeout in milliseconds (0 = non-blocking).
41 pub recv_timeout_ms: u64,
42
43 /// Maximum message size in bytes (both send and receive).
44 pub max_message_size: usize,
45
46 /// Enable gzip compression for gRPC messages.
47 pub compression: bool,
48
49 /// Enable Vector wire protocol compatibility on the same server.
50 /// When true, the server also accepts `/vector.Vector/PushEvents` RPCs
51 /// from legacy Vector sinks.
52 /// Requires the `transport-grpc-vector-compat` feature.
53 #[cfg(feature = "transport-grpc-vector-compat")]
54 pub vector_compat: bool,
55
56 /// Inbound message filters (applied on recv before caller sees messages).
57 pub filters_in: Vec<crate::transport::filter::FilterRule>,
58
59 /// Outbound message filters (applied on send before transport dispatches).
60 pub filters_out: Vec<crate::transport::filter::FilterRule>,
61}
62
63impl Default for GrpcConfig {
64 fn default() -> Self {
65 Self {
66 listen: None,
67 endpoint: None,
68 recv_buffer_size: 10_000,
69 recv_timeout_ms: 100,
70 max_message_size: 16 * 1024 * 1024, // 16 MB
71 compression: false,
72 #[cfg(feature = "transport-grpc-vector-compat")]
73 vector_compat: false,
74 filters_in: Vec::new(),
75 filters_out: Vec::new(),
76 }
77 }
78}
79
80impl GrpcConfig {
81 /// Load from the config cascade under the `grpc` key.
82 #[must_use]
83 pub fn from_cascade() -> Self {
84 #[cfg(feature = "config")]
85 {
86 if let Some(cfg) = crate::config::try_get()
87 && let Ok(grpc) = cfg.unmarshal_key_registered::<Self>("grpc")
88 {
89 return grpc;
90 }
91 }
92 Self::default()
93 }
94
95 /// Create a server-only config.
96 #[must_use]
97 pub fn server(listen: &str) -> Self {
98 Self {
99 listen: Some(listen.to_string()),
100 ..Default::default()
101 }
102 }
103
104 /// Create a client-only config.
105 #[must_use]
106 pub fn client(endpoint: &str) -> Self {
107 Self {
108 endpoint: Some(endpoint.to_string()),
109 ..Default::default()
110 }
111 }
112
113 /// Enable gzip compression.
114 #[must_use]
115 pub fn with_compression(mut self) -> Self {
116 self.compression = true;
117 self
118 }
119
120 /// Set max message size.
121 #[must_use]
122 pub fn with_max_message_size(mut self, size: usize) -> Self {
123 self.max_message_size = size;
124 self
125 }
126
127 /// Enable Vector wire protocol compatibility (feature-gated).
128 #[cfg(feature = "transport-grpc-vector-compat")]
129 #[must_use]
130 pub fn with_vector_compat(mut self) -> Self {
131 self.vector_compat = true;
132 self
133 }
134}