reqwest_websocket/
json.rs

1use crate::{Error, Message};
2use serde::{de::DeserializeOwned, Serialize};
3
4impl Message {
5    /// Tries to serialize the JSON as a [`Message::Text`].
6    ///
7    /// # Optional
8    ///
9    /// This requires the optional `json` feature enabled.
10    ///
11    /// # Errors
12    ///
13    /// Serialization can fail if `T`'s implementation of `Serialize` decides to
14    /// fail, or if `T` contains a map with non-string keys.
15    #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
16    pub fn text_from_json<T: Serialize + ?Sized>(json: &T) -> Result<Self, Error> {
17        serde_json::to_string(json)
18            .map(Message::Text)
19            .map_err(Into::into)
20    }
21
22    /// Tries to serialize the JSON as a [`Message::Binary`].
23    ///
24    /// # Optional
25    ///
26    /// This requires that the optional `json` feature is enabled.
27    ///
28    /// # Errors
29    ///
30    /// Serialization can fail if `T`'s implementation of `Serialize` decides to
31    /// fail, or if `T` contains a map with non-string keys.
32    #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
33    pub fn binary_from_json<T: Serialize + ?Sized>(json: &T) -> Result<Self, Error> {
34        serde_json::to_vec(json)
35            .map(|data| Message::Binary(data.into()))
36            .map_err(Into::into)
37    }
38
39    /// Tries to deserialize the message body as JSON.
40    ///
41    /// # Optional
42    ///
43    /// This requires that the optional `json` feature is enabled.
44    ///
45    /// # Errors
46    ///
47    /// This method fails whenever the response body is not in `JSON` format,
48    /// or it cannot be properly deserialized to target type `T`.
49    ///
50    /// For more details please see [`serde_json::from_str`] and
51    /// [`serde_json::from_slice`].
52    #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
53    pub fn json<T: DeserializeOwned>(&self) -> Result<T, Error> {
54        use serde::de::Error as _;
55        match self {
56            Self::Text(x) => serde_json::from_str(x).map_err(Into::into),
57            Self::Binary(x) => serde_json::from_slice(x).map_err(Into::into),
58            #[allow(deprecated)]
59            Self::Ping(_) | Self::Pong(_) | Self::Close { .. } => {
60                Err(serde_json::Error::custom("neither text nor binary").into())
61            }
62        }
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use serde::{Deserialize, Serialize};
69
70    use crate::{Error, Message};
71
72    #[derive(Default, Serialize, Deserialize)]
73    struct Content {
74        message: String,
75    }
76
77    #[test]
78    pub fn text_json() -> Result<(), Error> {
79        let content = Content::default();
80        let message = Message::text_from_json(&content)?;
81        assert!(matches!(message, Message::Text(_)));
82        let _: Content = message.json()?;
83
84        Ok(())
85    }
86
87    #[test]
88    pub fn binary_json() -> Result<(), Error> {
89        let content = Content::default();
90        let message = Message::binary_from_json(&content)?;
91        assert!(matches!(message, Message::Binary(_)));
92        let _: Content = message.json()?;
93
94        Ok(())
95    }
96}