1use borsh::{BorshDeserialize, BorshSerialize};
4
5mod borsh_schema;
6mod digest;
7
8pub use borsh_schema::*;
9pub use digest::*;
10
11pub type NamespaceId = [u8; 32];
12pub type SubspaceId = [u8; 32];
13pub type SubspaceSecretKey = [u8; 32];
14pub type NamespaceSecretKey = [u8; 32];
15
16#[derive(
18 borsh::BorshDeserialize,
19 borsh::BorshSerialize,
20 Debug,
21 Clone,
22 PartialEq,
23 Eq,
24 PartialOrd,
25 Ord,
26 Hash,
27 Default,
28)]
29pub struct EntityPath(pub Vec<PathSegment>);
30impl AsRef<[PathSegment]> for EntityPath {
31 fn as_ref(&self) -> &[PathSegment] {
32 &self.0
33 }
34}
35impl From<()> for EntityPath {
36 fn from(_: ()) -> Self {
37 EntityPath(Vec::default())
38 }
39}
40impl<T: Into<PathSegment>, const N: usize> From<[T; N]> for EntityPath {
41 fn from(value: [T; N]) -> Self {
42 EntityPath(value.into_iter().map(|x| x.into()).collect())
43 }
44}
45
46#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone, Default)]
47pub struct Entity {
48 pub components: Vec<ComponentEntry>,
49}
50
51impl Entity {
52 pub fn sort_components(&mut self) {
53 self.components.sort();
54 }
55
56 pub fn compute_digest(&self) -> Digest {
57 let is_sorted = self.components.windows(2).all(|w| w[0] <= w[1]);
58 assert!(is_sorted, "Components must be sorted to compute digest");
59 let mut buf = Vec::new();
60 self.serialize(&mut buf).unwrap();
61 Digest::new(&buf)
62 }
63}
64
65#[derive(
66 borsh::BorshDeserialize,
67 borsh::BorshSerialize,
68 Debug,
69 Clone,
70 Copy,
71 PartialEq,
72 PartialOrd,
73 Ord,
74 Eq,
75)]
76pub struct ComponentEntry {
77 pub schema_id: Option<Digest>,
79 pub component_id: Digest,
80}
81
82#[derive(
84 borsh::BorshDeserialize, borsh::BorshSerialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
85)]
86pub enum PathSegment {
87 Null,
88 Bool(bool),
89 Uint(u64),
90 Int(i64),
91 String(String),
92 Bytes(Vec<u8>),
93}
94impl std::fmt::Debug for PathSegment {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 match self {
97 Self::Null => write!(f, "Null"),
98 Self::Bool(arg0) => write!(f, "{arg0}"),
99 Self::Uint(arg0) => write!(f, "{arg0}_u64"),
100 Self::Int(arg0) => write!(f, "{arg0}_i64"),
101 Self::String(arg0) => write!(f, "\"{arg0}\""),
102 Self::Bytes(arg0) => write!(f, "base32:{}", &iroh_base::base32::fmt(arg0)),
103 }
104 }
105}
106impl From<()> for PathSegment {
107 fn from(_: ()) -> Self {
108 Self::Null
109 }
110}
111impl From<bool> for PathSegment {
112 fn from(value: bool) -> Self {
113 Self::Bool(value)
114 }
115}
116impl From<u64> for PathSegment {
117 fn from(value: u64) -> Self {
118 Self::Uint(value)
119 }
120}
121impl From<i64> for PathSegment {
122 fn from(value: i64) -> Self {
123 Self::Int(value)
124 }
125}
126impl<'a> From<&'a str> for PathSegment {
127 fn from(value: &'a str) -> Self {
128 Self::String(value.into())
129 }
130}
131impl From<String> for PathSegment {
132 fn from(value: String) -> Self {
133 Self::String(value)
134 }
135}
136impl From<Vec<u8>> for PathSegment {
137 fn from(value: Vec<u8>) -> Self {
138 Self::Bytes(value)
139 }
140}
141
142#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
144pub enum ComponentKind {
145 Unencrypted(ComponentData),
147 Encrypted {
149 algorithm: EncryptionAlgorithm,
150 key_id: [u8; 32],
151 encrypted_data: Vec<u8>,
152 },
153}
154
155impl ComponentKind {
156 pub fn unencrypted(&self) -> Option<&ComponentData> {
157 match self {
158 ComponentKind::Unencrypted(u) => Some(u),
159 _ => None,
160 }
161 }
162}
163
164#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
166pub struct ComponentData {
167 pub schema: Digest,
169 pub data: Vec<u8>,
171}
172
173#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
175pub struct Schema {
176 pub name: String,
178 pub format: BorshSchema,
180 pub specification: Digest,
182}
183
184#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
186pub enum BorshSchema {
187 Null,
188 Bool,
189 U8,
190 U16,
191 U32,
192 U64,
193 U128,
194 I8,
195 I16,
196 I32,
197 I64,
198 I128,
199 F32,
200 F64,
201 String,
202 Option {
203 schema: Box<BorshSchema>,
204 },
205 Array {
206 schema: Box<BorshSchema>,
207 len: u32,
208 },
209 Struct {
210 fields: Vec<(String, BorshSchema)>,
211 },
212 Enum {
213 variants: Vec<(String, BorshSchema)>,
214 },
215 Vector {
216 schema: Box<BorshSchema>,
217 },
218 Map {
219 key: Box<BorshSchema>,
220 value: Box<BorshSchema>,
221 },
222 Set {
223 schema: Box<BorshSchema>,
224 },
225 Blob,
226 Snapshot,
227 Link,
228}
229
230#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
231pub struct Link {
232 namespace: KeyResolverKind,
233 subspace: KeyResolverKind,
234 path: Vec<PathSegment>,
235 snapshot: Option<Digest>,
236}
237impl HasBorshSchema for Link {
238 fn borsh_schema() -> BorshSchema {
239 BorshSchema::Link
240 }
241}
242
243#[derive(
245 Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, BorshDeserialize, BorshSerialize, Default,
246)]
247pub struct ExactLink {
248 pub namespace: NamespaceId,
249 pub subspace: SubspaceId,
250 pub path: EntityPath,
251}
252
253impl<P: Into<EntityPath>> From<(NamespaceId, SubspaceId, P)> for ExactLink {
254 fn from((n, s, p): (NamespaceId, SubspaceId, P)) -> Self {
255 Self {
256 namespace: n,
257 subspace: s,
258 path: p.into(),
259 }
260 }
261}
262
263#[derive(
264 borsh::BorshDeserialize,
265 borsh::BorshSerialize,
266 Debug,
267 Clone,
268 Hash,
269 Eq,
270 PartialEq,
271 Ord,
272 PartialOrd,
273)]
274pub struct Blob(pub Digest);
275impl HasBorshSchema for Blob {
276 fn borsh_schema() -> BorshSchema {
277 BorshSchema::Blob
278 }
279}
280
281#[derive(
282 borsh::BorshDeserialize,
283 borsh::BorshSerialize,
284 Debug,
285 Clone,
286 Hash,
287 Eq,
288 PartialEq,
289 Ord,
290 PartialOrd,
291)]
292pub struct Snapshot(pub Digest);
293impl HasBorshSchema for Snapshot {
294 fn borsh_schema() -> BorshSchema {
295 BorshSchema::Snapshot
296 }
297}
298
299#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
301pub enum KeyResolverKind {
302 Inline([u8; 32]),
304 Custom { id: Digest, data: Vec<u8> },
307}
308
309#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
311pub struct KeyResolver {
312 pub name: String,
313 pub specification: Digest,
314}
315
316#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone)]
318pub struct EncryptionAlgorithm {
319 pub name: String,
320 pub specification: Digest,
321}