use std::borrow::Cow;
use tokio_websockets::{CloseCode, Message as WebsocketMessage};
use twilight_model::gateway::CloseFrame;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
Close(Option<CloseFrame<'static>>),
Text(String),
}
impl Message {
pub(crate) const ABNORMAL_CLOSE: Self = Self::Close(Some(CloseFrame::new(1006, "")));
pub const fn is_close(&self) -> bool {
matches!(self, Self::Close(_))
}
pub const fn is_text(&self) -> bool {
matches!(self, Self::Text(_))
}
pub(crate) fn from_websocket_msg(msg: &WebsocketMessage) -> Option<Self> {
if msg.is_close() {
let (code, reason) = msg.as_close().unwrap();
let frame = (code != CloseCode::NO_STATUS_RECEIVED).then(|| CloseFrame {
code: code.into(),
reason: Cow::Owned(reason.to_string()),
});
Some(Self::Close(frame))
} else if msg.is_text() {
Some(Self::Text(msg.as_text().unwrap().to_owned()))
} else {
None
}
}
pub(crate) fn into_websocket(self) -> WebsocketMessage {
match self {
Self::Close(frame) => WebsocketMessage::close(
frame
.as_ref()
.and_then(|f| CloseCode::try_from(f.code).ok()),
frame.map(|f| f.reason).as_deref().unwrap_or_default(),
),
Self::Text(string) => WebsocketMessage::text(string),
}
}
}
#[cfg(test)]
mod tests {
use super::Message;
use static_assertions::assert_impl_all;
use std::fmt::Debug;
assert_impl_all!(Message: Clone, Debug, Eq, PartialEq);
}