botcat-capoo 1.0.3

A NapCat based QQ bot implemented in Rust
Documentation
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "sub_type", rename_all = "snake_case")]
pub enum NotifyEvent {
    Poke(PokeEvent),
    LuckyKing(LuckyKingEvent),
    Honor(HonorEvent),
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PokeEvent {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub group_id: Option<u64>,
    pub user_id: u64,
    pub target_id: u64,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LuckyKingEvent {
    group_id: u64,
    user_id: u64,
    target_id: u64,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct HonorEvent {
    honor_type: String,
    group_id: u64,
    user_id: u64,
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::model::event::{BotEvent, NoticeEvent, PostEvent};

    #[test]
    fn test_serialize_group_poke_event() {
        let poke_event = PokeEvent {
            group_id: Some(123456),
            user_id: 654321,
            target_id: 111111,
        };
        let notify_event = NotifyEvent::Poke(poke_event);
        let notice_event = NoticeEvent::Notify(notify_event);
        let post_event = PostEvent::Notice(notice_event);
        let bot_event = BotEvent {
            time: 1625079600,
            self_id: 123456789,
            post_type: post_event,
        };

        let json = serde_json::to_string(&bot_event).expect("Failed to serialize BotEvent");

        println!("{json}");

        assert!(json.contains("\"sub_type\":\"poke\""));
        assert!(json.contains("\"group_id\":123456"));
        assert!(json.contains("\"user_id\":654321"));
        assert!(json.contains("\"target_id\":111111"));
    }

    #[test]
    fn test_deserialize_group_poke_event() {
        let json = r#"{"time":1625079600,"self_id":123456789,"post_type":"notice","notice_type":"notify","sub_type":"poke","group_id":123456,"user_id":654321,"target_id":111111}"#;
        let bot_event: BotEvent =
            serde_json::from_str(json).expect("Failed to deserialize BotEvent");

        println!("{:?}", bot_event);

        match bot_event.post_type {
            PostEvent::Notice(notice_event) => match notice_event {
                NoticeEvent::Notify(notify_event) => match notify_event {
                    NotifyEvent::Poke(poke_event) => {
                        assert_eq!(poke_event.group_id, Some(123456));
                        assert_eq!(poke_event.user_id, 654321);
                        assert_eq!(poke_event.target_id, 111111);
                    }
                    _ => panic!("Expected PokeEvent"),
                },
                _ => panic!("Expected NotifyEvent"),
            },
            _ => panic!("Expected NoticeEvent"),
        }
    }

    #[test]
    fn test_serialize_private_poke_event() {
        let poke_event = PokeEvent {
            group_id: None,
            user_id: 654321,
            target_id: 111111,
        };
        let notify_event = NotifyEvent::Poke(poke_event);
        let notice_event = NoticeEvent::Notify(notify_event);
        let post_event = PostEvent::Notice(notice_event);
        let bot_event = BotEvent {
            time: 1625079600,
            self_id: 123456789,
            post_type: post_event,
        };

        let json = serde_json::to_string(&bot_event).expect("Failed to serialize BotEvent");

        println!("{json}");

        assert!(json.contains("\"sub_type\":\"poke\""));
        assert!(json.contains("\"user_id\":654321"));
        assert!(!json.contains("\"group_id\""));
        assert!(json.contains("\"target_id\":111111"));
    }

    #[test]
    fn test_deserialize_private_poke_event() {
        let json = r#"{"time":1625079600,"self_id":123456789,"post_type":"notice","notice_type":"notify","sub_type":"poke","user_id":654321,"target_id":111111}"#;
        let bot_event: BotEvent =
            serde_json::from_str(json).expect("Failed to deserialize BotEvent");

        println!("{:?}", bot_event);

        match bot_event.post_type {
            PostEvent::Notice(notice_event) => match notice_event {
                NoticeEvent::Notify(notify_event) => match notify_event {
                    NotifyEvent::Poke(poke_event) => {
                        assert_eq!(poke_event.group_id, None);
                        assert_eq!(poke_event.user_id, 654321);
                        assert_eq!(poke_event.target_id, 111111);
                    }
                    _ => panic!("Expected PokeEvent"),
                },
                _ => panic!("Expected NotifyEvent"),
            },
            _ => panic!("Expected NoticeEvent"),
        }
    }
}