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