mdnt_groups_support/
lib.rs

1#![doc = include_str!("../README.md")]
2//!
3//! Includes some implementations of the [`DecomposeIn<Cell>`] trait for standard
4//! types but is not exhaustive. The implemented types cover the needs of the
5//! circuits crate.
6//!
7//! If other external types are required their implementation should be added to
8//! this crate.
9
10#![deny(rustdoc::broken_intra_doc_links)]
11#![deny(missing_debug_implementations)]
12#![deny(missing_docs)]
13
14/// Implementations of this trait represent complex types that aggregate a
15/// collection of `AssignedCell` values.
16pub trait DecomposeIn<Cell> {
17    /// Returns an iterator of `Cell` instances.
18    fn cells(&self) -> impl IntoIterator<Item = Cell>;
19}
20
21impl<Cell> DecomposeIn<Cell> for u32 {
22    fn cells(&self) -> impl IntoIterator<Item = Cell> {
23        std::iter::empty()
24    }
25}
26
27impl<Cell, T: DecomposeIn<Cell> + ?Sized> DecomposeIn<Cell> for &T {
28    fn cells(&self) -> impl IntoIterator<Item = Cell> {
29        (*self).cells()
30    }
31}
32
33impl<Cell, T: DecomposeIn<Cell> + ?Sized> DecomposeIn<Cell> for &mut T {
34    fn cells(&self) -> impl IntoIterator<Item = Cell> {
35        (**self).cells()
36    }
37}
38
39impl<Cell, T: DecomposeIn<Cell>, E> DecomposeIn<Cell> for Result<T, E> {
40    fn cells(&self) -> impl IntoIterator<Item = Cell> {
41        self.iter().flat_map(|t| t.cells())
42    }
43}
44
45impl<Cell, T: DecomposeIn<Cell>> DecomposeIn<Cell> for Option<T> {
46    fn cells(&self) -> impl IntoIterator<Item = Cell> {
47        self.iter().flat_map(|t| t.cells())
48    }
49}
50
51impl<Cell, T: DecomposeIn<Cell>> DecomposeIn<Cell> for [T] {
52    fn cells(&self) -> impl IntoIterator<Item = Cell> {
53        self.iter().flat_map(|t| t.cells())
54    }
55}
56
57impl<Cell, T: DecomposeIn<Cell>, const N: usize> DecomposeIn<Cell> for [T; N] {
58    fn cells(&self) -> impl IntoIterator<Item = Cell> {
59        self.iter().flat_map(|t| t.cells())
60    }
61}
62
63impl<Cell, T: DecomposeIn<Cell>> DecomposeIn<Cell> for Vec<T> {
64    fn cells(&self) -> impl IntoIterator<Item = Cell> {
65        self.iter().flat_map(|t| t.cells())
66    }
67}
68
69macro_rules! chain {
70    () => {
71        std::iter::empty()
72    };
73    ($h:expr $(,$t:expr)* $(,)?) => {
74        $h.into_iter().chain( chain!($( $t, )*))
75    };
76}
77
78macro_rules! tuple_impl {
79    () => {
80        tuple_impl!(@impl [] [] [A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12] [0 1 2 3 4 5 6 7 8 9 10 11]);
81    };
82
83    (@impl [$($done:ident)*] [$($idxs:tt)*] [$head:ident $($rest:ident)*] [$i:tt $($is:tt)*]) => {
84        //// Implement for tuple ($head, $done...)
85        impl<Cell, $head: DecomposeIn<Cell>, $( $done: DecomposeIn<Cell>, )*> DecomposeIn<Cell> for (
86                $head, $( $done, )*
87            )
88        {
89            fn cells(&self) -> impl IntoIterator<Item = Cell> {
90                chain!($(
91                    self.$idxs.cells(),
92                )*
93                self.$i.cells())
94            }
95        }
96
97        // Recurse
98        tuple_impl!(
99            @impl [$head $($done)*] [$($idxs)* $i] [$($rest)*] [$($is)*]
100        );
101    };
102
103    // Stop when no identifiers remain
104    (@impl [$($done:ident)*] [$($idxs:tt)*] [] $rem:tt) => {
105        // Also emit the 0-tuple base case
106        impl<Cell> DecomposeIn<Cell> for () {
107            fn cells(&self) -> impl IntoIterator<Item = Cell> {
108                std::iter::empty()
109            }
110        }
111    };
112
113}
114
115tuple_impl!();