use std::collections::BTreeMap;
use serde::{Serialize, Deserialize};
use std::str::FromStr;
use crate::protocol::kind::ProtocolKind;
pub type RpcUrl = Url;
#[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(())
}
}