Skip to main content

platform_module_remote/
config.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct RemoteModuleConfig {
3    pub name: String,
4    pub base_url: String,
5    pub transport: RemoteModuleTransport,
6    pub auth_token: Option<String>,
7    pub timeout_ms: u64,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum RemoteModuleTransport {
12    HttpJson,
13    Grpc,
14}
15
16impl RemoteModuleConfig {
17    #[must_use]
18    pub fn new(name: impl Into<String>, base_url: impl Into<String>) -> Self {
19        let (transport, base_url) = normalize_base_url(base_url.into());
20        Self {
21            name: name.into(),
22            base_url,
23            transport,
24            auth_token: None,
25            timeout_ms: 5_000,
26        }
27    }
28
29    #[must_use]
30    pub fn with_auth_token(mut self, token: impl Into<String>) -> Self {
31        self.auth_token = Some(token.into());
32        self
33    }
34
35    #[must_use]
36    pub fn with_timeout_ms(mut self, timeout_ms: u64) -> Self {
37        self.timeout_ms = timeout_ms;
38        self
39    }
40
41    #[must_use]
42    pub fn for_service_module(&self, module_name: &str) -> Self {
43        let mut config = self.clone();
44        config.name = module_name.to_owned();
45        if config.transport == RemoteModuleTransport::HttpJson {
46            config.base_url = format!("{}/modules/{module_name}", self.base_url);
47        }
48        config
49    }
50}
51
52fn normalize_base_url(base_url: String) -> (RemoteModuleTransport, String) {
53    let trimmed = base_url.trim().trim_end_matches('/');
54    match trimmed.strip_prefix("grpc://") {
55        Some(rest) => (
56            RemoteModuleTransport::Grpc,
57            format!("http://{}", rest.trim_end_matches('/')),
58        ),
59        None => match trimmed.strip_prefix("grpcs://") {
60            Some(rest) => (
61                RemoteModuleTransport::Grpc,
62                format!("https://{}", rest.trim_end_matches('/')),
63            ),
64            None => (RemoteModuleTransport::HttpJson, trimmed.to_owned()),
65        },
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn defaults_to_http_json_transport() {
75        let config =
76            RemoteModuleConfig::new("remote-crm", "http://127.0.0.1:4100/lenso/module/v1/");
77
78        assert_eq!(config.transport, RemoteModuleTransport::HttpJson);
79        assert_eq!(config.base_url, "http://127.0.0.1:4100/lenso/module/v1");
80    }
81
82    #[test]
83    fn grpc_scheme_selects_grpc_transport() {
84        let config = RemoteModuleConfig::new("remote-crm", "grpc://127.0.0.1:50051/");
85
86        assert_eq!(config.transport, RemoteModuleTransport::Grpc);
87        assert_eq!(config.base_url, "http://127.0.0.1:50051");
88    }
89
90    #[test]
91    fn grpcs_scheme_selects_grpc_transport_with_tls_endpoint() {
92        let config = RemoteModuleConfig::new("remote-crm", "grpcs://remote.example.test:50051/");
93
94        assert_eq!(config.transport, RemoteModuleTransport::Grpc);
95        assert_eq!(config.base_url, "https://remote.example.test:50051");
96    }
97}