cyfs_core/app/
app_list.rs1use crate::app::app_status::AppStatus;
2use crate::codec::*;
3use crate::coreobj::CoreObjectType;
4use crate::{AppStatusObj, DecAppId};
5use cyfs_base::*;
6
7use serde::Serialize;
8
9use std::collections::HashMap;
10
11pub const APPLIST_APP_CATEGORY: &str = "app";
13pub const APPLIST_SERVICE_CATEGORY: &str = "service";
14
15#[derive(Clone, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
16#[cyfs_protobuf_type(crate::codec::protos::AppListDescContent)]
17pub struct AppListDescContent {
18 id: String,
19 category: String,
20}
21
22impl DescContent for AppListDescContent {
23 fn obj_type() -> u16 {
24 CoreObjectType::AppList as u16
25 }
26
27 fn format(&self) -> u8 {
28 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
29 }
30
31 type OwnerType = Option<ObjectId>;
32 type AreaType = SubDescNone;
33 type AuthorType = SubDescNone;
34 type PublicKeyType = SubDescNone;
35}
36
37#[derive(Clone, ProtobufEncode, ProtobufDecode, ProtobufTransformType)]
38#[cyfs_protobuf_type(crate::codec::protos::AppListContent)]
39pub struct AppListContent {
40 pub(crate) source: HashMap<DecAppId, AppStatus>,
41}
42
43impl BodyContent for AppListContent {
44 fn format(&self) -> u8 {
45 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
46 }
47}
48
49impl ProtobufTransform<protos::AppListContent> for AppListContent {
50 fn transform(value: protos::AppListContent) -> BuckyResult<Self> {
51 let mut source: HashMap<DecAppId, AppStatus> = HashMap::new();
52 for item in value.source {
53 let status = AppStatus::clone_from_slice(item.app_status.as_slice())?;
54 let app_id = DecAppId::clone_from_slice(item.app_id.as_slice())?;
55 if let Some(old) = source.insert(app_id, status) {
56 error!(
57 "decode AppListContent source but got repeated item: {}",
58 old.desc().calculate_id()
59 );
60 }
61 }
62
63 Ok(Self { source })
64 }
65}
66impl ProtobufTransform<&AppListContent> for protos::AppListContent {
67 fn transform(value: &AppListContent) -> BuckyResult<Self> {
68 let mut ret = Self { source: vec![] };
69 let mut list = Vec::new();
70 for (key, value) in &value.source {
71 let mut item = protos::AppListSourceItem {
72 app_id: vec![],
73 app_status: vec![],
74 };
75 item.app_id = key.to_vec()?;
76 item.app_status = value.to_vec()?;
77 list.push(item);
78 }
79 list.sort_by(|left, right| left.app_id.partial_cmp(&right.app_id).unwrap());
80
81 ret.source = list;
82
83 Ok(ret)
84 }
85}
86
87type AppListType = NamedObjType<AppListDescContent, AppListContent>;
88type AppListBuilder = NamedObjectBuilder<AppListDescContent, AppListContent>;
89type AppListDesc = NamedObjectDesc<AppListDescContent>;
90
91pub type AppListId = NamedObjectId<AppListType>;
92pub type AppList = NamedObjectBase<AppListType>;
93
94pub trait AppListObj {
95 fn create(owner: ObjectId, id: &str, category: &str) -> Self;
96 fn put(&mut self, app: AppStatus);
97 fn remove(&mut self, id: &DecAppId);
98 fn clear(&mut self);
99 fn app_list(&self) -> &HashMap<DecAppId, AppStatus>;
100 fn id(&self) -> &str;
101 fn category(&self) -> &str;
102 fn exists(&self, id: &DecAppId) -> bool;
103
104 fn generate_id(owner: ObjectId, id: &str, category: &str) -> ObjectId;
105}
106
107impl AppListObj for AppList {
108 fn create(owner: ObjectId, id: &str, category: &str) -> Self {
109 let body = AppListContent {
110 source: HashMap::new(),
111 };
112 let desc = AppListDescContent {
113 id: id.to_owned(),
114 category: category.to_owned(),
115 };
116 AppListBuilder::new(desc, body)
117 .owner(owner)
118 .no_create_time()
119 .build()
120 }
121
122 fn put(&mut self, app: AppStatus) {
123 let id = app.app_id().clone();
124 self.body_mut_expect("")
125 .content_mut()
126 .source
127 .insert(id, app);
128 self.body_mut_expect("")
129 .increase_update_time(bucky_time_now());
130 }
131
132 fn remove(&mut self, id: &DecAppId) {
133 self.body_mut_expect("").content_mut().source.remove(id);
134 self.body_mut_expect("")
135 .increase_update_time(bucky_time_now());
136 }
137
138 fn clear(&mut self) {
139 self.body_mut_expect("").content_mut().source.clear();
140 self.body_mut_expect("")
141 .increase_update_time(bucky_time_now());
142 }
143
144 fn app_list(&self) -> &HashMap<DecAppId, AppStatus> {
145 &self.body_expect("").content().source
146 }
147
148 fn id(&self) -> &str {
149 &self.desc().content().id
150 }
151
152 fn category(&self) -> &str {
153 &self.desc().content().category
154 }
155
156 fn exists(&self, id: &DecAppId) -> bool {
157 self.body_expect("").content().source.contains_key(id)
158 }
159
160 fn generate_id(owner: ObjectId, id: &str, category: &str) -> ObjectId {
161 Self::create(owner, id, category).desc().calculate_id()
162 }
163}