use serde::{Deserialize, Serialize};
use crate::session_key::SessionKey;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ChannelEvent {
DeliverMessage {
session_key: SessionKey,
content: serde_json::Value,
},
SessionComplete {
session_key: SessionKey,
},
RoutePermission {
session_key: SessionKey,
request_id: String,
description: String,
options: Vec<crate::permission::PermissionOption>,
},
AckMessage {
session_key: SessionKey,
channel_name: String,
peer_id: String,
message_id: Option<String>,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn when_deliver_message_event_serialized_then_deserializes_correctly() {
let event = ChannelEvent::DeliverMessage {
session_key: SessionKey::new("debug-http", "local", "dev"),
content: serde_json::json!({"text": "hello"}),
};
let json = serde_json::to_value(&event).unwrap();
let deser: ChannelEvent = serde_json::from_value(json).unwrap();
assert!(matches!(deser, ChannelEvent::DeliverMessage { .. }));
}
#[test]
fn when_route_permission_event_serialized_then_deserializes_correctly() {
let event = ChannelEvent::RoutePermission {
session_key: SessionKey::new("telegram", "direct", "alice"),
request_id: "req-1".into(),
description: "Allow file write?".into(),
options: vec![crate::permission::PermissionOption {
option_id: "allow".into(),
label: "Allow".into(),
}],
};
let json = serde_json::to_value(&event).unwrap();
let deser: ChannelEvent = serde_json::from_value(json).unwrap();
assert!(matches!(deser, ChannelEvent::RoutePermission { .. }));
}
#[test]
fn when_route_permission_options_round_trip_then_typed_vec() {
let event = ChannelEvent::RoutePermission {
session_key: SessionKey::new("telegram", "direct", "alice"),
request_id: "req-2".into(),
description: "Allow network?".into(),
options: vec![
crate::permission::PermissionOption {
option_id: "allow_once".into(),
label: "Allow once".into(),
},
crate::permission::PermissionOption {
option_id: "deny".into(),
label: "Deny".into(),
},
],
};
let json = serde_json::to_string(&event).unwrap();
let back: ChannelEvent = serde_json::from_str(&json).unwrap();
if let ChannelEvent::RoutePermission { options, .. } = back {
assert_eq!(options.len(), 2);
assert_eq!(options[0].option_id, "allow_once");
assert_eq!(options[1].label, "Deny");
} else {
panic!("expected RoutePermission");
}
}
#[test]
fn when_ack_message_event_serialized_then_deserializes_correctly() {
let event = ChannelEvent::AckMessage {
session_key: SessionKey::new("telegram", "direct", "alice"),
channel_name: "telegram".into(),
peer_id: "alice".into(),
message_id: Some("msg-123".into()),
};
let json = serde_json::to_value(&event).unwrap();
let deser: ChannelEvent = serde_json::from_value(json).unwrap();
assert!(matches!(deser, ChannelEvent::AckMessage { .. }));
}
#[test]
fn when_ack_message_has_no_message_id_then_serializes_as_null() {
let event = ChannelEvent::AckMessage {
session_key: SessionKey::new("debug-http", "local", "dev"),
channel_name: "debug-http".into(),
peer_id: "dev".into(),
message_id: None,
};
let json = serde_json::to_value(&event).unwrap();
let deser: ChannelEvent = serde_json::from_value(json).unwrap();
assert!(matches!(
deser,
ChannelEvent::AckMessage {
message_id: None,
..
}
));
}
}