reconnecting_websocket/
location.rs

1use std::fmt::Debug;
2
3use gloo::utils::errors::JsError;
4use web_sys::{
5    js_sys::{Error as JsSysError, ReferenceError},
6    window,
7};
8
9/// The protocol extracted from `window.location`
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum HttpProtocol {
12    /// Insecure http
13    Http,
14    /// Secure https
15    Https,
16}
17
18impl ToString for HttpProtocol {
19    fn to_string(&self) -> String {
20        use HttpProtocol::*;
21        match self {
22            Http => "http".to_string(),
23            Https => "https".to_string(),
24        }
25    }
26}
27
28impl Into<WebSocketProtocol> for HttpProtocol {
29    fn into(self) -> WebSocketProtocol {
30        use HttpProtocol::*;
31        match self {
32            Http => WebSocketProtocol::Ws,
33            Https => WebSocketProtocol::Wss,
34        }
35    }
36}
37
38/// A websocket protocol
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum WebSocketProtocol {
41    /// Insecure websocket
42    Ws,
43    /// Secure websocket
44    Wss,
45}
46
47impl ToString for WebSocketProtocol {
48    fn to_string(&self) -> String {
49        use WebSocketProtocol::*;
50        match self {
51            Ws => "ws".to_string(),
52            Wss => "wss".to_string(),
53        }
54    }
55}
56
57/// Helper function to get the protocol and host from `window.location`
58pub fn get_proto_and_host() -> Result<(HttpProtocol, String), JsError> {
59    let location =
60        window().ok_or(JsSysError::from(ReferenceError::new("window global was none")))?.location();
61
62    let host = location.host().map_err(|v| {
63        JsSysError::try_from(v).unwrap_or(JsSysError::new("failed to get location.host"))
64    })?;
65
66    let proto = location.protocol().map_err(|v| {
67        JsSysError::try_from(v).unwrap_or(JsSysError::new("faild to get location.protocol"))
68    })?;
69
70    let proto = match proto.as_ref() {
71        "http:" => Ok(HttpProtocol::Http),
72        "https:" => Ok(HttpProtocol::Https),
73        other => Err(JsSysError::new(&format!(
74            "Unexpected protocol \"{other}\" (Expected http: or https:)"
75        ))),
76    }?;
77
78    Ok((proto, host))
79}