flow_bot/event/
mod.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use serde::Deserialize;
5
6use crate::base::{context::BotContext, extract::FromEvent};
7
8pub mod message;
9pub mod meta_event;
10pub mod notice;
11pub mod request;
12
13#[derive(Deserialize, Debug, Clone)]
14#[serde(tag = "post_type")]
15#[serde(rename_all = "snake_case")]
16pub enum TypedEvent {
17    // use Box to avoid large size differences between variants
18    Message(Box<message::Message>),
19    Notice(notice::Notice),
20    Request(request::Request),
21    MetaEvent(meta_event::MetaEvent),
22    #[serde(untagged)]
23    Unknown(serde_json::Value),
24}
25
26impl TypedEvent {
27    pub fn get_type(&self) -> &str {
28        match self {
29            TypedEvent::Message(..) => "message",
30            TypedEvent::Notice(..) => "notice",
31            TypedEvent::Request(..) => "request",
32            TypedEvent::MetaEvent(..) => "meta_event",
33            TypedEvent::Unknown(..) => "unknown",
34        }
35    }
36}
37
38#[derive(Deserialize, Debug, Clone)]
39pub struct Event {
40    pub time: i64,
41    pub self_id: i64,
42    #[serde(flatten)]
43    pub event: TypedEvent,
44}
45
46pub type BotEvent = Arc<Event>;
47
48#[async_trait]
49impl FromEvent for BotEvent {
50    async fn from_event(_: BotContext, event: BotEvent) -> Option<Self> {
51        Some(event)
52    }
53}
54
55#[macro_export]
56macro_rules! impl_from_event {
57    ($event_type:ident) => {
58        #[::async_trait::async_trait]
59        impl $crate::base::extract::FromEvent for $event_type {
60            async fn from_event(
61                _: $crate::base::context::BotContext,
62                event: $crate::event::BotEvent,
63            ) -> Option<Self> {
64                match &event.event {
65                    $crate::event::TypedEvent::$event_type(inner) => Some(inner.clone()),
66                    _ => None,
67                }
68            }
69        }
70    };
71
72    ($event_type:ident,$variant:ident, $variant_type:ident) => {
73        #[::async_trait::async_trait]
74        impl $crate::base::extract::FromEvent for $variant_type {
75            async fn from_event(
76                _: $crate::base::context::BotContext,
77                event: $crate::event::BotEvent,
78            ) -> Option<Self> {
79                match &event.event {
80                    $crate::event::TypedEvent::$event_type($event_type::$variant(inner)) => {
81                        Some(inner.clone())
82                    }
83                    _ => None,
84                }
85            }
86        }
87    };
88
89    ($event_type:ident, $variant:ident) => {
90        impl_from_event!($event_type, $variant, $variant);
91    };
92}