1use alloc::vec;
2use alloc::vec::{IntoIter, Vec};
3use core::borrow::Borrow;
4use core::marker::PhantomData;
5
6use p3_util::log2_strict_usize;
7use serde::{Deserialize, Serialize};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(bound(serialize = "[W; DIGEST_ELEMS]: Serialize"))]
13#[serde(bound(deserialize = "[W; DIGEST_ELEMS]: Deserialize<'de>"))]
14pub struct Hash<F, W, const DIGEST_ELEMS: usize> {
15 value: [W; DIGEST_ELEMS],
16 _marker: PhantomData<F>,
17}
18
19#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(bound(serialize = "Digest: Serialize"))]
26#[serde(bound(deserialize = "Digest: Deserialize<'de>"))]
27pub struct MerkleCap<F, Digest> {
28 cap: Vec<Digest>,
29 _marker: PhantomData<F>,
30}
31
32impl<F, Digest: Default> Default for MerkleCap<F, Digest> {
33 fn default() -> Self {
34 Self {
35 cap: vec![Digest::default()],
36 _marker: PhantomData,
37 }
38 }
39}
40
41impl<F, Digest> MerkleCap<F, Digest> {
42 pub fn new(cap: Vec<Digest>) -> Self {
44 assert!(cap.len().is_power_of_two() || cap.is_empty());
45 Self {
46 cap,
47 _marker: PhantomData,
48 }
49 }
50
51 #[must_use]
53 pub const fn num_roots(&self) -> usize {
54 self.cap.len()
55 }
56
57 #[must_use]
60 pub const fn height(&self) -> usize {
61 log2_strict_usize(self.num_roots())
62 }
63
64 #[must_use]
66 pub fn roots(&self) -> &[Digest] {
67 &self.cap
68 }
69
70 pub fn into_roots(self) -> Vec<Digest> {
72 self.cap.into_iter().collect()
73 }
74}
75
76impl<F, Digest> From<Vec<Digest>> for MerkleCap<F, Digest> {
77 fn from(cap: Vec<Digest>) -> Self {
78 Self::new(cap)
79 }
80}
81
82impl<F, W, const N: usize> From<Hash<F, W, N>> for MerkleCap<F, [W; N]> {
83 fn from(hash: Hash<F, W, N>) -> Self {
84 Self::new(vec![hash.into()])
85 }
86}
87
88impl<F, Digest> Borrow<[Digest]> for MerkleCap<F, Digest> {
89 fn borrow(&self) -> &[Digest] {
90 &self.cap
91 }
92}
93
94impl<F, Digest> AsRef<[Digest]> for MerkleCap<F, Digest> {
95 fn as_ref(&self) -> &[Digest] {
96 &self.cap
97 }
98}
99
100impl<F, Digest> core::ops::Index<usize> for MerkleCap<F, Digest> {
101 type Output = Digest;
102
103 fn index(&self, index: usize) -> &Self::Output {
104 &self.cap[index]
105 }
106}
107
108impl<F, Digest> IntoIterator for MerkleCap<F, Digest> {
109 type Item = Digest;
110 type IntoIter = IntoIter<Digest>;
111
112 fn into_iter(self) -> Self::IntoIter {
113 self.cap.into_iter()
114 }
115}
116
117impl<F, W, const DIGEST_ELEMS: usize> From<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
118 fn from(value: [W; DIGEST_ELEMS]) -> Self {
119 Self {
120 value,
121 _marker: PhantomData,
122 }
123 }
124}
125
126impl<F, W, const DIGEST_ELEMS: usize> From<Hash<F, W, DIGEST_ELEMS>> for [W; DIGEST_ELEMS] {
127 fn from(value: Hash<F, W, DIGEST_ELEMS>) -> [W; DIGEST_ELEMS] {
128 value.value
129 }
130}
131
132impl<F, W: PartialEq, const DIGEST_ELEMS: usize> PartialEq<[W; DIGEST_ELEMS]>
133 for Hash<F, W, DIGEST_ELEMS>
134{
135 fn eq(&self, other: &[W; DIGEST_ELEMS]) -> bool {
136 self.value == *other
137 }
138}
139
140impl<F, W, const DIGEST_ELEMS: usize> IntoIterator for Hash<F, W, DIGEST_ELEMS> {
141 type Item = W;
142 type IntoIter = core::array::IntoIter<W, DIGEST_ELEMS>;
143
144 fn into_iter(self) -> Self::IntoIter {
145 self.value.into_iter()
146 }
147}
148
149impl<F, W, const DIGEST_ELEMS: usize> Borrow<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
150 fn borrow(&self) -> &[W; DIGEST_ELEMS] {
151 &self.value
152 }
153}
154
155impl<F, W, const DIGEST_ELEMS: usize> AsRef<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
156 fn as_ref(&self) -> &[W; DIGEST_ELEMS] {
157 &self.value
158 }
159}