Skip to main content

object_rainbow/
lib.rs

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