Fix up is binary & sync_lib docs & tests
This commit is contained in:
parent
825d398dec
commit
44cb7a5b7c
7 changed files with 80 additions and 42 deletions
|
|
@ -1,5 +1,3 @@
|
|||
use std::str::Utf8Error;
|
||||
|
||||
use base64::DecodeError;
|
||||
use thiserror::Error;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
|
@ -8,9 +6,6 @@ use wasm_bindgen::JsValue;
|
|||
pub enum SyncLibError {
|
||||
#[error("Base64 decoding error because of {}", .reason)]
|
||||
Base64DecodingError { reason: String },
|
||||
|
||||
#[error("Bytes cannot be decoded as UTF-8 string because of {}", .reason)]
|
||||
StringDecodingError { reason: String },
|
||||
}
|
||||
|
||||
impl From<DecodeError> for SyncLibError {
|
||||
|
|
@ -21,14 +16,6 @@ impl From<DecodeError> for SyncLibError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Utf8Error> for SyncLibError {
|
||||
fn from(e: Utf8Error) -> Self {
|
||||
SyncLibError::StringDecodingError {
|
||||
reason: e.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::string::FromUtf8Error> for SyncLibError {
|
||||
fn from(e: std::string::FromUtf8Error) -> Self {
|
||||
SyncLibError::Base64DecodingError {
|
||||
|
|
|
|||
|
|
@ -6,53 +6,57 @@ use wasm_bindgen::prelude::*;
|
|||
|
||||
pub mod errors;
|
||||
|
||||
/// Encode binary data for easy transport over HTTP. Inverse of
|
||||
/// `base64_to_bytes`.
|
||||
#[wasm_bindgen(js_name = bytesToBase64)]
|
||||
pub fn bytes_to_base64(input: &[u8]) -> String { STANDARD_NO_PAD.encode(input) }
|
||||
|
||||
#[wasm_bindgen(js_name = stringToBase64)]
|
||||
pub fn string_to_base64(input: &str) -> String { bytes_to_base64(input.as_bytes()) }
|
||||
|
||||
/// Inverse of `bytes_to_base64`.
|
||||
#[wasm_bindgen(js_name = base64ToBytes)]
|
||||
pub fn base64_to_bytes(input: &str) -> Result<Vec<u8>, SyncLibError> {
|
||||
STANDARD_NO_PAD.decode(input).map_err(SyncLibError::from)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = base64ToString)]
|
||||
pub fn base64_to_string(input: &str) -> Result<String, SyncLibError> {
|
||||
let bytes = base64_to_bytes(input)?;
|
||||
String::from_utf8(bytes).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.
|
||||
#[wasm_bindgen]
|
||||
pub fn merge(parent: &[u8], left: &[u8], right: &[u8]) -> Result<Vec<u8>, SyncLibError> {
|
||||
Ok(if is_binary(right) {
|
||||
pub fn merge(parent: &[u8], left: &[u8], right: &[u8]) -> Vec<u8> {
|
||||
if is_binary(parent) || is_binary(left) || is_binary(right) {
|
||||
right.to_vec()
|
||||
} else {
|
||||
reconcile::reconcile(
|
||||
str::from_utf8(parent).map_err(SyncLibError::from)?,
|
||||
str::from_utf8(left).map_err(SyncLibError::from)?,
|
||||
str::from_utf8(right).map_err(SyncLibError::from)?,
|
||||
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 text merging.
|
||||
#[wasm_bindgen(js_name = mergeText)]
|
||||
pub fn merge_text(parent: &str, left: &str, right: &str) -> String {
|
||||
reconcile::reconcile(parent, left, right)
|
||||
}
|
||||
|
||||
/// Heuristically determine if the given data is a binary or a text file's
|
||||
/// content.
|
||||
#[wasm_bindgen(js_name = isBinary)]
|
||||
pub fn is_binary(data: &[u8]) -> bool { std::str::from_utf8(data).is_ok() }
|
||||
pub fn is_binary(data: &[u8]) -> bool {
|
||||
if data.iter().any(|&b| b == 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()
|
||||
}
|
||||
|
||||
/// Set up panic hook for better error messages in the browser console.
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
#[wasm_bindgen(js_name = setPanicHook)]
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue