cola/
encoded_replica.rs

1use sha2::{Digest, Sha256};
2
3use crate::*;
4
5pub type Checksum = Vec<u8>;
6
7/// A [`Replica`] encoded into a compact binary format suitable for
8/// transmission over the network.
9///
10/// This struct is created by [`encode`](Replica::encode)ing a [`Replica`] and
11/// can be decoded back into a [`Replica`] by calling
12/// [`decode`](Replica::decode). See the documentation of those methods for
13/// more information.
14#[cfg_attr(docsrs, doc(cfg(feature = "encode")))]
15#[derive(Clone, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct EncodedReplica {
18    protocol_version: ProtocolVersion,
19    checksum: Checksum,
20    bytes: Vec<u8>,
21}
22
23impl EncodedReplica {
24    #[inline]
25    pub(crate) fn bytes(&self) -> &[u8] {
26        self.bytes.as_slice()
27    }
28
29    #[inline]
30    pub(crate) fn checksum(&self) -> &Checksum {
31        &self.checksum
32    }
33
34    #[inline]
35    pub(crate) fn new(
36        protocol_version: ProtocolVersion,
37        checksum: Checksum,
38        bytes: Vec<u8>,
39    ) -> Self {
40        Self { protocol_version, checksum, bytes }
41    }
42
43    #[inline]
44    pub(crate) fn protocol_version(&self) -> ProtocolVersion {
45        self.protocol_version
46    }
47}
48
49/// The type of error that can occur when [`decode`](Replica::decode)ing an
50/// [`EncodedReplica`].
51#[cfg_attr(docsrs, doc(cfg(feature = "encode")))]
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub enum DecodeError {
54    /// This error occurs when the internal checksum of the [`EncodedReplica`]
55    /// fails.
56    ///
57    /// This typically means that the [`EncodedReplica`] was corrupted during
58    /// transmission.
59    ChecksumFailed,
60
61    /// This error occurs when the machine that created the [`EncodedReplica`]
62    /// and the one that is trying to [`decode`](Replica::decode) it are using
63    /// two incompatible versions of cola.
64    DifferentProtocol {
65        /// The `ProtocolVersion` of cola on the machine that created the
66        /// `EncodedReplica`.
67        encoded_on: ProtocolVersion,
68
69        /// The `ProtocolVersion` of cola on the machine that is trying to
70        /// decode the `EncodedReplica`.
71        decoding_on: ProtocolVersion,
72    },
73
74    /// This error is an umbrella variant that encompasses all other errors
75    /// that can occur when the binary data wrapped by the [`EncodedReplica`]
76    /// cannot be decoded into a `Replica`.
77    ///
78    /// This is returned when the checksum and protocol version checks both
79    /// succeed, *and yet* the data is still invalid. The only way this can
80    /// occur in practice is if the `EncodedReplica` passed to
81    /// [`decode`](Replica::decode) was deserialized from a byte vector that
82    /// was not the result of serializing an `EncodedReplica`.
83    ///
84    /// As long as you're not doing that (and you shouldn't be) this variant
85    /// can be ignored.
86    InvalidData,
87}
88
89#[inline]
90pub fn checksum(bytes: &[u8]) -> Checksum {
91    Sha256::digest(bytes)[..].to_vec()
92}