object_rainbow/
addressed.rs1use std::sync::Arc;
2
3use crate::{extras::Extras, object_marker::ObjectMarker, *};
4
5pub trait ExtractResolve: FetchBytes {
6 fn extract_resolve<R: Any>(&self) -> Option<(&Address, &R)> {
7 let AddressedBytes { address, resolve } =
8 self.as_inner()?.downcast_ref::<AddressedBytes>()?;
9 let resolve = resolve.as_ref().any_ref().downcast_ref::<R>()?;
10 Some((address, resolve))
11 }
12}
13
14impl<T: ?Sized + FetchBytes> ExtractResolve for T {}
15
16#[derive(
17 Clone, ToOutput, InlineOutput, Tagged, ListHashes, Parse, ParseInline, Size, MaybeHasNiche,
18)]
19pub struct AddressedBytes {
20 pub address: Address,
21 pub resolve: Arc<dyn Resolve>,
22}
23
24impl FetchBytes for AddressedBytes {
25 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
26 self.resolve.resolve(self.address, &self.resolve)
27 }
28
29 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
30 self.resolve.resolve_data(self.address)
31 }
32
33 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
34 self.resolve.try_resolve_local(self.address, &self.resolve)
35 }
36
37 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
38 Some(&self.resolve)
39 }
40
41 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
42 Arc::try_unwrap(self)
43 .ok()
44 .map(|Self { resolve, .. }| resolve)
45 }
46}
47
48impl Singular for AddressedBytes {
49 fn hash(&self) -> Hash {
50 self.address.hash
51 }
52}
53
54impl<I: PointInput> Parse<I> for Arc<dyn '_ + Singular> {
55 fn parse(input: I) -> crate::Result<Self> {
56 Self::parse_as_inline(input)
57 }
58}
59
60impl<I: PointInput> ParseInline<I> for Arc<dyn '_ + Singular> {
61 fn parse_inline(input: &mut I) -> crate::Result<Self> {
62 Ok(Arc::new(input.parse_inline::<AddressedBytes>()?))
63 }
64}
65
66#[derive(
67 ToOutput,
68 InlineOutput,
69 Tagged,
70 ListHashes,
71 Parse,
72 ParseInline,
73 Size,
74 MaybeHasNiche,
75 CanonicalExtra,
76 ToCanonicalExtra,
77)]
78pub struct Addressed<T, Extra> {
79 extra: Extras<Extra>,
80 inner: AddressedBytes,
81 _object: ObjectMarker<T>,
82}
83
84impl<T, Extra> AsRef<Extra> for Addressed<T, Extra> {
85 fn as_ref(&self) -> &Extra {
86 &self.extra
87 }
88}
89
90impl<T: Traversible, Extra: 'static + Send + Sync + Clone + ExtraFor<T>> Topological
91 for Addressed<T, Extra>
92{
93 fn traverse(&self, visitor: &mut (impl ?Sized + PointVisitor)) {
94 visitor.visit(self);
95 }
96}
97
98impl<T, Extra: Clone> Clone for Addressed<T, Extra> {
99 fn clone(&self) -> Self {
100 Self {
101 extra: self.extra.clone(),
102 inner: self.inner.clone(),
103 _object: Default::default(),
104 }
105 }
106}
107
108impl<T, Extra> Addressed<T, Extra> {
109 pub fn from_inner(inner: AddressedBytes, extra: Extra) -> Self {
110 Self {
111 extra: Extras(extra),
112 inner,
113 _object: Default::default(),
114 }
115 }
116}
117
118impl<T, Extra> FetchBytes for Addressed<T, Extra> {
119 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
120 self.inner.fetch_bytes()
121 }
122
123 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
124 self.inner.fetch_data()
125 }
126
127 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
128 self.inner.fetch_bytes_local()
129 }
130
131 fn as_inner(&self) -> Option<&dyn Any> {
132 Some(&self.inner)
133 }
134
135 fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
136 self.inner.as_resolve()
137 }
138
139 fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
140 Arc::try_unwrap(self)
141 .ok()
142 .map(|Self { inner, .. }| inner.resolve)
143 }
144}
145
146impl<T, Extra: Send + Sync> Singular for Addressed<T, Extra> {
147 fn hash(&self) -> Hash {
148 self.inner.hash()
149 }
150}
151
152impl<T: FullHash, Extra: Send + Sync + ExtraFor<T>> Fetch for Addressed<T, Extra> {
153 type T = T;
154
155 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
156 self.fetch_checked()
157 }
158
159 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Self::T>> {
160 self.try_fetch_local_checked()
161 }
162}
163
164impl<'a, T: 'a + FullHash, I: PointInput<Extra: Send + Sync + ExtraFor<T>>> Parse<I>
165 for Arc<dyn 'a + SingularFetch<T = T>>
166{
167 fn parse(input: I) -> crate::Result<Self> {
168 Self::parse_as_inline(input)
169 }
170}
171
172impl<'a, T: 'a + FullHash, I: PointInput<Extra: Send + Sync + ExtraFor<T>>> ParseInline<I>
173 for Arc<dyn 'a + SingularFetch<T = T>>
174{
175 fn parse_inline(input: &mut I) -> crate::Result<Self> {
176 Ok(Arc::new(input.parse_inline::<Addressed<_, _>>()?))
177 }
178}