Skip to main content

reifydb_engine/expression/cast/
blob.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_core::value::column::data::ColumnData;
5use reifydb_type::{
6	error::TypeError,
7	fragment::{Fragment, LazyFragment},
8	value::{blob::Blob, r#type::Type},
9};
10
11use crate::Result;
12
13pub fn to_blob(data: &ColumnData, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
14	match data {
15		ColumnData::Utf8 {
16			container,
17			..
18		} => {
19			let mut out = ColumnData::with_capacity(Type::Blob, container.len());
20			for idx in 0..container.len() {
21				if container.is_defined(idx) {
22					let temp_fragment = Fragment::internal(container[idx].as_str());
23					out.push(Blob::from_utf8(temp_fragment));
24				} else {
25					out.push_none()
26				}
27			}
28			Ok(out)
29		}
30		_ => {
31			let from = data.get_type();
32			Err(TypeError::UnsupportedCast {
33				from,
34				to: Type::Blob,
35				fragment: lazy_fragment.fragment(),
36			}
37			.into())
38		}
39	}
40}
41
42#[cfg(test)]
43pub mod tests {
44	use reifydb_type::{fragment::Fragment, util::bitvec::BitVec};
45
46	use super::*;
47
48	#[test]
49	fn test_from_utf8() {
50		let strings = vec!["Hello".to_string(), "World".to_string()];
51		let bitvec = BitVec::repeat(2, true);
52		let container = ColumnData::utf8_with_bitvec(strings, bitvec);
53
54		let result = to_blob(&container, || Fragment::testing_empty()).unwrap();
55
56		match result {
57			ColumnData::Blob {
58				container,
59				..
60			} => {
61				assert_eq!(container[0].as_bytes(), b"Hello");
62				assert_eq!(container[1].as_bytes(), b"World");
63			}
64			_ => panic!("Expected BLOB column data"),
65		}
66	}
67
68	#[test]
69	fn test_unsupported() {
70		let ints = vec![42i32];
71		let bitvec = BitVec::repeat(1, true);
72		let container = ColumnData::int4_with_bitvec(ints, bitvec);
73
74		let result = to_blob(&container, || Fragment::testing_empty());
75		assert!(result.is_err());
76	}
77}