common/bucket/
manifest.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6use crate::crypto::{PublicKey, Secret, Share, ShareError};
7use crate::linked_data::{BlockEncoded, DagCborCodec, Link};
8use crate::version::Version;
9
10use super::principal::{Principal, PrincipalRole};
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13pub struct BucketShare {
14 principal: Principal,
15 share: Share,
16}
17
18impl BucketShare {
19 pub fn new(share: Share, public_key: PublicKey) -> Self {
20 Self {
21 principal: Principal {
22 role: PrincipalRole::Owner,
23 identity: public_key,
24 },
25 share,
26 }
27 }
28
29 pub fn principal(&self) -> &Principal {
30 &self.principal
31 }
32
33 pub fn share(&self) -> &Share {
34 &self.share
35 }
36}
37
38pub type Shares = BTreeMap<String, BucketShare>;
39
40#[allow(clippy::doc_overindented_list_items)]
53#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
54pub struct Manifest {
55 id: Uuid,
58 name: String,
62 shares: Shares,
66 entry: Link,
68 pins: Link,
71 previous: Option<Link>,
73 version: Version,
75}
76
77impl BlockEncoded<DagCborCodec> for Manifest {}
78
79impl Manifest {
80 pub fn new(
82 id: Uuid,
83 name: String,
84 owner: PublicKey,
85 share: Share,
86 entry: Link,
87 pins: Link,
88 ) -> Self {
89 Manifest {
90 id,
91 name,
92 shares: BTreeMap::from([(
93 owner.to_hex(),
94 BucketShare {
95 principal: Principal {
96 role: PrincipalRole::Owner,
97 identity: owner,
98 },
99 share,
100 },
101 )]),
102 entry,
103 pins,
104 previous: None,
105 version: Version::default(),
106 }
107 }
108
109 pub fn get_share(&self, public_key: &PublicKey) -> Option<&BucketShare> {
110 self.shares.get(&public_key.to_hex())
111 }
112
113 pub fn add_share(&mut self, public_key: PublicKey, secret: Secret) -> Result<(), ShareError> {
114 let share = Share::new(&secret, &public_key)?;
115 let bucket_share = BucketShare::new(share, public_key);
116 self.shares.insert(public_key.to_hex(), bucket_share);
117 Ok(())
118 }
119
120 pub fn unset_shares(&mut self) {
121 self.shares.clear();
122 }
123
124 pub fn id(&self) -> &Uuid {
125 &self.id
126 }
127
128 pub fn name(&self) -> &str {
129 &self.name
130 }
131
132 pub fn shares(&self) -> &BTreeMap<String, BucketShare> {
133 &self.shares
134 }
135
136 pub fn version(&self) -> &Version {
137 &self.version
138 }
139
140 pub fn entry(&self) -> &Link {
141 &self.entry
142 }
143
144 pub fn set_entry(&mut self, entry: Link) {
145 self.entry = entry;
146 }
147
148 pub fn pins(&self) -> &Link {
149 &self.pins
150 }
151
152 pub fn set_pins(&mut self, pins_link: Link) {
153 self.pins = pins_link;
154 }
155
156 pub fn set_previous(&mut self, previous: Link) {
157 self.previous = Some(previous);
158 }
159
160 pub fn previous(&self) -> &Option<Link> {
161 &self.previous
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168 #[allow(unused_imports)]
169 use crate::crypto::{PublicKey, Secret};
170
171 #[test]
172 fn test_share_serialize() {
173 use ipld_core::codec::Codec;
174 use serde_ipld_dagcbor::codec::DagCborCodec;
175
176 let share = Share::default();
177
178 let encoded = DagCborCodec::encode_to_vec(&share).unwrap();
180 let decoded: Share = DagCborCodec::decode_from_slice(&encoded).unwrap();
181
182 assert_eq!(share, decoded);
183 }
184
185 #[test]
186 fn test_principal_serialize() {
187 use ipld_core::codec::Codec;
188 use serde_ipld_dagcbor::codec::DagCborCodec;
189
190 let public_key = crate::crypto::SecretKey::generate().public();
191 let principal = Principal {
192 role: PrincipalRole::Owner,
193 identity: public_key,
194 };
195
196 let encoded = DagCborCodec::encode_to_vec(&principal).unwrap();
198 let decoded: Principal = DagCborCodec::decode_from_slice(&encoded).unwrap();
199
200 assert_eq!(principal, decoded);
201 }
202}