Skip to main content

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}