reifydb-engine 0.4.12

Query execution and processing engine for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

use reifydb_core::value::column::data::ColumnData;
use reifydb_type::{
	error::{Error, TypeError},
	fragment::{Fragment, LazyFragment},
	value::{
		container::{identity_id::IdentityIdContainer, utf8::Utf8Container, uuid::UuidContainer},
		identity::IdentityId,
		r#type::Type,
		uuid::{
			Uuid4, Uuid7,
			parse::{parse_identity_id, parse_uuid4, parse_uuid7},
		},
	},
};

use crate::{Result, error::CastError};

pub fn to_uuid(data: &ColumnData, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
	match data {
		ColumnData::Utf8 {
			container,
			..
		} => from_text(container, target, lazy_fragment),
		ColumnData::Uuid4(container) => from_uuid4(container, target, lazy_fragment),
		ColumnData::Uuid7(container) => from_uuid7(container, target, lazy_fragment),
		ColumnData::IdentityId(container) => from_identity_id(container, target, lazy_fragment),
		_ => {
			let shape_type = data.get_type();
			Err(TypeError::UnsupportedCast {
				from: shape_type,
				to: target,
				fragment: lazy_fragment.fragment(),
			}
			.into())
		}
	}
}

#[inline]
fn from_text(container: &Utf8Container, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
	match target {
		Type::Uuid4 => to_uuid4(container, lazy_fragment),
		Type::Uuid7 => to_uuid7(container, lazy_fragment),
		Type::IdentityId => to_identity_id(container, lazy_fragment),
		_ => {
			let shape_type = Type::Utf8;
			Err(TypeError::UnsupportedCast {
				from: shape_type,
				to: target,
				fragment: lazy_fragment.fragment(),
			}
			.into())
		}
	}
}

macro_rules! impl_to_uuid {
	($fn_name:ident, $type:ty, $target_type:expr, $parse_fn:expr) => {
		#[inline]
		fn $fn_name(container: &Utf8Container, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
			let mut out = ColumnData::with_capacity($target_type, container.len());
			for idx in 0..container.len() {
				if container.is_defined(idx) {
					let val = &container[idx];
					let temp_fragment = Fragment::internal(val.as_str());

					let parsed = $parse_fn(temp_fragment).map_err(|mut e| {
						// Get the original fragment for error reporting
						let proper_fragment = lazy_fragment.fragment();

						// Replace the error's origin with the proper RQL fragment
						// This ensures the error shows "at col" not the actual value
						e.0.with_fragment(proper_fragment.clone());

						// Wrap in cast error with the original fragment
						Error::from(CastError::InvalidUuid {
							fragment: proper_fragment,
							target: $target_type,
							cause: *e.0,
						})
					})?;

					out.push::<$type>(parsed);
				} else {
					out.push_none();
				}
			}
			Ok(out)
		}
	};
}

impl_to_uuid!(to_uuid4, Uuid4, Type::Uuid4, parse_uuid4);
impl_to_uuid!(to_uuid7, Uuid7, Type::Uuid7, parse_uuid7);
impl_to_uuid!(to_identity_id, IdentityId, Type::IdentityId, parse_identity_id);

#[inline]
fn from_uuid4(container: &UuidContainer<Uuid4>, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
	match target {
		Type::Uuid4 => Ok(ColumnData::Uuid4(UuidContainer::new(container.data().to_vec()))),
		_ => {
			let shape_type = Type::Uuid4;
			Err(TypeError::UnsupportedCast {
				from: shape_type,
				to: target,
				fragment: lazy_fragment.fragment(),
			}
			.into())
		}
	}
}

#[inline]
fn from_uuid7(container: &UuidContainer<Uuid7>, target: Type, lazy_fragment: impl LazyFragment) -> Result<ColumnData> {
	match target {
		Type::Uuid7 => Ok(ColumnData::Uuid7(UuidContainer::new(container.data().to_vec()))),
		_ => {
			let shape_type = Type::Uuid7;
			Err(TypeError::UnsupportedCast {
				from: shape_type,
				to: target,
				fragment: lazy_fragment.fragment(),
			}
			.into())
		}
	}
}

#[inline]
fn from_identity_id(
	container: &IdentityIdContainer,
	target: Type,
	lazy_fragment: impl LazyFragment,
) -> Result<ColumnData> {
	match target {
		Type::IdentityId => {
			Ok(ColumnData::IdentityId(IdentityIdContainer::from_vec(container.data().to_vec())))
		}
		_ => Err(TypeError::UnsupportedCast {
			from: Type::IdentityId,
			to: target,
			fragment: lazy_fragment.fragment(),
		}
		.into()),
	}
}