twilight_gateway/
json.rs

1//! Function wrappers for deserializing and serializing events and commands.
2
3pub use serde_json::from_str;
4#[cfg(not(feature = "simd-json"))]
5pub use serde_json::to_string;
6#[cfg(feature = "simd-json")]
7pub use simd_json::to_string;
8
9use crate::{
10    error::{ReceiveMessageError, ReceiveMessageErrorType},
11    EventTypeFlags,
12};
13use serde::de::DeserializeSeed;
14use twilight_model::gateway::{
15    event::{GatewayEvent, GatewayEventDeserializer},
16    OpCode,
17};
18
19/// Parse a JSON encoded gateway event into a `GatewayEvent` if
20/// `wanted_event_types` contains its type.
21///
22/// # Errors
23///
24/// Returns a [`ReceiveMessageErrorType::Deserializing`] error if the *known*
25/// event could not be deserialized.
26pub fn parse(
27    event: String,
28    wanted_event_types: EventTypeFlags,
29) -> Result<Option<GatewayEvent>, ReceiveMessageError> {
30    let Some(gateway_deserializer) = GatewayEventDeserializer::from_json(&event) else {
31        return Err(ReceiveMessageError {
32            kind: ReceiveMessageErrorType::Deserializing { event },
33            source: None,
34        });
35    };
36
37    let Some(opcode) = OpCode::from(gateway_deserializer.op()) else {
38        return Ok(None);
39    };
40
41    let event_type = gateway_deserializer.event_type();
42
43    let Ok(event_type) = EventTypeFlags::try_from((opcode, event_type)) else {
44        return Ok(None);
45    };
46
47    if wanted_event_types.contains(event_type) {
48        #[cfg(feature = "simd-json")]
49        let gateway_deserializer = gateway_deserializer.into_owned();
50        #[cfg(feature = "simd-json")]
51        let mut bytes = event.into_bytes();
52
53        #[cfg(feature = "simd-json")]
54        let mut json_deserializer = match simd_json::Deserializer::from_slice(&mut bytes) {
55            Ok(deserializer) => deserializer,
56            Err(source) => {
57                return Err(ReceiveMessageError {
58                    kind: ReceiveMessageErrorType::Deserializing {
59                        event: String::from_utf8_lossy(&bytes).into_owned(),
60                    },
61                    source: Some(Box::new(source)),
62                })
63            }
64        };
65
66        #[cfg(not(feature = "simd-json"))]
67        let mut json_deserializer = serde_json::Deserializer::from_str(&event);
68
69        gateway_deserializer
70            .deserialize(&mut json_deserializer)
71            .map(Some)
72            .map_err(|source| ReceiveMessageError {
73                kind: ReceiveMessageErrorType::Deserializing {
74                    #[cfg(feature = "simd-json")]
75                    event: String::from_utf8_lossy(&bytes).into_owned(),
76                    #[cfg(not(feature = "simd-json"))]
77                    event,
78                },
79                source: Some(Box::new(source)),
80            })
81    } else {
82        Ok(None)
83    }
84}