extern crate alloc;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use crate::metis::{
Anchor, Cut, Dot, DotSet, DotStore, Dotted, Locus, Retired, Rhapsody, Stability,
};
use super::Replica;
impl Replica {
pub fn insert(&mut self, ch: char, anchor: Option<Dot>) -> Dot {
let rank = self.clock.now(0u16);
let anchor = anchor.map_or(Anchor::Origin, |dot| Anchor::After(dot.into()));
let (dot, _) = self.text.compose(|assigned| {
let mut rhapsody = Rhapsody::new();
let _ = rhapsody.weave(assigned, Locus { anchor, rank });
(rhapsody, DotSet::new())
});
let _ = self.chars.insert(dot, ch);
dot
}
pub fn insert_visual(&mut self, ch: char, after: Option<Dot>) -> Dot {
let anchor = self
.text
.state()
.store()
.anchor_for_visual_insert(after.map(Into::into));
self.weave_at_seam(ch, anchor)
}
pub fn insert_before_visual(&mut self, ch: char, before: Option<Dot>) -> Dot {
let order = self.order();
let after = before.map_or_else(
|| order.last().copied(),
|target| {
order
.iter()
.position(|&d| d == target)
.and_then(|idx| idx.checked_sub(1).map(|prev| order[prev]))
},
);
let anchor = self
.text
.state()
.store()
.anchor_for_visual_insert(after.map(Into::into));
self.weave_at_seam(ch, anchor)
}
fn weave_at_seam(&mut self, ch: char, anchor: Anchor) -> Dot {
if let Some(top_child) = self.text.state().store().children_of(anchor).next()
&& let Some(locus) = self.text.state().store().locus(top_child)
{
self.clock.observe(locus.rank);
}
let rank = self.clock.now(0u16);
let dot = self.text.state().next_dot(self.station);
let _ = self.text.compose(|assigned| {
let mut rhapsody = Rhapsody::new();
let _ = rhapsody.weave(assigned, Locus { anchor, rank });
(rhapsody, DotSet::new())
});
let _ = self.chars.insert(dot, ch);
dot
}
pub fn delete(&mut self, dot: Dot) {
let mut superseded = DotSet::new();
let _ = superseded.insert(dot);
let _ = self.text.retract(superseded);
}
#[must_use]
pub fn text(&self) -> String {
self.text
.state()
.store()
.order()
.into_iter()
.filter_map(|dot| self.chars.get(&dot).copied())
.collect()
}
#[must_use]
pub fn order(&self) -> Vec<Dot> {
self.text.state().store().order()
}
#[must_use]
pub fn text_context(&self) -> &DotSet {
self.text.state().context()
}
#[must_use]
pub fn text_owed(&self, peer: u32) -> Option<Dotted<Rhapsody>> {
self.purview.owed(self.text.state(), peer)
}
#[must_use]
pub fn text_owed_to(&self, peer_context: &DotSet) -> Dotted<Rhapsody> {
self.text.owed_to(peer_context)
}
#[must_use]
pub fn text_owed_witnessed(
&self,
peer_context: &DotSet,
peer_woven: &DotSet,
) -> Dotted<Rhapsody> {
self.text.owed_to_witnessed(peer_context, peer_woven)
}
#[must_use]
pub fn text_woven(&self) -> &DotSet {
self.text.state().store().woven()
}
#[must_use]
pub fn text_owed_since(&self, peer: &Cut) -> Dotted<Rhapsody> {
self.text.state().delta_for_since(peer)
}
pub fn absorb_text(
&mut self,
from: u32,
delta: &Dotted<Rhapsody>,
chars: &BTreeMap<Dot, char>,
) {
let received = self.text.absorb(from, delta);
for dot in delta.store().dots() {
if let Some(&ch) = chars.get(&dot) {
let _ = self.chars.insert(dot, ch);
}
}
let _ = self.purview.note(&received);
}
#[must_use]
pub fn visible_len(&self) -> usize {
self.text.state().store().visible_len()
}
#[must_use]
pub fn skeleton_len(&self) -> usize {
self.text.state().store().skeleton_len()
}
pub fn condense(&mut self, retired: &Retired) -> usize {
self.text.condense(retired)
}
pub fn report_into(&self, stability: &mut Stability) {
let floor = self.text.state().context().floor();
let _ = stability.report(self.station, &floor);
}
}