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::{Error, diagnostic::blob},
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(Error(blob::invalid_hex_string(fragment))),
24		}
25	}
26
27	pub fn to_hex(&self) -> String {
28		format!("0x{}", encode(self.as_bytes()))
29	}
30}
31
32#[cfg(test)]
33pub mod tests {
34	use super::*;
35	use crate::fragment::Fragment;
36
37	#[test]
38	fn test_from_hex() {
39		let blob = Blob::from_hex(Fragment::testing("48656c6c6f")).unwrap();
40		assert_eq!(blob.as_bytes(), b"Hello");
41	}
42
43	#[test]
44	fn test_from_hex_with_prefix() {
45		let blob = Blob::from_hex(Fragment::testing("0x48656c6c6f")).unwrap();
46		assert_eq!(blob.as_bytes(), b"Hello");
47
48		let blob = Blob::from_hex(Fragment::testing("0X48656c6c6f")).unwrap();
49		assert_eq!(blob.as_bytes(), b"Hello");
50	}
51
52	#[test]
53	fn test_from_hex_empty() {
54		let blob = Blob::from_hex(Fragment::testing("")).unwrap();
55		assert_eq!(blob.as_bytes(), b"");
56	}
57
58	#[test]
59	fn test_from_hex_invalid() {
60		let result = Blob::from_hex(Fragment::testing("xyz"));
61		assert!(result.is_err());
62
63		let result = Blob::from_hex(Fragment::testing("48656c6c6")); // odd length
64		assert!(result.is_err());
65	}
66
67	#[test]
68	fn test_to_hex() {
69		let blob = Blob::new(b"Hello".to_vec());
70		assert_eq!(blob.to_hex(), "0x48656c6c6f");
71	}
72
73	#[test]
74	fn test_hex_roundtrip() {
75		let original = b"Hello, World! \x00\x01\x02\xFF";
76		let blob = Blob::new(original.to_vec());
77		let hex_str = blob.to_hex();
78		let decoded = Blob::from_hex(Fragment::testing(&hex_str)).unwrap();
79		assert_eq!(decoded.as_bytes(), original);
80	}
81}