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(ToOutput, InlineOutput, Tagged, ListHashes, Parse, ParseInline, Size, MaybeHasNiche)]
67pub struct Addressed<T, Extra> {
68    inner: AddressedBytes,
69    extra: Extras<Extra>,
70    _object: ObjectMarker<T>,
71}
72
73impl<T: Traversible, Extra: 'static + Send + Sync + Clone + ExtraFor<T>> Topological
74    for Addressed<T, Extra>
75{
76    fn traverse(&self, visitor: &mut impl PointVisitor) {
77        visitor.visit(self);
78    }
79}
80
81impl<T, Extra: Clone> Clone for Addressed<T, Extra> {
82    fn clone(&self) -> Self {
83        Self {
84            inner: self.inner.clone(),
85            extra: self.extra.clone(),
86            _object: Default::default(),
87        }
88    }
89}
90
91impl<T, Extra> Addressed<T, Extra> {
92    pub fn from_inner(inner: AddressedBytes, extra: Extra) -> Self {
93        Self {
94            inner,
95            extra: Extras(extra),
96            _object: Default::default(),
97        }
98    }
99}
100
101impl<T, Extra> FetchBytes for Addressed<T, Extra> {
102    fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
103        self.inner.fetch_bytes()
104    }
105
106    fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
107        self.inner.fetch_data()
108    }
109
110    fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
111        self.inner.fetch_bytes_local()
112    }
113
114    fn as_inner(&self) -> Option<&dyn Any> {
115        Some(&self.inner)
116    }
117
118    fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
119        self.inner.as_resolve()
120    }
121
122    fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
123        Arc::try_unwrap(self)
124            .ok()
125            .map(|Self { inner, .. }| inner.resolve)
126    }
127}
128
129impl<T, Extra: Send + Sync> Singular for Addressed<T, Extra> {
130    fn hash(&self) -> Hash {
131        self.inner.hash()
132    }
133}
134
135impl<T: FullHash, Extra: Send + Sync + ExtraFor<T>> Fetch for Addressed<T, Extra> {
136    type T = T;
137
138    fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
139        Box::pin(async {
140            let (data, resolve) = self.fetch_bytes().await?;
141            self.extra.parse_checked(self.inner.hash(), &data, &resolve)
142        })
143    }
144
145    fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
146        let Some((data, resolve)) = self.fetch_bytes_local()? else {
147            return Ok(None);
148        };
149        let object = self
150            .extra
151            .parse_checked(self.inner.hash(), &data, &resolve)?;
152        Ok(Some((object, resolve)))
153    }
154}