diff --git a/crates/loro-internal/src/container/list/list_container.rs b/crates/loro-internal/src/container/list/list_container.rs index d8652144..8389e295 100644 --- a/crates/loro-internal/src/container/list/list_container.rs +++ b/crates/loro-internal/src/container/list/list_container.rs @@ -90,7 +90,7 @@ impl ListContainer { let store = m.read().unwrap(); let container = store.get_container(&container_id).unwrap(); drop(store); - prelim.integrate(ctx, container); + prelim.integrate(ctx, container)?; Ok((event, Some(container_id))) } else { let value = value.into_value().unwrap(); diff --git a/crates/loro-internal/src/prelim.rs b/crates/loro-internal/src/prelim.rs index 47500408..40dbe4db 100644 --- a/crates/loro-internal/src/prelim.rs +++ b/crates/loro-internal/src/prelim.rs @@ -1,6 +1,7 @@ use std::sync::{Mutex, Weak}; use enum_as_inner::EnumAsInner; +use fxhash::FxHashMap; use crate::{ container::registry::ContainerInstance, context::Context, ContainerType, LoroError, LoroValue, @@ -87,3 +88,65 @@ impl From for PrelimValue { PrelimValue::Value(v.into()) } } + +pub struct PrelimText(pub String); + +impl Prelim for PrelimText { + fn convert_value(self) -> Result<(PrelimValue, Option), LoroError> { + Ok((PrelimValue::Container(ContainerType::Text), Some(self))) + } + + fn integrate( + self, + ctx: &C, + container: Weak>, + ) -> Result<(), LoroError> { + let text = container.upgrade().unwrap(); + let mut text = text.try_lock().unwrap(); + let text = text.as_text_mut().unwrap(); + text.insert(ctx, 0, &self.0); + Ok(()) + } +} + +pub struct PrelimList(pub Vec); + +impl Prelim for PrelimList { + fn convert_value(self) -> Result<(PrelimValue, Option), LoroError> { + Ok((PrelimValue::Container(ContainerType::List), Some(self))) + } + + fn integrate( + self, + ctx: &C, + container: Weak>, + ) -> Result<(), LoroError> { + let list = container.upgrade().unwrap(); + let mut list = list.try_lock().unwrap(); + let list = list.as_list_mut().unwrap(); + list.insert_batch(ctx, 0, self.0); + Ok(()) + } +} + +pub struct PrelimMap(pub FxHashMap); + +impl Prelim for PrelimMap { + fn convert_value(self) -> Result<(PrelimValue, Option), LoroError> { + Ok((PrelimValue::Container(ContainerType::Map), Some(self))) + } + + fn integrate( + self, + ctx: &C, + container: Weak>, + ) -> Result<(), LoroError> { + let map = container.upgrade().unwrap(); + let mut map = map.try_lock().unwrap(); + let map = map.as_map_mut().unwrap(); + for (key, value) in self.0.into_iter() { + map.insert(ctx, key.into(), value)?; + } + Ok(()) + } +}