Skip to main content

meerkat_mobkit/
protocol.rs

1//! Wire protocol parsing for the gateway RPC transport.
2
3use serde::de::DeserializeOwned;
4
5use crate::types::{EventEnvelope, UnifiedEvent};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum ProtocolParseError {
9    InvalidJson,
10    InvalidSchema,
11    UnexpectedEventKind,
12    UnexpectedPayloadType,
13}
14
15impl std::fmt::Display for ProtocolParseError {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        match self {
18            Self::InvalidJson => write!(f, "invalid JSON"),
19            Self::InvalidSchema => write!(f, "invalid schema"),
20            Self::UnexpectedEventKind => write!(f, "unexpected event kind"),
21            Self::UnexpectedPayloadType => write!(f, "unexpected payload type"),
22        }
23    }
24}
25
26impl std::error::Error for ProtocolParseError {}
27
28pub fn parse_unified_event_line(
29    line: &str,
30) -> Result<EventEnvelope<UnifiedEvent>, ProtocolParseError> {
31    let value: serde_json::Value =
32        serde_json::from_str(line).map_err(|_| ProtocolParseError::InvalidJson)?;
33    serde_json::from_value(value).map_err(|_| ProtocolParseError::InvalidSchema)
34}
35
36pub fn parse_module_event_line<T: DeserializeOwned>(
37    line: &str,
38    expected_event_type: &str,
39) -> Result<EventEnvelope<T>, ProtocolParseError> {
40    let envelope = parse_unified_event_line(line)?;
41
42    let module_event = match envelope.event {
43        UnifiedEvent::Module(module_event) => module_event,
44        _ => return Err(ProtocolParseError::UnexpectedEventKind),
45    };
46
47    if module_event.event_type != expected_event_type {
48        return Err(ProtocolParseError::UnexpectedPayloadType);
49    }
50
51    let typed_payload: T = serde_json::from_value(module_event.payload)
52        .map_err(|_| ProtocolParseError::UnexpectedPayloadType)?;
53
54    Ok(EventEnvelope {
55        event_id: envelope.event_id,
56        source: envelope.source,
57        timestamp_ms: envelope.timestamp_ms,
58        event: typed_payload,
59    })
60}