diff --git a/crates/loro-internal/src/handler.rs b/crates/loro-internal/src/handler.rs index 75c5986f..995396e2 100644 --- a/crates/loro-internal/src/handler.rs +++ b/crates/loro-internal/src/handler.rs @@ -11,7 +11,7 @@ use crate::{ diff::{myers_diff, OperateProxy}, event::{Diff, TextDiffItem}, op::ListSlice, - state::{ContainerState, IndexType, State, TreeParentId}, + state::{IndexType, State, TreeParentId}, txn::EventHint, utils::{string_slice::StringSlice, utf16::count_utf16_len}, }; @@ -777,6 +777,7 @@ impl HandlerTrait for ListHandler { } } } + #[derive(Clone)] pub struct UnknownHandler { inner: BasicHandler, @@ -2690,6 +2691,21 @@ impl ListHandler { MaybeDetached::Attached(a) => a.is_deleted(), } } + + pub fn clear(&self) -> LoroResult<()> { + match &self.inner { + MaybeDetached::Detached(l) => { + let mut l = l.try_lock().unwrap(); + l.value.clear(); + Ok(()) + } + MaybeDetached::Attached(a) => a.with_txn(|txn| self.clear_with_txn(txn)), + } + } + + pub fn clear_with_txn(&self, txn: &mut Transaction) -> LoroResult<()> { + self.delete_with_txn(txn, 0, self.len()) + } } impl MovableListHandler { @@ -3207,8 +3223,8 @@ impl MovableListHandler { let a = state.as_movable_list_state().unwrap(); match a.get(index, IndexType::ForUser) { Some(v) => { - if let LoroValue::Container(id) = v { - Some(ValueOrHandler::Handler(create_handler(m, id.clone()))) + if let LoroValue::Container(c) = v { + Some(ValueOrHandler::Handler(create_handler(m, c.clone()))) } else { Some(ValueOrHandler::Value(v.clone())) } @@ -3329,6 +3345,21 @@ impl MovableListHandler { MaybeDetached::Attached(a) => a.is_deleted(), } } + + pub fn clear(&self) -> LoroResult<()> { + match &self.inner { + MaybeDetached::Detached(d) => { + let mut d = d.lock().unwrap(); + d.value.clear(); + Ok(()) + } + MaybeDetached::Attached(a) => a.with_txn(|txn| self.clear_with_txn(txn)), + } + } + + pub fn clear_with_txn(&self, txn: &mut Transaction) -> LoroResult<()> { + self.delete_with_txn(txn, 0, self.len()) + } } impl MapHandler { @@ -3638,6 +3669,34 @@ impl MapHandler { MaybeDetached::Attached(a) => a.is_deleted(), } } + + pub fn clear(&self) -> LoroResult<()> { + match &self.inner { + MaybeDetached::Detached(m) => { + let mut m = m.try_lock().unwrap(); + m.value.clear(); + Ok(()) + } + MaybeDetached::Attached(a) => a.with_txn(|txn| self.clear_with_txn(txn)), + } + } + + pub fn clear_with_txn(&self, txn: &mut Transaction) -> LoroResult<()> { + let keys: Vec = self.inner.try_attached_state()?.with_state(|state| { + state + .as_map_state() + .unwrap() + .iter() + .map(|(k, _)| k.clone()) + .collect() + }); + + for key in keys { + self.delete_with_txn(txn, &key)?; + } + + Ok(()) + } } #[inline(always)] diff --git a/crates/loro-wasm/src/lib.rs b/crates/loro-wasm/src/lib.rs index 0334453e..6261f710 100644 --- a/crates/loro-wasm/src/lib.rs +++ b/crates/loro-wasm/src/lib.rs @@ -2415,6 +2415,12 @@ impl LoroMap { }; handler_to_js_value(Handler::Map(h), self.doc.clone()).into() } + + /// Delete all key-value pairs in the map. + pub fn clear(&self) -> JsResult<()> { + self.handler.clear()?; + Ok(()) + } } impl Default for LoroMap { @@ -2743,6 +2749,12 @@ impl LoroList { Ok(None) } } + + /// Delete all elements in the list. + pub fn clear(&self) -> JsResult<()> { + self.handler.clear()?; + Ok(()) + } } impl Default for LoroList { @@ -3115,6 +3127,12 @@ impl LoroMovableList { v.into() })) } + + /// Delete all elements in the list. + pub fn clear(&self) -> JsResult<()> { + self.handler.clear()?; + Ok(()) + } } /// The handler of a tree(forest) container. diff --git a/crates/loro/src/lib.rs b/crates/loro/src/lib.rs index aa9aeafc..675cdaf6 100644 --- a/crates/loro/src/lib.rs +++ b/crates/loro/src/lib.rs @@ -1058,6 +1058,11 @@ impl LoroList { pub fn to_vec(&self) -> Vec { Arc::unwrap_or_clone(self.get_value().into_list().unwrap()) } + + /// Delete all elements in the list. + pub fn clear(&self) -> LoroResult<()> { + self.handler.clear() + } } impl Default for LoroList { @@ -1229,6 +1234,11 @@ impl LoroMap { .get_or_create_container(key, child.to_handler())?, )) } + + /// Delete all key-value pairs in the map. + pub fn clear(&self) -> LoroResult<()> { + self.handler.clear() + } } impl Default for LoroMap { @@ -2102,6 +2112,11 @@ impl LoroMovableList { pub fn to_vec(&self) -> Vec { Arc::unwrap_or_clone(self.get_value().into_list().unwrap()) } + + /// Delete all elements in the list. + pub fn clear(&self) -> LoroResult<()> { + self.handler.clear() + } } impl Default for LoroMovableList {