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