use serde::{Deserialize, Serialize};
use crate::envelope::CloseCode;
pub const PROTOCOL_VERSION: u32 = 1;
pub const PROTOCOL_HEADER: &str = "x-net-backend-protocol";
pub const HTTP_REFUSAL_STATUS: u16 = 400;
pub const WS_REFUSAL_CLOSE: CloseCode = CloseCode::UNSUPPORTED_PROTOCOL;
pub const WS_HANDSHAKE_REFUSAL_STATUS: u16 = 403;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ServerInfo {
pub protocol: u32,
pub min_protocol: u32,
#[serde(default)]
pub modules: Vec<String>,
}
impl ServerInfo {
pub fn new(modules: Vec<String>) -> Self {
Self { protocol: PROTOCOL_VERSION, min_protocol: PROTOCOL_VERSION, modules }
}
pub fn with_versions(mut self, min_protocol: u32, protocol: u32) -> Self {
self.min_protocol = min_protocol;
self.protocol = protocol;
self
}
pub fn supports(&self, version: u32) -> bool {
(self.min_protocol..=self.protocol).contains(&version)
}
pub fn has_module(&self, name: &str) -> bool {
self.modules.iter().any(|m| m == name)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[non_exhaustive]
pub struct GetServerInfo {}
impl GetServerInfo {
pub const fn new() -> Self {
Self {}
}
}
impl crate::http_call::HttpCall for GetServerInfo {
type Payload = crate::http_call::NoPayload;
type Response = ServerInfo;
const ROUTE: crate::routes::Route = crate::routes::Route::new(crate::routes::HttpMethod::Get, crate::routes::INFO, false);
const PAYLOAD: crate::http_call::PayloadKind = crate::http_call::PayloadKind::Empty;
fn payload(&self) -> &crate::http_call::NoPayload {
&crate::http_call::NO_PAYLOAD
}
fn from_parts(_params: &crate::http_call::PathParams, _payload: crate::http_call::NoPayload) -> Result<Self, crate::ApiError> {
Ok(Self::new())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn server_info() {
let info = ServerInfo::new(vec!["chat".into()]).with_versions(1, 3);
assert!(info.supports(1) && info.supports(3) && !info.supports(4) && !info.supports(0));
assert!(info.has_module("chat") && !info.has_module("storage"));
assert!(WS_REFUSAL_CLOSE.is_permanent());
assert_ne!(WS_HANDSHAKE_REFUSAL_STATUS, HTTP_REFUSAL_STATUS);
}
}