pub use serde_json::from_str;
#[cfg(not(feature = "simd-json"))]
pub use serde_json::to_string;
#[cfg(feature = "simd-json")]
pub use simd_json::to_string;
use crate::{
error::{ReceiveMessageError, ReceiveMessageErrorType},
EventTypeFlags,
};
use serde::de::DeserializeSeed;
use twilight_model::gateway::{
event::{GatewayEvent, GatewayEventDeserializer},
OpCode,
};
pub fn parse(
event: String,
wanted_event_types: EventTypeFlags,
) -> Result<Option<GatewayEvent>, ReceiveMessageError> {
let gateway_deserializer =
if let Some(gateway_deserializer) = GatewayEventDeserializer::from_json(&event) {
gateway_deserializer
} else {
return Err(ReceiveMessageError {
kind: ReceiveMessageErrorType::Deserializing { event },
source: Some("missing opcode".into()),
});
};
let opcode = if let Some(opcode) = OpCode::from(gateway_deserializer.op()) {
opcode
} else {
let opcode = gateway_deserializer.op();
return Err(ReceiveMessageError {
kind: ReceiveMessageErrorType::Deserializing { event },
source: Some(format!("unknown opcode: {opcode}").into()),
});
};
let event_type = gateway_deserializer.event_type();
let event_type = if let Ok(event_type) = EventTypeFlags::try_from((opcode, event_type)) {
event_type
} else {
let opcode = opcode as u8;
let source = format!("unknown opcode/dispatch event type: {opcode}/{event_type:?}");
return Err(ReceiveMessageError {
kind: ReceiveMessageErrorType::Deserializing { event },
source: Some(source.into()),
});
};
if wanted_event_types.contains(event_type) {
#[cfg(feature = "simd-json")]
let gateway_deserializer = gateway_deserializer.into_owned();
#[cfg(feature = "simd-json")]
let mut bytes = event.into_bytes();
#[cfg(feature = "simd-json")]
let mut json_deserializer = match simd_json::Deserializer::from_slice(&mut bytes) {
Ok(deserializer) => deserializer,
Err(source) => {
return Err(ReceiveMessageError {
kind: ReceiveMessageErrorType::Deserializing {
event: String::from_utf8_lossy(&bytes).into_owned(),
},
source: Some(Box::new(source)),
})
}
};
#[cfg(not(feature = "simd-json"))]
let mut json_deserializer = serde_json::Deserializer::from_str(&event);
gateway_deserializer
.deserialize(&mut json_deserializer)
.map(Some)
.map_err(|source| ReceiveMessageError {
kind: ReceiveMessageErrorType::Deserializing {
#[cfg(feature = "simd-json")]
event: String::from_utf8_lossy(&bytes).into_owned(),
#[cfg(not(feature = "simd-json"))]
event,
},
source: Some(Box::new(source)),
})
} else {
Ok(None)
}
}