y-octo 0.0.3

High-performance and thread-safe CRDT implementation compatible with Yjs
Documentation
use super::*;

pub fn encode_awareness_as_message(awareness: AwarenessStates) -> JwstCodecResult<Vec<u8>> {
    let mut buffer = Vec::new();
    write_sync_message(&mut buffer, &SyncMessage::Awareness(awareness))
        .map_err(|e| JwstCodecError::InvalidWriteBuffer(e.to_string()))?;

    Ok(buffer)
}

pub fn encode_update_as_message(update: Vec<u8>) -> JwstCodecResult<Vec<u8>> {
    let mut buffer = Vec::new();
    write_sync_message(&mut buffer, &SyncMessage::Doc(DocMessage::Update(update)))
        .map_err(|e| JwstCodecError::InvalidWriteBuffer(e.to_string()))?;

    Ok(buffer)
}

pub fn merge_updates_v1<V: AsRef<[u8]>, I: IntoIterator<Item = V>>(updates: I) -> JwstCodecResult<Update> {
    let updates = updates
        .into_iter()
        .map(Update::decode_v1)
        .collect::<JwstCodecResult<Vec<_>>>()?;

    Ok(Update::merge(updates))
}

/// It tends to generate small numbers.
/// Since the client id will be included in all crdt items, the
/// small client helps to reduce the binary size.
///
/// NOTE: The probability of 36% of the random number generated by
/// this function is greater than [u32::MAX]
pub fn prefer_small_random() -> u64 {
    use rand::{distr::Distribution, rng};
    use rand_distr::Exp;

    let scale_factor = u16::MAX as f64;
    let v: f64 = Exp::new(1.0 / scale_factor)
        .map(|exp| exp.sample(&mut rng()))
        .unwrap_or_else(|_| rand::random());

    (v * scale_factor) as u64
}