http_request/websocket/shared/
impl.rs

1use crate::*;
2
3impl std::fmt::Display for WebSocketError {
4    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
5        match self.kind {
6            WebSocketErrorKind::Connection => write!(f, "Connection error: {}", self.message),
7            WebSocketErrorKind::Protocol => write!(f, "Protocol error: {}", self.message),
8            WebSocketErrorKind::Timeout => write!(f, "Timeout error: {}", self.message),
9            WebSocketErrorKind::InvalidUrl => write!(f, "Invalid URL: {}", self.message),
10            WebSocketErrorKind::Io => write!(f, "IO error: {}", self.message),
11            WebSocketErrorKind::Tls => write!(f, "TLS error: {}", self.message),
12        }
13    }
14}
15
16impl std::error::Error for WebSocketError {}
17
18impl WebSocketError {
19    pub(crate) fn connection<T: ToString>(message: T) -> Self {
20        Self {
21            kind: WebSocketErrorKind::Connection,
22            message: message.to_string(),
23        }
24    }
25
26    pub(crate) fn protocol<T: ToString>(message: T) -> Self {
27        Self {
28            kind: WebSocketErrorKind::Protocol,
29            message: message.to_string(),
30        }
31    }
32
33    pub(crate) fn timeout<T: ToString>(message: T) -> Self {
34        Self {
35            kind: WebSocketErrorKind::Timeout,
36            message: message.to_string(),
37        }
38    }
39
40    pub(crate) fn invalid_url<T: ToString>(message: T) -> Self {
41        Self {
42            kind: WebSocketErrorKind::InvalidUrl,
43            message: message.to_string(),
44        }
45    }
46
47    pub(crate) fn io<T: ToString>(message: T) -> Self {
48        Self {
49            kind: WebSocketErrorKind::Io,
50            message: message.to_string(),
51        }
52    }
53
54    pub(crate) fn tls<T: ToString>(message: T) -> Self {
55        Self {
56            kind: WebSocketErrorKind::Tls,
57            message: message.to_string(),
58        }
59    }
60}
61
62impl SharedWebSocketBuilder {
63    pub(crate) fn parse_url(url: &str) -> Result<HttpUrlComponents, WebSocketError> {
64        if url.is_empty() {
65            return Err(WebSocketError::invalid_url("URL is empty"));
66        }
67        let mut url_obj: HttpUrlComponents = HttpUrlComponents::default();
68        if url.starts_with("ws://") {
69            url_obj.protocol = Protocol::HTTP;
70            url_obj.port = Some(80);
71        } else if url.starts_with("wss://") {
72            url_obj.protocol = Protocol::HTTPS;
73            url_obj.port = Some(443);
74        } else {
75            return Err(WebSocketError::invalid_url("Invalid WebSocket URL scheme"));
76        }
77        let without_protocol: &str = if url.starts_with("ws://") {
78            &url[5..]
79        } else {
80            &url[6..]
81        };
82        let parts: Vec<&str> = without_protocol.splitn(2, '/').collect();
83        let host_port: &str = parts[0];
84        let path: &str = if parts.len() > 1 { parts[1] } else { "" };
85        if host_port.contains(':') {
86            let host_port_parts: Vec<&str> = host_port.splitn(2, ':').collect();
87            url_obj.host = Some(host_port_parts[0].to_string());
88            if let Ok(port) = host_port_parts[1].parse::<u16>() {
89                url_obj.port = Some(port);
90            }
91        } else {
92            url_obj.host = Some(host_port.to_string());
93        }
94        url_obj.path = Some(if path.is_empty() {
95            "/".to_string()
96        } else {
97            format!("/{}", path)
98        });
99        Ok(url_obj)
100    }
101}