1#[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#[derive(Copy, Clone, Eq, PartialEq, Debug)]
38pub struct FromSliceError {
39 pub expected: usize,
41 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
59pub type Bytes<const LEN: usize> = Array<u8, LEN>;
65
66pub type Bytes4 = Array<u8, 4>;
72
73pub type Bytes16 = Array<u8, 16>;
79
80pub type Bytes20 = Array<u8, 20>;
86
87pub type Bytes32 = Array<u8, 32>;
93
94pub type Bytes32StrRev = Array<u8, 32, true>;
100
101pub type Bytes64 = Array<u8, 64>;
107
108#[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 pub fn with_fill(val: T) -> Self
121 where
122 T: Copy,
123 {
124 Self([val; LEN])
125 }
126
127 pub const fn from_array(inner: [T; LEN]) -> Self {
129 Self(inner)
130 }
131
132 #[inline]
134 pub fn as_slice(&self) -> &[T] {
135 self.as_ref()
136 }
137
138 #[inline]
140 pub fn as_slice_mut(&mut self) -> &mut [T] {
141 self.as_mut()
142 }
143
144 #[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 pub fn iter(&self) -> slice::Iter<T> {
158 self.0.iter()
159 }
160
161 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 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 pub const fn zero() -> Self {
181 Self([0u8; LEN])
182 }
183
184 #[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 #[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 #[inline]
218 pub fn to_byte_array(&self) -> [u8; LEN] {
219 self.0
220 }
221
222 #[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 #[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 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 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#[deprecated(since = "4.2.0", note = "use ByteArray instead")]
711pub trait RawArray<const LEN: usize>: Sized {
712 fn from_raw_array(val: impl Into<[u8; LEN]>) -> Self;
714
715 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
733pub trait ByteArray<const LEN: usize>: Sized {
735 fn from_byte_array(val: impl Into<[u8; LEN]>) -> Self;
737
738 fn from_slice(slice: impl AsRef<[u8]>) -> Result<Self, FromSliceError>;
741
742 #[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 fn from_slice_checked(slice: impl AsRef<[u8]>) -> Self {
760 Self::from_slice(slice).expect("slice length not matching type requirements")
761 }
762
763 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}