Skip to main content

object_rainbow_history/
lib.rs

1#![forbid(unsafe_code)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
4
5use futures_util::TryStreamExt;
6use object_rainbow::{
7    Equivalent, Fetch, Inline, InlineOutput, ListHashes, MaybeHasNiche, Object, Parse, ParseInline,
8    Size, Tagged, ToOutput, Topological, Traversible, assert_impl, derive_for_wrapped,
9};
10use object_rainbow_chain_tree::ChainTree;
11use object_rainbow_point::Point;
12
13pub mod enforce_unique;
14#[cfg(feature = "hamt")]
15mod hamt;
16pub mod hashed;
17pub mod remap;
18pub mod skip;
19#[cfg(feature = "trie")]
20mod trie;
21#[cfg(feature = "unique-diffs")]
22pub mod unique_diffs;
23
24#[derive(
25    ToOutput, InlineOutput, Tagged, ListHashes, Topological, Parse, ParseInline, Size, MaybeHasNiche,
26)]
27pub struct History<T, D>(ChainTree<(T, D)>);
28
29assert_impl!(
30    impl<T, D, E> Inline<E> for History<T, D>
31    where
32        E: 'static + Send + Sync + Clone,
33        T: Inline<E>,
34        D: Object<E>,
35    {
36    }
37);
38
39impl<T, D> Clone for History<T, D> {
40    fn clone(&self) -> Self {
41        Self(self.0.clone())
42    }
43}
44
45impl<T, D> History<T, D> {
46    pub const ROOT: Self = Self(ChainTree::EMPTY);
47}
48
49impl<T, D> Default for History<T, D> {
50    fn default() -> Self {
51        Self(Default::default())
52    }
53}
54
55impl<T, D> History<T, D> {
56    pub const fn new() -> Self {
57        Self::ROOT
58    }
59}
60
61#[derive_for_wrapped]
62pub trait Apply<Diff: Send>: Send {
63    type Output: Send;
64    /// Must stay isomorphic under [`Equivalent`] conversions.
65    fn apply(
66        &mut self,
67        diff: Diff,
68    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>>;
69}
70
71impl<T: Clone + Traversible + InlineOutput + Default + Apply<D>, D: Clone + Traversible>
72    History<T, D>
73{
74    pub async fn commit(&mut self, diff: D) -> object_rainbow::Result<()> {
75        let mut tree = self.tree().await?;
76        let hash = tree.full_hash();
77        tree.apply(diff.clone()).await?;
78        if hash != tree.full_hash() {
79            self.0.push((tree, diff)).await?;
80        }
81        Ok(())
82    }
83
84    pub async fn check_forward(&self, other: &Self) -> object_rainbow::Result<()> {
85        other
86            .0
87            .diff(&self.0)
88            .and_then(async |node| {
89                let diff = node.value().1.clone();
90                let mut tree = node
91                    .prev()
92                    .last()
93                    .await?
94                    .map(|(tree, _)| tree)
95                    .unwrap_or_default();
96                let hash = tree.full_hash();
97                tree.apply(diff).await?;
98                let new_hash = tree.full_hash();
99                if new_hash == hash {
100                    Err(object_rainbow::error_consistency!("noop diff"))
101                } else if new_hash == node.value().0.full_hash() {
102                    Ok(())
103                } else {
104                    Err(object_rainbow::error_consistency!(
105                        "diff doesn't match the new tree",
106                    ))
107                }
108            })
109            .try_collect()
110            .await
111    }
112
113    pub async fn forward(&mut self, other: Self) -> object_rainbow::Result<()> {
114        self.check_forward(&other).await?;
115        self.forward(other).await
116    }
117
118    pub async fn tree(&self) -> object_rainbow::Result<T> {
119        Ok(self
120            .0
121            .last()
122            .await?
123            .map(|(tree, _)| tree)
124            .unwrap_or_default())
125    }
126
127    pub async fn rebase(&mut self, base: &Self) -> object_rainbow::Result<()> {
128        let mut base = base.clone();
129        base.rebase_other(self).await?;
130        *self = base;
131        Ok(())
132    }
133
134    pub async fn rebase_other(&mut self, other: &Self) -> object_rainbow::Result<()> {
135        let common_ancestor = self.0.common_ancestor(&[&other.0]).await?;
136        let diff = other
137            .0
138            .diff_backwards(&common_ancestor)
139            .map_ok(|node| node.value().1.clone())
140            .try_collect::<Vec<_>>()
141            .await?;
142        for diff in diff.into_iter().rev() {
143            self.commit(diff).await?;
144        }
145        Ok(())
146    }
147}
148
149#[derive(
150    Debug,
151    ToOutput,
152    InlineOutput,
153    Tagged,
154    ListHashes,
155    Topological,
156    Parse,
157    ParseInline,
158    Size,
159    MaybeHasNiche,
160    Clone,
161    Copy,
162    PartialEq,
163    Eq,
164    PartialOrd,
165    Ord,
166    Default,
167)]
168pub struct FromIter<T>(pub T);
169
170impl<T: Apply<D>, D: Send, I: Send + IntoIterator<Item = D, IntoIter: Send>> Apply<I>
171    for FromIter<T>
172{
173    type Output = Vec<T::Output>;
174
175    async fn apply(&mut self, diff: I) -> object_rainbow::Result<Self::Output> {
176        let mut output = Vec::new();
177        for diff in diff {
178            output.push(self.0.apply(diff).await?);
179        }
180        Ok(output)
181    }
182}
183
184#[derive(
185    Debug,
186    ToOutput,
187    InlineOutput,
188    Tagged,
189    ListHashes,
190    Topological,
191    Parse,
192    ParseInline,
193    Size,
194    MaybeHasNiche,
195    Clone,
196    Copy,
197    PartialEq,
198    Eq,
199    PartialOrd,
200    Ord,
201    Default,
202)]
203pub struct Points<T>(pub T);
204
205impl<T: Apply<D>, D: Send + Traversible> Apply<Point<D>> for Points<T> {
206    type Output = T::Output;
207
208    async fn apply(&mut self, diff: Point<D>) -> object_rainbow::Result<Self::Output> {
209        self.0.apply(diff.fetch().await?).await
210    }
211}
212
213#[derive(
214    Debug,
215    ToOutput,
216    InlineOutput,
217    Tagged,
218    ListHashes,
219    Topological,
220    Parse,
221    ParseInline,
222    Size,
223    MaybeHasNiche,
224    Clone,
225    Copy,
226    PartialEq,
227    Eq,
228    Default,
229)]
230pub struct DiscardHeader<T>(pub T);
231
232assert_impl!(
233    impl<T, E> Inline<E> for DiscardHeader<T>
234    where
235        T: Inline<E>,
236        E: 'static + Send + Sync + Clone,
237    {
238    }
239);
240
241impl<T: Apply<D>, D: Send, H: Send> Apply<(H, D)> for DiscardHeader<T> {
242    type Output = T::Output;
243
244    fn apply(
245        &mut self,
246        (_, diff): (H, D),
247    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
248        self.0.apply(diff)
249    }
250}
251
252impl<T> Equivalent<T> for DiscardHeader<T> {
253    fn into_equivalent(self) -> T {
254        self.0
255    }
256
257    fn from_equivalent(tree: T) -> Self {
258        Self(tree)
259    }
260}
261
262#[derive(
263    Debug,
264    ToOutput,
265    InlineOutput,
266    Tagged,
267    ListHashes,
268    Topological,
269    Parse,
270    ParseInline,
271    Size,
272    MaybeHasNiche,
273    Clone,
274    Copy,
275    PartialEq,
276    Eq,
277    Default,
278)]
279pub struct Sequential<First, Second> {
280    first: First,
281    second: Second,
282}
283
284impl<First, Second> Sequential<First, Second> {
285    pub fn first(&self) -> &First {
286        &self.first
287    }
288
289    pub fn second(&self) -> &Second {
290        &self.second
291    }
292}
293
294impl<Diff: Send, First: Apply<Diff>, Second: Apply<First::Output>> Apply<Diff>
295    for Sequential<First, Second>
296{
297    type Output = Second::Output;
298    fn apply(
299        &mut self,
300        diff: Diff,
301    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
302        async move { self.second.apply(self.first.apply(diff).await?).await }
303    }
304}
305
306#[derive(
307    Debug,
308    ToOutput,
309    InlineOutput,
310    Tagged,
311    ListHashes,
312    Topological,
313    Parse,
314    ParseInline,
315    Size,
316    MaybeHasNiche,
317    Clone,
318    Copy,
319    PartialEq,
320    Eq,
321    Default,
322)]
323pub struct Parallel<A, B> {
324    a: A,
325    b: B,
326}
327
328impl<A, B> Parallel<A, B> {
329    pub fn a(&self) -> &A {
330        &self.a
331    }
332
333    pub fn b(&self) -> &B {
334        &self.b
335    }
336}
337
338impl<Diff: Send + Clone, A: Apply<Diff>, B: Apply<Diff>> Apply<Diff> for Parallel<A, B> {
339    type Output = (A::Output, B::Output);
340
341    fn apply(
342        &mut self,
343        diff: Diff,
344    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
345        futures_util::future::try_join(self.a.apply(diff.clone()), self.b.apply(diff))
346    }
347}
348
349#[derive(
350    Debug,
351    ToOutput,
352    InlineOutput,
353    Tagged,
354    ListHashes,
355    Topological,
356    Parse,
357    ParseInline,
358    Size,
359    MaybeHasNiche,
360    Clone,
361    Copy,
362    PartialEq,
363    Eq,
364    Default,
365)]
366pub struct Discard;
367
368impl<D: Send> Apply<D> for Discard {
369    type Output = ();
370
371    fn apply(&mut self, _: D) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
372        futures_util::future::ready(Ok(()))
373    }
374}
375
376impl Apply<()> for () {
377    type Output = ();
378
379    fn apply(
380        &mut self,
381        (): (),
382    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
383        futures_util::future::ready(Ok(()))
384    }
385}
386
387impl<A: Apply<DiffA>, B: Apply<DiffB>, DiffA: Send, DiffB: Send> Apply<(DiffA, DiffB)> for (A, B) {
388    type Output = (A::Output, B::Output);
389
390    fn apply(
391        &mut self,
392        (a, b): (DiffA, DiffB),
393    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
394        futures_util::future::try_join(self.0.apply(a), self.1.apply(b))
395    }
396}
397
398impl<T: Clone + Traversible + Apply<D>, D: Send> Apply<D> for Point<T> {
399    type Output = T::Output;
400
401    async fn apply(&mut self, diff: D) -> object_rainbow::Result<Self::Output> {
402        self.fetch_mut().await?.apply(diff).await
403    }
404}
405
406#[derive(
407    Debug,
408    ToOutput,
409    InlineOutput,
410    Tagged,
411    ListHashes,
412    Topological,
413    Parse,
414    ParseInline,
415    Size,
416    MaybeHasNiche,
417    Clone,
418    Copy,
419    PartialEq,
420    Eq,
421    Default,
422)]
423pub struct Return;
424
425impl<D: Send> Apply<D> for Return {
426    type Output = D;
427
428    fn apply(
429        &mut self,
430        diff: D,
431    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
432        futures_util::future::ready(Ok(diff))
433    }
434}
435
436#[derive(
437    Debug,
438    ToOutput,
439    InlineOutput,
440    Tagged,
441    ListHashes,
442    Topological,
443    Parse,
444    ParseInline,
445    Size,
446    MaybeHasNiche,
447    Clone,
448    Copy,
449    PartialEq,
450    Eq,
451    Default,
452)]
453pub struct Swap;
454
455impl<A: Send, B: Send> Apply<(A, B)> for Swap {
456    type Output = (B, A);
457
458    fn apply(
459        &mut self,
460        (a, b): (A, B),
461    ) -> impl Send + Future<Output = object_rainbow::Result<Self::Output>> {
462        futures_util::future::ready(Ok((b, a)))
463    }
464}