im-core 0.1.0

Rust IM SDK for Awiki clients built on Agent Network Protocol (ANP)
Documentation
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ServiceEndpoint(String);

impl ServiceEndpoint {
    pub fn parse(input: impl Into<String>) -> crate::ImResult<Self> {
        let input = input.into();
        let trimmed = input.trim();
        if trimmed.is_empty() {
            return Err(crate::ImError::invalid_input(
                Some("service_base_url".to_string()),
                "endpoint must not be empty",
            ));
        }
        if !(trimmed.starts_with("http://") || trimmed.starts_with("https://")) {
            return Err(crate::ImError::invalid_input(
                Some("service_base_url".to_string()),
                "endpoint must start with http:// or https://",
            ));
        }
        Ok(Self(trimmed.trim_end_matches('/').to_string()))
    }

    pub fn as_str(&self) -> &str {
        &self.0
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImCoreConfig {
    pub service_base_url: ServiceEndpoint,
    pub did_domain: String,
    pub user_service_endpoint: Option<ServiceEndpoint>,
    pub message_service_endpoint: Option<ServiceEndpoint>,
    pub mail_service_endpoint: Option<ServiceEndpoint>,
    pub anp_service_endpoint: Option<ServiceEndpoint>,
    pub anp_service_did: Option<crate::ids::Did>,
    pub ca_bundle: Option<String>,
    pub transport_policy: MessageTransportPolicy,
}

impl ImCoreConfig {
    pub fn new(
        service_base_url: ServiceEndpoint,
        did_domain: impl Into<String>,
    ) -> crate::ImResult<Self> {
        let did_domain = did_domain.into();
        if did_domain.trim().is_empty() {
            return Err(crate::ImError::invalid_input(
                Some("did_domain".to_string()),
                "DID domain must not be empty",
            ));
        }
        Ok(Self {
            service_base_url,
            did_domain,
            user_service_endpoint: None,
            message_service_endpoint: None,
            mail_service_endpoint: None,
            anp_service_endpoint: None,
            anp_service_did: None,
            ca_bundle: None,
            transport_policy: MessageTransportPolicy::Auto,
        })
    }

    pub(crate) fn ca_bundle_path(&self) -> Option<&str> {
        self.ca_bundle
            .as_deref()
            .map(str::trim)
            .filter(|value| !value.is_empty())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum MessageTransportPolicy {
    Auto,
    HttpOnly,
    RealtimePreferred,
}