object-rainbow-apply 0.0.0-a.1

asynchronous map trait for object-rainbow-history
Documentation
use object_rainbow::{Component, Hash};
use object_rainbow_hamt::{HamtMap, HamtSet};

use crate::Apply;

impl<V: 'static + Send + Sync + Component> Apply<(Option<V>, Hash)> for HamtMap<V> {
    type Output = Option<(V, Hash)>;

    async fn apply(
        &mut self,
        (value, hash): (Option<V>, Hash),
    ) -> object_rainbow::Result<Self::Output> {
        if let Some(value) = value {
            self.insert_replace(hash, value).await
        } else {
            self.remove_entry(hash).await
        }
        .map(|o| o.map(|(k, v)| (v, k)))
    }
}

impl<V: 'static + Send + Sync + Component> Apply<(V, Hash)> for HamtMap<V> {
    type Output = Option<(V, Hash)>;

    async fn apply(&mut self, (value, hash): (V, Hash)) -> object_rainbow::Result<Self::Output> {
        self.insert_replace(hash, value)
            .await
            .map(|o| o.map(|(k, v)| (v, k)))
    }
}

impl Apply<(Option<()>, Hash)> for HamtSet {
    type Output = Option<Hash>;

    async fn apply(
        &mut self,
        (target, hash): (Option<()>, Hash),
    ) -> object_rainbow::Result<Self::Output> {
        if target.is_some() {
            self.replace(hash).await
        } else {
            self.take(hash).await
        }
    }
}

impl Apply<Hash> for HamtSet {
    type Output = Option<Hash>;

    async fn apply(&mut self, hash: Hash) -> object_rainbow::Result<Self::Output> {
        Ok((!self.insert(hash).await?).then_some(hash))
    }
}

impl Apply<((), Hash)> for HamtSet {
    type Output = Option<Hash>;

    async fn apply(&mut self, ((), hash): ((), Hash)) -> object_rainbow::Result<Self::Output> {
        self.apply(hash).await
    }
}