cyfs_core/common/
text.rs

1use crate::coreobj::CoreObjectType;
2use cyfs_base::*;
3use serde::Serialize;
4
5#[derive(Debug, Clone, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
6#[cyfs_protobuf_type(crate::codec::protos::TextDescContent)]
7pub struct TextDescContent {
8    id: String,
9    header: String,
10}
11impl TextDescContent {
12    pub fn id(&self) -> &str {
13        &self.id
14    }
15
16    pub fn header(&self) -> &str {
17        &self.header
18    }
19
20    pub fn header_mut(&mut self) -> &mut String {
21        &mut self.header
22    }
23}
24
25impl DescContent for TextDescContent {
26    fn obj_type() -> u16 {
27        CoreObjectType::Text as u16
28    }
29
30    fn format(&self) -> u8 {
31        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
32    }
33
34    type OwnerType = Option<ObjectId>;
35    type AreaType = SubDescNone;
36    type AuthorType = SubDescNone;
37    type PublicKeyType = SubDescNone;
38}
39
40#[derive(Clone, Debug, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
41#[cyfs_protobuf_type(crate::codec::protos::TextContent)]
42pub struct TextContent {
43    value: String,
44}
45
46impl BodyContent for TextContent {
47    fn format(&self) -> u8 {
48        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
49    }
50}
51
52impl TextContent {
53    pub fn value(&self) -> &str {
54        &self.value
55    }
56
57    pub fn value_mut(&mut self) -> &mut String {
58        &mut self.value
59    }
60}
61
62type TextType = NamedObjType<TextDescContent, TextContent>;
63type TextBuilder = NamedObjectBuilder<TextDescContent, TextContent>;
64type TextDesc = NamedObjectDesc<TextDescContent>;
65
66pub type TextId = NamedObjectId<TextType>;
67pub type Text = NamedObjectBase<TextType>;
68
69pub trait TextObj {
70    fn build(id: &str, header: impl Into<String>, value: impl Into<String>) -> TextBuilder;
71    fn create(id: &str, header: impl Into<String>, value: impl Into<String>) -> Self;
72
73    fn id(&self) -> &str;
74
75    fn header(&self) -> &str;
76    fn header_mut(&mut self) -> &mut String;
77
78    fn value(&self) -> &str;
79    fn value_mut(&mut self) -> &mut String;
80
81    fn into_header(self) -> String;
82    fn into_value(self) -> String;
83
84    fn text_id(&self) -> TextId;
85}
86
87impl TextObj for Text {
88    fn create(id: &str, header: impl Into<String>, value: impl Into<String>) -> Self {
89        Self::build(id, header, value).no_create_time().build()
90    }
91
92    fn build(id: &str, header: impl Into<String>, value: impl Into<String>) -> TextBuilder {
93        let desc = TextDescContent {
94            id: id.to_owned(),
95            header: header.into(),
96        };
97        let body = TextContent {
98            value: value.into(),
99        };
100        TextBuilder::new(desc, body)
101    }
102
103    fn id(&self) -> &str {
104        &self.desc().content().id
105    }
106
107    fn header(&self) -> &str {
108        &self.desc().content().header
109    }
110
111    fn header_mut(&mut self) -> &mut String {
112        self.desc_mut().content_mut().header_mut()
113    }
114
115    fn value(&self) -> &str {
116        self.body().as_ref().unwrap().content().value()
117    }
118
119    fn value_mut(&mut self) -> &mut String {
120        self.body_mut().as_mut().unwrap().content_mut().value_mut()
121    }
122
123    fn into_header(self) -> String {
124        self.into_desc().into_content().header
125    }
126
127    fn into_value(self) -> String {
128        self.into_body().unwrap().into_content().value.to_string()
129    }
130
131    fn text_id(&self) -> TextId {
132        self.desc().calculate_id().try_into().unwrap()
133    }
134}
135
136#[cfg(test)]
137mod test {
138    use crate::*;
139    use cyfs_base::*;
140
141    #[test]
142    fn test() {
143        let header = "cyfs system";
144        let value = "xxxxx";
145        let obj = Text::create("cyfs", header, value);
146        assert!(obj.desc().content().id() == "cyfs");
147
148        let obj2 = obj.clone();
149        let header2 = obj2.into_header();
150        assert_eq!(header2, header);
151
152        let obj2 = obj.clone();
153        let value2 = obj2.into_value();
154        assert_eq!(value2, value);
155
156        let value = "yyyyyyy";
157        let mut obj2 = obj.clone();
158        *obj2.value_mut() = value.to_owned();
159        let value2 = obj2.into_value();
160        assert_eq!(value2, value);
161    }
162
163    #[test]
164    fn test_empty() {
165        let text_obj = Text::create("", "", "");
166        let buf = text_obj.to_vec().unwrap();
167
168        println!("empty text_id: {}", text_obj.text_id());
169        let path = cyfs_util::get_app_data_dir("tests");
170        std::fs::create_dir_all(&path).unwrap();
171        let name = path.join("text_empty.desc");
172        std::fs::write(&name, buf).unwrap();
173    }
174
175    #[test]
176    fn test_codec() {
177        let id = "test_text";
178        let header = "test_header";
179        let value = "test_value";
180        let text_obj = Text::create(id, header, value);
181        let text_id = text_obj.desc().calculate_id();
182        let buf = text_obj.to_vec().unwrap();
183
184        let text_obj2 = Text::clone_from_slice(&buf).unwrap();
185        assert_eq!(text_id, text_obj2.desc().calculate_id());
186        assert_eq!(text_obj.id(), text_obj2.id());
187        assert_eq!(text_obj.header(), text_obj2.header());
188        assert_eq!(text_obj.value(), text_obj2.value());
189
190        let (any, left_buf) = AnyNamedObject::raw_decode(&buf).unwrap();
191        assert_eq!(left_buf.len(), 0);
192        info!("any id={}", any.calculate_id());
193        assert_eq!(text_id, any.calculate_id());
194
195        let buf2 = any.to_vec().unwrap();
196        assert_eq!(buf.len(), buf2.len());
197        assert_eq!(buf, buf2);
198
199        // 保存到文件
200        let path = cyfs_util::get_app_data_dir("tests");
201        std::fs::create_dir_all(&path).unwrap();
202        let name = path.join("text.desc");
203        std::fs::write(&name, buf2).unwrap();
204    }
205}