p3_symmetric/
hash.rs

1use core::borrow::Borrow;
2use core::marker::PhantomData;
3
4use serde::{Deserialize, Serialize};
5
6/// A wrapper around an array digest, with a phantom type parameter to ensure that the digest is
7/// associated with a particular field.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(bound(serialize = "[W; DIGEST_ELEMS]: Serialize"))]
10#[serde(bound(deserialize = "[W; DIGEST_ELEMS]: Deserialize<'de>"))]
11pub struct Hash<F, W, const DIGEST_ELEMS: usize> {
12    value: [W; DIGEST_ELEMS],
13    _marker: PhantomData<F>,
14}
15
16impl<F, W, const DIGEST_ELEMS: usize> From<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
17    fn from(value: [W; DIGEST_ELEMS]) -> Self {
18        Self {
19            value,
20            _marker: PhantomData,
21        }
22    }
23}
24
25impl<F, W, const DIGEST_ELEMS: usize> From<Hash<F, W, DIGEST_ELEMS>> for [W; DIGEST_ELEMS] {
26    fn from(value: Hash<F, W, DIGEST_ELEMS>) -> [W; DIGEST_ELEMS] {
27        value.value
28    }
29}
30
31impl<F, W: PartialEq, const DIGEST_ELEMS: usize> PartialEq<[W; DIGEST_ELEMS]>
32    for Hash<F, W, DIGEST_ELEMS>
33{
34    fn eq(&self, other: &[W; DIGEST_ELEMS]) -> bool {
35        self.value == *other
36    }
37}
38
39impl<F, W, const DIGEST_ELEMS: usize> IntoIterator for Hash<F, W, DIGEST_ELEMS> {
40    type Item = W;
41    type IntoIter = core::array::IntoIter<W, DIGEST_ELEMS>;
42
43    fn into_iter(self) -> Self::IntoIter {
44        self.value.into_iter()
45    }
46}
47
48impl<F, W, const DIGEST_ELEMS: usize> Borrow<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
49    fn borrow(&self) -> &[W; DIGEST_ELEMS] {
50        &self.value
51    }
52}
53
54impl<F, W, const DIGEST_ELEMS: usize> AsRef<[W; DIGEST_ELEMS]> for Hash<F, W, DIGEST_ELEMS> {
55    fn as_ref(&self) -> &[W; DIGEST_ELEMS] {
56        &self.value
57    }
58}