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