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