1pub 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
19pub 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}