1use crate::Hasher;
2use core::{
3 fmt,
4 ops::Deref,
5};
6pub use fuel_types::Bytes32;
7
8#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[repr(transparent)]
12pub struct Message(Bytes32);
13
14impl Message {
15 pub const LEN: usize = Bytes32::LEN;
17
18 pub fn new<M>(message: M) -> Self
21 where
22 M: AsRef<[u8]>,
23 {
24 Self(Hasher::hash(message))
25 }
26
27 pub fn from_bytes(bytes: [u8; Self::LEN]) -> Self {
32 Self(bytes.into())
33 }
34
35 pub fn from_bytes_ref(bytes: &[u8; Self::LEN]) -> &Self {
40 #[allow(unsafe_code)]
42 unsafe {
43 &*(bytes.as_ptr() as *const Self)
44 }
45 }
46
47 #[deprecated = "Use `Message::from_bytes` instead"]
49 pub fn from_bytes_unchecked(bytes: [u8; Self::LEN]) -> Self {
50 Self::from_bytes(bytes)
51 }
52}
53
54impl Deref for Message {
55 type Target = [u8; Message::LEN];
56
57 fn deref(&self) -> &[u8; Message::LEN] {
58 self.0.deref()
59 }
60}
61
62impl AsRef<[u8]> for Message {
63 fn as_ref(&self) -> &[u8] {
64 self.0.as_ref()
65 }
66}
67
68impl From<Message> for [u8; Message::LEN] {
69 fn from(message: Message) -> [u8; Message::LEN] {
70 message.0.into()
71 }
72}
73
74impl From<Message> for Bytes32 {
75 fn from(s: Message) -> Self {
76 s.0
77 }
78}
79
80impl From<&Hasher> for Message {
81 fn from(hasher: &Hasher) -> Self {
82 Self::from_bytes(*hasher.digest())
84 }
85}
86
87impl From<Hasher> for Message {
88 fn from(hasher: Hasher) -> Self {
89 Self::from_bytes(*hasher.finalize())
91 }
92}
93
94impl fmt::LowerHex for Message {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 self.0.fmt(f)
97 }
98}
99
100impl fmt::UpperHex for Message {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 self.0.fmt(f)
103 }
104}
105
106impl fmt::Debug for Message {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 self.0.fmt(f)
109 }
110}
111
112impl fmt::Display for Message {
113 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114 self.0.fmt(f)
115 }
116}
117
118#[cfg(feature = "std")]
119impl From<&Message> for secp256k1::Message {
120 fn from(message: &Message) -> Self {
121 secp256k1::Message::from_digest_slice(&*message.0).expect("length always matches")
122 }
123}