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::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    #[deprecated(since = "4.9.0", note = "use `from_slice_checked` instead")]
201    pub fn from_slice_unsafe(slice: impl AsRef<[u8]>) -> Self {
202        Self::from_slice_checked(slice)
203    }
204
205    /// Constructs a byte array from the slice. Expects the slice length
206    /// doesn't match `LEN` constant generic.
207    ///
208    /// # Safety
209    ///
210    /// Panics if the slice length doesn't match `LEN` constant generic.
211    #[inline]
212    pub fn from_slice_checked(slice: impl AsRef<[u8]>) -> Self {
213        Self::copy_from_slice(slice).expect("slice length not matching type requirements")
214    }
215
216    /// Returns a byte array representation stored in the wrapped type.
217    #[inline]
218    pub fn to_byte_array(&self) -> [u8; LEN] {
219        self.0
220    }
221
222    /// Constructs [`Array`] type from another type containing raw array.
223    #[inline]
224    pub fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self {
225        Array::from_inner(val.into())
226    }
227}
228
229impl<const LEN: usize, const REVERSE_STR: bool> BitAnd for Array<u8, LEN, REVERSE_STR> {
230    type Output = Self;
231
232    fn bitand(mut self, rhs: Self) -> Self::Output {
233        self.bitand_assign(rhs);
234        self
235    }
236}
237
238impl<const LEN: usize, const REVERSE_STR: bool> BitAndAssign for Array<u8, LEN, REVERSE_STR> {
239    fn bitand_assign(&mut self, rhs: Self) {
240        self.0
241            .iter_mut()
242            .zip(rhs)
243            .for_each(|(a, b)| a.bitand_assign(b));
244    }
245}
246
247impl<const LEN: usize, const REVERSE_STR: bool> BitOr for Array<u8, LEN, REVERSE_STR> {
248    type Output = Self;
249
250    fn bitor(mut self, rhs: Self) -> Self::Output {
251        self.bitor_assign(rhs);
252        self
253    }
254}
255
256impl<const LEN: usize, const REVERSE_STR: bool> BitOrAssign for Array<u8, LEN, REVERSE_STR> {
257    fn bitor_assign(&mut self, rhs: Self) {
258        self.0
259            .iter_mut()
260            .zip(rhs)
261            .for_each(|(a, b)| a.bitor_assign(b));
262    }
263}
264
265impl<const LEN: usize, const REVERSE_STR: bool> BitXor for Array<u8, LEN, REVERSE_STR> {
266    type Output = Self;
267
268    fn bitxor(mut self, rhs: Self) -> Self::Output {
269        self.bitxor_assign(rhs);
270        self
271    }
272}
273
274impl<const LEN: usize, const REVERSE_STR: bool> BitXorAssign for Array<u8, LEN, REVERSE_STR> {
275    fn bitxor_assign(&mut self, rhs: Self) {
276        self.0
277            .iter_mut()
278            .zip(rhs)
279            .for_each(|(a, b)| a.bitxor_assign(b));
280    }
281}
282
283impl<const LEN: usize, const REVERSE_STR: bool> Not for Array<u8, LEN, REVERSE_STR> {
284    type Output = Self;
285
286    fn not(mut self) -> Self::Output {
287        self.0.iter_mut().for_each(|e| *e = e.not());
288        self
289    }
290}
291
292impl<T, const LEN: usize, const REVERSE_STR: bool> Array<T, LEN, REVERSE_STR>
293where
294    T: Default + Copy,
295{
296    /// Constructs 256-bit array from a provided slice. If the slice length
297    /// is not equal to `LEN` bytes, returns `None`
298    #[deprecated(since = "4.2.0", note = "use copy_from_slice")]
299    pub fn from_slice(slice: impl AsRef<[T]>) -> Option<Self> {
300        let slice = slice.as_ref();
301        if slice.len() != LEN {
302            return None;
303        }
304        let mut inner = [T::default(); LEN];
305        inner.copy_from_slice(slice);
306        Some(Self(inner))
307    }
308
309    /// Constructs 256-bit array by copying from a provided slice. Errors if the
310    /// slice length is not equal to `LEN` bytes.
311    pub fn copy_from_slice(slice: impl AsRef<[T]>) -> Result<Self, FromSliceError> {
312        let slice = slice.as_ref();
313        let len = slice.len();
314        if len != LEN {
315            return Err(FromSliceError {
316                actual: len,
317                expected: LEN,
318            });
319        }
320        let mut inner = [T::default(); LEN];
321        inner.copy_from_slice(slice);
322        Ok(Self(inner))
323    }
324}
325
326impl<T, const LEN: usize, const REVERSE_STR: bool> Default for Array<T, LEN, REVERSE_STR>
327where
328    T: Default + Copy,
329{
330    fn default() -> Self {
331        let inner = [T::default(); LEN];
332        Self(inner)
333    }
334}
335
336impl<T, const LEN: usize, const REVERSE_STR: bool> From<[T; LEN]> for Array<T, LEN, REVERSE_STR> {
337    fn from(array: [T; LEN]) -> Self {
338        Array(array)
339    }
340}
341
342impl<T, const LEN: usize, const REVERSE_STR: bool> TryFrom<&[T]> for Array<T, LEN, REVERSE_STR>
343where
344    T: Copy + Default,
345{
346    type Error = FromSliceError;
347
348    fn try_from(value: &[T]) -> Result<Self, Self::Error> {
349        <[T; LEN]>::try_from(value)
350            .map_err(|_| FromSliceError {
351                actual: value.len(),
352                expected: LEN,
353            })
354            .map(Self)
355    }
356}
357
358impl<T, const LEN: usize, const REVERSE_STR: bool> AsRef<[T]> for Array<T, LEN, REVERSE_STR> {
359    #[inline]
360    fn as_ref(&self) -> &[T] {
361        self.0.as_ref()
362    }
363}
364
365impl<T, const LEN: usize, const REVERSE_STR: bool> AsMut<[T]> for Array<T, LEN, REVERSE_STR> {
366    #[inline]
367    fn as_mut(&mut self) -> &mut [T] {
368        self.0.as_mut()
369    }
370}
371
372impl<T, const LEN: usize, const REVERSE_STR: bool> Borrow<[T]> for Array<T, LEN, REVERSE_STR> {
373    #[inline]
374    fn borrow(&self) -> &[T] {
375        self.0.borrow()
376    }
377}
378
379impl<T, const LEN: usize, const REVERSE_STR: bool> BorrowMut<[T]> for Array<T, LEN, REVERSE_STR> {
380    #[inline]
381    fn borrow_mut(&mut self) -> &mut [T] {
382        self.0.borrow_mut()
383    }
384}
385
386impl<T, const LEN: usize, const REVERSE_STR: bool> Index<usize> for Array<T, LEN, REVERSE_STR> {
387    type Output = T;
388    #[inline]
389    fn index(&self, index: usize) -> &Self::Output {
390        &self.0[index]
391    }
392}
393
394impl<T, const LEN: usize, const REVERSE_STR: bool> Index<Range<usize>>
395    for Array<T, LEN, REVERSE_STR>
396{
397    type Output = [T];
398    #[inline]
399    fn index(&self, index: Range<usize>) -> &Self::Output {
400        &self.0[index]
401    }
402}
403
404impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeTo<usize>>
405    for Array<T, LEN, REVERSE_STR>
406{
407    type Output = [T];
408    #[inline]
409    fn index(&self, index: RangeTo<usize>) -> &Self::Output {
410        &self.0[index]
411    }
412}
413
414impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeFrom<usize>>
415    for Array<T, LEN, REVERSE_STR>
416{
417    type Output = [T];
418    #[inline]
419    fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
420        &self.0[index]
421    }
422}
423
424impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeInclusive<usize>>
425    for Array<T, LEN, REVERSE_STR>
426{
427    type Output = [T];
428    #[inline]
429    fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
430        &self.0[index]
431    }
432}
433
434impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeToInclusive<usize>>
435    for Array<T, LEN, REVERSE_STR>
436{
437    type Output = [T];
438    #[inline]
439    fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
440        &self.0[index]
441    }
442}
443
444impl<T, const LEN: usize, const REVERSE_STR: bool> Index<RangeFull> for Array<T, LEN, REVERSE_STR> {
445    type Output = [T];
446    #[inline]
447    fn index(&self, index: RangeFull) -> &Self::Output {
448        &self.0[index]
449    }
450}
451
452impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<usize> for Array<T, LEN, REVERSE_STR> {
453    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
454        &mut self.0[index]
455    }
456}
457
458impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<Range<usize>>
459    for Array<T, LEN, REVERSE_STR>
460{
461    #[inline]
462    fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
463        &mut self.0[index]
464    }
465}
466
467impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeTo<usize>>
468    for Array<T, LEN, REVERSE_STR>
469{
470    #[inline]
471    fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
472        &mut self.0[index]
473    }
474}
475
476impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeFrom<usize>>
477    for Array<T, LEN, REVERSE_STR>
478{
479    #[inline]
480    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
481        &mut self.0[index]
482    }
483}
484
485impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeInclusive<usize>>
486    for Array<T, LEN, REVERSE_STR>
487{
488    #[inline]
489    fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
490        &mut self.0[index]
491    }
492}
493
494impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeToInclusive<usize>>
495    for Array<T, LEN, REVERSE_STR>
496{
497    #[inline]
498    fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
499        &mut self.0[index]
500    }
501}
502
503impl<T, const LEN: usize, const REVERSE_STR: bool> IndexMut<RangeFull>
504    for Array<T, LEN, REVERSE_STR>
505{
506    #[inline]
507    fn index_mut(&mut self, index: RangeFull) -> &mut Self::Output {
508        &mut self.0[index]
509    }
510}
511
512impl<T, const LEN: usize, const REVERSE_STR: bool> IntoIterator for Array<T, LEN, REVERSE_STR> {
513    type Item = T;
514    type IntoIter = array::IntoIter<T, LEN>;
515
516    fn into_iter(self) -> Self::IntoIter {
517        self.0.into_iter()
518    }
519}
520
521impl<T, const LEN: usize, const REVERSE_STR: bool> From<T> for Array<T, LEN, REVERSE_STR>
522where
523    T: Into<[T; LEN]>,
524{
525    fn from(array: T) -> Self {
526        Self(array.into())
527    }
528}
529
530impl<T, const LEN: usize, const REVERSE_STR: bool> Wrapper for Array<T, LEN, REVERSE_STR> {
531    type Inner = [T; LEN];
532
533    #[inline]
534    fn from_inner(inner: Self::Inner) -> Self {
535        Self(inner)
536    }
537
538    #[inline]
539    fn as_inner(&self) -> &Self::Inner {
540        &self.0
541    }
542
543    #[inline]
544    fn into_inner(self) -> Self::Inner {
545        self.0
546    }
547}
548
549impl<T, const LEN: usize, const REVERSE_STR: bool> WrapperMut for Array<T, LEN, REVERSE_STR> {
550    fn as_inner_mut(&mut self) -> &mut Self::Inner {
551        &mut self.0
552    }
553}
554
555#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
556impl<const LEN: usize, const REVERSE_STR: bool> Display for Array<u8, LEN, REVERSE_STR> {
557    #[inline]
558    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
559        LowerHex::fmt(self, f)
560    }
561}
562
563#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
564impl<const LEN: usize, const REVERSE_STR: bool> Debug for Array<u8, LEN, REVERSE_STR> {
565    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
566        write!(f, "Array<{}>({})", LEN, self.to_hex())
567    }
568}
569
570#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
571impl<const LEN: usize, const REVERSE_STR: bool> FromStr for Array<u8, LEN, REVERSE_STR> {
572    type Err = hex::Error;
573
574    fn from_str(s: &str) -> Result<Self, Self::Err> {
575        Self::from_hex(s)
576    }
577}
578
579#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
580impl<const LEN: usize, const REVERSE_STR: bool> FromHex for Array<u8, LEN, REVERSE_STR> {
581    fn from_byte_iter<I>(iter: I) -> Result<Self, hex::Error>
582    where
583        I: Iterator<Item = Result<u8, hex::Error>> + ExactSizeIterator + DoubleEndedIterator,
584    {
585        let mut vec = Vec::<u8>::from_byte_iter(iter)?;
586        if REVERSE_STR {
587            vec.reverse();
588        }
589        if vec.len() != LEN {
590            return Err(hex::Error::InvalidLength(LEN, vec.len()));
591        }
592        let mut id = [0u8; LEN];
593        id.copy_from_slice(&vec);
594        Ok(Array(id))
595    }
596}
597
598#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
599impl<const LEN: usize, const REVERSE_STR: bool> LowerHex for Array<u8, LEN, REVERSE_STR> {
600    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
601        let mut slice = self.into_inner();
602        if REVERSE_STR {
603            slice.reverse();
604        }
605        if f.alternate() {
606            write!(
607                f,
608                "{}..{}",
609                slice[..4].to_hex(),
610                slice[(slice.len() - 4)..].to_hex()
611            )
612        } else {
613            f.write_str(&slice.to_hex())
614        }
615    }
616}
617
618#[cfg(all(feature = "hex", any(feature = "std", feature = "alloc")))]
619impl<const LEN: usize, const REVERSE_STR: bool> UpperHex for Array<u8, LEN, REVERSE_STR> {
620    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
621        let mut slice = self.into_inner();
622        if REVERSE_STR {
623            slice.reverse();
624        }
625        if f.alternate() {
626            write!(
627                f,
628                "{}..{}",
629                slice[..4].to_hex().to_ascii_uppercase(),
630                slice[(slice.len() - 4)..].to_hex().to_ascii_uppercase()
631            )
632        } else {
633            f.write_str(&slice.to_hex().to_ascii_uppercase())
634        }
635    }
636}
637
638#[cfg(all(feature = "serde", feature = "hex"))]
639pub(crate) mod serde_helpers {
640    //! Serde serialization helpers
641
642    use core::fmt;
643    use serde::{Deserialize, Deserializer, Serializer, Serialize};
644    use serde_crate::de::{SeqAccess, Visitor};
645    use serde_crate::ser::SerializeTuple;
646
647    use crate::Array;
648    use crate::hex::{FromHex, ToHex};
649
650    impl<const LEN: usize, const REVERSE_STR: bool> Serialize for Array<u8, LEN, REVERSE_STR> {
651        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
652        where
653            S: Serializer,
654        {
655            if serializer.is_human_readable() {
656                serializer.serialize_str(&self.to_hex())
657            } else {
658                let mut ser = serializer.serialize_tuple(LEN)?;
659                for i in 0..LEN {
660                    ser.serialize_element(&self.0[i])?;
661                }
662                ser.end()
663            }
664        }
665    }
666
667    impl<'de, const LEN: usize, const REVERSE_STR: bool> Deserialize<'de>
668        for Array<u8, LEN, REVERSE_STR>
669    {
670        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
671        where
672            D: Deserializer<'de>,
673        {
674            use serde::de::Error;
675            if deserializer.is_human_readable() {
676                String::deserialize(deserializer).and_then(|string| {
677                    Self::from_hex(&string).map_err(|_| D::Error::custom("wrong hex data"))
678                })
679            } else {
680                struct ArrayVisitor<const LEN: usize>;
681
682                impl<'de, const LEN: usize> Visitor<'de> for ArrayVisitor<LEN> {
683                    type Value = [u8; LEN];
684
685                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
686                        write!(formatter, "an array of length {LEN}")
687                    }
688
689                    fn visit_seq<A>(self, mut seq: A) -> Result<[u8; LEN], A::Error>
690                    where
691                        A: SeqAccess<'de>,
692                    {
693                        let mut arr = [0; LEN];
694                        for (i, el) in arr.iter_mut().enumerate() {
695                            *el = seq
696                                .next_element()?
697                                .ok_or_else(|| Error::invalid_length(i, &self))?;
698                        }
699                        Ok(arr)
700                    }
701                }
702
703                deserializer.deserialize_tuple(LEN, ArrayVisitor).map(Self)
704            }
705        }
706    }
707}
708
709/// Trait which does a blanket implementation for all types wrapping [`Array`]s
710#[deprecated(since = "4.2.0", note = "use ByteArray instead")]
711pub trait RawArray<const LEN: usize>: Sized {
712    /// Constructs a wrapper type around an array.
713    fn from_raw_array(val: impl Into<[u8; LEN]>) -> Self;
714
715    /// Returns a raw array representation stored in the wrapped type.
716    fn to_raw_array(&self) -> [u8; LEN];
717}
718
719#[allow(deprecated)]
720impl<Id, const LEN: usize, const REVERSE_STR: bool> RawArray<LEN> for Id
721where
722    Id: Wrapper<Inner = Array<u8, LEN, REVERSE_STR>>,
723{
724    fn from_raw_array(val: impl Into<[u8; LEN]>) -> Self {
725        Self::from_inner(Array::from_inner(val.into()))
726    }
727
728    fn to_raw_array(&self) -> [u8; LEN] {
729        self.as_inner().into_inner()
730    }
731}
732
733/// Trait which does a blanket implementation for all types wrapping [`Array`]s
734pub trait ByteArray<const LEN: usize>: Sized {
735    /// Constructs a wrapper type around a byte array.
736    fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self;
737
738    /// Constructs a byte array from the slice. Errors if the slice length
739    /// doesn't match `LEN` constant generic.
740    fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError>;
741
742    /// Constructs a byte array from the slice. Expects the slice length
743    /// doesn't match `LEN` constant generic.
744    ///
745    /// # Safety
746    ///
747    /// Panics if the slice length doesn't match `LEN` constant generic.
748    #[deprecated(since = "4.9.0", note = "use from_slice_unsafe instead")]
749    fn from_slice_unsafe(slice: impl AsRef<[u8]>) -> Self {
750        Self::from_slice_checked(slice)
751    }
752
753    /// Constructs a byte array from the slice. Expects the slice length
754    /// doesn't match `LEN` constant generic.
755    ///
756    /// # Safety
757    ///
758    /// Panics if the slice length doesn't match `LEN` constant generic.
759    fn from_slice_checked(slice: impl AsRef<[u8]>) -> Self {
760        Self::from_slice(slice).expect("slice length not matching type requirements")
761    }
762
763    /// Returns a byte array representation stored in the wrapped type.
764    fn to_byte_array(&self) -> [u8; LEN];
765}
766
767impl<Id, const LEN: usize, const REVERSE_STR: bool> ByteArray<LEN> for Id
768where
769    Id: Wrapper<Inner = Array<u8, LEN, REVERSE_STR>>,
770{
771    fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self {
772        Self::from_inner(Array::from_inner(val.into()))
773    }
774
775    fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError> {
776        Array::try_from(slice.as_ref()).map(Self::from_inner)
777    }
778
779    fn to_byte_array(&self) -> [u8; LEN] {
780        self.as_inner().into_inner()
781    }
782}
783
784#[cfg(test)]
785mod test {
786    use core::str::FromStr;
787
788    use super::*;
789    use crate::Wrapper;
790    use crate::hex::FromHex;
791
792    #[test]
793    fn test_slice32_str() {
794        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
795        let slice32 = Bytes32::from_hex(s).unwrap();
796
797        assert_eq!(slice32[0], 0xa3);
798
799        assert_eq!(Bytes32::from_str(s), Ok(slice32));
800
801        assert_eq!(Bytes32::from_hex(&s.to_uppercase()), Ok(slice32));
802        assert_eq!(
803            Bytes32::from_str(&s[..30]),
804            Err(hex::Error::InvalidLength(32, 15))
805        );
806
807        assert_eq!(&slice32.to_string(), s);
808        assert_eq!(format!("{:x}", slice32), s);
809        assert_eq!(format!("{:X}", slice32), s.to_uppercase());
810        assert_eq!(format!("{:?}", slice32), format!("Array<32>({})", s));
811
812        #[cfg(feature = "serde")]
813        {
814            assert_eq!(
815                serde_json::to_string(&slice32).unwrap(),
816                format!(r#""{s}""#)
817            );
818            assert_eq!(
819                serde_json::from_str::<Bytes32>(&format!(r#""{s}""#)).unwrap(),
820                slice32
821            );
822        }
823    }
824
825    #[test]
826    fn test_slice32_rev_str() {
827        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
828        let slice32 = Bytes32StrRev::from_hex(s).unwrap();
829
830        assert_eq!(slice32[0], 0x53);
831
832        assert_eq!(Bytes32StrRev::from_str(s), Ok(slice32));
833
834        assert_eq!(Bytes32StrRev::from_hex(&s.to_uppercase()), Ok(slice32));
835        assert_eq!(
836            Bytes32StrRev::from_str(&s[..30]),
837            Err(hex::Error::InvalidLength(32, 15))
838        );
839
840        assert_eq!(&slice32.to_string(), s);
841        assert_eq!(format!("{:x}", slice32), s);
842        assert_eq!(format!("{:X}", slice32), s.to_uppercase());
843        assert_eq!(format!("{:?}", slice32), format!("Array<32>({})", s));
844
845        #[cfg(feature = "serde")]
846        {
847            assert_eq!(
848                serde_json::to_string(&slice32).unwrap(),
849                format!(r#""{s}""#)
850            );
851            assert_eq!(
852                serde_json::from_str::<Bytes32StrRev>(&format!(r#""{s}""#)).unwrap(),
853                slice32
854            );
855        }
856    }
857
858    #[test]
859    fn test_encoding() {
860        let s = "a3401bcceb26201b55978ff705fecf7d8a0a03598ebeccf2a947030b91a0ff53";
861        let slice32 = Array::from_hex(s).unwrap();
862
863        let data = [
864            0xa3, 0x40, 0x1b, 0xcc, 0xeb, 0x26, 0x20, 0x1b, 0x55, 0x97, 0x8f, 0xf7, 0x05, 0xfe,
865            0xcf, 0x7d, 0x8a, 0x0a, 0x03, 0x59, 0x8e, 0xbe, 0xcc, 0xf2, 0xa9, 0x47, 0x03, 0x0b,
866            0x91, 0xa0, 0xff, 0x53,
867        ];
868
869        assert_eq!(Bytes32::copy_from_slice(data), Ok(slice32));
870        assert_eq!(
871            Bytes32::copy_from_slice(&data[..30]),
872            Err(FromSliceError {
873                actual: 30,
874                expected: 32
875            })
876        );
877        assert_eq!(&slice32.to_vec(), &data);
878        assert_eq!(&slice32.as_inner()[..], &data);
879        assert_eq!(slice32.to_inner(), data);
880        assert_eq!(slice32.into_inner(), data);
881    }
882}