Skip to main content

vectorizer_sdk/
transport.rs

1//! Transport abstraction layer for Vectorizer client.
2//!
3//! Supports multiple transport protocols:
4//! - HTTP/HTTPS (default)
5//! - UMICP (Universal Messaging and Inter-process Communication Protocol)
6
7use async_trait::async_trait;
8use serde_json::Value;
9
10use crate::error::Result;
11
12/// Transport protocol type
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Protocol {
15    /// HTTP/HTTPS protocol
16    Http,
17    /// UMICP protocol
18    #[cfg(feature = "umicp")]
19    Umicp,
20}
21
22impl std::fmt::Display for Protocol {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        match self {
25            Protocol::Http => write!(f, "http"),
26            #[cfg(feature = "umicp")]
27            Protocol::Umicp => write!(f, "umicp"),
28        }
29    }
30}
31
32/// Transport trait for making requests
33#[async_trait]
34pub trait Transport: Send + Sync {
35    /// Make a GET request
36    async fn get(&self, path: &str) -> Result<String>;
37
38    /// Make a POST request
39    async fn post(&self, path: &str, data: Option<&Value>) -> Result<String>;
40
41    /// Make a PUT request
42    async fn put(&self, path: &str, data: Option<&Value>) -> Result<String>;
43
44    /// Make a DELETE request
45    async fn delete(&self, path: &str) -> Result<String>;
46
47    /// Make a PATCH request
48    async fn patch(&self, path: &str, data: Option<&Value>) -> Result<String>;
49
50    /// Get the protocol being used
51    fn protocol(&self) -> Protocol;
52}
53
54/// Parse a connection string into protocol and connection details
55///
56/// Examples:
57/// - "http://localhost:15002" -> HTTP transport
58/// - "https://api.example.com" -> HTTPS transport
59/// - "umicp://localhost:15003" -> UMICP transport
60pub fn parse_connection_string(connection_string: &str) -> Result<(Protocol, String, Option<u16>)> {
61    // Simple manual parsing
62    let parts: Vec<&str> = connection_string.split("://").collect();
63
64    if parts.len() != 2 {
65        return Err(crate::error::VectorizerError::configuration(
66            "Invalid connection string format. Expected protocol://host[:port]",
67        ));
68    }
69
70    let scheme = parts[0];
71    let authority = parts[1];
72
73    // Parse host and port
74    #[allow(unused_variables)]
75    let (host, port) = if authority.contains(':') {
76        let host_port: Vec<&str> = authority.split(':').collect();
77        if host_port.len() != 2 {
78            return Err(crate::error::VectorizerError::configuration(
79                "Invalid host:port format",
80            ));
81        }
82        let port = host_port[1]
83            .parse::<u16>()
84            .map_err(|_| crate::error::VectorizerError::configuration("Invalid port number"))?;
85        (host_port[0].to_string(), Some(port))
86    } else {
87        (authority.to_string(), None)
88    };
89
90    match scheme {
91        "http" => Ok((Protocol::Http, format!("http://{}", authority), None)),
92        "https" => Ok((Protocol::Http, format!("https://{}", authority), None)),
93        #[cfg(feature = "umicp")]
94        "umicp" => Ok((Protocol::Umicp, host, port)),
95        _ => Err(crate::error::VectorizerError::configuration(format!(
96            "Unsupported protocol: {}",
97            scheme
98        ))),
99    }
100}