Skip to main content

object_rainbow_point/
lib.rs

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