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