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 async fn echo(fetch: impl 'static + Fetch<T = T>) -> object_rainbow::Result<Self>
455 where
456 T: FullHash,
457 {
458 Ok(Self::from_alternate_source(&fetch.fetch().await?, fetch))
459 }
460
461 pub fn from_alternate_source(object: &T, fetch: impl 'static + Fetch<T = T>) -> Self
462 where
463 T: FullHash,
464 {
465 Self::from_fetch(object.full_hash(), fetch)
466 }
467
468 fn from_trusted_fetch(hash: Hash, fetch: Arc<dyn Fetch<T = T>>) -> Self {
469 Self {
470 hash: hash.into(),
471 fetch,
472 }
473 }
474
475 pub fn from_fetch(hash: Hash, fetch: impl 'static + Fetch<T = T>) -> Self {
476 Self::from_trusted_fetch(hash, fetch.into_dyn_fetch())
477 }
478
479 pub fn from_singular(singular: impl 'static + SingularFetch<T = T>) -> Self {
480 Self::from_fetch(singular.hash(), singular)
481 }
482
483 fn map_fetch<U>(
484 self,
485 f: impl FnOnce(Arc<dyn Fetch<T = T>>) -> Arc<dyn Fetch<T = U>>,
486 ) -> Point<U> {
487 Point {
488 hash: self.hash,
489 fetch: f(self.fetch),
490 }
491 }
492}
493
494impl<U: 'static + Equivalent<T>, T: 'static, Extra> Equivalent<RawPoint<T, Extra>>
495 for RawPoint<U, Extra>
496{
497 fn into_equivalent(self) -> RawPoint<T, Extra> {
498 RawPoint {
499 inner: self.inner,
500 extra: self.extra,
501 object: Default::default(),
502 }
503 }
504
505 fn from_equivalent(object: RawPoint<T, Extra>) -> Self {
506 Self {
507 inner: object.inner,
508 extra: object.extra,
509 object: Default::default(),
510 }
511 }
512}
513
514#[derive(ParseAsInline, Tagged)]
515#[must_use]
516pub struct Point<T> {
517 hash: OptionalHash,
518 fetch: Arc<dyn Fetch<T = T>>,
519}
520
521impl<T> std::hash::Hash for Point<T> {
522 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
523 self.hash.hash(state);
524 }
525}
526
527impl<T> std::fmt::Debug for Point<T> {
528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
529 #[derive(Debug)]
530 struct Arc;
531 f.debug_struct("Point")
532 .field("hash", &self.hash)
533 .field("fetch", &Arc)
534 .finish()
535 }
536}
537
538impl<T> Point<T> {
539 pub fn raw<Extra: 'static + Clone>(self, extra: Extra) -> RawPoint<T, Extra> {
540 {
541 if let Some(raw) = self.fetch.inner_cast(&extra) {
542 return raw;
543 }
544 }
545 RawPointInner {
546 hash: self.hash(),
547 fetch: self.fetch,
548 }
549 .cast(extra)
550 }
551}
552
553impl<T> PartialOrd for Point<T> {
554 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
555 Some(self.cmp(other))
556 }
557}
558
559impl<T> Ord for Point<T> {
560 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
561 self.hash().cmp(&other.hash())
562 }
563}
564
565impl<T> Eq for Point<T> {}
566
567impl<T> PartialEq for Point<T> {
568 fn eq(&self, other: &Self) -> bool {
569 self.hash() == other.hash()
570 }
571}
572
573impl<T> Clone for Point<T> {
574 fn clone(&self) -> Self {
575 Self {
576 hash: self.hash,
577 fetch: self.fetch.clone(),
578 }
579 }
580}
581
582impl<T> Size for Point<T> {
583 const SIZE: usize = Hash::SIZE;
584 type Size = <Hash as Size>::Size;
585}
586
587impl<T: 'static + FullHash> Point<T>
588where
589 (): ExtraFor<T>,
590{
591 pub fn from_address(address: Address, resolve: Arc<dyn Resolve>) -> Self {
592 Self::from_address_extra(address, resolve, ())
593 }
594}
595
596impl<T: 'static + FullHash> Point<T> {
597 pub fn from_address_extra<Extra: 'static + Send + Sync + Clone + ExtraFor<T>>(
598 address: Address,
599 resolve: Arc<dyn Resolve>,
600 extra: Extra,
601 ) -> Self {
602 Self::from_trusted_fetch(
603 address.hash,
604 ByAddress::from_inner(ByAddressInner { address, resolve }, extra).into_dyn_fetch(),
605 )
606 }
607
608 pub fn with_resolve<Extra: 'static + Send + Sync + Clone + ExtraFor<T>>(
609 &self,
610 resolve: Arc<dyn Resolve>,
611 extra: Extra,
612 ) -> Self {
613 Self::from_address_extra(Address::from_hash(self.hash()), resolve, extra)
614 }
615
616 pub fn from_fetch_extra<Extra: 'static + Send + Sync + Clone + ExtraFor<T>>(
617 address: Address,
618 resolve: Arc<dyn Resolve>,
619 fetch: impl 'static + Fetch<T = Extra>,
620 ) -> Self
621 where
622 T: Send,
623 {
624 Self::from_trusted_fetch(
625 address.hash,
626 FetchExtra::from_inner(ByAddressInner { address, resolve }, fetch).into_dyn_fetch(),
627 )
628 }
629}
630
631impl<T> ListHashes for Point<T> {
632 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
633 f(self.hash());
634 }
635
636 fn point_count(&self) -> usize {
637 1
638 }
639}
640
641impl<T: Traversible> Topological for Point<T> {
642 fn traverse(&self, visitor: &mut impl PointVisitor) {
643 visitor.visit(self);
644 }
645}
646
647impl<T: 'static + FullHash, I: PointInput<Extra: Send + Sync + ExtraFor<T>>> ParseInline<I>
648 for Point<T>
649{
650 fn parse_inline(input: &mut I) -> object_rainbow::Result<Self> {
651 Ok(Self::from_address_extra(
652 input.parse_inline()?,
653 input.resolve(),
654 input.extra().clone(),
655 ))
656 }
657}
658
659impl<T> ToOutput for Point<T> {
660 fn to_output(&self, output: &mut impl Output) {
661 self.hash().to_output(output);
662 }
663}
664
665impl<T> InlineOutput for Point<T> {}
666
667impl<T> FetchBytes for Point<T> {
668 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
669 self.fetch.fetch_bytes()
670 }
671
672 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
673 self.fetch.fetch_data()
674 }
675
676 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
677 self.fetch.fetch_bytes_local()
678 }
679
680 fn fetch_data_local(&self) -> Option<Vec<u8>> {
681 self.fetch.fetch_data_local()
682 }
683
684 fn as_inner(&self) -> Option<&dyn Any> {
685 self.fetch.as_inner()
686 }
687
688 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
689 self.fetch.as_resolve()
690 }
691
692 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
693 Arc::try_unwrap(self).ok()?.fetch.try_unwrap_resolve()
694 }
695}
696
697impl<T> Singular for Point<T> {
698 fn hash(&self) -> Hash {
699 self.hash.unwrap()
700 }
701}
702
703impl<T> Point<T> {
704 pub fn get(&self) -> Option<&T> {
705 self.fetch.get()
706 }
707
708 pub fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<T>>> {
709 self.fetch.try_fetch_local()
710 }
711
712 pub fn try_unwrap(self) -> Option<T> {
713 self.fetch.try_unwrap()
714 }
715
716 pub fn fetch(&self) -> FailFuture<'_, T> {
717 self.fetch.fetch()
718 }
719}
720
721impl<T: Traversible + Clone> Point<T> {
722 pub fn from_object(object: T) -> Self {
723 Self::from_trusted_fetch(object.full_hash(), object.local_fetch())
724 }
725
726 fn yolo_mut(&mut self) -> bool {
727 self.fetch.get().is_some()
728 && Arc::get_mut(&mut self.fetch).is_some_and(|fetch| fetch.get_mut().is_some())
729 }
730
731 async fn prepare_yolo_fetch(&mut self) -> object_rainbow::Result<()> {
732 if !self.yolo_mut() {
733 let object = self.fetch.fetch().await?;
734 self.fetch = object.local_fetch();
735 }
736 Ok(())
737 }
738
739 pub async fn fetch_mut(&'_ mut self) -> object_rainbow::Result<PointMut<'_, T>> {
740 self.prepare_yolo_fetch().await?;
741 let fetch = Arc::get_mut(&mut self.fetch).expect("shared fetch?");
742 assert!(fetch.get_mut().is_some());
743 self.hash.clear();
744 Ok(PointMut {
745 hash: &mut self.hash,
746 fetch,
747 })
748 }
749
750 pub async fn fetch_ref(&mut self) -> object_rainbow::Result<&T> {
751 self.prepare_yolo_fetch().await?;
752 Ok(self.fetch.get().expect("non-local fetch"))
753 }
754
755 pub async fn fetch_take(&mut self) -> object_rainbow::Result<T>
756 where
757 T: Default,
758 {
759 Ok(std::mem::take(&mut *self.fetch_mut().await?))
760 }
761}
762
763impl<T: FullHash> Fetch for Point<T> {
764 type T = T;
765
766 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
767 self.fetch.fetch_full()
768 }
769
770 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
771 self.fetch.fetch()
772 }
773
774 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
775 self.fetch.try_fetch_local()
776 }
777
778 fn fetch_local(&self) -> Option<Self::T> {
779 self.fetch.fetch_local()
780 }
781
782 fn get(&self) -> Option<&Self::T> {
783 self.fetch.get()
784 }
785
786 fn get_mut(&mut self) -> Option<&mut Self::T> {
787 self.hash.clear();
788 Arc::get_mut(&mut self.fetch)?.get_mut()
789 }
790
791 fn get_mut_finalize(&mut self) {
792 let fetch = Arc::get_mut(&mut self.fetch).expect("shared fetch?");
793 fetch.get_mut_finalize();
794 self.hash = fetch.get().expect("non-local fetch").full_hash().into();
795 }
796
797 fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
798 Arc::try_unwrap(self).ok()?.fetch.try_unwrap()
799 }
800
801 fn into_dyn_fetch<'a>(self) -> Arc<dyn 'a + Fetch<T = Self::T>>
802 where
803 Self: 'a + Sized,
804 {
805 self.fetch
806 }
807}
808
809impl<U: 'static + Equivalent<T>, T: 'static> Equivalent<Point<T>> for Point<U> {
812 fn into_equivalent(self) -> Point<T> {
813 self.map_fetch(|fetch| {
814 MapEquivalent {
815 fetch,
816 map: U::into_equivalent,
817 }
818 .into_dyn_fetch()
819 })
820 }
821
822 fn from_equivalent(point: Point<T>) -> Self {
823 point.map_fetch(|fetch| {
824 MapEquivalent {
825 fetch,
826 map: U::from_equivalent,
827 }
828 .into_dyn_fetch()
829 })
830 }
831}
832
833impl<T> MaybeHasNiche for Point<T> {
834 type MnArray = <Hash as MaybeHasNiche>::MnArray;
835}
836
837impl<T: DefaultHash> Point<T> {
838 pub fn is_default(&self) -> bool {
839 self.hash() == T::default_hash()
840 }
841}
842
843impl<T: Default + Traversible + Clone> Default for Point<T> {
844 fn default() -> Self {
845 T::default().point()
846 }
847}
848
849pub trait IntoPoint: Traversible {
850 fn point(self) -> Point<Self>
851 where
852 Self: Clone,
853 {
854 Point::from_object(self)
855 }
856}
857
858impl<T: Traversible> IntoPoint for T {}
859
860struct MapEquivalent<T, F> {
861 fetch: Arc<dyn Fetch<T = T>>,
862 map: F,
863}
864
865impl<T, F> FetchBytes for MapEquivalent<T, F> {
866 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
867 self.fetch.fetch_bytes()
868 }
869
870 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
871 self.fetch.fetch_data()
872 }
873
874 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
875 self.fetch.fetch_bytes_local()
876 }
877
878 fn fetch_data_local(&self) -> Option<Vec<u8>> {
879 self.fetch.fetch_data_local()
880 }
881
882 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
883 self.fetch.as_resolve()
884 }
885
886 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
887 Arc::try_unwrap(self).ok()?.fetch.try_unwrap_resolve()
888 }
889}
890
891trait Map1<T>: Fn(T) -> Self::U {
892 type U;
893}
894
895impl<T, U, F: Fn(T) -> U> Map1<T> for F {
896 type U = U;
897}
898
899impl<T, F: Send + Sync + Map1<T>> Fetch for MapEquivalent<T, F> {
900 type T = F::U;
901
902 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
903 Box::pin(self.fetch.fetch_full().map_ok(|(x, r)| ((self.map)(x), r)))
904 }
905
906 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
907 Box::pin(self.fetch.fetch().map_ok(&self.map))
908 }
909
910 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
911 let Some((object, resolve)) = self.fetch.try_fetch_local()? else {
912 return Ok(None);
913 };
914 let object = (self.map)(object);
915 Ok(Some((object, resolve)))
916 }
917
918 fn fetch_local(&self) -> Option<Self::T> {
919 self.fetch.fetch_local().map(&self.map)
920 }
921
922 fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
923 let Self { fetch, map } = Arc::try_unwrap(self).ok()?;
924 fetch.try_unwrap().map(map)
925 }
926}
927
928pub struct PointMut<'a, T: FullHash> {
929 hash: &'a mut OptionalHash,
930 fetch: &'a mut dyn Fetch<T = T>,
931}
932
933impl<T: FullHash> Deref for PointMut<'_, T> {
934 type Target = T;
935
936 fn deref(&self) -> &Self::Target {
937 self.fetch.get().expect("non-local fetch")
938 }
939}
940
941impl<T: FullHash> DerefMut for PointMut<'_, T> {
942 fn deref_mut(&mut self) -> &mut Self::Target {
943 self.fetch.get_mut().expect("non-local fetch")
944 }
945}
946
947impl<T: FullHash> Drop for PointMut<'_, T> {
948 fn drop(&mut self) {
949 if !std::thread::panicking() {
950 self.finalize();
951 }
952 }
953}
954
955impl<'a, T: FullHash> PointMut<'a, T> {
956 fn finalize(&mut self) {
957 self.fetch.get_mut_finalize();
958 *self.hash = self.full_hash().into();
959 }
960}
961
962#[derive(ToOutput, InlineOutput, ListHashes, Topological, Tagged, Parse, ParseInline)]
963pub struct ExtraPoint<T, Extra = ()> {
964 pub extra: Extras<Extra>,
965 pub point: Point<T>,
966}
967
968impl<T, Extra: std::fmt::Debug> std::fmt::Debug for ExtraPoint<T, Extra> {
969 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
970 f.debug_struct("ExtraPoint")
971 .field("extra", &self.extra)
972 .field("point", &self.point)
973 .finish()
974 }
975}
976
977impl<T, Extra: Clone> Clone for ExtraPoint<T, Extra> {
978 fn clone(&self) -> Self {
979 Self {
980 extra: self.extra.clone(),
981 point: self.point.clone(),
982 }
983 }
984}
985
986impl<T, Extra: PartialEq> PartialEq for ExtraPoint<T, Extra> {
987 fn eq(&self, other: &Self) -> bool {
988 self.extra == other.extra && self.point == other.point
989 }
990}
991
992impl<T, Extra: Clone> CanonicalExtra for ExtraPoint<T, Extra> {
993 type Extra = Extra;
994
995 fn canonical_extra(&self) -> Self::Extra {
996 self.extra.canonical_extra()
997 }
998}
999
1000impl<T, E> FetchBytes for ExtraPoint<T, E> {
1001 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
1002 self.point.fetch_bytes()
1003 }
1004
1005 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
1006 self.point.fetch_data()
1007 }
1008}
1009
1010impl<T: FullHash, E: Send + Sync> Fetch for ExtraPoint<T, E> {
1011 type T = T;
1012
1013 fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>> {
1014 self.point.fetch_full()
1015 }
1016
1017 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
1018 self.point.fetch()
1019 }
1020}
1021
1022impl<T: 'static + Send + FullHash, E: 'static + Send + Sync + Clone + ExtraFor<T>> ParseFetch<E>
1023 for Point<T>
1024{
1025 fn parse_fetch<I: PointInput<Extra: Fetch<T = E>>>(input: I) -> object_rainbow::Result<Self> {
1026 Self::parse_fetch_as_inline(input)
1027 }
1028}
1029
1030impl<T: 'static + Send + FullHash, E: 'static + Send + Sync + Clone + ExtraFor<T>>
1031 ParseFetchInline<E> for Point<T>
1032{
1033 fn parse_fetch_inline<I: PointInput<Extra: Fetch<T = E>>>(
1034 input: &mut I,
1035 ) -> object_rainbow::Result<Self> {
1036 Ok(Self::from_fetch_extra(
1037 input.parse_inline()?,
1038 input.resolve(),
1039 input.extra().clone(),
1040 ))
1041 }
1042}