use crate::imp::core::bytes::Bytes32;
use crate::imp::core::codec::{Decode, DecodeError, Decoder, Encode, Encoder};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum RevocationReason {
Unspecified = 0,
Compromise = 1,
Superseded = 2,
Takedown = 3,
}
impl RevocationReason {
pub fn as_u8(self) -> u8 {
self as u8
}
pub fn from_u8(b: u8) -> Self {
match b {
1 => RevocationReason::Compromise,
2 => RevocationReason::Superseded,
3 => RevocationReason::Takedown,
_ => RevocationReason::Unspecified,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TombstoneScope {
Root(Bytes32),
Store,
}
impl TombstoneScope {
fn tag(&self) -> u8 {
match self {
TombstoneScope::Root(_) => 0,
TombstoneScope::Store => 1,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Tombstone {
pub store_id: Bytes32,
pub scope: TombstoneScope,
pub not_after: u64,
pub reason: u8,
}
impl Tombstone {
pub fn root(
store_id: Bytes32,
root: Bytes32,
not_after: u64,
reason: RevocationReason,
) -> Self {
Tombstone {
store_id,
scope: TombstoneScope::Root(root),
not_after,
reason: reason.as_u8(),
}
}
pub fn store(store_id: Bytes32, not_after: u64, reason: RevocationReason) -> Self {
Tombstone {
store_id,
scope: TombstoneScope::Store,
not_after,
reason: reason.as_u8(),
}
}
pub fn canonical(&self) -> alloc::vec::Vec<u8> {
self.to_bytes()
}
}
impl Encode for Tombstone {
fn encode(&self, enc: &mut Encoder) {
self.store_id.encode(enc);
enc.write_bytes(&[self.scope.tag()]);
if let TombstoneScope::Root(root) = &self.scope {
root.encode(enc);
}
self.not_after.encode(enc);
enc.write_bytes(&[self.reason]);
}
}
impl Decode for Tombstone {
fn decode(dec: &mut Decoder<'_>) -> Result<Self, DecodeError> {
let store_id = Bytes32::decode(dec)?;
let scope_tag = dec.read_bytes(1)?[0];
let scope = match scope_tag {
0 => TombstoneScope::Root(Bytes32::decode(dec)?),
1 => TombstoneScope::Store,
other => return Err(DecodeError::InvalidTag(other)),
};
let not_after = u64::decode(dec)?;
let reason = dec.read_bytes(1)?[0];
Ok(Tombstone {
store_id,
scope,
not_after,
reason,
})
}
}