Skip to main content

reifydb_type/value/blob/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	fmt,
6	fmt::{Display, Formatter},
7	ops::Deref,
8};
9
10use serde::{Deserialize, Serialize};
11
12use crate::util;
13
14pub mod base58;
15pub mod base64;
16pub mod hex;
17pub mod utf8;
18
19#[repr(transparent)]
20#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
21pub struct Blob(Vec<u8>);
22
23impl Blob {
24	pub fn new(bytes: Vec<u8>) -> Self {
25		Self(bytes)
26	}
27
28	pub fn empty() -> Self {
29		Self(Vec::with_capacity(0))
30	}
31
32	pub fn from_slice(bytes: &[u8]) -> Self {
33		Self(bytes.to_vec())
34	}
35
36	pub fn as_bytes(&self) -> &[u8] {
37		&self.0
38	}
39
40	pub fn len(&self) -> usize {
41		self.0.len()
42	}
43
44	pub fn is_empty(&self) -> bool {
45		self.0.is_empty()
46	}
47
48	pub fn into_bytes(self) -> Vec<u8> {
49		self.0.to_vec()
50	}
51}
52
53impl Deref for Blob {
54	type Target = [u8];
55
56	fn deref(&self) -> &Self::Target {
57		&self.0
58	}
59}
60
61impl From<Vec<u8>> for Blob {
62	fn from(bytes: Vec<u8>) -> Self {
63		Self::new(bytes)
64	}
65}
66
67impl From<&[u8]> for Blob {
68	fn from(bytes: &[u8]) -> Self {
69		Self::from_slice(bytes)
70	}
71}
72
73impl From<Blob> for Vec<u8> {
74	fn from(blob: Blob) -> Self {
75		blob.into_bytes()
76	}
77}
78
79impl Display for Blob {
80	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
81		write!(f, "0x{}", util::hex::encode(self.as_bytes()))
82	}
83}
84
85#[cfg(test)]
86pub mod tests {
87	use super::*;
88
89	#[test]
90	fn test_blob_from_bytes() {
91		let data = vec![0xDE, 0xAD, 0xBE, 0xEF];
92		let blob = Blob::new(data.clone());
93		assert_eq!(blob.as_bytes(), &data);
94		assert_eq!(blob.len(), 4);
95		assert!(!blob.is_empty());
96	}
97
98	#[test]
99	fn test_blob_from_slice() {
100		let data = [0xCA, 0xFE, 0xBA, 0xBE];
101		let blob = Blob::from_slice(&data);
102		assert_eq!(blob.as_bytes(), &data);
103	}
104
105	#[test]
106	fn test_blob_deref() {
107		let blob = Blob::new(vec![1, 2, 3]);
108		let bytes: &[u8] = &blob;
109		assert_eq!(bytes, &[1, 2, 3]);
110	}
111
112	#[test]
113	fn test_blob_conversions() {
114		let data = vec![0xFF, 0x00, 0xFF];
115		let blob = Blob::from(data.clone());
116		let bytes: Vec<u8> = blob.into();
117		assert_eq!(bytes, data);
118	}
119
120	#[test]
121	fn test_blob_display() {
122		let blob = Blob::new(vec![0xDE, 0xAD, 0xBE, 0xEF]);
123		assert_eq!(format!("{}", blob), "0xdeadbeef");
124
125		let empty_blob = Blob::new(vec![]);
126		assert_eq!(format!("{}", empty_blob), "0x");
127
128		let single_byte_blob = Blob::new(vec![0xFF]);
129		assert_eq!(format!("{}", single_byte_blob), "0xff");
130	}
131}