use loro_common::{ContainerID, ContainerType, InternalString, LoroMapValue};
use crate::{container::idx::ContainerIdx, event::Index};
use super::{ContainerState, DocState};
impl DocState {
pub(super) fn get_logical_child_index(
&mut self,
parent_idx: ContainerIdx,
child_id: &ContainerID,
) -> Option<Index> {
if let Some((parent_id, key, kind)) = child_id.parse_mergeable() {
return self.resolve_mergeable_child_index(parent_idx, &parent_id, &key, kind);
}
self.store
.get_container_mut(parent_idx)
.and_then(|parent_state| parent_state.get_child_index(child_id))
}
pub(super) fn contains_logical_child(
&mut self,
parent_idx: ContainerIdx,
child_id: &ContainerID,
) -> bool {
self.get_logical_child_index(parent_idx, child_id).is_some()
}
fn resolve_mergeable_child_index(
&mut self,
parent_idx: ContainerIdx,
encoded_parent_id: &ContainerID,
key: &str,
kind: ContainerType,
) -> Option<Index> {
if parent_idx.get_type() != ContainerType::Map {
return None;
}
let actual_parent_id = self.arena.idx_to_id(parent_idx)?;
if &actual_parent_id != encoded_parent_id {
return None;
}
let value = self.store.map_get(parent_idx, key)?;
if loro_common::parse_mergeable_marker(&actual_parent_id, key, &value) == Some(kind) {
Some(Index::Key(key.into()))
} else {
None
}
}
pub(super) fn mergeable_children_from_value(
&self,
parent_id: &ContainerID,
map_value: &LoroMapValue,
) -> Vec<(InternalString, ContainerID)> {
let mut ans = Vec::new();
for (key, value) in map_value.iter() {
if let Some(kind) = loro_common::parse_mergeable_marker(parent_id, key, value) {
let key_istr: InternalString = key.as_str().into();
let cid = ContainerID::new_mergeable(parent_id, key, kind);
ans.push((key_istr, cid));
}
}
ans
}
}