1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! mirai 传回的消息,群聊、私聊、事件等
mod chain;
mod chain_xml;
pub mod events;
pub mod friend;
pub mod group;
mod stranger;
mod stream;
mod temp;
mod traits;

use std::convert::TryFrom;

pub use chain::{MessageBlock, MessageChain};
pub use events::Event;
pub use friend::FriendMessage;
pub use group::GroupMessage;
use serde::Deserialize;
use serde_json::Value;
pub use stranger::StrangerMessage;
pub use temp::TempMessage;
pub use traits::Conversation;

/// 接收到的消息,可能是群消息、私聊消息、事件等
#[derive(Debug, Clone)]
pub enum Message {
    Friend(FriendMessage),
    Group(GroupMessage),
    Temp(TempMessage),
    Stranger(StrangerMessage),
    Event(Event),
}

impl crate::msg_framework::FromRequest<crate::Bot> for Message {
    fn from_request(request: crate::msg_framework::Request<crate::Bot>) -> Option<Self> {
        Some(request.message)
    }
}

impl TryFrom<Value> for Message {
    type Error = serde_json::Error;
    fn try_from(value: Value) -> Result<Self, Self::Error> {
        use crate::serde::de::Error;
        let t = value
            .get("type")
            .and_then(|s| s.as_str())
            .ok_or_else(|| serde_json::Error::custom("type not found."))?;
        let msg = match t {
            "FriendMessage" => Message::Friend(serde_json::from_value(value)?),
            "GroupMessage" => Message::Group(serde_json::from_value(value)?),
            "TempMessage" => Message::Temp(serde_json::from_value(value)?),
            "StrangerMessage" => Message::Stranger(serde_json::from_value(value)?),
            "OtherClientMessage" => {
                return Err(serde_json::Error::custom(
                    "Unsupported type: `OtherClientMessage`",
                ));
            }
            _event_type => Message::Event(serde_json::from_value(value)?),
        };
        Ok(msg)
    }
}

impl<'de> Deserialize<'de> for Message {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        use serde::de::Error;
        let value = Value::deserialize(deserializer)?;
        let msg = Message::try_from(value).map_err(|e| D::Error::custom(e.to_string()))?;

        Ok(msg)
    }
}