mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
feat: make getting child container handler simple (#104)
This commit is contained in:
parent
72cc8c6ed5
commit
b22bd98f6b
4 changed files with 63 additions and 3 deletions
|
@ -8,6 +8,7 @@ use crate::{
|
|||
delta::MapValue,
|
||||
txn::EventHint,
|
||||
};
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use loro_common::{ContainerID, ContainerType, LoroResult, LoroValue};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
|
@ -32,6 +33,23 @@ pub struct ListHandler {
|
|||
state: Weak<Mutex<DocState>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, EnumAsInner)]
|
||||
pub enum Handler {
|
||||
Text(TextHandler),
|
||||
Map(MapHandler),
|
||||
List(ListHandler),
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
fn new(value: ContainerIdx, state: Weak<Mutex<DocState>>) -> Self {
|
||||
match value.get_type() {
|
||||
ContainerType::Text => Self::Text(TextHandler::new(value, state)),
|
||||
ContainerType::Map => Self::Map(MapHandler::new(value, state)),
|
||||
ContainerType::List => Self::List(ListHandler::new(value, state)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextHandler {
|
||||
pub fn new(idx: ContainerIdx, state: Weak<Mutex<DocState>>) -> Self {
|
||||
assert_eq!(idx.get_type(), ContainerType::Text);
|
||||
|
@ -343,6 +361,24 @@ impl ListHandler {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn get_child_handler(&self, index: usize) -> Handler {
|
||||
let mutex = &self.state.upgrade().unwrap();
|
||||
let state = mutex.lock().unwrap();
|
||||
let container_id = state.with_state(self.container_idx, |state| {
|
||||
state
|
||||
.as_list_state()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(index)
|
||||
.unwrap()
|
||||
.as_container()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
let idx = state.arena.register_container(&container_id);
|
||||
Handler::new(idx, self.state.clone())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.state
|
||||
.upgrade()
|
||||
|
@ -504,6 +540,24 @@ impl MapHandler {
|
|||
.get_value_by_idx(self.container_idx)
|
||||
}
|
||||
|
||||
pub fn get_child_handler(&self, key: &str) -> Handler {
|
||||
let mutex = &self.state.upgrade().unwrap();
|
||||
let state = mutex.lock().unwrap();
|
||||
let container_id = state.with_state(self.container_idx, |state| {
|
||||
state
|
||||
.as_map_state()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(key)
|
||||
.unwrap()
|
||||
.as_container()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
let idx = state.arena.register_container(&container_id);
|
||||
Handler::new(idx, self.state.clone())
|
||||
}
|
||||
|
||||
pub fn get_deep_value(&self) -> LoroValue {
|
||||
self.state
|
||||
.upgrade()
|
||||
|
|
|
@ -118,10 +118,10 @@ impl LoroDoc {
|
|||
#[inline(always)]
|
||||
pub fn with_txn<F>(&self, f: F) -> LoroResult<()>
|
||||
where
|
||||
F: Fn(&mut Transaction),
|
||||
F: Fn(&mut Transaction) -> LoroResult<()>,
|
||||
{
|
||||
let mut txn = self.txn().unwrap();
|
||||
f(&mut txn);
|
||||
f(&mut txn)?;
|
||||
txn.commit()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::{borrow::Cow, mem::take, sync::Arc};
|
||||
|
||||
use debug_log::debug_dbg;
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
|
@ -374,6 +373,7 @@ impl DocState {
|
|||
.as_text_state()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn with_state<F, R>(&self, idx: ContainerIdx, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&State) -> R,
|
||||
|
|
|
@ -53,11 +53,13 @@ fn map_checkout() {
|
|||
let v_empty = doc.oplog_frontiers();
|
||||
doc.with_txn(|txn| {
|
||||
meta.insert(txn, "key", 0.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let v0 = doc.oplog_frontiers();
|
||||
doc.with_txn(|txn| {
|
||||
meta.insert(txn, "key", 1.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let v1 = doc.oplog_frontiers();
|
||||
|
@ -80,18 +82,21 @@ fn map_concurrent_checkout() {
|
|||
doc_a
|
||||
.with_txn(|txn| {
|
||||
meta_a.insert(txn, "key", 0.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let va = doc_a.oplog_frontiers();
|
||||
doc_b
|
||||
.with_txn(|txn| {
|
||||
meta_b.insert(txn, "s", 1.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let vb_0 = doc_b.oplog_frontiers();
|
||||
doc_b
|
||||
.with_txn(|txn| {
|
||||
meta_b.insert(txn, "key", 1.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let vb_1 = doc_b.oplog_frontiers();
|
||||
|
@ -99,6 +104,7 @@ fn map_concurrent_checkout() {
|
|||
doc_a
|
||||
.with_txn(|txn| {
|
||||
meta_a.insert(txn, "key", 2.into()).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
|
|
Loading…
Reference in a new issue