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