cyfs_base/objects/
people.rs1use crate::codec as cyfs_base;
2use crate::*;
3use serde::Serialize;
4
5use std::convert::TryFrom;
6use std::str::FromStr;
7
8#[repr(u8)]
9#[derive(Clone, Debug, Eq, PartialEq, RawEncode, RawDecode, Serialize)]
10pub enum OODWorkMode {
11 Standalone = 0,
12 ActiveStandby = 1,
13}
14
15impl OODWorkMode {
16 pub fn as_str(&self) -> &str {
17 match &self {
18 Self::Standalone => "standalone",
19 Self::ActiveStandby => "active-standby",
20 }
21 }
22}
23
24impl std::fmt::Display for OODWorkMode {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, "{}", self.as_str())
27 }
28}
29
30impl FromStr for OODWorkMode {
31 type Err = BuckyError;
32 fn from_str(value: &str) -> Result<Self, Self::Err> {
33 let ret = match value {
34 "standalone" => Self::Standalone,
35 "active-standby" => Self::ActiveStandby,
36 _ => {
37 let msg = format!("unknown OODWorkMode: {}", value);
38 error!("{}", msg);
39
40 return Err(BuckyError::new(BuckyErrorCode::UnSupport, msg));
41 }
42 };
43
44 Ok(ret)
45 }
46}
47
48#[derive(Clone, Debug, RawEncode, RawDecode)]
49pub struct PeopleDescContent {}
50
51impl PeopleDescContent {
52 pub fn new() -> Self {
53 Self {}
54 }
55}
56
57impl DescContent for PeopleDescContent {
58 fn obj_type() -> u16 {
59 ObjectTypeCode::People.into()
60 }
61
62 type OwnerType = Option<ObjectId>;
63 type AreaType = Option<Area>;
64 type AuthorType = SubDescNone;
65 type PublicKeyType = PublicKey;
66}
67
68#[derive(Clone, Debug)]
69pub struct PeopleBodyContent {
70 ood_work_mode: Option<OODWorkMode>,
71 ood_list: Vec<DeviceId>,
72 name: Option<String>,
73 icon: Option<FileId>,
74}
75
76impl BodyContent for PeopleBodyContent {
77 fn format(&self) -> u8 {
78 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
79 }
80}
81
82impl TryFrom<protos::PeopleBodyContent> for PeopleBodyContent {
84 type Error = BuckyError;
85
86 fn try_from(mut value: protos::PeopleBodyContent) -> BuckyResult<Self> {
87 let mut ret = Self {
88 ood_work_mode: None,
89 ood_list: ProtobufCodecHelper::decode_buf_list(value.take_ood_list())?,
90 name: None,
91 icon: None,
92 };
93
94 if value.has_ood_work_mode() {
95 ret.ood_work_mode = Some(OODWorkMode::from_str(value.get_ood_work_mode())?);
96 }
97
98 if value.has_name() {
99 ret.name = Some(value.take_name());
100 }
101 if value.has_icon() {
102 ret.icon = Some(ProtobufCodecHelper::decode_buf(value.take_icon())?);
103 }
104
105 Ok(ret)
106 }
107}
108
109impl TryFrom<&PeopleBodyContent> for protos::PeopleBodyContent {
110 type Error = BuckyError;
111
112 fn try_from(value: &PeopleBodyContent) -> BuckyResult<Self> {
113 let mut ret = Self::new();
114 ret.set_ood_list(ProtobufCodecHelper::encode_buf_list(&value.ood_list)?);
115
116 if let Some(ood_work_mode) = &value.ood_work_mode {
117 ret.set_ood_work_mode(ood_work_mode.to_string());
118 }
119
120 if let Some(name) = &value.name {
121 ret.set_name(name.to_owned());
122 }
123 if let Some(icon) = &value.icon {
124 ret.set_icon(icon.to_vec()?);
125 }
126
127 Ok(ret)
128 }
129}
130
131crate::inner_impl_default_protobuf_raw_codec!(PeopleBodyContent);
132
133impl PeopleBodyContent {
134 pub fn new(
135 ood_work_mode: OODWorkMode,
136 ood_list: Vec<DeviceId>,
137 name: Option<String>,
138 icon: Option<FileId>,
139 ) -> Self {
140 Self {
141 ood_work_mode: Some(ood_work_mode),
142 ood_list,
143 name,
144 icon,
145 }
146 }
147
148 pub fn ood_work_mode(&self) -> OODWorkMode {
149 self.ood_work_mode.clone().unwrap_or(OODWorkMode::Standalone)
150 }
151
152 pub fn set_ood_work_mode(&mut self, ood_work_mode: OODWorkMode) {
153 self.ood_work_mode = Some(ood_work_mode);
154 }
155
156 pub fn ood_list(&self) -> &Vec<DeviceId> {
157 &self.ood_list
158 }
159
160 pub fn ood_list_mut(&mut self) -> &mut Vec<DeviceId> {
161 &mut self.ood_list
162 }
163
164 pub fn name(&self) -> Option<&str> {
165 self.name.as_ref().map(|f| f.as_str())
166 }
167 pub fn icon(&self) -> Option<&FileId> {
168 self.icon.as_ref()
169 }
170
171 pub fn set_name(&mut self, name: String) {
172 self.name = Some(name)
173 }
174 pub fn set_icon(&mut self, icon: FileId) {
175 self.icon = Some(icon)
176 }
177}
178
179pub type PeopleType = NamedObjType<PeopleDescContent, PeopleBodyContent>;
180pub type PeopleBuilder = NamedObjectBuilder<PeopleDescContent, PeopleBodyContent>;
181
182pub type PeopleDesc = NamedObjectDesc<PeopleDescContent>;
183pub type PeopleId = NamedObjectId<PeopleType>;
184pub type People = NamedObjectBase<PeopleType>;
185
186impl PeopleDesc {
187 pub fn people_id(&self) -> PeopleId {
188 PeopleId::try_from(self.calculate_id()).unwrap()
189 }
190}
191
192impl People {
193 pub fn new(
194 owner: Option<ObjectId>,
195 ood_list: Vec<DeviceId>,
196 public_key: PublicKey,
197 area: Option<Area>,
198 name: Option<String>,
199 icon: Option<FileId>,
200 ) -> PeopleBuilder {
201 let desc_content = PeopleDescContent::new();
202
203 let body_content = PeopleBodyContent::new(OODWorkMode::Standalone, ood_list, name, icon);
204
205 PeopleBuilder::new(desc_content, body_content)
206 .option_owner(owner)
207 .option_area(area)
208 .public_key(public_key)
209 }
210
211 pub fn ood_work_mode(&self) -> OODWorkMode {
212 self.body().as_ref().unwrap().content().ood_work_mode()
213 }
214
215 pub fn set_ood_work_mode(&mut self, ood_work_mode: OODWorkMode) {
216 self.body_mut()
217 .as_mut()
218 .unwrap()
219 .content_mut()
220 .set_ood_work_mode(ood_work_mode)
221 }
222
223 pub fn ood_list(&self) -> &Vec<DeviceId> {
224 self.body().as_ref().unwrap().content().ood_list()
225 }
226
227 pub fn ood_list_mut(&mut self) -> &mut Vec<DeviceId> {
228 self.body_mut()
229 .as_mut()
230 .unwrap()
231 .content_mut()
232 .ood_list_mut()
233 }
234
235 pub fn name(&self) -> Option<&str> {
236 self.body().as_ref().unwrap().content().name()
237 }
238 pub fn icon(&self) -> Option<&FileId> {
239 self.body().as_ref().unwrap().content().icon()
240 }
241
242 pub fn set_name(&mut self, name: String) {
243 self.body_mut()
244 .as_mut()
245 .unwrap()
246 .content_mut()
247 .set_name(name)
248 }
249 pub fn set_icon(&mut self, icon: FileId) {
250 self.body_mut()
251 .as_mut()
252 .unwrap()
253 .content_mut()
254 .set_icon(icon)
255 }
256}
257
258#[cfg(test)]
259mod test {
260 use crate::*;
261 const OLD_LIST: &'static [&'static str] = &[
265 "0002500e0000000000010030818902818100e0252144cac6aa8493f252c1c7d288afd9d01f04430a24f19bbd1f0fec428278b149f3b748e26a532c7e238dcdde6fb60d3820727f53b7ae090ce1bb04f637d43aea4551043a06535ded73e6a7de845e6a6187cfcd4def56b841fd098afc0671f659bfbabd1fbceb268b6fa0f47b8c7e3cb698a2d6ba120e54b6df9064c889ed0203010001000000000000000000000000000000000000000000000000000000002f3b2f6e3acd900001390a2045c40d30000cd65e863aa69f59d818f2090e3fa3b3d646dadc87568f773da50c12096275636b7962616c6c220a7374616e64616c6f6e650100ff002f3b2f6e3ad56000c661eeddb115b2b1cc8f6a0abe871b83c3108379c766303457676e1beca4836220767e72cac8fa53b3addff7686a604ee5537b4593d7ef363dcfd827dace32a51fb46c527330d6cb1a2bf37a4fcc4d6bae9ed5acf0289c7f6fa3e957c4a11362bf237746a253edd574c59acf85705d36747dd83ac65acd0995c201e76be7db5f0100ff002f3b2f6e3e09b000bb6a8d783a3be84580323e7e70b7aeb0c277c60c09705218fe77eb5a527df5cfdfe738d05c0661c9e06f59c883d7b314d4709d56675cecdde81bbb72dc692c5413c9a39f81aaf7fd928319f7bd4183132ab3c383b6e39a924a87ba1608133cbd2a6bdfeb2e613752971d24c944ed666ed5d50c9a77177ab4077143c5354f90c2",
267 "0002500e0000000000010030818902818100e0252144cac6aa8493f252c1c7d288afd9d01f04430a24f19bbd1f0fec428278b149f3b748e26a532c7e238dcdde6fb60d3820727f53b7ae090ce1bb04f637d43aea4551043a06535ded73e6a7de845e6a6187cfcd4def56b841fd098afc0671f659bfbabd1fbceb268b6fa0f47b8c7e3cb698a2d6ba120e54b6df9064c889ed0203010001000000000000000000000000000000000000000000000000000000002f3b2f6e3acd9000013f0a2045c40d30000cd65e863aa69f59d818f2090e3fa3b3d646dadc87568f773da50c120fe7bab3e696afe8b59be58d9ae4bcaf220a7374616e64616c6f6e650100ff002f3b2f6e3ad56000c661eeddb115b2b1cc8f6a0abe871b83c3108379c766303457676e1beca4836220767e72cac8fa53b3addff7686a604ee5537b4593d7ef363dcfd827dace32a51fb46c527330d6cb1a2bf37a4fcc4d6bae9ed5acf0289c7f6fa3e957c4a11362bf237746a253edd574c59acf85705d36747dd83ac65acd0995c201e76be7db5f0100ff002f3b2f6e3e09b000bb6a8d783a3be84580323e7e70b7aeb0c277c60c09705218fe77eb5a527df5cfdfe738d05c0661c9e06f59c883d7b314d4709d56675cecdde81bbb72dc692c5413c9a39f81aaf7fd928319f7bd4183132ab3c383b6e39a924a87ba1608133cbd2a6bdfeb2e613752971d24c944ed666ed5d50c9a77177ab4077143c5354f90c2",
268 ];
269
270 #[test]
271 fn test_codec_with_author() {
272 let data = "000262220564656369640000000000000000000000000000000000000000000000000000002f4f8b051af10806617574686f7200000000000000000000000000000000000000000000000000010030818902818100e6f0a1f6d3ca953f315039103eea4f3bf4f4e4acab178a3f6552d45bb3352fb875a386c51ef0eeed2ed4c49faabcf47c252333cd8d809fcc237dcb537276e8ee71a6b96a881c1c177bce51ecd5222dc08f37bdf9d461d6f751fe49d3070faaf07708bb82e59e0ec839351fdd88c4bb344e4366895f12444608e8b2160112e6bd0203010001000000000000000000000000000000000000000000000000000000002f4f8b051af108000100";
273 let buf = hex::decode(data).unwrap();
274 People::clone_from_slice(&buf).unwrap_err();
275 }
276
277 #[test]
278 fn test_codec() {
279 for code in OLD_LIST {
280 let code = hex::decode(code).unwrap();
281 let people = People::clone_from_slice(&code).unwrap();
282
283 println!("ood list: {:?}", people.ood_list());
284 println!("ood_work_mode: {}, name={:?}", people.ood_work_mode(), people.name());
285 let hash = people.body().as_ref().unwrap().raw_hash_value().unwrap();
286 println!("desc hash: {}", hash);
287
288 let new_buf = people.to_vec().unwrap();
289 assert_eq!(code.len(), new_buf.len());
290
291 println!("code: {:?}", code);
292 assert_eq!(code, new_buf);
293 }
294 }
295
296 #[test]
297 fn people() {
298 let private_key = PrivateKey::generate_rsa(1024).unwrap();
299
300 let pubic_key = private_key.public();
301
302 let mut p = People::new(None, Vec::new(), pubic_key.clone(), None, None, None)
303 .no_create_time()
304 .build();
305
306 let p2 = People::new(None, Vec::new(), pubic_key, None, None, None)
307 .no_create_time()
308 .build();
309
310 assert!(p.desc().people_id() == p2.desc().people_id());
311
312 p.set_name("people".to_owned());
313
314 let user_data = vec![0u8; 100];
320 let _ = p.body_mut().as_mut().unwrap().set_userdata(&user_data);
321
322 let buf = p.to_vec().unwrap();
323 let pp = People::clone_from_slice(&buf).unwrap();
324
325 assert_eq!(p.desc().people_id(), pp.desc().people_id());
326 assert_eq!(p.name(), pp.name());
327 }
328}