use crate::{Error, Message};
use bytes::Bytes;
use serde::{Serialize, de::DeserializeOwned};
use super::Utf8Bytes;
impl Message {
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub fn text_from_json<T: Serialize + ?Sized>(json: &T) -> Result<Self, Error> {
serde_json::to_string(json)
.map(Utf8Bytes::from)
.map(Message::Text)
.map_err(Into::into)
}
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub fn binary_from_json<T: Serialize + ?Sized>(json: &T) -> Result<Self, Error> {
serde_json::to_vec(json)
.map(Bytes::from)
.map(Message::Binary)
.map_err(Into::into)
}
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub fn json<T: DeserializeOwned>(&self) -> Result<T, Error> {
use serde::de::Error as _;
match self {
Self::Text(x) => serde_json::from_str(x).map_err(Into::into),
Self::Binary(x) => serde_json::from_slice(x).map_err(Into::into),
#[allow(deprecated)]
Self::Ping(_) | Self::Pong(_) | Self::Close { .. } => {
Err(serde_json::Error::custom("neither text nor binary").into())
}
}
}
}
#[cfg(test)]
mod test {
use serde::{Deserialize, Serialize};
use crate::{Error, Message};
#[derive(Default, Serialize, Deserialize)]
struct Content {
message: String,
}
#[test]
pub fn text_json() -> Result<(), Error> {
let content = Content::default();
let message = Message::text_from_json(&content)?;
assert!(matches!(message, Message::Text(_)));
let _: Content = message.json()?;
Ok(())
}
#[test]
pub fn binary_json() -> Result<(), Error> {
let content = Content::default();
let message = Message::binary_from_json(&content)?;
assert!(matches!(message, Message::Binary(_)));
let _: Content = message.json()?;
Ok(())
}
}