automerge/rust/automerge-wasm/src/sync.rs
Alex Good 0ab6a770d8 wasm: improve error messages
The error messages produced by various conversions in `automerge-wasm`
were quite uninformative - often consisting of just returning the
offending value with no description of the problem. The logic of these
error messages was often hard to trace due to the use of `JsValue` to
represent both error conditions and valid values - evidenced by most of
the public functions of `automerge-wasm` having return types of
`Result<JsValue, JsValue>`. Change these return types to mention
specific errors, thus enlisting the compilers help in ensuring that
specific error messages are emitted.
2022-12-02 14:42:55 +00:00

65 lines
1.9 KiB
Rust

use automerge as am;
use automerge::ChangeHash;
use js_sys::Uint8Array;
use std::collections::{BTreeSet, HashMap};
use std::convert::TryInto;
use wasm_bindgen::prelude::*;
use crate::interop::{self, to_js_err, AR, JS};
#[wasm_bindgen]
#[derive(Debug)]
pub struct SyncState(pub(crate) am::sync::State);
#[wasm_bindgen]
impl SyncState {
#[wasm_bindgen(getter, js_name = sharedHeads)]
pub fn shared_heads(&self) -> JsValue {
AR::from(self.0.shared_heads.as_slice()).into()
}
#[wasm_bindgen(getter, js_name = lastSentHeads)]
pub fn last_sent_heads(&self) -> JsValue {
AR::from(self.0.last_sent_heads.as_slice()).into()
}
#[wasm_bindgen(setter, js_name = lastSentHeads)]
pub fn set_last_sent_heads(
&mut self,
heads: JsValue,
) -> Result<(), interop::error::BadChangeHashes> {
let heads: Vec<ChangeHash> = JS(heads).try_into()?;
self.0.last_sent_heads = heads;
Ok(())
}
#[wasm_bindgen(setter, js_name = sentHashes)]
pub fn set_sent_hashes(&mut self, hashes: JsValue) -> Result<(), JsValue> {
let hashes_map: HashMap<ChangeHash, bool> =
serde_wasm_bindgen::from_value(hashes).map_err(to_js_err)?;
let hashes_set: BTreeSet<ChangeHash> = hashes_map.keys().cloned().collect();
self.0.sent_hashes = hashes_set;
Ok(())
}
#[allow(clippy::should_implement_trait)]
pub fn clone(&self) -> Self {
SyncState(self.0.clone())
}
pub(crate) fn decode(data: Uint8Array) -> Result<SyncState, DecodeSyncStateErr> {
let data = data.to_vec();
let s = am::sync::State::decode(&data)?;
Ok(SyncState(s))
}
}
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct DecodeSyncStateErr(#[from] automerge::sync::DecodeStateError);
impl From<DecodeSyncStateErr> for JsValue {
fn from(e: DecodeSyncStateErr) -> Self {
JsValue::from(e.to_string())
}
}