1use std::collections::HashMap;
2use yrs::error::{Error, UpdateError};
3use yrs::updates::decoder::Decode;
4use yrs::{
5 Doc, Out, ReadTxn, StateVector, Subscription, Transact, Transaction, TransactionAcqError,
6 TransactionCleanupEvent, TransactionMut, Update,
7};
8
9pub trait ForStore {
10 fn get_update(&self) -> Vec<u8>;
11 fn diff_state_update(&self, state: &Vec<u8>) -> Result<Vec<u8>, Error>;
12 fn apply_update(&self, txn: &mut TransactionMut, update: &Vec<u8>) -> Result<(), UpdateError>;
13 fn roots(&self, txn: &Transaction<'static>) -> HashMap<String, Out>;
14 fn observe<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
15 where
16 F: Fn(&TransactionMut, &TransactionCleanupEvent) + Send + Sync + 'static;
17}
18
19impl ForStore for Doc {
20 fn get_update(&self) -> Vec<u8> {
21 self.transact()
22 .encode_state_as_update_v1(&StateVector::default())
23 .into()
24 }
25
26 fn diff_state_update(&self, state: &Vec<u8>) -> Result<Vec<u8>, Error> {
27 let state_vector = StateVector::decode_v1(&state.as_ref())?;
28 let update = self.transact().encode_state_as_update_v1(&state_vector);
29 Ok(update.into())
30 }
31
32 fn apply_update(&self, txn: &mut TransactionMut, update: &Vec<u8>) -> Result<(), UpdateError> {
33 let u = Update::decode_v1(update.as_ref()).unwrap();
34 txn.apply_update(u)
35 }
36
37 fn roots(&self, txn: &Transaction<'static>) -> HashMap<String, Out> {
38 txn.root_refs()
39 .map(|(key_slice, value)| (key_slice.to_string(), value))
40 .collect::<HashMap<String, Out>>()
41 }
42
43 fn observe<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
44 where
45 F: Fn(&TransactionMut, &TransactionCleanupEvent) + Send + Sync + 'static,
46 {
47 self.observe_transaction_cleanup(move |txn, event| {
48 if !event.delete_set.is_empty() || event.before_state != event.after_state {
49 f(txn, event);
50 }
51 })
52 }
53}