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 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}