use serde_derive::{Deserialize, Serialize};
use crate::{
mem_use::{MemUsage, MemUser},
ops::{ObjID, Op, OpKind},
};
#[derive(Clone, Debug)]
pub(crate) struct TextState {
pub(super) create: Option<Op>,
pub(super) root: Option<TextRoot>,
}
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
pub(crate) struct TextRoot {
pub ranges: ObjID,
pub graphemes: ObjID,
}
impl TextState {
pub fn new() -> Self {
TextState {
create: None,
root: None,
}
}
pub fn apply_op(&self, op: Op) -> Self {
match op.kind {
OpKind::TextCreate => {
if let Some(existing_entry) = &self.create {
if existing_entry.id == op.id {
return self.clone();
} else {
panic!("Already has a create op, with different id")
}
}
TextState {
root: Some(
litl::from_val(
op.val
.clone()
.expect("Expected text root as val on create op"),
)
.expect("Expected valid text root in create op"),
),
create: Some(op),
}
}
_ => panic!("Unexpected op for text"),
}
}
pub fn apply_ops<II: IntoIterator<Item = Op>>(&self, ops: II) -> Self {
let mut next = self.clone();
for op in ops {
next = next.apply_op(op);
}
next
}
pub(crate) fn ops_since(&self, maybe_other: Option<&Self>) -> Vec<Op> {
if let Some(create) = &self.create {
if maybe_other.map(|other| &other.create).is_none() {
vec![create.clone()]
} else {
vec![]
}
} else {
vec![]
}
}
}
impl MemUser for TextState {
fn mem_use(&self) -> MemUsage {
MemUsage::Struct {
name: "TextState",
fields: vec![
("create", self.create.mem_use()),
("root", self.root.mem_use()),
],
}
}
}
impl MemUser for TextRoot {
fn mem_use(&self) -> MemUsage {
MemUsage::Struct {
name: "TextRoot",
fields: vec![
("ranges", self.ranges.mem_use()),
("graphemes", self.graphemes.mem_use()),
],
}
}
}