use std::borrow::Cow;
use tokio_tungstenite::tungstenite::{
protocol::{frame::coding::CloseCode, CloseFrame as TungsteniteCloseFrame},
Message as TungsteniteMessage,
};
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct CloseFrame<'a> {
pub code: u16,
pub reason: Cow<'a, str>,
}
impl<'a, T: Into<Cow<'a, str>>> From<(u16, T)> for CloseFrame<'a> {
fn from((code, reason): (u16, T)) -> Self {
Self {
code,
reason: reason.into(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Message {
Binary(Vec<u8>),
Close(Option<CloseFrame<'static>>),
Ping(Vec<u8>),
Pong(Vec<u8>),
Text(String),
}
impl Message {
pub(super) fn into_tungstenite(self) -> TungsteniteMessage {
match self {
Self::Binary(bytes) => TungsteniteMessage::Binary(bytes),
Self::Close(close) => {
TungsteniteMessage::Close(close.map(|close| TungsteniteCloseFrame {
code: CloseCode::from(close.code),
reason: close.reason,
}))
}
Self::Ping(bytes) => TungsteniteMessage::Ping(bytes),
Self::Pong(bytes) => TungsteniteMessage::Pong(bytes),
Self::Text(string) => TungsteniteMessage::Text(string),
}
}
}
#[cfg(test)]
mod tests {
use super::{CloseFrame, Message};
use static_assertions::{assert_fields, assert_impl_all};
use std::fmt::Debug;
assert_fields!(CloseFrame<'_>: code, reason);
assert_impl_all!(
CloseFrame<'_>:
Clone,
Debug,
Eq,
From<(u16, &'static str)>,
From<(u16, String)>,
PartialEq,
);
assert_impl_all!(Message: Clone, Debug, Eq, PartialEq);
}