1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4pub struct ServiceEndpoint(String);
5
6impl ServiceEndpoint {
7 pub fn parse(input: impl Into<String>) -> crate::ImResult<Self> {
8 let input = input.into();
9 let trimmed = input.trim();
10 if trimmed.is_empty() {
11 return Err(crate::ImError::invalid_input(
12 Some("service_base_url".to_string()),
13 "endpoint must not be empty",
14 ));
15 }
16 if !(trimmed.starts_with("http://") || trimmed.starts_with("https://")) {
17 return Err(crate::ImError::invalid_input(
18 Some("service_base_url".to_string()),
19 "endpoint must start with http:// or https://",
20 ));
21 }
22 Ok(Self(trimmed.trim_end_matches('/').to_string()))
23 }
24
25 pub fn as_str(&self) -> &str {
26 &self.0
27 }
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
31pub struct ImCoreConfig {
32 pub service_base_url: ServiceEndpoint,
33 pub did_domain: String,
34 pub user_service_endpoint: Option<ServiceEndpoint>,
35 pub message_service_endpoint: Option<ServiceEndpoint>,
36 pub mail_service_endpoint: Option<ServiceEndpoint>,
37 pub anp_service_endpoint: Option<ServiceEndpoint>,
38 pub anp_service_did: Option<crate::ids::Did>,
39 pub ca_bundle: Option<String>,
40 pub transport_policy: MessageTransportPolicy,
41}
42
43impl ImCoreConfig {
44 pub fn new(
45 service_base_url: ServiceEndpoint,
46 did_domain: impl Into<String>,
47 ) -> crate::ImResult<Self> {
48 let did_domain = did_domain.into();
49 if did_domain.trim().is_empty() {
50 return Err(crate::ImError::invalid_input(
51 Some("did_domain".to_string()),
52 "DID domain must not be empty",
53 ));
54 }
55 Ok(Self {
56 service_base_url,
57 did_domain,
58 user_service_endpoint: None,
59 message_service_endpoint: None,
60 mail_service_endpoint: None,
61 anp_service_endpoint: None,
62 anp_service_did: None,
63 ca_bundle: None,
64 transport_policy: MessageTransportPolicy::Auto,
65 })
66 }
67
68 pub(crate) fn ca_bundle_path(&self) -> Option<&str> {
69 self.ca_bundle
70 .as_deref()
71 .map(str::trim)
72 .filter(|value| !value.is_empty())
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
77pub enum MessageTransportPolicy {
78 Auto,
79 HttpOnly,
80 RealtimePreferred,
81}