mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
feat: hierarchy children & parent
This commit is contained in:
parent
13becdb3f3
commit
e402850440
4 changed files with 73 additions and 8 deletions
|
@ -684,12 +684,9 @@ impl List {
|
|||
self.with_container(|list| list.iter().enumerate().for_each(f))
|
||||
}
|
||||
|
||||
// pub fn map<F: FnMut(&LoroValue) -> R, R>(
|
||||
// &self,
|
||||
// f: F,
|
||||
// ) -> Map<impl Iterator<Item = &LoroValue>, F> {
|
||||
// self.with_container(|list| list.iter().map(f))
|
||||
// }
|
||||
pub fn map<F: FnMut((usize, &LoroValue)) -> R, R>(&self, f: F) -> Vec<R> {
|
||||
self.with_container(|list| list.iter().enumerate().map(f).collect())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
|
@ -735,7 +732,7 @@ impl ContainerWrapper for List {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::LoroCore;
|
||||
use crate::{LoroCore, LoroValue, PrelimContainer};
|
||||
|
||||
#[test]
|
||||
fn test_list_get() {
|
||||
|
@ -787,4 +784,16 @@ mod test {
|
|||
assert_eq!(format!("\"{c}\""), v.to_json())
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn map() {
|
||||
let mut loro = LoroCore::default();
|
||||
let mut list = loro.get_list("list");
|
||||
list.insert(&loro, 0, "a").unwrap();
|
||||
list.insert(&loro, 1, "b").unwrap();
|
||||
list.insert(&loro, 2, "c").unwrap();
|
||||
// list.insert(&loro, 3, PrelimContainer::from("hello".to_string()))
|
||||
// .unwrap();
|
||||
assert_eq!(list.map(|(_, v)| v.to_json()),vec!["\"a\"", "\"b\"", "\"c\""]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ pub enum LoroError {
|
|||
LockError,
|
||||
#[error("LoroValue::Unresolved cannot be converted to PrelimValue")]
|
||||
PrelimError,
|
||||
#[error("Cannot find ({0}) ")]
|
||||
NotFoundError(Box<str>),
|
||||
// #[error("the data for key `{0}` is not available")]
|
||||
// Redaction(String),
|
||||
// #[error("invalid header (expected {expected:?}, found {found:?})")]
|
||||
|
|
|
@ -8,6 +8,7 @@ use fxhash::{FxHashMap, FxHashSet};
|
|||
use crate::{
|
||||
container::{registry::ContainerRegistry, ContainerID},
|
||||
event::{Event, EventDispatch, Index, Observer, Path, PathAndTarget, RawEvent, SubscriptionID},
|
||||
LoroError,
|
||||
};
|
||||
|
||||
/// [`Hierarchy`] stores the hierarchical relationship between containers
|
||||
|
@ -78,6 +79,20 @@ impl Hierarchy {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn children(&self, id: &ContainerID) -> Result<FxHashSet<ContainerID>, LoroError> {
|
||||
self.nodes
|
||||
.get(id)
|
||||
.ok_or(LoroError::NotFoundError(format!("{:?}", id).into()))
|
||||
.map(|node| node.children.clone())
|
||||
}
|
||||
|
||||
pub fn parent(&self, id: &ContainerID) -> Result<Option<ContainerID>, LoroError> {
|
||||
self.nodes
|
||||
.get(id)
|
||||
.ok_or(LoroError::NotFoundError(format!("{:?}", id).into()))
|
||||
.map(|node| node.parent.clone())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains(&self, id: &ContainerID) -> bool {
|
||||
self.nodes.get(id).is_some() || id.is_root()
|
||||
|
@ -429,3 +444,32 @@ impl Hierarchy {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use fxhash::FxHashMap;
|
||||
|
||||
use crate::{LoroCore, PrelimContainer};
|
||||
|
||||
#[test]
|
||||
fn children_parent() {
|
||||
let mut loro = LoroCore::default();
|
||||
let mut list = loro.get_list("list");
|
||||
let map_container_id = list
|
||||
.push(&loro, PrelimContainer::from(FxHashMap::default()))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let list_container_id = list.id();
|
||||
assert_eq!(
|
||||
loro.children(&list_container_id)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
vec![map_container_id.clone()]
|
||||
);
|
||||
assert_eq!(
|
||||
loro.parent(&map_container_id).unwrap().unwrap(),
|
||||
list_container_id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
log_store::{EncodeConfig, LoroEncoder},
|
||||
LoroError, LoroValue,
|
||||
};
|
||||
use fxhash::FxHashMap;
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
|
@ -79,6 +79,16 @@ impl LoroCore {
|
|||
store.contains_container(id)
|
||||
}
|
||||
|
||||
pub fn children(&self, id: &ContainerID) -> Result<FxHashSet<ContainerID>, LoroError> {
|
||||
let hierarchy = self.hierarchy.try_lock().unwrap();
|
||||
hierarchy.children(id)
|
||||
}
|
||||
|
||||
pub fn parent(&self, id: &ContainerID) -> Result<Option<ContainerID>, LoroError> {
|
||||
let hierarchy = self.hierarchy.try_lock().unwrap();
|
||||
hierarchy.parent(id)
|
||||
}
|
||||
|
||||
// TODO: make it private
|
||||
pub fn export(&self, remote_vv: VersionVector) -> FxHashMap<u64, Vec<Change<RemoteOp>>> {
|
||||
let store = self.log_store.read().unwrap();
|
||||
|
|
Loading…
Reference in a new issue