keys-lib 0.1.0

Library for the Keys key-value store
Documentation
use std::fmt::Display;

use base64::{engine::general_purpose::URL_SAFE_NO_PAD, DecodeSliceError, Engine as _};
use rand::Rng;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyValue {
    key: String,
    value: Option<String>,
}

impl KeyValue {
    pub fn new<K: Into<String>, V: Into<String>>(
        key: K,
        value: Option<V>,
    ) -> Self {
        Self {
            key: key.into(),
            value: value.map(|value| value.into()),
        }
    }

    pub fn get_key(&self) -> &str {
        &self.key
    }

    pub fn get_value(&self) -> Option<&str> {
        self.value.as_deref()
    }
}

impl Display for KeyValue {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self.get_value() {
            Some(value) => write!(f, "{}: {}", self.get_key(), value),
            None => write!(f, "{}", self.get_key()),
        }
    }
}

#[derive(Debug, Clone)]
pub struct ApiKey {
    bytes: [u8; 32],
}

impl ApiKey {
    pub fn random<R: Rng>(rng: &mut R) -> Self {
        let mut bytes = [0u8; 32];
        rng.fill_bytes(&mut bytes);
        Self::from_bytes(bytes)
    }

    pub fn from_bytes(bytes: [u8; 32]) -> Self {
        Self { bytes }
    }

    pub fn from_base64<S: AsRef<str>>(base64_api_key: S) -> Result<Self, DecodeSliceError> {
        let mut bytes = [0u8; 32];
        URL_SAFE_NO_PAD.decode_slice(base64_api_key.as_ref(), &mut bytes)?;
        Ok(Self::from_bytes(bytes))
    }

    pub fn to_base64(&self) -> String {
        URL_SAFE_NO_PAD.encode(self.bytes)
    }

    pub fn hash(&self) -> Vec<u8> {
        hex::decode(sha256::digest(&self.bytes)).expect("SHA256 digest contained invalid hex")
    }
}