reifydb_engine/expression/cast/
uuid.rs1use reifydb_core::value::column::data::ColumnData;
5use reifydb_type::{
6 error::{Error, TypeError},
7 fragment::{Fragment, LazyFragment},
8 value::{
9 container::{utf8::Utf8Container, uuid::UuidContainer},
10 r#type::Type,
11 uuid::{
12 Uuid4, Uuid7,
13 parse::{parse_uuid4, parse_uuid7},
14 },
15 },
16};
17
18use crate::{Result, error::CastError};
19
20pub fn to_uuid(data: &ColumnData, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
21 match data {
22 ColumnData::Utf8 {
23 container,
24 ..
25 } => from_text(container, target, lazy_fragment),
26 ColumnData::Uuid4(container) => from_uuid4(container, target, lazy_fragment),
27 ColumnData::Uuid7(container) => from_uuid7(container, target, lazy_fragment),
28 _ => {
29 let source_type = data.get_type();
30 Err(TypeError::UnsupportedCast {
31 from: source_type,
32 to: target,
33 fragment: lazy_fragment.fragment(),
34 }
35 .into())
36 }
37 }
38}
39
40#[inline]
41fn from_text(container: &Utf8Container, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
42 match target {
43 Type::Uuid4 => to_uuid4(container, lazy_fragment),
44 Type::Uuid7 => to_uuid7(container, lazy_fragment),
45 _ => {
46 let source_type = Type::Utf8;
47 Err(TypeError::UnsupportedCast {
48 from: source_type,
49 to: target,
50 fragment: lazy_fragment.fragment(),
51 }
52 .into())
53 }
54 }
55}
56
57macro_rules! impl_to_uuid {
58 ($fn_name:ident, $type:ty, $target_type:expr, $parse_fn:expr) => {
59 #[inline]
60 fn $fn_name(container: &Utf8Container, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
61 let mut out = ColumnData::with_capacity($target_type, container.len());
62 for idx in 0..container.len() {
63 if container.is_defined(idx) {
64 let val = &container[idx];
65 let temp_fragment = Fragment::internal(val.as_str());
66
67 let parsed = $parse_fn(temp_fragment).map_err(|mut e| {
68 let proper_fragment = lazy_fragment.fragment();
70
71 e.0.with_fragment(proper_fragment.clone());
74
75 Error::from(CastError::InvalidUuid {
77 fragment: proper_fragment,
78 target: $target_type,
79 cause: e.0,
80 })
81 })?;
82
83 out.push::<$type>(parsed);
84 } else {
85 out.push_none();
86 }
87 }
88 Ok(out)
89 }
90 };
91}
92
93impl_to_uuid!(to_uuid4, Uuid4, Type::Uuid4, parse_uuid4);
94impl_to_uuid!(to_uuid7, Uuid7, Type::Uuid7, parse_uuid7);
95
96#[inline]
97fn from_uuid4(container: &UuidContainer<Uuid4>, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
98 match target {
99 Type::Uuid4 => Ok(ColumnData::Uuid4(UuidContainer::new(container.data().to_vec()))),
100 _ => {
101 let source_type = Type::Uuid4;
102 Err(TypeError::UnsupportedCast {
103 from: source_type,
104 to: target,
105 fragment: lazy_fragment.fragment(),
106 }
107 .into())
108 }
109 }
110}
111
112#[inline]
113fn from_uuid7(container: &UuidContainer<Uuid7>, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
114 match target {
115 Type::Uuid7 => Ok(ColumnData::Uuid7(UuidContainer::new(container.data().to_vec()))),
116 _ => {
117 let source_type = Type::Uuid7;
118 Err(TypeError::UnsupportedCast {
119 from: source_type,
120 to: target,
121 fragment: lazy_fragment.fragment(),
122 }
123 .into())
124 }
125 }
126}