zoe_wire_protocol/
primitives.rs1use crate::Hash;
2use serde::{Deserialize, Serialize};
3use std::ops::Deref;
4
5#[cfg(feature = "frb-api")]
6use flutter_rust_bridge::frb;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub struct KeyId(pub Hash);
14
15impl KeyId {
16 pub fn new(hash: Hash) -> Self {
18 Self(hash)
19 }
20
21 pub fn from_bytes(bytes: [u8; 32]) -> Self {
23 Self(Hash::from(bytes))
24 }
25
26 pub fn as_bytes(&self) -> &[u8; 32] {
28 self.0.as_bytes()
29 }
30
31 pub fn to_hex(&self) -> String {
33 hex::encode(self.as_bytes())
34 }
35}
36
37impl Deref for KeyId {
38 type Target = Hash;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl From<Hash> for KeyId {
46 fn from(hash: Hash) -> Self {
47 Self(hash)
48 }
49}
50
51impl From<[u8; 32]> for KeyId {
52 fn from(bytes: [u8; 32]) -> Self {
53 Self(Hash::from(bytes))
54 }
55}
56
57impl std::fmt::Display for KeyId {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "{}", self.to_hex())
60 }
61}
62
63impl AsRef<[u8]> for KeyId {
64 fn as_ref(&self) -> &[u8] {
65 self.0.as_bytes()
66 }
67}
68
69impl PartialOrd for KeyId {
70 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
71 Some(self.cmp(other))
72 }
73}
74
75impl Ord for KeyId {
76 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
77 self.0.as_bytes().cmp(other.0.as_bytes())
78 }
79}
80
81#[cfg(feature = "rusqlite")]
82impl rusqlite::ToSql for KeyId {
83 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
84 Ok(rusqlite::types::ToSqlOutput::from(
85 self.as_bytes().as_slice(),
86 ))
87 }
88}
89
90#[cfg(feature = "rusqlite")]
91impl rusqlite::types::FromSql for KeyId {
92 fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
93 match value {
94 rusqlite::types::ValueRef::Blob(bytes) => {
95 if bytes.len() != 32 {
96 return Err(rusqlite::types::FromSqlError::InvalidBlobSize {
97 expected_size: 32,
98 blob_size: bytes.len(),
99 });
100 }
101 let mut array = [0u8; 32];
102 array.copy_from_slice(bytes);
103 Ok(KeyId::from_bytes(array))
104 }
105 _ => Err(rusqlite::types::FromSqlError::InvalidType),
106 }
107 }
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
115pub struct BlobId(pub Hash);
116
117impl BlobId {
118 pub fn new(hash: Hash) -> Self {
120 Self(hash)
121 }
122
123 pub fn from_content(content: &[u8]) -> Self {
125 Self(crate::hash(content))
126 }
127
128 pub fn from_bytes(bytes: [u8; 32]) -> Self {
130 Self(Hash::from(bytes))
131 }
132
133 pub fn as_bytes(&self) -> &[u8; 32] {
135 self.0.as_bytes()
136 }
137
138 pub fn to_hex(&self) -> String {
140 hex::encode(self.as_bytes())
141 }
142}
143
144impl Deref for BlobId {
145 type Target = Hash;
146
147 fn deref(&self) -> &Self::Target {
148 &self.0
149 }
150}
151
152impl From<Hash> for BlobId {
153 fn from(hash: Hash) -> Self {
154 Self(hash)
155 }
156}
157
158impl From<[u8; 32]> for BlobId {
159 fn from(bytes: [u8; 32]) -> Self {
160 Self(Hash::from(bytes))
161 }
162}
163
164impl std::fmt::Display for BlobId {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 write!(f, "{}", self.to_hex())
167 }
168}
169
170impl AsRef<[u8]> for BlobId {
171 fn as_ref(&self) -> &[u8] {
172 self.0.as_bytes()
173 }
174}
175
176impl PartialOrd for BlobId {
177 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
178 Some(self.cmp(other))
179 }
180}
181
182impl Ord for BlobId {
183 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
184 self.0.as_bytes().cmp(other.0.as_bytes())
185 }
186}
187
188#[cfg(feature = "rusqlite")]
189impl rusqlite::ToSql for BlobId {
190 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
191 Ok(rusqlite::types::ToSqlOutput::from(
192 self.as_bytes().as_slice(),
193 ))
194 }
195}
196
197#[cfg(feature = "rusqlite")]
198impl rusqlite::types::FromSql for BlobId {
199 fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
200 match value {
201 rusqlite::types::ValueRef::Blob(bytes) => {
202 if bytes.len() != 32 {
203 return Err(rusqlite::types::FromSqlError::InvalidBlobSize {
204 expected_size: 32,
205 blob_size: bytes.len(),
206 });
207 }
208 let mut array = [0u8; 32];
209 array.copy_from_slice(bytes);
210 Ok(BlobId::from_bytes(array))
211 }
212 _ => Err(rusqlite::types::FromSqlError::InvalidType),
213 }
214 }
215}
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
222#[cfg_attr(feature = "frb-api", frb(opaque))]
223pub struct MessageId(pub Hash);
224
225#[cfg_attr(feature = "frb-api", frb)]
226impl MessageId {
227 pub fn new(hash: Hash) -> Self {
229 Self(hash)
230 }
231
232 pub fn from_content(content: &[u8]) -> Self {
234 Self(crate::hash(content))
235 }
236
237 pub fn from_bytes(bytes: [u8; 32]) -> Self {
239 Self(Hash::from(bytes))
240 }
241
242 pub fn as_bytes(&self) -> &[u8; 32] {
244 self.0.as_bytes()
245 }
246
247 pub fn to_hex(&self) -> String {
249 hex::encode(self.as_bytes())
250 }
251}
252
253impl Deref for MessageId {
254 type Target = Hash;
255
256 fn deref(&self) -> &Self::Target {
257 &self.0
258 }
259}
260
261impl From<Hash> for MessageId {
262 fn from(hash: Hash) -> Self {
263 Self(hash)
264 }
265}
266
267impl From<[u8; 32]> for MessageId {
268 fn from(bytes: [u8; 32]) -> Self {
269 Self(Hash::from(bytes))
270 }
271}
272
273impl std::fmt::Display for MessageId {
274 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
275 write!(f, "{}", self.to_hex())
276 }
277}
278
279impl AsRef<[u8]> for MessageId {
280 fn as_ref(&self) -> &[u8] {
281 self.0.as_bytes()
282 }
283}
284
285impl PartialOrd for MessageId {
286 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
287 Some(self.cmp(other))
288 }
289}
290
291impl Ord for MessageId {
292 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
293 self.0.as_bytes().cmp(other.0.as_bytes())
294 }
295}
296
297#[cfg(feature = "rusqlite")]
298impl rusqlite::ToSql for MessageId {
299 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
300 Ok(rusqlite::types::ToSqlOutput::from(
301 self.as_bytes().as_slice(),
302 ))
303 }
304}
305
306#[cfg(feature = "rusqlite")]
307impl rusqlite::types::FromSql for MessageId {
308 fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
309 match value {
310 rusqlite::types::ValueRef::Blob(bytes) => {
311 if bytes.len() != 32 {
312 return Err(rusqlite::types::FromSqlError::InvalidBlobSize {
313 expected_size: 32,
314 blob_size: bytes.len(),
315 });
316 }
317 let mut array = [0u8; 32];
318 array.copy_from_slice(bytes);
319 Ok(MessageId::from_bytes(array))
320 }
321 _ => Err(rusqlite::types::FromSqlError::InvalidType),
322 }
323 }
324}
325
326#[deprecated(note = "Use KeyId instead")]
328pub type Id = [u8; 32];