Skip to main content

object_rainbow/
addressed.rs

1use 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}