1use std::str::FromStr;
2
3use bytes::{Bytes, BytesMut};
4use nodecraft::CheapClone;
5
6use crate::DataRef;
7
8use super::{Data, DecodeError, EncodeError};
9
10#[derive(Debug, thiserror::Error)]
12#[error("the size of meta must between [0-512] bytes, got {0}")]
13pub struct LargeMeta(usize);
14
15#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
17#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
18#[cfg_attr(feature = "serde", serde(transparent))]
19pub struct Meta(Bytes);
20
21impl Default for Meta {
22 #[inline]
23 fn default() -> Self {
24 Self::empty()
25 }
26}
27
28impl CheapClone for Meta {}
29
30impl Meta {
31 pub const MAX_SIZE: usize = 512;
33
34 #[inline]
36 pub const fn empty() -> Meta {
37 Meta(Bytes::new())
38 }
39
40 #[inline]
42 pub const fn from_static_str(s: &'static str) -> Result<Self, LargeMeta> {
43 if s.len() > Self::MAX_SIZE {
44 return Err(LargeMeta(s.len()));
45 }
46 Ok(Self(Bytes::from_static(s.as_bytes())))
47 }
48
49 #[inline]
51 pub const fn from_static(s: &'static [u8]) -> Result<Self, LargeMeta> {
52 if s.len() > Self::MAX_SIZE {
53 return Err(LargeMeta(s.len()));
54 }
55 Ok(Self(Bytes::from_static(s)))
56 }
57
58 #[inline]
60 pub fn as_bytes(&self) -> &[u8] {
61 &self.0
62 }
63
64 #[inline]
66 pub fn is_empty(&self) -> bool {
67 self.0.is_empty()
68 }
69
70 #[inline]
72 pub fn len(&self) -> usize {
73 self.0.len()
74 }
75}
76
77impl AsRef<[u8]> for Meta {
78 fn as_ref(&self) -> &[u8] {
79 self.as_bytes()
80 }
81}
82
83impl core::ops::Deref for Meta {
84 type Target = [u8];
85
86 fn deref(&self) -> &Self::Target {
87 self.as_bytes()
88 }
89}
90
91impl core::cmp::PartialEq<[u8]> for Meta {
92 fn eq(&self, other: &[u8]) -> bool {
93 self.as_bytes().eq(other)
94 }
95}
96
97impl core::cmp::PartialEq<&[u8]> for Meta {
98 fn eq(&self, other: &&[u8]) -> bool {
99 self.as_bytes().eq(*other)
100 }
101}
102
103impl core::cmp::PartialEq<Bytes> for Meta {
104 fn eq(&self, other: &Bytes) -> bool {
105 self.as_bytes().eq(other.as_ref())
106 }
107}
108
109impl core::cmp::PartialEq<Vec<u8>> for Meta {
110 fn eq(&self, other: &Vec<u8>) -> bool {
111 self.as_bytes().eq(other.as_slice())
112 }
113}
114
115impl TryFrom<&str> for Meta {
116 type Error = LargeMeta;
117
118 fn try_from(s: &str) -> Result<Self, Self::Error> {
119 if s.len() > Self::MAX_SIZE {
120 return Err(LargeMeta(s.len()));
121 }
122 Ok(Self(Bytes::copy_from_slice(s.as_bytes())))
123 }
124}
125
126impl FromStr for Meta {
127 type Err = LargeMeta;
128
129 fn from_str(s: &str) -> Result<Self, Self::Err> {
130 Meta::try_from(s)
131 }
132}
133
134impl TryFrom<String> for Meta {
135 type Error = LargeMeta;
136
137 fn try_from(s: String) -> Result<Self, Self::Error> {
138 Meta::try_from(s.into_bytes())
139 }
140}
141
142impl TryFrom<Bytes> for Meta {
143 type Error = LargeMeta;
144
145 fn try_from(s: Bytes) -> Result<Self, Self::Error> {
146 if s.len() > Self::MAX_SIZE {
147 return Err(LargeMeta(s.len()));
148 }
149 Ok(Self(s))
150 }
151}
152
153impl TryFrom<Vec<u8>> for Meta {
154 type Error = LargeMeta;
155
156 fn try_from(s: Vec<u8>) -> Result<Self, Self::Error> {
157 Meta::try_from(Bytes::from(s))
158 }
159}
160
161impl TryFrom<&[u8]> for Meta {
162 type Error = LargeMeta;
163
164 fn try_from(s: &[u8]) -> Result<Self, Self::Error> {
165 if s.len() > Self::MAX_SIZE {
166 return Err(LargeMeta(s.len()));
167 }
168 Ok(Self(Bytes::copy_from_slice(s)))
169 }
170}
171
172impl TryFrom<&Bytes> for Meta {
173 type Error = LargeMeta;
174
175 fn try_from(s: &Bytes) -> Result<Self, Self::Error> {
176 if s.len() > Self::MAX_SIZE {
177 return Err(LargeMeta(s.len()));
178 }
179 Ok(Self(s.clone()))
180 }
181}
182
183impl TryFrom<BytesMut> for Meta {
184 type Error = LargeMeta;
185
186 fn try_from(s: BytesMut) -> Result<Self, Self::Error> {
187 if s.len() > Self::MAX_SIZE {
188 return Err(LargeMeta(s.len()));
189 }
190 Ok(Self(s.freeze()))
191 }
192}
193
194impl<'a> DataRef<'a, Meta> for &'a [u8] {
195 fn decode(src: &'a [u8]) -> Result<(usize, &'a [u8]), DecodeError> {
196 let len = src.len();
197 if len > Meta::MAX_SIZE {
198 return Err(DecodeError::custom(LargeMeta(len).to_string()));
199 }
200
201 Ok((len, src))
202 }
203}
204
205impl Data for Meta {
206 type Ref<'a> = &'a [u8];
207
208 fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
209 where
210 Self: Sized,
211 {
212 Ok(Self(Bytes::copy_from_slice(val)))
213 }
214
215 fn encoded_len(&self) -> usize {
216 self.len()
217 }
218
219 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
220 <Bytes as Data>::encode(&self.0, buf)
221 }
222}
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227
228 #[test]
229 fn test_try_from_string() {
230 let meta = Meta::try_from("hello".to_string()).unwrap();
231 assert_eq!(meta, Meta::from_static_str("hello").unwrap());
232 assert!(Meta::from_static([0; 513].as_slice()).is_err());
233 }
234
235 #[test]
236 fn test_try_from_bytes() {
237 let meta = Meta::try_from(Bytes::from("hello")).unwrap();
238 assert_eq!(meta, Bytes::from("hello"));
239
240 assert!(Meta::try_from(Bytes::from("a".repeat(513).into_bytes())).is_err());
241 }
242
243 #[test]
244 fn test_try_from_bytes_mut() {
245 let meta = Meta::try_from(BytesMut::from("hello")).unwrap();
246 assert_eq!(meta, "hello".as_bytes().to_vec());
247
248 assert!(Meta::try_from(BytesMut::from([0; 513].as_slice())).is_err());
249 }
250
251 #[test]
252 fn test_try_from_bytes_ref() {
253 let meta = Meta::try_from(&Bytes::from("hello")).unwrap();
254 assert_eq!(meta, "hello".as_bytes());
255
256 assert!(Meta::try_from(&Bytes::from("a".repeat(513).into_bytes())).is_err());
257 }
258
259 #[test]
260 fn test_default() {
261 let meta = Meta::default();
262 assert!(meta.is_empty());
263
264 assert_eq!(Meta::empty(), [].as_slice());
265 }
266}