cyfs_core/app/
app_list.rs

1use 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
11// 一些内置的categroy
12pub 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}