use litl::{impl_debug_as_litl, impl_single_tagged_data_serde, SingleTaggedData};
use thiserror::Error;
use ti64::MsSinceEpoch;
use crate::ops::{ObjID, Op, OpID, OpKind, OpWithTarget};
use rand::{rngs::OsRng, RngCore};
use crate::mem_use::{MemUsage, MemUser};
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SrcID([u8; 16]);
impl SingleTaggedData for SrcID {
const TAG: &'static str = "opSrc";
fn as_bytes(&self) -> std::borrow::Cow<'_, [u8]> {
std::borrow::Cow::Borrowed(&self.0)
}
fn from_bytes(data: &[u8]) -> Result<Self, litl::TaggedDataError>
where
Self: Sized,
{
let bytes: [u8; 16] = data
.try_into()
.map_err(Into::<SrcIDError>::into)
.map_err(litl::TaggedDataError::data_error)?;
Ok(SrcID(bytes))
}
}
#[derive(Debug, Error)]
pub enum SrcIDError {
#[error("Invalid length for LogID")]
InvalidLength(#[from] std::array::TryFromSliceError),
}
impl_single_tagged_data_serde!(SrcID);
impl_debug_as_litl!(SrcID);
impl SrcID {
pub fn new_random() -> SrcID {
let mut id = [0u8; 16];
OsRng {}.fill_bytes(&mut id);
SrcID(id)
}
pub fn as_bytes(&self) -> &[u8; 16] {
&self.0
}
}
impl MemUser for SrcID {
fn mem_use(&self) -> MemUsage {
MemUsage::Simple(std::mem::size_of::<SrcID>())
}
}
pub struct OpOutput {
pub src_id: SrcID,
sender: Box<dyn OpSender>,
next_sequence_idx: u32,
}
impl OpOutput {
pub fn next_sequence_idx(&self) -> u32 {
self.next_sequence_idx
}
}
pub trait OpSender {
fn send(&mut self, value: OpWithTarget) -> Result<(), String>;
fn test_get_past_sent_ops(&mut self) -> Option<Vec<OpWithTarget>>;
}
#[derive(Default)]
struct DummySender {
sent_ops: Vec<OpWithTarget>,
}
impl OpSender for DummySender {
fn send(&mut self, value: OpWithTarget) -> Result<(), String> {
self.sent_ops.push(value);
Ok(())
}
fn test_get_past_sent_ops(&mut self) -> Option<Vec<OpWithTarget>> {
Some(std::mem::take(&mut self.sent_ops))
}
}
impl OpOutput {
pub fn new_dummy() -> OpOutput {
OpOutput {
src_id: SrcID::new_random(),
next_sequence_idx: 0,
sender: Box::new(DummySender::default()),
}
}
pub fn new(sender: Box<dyn OpSender>) -> OpOutput {
OpOutput {
src_id: SrcID::new_random(),
next_sequence_idx: 0,
sender,
}
}
pub fn write_op_at_time(
&mut self,
target_obj_id: ObjID,
time: MsSinceEpoch,
prev: OpID,
kind: OpKind,
val: Option<litl::Val>,
) -> Op {
let op = Op {
id: OpID(self.src_id, self.next_sequence_idx),
time,
prev,
kind,
val,
};
self.next_sequence_idx += 1;
self.sender
.send(OpWithTarget {
target_obj_id,
op: op.clone(),
})
.unwrap();
op
}
pub fn write_op_now(
&mut self,
target_obj_id: ObjID,
prev: OpID,
kind: OpKind,
val: Option<litl::Val>,
) -> Op {
let op = Op::new(OpID(self.src_id, self.next_sequence_idx), prev, kind, val);
self.next_sequence_idx += 1;
self.sender
.send(OpWithTarget {
target_obj_id,
op: op.clone(),
})
.unwrap();
op
}
pub fn write_create_op(&mut self, kind: OpKind, val: Option<litl::Val>) -> (Op, ObjID) {
let op = Op::new_initial(OpID(self.src_id, self.next_sequence_idx), kind, val);
let obj_id = ObjID::from_first_op_id(op.id);
self.next_sequence_idx += 1;
self.sender
.send(OpWithTarget {
target_obj_id: obj_id,
op: op.clone(),
})
.unwrap();
(op, obj_id)
}
pub fn test_get_past_sent_ops(&mut self) -> Option<Vec<OpWithTarget>> {
self.sender.test_get_past_sent_ops()
}
}