1use std::borrow::Cow;
2
3pub mod de;
4pub mod ser;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum Data<'a> {
20 SimpleString(Cow<'a, str>),
21 Integer(i64),
22 BulkString(Cow<'a, [u8]>),
23 Array(Vec<Data<'a>>),
24 Null,
25}
26
27impl<'a> Data<'a> {
28 pub fn simple_string<T>(str: &'a T) -> Self
30 where
31 T: AsRef<str> + ?Sized,
32 {
33 Self::SimpleString(str.as_ref().into())
34 }
35
36 pub fn bulk_string<T>(bytes: &'a T) -> Self
38 where
39 T: AsRef<[u8]> + ?Sized,
40 {
41 Self::BulkString(bytes.as_ref().into())
42 }
43
44 pub fn into_owned(self) -> Data<'static> {
46 match self {
47 Self::SimpleString(str) => Data::SimpleString(str.into_owned().into()),
48 Self::Integer(int) => Data::Integer(int),
49 Self::BulkString(bytes) => Data::BulkString(bytes.into_owned().into()),
50 Self::Array(arr) => Data::Array(arr.into_iter().map(Data::into_owned).collect()),
51 Self::Null => Data::Null,
52 }
53 }
54
55 pub fn from_bytes_iter<I, B>(iter: I) -> Data<'a>
56 where
57 I: IntoIterator<Item = &'a B>,
58 B: 'a + AsRef<[u8]> + ?Sized,
59 {
60 Data::Array(iter.into_iter().map(Data::from_bytes).collect())
61 }
62
63 pub fn from_bytes<B>(bytes: &'a B) -> Data<'a>
64 where
65 B: 'a + AsRef<[u8]> + ?Sized,
66 {
67 Data::BulkString(bytes.as_ref().into())
68 }
69}
70
71impl<'a> From<&'a str> for Data<'a> {
72 fn from(str: &'a str) -> Self {
73 Data::SimpleString(str.into())
74 }
75}
76
77impl From<String> for Data<'_> {
78 fn from(str: String) -> Self {
79 Data::SimpleString(str.into())
80 }
81}
82
83impl From<i64> for Data<'_> {
84 fn from(i: i64) -> Self {
85 Data::Integer(i)
86 }
87}
88
89impl<'a, const N: usize> From<&'a [u8; N]> for Data<'a> {
90 fn from(bytes: &'a [u8; N]) -> Self {
91 Self::bulk_string(bytes)
92 }
93}
94
95impl<'a> From<&'a [u8]> for Data<'a> {
96 fn from(bytes: &'a [u8]) -> Self {
97 Self::BulkString(bytes.into())
98 }
99}
100
101impl From<Vec<u8>> for Data<'_> {
102 fn from(bytes: Vec<u8>) -> Self {
103 Self::BulkString(bytes.into())
104 }
105}
106
107impl<I> FromIterator<I> for Data<'_>
108where
109 Self: From<I>,
110{
111 fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
112 iter.into_iter()
113 .map(Data::from)
114 .collect::<Vec<Data>>()
115 .into()
116 }
117}
118
119impl<'a> From<Vec<Data<'a>>> for Data<'a> {
120 fn from(data: Vec<Data<'a>>) -> Self {
121 Self::Array(data)
122 }
123}
124
125impl From<()> for Data<'_> {
126 fn from(_: ()) -> Self {
127 Data::Null
128 }
129}
130
131impl PartialEq<str> for Data<'_> {
132 fn eq(&self, other: &str) -> bool {
133 matches!(self, Data::SimpleString(str) if str == other)
134 }
135}
136
137impl PartialEq<&str> for Data<'_> {
138 fn eq(&self, other: &&str) -> bool {
139 matches!(self, Data::SimpleString(str) if str == other)
140 }
141}
142
143impl PartialEq<[u8]> for Data<'_> {
144 fn eq(&self, other: &[u8]) -> bool {
145 matches!(self, Data::BulkString(bytes) if bytes.as_ref() == other)
146 }
147}
148
149impl PartialEq<&[u8]> for Data<'_> {
150 fn eq(&self, other: &&[u8]) -> bool {
151 matches!(self, Data::BulkString(bytes) if bytes == other)
152 }
153}
154
155impl<const N: usize> PartialEq<[u8; N]> for Data<'_> {
156 fn eq(&self, other: &[u8; N]) -> bool {
157 matches!(self, Data::BulkString(bytes) if bytes.as_ref() == other)
158 }
159}
160
161impl<const N: usize> PartialEq<&[u8; N]> for Data<'_> {
162 fn eq(&self, other: &&[u8; N]) -> bool {
163 matches!(self, Data::BulkString(bytes) if bytes.as_ref() == *other)
164 }
165}
166
167impl PartialEq<i64> for Data<'_> {
168 fn eq(&self, other: &i64) -> bool {
169 matches!(self, Data::Integer(i) if *i == *other)
170 }
171}
172
173impl PartialEq<()> for Data<'_> {
174 fn eq(&self, _: &()) -> bool {
175 matches!(self, Data::Null)
176 }
177}
178
179#[macro_export]
192macro_rules! array {
193 ($($items:expr),*) => {
194 $crate::Data::Array(vec![$($crate::Data::from($items)),*])
195 };
196}