1use std::{
2 any::Any,
3 marker::PhantomData,
4 ops::{Deref, DerefMut},
5 sync::Arc,
6};
7
8use futures_util::{TryFutureExt, future::ready};
9use object_rainbow::{
10 Address, ByteNode, Equivalent, ExtraFor, FailFuture, Fetch, FetchBytes, FullHash, Hash,
11 InlineOutput, ListHashes, MaybeHasNiche, Node, ObjectMarker, OptionalHash, Output, Parse,
12 ParseAsInline, ParseInline, PointInput, PointVisitor, Resolve, Singular, Size, Tagged, Tags,
13 ToOutput, Topological, Traversible,
14};
15
16#[cfg(feature = "serde")]
17mod point_deserialize;
18#[cfg(feature = "point-serialize")]
19mod point_serialize;
20
21#[derive(Clone, ParseAsInline)]
22struct Extras<Extra>(Extra);
23
24impl<Extra> Deref for Extras<Extra> {
25 type Target = Extra;
26
27 fn deref(&self) -> &Self::Target {
28 &self.0
29 }
30}
31
32impl<Extra> ToOutput for Extras<Extra> {
33 fn to_output(&self, _: &mut dyn Output) {}
34}
35
36impl<Extra> InlineOutput for Extras<Extra> {}
37
38impl<I: PointInput> ParseInline<I> for Extras<I::Extra> {
39 fn parse_inline(input: &mut I) -> object_rainbow::Result<Self> {
40 Ok(Self(input.extra().clone()))
41 }
42}
43
44impl<Extra> Tagged for Extras<Extra> {}
45impl<Extra> ListHashes for Extras<Extra> {}
46impl<Extra> Topological for Extras<Extra> {}
47
48#[derive(Clone)]
49struct ByAddressInner {
50 address: Address,
51 resolve: Arc<dyn Resolve>,
52}
53
54impl FetchBytes for ByAddressInner {
55 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
56 self.resolve.resolve(self.address)
57 }
58
59 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
60 self.resolve.resolve_data(self.address)
61 }
62
63 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
64 self.resolve.try_resolve_local(self.address)
65 }
66
67 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
68 Some(&self.resolve)
69 }
70
71 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
72 Arc::try_unwrap(self)
73 .ok()
74 .map(|Self { resolve, .. }| resolve)
75 }
76}
77
78impl Singular for ByAddressInner {
79 fn hash(&self) -> Hash {
80 self.address.hash
81 }
82}
83
84struct ByAddress<T, Extra> {
85 inner: ByAddressInner,
86 extra: Extra,
87 _object: PhantomData<fn() -> T>,
88}
89
90impl<T, Extra> ByAddress<T, Extra> {
91 fn from_inner(inner: ByAddressInner, extra: Extra) -> Self {
92 Self {
93 inner,
94 extra,
95 _object: PhantomData,
96 }
97 }
98}
99
100impl<T, Extra> FetchBytes for ByAddress<T, Extra> {
101 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
102 self.inner.fetch_bytes()
103 }
104
105 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
106 self.inner.fetch_data()
107 }
108
109 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
110 self.inner.fetch_bytes_local()
111 }
112
113 fn as_inner(&self) -> Option<&dyn Any> {
114 Some(&self.inner)
115 }
116
117 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
118 self.inner.as_resolve()
119 }
120
121 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
122 Arc::try_unwrap(self).ok().map(
123 |Self {
124 inner: ByAddressInner { resolve, .. },
125 ..
126 }| resolve,
127 )
128 }
129}
130
131impl<T, Extra: Send + Sync> Singular for ByAddress<T, Extra> {
132 fn hash(&self) -> Hash {
133 self.inner.hash()
134 }
135}
136
137impl<T: FullHash, Extra: Send + Sync + ExtraFor<T>> Fetch for ByAddress<T, Extra> {
138 type T = T;
139
140 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
141 Box::pin(async {
142 let (data, resolve) = self.fetch_bytes().await?;
143 let object = self
144 .extra
145 .parse_checked(self.inner.address.hash, &data, &resolve)?;
146 Ok((object, resolve))
147 })
148 }
149
150 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
151 Box::pin(async {
152 let (data, resolve) = self.fetch_bytes().await?;
153 self.extra
154 .parse_checked(self.inner.address.hash, &data, &resolve)
155 })
156 }
157
158 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
159 let Some((data, resolve)) = self.fetch_bytes_local()? else {
160 return Ok(None);
161 };
162 let object = self
163 .extra
164 .parse_checked(self.inner.address.hash, &data, &resolve)?;
165 Ok(Some((object, resolve)))
166 }
167}
168
169trait FromInner {
170 type Inner: 'static + Clone;
171 type Extra: 'static + Clone;
172
173 fn from_inner(inner: Self::Inner, extra: Self::Extra) -> Self;
174}
175
176trait InnerCast: FetchBytes {
177 fn inner_cast<T: FromInner>(&self, extra: &T::Extra) -> Option<T> {
178 self.as_inner()?
179 .downcast_ref()
180 .cloned()
181 .map(|inner| T::from_inner(inner, extra.clone()))
182 }
183}
184
185impl<T: ?Sized + FetchBytes> InnerCast for T {}
186
187pub trait ExtractResolve: FetchBytes {
188 fn extract_resolve<R: Any>(&self) -> Option<(&Address, &R)> {
189 let ByAddressInner { address, resolve } =
190 self.as_inner()?.downcast_ref::<ByAddressInner>()?;
191 let resolve = resolve.as_ref().any_ref().downcast_ref::<R>()?;
192 Some((address, resolve))
193 }
194}
195
196impl<T: ?Sized + FetchBytes> ExtractResolve for T {}
197
198#[derive(Clone, ParseAsInline)]
199pub struct RawPointInner {
200 hash: Hash,
201 fetch: Arc<dyn Send + Sync + FetchBytes>,
202}
203
204impl RawPointInner {
205 pub fn cast<T, Extra: 'static + Clone>(self, extra: Extra) -> RawPoint<T, Extra> {
206 RawPoint::from_inner(self, extra)
207 }
208
209 pub fn from_address(address: Address, resolve: Arc<dyn Resolve>) -> Self {
210 Self {
211 hash: address.hash,
212 fetch: Arc::new(ByAddressInner { address, resolve }),
213 }
214 }
215
216 pub fn from_singular(singular: impl 'static + Singular) -> Self {
217 Self {
218 hash: singular.hash(),
219 fetch: Arc::new(singular),
220 }
221 }
222}
223
224impl ToOutput for RawPointInner {
225 fn to_output(&self, output: &mut dyn Output) {
226 self.hash.to_output(output);
227 }
228}
229
230impl InlineOutput for RawPointInner {}
231
232impl<I: PointInput> ParseInline<I> for RawPointInner {
233 fn parse_inline(input: &mut I) -> object_rainbow::Result<Self> {
234 Ok(Self::from_address(input.parse_inline()?, input.resolve()))
235 }
236}
237
238impl Tagged for RawPointInner {}
239
240impl Singular for RawPointInner {
241 fn hash(&self) -> Hash {
242 self.hash
243 }
244}
245
246impl ListHashes for RawPointInner {
247 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
248 f(self.hash)
249 }
250
251 fn point_count(&self) -> usize {
252 1
253 }
254}
255
256impl FetchBytes for RawPointInner {
257 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
258 self.fetch.fetch_bytes()
259 }
260
261 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
262 self.fetch.fetch_data()
263 }
264
265 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
266 self.fetch.fetch_bytes_local()
267 }
268
269 fn fetch_data_local(&self) -> Option<Vec<u8>> {
270 self.fetch.fetch_data_local()
271 }
272
273 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
274 self.fetch.as_resolve()
275 }
276
277 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
278 Arc::try_unwrap(self).ok()?.fetch.try_unwrap_resolve()
279 }
280}
281
282#[derive(ToOutput, InlineOutput, Tagged, Parse, ParseInline)]
283pub struct RawPoint<T, Extra = ()> {
284 inner: RawPointInner,
285 extra: Extras<Extra>,
286 object: ObjectMarker<T>,
287}
288
289impl<T, Extra> ListHashes for RawPoint<T, Extra> {
290 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
291 self.inner.list_hashes(f);
292 }
293
294 fn topology_hash(&self) -> Hash {
295 self.inner.topology_hash()
296 }
297
298 fn point_count(&self) -> usize {
299 self.inner.point_count()
300 }
301}
302
303impl<T, Extra: 'static + Clone> FromInner for RawPoint<T, Extra> {
304 type Inner = RawPointInner;
305 type Extra = Extra;
306
307 fn from_inner(inner: Self::Inner, extra: Self::Extra) -> Self {
308 RawPoint {
309 inner,
310 extra: Extras(extra),
311 object: Default::default(),
312 }
313 }
314}
315
316impl<T, Extra: Clone> Clone for RawPoint<T, Extra> {
317 fn clone(&self) -> Self {
318 Self {
319 inner: self.inner.clone(),
320 extra: self.extra.clone(),
321 object: Default::default(),
322 }
323 }
324}
325
326impl<T: 'static + Traversible, Extra: 'static + Send + Sync + Clone + ExtraFor<T>> Topological
327 for RawPoint<T, Extra>
328{
329 fn traverse(&self, visitor: &mut impl PointVisitor) {
330 visitor.visit(self);
331 }
332}
333
334impl<T, Extra: Send + Sync> Singular for RawPoint<T, Extra> {
335 fn hash(&self) -> Hash {
336 self.inner.hash()
337 }
338}
339
340impl<T, Extra: 'static + Clone> RawPoint<T, Extra> {
341 pub fn cast<U>(self) -> RawPoint<U, Extra> {
342 self.inner.cast(self.extra.0)
343 }
344}
345
346impl<T: 'static + FullHash, Extra: 'static + Send + Sync + ExtraFor<T>> RawPoint<T, Extra> {
347 pub fn into_point(self) -> Point<T> {
348 Point::from_fetch(self.inner.hash, Arc::new(self))
349 }
350}
351
352impl<T, Extra> FetchBytes for RawPoint<T, Extra> {
353 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
354 self.inner.fetch_bytes()
355 }
356
357 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
358 self.inner.fetch_data()
359 }
360
361 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
362 self.inner.fetch_bytes_local()
363 }
364
365 fn fetch_data_local(&self) -> Option<Vec<u8>> {
366 self.inner.fetch_data_local()
367 }
368
369 fn as_inner(&self) -> Option<&dyn Any> {
370 Some(&self.inner)
371 }
372
373 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
374 self.inner.as_resolve()
375 }
376
377 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
378 Arc::try_unwrap(self).ok()?.inner.fetch.try_unwrap_resolve()
379 }
380}
381
382impl<T: FullHash, Extra: Send + Sync + ExtraFor<T>> Fetch for RawPoint<T, Extra> {
383 type T = T;
384
385 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
386 Box::pin(async {
387 let (data, resolve) = self.inner.fetch.fetch_bytes().await?;
388 let object = self
389 .extra
390 .0
391 .parse_checked(self.inner.hash, &data, &resolve)?;
392 Ok((object, resolve))
393 })
394 }
395
396 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
397 Box::pin(async {
398 let (data, resolve) = self.inner.fetch.fetch_bytes().await?;
399 self.extra.0.parse_checked(self.inner.hash, &data, &resolve)
400 })
401 }
402
403 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
404 let Some((data, resolve)) = self.inner.fetch.fetch_bytes_local()? else {
405 return Ok(None);
406 };
407 let object = self
408 .extra
409 .0
410 .parse_checked(self.inner.hash, &data, &resolve)?;
411 Ok(Some((object, resolve)))
412 }
413}
414
415impl<T> Point<T> {
416 pub fn from_fetch(hash: Hash, fetch: Arc<dyn Fetch<T = T>>) -> Self {
417 Self {
418 hash: hash.into(),
419 fetch,
420 }
421 }
422
423 fn map_fetch<U>(
424 self,
425 f: impl FnOnce(Arc<dyn Fetch<T = T>>) -> Arc<dyn Fetch<T = U>>,
426 ) -> Point<U> {
427 Point {
428 hash: self.hash,
429 fetch: f(self.fetch),
430 }
431 }
432}
433
434impl<U: 'static + Equivalent<T>, T: 'static, Extra> Equivalent<RawPoint<T, Extra>>
435 for RawPoint<U, Extra>
436{
437 fn into_equivalent(self) -> RawPoint<T, Extra> {
438 RawPoint {
439 inner: self.inner,
440 extra: self.extra,
441 object: Default::default(),
442 }
443 }
444
445 fn from_equivalent(object: RawPoint<T, Extra>) -> Self {
446 Self {
447 inner: object.inner,
448 extra: object.extra,
449 object: Default::default(),
450 }
451 }
452}
453
454#[derive(ParseAsInline)]
455#[must_use]
456pub struct Point<T> {
457 hash: OptionalHash,
458 fetch: Arc<dyn Fetch<T = T>>,
459}
460
461impl<T> std::fmt::Debug for Point<T> {
462 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
463 #[derive(Debug)]
464 struct Arc;
465 f.debug_struct("Point")
466 .field("hash", &self.hash)
467 .field("fetch", &Arc)
468 .finish()
469 }
470}
471
472impl<T> Point<T> {
473 pub fn raw<Extra: 'static + Clone>(self, extra: Extra) -> RawPoint<T, Extra> {
474 {
475 if let Some(raw) = self.fetch.inner_cast(&extra) {
476 return raw;
477 }
478 }
479 RawPointInner {
480 hash: self.hash.unwrap(),
481 fetch: self.fetch,
482 }
483 .cast(extra)
484 }
485}
486
487impl<T> PartialOrd for Point<T> {
488 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
489 Some(self.cmp(other))
490 }
491}
492
493impl<T> Ord for Point<T> {
494 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
495 self.hash().cmp(&other.hash())
496 }
497}
498
499impl<T> Eq for Point<T> {}
500
501impl<T> PartialEq for Point<T> {
502 fn eq(&self, other: &Self) -> bool {
503 self.hash() == other.hash()
504 }
505}
506
507impl<T> Clone for Point<T> {
508 fn clone(&self) -> Self {
509 Self {
510 hash: self.hash,
511 fetch: self.fetch.clone(),
512 }
513 }
514}
515
516impl<T> Size for Point<T> {
517 const SIZE: usize = Hash::SIZE;
518 type Size = <Hash as Size>::Size;
519}
520
521impl<T: 'static + FullHash> Point<T>
522where
523 (): ExtraFor<T>,
524{
525 pub fn from_address(address: Address, resolve: Arc<dyn Resolve>) -> Self {
526 Self::from_address_extra(address, resolve, ())
527 }
528}
529
530impl<T: 'static + FullHash> Point<T> {
531 pub fn from_address_extra<Extra: 'static + Send + Sync + Clone + ExtraFor<T>>(
532 address: Address,
533 resolve: Arc<dyn Resolve>,
534 extra: Extra,
535 ) -> Self {
536 Self::from_fetch(
537 address.hash,
538 Arc::new(ByAddress::from_inner(
539 ByAddressInner { address, resolve },
540 extra,
541 )),
542 )
543 }
544
545 pub fn with_resolve<Extra: 'static + Send + Sync + Clone + ExtraFor<T>>(
546 &self,
547 resolve: Arc<dyn Resolve>,
548 extra: Extra,
549 ) -> Self {
550 Self::from_address_extra(Address::from_hash(self.hash()), resolve, extra)
551 }
552}
553
554impl<T> ListHashes for Point<T> {
555 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
556 f(self.hash());
557 }
558
559 fn point_count(&self) -> usize {
560 1
561 }
562}
563
564impl<T: Traversible> Topological for Point<T> {
565 fn traverse(&self, visitor: &mut impl PointVisitor) {
566 visitor.visit(self);
567 }
568}
569
570impl<T: 'static + FullHash, I: PointInput<Extra: Send + Sync + ExtraFor<T>>> ParseInline<I>
571 for Point<T>
572{
573 fn parse_inline(input: &mut I) -> object_rainbow::Result<Self> {
574 Ok(Self::from_address_extra(
575 input.parse_inline()?,
576 input.resolve(),
577 input.extra().clone(),
578 ))
579 }
580}
581
582impl<T: Tagged> Tagged for Point<T> {
583 const TAGS: Tags = T::TAGS;
584}
585
586impl<T> ToOutput for Point<T> {
587 fn to_output(&self, output: &mut dyn Output) {
588 self.hash().to_output(output);
589 }
590}
591
592impl<T> InlineOutput for Point<T> {}
593
594impl<T> FetchBytes for Point<T> {
595 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
596 self.fetch.fetch_bytes()
597 }
598
599 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
600 self.fetch.fetch_data()
601 }
602
603 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
604 self.fetch.fetch_bytes_local()
605 }
606
607 fn fetch_data_local(&self) -> Option<Vec<u8>> {
608 self.fetch.fetch_data_local()
609 }
610
611 fn as_inner(&self) -> Option<&dyn Any> {
612 self.fetch.as_inner()
613 }
614
615 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
616 self.fetch.as_resolve()
617 }
618
619 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
620 Arc::try_unwrap(self).ok()?.fetch.try_unwrap_resolve()
621 }
622}
623
624impl<T> Singular for Point<T> {
625 fn hash(&self) -> Hash {
626 self.hash.unwrap()
627 }
628}
629
630impl<T> Point<T> {
631 pub fn get(&self) -> Option<&T> {
632 self.fetch.get()
633 }
634
635 pub fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<T>>> {
636 self.fetch.try_fetch_local()
637 }
638
639 pub fn try_unwrap(self) -> Option<T> {
640 self.fetch.try_unwrap()
641 }
642}
643
644impl<T: Traversible + Clone> Point<T> {
645 pub fn from_object(object: T) -> Self {
646 Self::from_fetch(object.full_hash(), Arc::new(LocalFetch { object }))
647 }
648
649 fn yolo_mut(&mut self) -> bool {
650 self.fetch.get().is_some()
651 && Arc::get_mut(&mut self.fetch).is_some_and(|fetch| fetch.get_mut().is_some())
652 }
653
654 async fn prepare_yolo_fetch(&mut self) -> object_rainbow::Result<()> {
655 if !self.yolo_mut() {
656 let object = self.fetch.fetch().await?;
657 self.fetch = Arc::new(LocalFetch { object });
658 }
659 Ok(())
660 }
661
662 pub async fn fetch_mut(&'_ mut self) -> object_rainbow::Result<PointMut<'_, T>> {
663 self.prepare_yolo_fetch().await?;
664 let fetch = Arc::get_mut(&mut self.fetch).unwrap();
665 assert!(fetch.get_mut().is_some());
666 self.hash.clear();
667 Ok(PointMut {
668 hash: &mut self.hash,
669 fetch,
670 })
671 }
672
673 pub async fn fetch_ref(&mut self) -> object_rainbow::Result<&T> {
674 self.prepare_yolo_fetch().await?;
675 Ok(self.fetch.get().unwrap())
676 }
677}
678
679impl<T: FullHash> Fetch for Point<T> {
680 type T = T;
681
682 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
683 self.fetch.fetch_full()
684 }
685
686 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
687 self.fetch.fetch()
688 }
689
690 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
691 self.fetch.try_fetch_local()
692 }
693
694 fn fetch_local(&self) -> Option<Self::T> {
695 self.fetch.fetch_local()
696 }
697
698 fn get(&self) -> Option<&Self::T> {
699 self.fetch.get()
700 }
701
702 fn get_mut(&mut self) -> Option<&mut Self::T> {
703 self.hash.clear();
704 Arc::get_mut(&mut self.fetch)?.get_mut()
705 }
706
707 fn get_mut_finalize(&mut self) {
708 let fetch = Arc::get_mut(&mut self.fetch).unwrap();
709 fetch.get_mut_finalize();
710 self.hash = fetch.get().unwrap().full_hash().into();
711 }
712
713 fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
714 Arc::try_unwrap(self).ok()?.fetch.try_unwrap()
715 }
716}
717
718impl<U: 'static + Equivalent<T>, T: 'static> Equivalent<Point<T>> for Point<U> {
721 fn into_equivalent(self) -> Point<T> {
722 self.map_fetch(|fetch| {
723 Arc::new(MapEquivalent {
724 fetch,
725 map: U::into_equivalent,
726 })
727 })
728 }
729
730 fn from_equivalent(point: Point<T>) -> Self {
731 point.map_fetch(|fetch| {
732 Arc::new(MapEquivalent {
733 fetch,
734 map: U::from_equivalent,
735 })
736 })
737 }
738}
739
740impl<T> MaybeHasNiche for Point<T> {
741 type MnArray = <Hash as MaybeHasNiche>::MnArray;
742}
743
744impl<T: FullHash + Default> Point<T> {
745 pub fn is_default(&self) -> bool {
746 self.hash() == T::default().full_hash()
747 }
748}
749
750impl<T: Default + Traversible + Clone> Default for Point<T> {
751 fn default() -> Self {
752 T::default().point()
753 }
754}
755
756pub trait IntoPoint: Traversible {
757 fn point(self) -> Point<Self>
758 where
759 Self: Clone,
760 {
761 Point::from_object(self)
762 }
763}
764
765impl<T: Traversible> IntoPoint for T {}
766
767struct LocalFetch<T> {
768 object: T,
769}
770
771impl<T: Traversible + Clone> Fetch for LocalFetch<T> {
772 type T = T;
773
774 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
775 Box::pin(ready(Ok((self.object.clone(), self.object.to_resolve()))))
776 }
777
778 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
779 Box::pin(ready(Ok(self.object.clone())))
780 }
781
782 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
783 Ok(Some((self.object.clone(), self.object.to_resolve())))
784 }
785
786 fn fetch_local(&self) -> Option<Self::T> {
787 Some(self.object.clone())
788 }
789
790 fn get(&self) -> Option<&Self::T> {
791 Some(&self.object)
792 }
793
794 fn get_mut(&mut self) -> Option<&mut Self::T> {
795 Some(&mut self.object)
796 }
797
798 fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
799 Arc::try_unwrap(self).ok().map(|Self { object }| object)
800 }
801}
802
803impl<T: Traversible + Clone> FetchBytes for LocalFetch<T> {
804 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
805 Box::pin(ready(Ok((self.object.output(), self.object.to_resolve()))))
806 }
807
808 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
809 Box::pin(ready(Ok(self.object.output())))
810 }
811
812 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
813 Ok(Some((self.object.output(), self.object.to_resolve())))
814 }
815
816 fn fetch_data_local(&self) -> Option<Vec<u8>> {
817 Some(self.object.output())
818 }
819}
820
821impl<T: Traversible + Clone> Singular for LocalFetch<T> {
822 fn hash(&self) -> Hash {
823 self.object.full_hash()
824 }
825}
826
827struct MapEquivalent<T, F> {
828 fetch: Arc<dyn Fetch<T = T>>,
829 map: F,
830}
831
832impl<T, F> FetchBytes for MapEquivalent<T, F> {
833 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
834 self.fetch.fetch_bytes()
835 }
836
837 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
838 self.fetch.fetch_data()
839 }
840
841 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
842 self.fetch.fetch_bytes_local()
843 }
844
845 fn fetch_data_local(&self) -> Option<Vec<u8>> {
846 self.fetch.fetch_data_local()
847 }
848
849 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
850 self.fetch.as_resolve()
851 }
852
853 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
854 Arc::try_unwrap(self).ok()?.fetch.try_unwrap_resolve()
855 }
856}
857
858trait Map1<T>: Fn(T) -> Self::U {
859 type U;
860}
861
862impl<T, U, F: Fn(T) -> U> Map1<T> for F {
863 type U = U;
864}
865
866impl<T, F: Send + Sync + Map1<T>> Fetch for MapEquivalent<T, F> {
867 type T = F::U;
868
869 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
870 Box::pin(self.fetch.fetch_full().map_ok(|(x, r)| ((self.map)(x), r)))
871 }
872
873 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
874 Box::pin(self.fetch.fetch().map_ok(&self.map))
875 }
876
877 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
878 let Some((object, resolve)) = self.fetch.try_fetch_local()? else {
879 return Ok(None);
880 };
881 let object = (self.map)(object);
882 Ok(Some((object, resolve)))
883 }
884
885 fn fetch_local(&self) -> Option<Self::T> {
886 self.fetch.fetch_local().map(&self.map)
887 }
888
889 fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
890 let Self { fetch, map } = Arc::try_unwrap(self).ok()?;
891 fetch.try_unwrap().map(map)
892 }
893}
894
895pub struct PointMut<'a, T: FullHash> {
896 hash: &'a mut OptionalHash,
897 fetch: &'a mut dyn Fetch<T = T>,
898}
899
900impl<T: FullHash> Deref for PointMut<'_, T> {
901 type Target = T;
902
903 fn deref(&self) -> &Self::Target {
904 self.fetch.get().unwrap()
905 }
906}
907
908impl<T: FullHash> DerefMut for PointMut<'_, T> {
909 fn deref_mut(&mut self) -> &mut Self::Target {
910 self.fetch.get_mut().unwrap()
911 }
912}
913
914impl<T: FullHash> Drop for PointMut<'_, T> {
915 fn drop(&mut self) {
916 self.finalize();
917 }
918}
919
920impl<'a, T: FullHash> PointMut<'a, T> {
921 fn finalize(&mut self) {
922 self.fetch.get_mut_finalize();
923 *self.hash = self.full_hash().into();
924 }
925}