1#[derive(Clone, Debug, PartialEq)]
16pub struct Blob {
17 data: Vec<u8>,
18}
19
20impl Blob {
21 pub fn new(data: Vec<u8>) -> Self {
30 Self { data }
31 }
32
33 pub fn empty() -> Self {
37 Self { data: vec![] }
38 }
39
40 pub fn from_str(s: &str) -> Self {
49 Self {
50 data: s.as_bytes().to_vec(),
51 }
52 }
53
54 pub fn data(&self) -> &[u8] {
56 &self.data
57 }
58
59 pub fn size(&self) -> usize {
61 self.data.len()
62 }
63
64 pub fn is_empty(&self) -> bool {
66 self.data.is_empty()
67 }
68
69 pub fn as_str(&self) -> Option<&str> {
71 std::str::from_utf8(&self.data).ok()
72 }
73
74 pub fn into_inner(self) -> Vec<u8> {
76 self.data
77 }
78}
79
80impl From<Vec<u8>> for Blob {
81 fn from(data: Vec<u8>) -> Self {
82 Self::new(data)
83 }
84}
85
86impl From<&[u8]> for Blob {
87 fn from(data: &[u8]) -> Self {
88 Self::new(data.to_vec())
89 }
90}
91
92impl From<&str> for Blob {
93 fn from(s: &str) -> Self {
94 Self::from_str(s)
95 }
96}
97
98impl From<String> for Blob {
99 fn from(s: String) -> Self {
100 Self::new(s.into_bytes())
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn test_blob_new() {
110 let blob = Blob::new(vec![1, 2, 3]);
111 assert_eq!(blob.data(), &[1, 2, 3]);
112 assert_eq!(blob.size(), 3);
113 }
114
115 #[test]
116 fn test_blob_empty() {
117 let blob = Blob::empty();
118 assert!(blob.is_empty());
119 assert_eq!(blob.size(), 0);
120 }
121
122 #[test]
123 fn test_blob_from_str() {
124 let blob = Blob::from_str("hello world");
125 assert_eq!(blob.as_str(), Some("hello world"));
126 }
127
128 #[test]
129 fn test_blob_as_str_invalid_utf8() {
130 let blob = Blob::new(vec![0xff, 0xfe]);
131 assert_eq!(blob.as_str(), None);
132 }
133
134 #[test]
135 fn test_blob_from_conversions() {
136 let blob1: Blob = vec![1, 2, 3].into();
137 assert_eq!(blob1.size(), 3);
138
139 let blob2: Blob = "test".into();
140 assert_eq!(blob2.as_str(), Some("test"));
141
142 let blob3: Blob = String::from("test").into();
143 assert_eq!(blob3.as_str(), Some("test"));
144 }
145
146 #[test]
147 fn test_blob_into_inner() {
148 let blob = Blob::new(vec![1, 2, 3]);
149 let data = blob.into_inner();
150 assert_eq!(data, vec![1, 2, 3]);
151 }
152}