amplify/collection/
array.rs

1// Rust language amplification library providing multiple generic trait
2// implementations, type wrappers, derive macros and other language enhancements
3//
4// Written in 2020-2021 by
5//     Dr. Maxim Orlovsky <orlovsky@ubideco.org>
6//
7// To the extent possible under law, the author(s) have dedicated all
8// copyright and related and neighboring rights to this software to
9// the public domain worldwide. This software is distributed without
10// any warranty.
11//
12// You should have received a copy of the MIT License
13// along with this software.
14// If not, see <https://opensource.org/licenses/MIT>.
15
16#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
17use core::fmt::{LowerHex, UpperHex};
18#[cfg(any(feature = "std", feature = "alloc"))]
19use core::fmt::{self, Display, Debug, Formatter};
20#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
21use core::str::FromStr;
22use core::ops::{Index, IndexMut, RangeFull};
23#[cfg(feature = "alloc")]
24use alloc::vec::Vec;
25use core::borrow::{Borrow, BorrowMut};
26use core::ops::{
27    Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive, BitAndAssign, BitOrAssign,
28    BitXorAssign, BitAnd, BitOr, BitXor, Not,
29};
30use core::{slice, array};
31
32#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
33use crate::hex::{FromHex, ToHex, self};
34use crate::{Wrapper, WrapperMut};
35
36/// Error when slice size mismatches array length.
37#[derive(Copy, Clone, Eq, PartialEq, Debug)]
38pub struct FromSliceError {
39    /// Expected slice length.
40    pub expected: usize,
41    /// Actual slice length.
42    pub actual: usize,
43}
44
45#[cfg(any(feature = "std", feature = "alloc"))]
46impl Display for FromSliceError {
47    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
48        write!(
49            f,
50            "the provided slice length {} doesn't match array size {}",
51            self.actual, self.expected
52        )
53    }
54}
55
56#[cfg(feature = "std")]
57impl std::error::Error for FromSliceError {}
58
59/// Wrapper type for all array-based bytes implementing many important
60/// traits, so types based on it can simply derive their implementations.
61///
62/// Type keeps data in little-endian byte order and displays them in the same
63/// order (like bitcoin SHA256 single hash type).
64pub type Bytes<const LEN: usize> = Array<u8, LEN>;
65
66/// Wrapper type for all array-based 32-bit types implementing many important
67/// traits, so types based on it can simply derive their implementations.
68///
69/// Type keeps data in little-endian byte order and displays them in the same
70/// order (like bitcoin SHA256 single hash type).
71pub type Bytes4 = Array<u8, 4>;
72
73/// Wrapper type for all array-based 128-bit types implementing many important
74/// traits, so types based on it can simply derive their implementations.
75///
76/// Type keeps data in little-endian byte order and displays them in the same
77/// order (like bitcoin SHA256 single hash type).
78pub type Bytes16 = Array<u8, 16>;
79
80/// Wrapper type for all array-based 160-bit types implementing many important
81/// traits, so types based on it can simply derive their implementations.
82///
83/// Type keeps data in little-endian byte order and displays them in the same
84/// order (like bitcoin SHA256 single hash type).
85pub type Bytes20 = Array<u8, 20>;
86
87/// Wrapper type for all array-based 256-bit types implementing many important
88/// traits, so types based on it can simply derive their implementations.
89///
90/// Type keeps data in little-endian byte order and displays them in the same
91/// order (like bitcoin SHA256 single hash type).
92pub type Bytes32 = Array<u8, 32>;
93
94/// Wrapper type for all array-based 256-bit types implementing many important
95/// traits, so types based on it can simply derive their implementations.
96///
97/// Type keeps data in little-endian byte order and displays them in the revers
98/// (like bitcoin SHA256d hash types).
99pub type Bytes32StrRev = Array<u8, 32, true>;
100
101/// Wrapper type for all array-based 512-bit types implementing many important
102/// traits, so types based on it can simply derive their implementations.
103///
104/// Type keeps data in little-endian byte order and displays them in the same
105/// order (like bitcoin SHA256 single hash type).
106pub type Bytes64 = Array<u8, 64>;
107
108/// Wrapper type for all fixed arrays implementing many important
109/// traits, so types based on it can simply derive their implementations.
110///
111/// Type keeps data in little-endian byte order and displays them in the same
112/// order (like bitcoin SHA256 single hash type).
113#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
114pub struct Array<T, const LEN: usize, const REVERSE_STR: bool = false>([T; LEN]);
115
116impl<T, const LEN: usize, const REVERSE_STR: bool> Array<T, LEN, REVERSE_STR> {
117    /// Constructs array filled with given value.
118    /// TODO: Revert commit 7110cee0cf539d8ff4270450183f7060a585bc87 and make
119    ///       method `const` once `const_fn_trait_bound` stabilize
120    pub fn with_fill(val: T) -> Self
121    where
122        T: Copy,
123    {
124        Self([val; LEN])
125    }
126
127    /// Wraps inner representation into array type.
128    pub const fn from_array(inner: [T; LEN]) -> Self {
129        Self(inner)
130    }
131
132    /// Returns byte slice representation.
133    #[inline]
134    pub fn as_slice(&self) -> &[T] {
135        self.as_ref()
136    }
137
138    /// Returns mutable byte slice representation.
139    #[inline]
140    pub fn as_slice_mut(&mut self) -> &mut [T] {
141        self.as_mut()
142    }
143
144    /// Returns vector representing internal slice data
145    #[allow(clippy::wrong_self_convention)]
146    #[cfg(any(test, feature = "std", feature = "alloc"))]
147    pub fn to_vec(&self) -> Vec<T>
148    where
149        T: Clone,
150    {
151        self.0.to_vec()
152    }
153
154    /// Returns an iterator over the array items.
155    ///
156    /// The iterator yields all items from start to end.
157    pub fn iter(&self) -> slice::Iter<T> {
158        self.0.iter()
159    }
160
161    /// Returns an iterator that allows modifying each value.
162    ///
163    /// The iterator yields all items from start to end.
164    pub fn iter_mut(&mut self) -> slice::IterMut<T> {
165        self.0.iter_mut()
166    }
167}
168
169impl<const LEN: usize, const REVERSE_STR: bool> Array<u8, LEN, REVERSE_STR> {
170    #[cfg(feature = "rand")]
171    /// Generates array from `rand::thread_rng` random number generator
172    pub fn random() -> Self {
173        use rand::RngCore;
174        let mut entropy = [0u8; LEN];
175        rand::thread_rng().fill_bytes(&mut entropy);
176        Array::from_inner(entropy)
177    }
178
179    /// Constructs array filled with zero bytes
180    pub const fn zero() -> Self {
181        Self([0u8; LEN])
182    }
183
184    /* TODO: Uncomment once Array::from_slice -> Option will be removed
185    /// Constructs a byte array from the slice. Errors if the slice length
186    /// doesn't match `LEN` constant generic.
187    #[inline]
188    pub fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError> {
189        Self::try_from(slice)
190    }
191     */
192
193    /// Constructs a byte array from the slice. Expects the slice length
194    /// doesn't match `LEN` constant generic.
195    ///
196    /// # Safety
197    ///
198    /// Panics if the slice length doesn't match `LEN` constant generic.
199    #[inline]
200    pub fn from_slice_unsafe(slice: impl AsRef<[u8]>) -> Self {
201        Self::copy_from_slice(slice).expect("slice length not matching type requirements")
202    }
203
204    /// Returns a byte array representation stored in the wrapped type.
205    #[inline]
206    pub fn to_byte_array(&self) -> [u8; LEN] {
207        self.0
208    }
209
210    /// Constructs [`Array`] type from another type containing raw array.
211    #[inline]
212    pub fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self {
213        Array::from_inner(val.into())
214    }
215}
216
217impl<const LEN: usize, const REVERSE_STR: bool> BitAnd for Array<u8, LEN, REVERSE_STR> {
218    type Output = Self;
219
220    fn bitand(mut self, rhs: Self) -> Self::Output {
221        self.bitand_assign(rhs);
222        self
223    }
224}
225
226impl<const LEN: usize, const REVERSE_STR: bool> BitAndAssign for Array<u8, LEN, REVERSE_STR> {
227    fn bitand_assign(&mut self, rhs: Self) {
228        self.0
229            .iter_mut()
230            .zip(rhs)
231            .for_each(|(a, b)| a.bitand_assign(b));
232    }
233}
234
235impl<const LEN: usize, const REVERSE_STR: bool> BitOr for Array<u8, LEN, REVERSE_STR> {
236    type Output = Self;
237
238    fn bitor(mut self, rhs: Self) -> Self::Output {
239        self.bitor_assign(rhs);
240        self
241    }
242}
243
244impl<const LEN: usize, const REVERSE_STR: bool> BitOrAssign for Array<u8, LEN, REVERSE_STR> {
245    fn bitor_assign(&mut self, rhs: Self) {
246        self.0
247            .iter_mut()
248            .zip(rhs)
249            .for_each(|(a, b)| a.bitor_assign(b));
250    }
251}
252
253impl<const LEN: usize, const REVERSE_STR: bool> BitXor for Array<u8, LEN, REVERSE_STR> {
254    type Output = Self;
255
256    fn bitxor(mut self, rhs: Self) -> Self::Output {
257        self.bitxor_assign(rhs);
258        self
259    }
260}
261
262impl<const LEN: usize, const REVERSE_STR: bool> BitXorAssign for Array<u8, LEN, REVERSE_STR> {
263    fn bitxor_assign(&mut self, rhs: Self) {
264        self.0
265            .iter_mut()
266            .zip(rhs)
267            .for_each(|(a, b)| a.bitxor_assign(b));
268    }
269}
270
271impl<const LEN: usize, const REVERSE_STR: bool> Not for Array<u8, LEN, REVERSE_STR> {
272    type Output = Self;
273
274    fn not(mut self) -> Self::Output {
275        self.0.iter_mut().for_each(|e| *e = e.not());
276        self
277    }
278}
279
280impl<T, const LEN: usize, const REVERSE_STR: bool> Array<T, LEN, REVERSE_STR>
281where
282    T: Default + Copy,
283{
284    /// Constructs 256-bit array from a provided slice. If the slice length
285    /// is not equal to `LEN` bytes, returns `None`
286    #[deprecated(since = "4.2.0", note = "use copy_from_slice")]
287    pub fn from_slice(slice: impl AsRef<[T]>) -> Option<Self> {
288        let slice = slice.as_ref();
289        if slice.len() != LEN {
290            return None;
291        }
292        let mut inner = [T::default(); LEN];
293        inner.copy_from_slice(slice);
294        Some(Self(inner))
295    }
296
297    /// Constructs 256-bit array by copying from a provided slice. Errors if the
298    /// slice length is not equal to `LEN` bytes.
299    pub fn copy_from_slice(slice: impl AsRef<[T]>) -> Result<Self, FromSliceError> {
300        let slice = slice.as_ref();
301        let len = slice.len();
302        if len != LEN {
303            return Err(FromSliceError {
304                actual: len,
305                expected: LEN,
306            });
307        }
308        let mut inner = [T::default(); LEN];
309        inner.copy_from_slice(slice);
310        Ok(Self(inner))
311    }
312}
313
314impl<T, const LEN: usize, const REVERSE_STR: bool> Default for Array<T, LEN, REVERSE_STR>
315where
316    T: Default + Copy,
317{
318    fn default() -> Self {
319        let inner = [T::default(); LEN];
320        Self(inner)
321    }
322}
323
324impl<T, const LEN: usize, const REVERSE_STR: bool> From<[T; LEN]> for Array<T, LEN, REVERSE_STR> {
325    fn from(array: [T; LEN]) -> Self {
326        Array(array)
327    }
328}
329
330impl<T, const LEN: usize, const REVERSE_STR: bool> TryFrom<&[T]> for Array<T, LEN, REVERSE_STR>
331where
332    T: Copy + Default,
333{
334    type Error = FromSliceError;
335
336    fn try_from(value: &[T]) -> Result<Self, Self::Error> {
337        <[T; LEN]>::try_from(value)
338            .map_err(|_| FromSliceError {
339                actual: value.len(),
340                expected: LEN,
341            })
342            .map(Self)
343    }
344}
345
346impl<T, const LEN: usize, const REVERSE_STR: bool> AsRef<[T]> for Array<T, LEN, REVERSE_STR> {
347    #[inline]
348    fn as_ref(&self) -> &[T] {
349        self.0.as_ref()
350    }
351}
352
353impl<T, const LEN: usize, const REVERSE_STR: bool> AsMut<[T]> for Array<T, LEN, REVERSE_STR> {
354    #[inline]
355    fn as_mut(&mut self) -> &mut [T] {
356        self.0.as_mut()
357    }
358}
359
360impl<T, const LEN: usize, const REVERSE_STR: bool> Borrow<[T]> for Array<T, LEN, REVERSE_STR> {
361    #[inline]
362    fn borrow(&self) -> &[T] {
363        self.0.borrow()
364    }
365}
366
367impl<T, const LEN: usize, const REVERSE_STR: bool> BorrowMut<[T]> for Array<T, LEN, REVERSE_STR> {
368    #[inline]
369    fn borrow_mut(&mut self) -> &mut [T] {
370        self.0.borrow_mut()
371    }
372}
373
374impl<T, const LEN: usize, const REVERSE_STR: bool> Index<usize> for Array<T, LEN, REVERSE_STR> {
375    type Output = T;
376    #[inline]
377    fn index(&self, index: usize) -> &Self::Output {
378        &self.0[index]
379    }
380}
381
382impl<T, const LEN: usize, const REVERSE_STR: bool> Index<Range<usize>>
383    for Array<T, LEN, REVERSE_STR>
384{
385    type Output = [T];
386    #[inline]
387    fn index(&self, index: Range<usize>) -> &Self::Output {
388        &self.0[index]
389    }
390}
391
392impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeTo<usize>>
393    for Array<T, LEN, REVERSE_STR>
394{
395    type Output = [T];
396    #[inline]
397    fn index(&self, index: RangeTo<usize>) -> &Self::Output {
398        &self.0[index]
399    }
400}
401
402impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeFrom<usize>>
403    for Array<T, LEN, REVERSE_STR>
404{
405    type Output = [T];
406    #[inline]
407    fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
408        &self.0[index]
409    }
410}
411
412impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeInclusive<usize>>
413    for Array<T, LEN, REVERSE_STR>
414{
415    type Output = [T];
416    #[inline]
417    fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
418        &self.0[index]
419    }
420}
421
422impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeToInclusive<usize>>
423    for Array<T, LEN, REVERSE_STR>
424{
425    type Output = [T];
426    #[inline]
427    fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
428        &self.0[index]
429    }
430}
431
432impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeFull> for Array<T, LEN, REVERSE_STR> {
433    type Output = [T];
434    #[inline]
435    fn index(&self, index: RangeFull) -> &Self::Output {
436        &self.0[index]
437    }
438}
439
440impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<usize> for Array<T, LEN, REVERSE_STR> {
441    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
442        &mut self.0[index]
443    }
444}
445
446impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<Range<usize>>
447    for Array<T, LEN, REVERSE_STR>
448{
449    #[inline]
450    fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
451        &mut self.0[index]
452    }
453}
454
455impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeTo<usize>>
456    for Array<T, LEN, REVERSE_STR>
457{
458    #[inline]
459    fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
460        &mut self.0[index]
461    }
462}
463
464impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeFrom<usize>>
465    for Array<T, LEN, REVERSE_STR>
466{
467    #[inline]
468    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
469        &mut self.0[index]
470    }
471}
472
473impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeInclusive<usize>>
474    for Array<T, LEN, REVERSE_STR>
475{
476    #[inline]
477    fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
478        &mut self.0[index]
479    }
480}
481
482impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeToInclusive<usize>>
483    for Array<T, LEN, REVERSE_STR>
484{
485    #[inline]
486    fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
487        &mut self.0[index]
488    }
489}
490
491impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeFull>
492    for Array<T, LEN, REVERSE_STR>
493{
494    #[inline]
495    fn index_mut(&mut self, index: RangeFull) -> &mut Self::Output {
496        &mut self.0[index]
497    }
498}
499
500impl<T, const LEN: usize, const REVERSE_STR: bool> IntoIterator for Array<T, LEN, REVERSE_STR> {
501    type Item = T;
502    type IntoIter = array::IntoIter<T, LEN>;
503
504    fn into_iter(self) -> Self::IntoIter {
505        self.0.into_iter()
506    }
507}
508
509impl<T, const LEN: usize, const REVERSE_STR: bool> From<T> for Array<T, LEN, REVERSE_STR>
510where
511    T: Into<[T; LEN]>,
512{
513    fn from(array: T) -> Self {
514        Self(array.into())
515    }
516}
517
518impl<T, const LEN: usize, const REVERSE_STR: bool> Wrapper for Array<T, LEN, REVERSE_STR> {
519    type Inner = [T; LEN];
520
521    #[inline]
522    fn from_inner(inner: Self::Inner) -> Self {
523        Self(inner)
524    }
525
526    #[inline]
527    fn as_inner(&self) -> &Self::Inner {
528        &self.0
529    }
530
531    #[inline]
532    fn into_inner(self) -> Self::Inner {
533        self.0
534    }
535}
536
537impl<T, const LEN: usize, const REVERSE_STR: bool> WrapperMut for Array<T, LEN, REVERSE_STR> {
538    fn as_inner_mut(&mut self) -> &mut Self::Inner {
539        &mut self.0
540    }
541}
542
543#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
544impl<const LEN: usize, const REVERSE_STR: bool> Display for Array<u8, LEN, REVERSE_STR> {
545    #[inline]
546    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
547        LowerHex::fmt(self, f)
548    }
549}
550
551#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
552impl<const LEN: usize, const REVERSE_STR: bool> Debug for Array<u8, LEN, REVERSE_STR> {
553    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
554        write!(f, "Array<{}>({})", LEN, self.to_hex())
555    }
556}
557
558#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
559impl<const LEN: usize, const REVERSE_STR: bool> FromStr for Array<u8, LEN, REVERSE_STR> {
560    type Err = hex::Error;
561
562    fn from_str(s: &str) -> Result<Self, Self::Err> {
563        Self::from_hex(s)
564    }
565}
566
567#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
568impl<const LEN: usize, const REVERSE_STR: bool> FromHex for Array<u8, LEN, REVERSE_STR> {
569    fn from_byte_iter<I>(iter: I) -> Result<Self, hex::Error>
570    where
571        I: Iterator<Item = Result<u8, hex::Error>> + ExactSizeIterator + DoubleEndedIterator,
572    {
573        let mut vec = Vec::<u8>::from_byte_iter(iter)?;
574        if REVERSE_STR {
575            vec.reverse();
576        }
577        if vec.len() != LEN {
578            return Err(hex::Error::InvalidLength(LEN, vec.len()));
579        }
580        let mut id = [0u8; LEN];
581        id.copy_from_slice(&vec);
582        Ok(Array(id))
583    }
584}
585
586#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
587impl<const LEN: usize, const REVERSE_STR: bool> LowerHex for Array<u8, LEN, REVERSE_STR> {
588    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
589        let mut slice = self.into_inner();
590        if REVERSE_STR {
591            slice.reverse();
592        }
593        if f.alternate() {
594            write!(
595                f,
596                "{}..{}",
597                slice[..4].to_hex(),
598                slice[(slice.len() - 4)..].to_hex()
599            )
600        } else {
601            f.write_str(&slice.to_hex())
602        }
603    }
604}
605
606#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
607impl<const LEN: usize, const REVERSE_STR: bool> UpperHex for Array<u8, LEN, REVERSE_STR> {
608    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
609        let mut slice = self.into_inner();
610        if REVERSE_STR {
611            slice.reverse();
612        }
613        if f.alternate() {
614            write!(
615                f,
616                "{}..{}",
617                slice[..4].to_hex().to_ascii_uppercase(),
618                slice[(slice.len() - 4)..].to_hex().to_ascii_uppercase()
619            )
620        } else {
621            f.write_str(&slice.to_hex().to_ascii_uppercase())
622        }
623    }
624}
625
626#[cfg(all(feature = "serde", feature = "hex"))]
627pub(crate) mod serde_helpers {
628    //! Serde serialization helpers
629
630    use core::fmt;
631    use serde::{Deserialize, Deserializer, Serializer, Serialize};
632    use serde_crate::de::{SeqAccess, Visitor};
633    use serde_crate::ser::SerializeTuple;
634
635    use crate::Array;
636    use crate::hex::{FromHex, ToHex};
637
638    impl<const LEN: usize, const REVERSE_STR: bool> Serialize for Array<u8, LEN, REVERSE_STR> {
639        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
640        where
641            S: Serializer,
642        {
643            if serializer.is_human_readable() {
644                serializer.serialize_str(&self.to_hex())
645            } else {
646                let mut ser = serializer.serialize_tuple(LEN)?;
647                for i in 0..LEN {
648                    ser.serialize_element(&self.0[i])?;
649                }
650                ser.end()
651            }
652        }
653    }
654
655    impl<'de, const LEN: usize, const REVERSE_STR: bool> Deserialize<'de>
656        for Array<u8, LEN, REVERSE_STR>
657    {
658        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
659        where
660            D: Deserializer<'de>,
661        {
662            use serde::de::Error;
663            if deserializer.is_human_readable() {
664                String::deserialize(deserializer).and_then(|string| {
665                    Self::from_hex(&string).map_err(|_| D::Error::custom("wrong hex data"))
666                })
667            } else {
668                struct ArrayVisitor<const LEN: usize>;
669
670                impl<'de, const LEN: usize> Visitor<'de> for ArrayVisitor<LEN> {
671                    type Value = [u8; LEN];
672
673                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
674                        write!(formatter, "an array of length {LEN}")
675                    }
676
677                    fn visit_seq<A>(self, mut seq: A) -> Result<[u8; LEN], A::Error>
678                    where
679                        A: SeqAccess<'de>,
680                    {
681                        let mut arr = [0; LEN];
682                        for (i, el) in arr.iter_mut().enumerate() {
683                            *el = seq
684                                .next_element()?
685                                .ok_or_else(|| Error::invalid_length(i, &self))?;
686                        }
687                        Ok(arr)
688                    }
689                }
690
691                deserializer.deserialize_tuple(LEN, ArrayVisitor).map(Self)
692            }
693        }
694    }
695}
696
697/// Trait which does a blanket implementation for all types wrapping [`Array`]s
698#[deprecated(since = "4.2.0", note = "use ByteArray instead")]
699pub trait RawArray<const LEN: usize>: Sized {
700    /// Constructs a wrapper type around an array.
701    fn from_raw_array(val: impl Into<[u8; LEN]>) -> Self;
702
703    /// Returns a raw array representation stored in the wrapped type.
704    fn to_raw_array(&self) -> [u8; LEN];
705}
706
707#[allow(deprecated)]
708impl<Id, const LEN: usize, const REVERSE_STR: bool> RawArray<LEN> for Id
709where
710    Id: Wrapper<Inner = Array<u8, LEN, REVERSE_STR>>,
711{
712    fn from_raw_array(val: impl Into<[u8; LEN]>) -> Self {
713        Self::from_inner(Array::from_inner(val.into()))
714    }
715
716    fn to_raw_array(&self) -> [u8; LEN] {
717        self.as_inner().into_inner()
718    }
719}
720
721/// Trait which does a blanket implementation for all types wrapping [`Array`]s
722pub trait ByteArray<const LEN: usize>: Sized {
723    /// Constructs a wrapper type around a byte array.
724    fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self;
725
726    /// Constructs a byte array from the slice. Errors if the slice length
727    /// doesn't match `LEN` constant generic.
728    fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError>;
729
730    /// Constructs a byte array from the slice. Expects the slice length
731    /// doesn't match `LEN` constant generic.
732    ///
733    /// # Safety
734    ///
735    /// Panics if the slice length doesn't match `LEN` constant generic.
736    fn from_slice_unsafe(slice: impl AsRef<[u8]>) -> Self;
737
738    /// Returns a byte array representation stored in the wrapped type.
739    fn to_byte_array(&self) -> [u8; LEN];
740}
741
742impl<Id, const LEN: usize, const REVERSE_STR: bool> ByteArray<LEN> for Id
743where
744    Id: Wrapper<Inner = Array<u8, LEN, REVERSE_STR>>,
745{
746    fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self {
747        Self::from_inner(Array::from_inner(val.into()))
748    }
749
750    fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError> {
751        Array::try_from(slice.as_ref()).map(Self::from_inner)
752    }
753
754    fn from_slice_unsafe(slice: impl AsRef<[u8]>) -> Self {
755        Self::from_slice(slice).expect("slice length not matching type requirements")
756    }
757
758    fn to_byte_array(&self) -> [u8; LEN] {
759        self.as_inner().into_inner()
760    }
761}
762
763#[cfg(test)]
764mod test {
765    use core::str::FromStr;
766
767    use super::*;
768    use crate::Wrapper;
769    use crate::hex::FromHex;
770
771    #[test]
772    fn test_slice32_str() {
773        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
774        let slice32 = Bytes32::from_hex(s).unwrap();
775
776        assert_eq!(slice32[0], 0xa3);
777
778        assert_eq!(Bytes32::from_str(s), Ok(slice32));
779
780        assert_eq!(Bytes32::from_hex(&s.to_uppercase()), Ok(slice32));
781        assert_eq!(
782            Bytes32::from_str(&s[..30]),
783            Err(hex::Error::InvalidLength(32, 15))
784        );
785
786        assert_eq!(&slice32.to_string(), s);
787        assert_eq!(format!("{:x}", slice32), s);
788        assert_eq!(format!("{:X}", slice32), s.to_uppercase());
789        assert_eq!(format!("{:?}", slice32), format!("Array<32>({})", s));
790
791        #[cfg(feature = "serde")]
792        {
793            assert_eq!(
794                serde_json::to_string(&slice32).unwrap(),
795                format!(r#""{s}""#)
796            );
797            assert_eq!(
798                serde_json::from_str::<Bytes32>(&format!(r#""{s}""#)).unwrap(),
799                slice32
800            );
801        }
802    }
803
804    #[test]
805    fn test_slice32_rev_str() {
806        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
807        let slice32 = Bytes32StrRev::from_hex(s).unwrap();
808
809        assert_eq!(slice32[0], 0x53);
810
811        assert_eq!(Bytes32StrRev::from_str(s), Ok(slice32));
812
813        assert_eq!(Bytes32StrRev::from_hex(&s.to_uppercase()), Ok(slice32));
814        assert_eq!(
815            Bytes32StrRev::from_str(&s[..30]),
816            Err(hex::Error::InvalidLength(32, 15))
817        );
818
819        assert_eq!(&slice32.to_string(), s);
820        assert_eq!(format!("{:x}", slice32), s);
821        assert_eq!(format!("{:X}", slice32), s.to_uppercase());
822        assert_eq!(format!("{:?}", slice32), format!("Array<32>({})", s));
823
824        #[cfg(feature = "serde")]
825        {
826            assert_eq!(
827                serde_json::to_string(&slice32).unwrap(),
828                format!(r#""{s}""#)
829            );
830            assert_eq!(
831                serde_json::from_str::<Bytes32StrRev>(&format!(r#""{s}""#)).unwrap(),
832                slice32
833            );
834        }
835    }
836
837    #[test]
838    fn test_encoding() {
839        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
840        let slice32 = Array::from_hex(s).unwrap();
841
842        let data = [
843            0xa3, 0x40, 0x1b, 0xcc, 0xeb, 0x26, 0x20, 0x1b, 0x55, 0x97, 0x8f, 0xf7, 0x05, 0xfe,
844            0xcf, 0x7d, 0x8a, 0x0a, 0x03, 0x59, 0x8e, 0xbe, 0xcc, 0xf2, 0xa9, 0x47, 0x03, 0x0b,
845            0x91, 0xa0, 0xff, 0x53,
846        ];
847
848        assert_eq!(Bytes32::copy_from_slice(data), Ok(slice32));
849        assert_eq!(
850            Bytes32::copy_from_slice(&data[..30]),
851            Err(FromSliceError {
852                actual: 30,
853                expected: 32
854            })
855        );
856        assert_eq!(&slice32.to_vec(), &data);
857        assert_eq!(&slice32.as_inner()[..], &data);
858        assert_eq!(slice32.to_inner(), data);
859        assert_eq!(slice32.into_inner(), data);
860    }
861}