cyfs_core/im/
msg.rs

1use crate::codec::*;
2use crate::CoreObjectType;
3use cyfs_base::*;
4use serde::Serialize;
5
6use std::convert::TryFrom;
7
8#[derive(Clone, ProtobufTransform, Serialize)]
9#[cyfs_protobuf_type(crate::codec::protos::MsgObjectContent)]
10pub struct MsgObjectContent {
11    pub id: ObjectId,
12    pub name: String,
13}
14
15#[derive(Clone, ProtobufTransformType, Serialize)]
16#[cyfs_protobuf_type(crate::codec::protos::MsgContent)]
17pub enum MsgContent {
18    Text(String),
19    Object(MsgObjectContent),
20}
21
22impl MsgContent {
23    fn is_text(&self) -> bool {
24        match self {
25            MsgContent::Text(_) => true,
26            _ => false,
27        }
28    }
29}
30
31// MsgContent的编解码
32impl ProtobufTransform<protos::MsgContent> for MsgContent {
33    fn transform(value: protos::MsgContent) -> BuckyResult<Self> {
34        let ret = match value.r#type {
35            0 => Self::Text(value.text.unwrap()),
36            1 => Self::Object(
37                ProtobufTransform::transform(value.content.unwrap())?,
38            ),
39            _ => {
40                return Err(BuckyError::new(BuckyErrorCode::Failed, format!("unknown msg content type {}", value.r#type)));
41            }
42        };
43
44        Ok(ret)
45    }
46}
47
48impl ProtobufTransform<&MsgContent> for protos::MsgContent {
49    fn transform(value: &MsgContent) -> BuckyResult<Self> {
50        let mut ret = Self::default();
51        match value {
52            MsgContent::Text(v) => {
53                ret.r#type = 0;
54                ret.text = Some(v.to_owned());
55            }
56            MsgContent::Object(o) => {
57                ret.r#type = 1;
58                ret.content = Some(ProtobufTransform::transform(o)?);
59            }
60        }
61        Ok(ret)
62    }
63}
64
65#[derive(Clone, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
66#[cyfs_protobuf_type(crate::codec::protos::MsgDescContent)]
67pub struct MsgDescContent {
68    to: ObjectId,
69    content: MsgContent,
70}
71
72impl DescContent for MsgDescContent {
73    fn obj_type() -> u16 {
74        CoreObjectType::Msg as u16
75    }
76
77    fn format(&self) -> u8 {
78        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
79    }
80
81    type OwnerType = Option<ObjectId>;
82    type AreaType = SubDescNone;
83    type AuthorType = SubDescNone;
84    type PublicKeyType = SubDescNone;
85}
86
87type MsgType = NamedObjType<MsgDescContent, EmptyProtobufBodyContent>;
88type MsgBuilder = NamedObjectBuilder<MsgDescContent, EmptyProtobufBodyContent>;
89
90pub type MsgId = NamedObjectId<MsgType>;
91pub type Msg = NamedObjectBase<MsgType>;
92
93impl MsgDescContent {
94    pub fn create(to: ObjectId, content: MsgContent) -> Self {
95        Self { to, content }
96    }
97}
98
99pub trait MsgObject {
100    fn to(&self) -> &ObjectId;
101    fn create(owner: PeopleId, to: ObjectId, content: MsgContent) -> Self;
102    fn content(&self) -> &MsgContent;
103    fn id(&self) -> MsgId;
104    fn belongs(&self, id: &ObjectId) -> bool;
105}
106
107impl MsgObject for Msg {
108    fn to(&self) -> &ObjectId {
109        &self.desc().content().to
110    }
111
112    fn create(owner: PeopleId, to: ObjectId, content: MsgContent) -> Self {
113        let desc_content = MsgDescContent::create(to, content);
114        MsgBuilder::new(desc_content, EmptyProtobufBodyContent::default())
115            .owner(owner.into())
116            .build()
117    }
118
119    fn content(&self) -> &MsgContent {
120        &self.desc().content().content
121    }
122
123    fn id(&self) -> MsgId {
124        MsgId::try_from(self.desc().calculate_id()).unwrap()
125    }
126
127    fn belongs(&self, id: &ObjectId) -> bool {
128        // 判断消息是否属于id
129        if let Some(owner) = self.desc().owner().as_ref() {
130            if owner == id {
131                return true;
132            }
133        }
134
135        self.to() == id
136    }
137}