1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! # Key Store Types
//!
//! This module defines the [`Status`] enum.
//! The [`Status`] defines values to tag key store values with.
//!
//! XXX: We might want to make the [`Status`] a trait type as well 🤔.

use std::convert::TryFrom;

use crate::traits::KeyStoreValue;

#[derive(Debug, Clone, PartialEq, Eq)]
/// Errors thrown by operations on the [`Status`].
pub enum StatusError {
    /// The value can't be converted to a [`Status`].
    InvalidStatus(String),

    /// Deserializing a byte slice failed.
    DeserializationError(String),
}

/// The status of a value in the key store.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Status {
    /// Values marked with this can be extracted from the key store.
    Extractable = 1,

    /// Values marked as hidden can not be extracted from the key store.
    Hidden = 2,

    /// Unconfirmed values must be confirmed before they are permanently stored.
    /// Note that unconfirmed values must be persisted as well, but may be dropped
    /// in bulk or can't be used for certain operations.
    UnconfirmedExtractable = 3,

    /// Same as `UnconfirmedExtractable` but the value can not be extracted.
    UnconfirmedHidden = 4,
}

impl TryFrom<u8> for Status {
    type Error = StatusError;

    fn try_from(value: u8) -> core::result::Result<Self, Self::Error> {
        Ok(match value {
            1 => Self::Extractable,
            2 => Self::Hidden,
            3 => Self::UnconfirmedExtractable,
            4 => Self::UnconfirmedHidden,
            _ => {
                return Err(Self::Error::InvalidStatus(format!(
                    "{} is not a valid status.",
                    value
                )))
            }
        })
    }
}

impl Into<String> for StatusError {
    fn into(self) -> String {
        format!("StatusError {:?}", self)
    }
}

impl KeyStoreValue for Status {
    type Error = StatusError;
    type SerializedValue = Vec<u8>;

    fn serialize(&self) -> Result<Self::SerializedValue, Self::Error> {
        Ok(vec![*self as u8])
    }

    fn deserialize(raw: &mut [u8]) -> Result<Self, Self::Error> {
        if raw.len() < 1 {
            return Err(Self::Error::DeserializationError(format!(
                "Can't deserialize an empty slice to a status."
            )));
        }
        Self::try_from(raw[0])
    }
}