reifydb-type 0.4.11

Core type system and value representations for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

use ::uuid::Uuid;

use crate::{
	error::{Error, TypeError},
	fragment::Fragment,
	value::{
		identity::IdentityId,
		uuid::{Uuid4, Uuid7},
	},
};

pub fn parse_uuid4(fragment: Fragment) -> Result<Uuid4, Error> {
	// Fragment is already owned, no conversion needed
	let value = fragment.text().trim();

	if let Ok(uuid) = Uuid::parse_str(value)
		&& uuid.get_version_num() == 4
	{
		return Ok(Uuid4(uuid));
	}
	Err(TypeError::InvalidUuid4Format {
		fragment,
	}
	.into())
}

pub fn parse_uuid7(fragment: Fragment) -> Result<Uuid7, Error> {
	// Fragment is already owned, no conversion needed
	let value = fragment.text().trim();
	if let Ok(uuid) = Uuid::parse_str(value)
		&& uuid.get_version_num() == 7
	{
		return Ok(Uuid7(uuid));
	}

	Err(TypeError::InvalidUuid7Format {
		fragment,
	}
	.into())
}

pub fn parse_identity_id(fragment: Fragment) -> Result<IdentityId, Error> {
	let uuid7 = parse_uuid7(fragment)?;
	Ok(IdentityId(uuid7))
}

#[cfg(test)]
pub mod tests {

	mod uuid4 {
		use crate::{fragment::Fragment, value::uuid::parse::parse_uuid4};

		#[test]
		fn test_valid_uuid4() {
			let uuid_str = "550e8400-e29b-41d4-a716-446655440000";
			let result = parse_uuid4(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 4);
		}

		#[test]
		fn test_valid_uuid4_uppercase() {
			let uuid_str = "550E8400-E29B-41D4-A716-446655440000";
			let result = parse_uuid4(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 4);
		}

		#[test]
		fn test_valid_uuid4_with_spaces() {
			let uuid_str = "  550e8400-e29b-41d4-a716-446655440000  ";
			let result = parse_uuid4(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 4);
		}

		#[test]
		fn test_invalid_uuid4_empty() {
			let result = parse_uuid4(Fragment::testing(""));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid4_whitespace() {
			let result = parse_uuid4(Fragment::testing("   "));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid4_format() {
			let result = parse_uuid4(Fragment::testing("not-a-uuid"));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid4_wrong_version() {
			// This is a UUID v1, should fail validation for v4
			let uuid_str = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
			let result = parse_uuid4(Fragment::testing(uuid_str));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid4_malformed() {
			let result = parse_uuid4(Fragment::testing("550e8400-e29b-41d4-a716"));
			assert!(result.is_err());
		}
	}

	mod uuid7 {
		use crate::{fragment::Fragment, value::uuid::parse::parse_uuid7};

		#[test]
		fn test_valid_uuid7() {
			let uuid_str = "017f22e2-79b0-7cc3-98c4-dc0c0c07398f";
			let result = parse_uuid7(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 7);
		}

		#[test]
		fn test_valid_uuid7_uppercase() {
			let uuid_str = "017F22E2-79B0-7CC3-98C4-DC0C0C07398F";
			let result = parse_uuid7(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 7);
		}

		#[test]
		fn test_valid_uuid7_with_spaces() {
			let uuid_str = "  017f22e2-79b0-7cc3-98c4-dc0c0c07398f  ";
			let result = parse_uuid7(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let uuid = result.unwrap();
			assert_eq!(uuid.get_version_num(), 7);
		}

		#[test]
		fn test_invalid_uuid7_empty() {
			let result = parse_uuid7(Fragment::testing(""));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid7_whitespace() {
			let result = parse_uuid7(Fragment::testing("   "));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid7_format() {
			let result = parse_uuid7(Fragment::testing("invalid-uuid"));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid7_wrong_version() {
			// This is a UUID v4, should fail validation for v7
			let uuid_str = "550e8400-e29b-41d4-a716-446655440000";
			let result = parse_uuid7(Fragment::testing(uuid_str));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_uuid7_malformed() {
			let result = parse_uuid7(Fragment::testing("017f22e2-79b0-7cc3"));
			assert!(result.is_err());
		}
	}

	mod identity_id {
		use crate::{fragment::Fragment, value::uuid::parse::parse_identity_id};

		#[test]
		fn test_valid_identity_id() {
			let uuid_str = "017f22e2-79b0-7cc3-98c4-dc0c0c07398f";
			let result = parse_identity_id(Fragment::testing(uuid_str));
			assert!(result.is_ok());
			let id = result.unwrap();
			assert_eq!(id.0.get_version_num(), 7);
		}

		#[test]
		fn test_valid_identity_id_uppercase() {
			let uuid_str = "017F22E2-79B0-7CC3-98C4-DC0C0C07398F";
			let result = parse_identity_id(Fragment::testing(uuid_str));
			assert!(result.is_ok());
		}

		#[test]
		fn test_valid_identity_id_with_spaces() {
			let uuid_str = "  017f22e2-79b0-7cc3-98c4-dc0c0c07398f  ";
			let result = parse_identity_id(Fragment::testing(uuid_str));
			assert!(result.is_ok());
		}

		#[test]
		fn test_invalid_identity_id_empty() {
			let result = parse_identity_id(Fragment::testing(""));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_identity_id_wrong_version() {
			// UUID v4 should fail - IdentityId requires v7
			let uuid_str = "550e8400-e29b-41d4-a716-446655440000";
			let result = parse_identity_id(Fragment::testing(uuid_str));
			assert!(result.is_err());
		}

		#[test]
		fn test_invalid_identity_id_malformed() {
			let result = parse_identity_id(Fragment::testing("not-a-uuid"));
			assert!(result.is_err());
		}
	}
}