fog_crypto/
serde.rs

1//! [`serde`](https://serde.rs/) support.
2//!
3//! This module is optionally compiled if the `with-serde` feature is enabled (which is the
4//! default). Each type is serialized as though it were part of an enum, with each specific type
5//! being an enum variant. The enum indexing and naming matches up with `fog-pack`'s encoding
6//! scheme for these types. Supported types for serialization & deserialization are `Hash`,
7//! `Identity`, `LockId`, `StreamId`, and all the lockbox types.
8//!
9//! The types will all serialize as bytes if the serializer is not marked as human-readable. If
10//! human-readable, the `Hash`, `Identity`, `StreamId`, and `LockId` types will serialize as base58
11//! strings (much like other public keys in a post-blockchain world), while the lockbox types will
12//! serialize as base64 strings.
13//!
14//! Finally, since human-readable formats require base64 encode/decode for lockboxes, the `Ref`
15//! variants used for zero-copy decoding are not supported in those instances.
16
17/// Name marker used for the library's fictional Enum type
18pub const FOG_TYPE_ENUM: &str = "_FogType";
19/// Enum variant name for `Time` Timestamp (used by fog-pack)
20pub const FOG_TYPE_ENUM_TIME_NAME: &str = "Time";
21/// Enum variant name for [`Hash`](crate::hash::Hash)
22pub const FOG_TYPE_ENUM_HASH_NAME: &str = "Hash";
23/// Enum variant name for [`Identity`](crate::identity::Identity)
24pub const FOG_TYPE_ENUM_IDENTITY_NAME: &str = "Identity";
25/// Enum variant name for [`LockId`](crate::lock::LockId)
26pub const FOG_TYPE_ENUM_LOCK_ID_NAME: &str = "LockId";
27/// Enum variant name for [`StreamId`](crate::stream::StreamId)
28pub const FOG_TYPE_ENUM_STREAM_ID_NAME: &str = "StreamId";
29/// Enum variant name for [`DataLockbox`](crate::lockbox::DataLockbox)
30pub const FOG_TYPE_ENUM_DATA_LOCKBOX_NAME: &str = "DataLockbox";
31/// Enum variant name for [`IdentityLockbox`](crate::lockbox::IdentityLockbox)
32pub const FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME: &str = "IdentityLockbox";
33/// Enum variant name for [`StreamLockbox`](crate::lockbox::StreamLockbox)
34pub const FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME: &str = "StreamLockbox";
35/// Enum variant name for [`LockLockbox`](crate::lockbox::LockLockbox)
36pub const FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME: &str = "LockLockbox";
37/// Enum variant name for [`BareIdKey`](crate::identity::BareIdKey)
38pub const FOG_TYPE_ENUM_BARE_ID_KEY_NAME: &str = "BareIdKey";
39
40/// Enum variant index for `Time` Timestamp (used by fog-pack)
41pub const FOG_TYPE_ENUM_TIME_INDEX: u64 = 0;
42/// Enum variant index for [`Hash`](crate::hash::Hash)
43pub const FOG_TYPE_ENUM_HASH_INDEX: u64 = 1;
44/// Enum variant index for [`Identity`](crate::identity::Identity)
45pub const FOG_TYPE_ENUM_IDENTITY_INDEX: u64 = 2;
46/// Enum variant index for [`LockId`](crate::lock::LockId)
47pub const FOG_TYPE_ENUM_LOCK_ID_INDEX: u64 = 3;
48/// Enum variant index for [`StreamId`](crate::stream::StreamId)
49pub const FOG_TYPE_ENUM_STREAM_ID_INDEX: u64 = 4;
50/// Enum variant index for [`DataLockbox`](crate::lockbox::DataLockbox)
51pub const FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX: u64 = 5;
52/// Enum variant index for [`IdentityLockbox`](crate::lockbox::IdentityLockbox)
53pub const FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX: u64 = 6;
54/// Enum variant index for [`StreamLockbox`](crate::lockbox::StreamLockbox)
55pub const FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX: u64 = 7;
56/// Enum variant index for [`LockLockbox`](crate::lockbox::LockLockbox)
57pub const FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX: u64 = 8;
58/// Enum variant name for [`BareIdKey`](crate::identity::BareIdKey)
59pub const FOG_TYPE_ENUM_BARE_ID_KEY_INDEX: u64 = 9;
60
61const VARIANTS: &[&str] = &[
62    FOG_TYPE_ENUM,
63    FOG_TYPE_ENUM_HASH_NAME,
64    FOG_TYPE_ENUM_IDENTITY_NAME,
65    FOG_TYPE_ENUM_LOCK_ID_NAME,
66    FOG_TYPE_ENUM_STREAM_ID_NAME,
67    FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
68    FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
69    FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
70    FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
71    FOG_TYPE_ENUM_BARE_ID_KEY_NAME,
72];
73
74use crate::{hash::Hash, identity::{Identity, BareIdKey}, lock::LockId, lockbox::*, stream::StreamId};
75
76use serde::{
77    de::{Deserialize, Deserializer, EnumAccess, Error, Unexpected, VariantAccess, Visitor},
78    ser::{Serialize, Serializer},
79};
80use serde_bytes::{ByteBuf, Bytes};
81use std::{convert::TryFrom, fmt};
82use base64::{
83    engine::general_purpose::STANDARD,
84    Engine,
85};
86
87impl Serialize for Hash {
88    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89    where
90        S: Serializer,
91    {
92        if serializer.is_human_readable() {
93            let value = self.to_base58();
94            serializer.serialize_newtype_variant(
95                FOG_TYPE_ENUM,
96                FOG_TYPE_ENUM_HASH_INDEX as u32,
97                FOG_TYPE_ENUM_HASH_NAME,
98                &value,
99            )
100        } else {
101            let value = Bytes::new(self.as_ref());
102            serializer.serialize_newtype_variant(
103                FOG_TYPE_ENUM,
104                FOG_TYPE_ENUM_HASH_INDEX as u32,
105                FOG_TYPE_ENUM_HASH_NAME,
106                value,
107            )
108        }
109    }
110}
111
112impl Serialize for Identity {
113    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114    where
115        S: Serializer,
116    {
117        if serializer.is_human_readable() {
118            let value = self.to_base58();
119            serializer.serialize_newtype_variant(
120                FOG_TYPE_ENUM,
121                FOG_TYPE_ENUM_IDENTITY_INDEX as u32,
122                FOG_TYPE_ENUM_IDENTITY_NAME,
123                &value,
124            )
125        } else {
126            let value = ByteBuf::from(self.as_vec());
127            serializer.serialize_newtype_variant(
128                FOG_TYPE_ENUM,
129                FOG_TYPE_ENUM_IDENTITY_INDEX as u32,
130                FOG_TYPE_ENUM_IDENTITY_NAME,
131                &value,
132            )
133        }
134    }
135}
136
137impl Serialize for BareIdKey {
138    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139    where
140        S: Serializer,
141    {
142        if serializer.is_human_readable() {
143            let value = self.to_base58();
144            serializer.serialize_newtype_variant(
145                FOG_TYPE_ENUM,
146                FOG_TYPE_ENUM_BARE_ID_KEY_INDEX as u32,
147                FOG_TYPE_ENUM_BARE_ID_KEY_NAME,
148                &value,
149            )
150        } else {
151            let mut value = ByteBuf::new();
152            self.encode_vec(&mut value);
153            serializer.serialize_newtype_variant(
154                FOG_TYPE_ENUM,
155                FOG_TYPE_ENUM_BARE_ID_KEY_INDEX as u32,
156                FOG_TYPE_ENUM_BARE_ID_KEY_NAME,
157                &value,
158            )
159        }
160    }
161}
162
163impl Serialize for StreamId {
164    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165    where
166        S: Serializer,
167    {
168        if serializer.is_human_readable() {
169            let value = self.to_base58();
170            serializer.serialize_newtype_variant(
171                FOG_TYPE_ENUM,
172                FOG_TYPE_ENUM_STREAM_ID_INDEX as u32,
173                FOG_TYPE_ENUM_STREAM_ID_NAME,
174                &value,
175            )
176        } else {
177            let value = ByteBuf::from(self.as_vec());
178            serializer.serialize_newtype_variant(
179                FOG_TYPE_ENUM,
180                FOG_TYPE_ENUM_STREAM_ID_INDEX as u32,
181                FOG_TYPE_ENUM_STREAM_ID_NAME,
182                &value,
183            )
184        }
185    }
186}
187
188impl Serialize for LockId {
189    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
190    where
191        S: Serializer,
192    {
193        if serializer.is_human_readable() {
194            let value = self.to_base58();
195            serializer.serialize_newtype_variant(
196                FOG_TYPE_ENUM,
197                FOG_TYPE_ENUM_LOCK_ID_INDEX as u32,
198                FOG_TYPE_ENUM_LOCK_ID_NAME,
199                &value,
200            )
201        } else {
202            let value = ByteBuf::from(self.as_vec());
203            serializer.serialize_newtype_variant(
204                FOG_TYPE_ENUM,
205                FOG_TYPE_ENUM_LOCK_ID_INDEX as u32,
206                FOG_TYPE_ENUM_LOCK_ID_NAME,
207                &value,
208            )
209        }
210    }
211}
212
213impl Serialize for DataLockbox {
214    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
215    where
216        S: Serializer,
217    {
218        if serializer.is_human_readable() {
219            let value = STANDARD.encode(self.as_bytes());
220            serializer.serialize_newtype_variant(
221                FOG_TYPE_ENUM,
222                FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX as u32,
223                FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
224                &value,
225            )
226        } else {
227            let value = Bytes::new(self.as_bytes());
228            serializer.serialize_newtype_variant(
229                FOG_TYPE_ENUM,
230                FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX as u32,
231                FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
232                &value,
233            )
234        }
235    }
236}
237
238impl Serialize for DataLockboxRef {
239    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
240    where
241        S: Serializer,
242    {
243        if serializer.is_human_readable() {
244            let value = STANDARD.encode(self.as_bytes());
245            serializer.serialize_newtype_variant(
246                FOG_TYPE_ENUM,
247                FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX as u32,
248                FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
249                &value,
250            )
251        } else {
252            let value = Bytes::new(self.as_bytes());
253            serializer.serialize_newtype_variant(
254                FOG_TYPE_ENUM,
255                FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX as u32,
256                FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
257                &value,
258            )
259        }
260    }
261}
262
263impl Serialize for IdentityLockbox {
264    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
265    where
266        S: Serializer,
267    {
268        if serializer.is_human_readable() {
269            let value = STANDARD.encode(self.as_bytes());
270            serializer.serialize_newtype_variant(
271                FOG_TYPE_ENUM,
272                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX as u32,
273                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
274                &value,
275            )
276        } else {
277            let value = Bytes::new(self.as_bytes());
278            serializer.serialize_newtype_variant(
279                FOG_TYPE_ENUM,
280                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX as u32,
281                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
282                &value,
283            )
284        }
285    }
286}
287
288impl Serialize for IdentityLockboxRef {
289    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
290    where
291        S: Serializer,
292    {
293        if serializer.is_human_readable() {
294            let value = STANDARD.encode(self.as_bytes());
295            serializer.serialize_newtype_variant(
296                FOG_TYPE_ENUM,
297                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX as u32,
298                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
299                &value,
300            )
301        } else {
302            let value = Bytes::new(self.as_bytes());
303            serializer.serialize_newtype_variant(
304                FOG_TYPE_ENUM,
305                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX as u32,
306                FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
307                &value,
308            )
309        }
310    }
311}
312
313impl Serialize for StreamLockbox {
314    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
315    where
316        S: Serializer,
317    {
318        if serializer.is_human_readable() {
319            let value = STANDARD.encode(self.as_bytes());
320            serializer.serialize_newtype_variant(
321                FOG_TYPE_ENUM,
322                FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX as u32,
323                FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
324                &value,
325            )
326        } else {
327            let value = Bytes::new(self.as_bytes());
328            serializer.serialize_newtype_variant(
329                FOG_TYPE_ENUM,
330                FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX as u32,
331                FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
332                &value,
333            )
334        }
335    }
336}
337
338impl Serialize for StreamLockboxRef {
339    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
340    where
341        S: Serializer,
342    {
343        if serializer.is_human_readable() {
344            let value = STANDARD.encode(self.as_bytes());
345            serializer.serialize_newtype_variant(
346                FOG_TYPE_ENUM,
347                FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX as u32,
348                FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
349                &value,
350            )
351        } else {
352            let value = Bytes::new(self.as_bytes());
353            serializer.serialize_newtype_variant(
354                FOG_TYPE_ENUM,
355                FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX as u32,
356                FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
357                &value,
358            )
359        }
360    }
361}
362
363impl Serialize for LockLockbox {
364    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
365    where
366        S: Serializer,
367    {
368        if serializer.is_human_readable() {
369            let value = STANDARD.encode(self.as_bytes());
370            serializer.serialize_newtype_variant(
371                FOG_TYPE_ENUM,
372                FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX as u32,
373                FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
374                &value,
375            )
376        } else {
377            let value = Bytes::new(self.as_bytes());
378            serializer.serialize_newtype_variant(
379                FOG_TYPE_ENUM,
380                FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX as u32,
381                FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
382                &value,
383            )
384        }
385    }
386}
387
388impl Serialize for LockLockboxRef {
389    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
390    where
391        S: Serializer,
392    {
393        if serializer.is_human_readable() {
394            let value = STANDARD.encode(self.as_bytes());
395            serializer.serialize_newtype_variant(
396                FOG_TYPE_ENUM,
397                FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX as u32,
398                FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
399                &value,
400            )
401        } else {
402            let value = Bytes::new(self.as_bytes());
403            serializer.serialize_newtype_variant(
404                FOG_TYPE_ENUM,
405                FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX as u32,
406                FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
407                &value,
408            )
409        }
410    }
411}
412
413///////////////////////////////////////////////////////////////////////////////
414// Deserialization
415///////////////////////////////////////////////////////////////////////////////
416
417#[doc(hidden)]
418/// Used for deserialization of the type identifier. Made public only so it can be used by
419/// fog-pack.
420pub enum CryptoEnum {
421    Time,
422    Hash,
423    Identity,
424    LockId,
425    StreamId,
426    DataLockbox,
427    IdentityLockbox,
428    StreamLockbox,
429    LockLockbox,
430    BareIdKey,
431}
432
433impl CryptoEnum {
434    pub fn as_str(&self) -> &'static str {
435        use CryptoEnum::*;
436        match *self {
437            Time => "Time",
438            Hash => "Hash",
439            Identity => "Identity",
440            LockId => "LockId",
441            StreamId => "StreamId",
442            DataLockbox => "DataLockbox",
443            IdentityLockbox => "IdentityLockbox",
444            StreamLockbox => "StreamLockbox",
445            LockLockbox => "LockLockbox",
446            BareIdKey => "BareIdKey",
447        }
448    }
449}
450
451struct CryptoEnumVisitor;
452impl<'de> Visitor<'de> for CryptoEnumVisitor {
453    type Value = CryptoEnum;
454    fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
455        write!(fmt, "variant identifier")
456    }
457
458    fn visit_u64<E: Error>(self, v: u64) -> Result<Self::Value, E> {
459        match v {
460            FOG_TYPE_ENUM_TIME_INDEX => Ok(CryptoEnum::Time),
461            FOG_TYPE_ENUM_HASH_INDEX => Ok(CryptoEnum::Hash),
462            FOG_TYPE_ENUM_IDENTITY_INDEX => Ok(CryptoEnum::Identity),
463            FOG_TYPE_ENUM_LOCK_ID_INDEX => Ok(CryptoEnum::LockId),
464            FOG_TYPE_ENUM_STREAM_ID_INDEX => Ok(CryptoEnum::StreamId),
465            FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX => Ok(CryptoEnum::DataLockbox),
466            FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX => Ok(CryptoEnum::IdentityLockbox),
467            FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX => Ok(CryptoEnum::StreamLockbox),
468            FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX => Ok(CryptoEnum::LockLockbox),
469            FOG_TYPE_ENUM_BARE_ID_KEY_INDEX => Ok(CryptoEnum::BareIdKey),
470            _ => Err(E::invalid_value(
471                serde::de::Unexpected::Unsigned(v),
472                &"variant index 1 <= i <= 8",
473            )),
474        }
475    }
476
477    fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
478        match v {
479            FOG_TYPE_ENUM_TIME_NAME => Ok(CryptoEnum::Time),
480            FOG_TYPE_ENUM_HASH_NAME => Ok(CryptoEnum::Hash),
481            FOG_TYPE_ENUM_IDENTITY_NAME => Ok(CryptoEnum::Identity),
482            FOG_TYPE_ENUM_LOCK_ID_NAME => Ok(CryptoEnum::LockId),
483            FOG_TYPE_ENUM_STREAM_ID_NAME => Ok(CryptoEnum::StreamId),
484            FOG_TYPE_ENUM_DATA_LOCKBOX_NAME => Ok(CryptoEnum::DataLockbox),
485            FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME => Ok(CryptoEnum::IdentityLockbox),
486            FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME => Ok(CryptoEnum::StreamLockbox),
487            FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME => Ok(CryptoEnum::LockLockbox),
488            FOG_TYPE_ENUM_BARE_ID_KEY_NAME => Ok(CryptoEnum::BareIdKey),
489            _ => Err(E::unknown_variant(v, VARIANTS)),
490        }
491    }
492
493    fn visit_bytes<E: Error>(self, v: &[u8]) -> Result<Self::Value, E> {
494        let v = std::str::from_utf8(v).map_err(|_| {
495            let v = String::from_utf8_lossy(v);
496            E::unknown_variant(v.as_ref(), VARIANTS)
497        })?;
498        match v {
499            FOG_TYPE_ENUM_TIME_NAME => Ok(CryptoEnum::Time),
500            FOG_TYPE_ENUM_HASH_NAME => Ok(CryptoEnum::Hash),
501            FOG_TYPE_ENUM_IDENTITY_NAME => Ok(CryptoEnum::Identity),
502            FOG_TYPE_ENUM_LOCK_ID_NAME => Ok(CryptoEnum::LockId),
503            FOG_TYPE_ENUM_STREAM_ID_NAME => Ok(CryptoEnum::StreamId),
504            FOG_TYPE_ENUM_DATA_LOCKBOX_NAME => Ok(CryptoEnum::DataLockbox),
505            FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME => Ok(CryptoEnum::IdentityLockbox),
506            FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME => Ok(CryptoEnum::StreamLockbox),
507            FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME => Ok(CryptoEnum::LockLockbox),
508            FOG_TYPE_ENUM_BARE_ID_KEY_NAME => Ok(CryptoEnum::BareIdKey),
509            _ => Err(E::unknown_variant(v, VARIANTS)),
510        }
511    }
512}
513impl<'de> Deserialize<'de> for CryptoEnum {
514    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
515    where
516        D: Deserializer<'de>,
517    {
518        deserializer.deserialize_identifier(CryptoEnumVisitor)
519    }
520}
521
522impl<'de> Deserialize<'de> for Hash {
523    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
524    where
525        D: Deserializer<'de>,
526    {
527        struct HashVisitor {
528            is_human_readable: bool,
529        }
530
531        impl<'de> serde::de::Visitor<'de> for HashVisitor {
532            type Value = Hash;
533
534            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
535                write!(
536                    fmt,
537                    "{} enum with variant {} (id {})",
538                    FOG_TYPE_ENUM, FOG_TYPE_ENUM_HASH_NAME, FOG_TYPE_ENUM_HASH_INDEX
539                )
540            }
541
542            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
543            where
544                A: EnumAccess<'de>,
545            {
546                let variant = match data.variant()? {
547                    (CryptoEnum::Hash, variant) => variant,
548                    (e, _) => {
549                        return Err(A::Error::invalid_type(
550                            Unexpected::Other(e.as_str()),
551                            &"Hash",
552                        ))
553                    }
554                };
555                if self.is_human_readable {
556                    let base58: String = variant.newtype_variant()?;
557                    Hash::from_base58(&base58).map_err(|e| A::Error::custom(e.serde_err()))
558                } else {
559                    let bytes: ByteBuf = variant.newtype_variant()?;
560                    Hash::try_from(bytes.as_ref()).map_err(|e| A::Error::custom(e.serde_err()))
561                }
562            }
563        }
564        let is_human_readable = deserializer.is_human_readable();
565        deserializer.deserialize_enum(
566            FOG_TYPE_ENUM,
567            &[FOG_TYPE_ENUM_HASH_NAME],
568            HashVisitor { is_human_readable },
569        )
570    }
571}
572
573impl<'de> Deserialize<'de> for Identity {
574    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
575    where
576        D: Deserializer<'de>,
577    {
578        struct IdentityVisitor {
579            is_human_readable: bool,
580        }
581
582        impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
583            type Value = Identity;
584
585            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
586                write!(
587                    fmt,
588                    "{} enum with variant {} (id {})",
589                    FOG_TYPE_ENUM, FOG_TYPE_ENUM_IDENTITY_NAME, FOG_TYPE_ENUM_IDENTITY_INDEX
590                )
591            }
592
593            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
594            where
595                A: EnumAccess<'de>,
596            {
597                let variant = match data.variant()? {
598                    (CryptoEnum::Identity, variant) => variant,
599                    (e, _) => {
600                        return Err(A::Error::invalid_type(
601                            Unexpected::Other(e.as_str()),
602                            &"Identity",
603                        ))
604                    }
605                };
606                if self.is_human_readable {
607                    let base58: String = variant.newtype_variant()?;
608                    Identity::from_base58(&base58).map_err(|e| A::Error::custom(e.serde_err()))
609                } else {
610                    let bytes: ByteBuf = variant.newtype_variant()?;
611                    Identity::try_from(bytes.as_ref()).map_err(|e| A::Error::custom(e.serde_err()))
612                }
613            }
614        }
615        let is_human_readable = deserializer.is_human_readable();
616        deserializer.deserialize_enum(
617            FOG_TYPE_ENUM,
618            &[FOG_TYPE_ENUM_IDENTITY_NAME],
619            IdentityVisitor { is_human_readable },
620        )
621    }
622}
623
624impl<'de> Deserialize<'de> for BareIdKey {
625    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
626    where
627        D: Deserializer<'de>,
628    {
629        struct BareIdVisitor {
630            is_human_readable: bool,
631        }
632
633        impl<'de> serde::de::Visitor<'de> for BareIdVisitor {
634            type Value = BareIdKey;
635
636            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
637                write!(
638                    fmt,
639                    "{} enum with variant {} (id {})",
640                    FOG_TYPE_ENUM, FOG_TYPE_ENUM_BARE_ID_KEY_NAME, FOG_TYPE_ENUM_BARE_ID_KEY_INDEX
641                )
642            }
643
644            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
645            where
646                A: EnumAccess<'de>,
647            {
648                let variant = match data.variant()? {
649                    (CryptoEnum::BareIdKey, variant) => variant,
650                    (e, _) => {
651                        return Err(A::Error::invalid_type(
652                            Unexpected::Other(e.as_str()),
653                            &"BareIdKey",
654                        ))
655                    }
656                };
657                if self.is_human_readable {
658                    let base58: String = variant.newtype_variant()?;
659                    BareIdKey::from_base58(&base58).map_err(|e| A::Error::custom(e.serde_err()))
660                } else {
661                    let bytes: ByteBuf = variant.newtype_variant()?;
662                    BareIdKey::try_from(bytes.as_ref()).map_err(|e| A::Error::custom(e.serde_err()))
663                }
664            }
665        }
666        let is_human_readable = deserializer.is_human_readable();
667        deserializer.deserialize_enum(
668            FOG_TYPE_ENUM,
669            &[FOG_TYPE_ENUM_BARE_ID_KEY_NAME],
670            BareIdVisitor { is_human_readable },
671        )
672    }
673}
674
675impl<'de> Deserialize<'de> for StreamId {
676    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
677    where
678        D: Deserializer<'de>,
679    {
680        struct StreamIdVisitor {
681            is_human_readable: bool,
682        }
683
684        impl<'de> serde::de::Visitor<'de> for StreamIdVisitor {
685            type Value = StreamId;
686
687            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
688                write!(
689                    fmt,
690                    "{} enum with variant {} (id {})",
691                    FOG_TYPE_ENUM, FOG_TYPE_ENUM_STREAM_ID_NAME, FOG_TYPE_ENUM_STREAM_ID_INDEX
692                )
693            }
694
695            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
696            where
697                A: EnumAccess<'de>,
698            {
699                let variant = match data.variant()? {
700                    (CryptoEnum::StreamId, variant) => variant,
701                    (e, _) => {
702                        return Err(A::Error::invalid_type(
703                            Unexpected::Other(e.as_str()),
704                            &"StreamId",
705                        ))
706                    }
707                };
708                if self.is_human_readable {
709                    let base58: String = variant.newtype_variant()?;
710                    StreamId::from_base58(&base58).map_err(|e| A::Error::custom(e.serde_err()))
711                } else {
712                    let bytes: ByteBuf = variant.newtype_variant()?;
713                    StreamId::try_from(bytes.as_ref()).map_err(|e| A::Error::custom(e.serde_err()))
714                }
715            }
716        }
717        let is_human_readable = deserializer.is_human_readable();
718        deserializer.deserialize_enum(
719            FOG_TYPE_ENUM,
720            &[FOG_TYPE_ENUM_STREAM_ID_NAME],
721            StreamIdVisitor { is_human_readable },
722        )
723    }
724}
725
726impl<'de> Deserialize<'de> for LockId {
727    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
728    where
729        D: Deserializer<'de>,
730    {
731        struct LockIdVisitor {
732            is_human_readable: bool,
733        }
734
735        impl<'de> serde::de::Visitor<'de> for LockIdVisitor {
736            type Value = LockId;
737
738            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
739                write!(
740                    fmt,
741                    "{} enum with variant {} (id {})",
742                    FOG_TYPE_ENUM, FOG_TYPE_ENUM_LOCK_ID_NAME, FOG_TYPE_ENUM_LOCK_ID_INDEX
743                )
744            }
745
746            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
747            where
748                A: EnumAccess<'de>,
749            {
750                let variant = match data.variant()? {
751                    (CryptoEnum::LockId, variant) => variant,
752                    (e, _) => {
753                        return Err(A::Error::invalid_type(
754                            Unexpected::Other(e.as_str()),
755                            &"LockId",
756                        ))
757                    }
758                };
759                if self.is_human_readable {
760                    let base58: String = variant.newtype_variant()?;
761                    LockId::from_base58(&base58).map_err(|e| A::Error::custom(e.serde_err()))
762                } else {
763                    let bytes: ByteBuf = variant.newtype_variant()?;
764                    LockId::try_from(bytes.as_ref()).map_err(|e| A::Error::custom(e.serde_err()))
765                }
766            }
767        }
768        let is_human_readable = deserializer.is_human_readable();
769        deserializer.deserialize_enum(
770            FOG_TYPE_ENUM,
771            &[FOG_TYPE_ENUM_LOCK_ID_NAME],
772            LockIdVisitor { is_human_readable },
773        )
774    }
775}
776
777impl<'de> Deserialize<'de> for DataLockbox {
778    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
779    where
780        D: Deserializer<'de>,
781    {
782        struct LockboxVisitor {
783            is_human_readable: bool,
784        }
785
786        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
787            type Value = DataLockbox;
788
789            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
790                write!(
791                    fmt,
792                    "{} enum with variant {} (id {})",
793                    FOG_TYPE_ENUM,
794                    FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
795                    FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX
796                )
797            }
798
799            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
800            where
801                A: EnumAccess<'de>,
802            {
803                let variant = match data.variant()? {
804                    (CryptoEnum::DataLockbox, variant) => variant,
805                    (e, _) => {
806                        return Err(A::Error::invalid_type(
807                            Unexpected::Other(e.as_str()),
808                            &"DataLockbox",
809                        ))
810                    }
811                };
812                if self.is_human_readable {
813                    let v: String = variant.newtype_variant()?;
814                    let bytes = STANDARD.decode(v).map_err(|_| A::Error::custom(""))?;
815                    Ok(DataLockboxRef::from_bytes(&bytes[..])
816                        .map_err(|e| A::Error::custom(e.serde_err()))?
817                        .to_owned())
818                } else {
819                    let bytes: &Bytes = variant.newtype_variant()?;
820                    Ok(DataLockboxRef::from_bytes(bytes)
821                        .map_err(|e| A::Error::custom(e.serde_err()))?
822                        .to_owned())
823                }
824            }
825        }
826        let is_human_readable = deserializer.is_human_readable();
827        deserializer.deserialize_enum(
828            FOG_TYPE_ENUM,
829            &[FOG_TYPE_ENUM_DATA_LOCKBOX_NAME],
830            LockboxVisitor { is_human_readable },
831        )
832    }
833}
834
835impl<'de: 'a, 'a> Deserialize<'de> for &'a DataLockboxRef {
836    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
837    where
838        D: Deserializer<'de>,
839    {
840        struct LockboxVisitor;
841
842        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
843            type Value = &'de DataLockboxRef;
844
845            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
846                write!(
847                    fmt,
848                    "{} enum with variant {} (id {})",
849                    FOG_TYPE_ENUM,
850                    FOG_TYPE_ENUM_DATA_LOCKBOX_NAME,
851                    FOG_TYPE_ENUM_DATA_LOCKBOX_INDEX
852                )
853            }
854
855            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
856            where
857                A: EnumAccess<'de>,
858            {
859                let variant = match data.variant()? {
860                    (CryptoEnum::DataLockbox, variant) => variant,
861                    (e, _) => {
862                        return Err(A::Error::invalid_type(
863                            Unexpected::Other(e.as_str()),
864                            &"DataLockbox",
865                        ))
866                    }
867                };
868                let bytes: &Bytes = variant.newtype_variant()?;
869                DataLockboxRef::from_bytes(bytes).map_err(|e| A::Error::custom(e.serde_err()))
870            }
871        }
872        deserializer.deserialize_enum(
873            FOG_TYPE_ENUM,
874            &[FOG_TYPE_ENUM_DATA_LOCKBOX_NAME],
875            LockboxVisitor,
876        )
877    }
878}
879
880impl<'de> Deserialize<'de> for IdentityLockbox {
881    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
882    where
883        D: Deserializer<'de>,
884    {
885        struct LockboxVisitor {
886            is_human_readable: bool,
887        }
888
889        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
890            type Value = IdentityLockbox;
891
892            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
893                write!(
894                    fmt,
895                    "{} enum with variant {} (id {})",
896                    FOG_TYPE_ENUM,
897                    FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
898                    FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX
899                )
900            }
901
902            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
903            where
904                A: EnumAccess<'de>,
905            {
906                let variant = match data.variant()? {
907                    (CryptoEnum::IdentityLockbox, variant) => variant,
908                    (e, _) => {
909                        return Err(A::Error::invalid_type(
910                            Unexpected::Other(e.as_str()),
911                            &"IdentityLockbox",
912                        ))
913                    }
914                };
915                if self.is_human_readable {
916                    let v: String = variant.newtype_variant()?;
917                    let bytes = STANDARD.decode(v).map_err(|_| A::Error::custom(""))?;
918                    Ok(IdentityLockboxRef::from_bytes(&bytes[..])
919                        .map_err(|e| A::Error::custom(e.serde_err()))?
920                        .to_owned())
921                } else {
922                    let bytes: &Bytes = variant.newtype_variant()?;
923                    Ok(IdentityLockboxRef::from_bytes(bytes)
924                        .map_err(|e| A::Error::custom(e.serde_err()))?
925                        .to_owned())
926                }
927            }
928        }
929        let is_human_readable = deserializer.is_human_readable();
930        deserializer.deserialize_enum(
931            FOG_TYPE_ENUM,
932            &[FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME],
933            LockboxVisitor { is_human_readable },
934        )
935    }
936}
937
938impl<'de: 'a, 'a> Deserialize<'de> for &'a IdentityLockboxRef {
939    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
940    where
941        D: Deserializer<'de>,
942    {
943        struct LockboxVisitor;
944
945        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
946            type Value = &'de IdentityLockboxRef;
947
948            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
949                write!(
950                    fmt,
951                    "{} enum with variant {} (id {})",
952                    FOG_TYPE_ENUM,
953                    FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME,
954                    FOG_TYPE_ENUM_IDENTITY_LOCKBOX_INDEX
955                )
956            }
957
958            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
959            where
960                A: EnumAccess<'de>,
961            {
962                let variant = match data.variant()? {
963                    (CryptoEnum::IdentityLockbox, variant) => variant,
964                    (e, _) => {
965                        return Err(A::Error::invalid_type(
966                            Unexpected::Other(e.as_str()),
967                            &"IdentityLockbox",
968                        ))
969                    }
970                };
971                let bytes: &Bytes = variant.newtype_variant()?;
972                IdentityLockboxRef::from_bytes(bytes).map_err(|e| A::Error::custom(e.serde_err()))
973            }
974        }
975        deserializer.deserialize_enum(
976            FOG_TYPE_ENUM,
977            &[FOG_TYPE_ENUM_IDENTITY_LOCKBOX_NAME],
978            LockboxVisitor,
979        )
980    }
981}
982
983impl<'de> Deserialize<'de> for StreamLockbox {
984    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
985    where
986        D: Deserializer<'de>,
987    {
988        struct LockboxVisitor {
989            is_human_readable: bool,
990        }
991
992        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
993            type Value = StreamLockbox;
994
995            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
996                write!(
997                    fmt,
998                    "{} enum with variant {} (id {})",
999                    FOG_TYPE_ENUM,
1000                    FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
1001                    FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX
1002                )
1003            }
1004
1005            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
1006            where
1007                A: EnumAccess<'de>,
1008            {
1009                let variant = match data.variant()? {
1010                    (CryptoEnum::StreamLockbox, variant) => variant,
1011                    (e, _) => {
1012                        return Err(A::Error::invalid_type(
1013                            Unexpected::Other(e.as_str()),
1014                            &"StreamLockbox",
1015                        ))
1016                    }
1017                };
1018                if self.is_human_readable {
1019                    let v: String = variant.newtype_variant()?;
1020                    let bytes = STANDARD.decode(v).map_err(|_| A::Error::custom(""))?;
1021                    Ok(StreamLockboxRef::from_bytes(&bytes[..])
1022                        .map_err(|e| A::Error::custom(e.serde_err()))?
1023                        .to_owned())
1024                } else {
1025                    let bytes: &Bytes = variant.newtype_variant()?;
1026                    Ok(StreamLockboxRef::from_bytes(bytes)
1027                        .map_err(|e| A::Error::custom(e.serde_err()))?
1028                        .to_owned())
1029                }
1030            }
1031        }
1032        let is_human_readable = deserializer.is_human_readable();
1033        deserializer.deserialize_enum(
1034            FOG_TYPE_ENUM,
1035            &[FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME],
1036            LockboxVisitor { is_human_readable },
1037        )
1038    }
1039}
1040
1041impl<'de: 'a, 'a> Deserialize<'de> for &'a StreamLockboxRef {
1042    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1043    where
1044        D: Deserializer<'de>,
1045    {
1046        struct LockboxVisitor;
1047
1048        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
1049            type Value = &'de StreamLockboxRef;
1050
1051            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1052                write!(
1053                    fmt,
1054                    "{} enum with variant {} (id {})",
1055                    FOG_TYPE_ENUM,
1056                    FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME,
1057                    FOG_TYPE_ENUM_STREAM_LOCKBOX_INDEX
1058                )
1059            }
1060
1061            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
1062            where
1063                A: EnumAccess<'de>,
1064            {
1065                let variant = match data.variant()? {
1066                    (CryptoEnum::StreamLockbox, variant) => variant,
1067                    (e, _) => {
1068                        return Err(A::Error::invalid_type(
1069                            Unexpected::Other(e.as_str()),
1070                            &"StreamLockbox",
1071                        ))
1072                    }
1073                };
1074                let bytes: &Bytes = variant.newtype_variant()?;
1075                StreamLockboxRef::from_bytes(bytes).map_err(|e| A::Error::custom(e.serde_err()))
1076            }
1077        }
1078        deserializer.deserialize_enum(
1079            FOG_TYPE_ENUM,
1080            &[FOG_TYPE_ENUM_STREAM_LOCKBOX_NAME],
1081            LockboxVisitor,
1082        )
1083    }
1084}
1085
1086impl<'de> Deserialize<'de> for LockLockbox {
1087    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1088    where
1089        D: Deserializer<'de>,
1090    {
1091        struct LockboxVisitor {
1092            is_human_readable: bool,
1093        }
1094
1095        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
1096            type Value = LockLockbox;
1097
1098            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1099                write!(
1100                    fmt,
1101                    "{} enum with variant {} (id {})",
1102                    FOG_TYPE_ENUM,
1103                    FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
1104                    FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX
1105                )
1106            }
1107
1108            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
1109            where
1110                A: EnumAccess<'de>,
1111            {
1112                let variant = match data.variant()? {
1113                    (CryptoEnum::LockLockbox, variant) => variant,
1114                    (e, _) => {
1115                        return Err(A::Error::invalid_type(
1116                            Unexpected::Other(e.as_str()),
1117                            &"LockLockbox",
1118                        ))
1119                    }
1120                };
1121                if self.is_human_readable {
1122                    let v: String = variant.newtype_variant()?;
1123                    let bytes = STANDARD.decode(v).map_err(|_| A::Error::custom(""))?;
1124                    Ok(LockLockboxRef::from_bytes(&bytes[..])
1125                        .map_err(|e| A::Error::custom(e.serde_err()))?
1126                        .to_owned())
1127                } else {
1128                    let bytes: &Bytes = variant.newtype_variant()?;
1129                    Ok(LockLockboxRef::from_bytes(bytes)
1130                        .map_err(|e| A::Error::custom(e.serde_err()))?
1131                        .to_owned())
1132                }
1133            }
1134        }
1135        let is_human_readable = deserializer.is_human_readable();
1136        deserializer.deserialize_enum(
1137            FOG_TYPE_ENUM,
1138            &[FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME],
1139            LockboxVisitor { is_human_readable },
1140        )
1141    }
1142}
1143
1144impl<'de: 'a, 'a> Deserialize<'de> for &'a LockLockboxRef {
1145    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1146    where
1147        D: Deserializer<'de>,
1148    {
1149        struct LockboxVisitor;
1150
1151        impl<'de> serde::de::Visitor<'de> for LockboxVisitor {
1152            type Value = &'de LockLockboxRef;
1153
1154            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1155                write!(
1156                    fmt,
1157                    "{} enum with variant {} (id {})",
1158                    FOG_TYPE_ENUM,
1159                    FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME,
1160                    FOG_TYPE_ENUM_LOCK_LOCKBOX_INDEX
1161                )
1162            }
1163
1164            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
1165            where
1166                A: EnumAccess<'de>,
1167            {
1168                let variant = match data.variant()? {
1169                    (CryptoEnum::LockLockbox, variant) => variant,
1170                    (e, _) => {
1171                        return Err(A::Error::invalid_type(
1172                            Unexpected::Other(e.as_str()),
1173                            &"LockLockbox",
1174                        ))
1175                    }
1176                };
1177                let bytes: &Bytes = variant.newtype_variant()?;
1178                LockLockboxRef::from_bytes(bytes).map_err(|e| A::Error::custom(e.serde_err()))
1179            }
1180        }
1181        deserializer.deserialize_enum(
1182            FOG_TYPE_ENUM,
1183            &[FOG_TYPE_ENUM_LOCK_LOCKBOX_NAME],
1184            LockboxVisitor,
1185        )
1186    }
1187}
1188
1189mod test {
1190
1191    // I have no idea why this gets marked as "unused"... because the code will not compile without
1192    // it 🙃
1193    #[allow(unused_imports)]
1194    use crate::{hash::Hash, identity::Identity, lock::LockId, lockbox::*, stream::StreamId};
1195
1196    #[test]
1197    fn serde_json_hash() {
1198        let hash = Hash::new(b"I'm going to be hashed and turned to JSON, yay!");
1199        let json = serde_json::to_string(&hash).unwrap();
1200        println!("{}", json);
1201        let dec_hash: Hash = serde_json::from_str(&json).unwrap();
1202        assert_eq!(dec_hash, hash);
1203    }
1204
1205    #[test]
1206    fn bincode_hash() {
1207        let hash = Hash::new(b"I'm going to be hashed and turned to bincode, yay!");
1208        let bin = bincode::serialize(&hash).unwrap();
1209        println!("Original Hash: {:x?}", hash);
1210        println!("Bincode: {:x?}", bin);
1211        let dec_hash: Hash = bincode::deserialize(&bin).unwrap();
1212        assert_eq!(dec_hash, hash);
1213    }
1214
1215    #[test]
1216    fn serde_json_identity() {
1217        let id = crate::IdentityKey::new().id().clone();
1218        let json = serde_json::to_string(&id).unwrap();
1219        println!("{}", json);
1220        let dec: Identity = serde_json::from_str(&json).unwrap();
1221        assert_eq!(dec, id);
1222    }
1223
1224    #[test]
1225    fn bincode_identity() {
1226        let id = crate::IdentityKey::new().id().clone();
1227        let bin = bincode::serialize(&id).unwrap();
1228        println!("Original Id: {:x?}", id);
1229        println!("Bincode: {:x?}", bin);
1230        let dec: Identity = bincode::deserialize(&bin).unwrap();
1231        assert_eq!(dec, id);
1232    }
1233
1234    #[test]
1235    fn serde_json_stream_id() {
1236        let id = crate::StreamKey::new().id().clone();
1237        let json = serde_json::to_string(&id).unwrap();
1238        println!("{}", json);
1239        let dec: StreamId = serde_json::from_str(&json).unwrap();
1240        assert_eq!(dec, id);
1241    }
1242
1243    #[test]
1244    fn bincode_stream_id() {
1245        let id = crate::StreamKey::new().id().clone();
1246        let bin = bincode::serialize(&id).unwrap();
1247        println!("Original Id: {:x?}", id);
1248        println!("Bincode: {:x?}", bin);
1249        let dec: StreamId = bincode::deserialize(&bin).unwrap();
1250        assert_eq!(dec, id);
1251    }
1252
1253    #[test]
1254    fn serde_json_lock_id() {
1255        let id = crate::LockKey::new().id().clone();
1256        let json = serde_json::to_string(&id).unwrap();
1257        println!("{}", json);
1258        let dec: LockId = serde_json::from_str(&json).unwrap();
1259        assert_eq!(dec, id);
1260    }
1261
1262    #[test]
1263    fn bincode_lock_id() {
1264        let id = crate::LockKey::new().id().clone();
1265        let bin = bincode::serialize(&id).unwrap();
1266        println!("Original Id: {:x?}", id);
1267        println!("Bincode: {:x?}", bin);
1268        let dec: LockId = bincode::deserialize(&bin).unwrap();
1269        assert_eq!(dec, id);
1270    }
1271
1272    #[test]
1273    fn serde_json_data_lockbox() {
1274        let key = crate::StreamKey::new();
1275        let to_send = b"Crypto in JSON, eh?";
1276        let lockbox = key.encrypt_data(to_send);
1277
1278        let json = serde_json::to_string(&lockbox).unwrap();
1279        println!("{}", json);
1280
1281        let dec: DataLockbox = serde_json::from_str(&json).unwrap();
1282        let dec = key.decrypt_data(&dec).unwrap();
1283        assert_eq!(dec, to_send);
1284    }
1285
1286    #[test]
1287    fn serde_json_data_lockbox_ref() {
1288        // Verify only that LockboxRef encodes the same way as main Lockbox
1289        // Set up crypto
1290        use std::ops::Deref;
1291        let key = crate::StreamKey::new();
1292        let to_send = b"Crypto in JSON, eh?";
1293        let lockbox = key.encrypt_data(to_send);
1294        // Encode & check
1295        let json1 = serde_json::to_string(&lockbox).unwrap();
1296        let lockbox_ref: &DataLockboxRef = lockbox.deref();
1297        let json2 = serde_json::to_string(lockbox_ref).unwrap();
1298        assert_eq!(json1, json2);
1299    }
1300
1301    #[test]
1302    fn bincode_data_lockbox() {
1303        // Set up crypto
1304        let key = crate::StreamKey::new();
1305        let to_send = b"Crypto in bincode, eh?";
1306        let lockbox = key.encrypt_data(to_send);
1307        // Encode
1308        let bin = bincode::serialize(&lockbox).unwrap();
1309        println!("Original Lockbox: {:x?}", lockbox);
1310        println!("Bincode: {:x?}", bin);
1311        // Decode & check
1312        let dec: DataLockbox = bincode::deserialize(&bin).unwrap();
1313        let dec = key.decrypt_data(&dec).unwrap();
1314        assert_eq!(dec, to_send);
1315    }
1316
1317    #[test]
1318    fn bincode_data_lockbox_ref() {
1319        // Set up crypto
1320        use std::ops::Deref;
1321        let key = crate::StreamKey::new();
1322        let to_send = b"Crypto in bincode, eh?";
1323        let lockbox = key.encrypt_data(to_send);
1324        // Encode
1325        let lockbox_ref: &DataLockboxRef = lockbox.deref();
1326        let bin = bincode::serialize(lockbox_ref).unwrap();
1327        println!("Original Lockbox: {:x?}", lockbox);
1328        println!("Bincode: {:x?}", bin);
1329        // Decode & check
1330        let dec: &DataLockboxRef = bincode::deserialize(&bin).unwrap();
1331        let dec = key.decrypt_data(dec).unwrap();
1332        assert_eq!(dec, to_send);
1333    }
1334
1335    #[test]
1336    fn serde_json_identity_lockbox() {
1337        let key = crate::StreamKey::new();
1338        let to_send = crate::IdentityKey::new();
1339        let lockbox = to_send.export_for_stream(&key).unwrap();
1340
1341        let json = serde_json::to_string(&lockbox).unwrap();
1342        println!("{}", json);
1343
1344        let dec: IdentityLockbox = serde_json::from_str(&json).unwrap();
1345        let dec = key.decrypt_identity_key(&dec).unwrap();
1346        assert_eq!(dec.id(), to_send.id());
1347    }
1348
1349    #[test]
1350    fn serde_json_identity_lockbox_ref() {
1351        // Verify only that LockboxRef encodes the same way as main Lockbox
1352        // Set up crypto
1353        use std::ops::Deref;
1354        let key = crate::StreamKey::new();
1355        let to_send = crate::IdentityKey::new();
1356        let lockbox = to_send.export_for_stream(&key).unwrap();
1357        // Encode & check
1358        let json1 = serde_json::to_string(&lockbox).unwrap();
1359        let lockbox_ref: &IdentityLockboxRef = lockbox.deref();
1360        let json2 = serde_json::to_string(lockbox_ref).unwrap();
1361        assert_eq!(json1, json2);
1362    }
1363
1364    #[test]
1365    fn bincode_identity_lockbox() {
1366        // Set up crypto
1367        let key = crate::StreamKey::new();
1368        let to_send = crate::IdentityKey::new();
1369        let lockbox = to_send.export_for_stream(&key).unwrap();
1370        // Encode
1371        let bin = bincode::serialize(&lockbox).unwrap();
1372        println!("Original Lockbox: {:x?}", lockbox);
1373        println!("Bincode: {:x?}", bin);
1374        // Decode & check
1375        let dec: IdentityLockbox = bincode::deserialize(&bin).unwrap();
1376        let dec = key.decrypt_identity_key(&dec).unwrap();
1377        assert_eq!(dec.id(), to_send.id());
1378    }
1379
1380    #[test]
1381    fn bincode_identity_lockbox_ref() {
1382        // Set up crypto
1383        use std::ops::Deref;
1384        let key = crate::StreamKey::new();
1385        let to_send = crate::IdentityKey::new();
1386        let lockbox = to_send.export_for_stream(&key).unwrap();
1387        // Encode
1388        let lockbox_ref: &IdentityLockboxRef = lockbox.deref();
1389        let bin = bincode::serialize(lockbox_ref).unwrap();
1390        println!("Original Lockbox: {:x?}", lockbox);
1391        println!("Bincode: {:x?}", bin);
1392        // Decode & check
1393        let dec: &IdentityLockboxRef = bincode::deserialize(&bin).unwrap();
1394        let dec = key.decrypt_identity_key(dec).unwrap();
1395        assert_eq!(dec.id(), to_send.id());
1396    }
1397
1398    #[test]
1399    fn serde_json_stream_lockbox() {
1400        let key = crate::StreamKey::new();
1401        let to_send = crate::StreamKey::new();
1402        let lockbox = to_send.export_for_stream(&key).unwrap();
1403
1404        let json = serde_json::to_string(&lockbox).unwrap();
1405        println!("{}", json);
1406
1407        let dec: StreamLockbox = serde_json::from_str(&json).unwrap();
1408        let dec = key.decrypt_stream_key(&dec).unwrap();
1409        assert_eq!(dec.id(), to_send.id());
1410    }
1411
1412    #[test]
1413    fn serde_json_stream_lockbox_ref() {
1414        // Verify only that LockboxRef encodes the same way as main Lockbox
1415        // Set up crypto
1416        use std::ops::Deref;
1417        let key = crate::StreamKey::new();
1418        let to_send = crate::StreamKey::new();
1419        let lockbox = to_send.export_for_stream(&key).unwrap();
1420        // Encode & check
1421        let json1 = serde_json::to_string(&lockbox).unwrap();
1422        let lockbox_ref: &StreamLockboxRef = lockbox.deref();
1423        let json2 = serde_json::to_string(lockbox_ref).unwrap();
1424        assert_eq!(json1, json2);
1425    }
1426
1427    #[test]
1428    fn bincode_stream_lockbox() {
1429        // Set up crypto
1430        let key = crate::StreamKey::new();
1431        let to_send = crate::StreamKey::new();
1432        let lockbox = to_send.export_for_stream(&key).unwrap();
1433        // Encode
1434        let bin = bincode::serialize(&lockbox).unwrap();
1435        println!("Original Lockbox: {:x?}", lockbox);
1436        println!("Bincode: {:x?}", bin);
1437        // Decode & check
1438        let dec: StreamLockbox = bincode::deserialize(&bin).unwrap();
1439        let dec = key.decrypt_stream_key(&dec).unwrap();
1440        assert_eq!(dec.id(), to_send.id());
1441    }
1442
1443    #[test]
1444    fn bincode_stream_lockbox_ref() {
1445        // Set up crypto
1446        use std::ops::Deref;
1447        let key = crate::StreamKey::new();
1448        let to_send = crate::StreamKey::new();
1449        let lockbox = to_send.export_for_stream(&key).unwrap();
1450        // Encode
1451        let lockbox_ref: &StreamLockboxRef = lockbox.deref();
1452        let bin = bincode::serialize(lockbox_ref).unwrap();
1453        println!("Original Lockbox: {:x?}", lockbox);
1454        println!("Bincode: {:x?}", bin);
1455        // Decode & check
1456        let dec: &StreamLockboxRef = bincode::deserialize(&bin).unwrap();
1457        let dec = key.decrypt_stream_key(dec).unwrap();
1458        assert_eq!(dec.id(), to_send.id());
1459    }
1460
1461    #[test]
1462    fn serde_json_lock_lockbox() {
1463        let key = crate::StreamKey::new();
1464        let to_send = crate::LockKey::new();
1465        let lockbox = to_send.export_for_stream(&key).unwrap();
1466
1467        let json = serde_json::to_string(&lockbox).unwrap();
1468        println!("{}", json);
1469
1470        let dec: LockLockbox = serde_json::from_str(&json).unwrap();
1471        let dec = key.decrypt_lock_key(&dec).unwrap();
1472        assert_eq!(dec.id(), to_send.id());
1473    }
1474
1475    #[test]
1476    fn serde_json_lock_lockbox_ref() {
1477        // Verify only that LockboxRef encodes the same way as main Lockbox
1478        // Set up crypto
1479        use std::ops::Deref;
1480        let key = crate::StreamKey::new();
1481        let to_send = crate::LockKey::new();
1482        let lockbox = to_send.export_for_stream(&key).unwrap();
1483        // Encode & check
1484        let json1 = serde_json::to_string(&lockbox).unwrap();
1485        let lockbox_ref: &LockLockboxRef = lockbox.deref();
1486        let json2 = serde_json::to_string(lockbox_ref).unwrap();
1487        assert_eq!(json1, json2);
1488    }
1489
1490    #[test]
1491    fn bincode_lock_lockbox() {
1492        // Set up crypto
1493        let key = crate::StreamKey::new();
1494        let to_send = crate::LockKey::new();
1495        let lockbox = to_send.export_for_stream(&key).unwrap();
1496        // Encode
1497        let bin = bincode::serialize(&lockbox).unwrap();
1498        println!("Original Lockbox: {:x?}", lockbox);
1499        println!("Bincode: {:x?}", bin);
1500        // Decode & check
1501        let dec: LockLockbox = bincode::deserialize(&bin).unwrap();
1502        let dec = key.decrypt_lock_key(&dec).unwrap();
1503        assert_eq!(dec.id(), to_send.id());
1504    }
1505
1506    #[test]
1507    fn bincode_lock_lockbox_ref() {
1508        // Set up crypto
1509        use std::ops::Deref;
1510        let key = crate::StreamKey::new();
1511        let to_send = crate::LockKey::new();
1512        let lockbox = to_send.export_for_stream(&key).unwrap();
1513        // Encode
1514        let lockbox_ref: &LockLockboxRef = lockbox.deref();
1515        let bin = bincode::serialize(lockbox_ref).unwrap();
1516        println!("Original Lockbox: {:x?}", lockbox);
1517        println!("Bincode: {:x?}", bin);
1518        // Decode & check
1519        let dec: &LockLockboxRef = bincode::deserialize(&bin).unwrap();
1520        let dec = key.decrypt_lock_key(dec).unwrap();
1521        assert_eq!(dec.id(), to_send.id());
1522    }
1523}