nym_credentials/ecash/bandwidth/serialiser/
mod.rs

1// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::ecash::bandwidth::issued::CURRENT_SERIALIZATION_REVISION;
5use crate::Error;
6use bincode::Options;
7use serde::de::DeserializeOwned;
8use serde::{Deserialize, Serialize};
9use std::marker::PhantomData;
10use zeroize::Zeroize;
11
12pub mod keys;
13pub mod signatures;
14
15#[derive(Zeroize, Serialize, Deserialize)]
16pub struct VersionSerialised<T: ?Sized> {
17    pub data: Vec<u8>,
18    pub revision: u8,
19
20    #[zeroize(skip)]
21    #[serde(skip)]
22    _phantom: PhantomData<T>,
23}
24
25impl<T> VersionSerialised<T> {
26    pub fn try_unpack(&self) -> Result<T, Error>
27    where
28        T: VersionedSerialise + DeserializeOwned,
29    {
30        T::try_unpack(&self.data, self.revision)
31    }
32}
33
34pub trait VersionedSerialise {
35    const CURRENT_SERIALISATION_REVISION: u8;
36
37    fn current_serialization_revision(&self) -> u8 {
38        CURRENT_SERIALIZATION_REVISION
39    }
40
41    // implicitly always uses current revision
42    fn pack(&self) -> VersionSerialised<Self>
43    where
44        Self: Serialize,
45    {
46        let data = make_current_storable_bincode_serializer()
47            .serialize(self)
48            .expect("serialisation failure");
49
50        VersionSerialised {
51            data,
52            revision: Self::CURRENT_SERIALISATION_REVISION,
53            _phantom: Default::default(),
54        }
55    }
56
57    fn try_unpack_current(b: &[u8]) -> Result<Self, Error>
58    where
59        Self: DeserializeOwned,
60    {
61        make_current_storable_bincode_serializer()
62            .deserialize(b)
63            .map_err(|source| Error::SerializationFailure {
64                source,
65                revision: Self::CURRENT_SERIALISATION_REVISION,
66            })
67    }
68
69    // this is up to whoever implements the trait to provide function implementation,
70    // as they might have to have different implementations per revision
71    fn try_unpack(b: &[u8], revision: impl Into<Option<u8>>) -> Result<Self, Error>
72    where
73        Self: DeserializeOwned;
74}
75
76fn make_current_storable_bincode_serializer() -> impl bincode::Options {
77    bincode::DefaultOptions::new()
78        .with_big_endian()
79        .with_varint_encoding()
80}