Skip to main content

reifydb_type/value/blob/
hex.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4use super::Blob;
5use crate::{
6	error::{BlobEncodingKind, Error, TypeError},
7	fragment::Fragment,
8	util::hex::{decode, encode},
9};
10
11impl Blob {
12	pub fn from_hex(fragment: Fragment) -> Result<Self, Error> {
13		let fragment = fragment;
14		let hex_str = fragment.text();
15		let clean_hex = if hex_str.starts_with("0x") || hex_str.starts_with("0X") {
16			&hex_str[2..]
17		} else {
18			hex_str
19		};
20
21		match decode(clean_hex) {
22			Ok(bytes) => Ok(Blob::new(bytes)),
23			Err(_) => Err(TypeError::BlobEncoding {
24				kind: BlobEncodingKind::InvalidHex,
25				message: format!("Invalid hexadecimal string: '{}'", fragment.text()),
26				fragment,
27			}
28			.into()),
29		}
30	}
31
32	pub fn to_hex(&self) -> String {
33		format!("0x{}", encode(self.as_bytes()))
34	}
35}
36
37#[cfg(test)]
38pub mod tests {
39	use super::*;
40	use crate::fragment::Fragment;
41
42	#[test]
43	fn test_from_hex() {
44		let blob = Blob::from_hex(Fragment::testing("48656c6c6f")).unwrap();
45		assert_eq!(blob.as_bytes(), b"Hello");
46	}
47
48	#[test]
49	fn test_from_hex_with_prefix() {
50		let blob = Blob::from_hex(Fragment::testing("0x48656c6c6f")).unwrap();
51		assert_eq!(blob.as_bytes(), b"Hello");
52
53		let blob = Blob::from_hex(Fragment::testing("0X48656c6c6f")).unwrap();
54		assert_eq!(blob.as_bytes(), b"Hello");
55	}
56
57	#[test]
58	fn test_from_hex_empty() {
59		let blob = Blob::from_hex(Fragment::testing("")).unwrap();
60		assert_eq!(blob.as_bytes(), b"");
61	}
62
63	#[test]
64	fn test_from_hex_invalid() {
65		let result = Blob::from_hex(Fragment::testing("xyz"));
66		assert!(result.is_err());
67
68		let result = Blob::from_hex(Fragment::testing("48656c6c6")); // odd length
69		assert!(result.is_err());
70	}
71
72	#[test]
73	fn test_to_hex() {
74		let blob = Blob::new(b"Hello".to_vec());
75		assert_eq!(blob.to_hex(), "0x48656c6c6f");
76	}
77
78	#[test]
79	fn test_hex_roundtrip() {
80		let original = b"Hello, World! \x00\x01\x02\xFF";
81		let blob = Blob::new(original.to_vec());
82		let hex_str = blob.to_hex();
83		let decoded = Blob::from_hex(Fragment::testing(&hex_str)).unwrap();
84		assert_eq!(decoded.as_bytes(), original);
85	}
86}