Remove merge from sync-lib
This commit is contained in:
parent
d9d14e03e9
commit
4543180f7b
8 changed files with 32 additions and 302 deletions
|
|
@ -11,7 +11,6 @@ crate-type = ["cdylib", "rlib"]
|
|||
|
||||
[dependencies]
|
||||
base64 = "0.22.1"
|
||||
reconcile = { path = "../reconcile" }
|
||||
wasm-bindgen = "0.2.99"
|
||||
thiserror = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
use wasm_bindgen::prelude::*;
|
||||
|
||||
/// Wrapper type to expose `TextWithCursors` to JS.
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TextWithCursors {
|
||||
text: String,
|
||||
cursors: Vec<CursorPosition>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl TextWithCursors {
|
||||
#[wasm_bindgen(constructor)]
|
||||
#[must_use]
|
||||
pub fn new(text: String, cursors: Vec<CursorPosition>) -> Self { Self { text, cursors } }
|
||||
|
||||
#[must_use]
|
||||
pub fn text(&self) -> String { self.text.clone() }
|
||||
|
||||
#[must_use]
|
||||
pub fn cursors(&self) -> Vec<CursorPosition> { self.cursors.clone() }
|
||||
}
|
||||
|
||||
impl From<TextWithCursors> for reconcile::TextWithCursors<'_> {
|
||||
fn from(owned: TextWithCursors) -> Self {
|
||||
reconcile::TextWithCursors::new_owned(
|
||||
owned.text.to_string(),
|
||||
owned
|
||||
.cursors
|
||||
.into_iter()
|
||||
.map(std::convert::Into::into)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reconcile::TextWithCursors<'_>> for TextWithCursors {
|
||||
fn from(text_with_cursors: reconcile::TextWithCursors<'_>) -> Self {
|
||||
TextWithCursors {
|
||||
text: text_with_cursors.text.into_owned(),
|
||||
cursors: text_with_cursors
|
||||
.cursors
|
||||
.into_iter()
|
||||
.map(std::convert::Into::into)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper type to expose `CursorPosition` to JS.
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct CursorPosition {
|
||||
id: usize,
|
||||
char_index: usize,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl CursorPosition {
|
||||
#[wasm_bindgen(constructor)]
|
||||
#[must_use]
|
||||
pub fn new(id: usize, char_index: usize) -> Self { Self { id, char_index } }
|
||||
|
||||
#[must_use]
|
||||
pub fn id(&self) -> usize { self.id }
|
||||
|
||||
#[wasm_bindgen(js_name = characterPosition)]
|
||||
#[must_use]
|
||||
pub fn char_index(&self) -> usize { self.char_index }
|
||||
}
|
||||
|
||||
impl From<CursorPosition> for reconcile::CursorPosition {
|
||||
fn from(owned: CursorPosition) -> Self {
|
||||
reconcile::CursorPosition {
|
||||
id: owned.id,
|
||||
char_index: owned.char_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reconcile::CursorPosition> for CursorPosition {
|
||||
fn from(cursor: reconcile::CursorPosition) -> Self {
|
||||
CursorPosition {
|
||||
id: cursor.id,
|
||||
char_index: cursor.char_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
//! This crate provides utilities for easily communicating between backend &
|
||||
//! frontend and ensuring the same logic for encoding and decoding binary data,
|
||||
//! and 3-way-merging documents in Rust and JavaScript.
|
||||
//! and filtering files.
|
||||
//!
|
||||
//! The crate is designed to be used as a Rust library and as a
|
||||
//! TypeScript/JavaScript package through WebAssembly (WASM).
|
||||
|
|
@ -12,11 +12,9 @@
|
|||
use core::str;
|
||||
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||
use cursor::TextWithCursors;
|
||||
use errors::SyncLibError;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod cursor;
|
||||
pub mod errors;
|
||||
|
||||
/// Encode binary data for easy transport over HTTP. Inverse of
|
||||
|
|
@ -62,78 +60,6 @@ pub fn base64_to_bytes(input: &str) -> Result<Vec<u8>, SyncLibError> {
|
|||
STANDARD.decode(input).map_err(SyncLibError::from)
|
||||
}
|
||||
|
||||
/// Merge two documents with a common parent. Relies on `reconcile::reconcile`
|
||||
/// for texts and returns the right document as-is if either of the updated
|
||||
/// documents is binary.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `parent`: The common parent document.
|
||||
/// - `left`: The left document updated by one user.
|
||||
/// - `right`: The right document updated by another user.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The merged document.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If any of the input documents are not valid UTF-8 strings.
|
||||
#[wasm_bindgen]
|
||||
#[must_use]
|
||||
pub fn merge(parent: &[u8], left: &[u8], right: &[u8]) -> Vec<u8> {
|
||||
set_panic_hook();
|
||||
|
||||
if is_binary(parent) || is_binary(left) || is_binary(right) {
|
||||
right.to_vec()
|
||||
} else {
|
||||
reconcile::reconcile(
|
||||
str::from_utf8(parent).expect("parent must be valid UTF-8 because it's not binary"),
|
||||
str::from_utf8(left).expect("left must be valid UTF-8 because it's not binary"),
|
||||
str::from_utf8(right).expect("right must be valid UTF-8 because it's not binary"),
|
||||
)
|
||||
.into_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
/// WASM wrapper around `reconcile::reconcile` for merging text.
|
||||
#[wasm_bindgen(js_name = mergeText)]
|
||||
#[must_use]
|
||||
pub fn merge_text(parent: &str, left: &str, right: &str) -> String {
|
||||
set_panic_hook();
|
||||
|
||||
reconcile::reconcile(parent, left, right)
|
||||
}
|
||||
|
||||
/// WASM wrapper around `reconcile::reconcile_with_cursors` for merging text.
|
||||
#[wasm_bindgen(js_name = mergeTextWithCursors)]
|
||||
#[must_use]
|
||||
pub fn merge_text_with_cursors(
|
||||
parent: &str,
|
||||
left: TextWithCursors,
|
||||
right: TextWithCursors,
|
||||
) -> TextWithCursors {
|
||||
set_panic_hook();
|
||||
|
||||
reconcile::reconcile_with_cursors(parent, left.into(), right.into()).into()
|
||||
}
|
||||
|
||||
/// Heuristically determine if the given data is a binary or a text file's
|
||||
/// content.
|
||||
#[wasm_bindgen(js_name = isBinary)]
|
||||
#[must_use]
|
||||
pub fn is_binary(data: &[u8]) -> bool {
|
||||
set_panic_hook();
|
||||
|
||||
if data.contains(&0) {
|
||||
// Even though the NUL character is valid in UTF-8, it's highly suspicious in
|
||||
// human-readable text.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::str::from_utf8(data).is_err()
|
||||
}
|
||||
|
||||
/// We don't want to support merging structured data like JSON, YAML, etc.
|
||||
#[wasm_bindgen(js_name = isFileTypeMergable)]
|
||||
#[must_use]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use insta::assert_debug_snapshot;
|
||||
use sync_lib::{
|
||||
cursor::{CursorPosition, TextWithCursors},
|
||||
*,
|
||||
};
|
||||
use sync_lib::*;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
|
|
@ -25,66 +22,6 @@ fn test_base64_to_bytes_error() {
|
|||
assert_debug_snapshot!(base64_to_bytes(input));
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_merge() {
|
||||
let left = b"hello ";
|
||||
let right = b"world";
|
||||
let result = merge(b"", left, right);
|
||||
assert_eq!(result, b"hello world");
|
||||
|
||||
let left = b"\0binary";
|
||||
let right = b"other";
|
||||
let result = merge(b"", left, right);
|
||||
assert_eq!(result, right);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_merge_text() {
|
||||
let left = "hello ";
|
||||
let right = "world";
|
||||
let result = merge_text("", left, right);
|
||||
assert_eq!(result, "hello world");
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_merge_text_with_cursors() {
|
||||
let result = merge_text_with_cursors(
|
||||
"hi",
|
||||
TextWithCursors::new("hi world".to_owned(), vec![]),
|
||||
TextWithCursors::new(
|
||||
"hi".to_owned(),
|
||||
vec![CursorPosition::new(0, 1), CursorPosition::new(1, 2)],
|
||||
),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
TextWithCursors::new(
|
||||
"hi world".to_owned(),
|
||||
vec![CursorPosition::new(0, 1), CursorPosition::new(1, 2)]
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn merge_binary() {
|
||||
let left = [0, 1, 2];
|
||||
let right = [3, 4, 5];
|
||||
assert_eq!(merge(b"", &left, &right), right);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_is_binary() {
|
||||
assert!(is_binary(&[0, 159, 146, 150]));
|
||||
assert!(is_binary(&[0, 12]));
|
||||
assert!(!is_binary(b"hello"));
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_is_binary_empty() {
|
||||
assert!(!is_binary(b""));
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(unsupported = test)]
|
||||
fn test_is_file_type_mergable() {
|
||||
assert!(is_file_type_mergable(".md"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue