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