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 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}