cyfs_core/storage/
storage.rs

1use crate::coreobj::CoreObjectType;
2use cyfs_base::*;
3use serde::Serialize;
4
5#[derive(Debug, Clone, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
6#[cyfs_protobuf_type(crate::codec::protos::StorageDescContent)]
7pub struct StorageDescContent {
8    id: String,
9    hash: Option<HashValue>,
10}
11
12impl DescContent for StorageDescContent {
13    fn obj_type() -> u16 {
14        CoreObjectType::Storage as u16
15    }
16
17    fn format(&self) -> u8 {
18        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
19    }
20
21    type OwnerType = Option<ObjectId>;
22    type AreaType = SubDescNone;
23    type AuthorType = SubDescNone;
24    type PublicKeyType = SubDescNone;
25}
26
27#[derive(Clone, Debug, ProtobufEncode, ProtobufDecode, ProtobufTransform)]
28#[cyfs_protobuf_type(crate::codec::protos::StorageBodyContent)]
29pub struct StorageBodyContent {
30    pub(crate) value: Vec<u8>,
31}
32
33impl BodyContent for StorageBodyContent {
34    fn format(&self) -> u8 {
35        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
36    }
37}
38
39type StorageType = NamedObjType<StorageDescContent, StorageBodyContent>;
40type StorageBuilder = NamedObjectBuilder<StorageDescContent, StorageBodyContent>;
41type StorageDesc = NamedObjectDesc<StorageDescContent>;
42
43pub type StorageId = NamedObjectId<StorageType>;
44pub type Storage = NamedObjectBase<StorageType>;
45
46pub trait StorageObj {
47    fn create(id: &str, value: Vec<u8>) -> Self;
48    fn create_with_hash(id: &str, value: Vec<u8>) -> Self;
49
50    fn id(&self) -> &str;
51    fn hash(&self) -> &Option<HashValue>;
52
53    fn value(&self) -> &Vec<u8>;
54    fn value_mut(&mut self) -> &mut Vec<u8>;
55
56    fn update_value(&mut self, value: Vec<u8>) -> bool;
57    fn into_value(self) -> Vec<u8>;
58
59    fn storage_id(&self) -> StorageId;
60}
61
62impl StorageObj for Storage {
63    fn create(id: &str, value: Vec<u8>) -> Self {
64        let body = StorageBodyContent { value };
65        let desc = StorageDescContent {
66            id: id.to_owned(),
67            hash: None,
68        };
69        StorageBuilder::new(desc, body).no_create_time().build()
70    }
71
72    fn create_with_hash(id: &str, value: Vec<u8>) -> Self {
73        let desc = StorageDescContent {
74            id: id.to_owned(),
75            hash: Some(hash_data(&value)),
76        };
77        let body = StorageBodyContent { value };
78        StorageBuilder::new(desc, body).no_create_time().build()
79    }
80
81    fn id(&self) -> &str {
82        &self.desc().content().id
83    }
84
85    fn hash(&self) -> &Option<HashValue> {
86        &self.desc().content().hash
87    }
88
89    fn value(&self) -> &Vec<u8> {
90        &self.body().as_ref().unwrap().content().value
91    }
92
93    fn value_mut(&mut self) -> &mut Vec<u8> {
94        &mut self.body_mut().as_mut().unwrap().content_mut().value
95    }
96
97    fn into_value(self) -> Vec<u8> {
98        self.into_body().unwrap().into_content().value
99    }
100
101    fn update_value(&mut self, value: Vec<u8>) -> bool {
102        let need_hash = self.desc().content().hash.is_some();
103
104        let mut hash = None;
105        {
106            let current_value = self.value_mut();
107
108            if *current_value == value {
109                return false;
110            }
111
112            if need_hash {
113                hash = Some(hash_data(&value));
114            }
115
116            *current_value = value;
117        }
118
119        if hash.is_some() {
120            self.desc_mut().content_mut().hash = hash;
121        }
122
123        self.body_mut()
124            .as_mut()
125            .unwrap()
126            .set_update_time(bucky_time_now());
127
128        true
129    }
130
131    fn storage_id(&self) -> StorageId {
132        self.desc().calculate_id().try_into().unwrap()
133    }
134}
135
136#[cfg(test)]
137mod test {
138    use crate::*;
139    use cyfs_base::*;
140
141    #[test]
142    fn test() {
143        let id = "test_storage";
144        let s = "self.desc().calculate_id().try_into().unwrap()".to_owned();
145        let value = s.to_vec().unwrap();
146        let storage_obj = Storage::create(id, value.clone());
147        let storage_id = storage_obj.desc().calculate_id();
148        let buf = storage_obj.to_vec().unwrap();
149
150        let storage_obj2 = Storage::clone_from_slice(&buf).unwrap();
151        assert_eq!(storage_id, storage_obj2.desc().calculate_id());
152        assert_eq!(storage_obj.id(), storage_obj2.id());
153        assert_eq!(*storage_obj.value(), *storage_obj2.value());
154
155        let (any, left_buf) = AnyNamedObject::raw_decode(&buf).unwrap();
156        assert_eq!(left_buf.len(), 0);
157        info!("any id={}", any.calculate_id());
158        assert_eq!(storage_id, any.calculate_id());
159
160        let buf2 = any.to_vec().unwrap();
161        assert_eq!(buf.len(), buf2.len());
162        assert_eq!(buf, buf2);
163    }
164}