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}