rubbo-core 0.1.0

Rust implementation of Apache Dubbo 3. High-performance RPC framework with Triple protocol.
Documentation
use std::collections::BTreeMap;
use serde::{Serialize, Deserialize};
use std::str::FromStr;
use crate::protocol::kind::ProtocolKind;

/// Alias for RPC URL
pub type RpcUrl = Url;

/// URL - The configuration bus
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct Url {
    pub protocol: ProtocolKind,
    pub host: String,
    pub port: u16,
    pub path: String,
    pub parameters: BTreeMap<String, String>,
}

impl Url {
    pub fn new(protocol: &str, host: &str, port: u16) -> Self {
        Self {
            protocol: ProtocolKind::from_str(protocol).unwrap_or_else(|_| ProtocolKind::Unknown(protocol.to_string())),
            host: host.to_string(),
            port,
            path: "".to_string(),
            parameters: BTreeMap::new(),
        }
    }

    pub fn get_param(&self, key: &str) -> Option<&String> {
        self.parameters.get(key)
    }

    pub fn add_param(&mut self, key: &str, value: &str) {
        self.parameters.insert(key.to_string(), value.to_string());
    }
}

impl std::fmt::Display for Url {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}://{}:{}", self.protocol, self.host, self.port)?;
        if !self.path.is_empty() {
            if !self.path.starts_with('/') {
                 write!(f, "/")?;
            }
            write!(f, "{}", self.path)?;
        }
        
        if !self.parameters.is_empty() {
            write!(f, "?")?;
            for (i, (k, v)) in self.parameters.iter().enumerate() {
                if i > 0 {
                    write!(f, "&")?;
                }
                write!(f, "{}={}", k, v)?;
            }
        }
        Ok(())
    }
}