1use crate::*;
2
3#[derive(Clone, Debug)]
4pub enum StandardObject {
5 Device(Device),
6 People(People),
7 AppGroup(AppGroup),
8 UnionAccount(UnionAccount),
9 ChunkId(ChunkId),
10 File(File),
11 Dir(Dir),
12 Diff(Diff),
13 ProofOfService(ProofOfService),
14 Tx(Tx),
15 Action(Action),
16 ObjectMap(ObjectMap),
17 Contract(Contract),
18 Group(Group),
19}
20
21#[macro_export]
22macro_rules! match_standard_obj {
23 ($on:ident, $o:ident, $body:tt, $chunk_id:ident, $chunk_body:tt) => {
24 match $on {
25 StandardObject::Device($o) => $body,
26 StandardObject::People($o) => $body,
27 StandardObject::Group($o) => $body,
28 StandardObject::AppGroup($o) => $body,
29 StandardObject::UnionAccount($o) => $body,
30 StandardObject::ChunkId($chunk_id) => $chunk_body,
31 StandardObject::File($o) => $body,
32 StandardObject::Dir($o) => $body,
33 StandardObject::Diff($o) => $body,
34 StandardObject::ProofOfService($o) => $body,
35 StandardObject::Tx($o) => $body,
36 StandardObject::Action($o) => $body,
37 StandardObject::ObjectMap($o) => $body,
38 StandardObject::Contract($o) => $body,
39 }
40 };
41}
42
43macro_rules! match_standard_owner_obj {
44 ($on:ident, $o:ident, $body:tt, $other_body:tt) => {
45 match $on {
46 StandardObject::Device($o) => $body,
47 StandardObject::People($o) => $body,
48 StandardObject::Contract($o) => $body,
49 StandardObject::File($o) => $body,
50 StandardObject::Dir($o) => $body,
51 StandardObject::Diff($o) => $body,
52 StandardObject::ProofOfService($o) => $body,
53 StandardObject::Action($o) => $body,
54 StandardObject::ObjectMap($o) => $body,
55 _ => $other_body,
56 }
57 };
58}
59
60macro_rules! match_standard_pubkey_obj {
61 ($on:ident, $o:ident, $body:tt, $other_body:tt) => {
62 match $on {
63 StandardObject::Device($o) => $body,
64 StandardObject::People($o) => $body,
65 _ => $other_body,
67 }
68 };
69}
70
71macro_rules! match_standard_author_obj {
72 ($on:ident, $o:ident, $body:tt, $other_body:tt) => {
73 match $on {
74 StandardObject::File($o) => $body,
75 StandardObject::Contract($o) => $body,
76 _ => $other_body,
77 }
78 };
79}
80
81macro_rules! match_standard_ood_list_obj {
82 ($on:ident, $o:ident, $body:tt, $other_body:tt) => {
83 match $on {
84 StandardObject::Group($o) => $body,
85 StandardObject::People($o) => $body,
86 _ => $other_body,
87 }
88 };
89}
90
91macro_rules! match_standard_ood_work_mode_obj {
92 ($on:ident, $o:ident, $body:tt, $other_body:tt) => {
93 match $on {
94 StandardObject::People($o) => $body,
95 _ => $other_body,
96 }
97 };
98}
99
100impl StandardObject {
101 pub fn calculate_id(&self) -> ObjectId {
102 match_standard_obj!(self, o, { o.desc().calculate_id() }, chunk_id, {
103 chunk_id.object_id()
104 })
105 }
106
107 pub fn obj_type(&self) -> BuckyResult<u16> {
108 match_standard_obj!(self, o, { Ok(o.desc().obj_type()) }, _chunk_id, {
109 Ok(ObjectTypeCode::Chunk.to_u16())
110 })
111 }
112
113 pub fn obj_type_code(&self) -> ObjectTypeCode {
114 match_standard_obj!(self, o, { o.desc().obj_type_code() }, _chunk_id, {
115 ObjectTypeCode::Chunk
116 })
117 }
118
119 pub fn dec_id(&self) -> &Option<ObjectId> {
120 match_standard_obj!(self, o, { o.desc().dec_id() }, _chunk_id, { &None })
121 }
122
123 pub fn owner(&self) -> &Option<ObjectId> {
124 match_standard_owner_obj!(self, o, { o.desc().owner() }, { &None })
125 }
126
127 pub fn prev(&self) -> &Option<ObjectId> {
128 match_standard_owner_obj!(self, o, { o.desc().prev() }, { &None })
129 }
130
131 pub fn public_key(&self) -> Option<PublicKeyRef> {
132 match_standard_pubkey_obj!(self, o, { o.desc().public_key_ref() }, { None })
133 }
134
135 pub fn author(&self) -> &Option<ObjectId> {
136 match_standard_author_obj!(self, o, { o.desc().author() }, { &None })
137 }
138
139 pub fn ood_list(&self) -> BuckyResult<&Vec<DeviceId>> {
140 match_standard_ood_list_obj!(
141 self,
142 o,
143 {
144 let b = o.body().as_ref();
145 if b.is_none() {
146 Err(BuckyError::new(BuckyErrorCode::NotFound, "missing body"))
147 } else {
148 let b = b.unwrap();
149 Ok(b.content().ood_list())
150 }
151 },
152 {
153 Err(BuckyError::new(
154 BuckyErrorCode::NotSupport,
155 "ood_list not support",
156 ))
157 }
158 )
159 }
160
161 pub fn ood_work_mode(&self) -> BuckyResult<OODWorkMode> {
162 match_standard_ood_work_mode_obj!(
163 self,
164 o,
165 {
166 let b = o.body().as_ref();
167 if b.is_none() {
168 Err(BuckyError::new(BuckyErrorCode::NotFound, "missing body"))
169 } else {
170 let b = b.unwrap();
171 Ok(b.content().ood_work_mode())
172 }
173 },
174 {
175 Err(BuckyError::new(
176 BuckyErrorCode::NotSupport,
177 "ood_work_mode not support",
178 ))
179 }
180 )
181 }
182
183 pub fn set_body_expect(&mut self, other: &Self) {
184 match self {
185 Self::Device(o) => match other {
186 Self::Device(other) => {
187 *o.body_mut() = other.body().clone();
188 }
189 _ => unreachable!(),
190 },
191 Self::People(o) => match other {
192 Self::People(other) => {
193 *o.body_mut() = other.body().clone();
194 }
195 _ => unreachable!(),
196 },
197 Self::Group(o) => match other {
198 Self::Group(other) => {
199 *o.body_mut() = other.body().clone();
200 }
201 _ => unreachable!(),
202 },
203 Self::AppGroup(o) => match other {
204 Self::AppGroup(other) => {
205 *o.body_mut() = other.body().clone();
206 }
207 _ => unreachable!(),
208 },
209 Self::UnionAccount(o) => match other {
210 Self::UnionAccount(other) => {
211 *o.body_mut() = other.body().clone();
212 }
213 _ => unreachable!(),
214 },
215 Self::File(o) => match other {
216 Self::File(other) => {
217 *o.body_mut() = other.body().clone();
218 }
219 _ => unreachable!(),
220 },
221 Self::Dir(o) => match other {
222 Self::Dir(other) => {
223 *o.body_mut() = other.body().clone();
224 }
225 _ => unreachable!(),
226 },
227 Self::Diff(o) => match other {
228 Self::Diff(other) => {
229 *o.body_mut() = other.body().clone();
230 }
231 _ => unreachable!(),
232 },
233 Self::ProofOfService(o) => match other {
234 Self::ProofOfService(other) => {
235 *o.body_mut() = other.body().clone();
236 }
237 _ => unreachable!(),
238 },
239 Self::Tx(o) => match other {
240 Self::Tx(other) => {
241 *o.body_mut() = other.body().clone();
242 }
243 _ => unreachable!(),
244 },
245 Self::Action(o) => match other {
246 Self::Action(other) => {
247 *o.body_mut() = other.body().clone();
248 }
249 _ => unreachable!(),
250 },
251 Self::ObjectMap(o) => match other {
252 Self::ObjectMap(other) => {
253 *o.body_mut() = other.body().clone();
254 }
255 _ => unreachable!(),
256 },
257 Self::Contract(o) => match other {
258 Self::Contract(other) => {
259 *o.body_mut() = other.body().clone();
260 }
261 _ => unreachable!(),
262 },
263 Self::ChunkId(_) => {
264 unreachable!();
265 }
266 }
267 }
268}
269
270impl RawEncode for StandardObject {
271 fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
272 match self {
273 StandardObject::Device(o) => o.raw_measure(purpose),
274 StandardObject::People(o) => o.raw_measure(purpose),
275 StandardObject::Group(o) => o.raw_measure(purpose),
276 StandardObject::AppGroup(o) => o.raw_measure(purpose),
277 StandardObject::UnionAccount(o) => o.raw_measure(purpose),
278 StandardObject::ChunkId(o) => o.raw_measure(purpose),
279 StandardObject::File(o) => o.raw_measure(purpose),
280 StandardObject::Dir(o) => o.raw_measure(purpose),
281 StandardObject::Diff(o) => o.raw_measure(purpose),
282 StandardObject::ProofOfService(o) => o.raw_measure(purpose),
283 StandardObject::Tx(o) => o.raw_measure(purpose),
284 StandardObject::Action(o) => o.raw_measure(purpose),
285 StandardObject::ObjectMap(o) => o.raw_measure(purpose),
286 StandardObject::Contract(o) => o.raw_measure(purpose),
287 }
288 }
289
290 fn raw_encode<'a>(
291 &self,
292 buf: &'a mut [u8],
293 purpose: &Option<RawEncodePurpose>,
294 ) -> BuckyResult<&'a mut [u8]> {
295 match self {
296 StandardObject::Device(o) => o.raw_encode(buf, purpose),
297 StandardObject::People(o) => o.raw_encode(buf, purpose),
298 StandardObject::Group(o) => o.raw_encode(buf, purpose),
299 StandardObject::AppGroup(o) => o.raw_encode(buf, purpose),
300 StandardObject::UnionAccount(o) => o.raw_encode(buf, purpose),
301 StandardObject::ChunkId(o) => o.raw_encode(buf, purpose),
302 StandardObject::File(o) => o.raw_encode(buf, purpose),
303 StandardObject::Dir(o) => o.raw_encode(buf, purpose),
304 StandardObject::Diff(o) => o.raw_encode(buf, purpose),
305 StandardObject::ProofOfService(o) => o.raw_encode(buf, purpose),
306 StandardObject::Tx(o) => o.raw_encode(buf, purpose),
307 StandardObject::Action(o) => o.raw_encode(buf, purpose),
308 StandardObject::ObjectMap(o) => o.raw_encode(buf, purpose),
309 StandardObject::Contract(o) => o.raw_encode(buf, purpose),
310 }
311 }
312}
313
314impl<'de> RawDecode<'de> for StandardObject {
316 fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
317 let (ctx, _) = NamedObjectContext::raw_decode(buf).map_err(|e| {
318 log::error!("StandardObject::raw_decode/NamedObjectContext error:{}", e);
319 e
320 })?;
321
322 match ctx.obj_type_code() {
323 ObjectTypeCode::Device => {
324 Device::raw_decode(buf).map(|(obj, buf)| (StandardObject::Device(obj), buf))
325 }
326 ObjectTypeCode::People => {
327 People::raw_decode(buf).map(|(obj, buf)| (StandardObject::People(obj), buf))
328 }
329 ObjectTypeCode::Group => {
330 Group::raw_decode(buf).map(|(obj, buf)| (StandardObject::Group(obj), buf))
331 }
332 ObjectTypeCode::AppGroup => {
333 AppGroup::raw_decode(buf).map(|(obj, buf)| (StandardObject::AppGroup(obj), buf))
334 }
335 ObjectTypeCode::UnionAccount => UnionAccount::raw_decode(buf)
336 .map(|(obj, buf)| (StandardObject::UnionAccount(obj), buf)),
337 ObjectTypeCode::Chunk => {
338 ChunkId::raw_decode(buf).map(|(obj, buf)| (StandardObject::ChunkId(obj), buf))
339 }
340 ObjectTypeCode::File => {
341 File::raw_decode(buf).map(|(obj, buf)| (StandardObject::File(obj), buf))
342 }
343 ObjectTypeCode::Dir => {
344 Dir::raw_decode(buf).map(|(obj, buf)| (StandardObject::Dir(obj), buf))
345 }
346 ObjectTypeCode::Diff => {
347 Diff::raw_decode(buf).map(|(obj, buf)| (StandardObject::Diff(obj), buf))
348 }
349 ObjectTypeCode::ProofOfService => ProofOfService::raw_decode(buf)
350 .map(|(obj, buf)| (StandardObject::ProofOfService(obj), buf)),
351 ObjectTypeCode::Tx => {
352 Tx::raw_decode(buf).map(|(obj, buf)| (StandardObject::Tx(obj), buf))
353 }
354 ObjectTypeCode::Action => {
355 Action::raw_decode(buf).map(|(obj, buf)| (StandardObject::Action(obj), buf))
356 }
357 ObjectTypeCode::ObjectMap => {
358 ObjectMap::raw_decode(buf).map(|(obj, buf)| (StandardObject::ObjectMap(obj), buf))
359 }
360 ObjectTypeCode::Contract => {
361 Contract::raw_decode(buf).map(|(obj, buf)| (StandardObject::Contract(obj), buf))
362 }
363 _ => {
364 unreachable!();
365 }
366 }
367 }
368}