Merge branch 'main' into refactor-wasm

This commit is contained in:
Zixuan Chen 2023-03-24 11:59:28 +08:00
commit 831ab0f04d
13 changed files with 152 additions and 24 deletions

View file

@ -21,7 +21,10 @@
"rust-analyzer.runnableEnv": {
"RUST_BACKTRACE": "full"
},
"rust-analyzer.cargo.features": ["test_utils", "wasm"],
"rust-analyzer.cargo.features": [
"loro-internal/test_utils",
"loro-internal/wasm"
],
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true,
"todo-tree.general.tags": [

3
Cargo.lock generated
View file

@ -747,6 +747,9 @@ dependencies = [
[[package]]
name = "loro"
version = "0.1.0"
dependencies = [
"loro-internal",
]
[[package]]
name = "loro-ffi"

View file

@ -21,7 +21,7 @@ use std::{
fmt::{Debug, Display},
};
use self::{pool_mapping::StateContent, registry::ContainerIdx};
use self::pool_mapping::StateContent;
pub mod pool_mapping;
pub mod registry;
@ -31,6 +31,7 @@ pub mod map;
mod pool;
pub mod text;
pub use registry::ContainerIdx;
// Note: It will be encoded into binary format, so the order of its fields should not be changed.
#[cfg_attr(feature = "test_utils", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)]

View file

@ -775,6 +775,7 @@ mod test {
}
#[test]
#[cfg(feature = "json")]
fn collection() {
let mut loro = LoroCore::default();
let mut list = loro.get_list("list");
@ -798,6 +799,7 @@ mod test {
}
#[test]
#[cfg(feature = "json")]
fn for_each() {
let mut loro = LoroCore::default();
let mut list = loro.get_list("list");
@ -816,6 +818,7 @@ mod test {
}
#[test]
#[cfg(feature = "json")]
fn map() {
let mut loro = LoroCore::default();
let mut list = loro.get_list("list");

View file

@ -13,7 +13,7 @@ use crate::{
};
#[derive(Debug)]
pub struct RawEvent {
pub(crate) struct RawEvent {
pub container_id: ContainerID,
pub old_version: Frontiers,
pub new_version: Frontiers,
@ -81,7 +81,7 @@ impl ObserverOptions {
pub type ObserverHandler = Box<dyn FnMut(Arc<Event>) + Send>;
pub struct Observer {
pub(crate) struct Observer {
handler: ObserverHandler,
options: ObserverOptions,
}

View file

@ -147,12 +147,16 @@ impl Hierarchy {
}
#[inline(always)]
pub fn get_abs_path(&self, reg: &ContainerRegistry, descendant: &ContainerID) -> Option<Path> {
pub(crate) fn get_abs_path(
&self,
reg: &ContainerRegistry,
descendant: &ContainerID,
) -> Option<Path> {
let path = self.get_path(reg, descendant, None);
path.and_then(|x| if x.is_empty() { None } else { Some(x) })
}
pub fn get_path(
pub(crate) fn get_path(
&self,
reg: &ContainerRegistry,
descendant: &ContainerID,
@ -208,7 +212,7 @@ impl Hierarchy {
Some(path)
}
pub fn should_notify(&self, container_id: &ContainerID) -> bool {
pub(crate) fn should_notify(&self, container_id: &ContainerID) -> bool {
if !self.root_observers.is_empty() {
return true;
}
@ -377,7 +381,7 @@ impl Hierarchy {
}
}
pub fn subscribe(&mut self, observer: Observer) -> SubscriptionID {
pub(crate) fn subscribe(&mut self, observer: Observer) -> SubscriptionID {
let id = self.next_id();
if observer.root() {
self.root_observers.insert(id);
@ -434,7 +438,7 @@ impl Hierarchy {
// Do we need return the information that the id does not exist ?
// Considering if in calling, the delete operation is delayed.
pub fn unsubscribe(&mut self, id: SubscriptionID) {
pub(crate) fn unsubscribe(&mut self, id: SubscriptionID) {
if self.calling {
self.deleted_observers.insert(id);
} else {
@ -448,7 +452,7 @@ impl Hierarchy {
}
}
pub fn send_notifications_without_lock(
pub(crate) fn send_notifications_without_lock(
hierarchy: Arc<Mutex<Hierarchy>>,
events: Vec<RawEvent>,
) {

View file

@ -118,7 +118,7 @@ impl LoroEncoder {
ans
}
pub fn decode(
pub(crate) fn decode(
store: &mut LogStore,
hierarchy: &mut Hierarchy,
input: &[u8],
@ -139,7 +139,7 @@ impl LoroEncoder {
}
}
pub fn decode_batch(
pub(crate) fn decode_batch(
store: &mut LogStore,
hierarchy: &mut Hierarchy,
batch: &[Vec<u8>],

View file

@ -81,7 +81,7 @@ impl LogStore {
/// - Update the rest of the log store state.
///
#[instrument(skip_all)]
pub fn import(
pub(crate) fn import(
&mut self,
hierarchy: &mut Hierarchy,
mut changes: RemoteClientChanges,

View file

@ -177,7 +177,7 @@ impl LoroCore {
}
#[instrument(skip_all)]
pub fn notify(&self, events: Vec<RawEvent>) {
pub(crate) fn notify(&self, events: Vec<RawEvent>) {
Hierarchy::send_notifications_without_lock(self.hierarchy.clone(), events)
}

View file

@ -82,6 +82,11 @@ impl TransactionWrap {
pub fn commit(&self) -> Result<(), LoroError> {
self.0.borrow_mut().commit()
}
pub fn decode(&mut self, input: &[u8]) -> Result<(), LoroError> {
let mut txn = self.0.borrow_mut();
txn.decode(input)
}
}
// TODO: use String as Origin for now

View file

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
loro-internal = { path = "../loro-internal" }

View file

@ -1,14 +1,105 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
use loro_internal::{
configure::Configure,
container::ContainerIdRaw,
event::{ObserverHandler, SubscriptionID},
LoroCore, Transact, TransactionWrap,
};
#[cfg(test)]
mod tests {
use super::*;
pub use loro_internal::{
container::ContainerIdx, event, id::ClientID, EncodeMode, List, LoroError, LoroValue, Map,
Text, VersionVector,
};
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
#[repr(transparent)]
#[derive(Default)]
pub struct Loro(LoroCore);
impl Loro {
#[inline(always)]
pub fn new(cfg: Configure, client_id: Option<ClientID>) -> Self {
Self(LoroCore::new(cfg, client_id))
}
#[inline(always)]
pub fn client_id(&self) -> ClientID {
self.0.client_id()
}
#[inline(always)]
pub fn vv_cloned(&self) -> VersionVector {
self.0.vv_cloned()
}
#[inline(always)]
pub fn get_list<I: Into<ContainerIdRaw>>(&mut self, id_or_name: I) -> List {
self.0.get_list(id_or_name)
}
#[inline(always)]
pub fn get_map<I: Into<ContainerIdRaw>>(&mut self, id_or_name: I) -> Map {
self.0.get_map(id_or_name)
}
#[inline(always)]
pub fn get_text<I: Into<ContainerIdRaw>>(&mut self, id_or_name: I) -> Text {
self.0.get_text(id_or_name)
}
#[inline(always)]
pub fn encode_all(&self) -> Vec<u8> {
self.0.encode_all()
}
#[inline(always)]
pub fn encode_from(&self, from: VersionVector) -> Vec<u8> {
self.0.encode_from(from)
}
#[inline(always)]
pub fn encode_with_cfg(&self, mode: EncodeMode) -> Vec<u8> {
self.0.encode_with_cfg(mode)
}
#[inline(always)]
pub fn decode(&mut self, input: &[u8]) -> Result<(), LoroError> {
self.0.decode(input)
}
#[inline(always)]
pub fn to_json(&self) -> LoroValue {
self.0.to_json()
}
#[inline(always)]
pub fn subscribe_deep(&mut self, handler: ObserverHandler) -> SubscriptionID {
self.0.subscribe_deep(handler)
}
#[inline(always)]
pub fn unsubscribe_deep(&mut self, subscription: SubscriptionID) {
self.0.unsubscribe_deep(subscription)
}
#[inline(always)]
pub fn subscribe_once(&mut self, handler: ObserverHandler) -> SubscriptionID {
self.0.subscribe_once(handler)
}
/// Execute with transaction
#[inline(always)]
pub fn txn(&mut self, f: impl FnOnce(TransactionWrap)) {
f(self.transact())
}
}
impl Transact for Loro {
#[inline(always)]
fn transact(&self) -> loro_internal::TransactionWrap {
self.0.transact()
}
#[inline(always)]
fn transact_with(&self, origin: Option<loro_internal::Origin>) -> TransactionWrap {
self.0.transact_with(origin)
}
}

17
crates/loro/tests/test.rs Normal file
View file

@ -0,0 +1,17 @@
use loro::Loro;
#[test]
fn input_text() {
let mut doc = Loro::new(Default::default(), None);
let mut text = doc.get_text("text");
doc.txn(|txn| {
text.insert(&txn, 0, "123").unwrap();
});
let mut doc_b = Loro::new(Default::default(), None);
doc_b.txn(|mut txn| {
txn.decode(&doc.encode_all()).unwrap();
});
let a = doc.to_json();
assert_eq!(a, doc_b.to_json());
}