use core::fmt::{self, Debug};
use crate::error::IntoAnyError;
#[cfg(mls_build_async)]
use alloc::boxed::Box;
use alloc::vec::Vec;
use zeroize::Zeroizing;
#[derive(Clone, PartialEq, Eq)]
pub struct GroupState {
pub id: Vec<u8>,
pub data: Zeroizing<Vec<u8>>,
}
impl Debug for GroupState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GroupState")
.field("id", &crate::debug::pretty_bytes(&self.id))
.finish()
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct EpochRecord {
pub id: u64,
pub data: Zeroizing<Vec<u8>>,
}
impl Debug for EpochRecord {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("EpochRecord").field("id", &self.id).finish()
}
}
impl EpochRecord {
pub fn new(id: u64, data: Zeroizing<Vec<u8>>) -> Self {
Self { id, data }
}
}
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
#[cfg_attr(mls_build_async, maybe_async::must_be_async)]
pub trait GroupStateStorage: Send + Sync {
type Error: IntoAnyError;
async fn state(&self, group_id: &[u8]) -> Result<Option<Zeroizing<Vec<u8>>>, Self::Error>;
async fn epoch(
&self,
group_id: &[u8],
epoch_id: u64,
) -> Result<Option<Zeroizing<Vec<u8>>>, Self::Error>;
async fn write(
&mut self,
state: GroupState,
epoch_inserts: Vec<EpochRecord>,
epoch_updates: Vec<EpochRecord>,
) -> Result<(), Self::Error>;
async fn max_epoch_id(&self, group_id: &[u8]) -> Result<Option<u64>, Self::Error>;
}