Skip to main content

object_rainbow/
lib.rs

1#![forbid(unsafe_code)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
4
5extern crate self as object_rainbow;
6
7use std::{
8    any::{Any, TypeId},
9    borrow::Cow,
10    cell::Cell,
11    convert::Infallible,
12    future::ready,
13    marker::PhantomData,
14    ops::{Deref, DerefMut},
15    pin::Pin,
16    sync::Arc,
17};
18
19pub use anyhow::anyhow;
20use generic_array::{ArrayLength, GenericArray, functional::FunctionalSequence};
21pub use object_rainbow_derive::{
22    Enum, InlineOutput, ListHashes, MaybeHasNiche, Parse, ParseAsInline, ParseInline, Size, Tagged,
23    ToOutput, Topological,
24};
25use sha2::{Digest, Sha256};
26#[doc(hidden)]
27pub use typenum;
28use typenum::Unsigned;
29
30pub use self::enumkind::Enum;
31pub use self::error::{Error, Result};
32pub use self::hash::{Hash, OptionalHash};
33pub use self::niche::{
34    AutoEnumNiche, AutoNiche, HackNiche, MaybeHasNiche, Niche, NicheForUnsized, NoNiche, OneNiche,
35    SomeNiche, ZeroNiche, ZeroNoNiche,
36};
37#[doc(hidden)]
38pub use self::niche::{MaybeNiche, MnArray, NicheFoldOrArray, NicheOr};
39
40mod assert_impl;
41pub mod enumkind;
42mod error;
43mod hash;
44pub mod hashed;
45mod impls;
46pub mod length_prefixed;
47mod niche;
48pub mod numeric;
49mod sha2_const;
50pub mod zero_terminated;
51
52/// SHA-256 hash size in bytes.
53pub const HASH_SIZE: usize = sha2_const::Sha256::DIGEST_SIZE;
54
55/// Address within a [`PointInput`].
56///
57/// This was introduced:
58/// - to avoid using a [`Hash`]-only map
59/// - to differentiate between separate [`Hash`]es within a context
60#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, ParseAsInline)]
61pub struct Address {
62    /// Monotonically incremented index. This is not present at all in the actual format.
63    pub index: usize,
64    /// Only this part is part of the parsed/generated input.
65    pub hash: Hash,
66}
67
68impl Address {
69    /// Construct an address which is invalid within parsing context, but can be used in map-based
70    /// [`Resolve`]s.
71    pub fn from_hash(hash: Hash) -> Self {
72        Self {
73            index: usize::MAX,
74            hash,
75        }
76    }
77}
78
79impl<I: PointInput> ParseInline<I> for Address {
80    fn parse_inline(input: &mut I) -> crate::Result<Self> {
81        Ok(Self {
82            index: input.next_index(),
83            hash: input.parse_inline()?,
84        })
85    }
86}
87
88/// Fallible future type yielding either `T` or [`Error`].
89pub type FailFuture<'a, T> = Pin<Box<dyn 'a + Send + Future<Output = Result<T>>>>;
90
91pub type Node<T> = (T, Arc<dyn Resolve>);
92
93/// Returned by [`Resolve`] and [`FetchBytes`]. Represents traversal through the object graph.
94pub type ByteNode = Node<Vec<u8>>;
95
96/// Trait for contextually using [`Any`]. Can itself be implemented for non-`'static` and `?Sized`
97/// types, and is `dyn`-compatible.
98pub trait AsAny {
99    /// Get a shared RTTI reference.
100    fn any_ref(&self) -> &dyn Any
101    where
102        Self: 'static;
103    /// Get an exclusive RTTI reference.
104    fn any_mut(&mut self) -> &mut dyn Any
105    where
106        Self: 'static;
107    /// Get an RTTI [`Box`].
108    fn any_box(self: Box<Self>) -> Box<dyn Any>
109    where
110        Self: 'static;
111    /// Get an RTTI [`Arc`].
112    fn any_arc(self: Arc<Self>) -> Arc<dyn Any>
113    where
114        Self: 'static;
115    /// Get an RTTI [`Arc`] which is also [`Send`].
116    fn any_arc_sync(self: Arc<Self>) -> Arc<dyn Send + Sync + Any>
117    where
118        Self: 'static + Send + Sync;
119}
120
121impl<T> AsAny for T {
122    fn any_ref(&self) -> &dyn Any
123    where
124        Self: 'static,
125    {
126        self
127    }
128
129    fn any_mut(&mut self) -> &mut dyn Any
130    where
131        Self: 'static,
132    {
133        self
134    }
135
136    fn any_box(self: Box<Self>) -> Box<dyn Any>
137    where
138        Self: 'static,
139    {
140        self
141    }
142
143    fn any_arc(self: Arc<Self>) -> Arc<dyn Any>
144    where
145        Self: 'static,
146    {
147        self
148    }
149
150    fn any_arc_sync(self: Arc<Self>) -> Arc<dyn Send + Sync + Any>
151    where
152        Self: 'static + Send + Sync,
153    {
154        self
155    }
156}
157
158/// Something that can resolve [`Address`]es to [`ByteNode`]s.
159pub trait Resolve: Send + Sync + AsAny {
160    /// Resolve the address. For an [`Object`], this is what gets used as [`PointInput`].
161    fn resolve(&'_ self, address: Address) -> FailFuture<'_, ByteNode>;
162    fn resolve_data(&'_ self, address: Address) -> FailFuture<'_, Vec<u8>>;
163    fn try_resolve_local(&self, address: Address) -> Result<Option<ByteNode>> {
164        let _ = address;
165        Ok(None)
166    }
167    /// Get a dynamic extension for a specific [`Address`].
168    fn resolve_extension(&self, address: Address, typeid: TypeId) -> crate::Result<&dyn Any> {
169        let _ = address;
170        let _ = typeid;
171        Err(Error::UnknownExtension)
172    }
173    /// Get a dynamic extension.
174    fn extension(&self, typeid: TypeId) -> crate::Result<&dyn Any> {
175        let _ = typeid;
176        Err(Error::UnknownExtension)
177    }
178    fn topology_hash(&self) -> Option<Hash> {
179        None
180    }
181    fn into_topovec(self: Arc<Self>) -> Option<TopoVec> {
182        None
183    }
184}
185
186pub trait FetchBytes: AsAny {
187    fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode>;
188    fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>>;
189    fn fetch_bytes_local(&self) -> Result<Option<ByteNode>> {
190        Ok(None)
191    }
192    fn fetch_data_local(&self) -> Option<Vec<u8>> {
193        None
194    }
195    fn as_inner(&self) -> Option<&dyn Any> {
196        None
197    }
198    fn as_resolve(&self) -> Option<&Arc<dyn Resolve>> {
199        None
200    }
201    fn try_unwrap_resolve(self: Arc<Self>) -> Option<Arc<dyn Resolve>> {
202        None
203    }
204}
205
206pub trait Fetch: Send + Sync + FetchBytes {
207    type T;
208    fn fetch_full(&'_ self) -> FailFuture<'_, Node<Self::T>>;
209    fn fetch(&'_ self) -> FailFuture<'_, Self::T>;
210    fn try_fetch_local(&self) -> Result<Option<Node<Self::T>>> {
211        Ok(None)
212    }
213    fn fetch_local(&self) -> Option<Self::T> {
214        None
215    }
216    fn get(&self) -> Option<&Self::T> {
217        None
218    }
219    fn get_mut(&mut self) -> Option<&mut Self::T> {
220        None
221    }
222    fn get_mut_finalize(&mut self) {}
223    fn try_unwrap(self: Arc<Self>) -> Option<Self::T> {
224        None
225    }
226}
227
228#[derive(ToOutput, InlineOutput, ListHashes, Topological, Parse, ParseInline)]
229pub struct ObjectMarker<T: ?Sized> {
230    object: PhantomData<fn() -> T>,
231}
232
233impl<T: ?Sized> Clone for ObjectMarker<T> {
234    fn clone(&self) -> Self {
235        *self
236    }
237}
238
239impl<T: ?Sized> Copy for ObjectMarker<T> {}
240
241impl<T: ?Sized> Default for ObjectMarker<T> {
242    fn default() -> Self {
243        Self {
244            object: Default::default(),
245        }
246    }
247}
248
249impl<T: ?Sized + Tagged> Tagged for ObjectMarker<T> {}
250
251pub trait PointVisitor {
252    fn visit<T: Traversible>(&mut self, point: &(impl 'static + SingularFetch<T = T> + Clone));
253}
254
255pub struct ReflessInput<'d> {
256    data: Option<&'d [u8]>,
257}
258
259pub struct Input<'d, Extra: Clone = ()> {
260    refless: ReflessInput<'d>,
261    resolve: &'d Arc<dyn Resolve>,
262    index: &'d Cell<usize>,
263    extra: Cow<'d, Extra>,
264}
265
266impl<'a, Extra: Clone> Deref for Input<'a, Extra> {
267    type Target = ReflessInput<'a>;
268
269    fn deref(&self) -> &Self::Target {
270        &self.refless
271    }
272}
273
274impl<Extra: Clone> DerefMut for Input<'_, Extra> {
275    fn deref_mut(&mut self) -> &mut Self::Target {
276        &mut self.refless
277    }
278}
279
280impl<'a> ReflessInput<'a> {
281    fn data(&self) -> crate::Result<&'a [u8]> {
282        self.data.ok_or(Error::EndOfInput)
283    }
284
285    fn make_error<T>(&mut self, e: crate::Error) -> crate::Result<T> {
286        self.data = None;
287        Err(e)
288    }
289
290    fn end_of_input<T>(&mut self) -> crate::Result<T> {
291        self.make_error(Error::EndOfInput)
292    }
293}
294
295impl<'d> ParseInput for ReflessInput<'d> {
296    type Data = &'d [u8];
297
298    fn parse_chunk<'a, const N: usize>(&mut self) -> crate::Result<&'a [u8; N]>
299    where
300        Self: 'a,
301    {
302        match self.data()?.split_first_chunk() {
303            Some((chunk, data)) => {
304                self.data = Some(data);
305                Ok(chunk)
306            }
307            None => self.end_of_input(),
308        }
309    }
310
311    fn parse_n(&mut self, n: usize) -> crate::Result<Self::Data> {
312        match self.data()?.split_at_checked(n) {
313            Some((chunk, data)) => {
314                self.data = Some(data);
315                Ok(chunk)
316            }
317            None => self.end_of_input(),
318        }
319    }
320
321    fn parse_until_zero(&mut self) -> crate::Result<Self::Data> {
322        let data = self.data()?;
323        match data.iter().enumerate().find(|(_, x)| **x == 0) {
324            Some((at, _)) => {
325                let (chunk, data) = data.split_at(at);
326                self.data = Some(&data[1..]);
327                Ok(chunk)
328            }
329            None => self.end_of_input(),
330        }
331    }
332
333    fn reparse<T: Parse<Self>>(&mut self, data: Self::Data) -> crate::Result<T> {
334        let input = Self { data: Some(data) };
335        T::parse(input)
336    }
337
338    fn parse_all(self) -> crate::Result<Self::Data> {
339        self.data()
340    }
341
342    fn empty(self) -> crate::Result<()> {
343        if self.data()?.is_empty() {
344            Ok(())
345        } else {
346            Err(Error::ExtraInputLeft)
347        }
348    }
349
350    fn non_empty(self) -> crate::Result<Option<Self>> {
351        Ok(if self.data()?.is_empty() {
352            None
353        } else {
354            Some(self)
355        })
356    }
357}
358
359impl<'d, Extra: Clone> ParseInput for Input<'d, Extra> {
360    type Data = &'d [u8];
361
362    fn parse_chunk<'a, const N: usize>(&mut self) -> crate::Result<&'a [u8; N]>
363    where
364        Self: 'a,
365    {
366        (**self).parse_chunk()
367    }
368
369    fn parse_n(&mut self, n: usize) -> crate::Result<Self::Data> {
370        (**self).parse_n(n)
371    }
372
373    fn parse_until_zero(&mut self) -> crate::Result<Self::Data> {
374        (**self).parse_until_zero()
375    }
376
377    fn reparse<T: Parse<Self>>(&mut self, data: Self::Data) -> crate::Result<T> {
378        let input = Self {
379            refless: ReflessInput { data: Some(data) },
380            resolve: self.resolve,
381            index: self.index,
382            extra: self.extra.clone(),
383        };
384        T::parse(input)
385    }
386
387    fn parse_all(self) -> crate::Result<Self::Data> {
388        self.refless.parse_all()
389    }
390
391    fn empty(self) -> crate::Result<()> {
392        self.refless.empty()
393    }
394
395    fn non_empty(mut self) -> crate::Result<Option<Self>> {
396        self.refless = match self.refless.non_empty()? {
397            Some(refless) => refless,
398            None => return Ok(None),
399        };
400        Ok(Some(self))
401    }
402}
403
404impl<'d, Extra: 'static + Clone> PointInput for Input<'d, Extra> {
405    type Extra = Extra;
406    type WithExtra<E: 'static + Clone> = Input<'d, E>;
407
408    fn next_index(&mut self) -> usize {
409        let index = self.index.get();
410        self.index.set(index + 1);
411        index
412    }
413
414    fn resolve_arc_ref(&self) -> &Arc<dyn Resolve> {
415        self.resolve
416    }
417
418    fn extra(&self) -> &Self::Extra {
419        &self.extra
420    }
421
422    fn map_extra<E: 'static + Clone>(
423        self,
424        f: impl FnOnce(&Self::Extra) -> &E,
425    ) -> Self::WithExtra<E> {
426        let Self {
427            refless,
428            resolve,
429            index,
430            extra,
431        } = self;
432        Input {
433            refless,
434            resolve,
435            index,
436            extra: match extra {
437                Cow::Borrowed(extra) => Cow::Borrowed(f(extra)),
438                Cow::Owned(extra) => Cow::Owned(f(&extra).clone()),
439            },
440        }
441    }
442
443    fn replace_extra<E: 'static + Clone>(self, e: E) -> (Extra, Self::WithExtra<E>) {
444        let Self {
445            refless,
446            resolve,
447            index,
448            extra,
449        } = self;
450        (
451            extra.into_owned(),
452            Input {
453                refless,
454                resolve,
455                index,
456                extra: Cow::Owned(e),
457            },
458        )
459    }
460
461    fn with_extra<E: 'static + Clone>(self, extra: E) -> Self::WithExtra<E> {
462        let Self {
463            refless,
464            resolve,
465            index,
466            ..
467        } = self;
468        Input {
469            refless,
470            resolve,
471            index,
472            extra: Cow::Owned(extra),
473        }
474    }
475
476    fn parse_inline_extra<E: 'static + Clone, T: ParseInline<Self::WithExtra<E>>>(
477        &mut self,
478        extra: E,
479    ) -> crate::Result<T> {
480        let Self {
481            refless,
482            resolve,
483            index,
484            ..
485        } = self;
486        let data = refless.data.take();
487        let mut input = Input {
488            refless: ReflessInput { data },
489            resolve,
490            index,
491            extra: Cow::Owned(extra),
492        };
493        let value = input.parse_inline()?;
494        refless.data = input.refless.data.take();
495        Ok(value)
496    }
497}
498
499pub trait ToOutput {
500    fn to_output(&self, output: &mut dyn Output);
501
502    fn data_hash(&self) -> Hash {
503        let mut output = HashOutput::default();
504        self.to_output(&mut output);
505        output.hash()
506    }
507
508    fn output<T: Output + Default>(&self) -> T {
509        let mut output = T::default();
510        self.to_output(&mut output);
511        output
512    }
513
514    fn vec(&self) -> Vec<u8> {
515        self.output()
516    }
517}
518
519/// Marker trait indicating that [`ToOutput`] result cannot be extended.
520pub trait InlineOutput: ToOutput {
521    fn slice_to_output(slice: &[Self], output: &mut dyn Output)
522    where
523        Self: Sized,
524    {
525        slice.iter_to_output(output);
526    }
527}
528
529pub trait ListHashes {
530    fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
531        let _ = f;
532    }
533
534    fn topology_hash(&self) -> Hash {
535        let mut hasher = Sha256::new();
536        self.list_hashes(&mut |hash| hasher.update(hash));
537        Hash::from_sha256(hasher.finalize().into())
538    }
539
540    fn point_count(&self) -> usize {
541        let mut count = 0;
542        self.list_hashes(&mut |_| count += 1);
543        count
544    }
545}
546
547pub trait Topological: ListHashes {
548    fn traverse(&self, visitor: &mut impl PointVisitor) {
549        let _ = visitor;
550    }
551
552    fn topology(&self) -> TopoVec {
553        let mut topology = TopoVec::with_capacity(self.point_count());
554        self.traverse(&mut topology);
555        topology
556    }
557}
558
559pub trait Tagged {
560    const TAGS: Tags = Tags(&[], &[]);
561
562    const HASH: Hash =
563        const { Hash::from_sha256(Self::TAGS.const_hash(sha2_const::Sha256::new()).finalize()) };
564}
565
566pub trait ParseSlice: for<'a> Parse<Input<'a>> {
567    fn parse_slice(data: &[u8], resolve: &Arc<dyn Resolve>) -> crate::Result<Self> {
568        Self::parse_slice_extra(data, resolve, &())
569    }
570
571    fn reparse(&self) -> crate::Result<Self>
572    where
573        Self: Traversible,
574    {
575        self.reparse_extra(&())
576    }
577}
578
579impl<T: for<'a> Parse<Input<'a>>> ParseSlice for T {}
580
581pub trait ParseSliceExtra<Extra: Clone>: for<'a> Parse<Input<'a, Extra>> {
582    fn parse_slice_extra(
583        data: &[u8],
584        resolve: &Arc<dyn Resolve>,
585        extra: &Extra,
586    ) -> crate::Result<Self> {
587        let input = Input {
588            refless: ReflessInput { data: Some(data) },
589            resolve,
590            index: &Cell::new(0),
591            extra: Cow::Borrowed(extra),
592        };
593        let object = Self::parse(input)?;
594        Ok(object)
595    }
596
597    fn reparse_extra(&self, extra: &Extra) -> crate::Result<Self>
598    where
599        Self: Traversible,
600    {
601        Self::parse_slice_extra(&self.vec(), &self.to_resolve(), extra)
602    }
603}
604
605impl<T: for<'a> Parse<Input<'a, Extra>>, Extra: Clone> ParseSliceExtra<Extra> for T {}
606
607#[derive(ToOutput)]
608pub struct ObjectHashes {
609    pub tags: Hash,
610    pub topology: Hash,
611    pub data: Hash,
612}
613
614pub trait FullHash: ToOutput + ListHashes + Tagged {
615    fn hashes(&self) -> ObjectHashes {
616        ObjectHashes {
617            tags: Self::HASH,
618            topology: self.topology_hash(),
619            data: self.data_hash(),
620        }
621    }
622
623    fn full_hash(&self) -> Hash {
624        self.hashes().data_hash()
625    }
626}
627
628impl<T: ?Sized + ToOutput + ListHashes + Tagged> FullHash for T {}
629
630pub trait Traversible: 'static + Sized + Send + Sync + FullHash + Topological {
631    fn to_resolve(&self) -> Arc<dyn Resolve> {
632        let topology = self.topology();
633        let topology_hash = topology.data_hash();
634        for singular in &topology {
635            if let Some(resolve) = singular.as_resolve()
636                && resolve.topology_hash() == Some(topology_hash)
637            {
638                return resolve.clone();
639            }
640        }
641        Arc::new(ByTopology {
642            topology,
643            topology_hash,
644        })
645    }
646}
647
648impl<T: 'static + Send + Sync + FullHash + Topological> Traversible for T {}
649
650pub trait Object<Extra = ()>: Traversible + for<'a> Parse<Input<'a, Extra>> {}
651
652impl<T: Traversible + for<'a> Parse<Input<'a, Extra>>, Extra> Object<Extra> for T {}
653
654pub struct Tags(pub &'static [&'static str], pub &'static [&'static Self]);
655
656impl Tags {
657    const fn const_hash(&self, mut hasher: sha2_const::Sha256) -> sha2_const::Sha256 {
658        {
659            let mut i = 0;
660            while i < self.0.len() {
661                hasher = hasher.update(self.0[i].as_bytes());
662                i += 1;
663            }
664        }
665        {
666            let mut i = 0;
667            while i < self.1.len() {
668                hasher = self.1[i].const_hash(hasher);
669                i += 1;
670            }
671        }
672        hasher
673    }
674}
675
676pub trait Inline<Extra = ()>:
677    Object<Extra> + InlineOutput + for<'a> ParseInline<Input<'a, Extra>>
678{
679}
680
681impl<T: Object<Extra> + InlineOutput + for<'a> ParseInline<Input<'a, Extra>>, Extra> Inline<Extra>
682    for T
683{
684}
685
686pub trait Topology: Send + Sync {
687    fn len(&self) -> usize;
688    fn get(&self, index: usize) -> Option<&Arc<dyn Singular>>;
689
690    fn is_empty(&self) -> bool {
691        self.len() == 0
692    }
693}
694
695pub trait Singular: Send + Sync + FetchBytes {
696    fn hash(&self) -> Hash;
697}
698
699pub trait SingularFetch: Singular + Fetch {}
700
701impl<T: ?Sized + Singular + Fetch> SingularFetch for T {}
702
703impl ToOutput for dyn Singular {
704    fn to_output(&self, output: &mut dyn Output) {
705        self.hash().to_output(output);
706    }
707}
708
709impl InlineOutput for dyn Singular {}
710
711pub type TopoVec = Vec<Arc<dyn Singular>>;
712
713impl PointVisitor for TopoVec {
714    fn visit<T: Traversible>(&mut self, point: &(impl 'static + SingularFetch<T = T> + Clone)) {
715        self.push(Arc::new(point.clone()));
716    }
717}
718
719impl Topology for TopoVec {
720    fn len(&self) -> usize {
721        self.len()
722    }
723
724    fn get(&self, index: usize) -> Option<&Arc<dyn Singular>> {
725        (**self).get(index)
726    }
727}
728
729pub trait ParseSliceRefless: for<'a> Parse<ReflessInput<'a>> {
730    fn parse_slice_refless(data: &[u8]) -> crate::Result<Self> {
731        let input = ReflessInput { data: Some(data) };
732        let object = Self::parse(input)?;
733        Ok(object)
734    }
735}
736
737impl<T: for<'a> Parse<ReflessInput<'a>>> ParseSliceRefless for T {}
738
739pub trait ReflessObject:
740    'static + Sized + Send + Sync + ToOutput + Tagged + for<'a> Parse<ReflessInput<'a>>
741{
742}
743
744impl<T: 'static + Sized + Send + Sync + ToOutput + Tagged + for<'a> Parse<ReflessInput<'a>>>
745    ReflessObject for T
746{
747}
748
749pub trait ReflessInline:
750    ReflessObject + InlineOutput + for<'a> ParseInline<ReflessInput<'a>>
751{
752}
753
754impl<T: ReflessObject + InlineOutput + for<'a> ParseInline<ReflessInput<'a>>> ReflessInline for T {}
755
756pub trait Output {
757    fn write(&mut self, data: &[u8]);
758}
759
760impl Output for Vec<u8> {
761    fn write(&mut self, data: &[u8]) {
762        self.extend_from_slice(data);
763    }
764}
765
766#[derive(Default)]
767struct HashOutput {
768    hasher: Sha256,
769    at: usize,
770}
771
772impl Output for HashOutput {
773    fn write(&mut self, data: &[u8]) {
774        self.hasher.update(data);
775        self.at += data.len();
776    }
777}
778
779impl HashOutput {
780    fn hash(self) -> Hash {
781        Hash::from_sha256(self.hasher.finalize().into())
782    }
783}
784
785struct ByTopology {
786    topology: TopoVec,
787    topology_hash: Hash,
788}
789
790impl Drop for ByTopology {
791    fn drop(&mut self) {
792        while let Some(singular) = self.topology.pop() {
793            if let Some(resolve) = singular.try_unwrap_resolve()
794                && let Some(topology) = &mut resolve.into_topovec()
795            {
796                self.topology.append(topology);
797            }
798        }
799    }
800}
801
802impl ByTopology {
803    fn try_resolve(&'_ self, address: Address) -> Result<FailFuture<'_, ByteNode>> {
804        let point = self
805            .topology
806            .get(address.index)
807            .ok_or(Error::AddressOutOfBounds)?;
808        if point.hash() != address.hash {
809            Err(Error::ResolutionMismatch)
810        } else {
811            Ok(point.fetch_bytes())
812        }
813    }
814
815    fn try_resolve_data(&'_ self, address: Address) -> Result<FailFuture<'_, Vec<u8>>> {
816        let point = self
817            .topology
818            .get(address.index)
819            .ok_or(Error::AddressOutOfBounds)?;
820        if point.hash() != address.hash {
821            Err(Error::ResolutionMismatch)
822        } else {
823            Ok(point.fetch_data())
824        }
825    }
826}
827
828impl Resolve for ByTopology {
829    fn resolve(&'_ self, address: Address) -> FailFuture<'_, ByteNode> {
830        self.try_resolve(address)
831            .map_err(Err)
832            .map_err(ready)
833            .map_err(Box::pin)
834            .unwrap_or_else(|x| x)
835    }
836
837    fn resolve_data(&'_ self, address: Address) -> FailFuture<'_, Vec<u8>> {
838        self.try_resolve_data(address)
839            .map_err(Err)
840            .map_err(ready)
841            .map_err(Box::pin)
842            .unwrap_or_else(|x| x)
843    }
844
845    fn try_resolve_local(&self, address: Address) -> Result<Option<ByteNode>> {
846        let point = self
847            .topology
848            .get(address.index)
849            .ok_or(Error::AddressOutOfBounds)?;
850        if point.hash() != address.hash {
851            Err(Error::ResolutionMismatch)
852        } else {
853            point.fetch_bytes_local()
854        }
855    }
856
857    fn topology_hash(&self) -> Option<Hash> {
858        Some(self.topology_hash)
859    }
860
861    fn into_topovec(self: Arc<Self>) -> Option<TopoVec> {
862        Arc::try_unwrap(self)
863            .ok()
864            .as_mut()
865            .map(|Self { topology, .. }| std::mem::take(topology))
866    }
867}
868
869pub trait Size {
870    const SIZE: usize = <Self::Size as Unsigned>::USIZE;
871    type Size: Unsigned;
872}
873
874pub trait SizeExt: Size<Size: ArrayLength> + ToOutput {
875    fn to_array(&self) -> GenericArray<u8, Self::Size> {
876        let mut array = GenericArray::default();
877        let mut output = ArrayOutput {
878            data: &mut array,
879            offset: 0,
880        };
881        self.to_output(&mut output);
882        output.finalize();
883        array
884    }
885}
886
887impl<T: Size<Size: ArrayLength> + ToOutput> SizeExt for T {}
888
889struct ArrayOutput<'a> {
890    data: &'a mut [u8],
891    offset: usize,
892}
893
894impl ArrayOutput<'_> {
895    fn finalize(self) {
896        assert_eq!(self.offset, self.data.len());
897    }
898}
899
900impl Output for ArrayOutput<'_> {
901    fn write(&mut self, data: &[u8]) {
902        self.data[self.offset..][..data.len()].copy_from_slice(data);
903        self.offset += data.len();
904    }
905}
906
907pub trait RainbowIterator: Sized + IntoIterator {
908    fn iter_to_output(self, output: &mut dyn Output)
909    where
910        Self::Item: InlineOutput,
911    {
912        self.into_iter().for_each(|item| item.to_output(output));
913    }
914
915    fn iter_list_hashes(self, f: &mut impl FnMut(Hash))
916    where
917        Self::Item: ListHashes,
918    {
919        self.into_iter().for_each(|item| item.list_hashes(f));
920    }
921
922    fn iter_traverse(self, visitor: &mut impl PointVisitor)
923    where
924        Self::Item: Topological,
925    {
926        self.into_iter().for_each(|item| item.traverse(visitor));
927    }
928}
929
930pub trait ParseInput: Sized {
931    type Data: AsRef<[u8]> + Deref<Target = [u8]> + Into<Vec<u8>> + Copy;
932    fn parse_chunk<'a, const N: usize>(&mut self) -> crate::Result<&'a [u8; N]>
933    where
934        Self: 'a;
935    fn parse_n(&mut self, n: usize) -> crate::Result<Self::Data>;
936    fn parse_until_zero(&mut self) -> crate::Result<Self::Data>;
937    fn parse_n_compare(&mut self, n: usize, c: &[u8]) -> crate::Result<Option<Self::Data>> {
938        let data = self.parse_n(n)?;
939        if *data == *c {
940            Ok(None)
941        } else {
942            Ok(Some(data))
943        }
944    }
945    fn reparse<T: Parse<Self>>(&mut self, data: Self::Data) -> crate::Result<T>;
946    fn parse_ahead<T: Parse<Self>>(&mut self, n: usize) -> crate::Result<T> {
947        let data = self.parse_n(n)?;
948        self.reparse(data)
949    }
950    fn parse_zero_terminated<T: Parse<Self>>(&mut self) -> crate::Result<T> {
951        let data = self.parse_until_zero()?;
952        self.reparse(data)
953    }
954    fn parse_compare<T: Parse<Self>>(&mut self, n: usize, c: &[u8]) -> Result<Option<T>> {
955        self.parse_n_compare(n, c)?
956            .map(|data| self.reparse(data))
957            .transpose()
958    }
959    fn parse_all(self) -> crate::Result<Self::Data>;
960    fn empty(self) -> crate::Result<()>;
961    fn non_empty(self) -> crate::Result<Option<Self>>;
962
963    fn consume(self, f: impl FnMut(&mut Self) -> crate::Result<()>) -> crate::Result<()> {
964        self.collect(f)
965    }
966
967    fn parse_collect<T: ParseInline<Self>, B: FromIterator<T>>(self) -> crate::Result<B> {
968        self.collect(|input| input.parse_inline())
969    }
970
971    fn collect<T, B: FromIterator<T>>(
972        self,
973        f: impl FnMut(&mut Self) -> crate::Result<T>,
974    ) -> crate::Result<B> {
975        self.iter(f).collect()
976    }
977
978    fn iter<T>(
979        self,
980        mut f: impl FnMut(&mut Self) -> crate::Result<T>,
981    ) -> impl Iterator<Item = crate::Result<T>> {
982        let mut state = Some(self);
983        std::iter::from_fn(move || {
984            let mut input = match state.take()?.non_empty() {
985                Ok(input) => input?,
986                Err(e) => return Some(Err(e)),
987            };
988            let item = f(&mut input);
989            state = Some(input);
990            Some(item)
991        })
992    }
993
994    fn parse_inline<T: ParseInline<Self>>(&mut self) -> crate::Result<T> {
995        T::parse_inline(self)
996    }
997
998    fn parse<T: Parse<Self>>(self) -> crate::Result<T> {
999        T::parse(self)
1000    }
1001
1002    fn parse_vec<T: ParseInline<Self>>(self) -> crate::Result<Vec<T>> {
1003        T::parse_vec(self)
1004    }
1005
1006    fn parse_vec_n<T: ParseInline<Self>>(&mut self, n: usize) -> crate::Result<Vec<T>> {
1007        T::parse_vec_n(self, n)
1008    }
1009
1010    fn parse_array<T: ParseInline<Self>, const N: usize>(&mut self) -> crate::Result<[T; N]> {
1011        T::parse_array(self)
1012    }
1013
1014    fn parse_generic_array<T: ParseInline<Self>, N: ArrayLength>(
1015        &mut self,
1016    ) -> crate::Result<GenericArray<T, N>> {
1017        T::parse_generic_array(self)
1018    }
1019}
1020
1021pub trait PointInput: ParseInput {
1022    type Extra: 'static + Clone;
1023    type WithExtra<E: 'static + Clone>: PointInput<Extra = E, WithExtra<Self::Extra> = Self>;
1024    fn next_index(&mut self) -> usize;
1025    fn resolve_arc_ref(&self) -> &Arc<dyn Resolve>;
1026    fn resolve(&self) -> Arc<dyn Resolve> {
1027        self.resolve_arc_ref().clone()
1028    }
1029    fn resolve_ref(&self) -> &dyn Resolve {
1030        self.resolve_arc_ref().as_ref()
1031    }
1032    fn extension<T: Any>(&self) -> crate::Result<&T> {
1033        self.resolve_ref()
1034            .extension(TypeId::of::<T>())?
1035            .downcast_ref()
1036            .ok_or(Error::ExtensionType)
1037    }
1038    fn extra(&self) -> &Self::Extra;
1039    fn map_extra<E: 'static + Clone>(
1040        self,
1041        f: impl FnOnce(&Self::Extra) -> &E,
1042    ) -> Self::WithExtra<E>;
1043    fn replace_extra<E: 'static + Clone>(self, extra: E) -> (Self::Extra, Self::WithExtra<E>);
1044    fn with_extra<E: 'static + Clone>(self, extra: E) -> Self::WithExtra<E> {
1045        self.replace_extra(extra).1
1046    }
1047    fn parse_extra<E: 'static + Clone, T: Parse<Self::WithExtra<E>>>(
1048        self,
1049        extra: E,
1050    ) -> crate::Result<T> {
1051        self.with_extra(extra).parse()
1052    }
1053    fn parse_inline_extra<E: 'static + Clone, T: ParseInline<Self::WithExtra<E>>>(
1054        &mut self,
1055        extra: E,
1056    ) -> crate::Result<T>;
1057}
1058
1059impl<T: Sized + IntoIterator> RainbowIterator for T {}
1060
1061pub trait Parse<I: ParseInput>: Sized {
1062    fn parse(input: I) -> crate::Result<Self>;
1063}
1064
1065pub trait ParseInline<I: ParseInput>: Parse<I> {
1066    fn parse_inline(input: &mut I) -> crate::Result<Self>;
1067    fn parse_as_inline(mut input: I) -> crate::Result<Self> {
1068        let object = Self::parse_inline(&mut input)?;
1069        input.empty()?;
1070        Ok(object)
1071    }
1072    fn parse_vec(input: I) -> crate::Result<Vec<Self>> {
1073        input.parse_collect()
1074    }
1075    fn parse_vec_n(input: &mut I, n: usize) -> crate::Result<Vec<Self>> {
1076        (0..n).map(|_| input.parse_inline()).collect()
1077    }
1078    fn parse_array<const N: usize>(input: &mut I) -> crate::Result<[Self; N]> {
1079        let mut scratch = std::array::from_fn(|_| None);
1080        for item in scratch.iter_mut() {
1081            *item = Some(input.parse_inline()?);
1082        }
1083        Ok(scratch.map(Option::unwrap))
1084    }
1085    fn parse_generic_array<N: ArrayLength>(input: &mut I) -> crate::Result<GenericArray<Self, N>> {
1086        let mut scratch = GenericArray::default();
1087        for item in scratch.iter_mut() {
1088            *item = Some(input.parse_inline()?);
1089        }
1090        Ok(scratch.map(Option::unwrap))
1091    }
1092}
1093
1094/// Implemented if both types have the exact same layout.
1095/// This implies having the same [`MaybeHasNiche::MnArray`].
1096///
1097/// This is represented as two-way conversion for two reasons:
1098/// - to highlight that the conversion is actual equivalence
1099/// - to increase flexibility (mostly to go around the orphan rule)
1100pub trait Equivalent<T>: Sized {
1101    /// Inverse of [`Equivalent::from_equivalent`].
1102    fn into_equivalent(self) -> T;
1103    /// Inverse of [`Equivalent::into_equivalent`].
1104    fn from_equivalent(object: T) -> Self;
1105}
1106
1107pub trait ExtraFor<T> {
1108    fn parse(&self, data: &[u8], resolve: &Arc<dyn Resolve>) -> Result<T>;
1109
1110    fn parse_checked(&self, hash: Hash, data: &[u8], resolve: &Arc<dyn Resolve>) -> Result<T>
1111    where
1112        T: FullHash,
1113    {
1114        let object = self.parse(data, resolve)?;
1115        if object.full_hash() != hash {
1116            Err(Error::FullHashMismatch)
1117        } else {
1118            Ok(object)
1119        }
1120    }
1121}
1122
1123impl<T: for<'a> Parse<Input<'a, Extra>>, Extra: Clone> ExtraFor<T> for Extra {
1124    fn parse(&self, data: &[u8], resolve: &Arc<dyn Resolve>) -> Result<T> {
1125        T::parse_slice_extra(data, resolve, self)
1126    }
1127}
1128
1129pub trait BoundPair: Sized {
1130    type T;
1131    type E;
1132}
1133
1134impl<T, E> BoundPair for (T, E) {
1135    type T = T;
1136    type E = E;
1137}
1138
1139#[derive(Debug, ToOutput, InlineOutput, Tagged, ListHashes, Topological, Clone, Copy)]
1140pub struct InlineExtra<T, E = ()>(pub E, pub T);
1141
1142impl<
1143    E: 'static + Send + Sync + Clone + ParseInline<I>,
1144    X: 'static + Send + Sync + Clone,
1145    T: Parse<J>,
1146    I: PointInput<Extra = X, WithExtra<(E, X)> = J>,
1147    J: ParseInput,
1148> Parse<I> for InlineExtra<T, E>
1149{
1150    fn parse(mut input: I) -> crate::Result<Self> {
1151        let e = input.parse_inline::<E>()?;
1152        let x = input.extra().clone();
1153        let t = input.parse_extra((e.clone(), x))?;
1154        Ok(Self(e, t))
1155    }
1156}
1157
1158impl<
1159    E: 'static + Send + Sync + Clone + ParseInline<I>,
1160    X: 'static + Send + Sync + Clone,
1161    T: ParseInline<J>,
1162    I: PointInput<Extra = X, WithExtra<(E, X)> = J>,
1163    J: ParseInput,
1164> ParseInline<I> for InlineExtra<T, E>
1165{
1166    fn parse_inline(input: &mut I) -> crate::Result<Self> {
1167        let e = input.parse_inline::<E>()?;
1168        let x = input.extra().clone();
1169        let t = input.parse_inline_extra((e.clone(), x))?;
1170        Ok(Self(e, t))
1171    }
1172}
1173
1174#[test]
1175fn options() {
1176    type T0 = ();
1177    type T1 = Option<T0>;
1178    type T2 = Option<T1>;
1179    type T3 = Option<T2>;
1180    type T4 = Option<T3>;
1181    type T5 = Option<T4>;
1182    assert_eq!(T0::SIZE, 0);
1183    assert_eq!(T1::SIZE, 1);
1184    assert_eq!(T2::SIZE, 1);
1185    assert_eq!(T3::SIZE, 1);
1186    assert_eq!(T4::SIZE, 1);
1187    assert_eq!(T5::SIZE, 1);
1188    assert_eq!(Some(Some(Some(()))).vec(), [0]);
1189    assert_eq!(Some(Some(None::<()>)).vec(), [1]);
1190    assert_eq!(Some(None::<Option<()>>).vec(), [2]);
1191    assert_eq!(None::<Option<Option<()>>>.vec(), [3]);
1192
1193    assert_eq!(false.vec(), [0]);
1194    assert_eq!(true.vec(), [1]);
1195    assert_eq!(Some(false).vec(), [0]);
1196    assert_eq!(Some(true).vec(), [1]);
1197    assert_eq!(None::<bool>.vec(), [2]);
1198    assert_eq!(Some(Some(false)).vec(), [0]);
1199    assert_eq!(Some(Some(true)).vec(), [1]);
1200    assert_eq!(Some(None::<bool>).vec(), [2]);
1201    assert_eq!(None::<Option<bool>>.vec(), [3]);
1202    assert_eq!(Some(Some(Some(false))).vec(), [0]);
1203    assert_eq!(Some(Some(Some(true))).vec(), [1]);
1204    assert_eq!(Some(Some(None::<bool>)).vec(), [2]);
1205    assert_eq!(Some(None::<Option<bool>>).vec(), [3]);
1206    assert_eq!(None::<Option<Option<bool>>>.vec(), [4]);
1207    assert_eq!(Option::<Hash>::SIZE, HASH_SIZE);
1208    assert_eq!(Some(()).vec(), [0]);
1209    assert_eq!(Some(((), ())).vec(), [0]);
1210    assert_eq!(Some(((), true)).vec(), [1]);
1211    assert_eq!(Some((true, true)).vec(), [1, 1]);
1212    assert_eq!(Some((Some(true), true)).vec(), [1, 1]);
1213    assert_eq!(Some((None::<bool>, true)).vec(), [2, 1]);
1214    assert_eq!(Some((true, None::<bool>)).vec(), [1, 2]);
1215    assert_eq!(None::<(Option<bool>, bool)>.vec(), [3, 2]);
1216    assert_eq!(None::<(bool, Option<bool>)>.vec(), [2, 3]);
1217    assert_eq!(Some(Some((Some(true), Some(true)))).vec(), [1, 1],);
1218    assert_eq!(Option::<Hash>::SIZE, HASH_SIZE);
1219    assert_eq!(Option::<Option<Hash>>::SIZE, HASH_SIZE);
1220    assert_eq!(Option::<Option<Option<Hash>>>::SIZE, HASH_SIZE);
1221}