use crate::error::Result;
use crate::ids::CollectionId;
use crate::page::{PageCodec, PlainCodec};
pub trait KeyRing: Send + Sync {
fn catalog_codec(&self) -> &dyn PageCodec;
fn collection_codec(&self, collection: CollectionId) -> Result<Box<dyn PageCodec>>;
fn provision_collection(&self, collection: CollectionId) -> Result<()>;
fn shred_collection(&self, collection: CollectionId) -> Result<()>;
}
pub struct SingleCodecKeyRing {
codec: Box<dyn PageCodec>,
}
impl SingleCodecKeyRing {
#[must_use]
pub fn new(codec: Box<dyn PageCodec>) -> Self {
Self { codec }
}
#[must_use]
pub fn plaintext() -> Self {
Self::new(Box::new(PlainCodec))
}
}
impl KeyRing for SingleCodecKeyRing {
fn catalog_codec(&self) -> &dyn PageCodec {
self.codec.as_ref()
}
fn collection_codec(&self, _collection: CollectionId) -> Result<Box<dyn PageCodec>> {
Ok(self.codec.clone_box())
}
fn provision_collection(&self, _collection: CollectionId) -> Result<()> {
Ok(())
}
fn shred_collection(&self, _collection: CollectionId) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::page::PAGE_SIZE;
#[test]
fn single_codec_keyring_shares_one_codec() {
let kr = SingleCodecKeyRing::plaintext();
assert_eq!(kr.catalog_codec().block_size(), PAGE_SIZE);
let c0 = kr.collection_codec(CollectionId(0)).unwrap();
let c1 = kr.collection_codec(CollectionId(1)).unwrap();
assert_eq!(c0.block_size(), PAGE_SIZE);
assert_eq!(c1.block_size(), PAGE_SIZE);
}
#[test]
fn single_codec_keyring_provision_and_shred_are_noops() {
let kr = SingleCodecKeyRing::plaintext();
kr.provision_collection(CollectionId(7)).unwrap();
kr.shred_collection(CollectionId(7)).unwrap();
assert!(kr.collection_codec(CollectionId(7)).is_ok());
}
}