object_rainbow/
lib.rs

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