use uuid::Uuid;
pub type NumericDate = i64;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub enum Alg {
Siv,
GcmSiv,
}
impl Alg {
pub fn code(self) -> char {
match self {
Alg::Siv => '0',
Alg::GcmSiv => '1',
}
}
pub fn from_code(c: char) -> Option<Alg> {
match c {
'0' => Some(Alg::Siv),
'1' => Some(Alg::GcmSiv),
_ => None,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Encoding {
B64,
Hex,
}
impl Encoding {
pub fn separator(self) -> char {
match self {
Encoding::B64 => '.',
Encoding::Hex => '~',
}
}
pub fn from_separator(c: char) -> Option<Encoding> {
match c {
'.' => Some(Encoding::B64),
'~' => Some(Encoding::Hex),
_ => None,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub enum Format {
Json,
Toml,
Cbor,
}
impl Format {
pub fn tag(self) -> u8 {
match self {
Format::Json => b'j',
Format::Toml => b't',
Format::Cbor => b'c',
}
}
pub fn from_tag(tag: u8) -> Option<Format> {
match tag {
b'j' => Some(Format::Json),
b't' => Some(Format::Toml),
b'c' => Some(Format::Cbor),
_ => None,
}
}
}
pub const MANIFEST_KEY: [u8; 64] = [
0x38, 0x12, 0x84, 0x63, 0x3d, 0x02, 0xea, 0x5f, 0x35, 0xdf, 0x85, 0x96, 0xb5, 0xcc, 0x42, 0x18, 0x31, 0x00, 0x60, 0x46, 0x8e, 0x8b, 0x46, 0x54, 0x55, 0xa4, 0x15, 0x17, 0x4e, 0xa6, 0xe9, 0x66, 0xa9, 0xf4, 0x8e, 0xec, 0x4b, 0xa4, 0x46, 0xdd, 0xfc, 0x8b, 0x78, 0x58, 0x78, 0x95, 0x35, 0x6f, 0x45, 0xa7, 0x5a, 0x1a, 0xb7, 0x41, 0x94, 0x54, 0xdd, 0x9f, 0x7a, 0xa8, 0xa9, 0x5d, 0xbd, 0xd5, ];
pub fn tid_issued_at(tid: Uuid) -> NumericDate {
let b = tid.as_bytes();
let ms = (u64::from(b[0]) << 40)
| (u64::from(b[1]) << 32)
| (u64::from(b[2]) << 24)
| (u64::from(b[3]) << 16)
| (u64::from(b[4]) << 8)
| u64::from(b[5]);
(ms / 1000) as NumericDate
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn manifest_key_matches_spec_hex() {
let mut hex = String::new();
crate::encoding::encode_into(&MANIFEST_KEY, Encoding::Hex, &mut hex);
assert_eq!(
hex,
"381284633d02ea5f35df8596b5cc4218310060468e8b465455a415174ea6e966\
a9f48eec4ba446ddfc8b78587895356f45a75a1ab7419454dd9f7aa8a95dbdd5"
);
}
#[test]
fn tid_issued_at_reads_the_48_bit_ms_field() {
let tid = Uuid::from_bytes([
0x00, 0x00, 0x00, 0x01, 0x86, 0xa0, 0x70, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
]);
assert_eq!(tid_issued_at(tid), 100);
}
}