reifydb_type/value/blob/
hex.rs

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