cyfs_lib/admin/
admin_object.rs

1use crate::root_state::*;
2use cyfs_base::*;
3use cyfs_core::codec::protos::core_objects as protos;
4use cyfs_core::*;
5
6use std::convert::{TryFrom, TryInto};
7use serde::Serialize;
8
9#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
10pub struct AdminGlobalStateAccessModeData {
11    pub category: GlobalStateCategory,
12    pub access_mode: GlobalStateAccessMode,
13}
14
15#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
16pub enum AdminCommand {
17    GlobalStateAccessMode(AdminGlobalStateAccessModeData),
18}
19
20#[derive(Debug, Clone, Serialize)]
21pub struct AdminDescContent {
22    pub target: DeviceId,
23    pub cmd: AdminCommand,
24}
25
26impl DescContent for AdminDescContent {
27    fn obj_type() -> u16 {
28        CoreObjectType::Admin as u16
29    }
30
31    fn format(&self) -> u8 {
32        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
33    }
34
35    type OwnerType = Option<ObjectId>;
36    type AreaType = SubDescNone;
37    type AuthorType = SubDescNone;
38    type PublicKeyType = SubDescNone;
39}
40
41
42#[derive(Debug, Clone, Serialize)]
43pub struct AdminBodyContent {}
44
45impl BodyContent for AdminBodyContent {
46    fn format(&self) -> u8 {
47        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
48    }
49}
50
51type AdminObjectType = NamedObjType<AdminDescContent, AdminBodyContent>;
52type AdminObjectBuilder = NamedObjectBuilder<AdminDescContent, AdminBodyContent>;
53type AdminObjectDesc = NamedObjectDesc<AdminDescContent>;
54
55pub type AdminObjectId = NamedObjectId<AdminObjectType>;
56pub type AdminObject = NamedObjectBase<AdminObjectType>;
57
58impl TryFrom<protos::AdminGlobalStateAccessModeData> for AdminGlobalStateAccessModeData {
59    type Error = BuckyError;
60
61    fn try_from(value: protos::AdminGlobalStateAccessModeData) -> BuckyResult<Self> {
62        let category = match value.category {
63            protos::AdminGlobalStateAccessModeData_Category::RootState => {
64                GlobalStateCategory::RootState
65            }
66            protos::AdminGlobalStateAccessModeData_Category::LocalCache => {
67                GlobalStateCategory::LocalCache
68            }
69        };
70
71        let access_mode = match value.access_mode {
72            protos::AdminGlobalStateAccessModeData_AccessMode::Read => GlobalStateAccessMode::Read,
73            protos::AdminGlobalStateAccessModeData_AccessMode::Write => {
74                GlobalStateAccessMode::Write
75            }
76        };
77
78        Ok(Self {
79            category,
80            access_mode,
81        })
82    }
83}
84
85impl TryFrom<&AdminGlobalStateAccessModeData> for protos::AdminGlobalStateAccessModeData {
86    type Error = BuckyError;
87
88    fn try_from(value: &AdminGlobalStateAccessModeData) -> BuckyResult<Self> {
89        let category = match value.category {
90            GlobalStateCategory::RootState => {
91                protos::AdminGlobalStateAccessModeData_Category::RootState
92            }
93            GlobalStateCategory::LocalCache => {
94                protos::AdminGlobalStateAccessModeData_Category::LocalCache
95            }
96        };
97
98        let access_mode = match value.access_mode {
99            GlobalStateAccessMode::Read => protos::AdminGlobalStateAccessModeData_AccessMode::Read,
100            GlobalStateAccessMode::Write => {
101                protos::AdminGlobalStateAccessModeData_AccessMode::Write
102            }
103        };
104
105        let mut ret = Self::new();
106        ret.set_category(category);
107        ret.set_access_mode(access_mode);
108
109        Ok(ret)
110    }
111}
112
113impl_default_protobuf_raw_codec!(AdminGlobalStateAccessModeData);
114
115impl TryFrom<protos::AdminDescContent> for AdminDescContent {
116    type Error = BuckyError;
117
118    fn try_from(mut value: protos::AdminDescContent) -> BuckyResult<Self> {
119        let cmd = match value.cmd {
120            protos::AdminDescContent_Command::GlobalStateAccessMode => {
121                if !value.has_global_state_access_mode() {
122                    let msg = format!(
123                        "invalid AdminDescContent global_state_access_mode field! {:?}",
124                        value
125                    );
126                    error!("{}", msg);
127                    return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
128                }
129
130                let data =
131                    ProtobufCodecHelper::decode_nested_item(value.take_global_state_access_mode())?;
132                AdminCommand::GlobalStateAccessMode(data)
133            }
134        };
135
136        let target = ProtobufCodecHelper::decode_buf(value.take_target())?;
137
138        let ret = Self { target, cmd };
139
140        Ok(ret)
141    }
142}
143
144impl TryFrom<&AdminDescContent> for protos::AdminDescContent {
145    type Error = BuckyError;
146
147    fn try_from(value: &AdminDescContent) -> BuckyResult<Self> {
148        let mut ret = protos::AdminDescContent::new();
149
150        match value.cmd {
151            AdminCommand::GlobalStateAccessMode(ref data) => {
152                let data = data.try_into()?;
153                ret.set_global_state_access_mode(data);
154            }
155        }
156
157        ret.set_target(value.target.to_vec().unwrap());
158
159        Ok(ret)
160    }
161}
162
163impl_default_protobuf_raw_codec!(AdminDescContent);
164impl_empty_protobuf_raw_codec!(AdminBodyContent);
165
166impl ObjectFormatAutoWithSerde for AdminDescContent {}
167impl ObjectFormatAutoWithSerde for AdminBodyContent {}
168
169pub trait AdminObj {
170    fn create(owner: ObjectId, target: DeviceId, cmd: AdminCommand) -> Self;
171
172    fn target(&self) -> &DeviceId;
173
174    fn into_command(self) -> AdminCommand;
175}
176
177impl AdminObj for AdminObject {
178    fn create(owner: ObjectId, target: DeviceId, cmd: AdminCommand) -> Self {
179        let desc = AdminDescContent { target, cmd };
180
181        let body = AdminBodyContent {};
182
183        AdminObjectBuilder::new(desc, body).owner(owner).build()
184    }
185
186    fn target(&self) -> &DeviceId {
187        &self.desc().content().target
188    }
189
190    fn into_command(self) -> AdminCommand {
191        self.into_desc().into_content().cmd
192    }
193}
194
195
196#[cfg(test)]
197mod test {
198    use cyfs_base::*;
199    use crate::*;
200
201    use std::str::FromStr;
202
203    #[test]
204    fn test_object() {
205        let data = AdminGlobalStateAccessModeData {
206            category: GlobalStateCategory::RootState,
207            access_mode: GlobalStateAccessMode::Read,
208        };
209
210        let cmd = AdminCommand::GlobalStateAccessMode(data);
211
212        let target = DeviceId::from_str("5aSixgLkHa2NR4vSKJLYLPo5Av6CY3RJeFJegtF5iR1g").unwrap();
213        let owner = PeopleId::default();
214        let obj = AdminObject::create(owner.into(), target.clone(), cmd.clone());
215        let buf = obj.to_vec().unwrap();
216        println!("{}", hex::encode(&buf));
217
218        let obj = AdminObject::clone_from_slice(&buf).unwrap();
219        assert_eq!(*obj.target(), target);
220        let c_cmd = obj.into_command();
221        assert_eq!(c_cmd, cmd);
222    }
223}