diff --git a/docs/docs/core/data_types.mdx b/docs/docs/core/data_types.mdx index 01703bb5f..6cc67467e 100644 --- a/docs/docs/core/data_types.mdx +++ b/docs/docs/core/data_types.mdx @@ -24,6 +24,7 @@ This is the list of all basic types supported by CocoIndex: | float32 | `cocoindex.typing.Float32` |`float` | | float64 | `cocoindex.typing.Float64` |`float` | | range | `cocoindex.typing.Range` | `tuple[int, int]` | +| uuid | `uuid.UUId` | `uuid.UUID` | | vector[*type*, *N*?] |`Annotated[list[type], cocoindex.typing.Vector(dim=N)]` | `list[type]` | | json | `cocoindex.typing.Json` | Any type convertible to JSON by `json` package | @@ -73,6 +74,7 @@ Currently, the following types are supported as types for key fields: - `bool` - `int64` - `range` +- `uuid` - Struct with all fields being key types ### Vector Type diff --git a/python/cocoindex/convert.py b/python/cocoindex/convert.py index a368ee8cd..d8e8d0ba5 100644 --- a/python/cocoindex/convert.py +++ b/python/cocoindex/convert.py @@ -3,6 +3,7 @@ """ import dataclasses import inspect +import uuid from typing import Any, Callable from .typing import analyze_type_info, COLLECTION_TYPES @@ -13,6 +14,8 @@ def to_engine_value(value: Any) -> Any: return [to_engine_value(getattr(value, f.name)) for f in dataclasses.fields(value)] if isinstance(value, (list, tuple)): return [to_engine_value(v) for v in value] + if isinstance(value, uuid.UUID): + return value.bytes return value def make_engine_value_converter( @@ -62,6 +65,9 @@ def make_engine_value_converter( field_path.pop() return lambda value: [elem_converter(v) for v in value] if value is not None else None + if src_type_kind == 'Uuid': + return lambda value: uuid.UUID(bytes=value) + return lambda value: value def _make_engine_struct_value_converter( diff --git a/python/cocoindex/typing.py b/python/cocoindex/typing.py index a626d9046..2a17b702f 100644 --- a/python/cocoindex/typing.py +++ b/python/cocoindex/typing.py @@ -3,6 +3,7 @@ import dataclasses import types import inspect +import uuid from typing import Annotated, NamedTuple, Any, TypeVar, TYPE_CHECKING, overload class Vector(NamedTuple): @@ -130,6 +131,8 @@ def analyze_type_info(t) -> AnalyzedTypeInfo: kind = 'Int64' elif t is float: kind = 'Float64' + elif t is uuid.UUID: + kind = 'Uuid' else: raise ValueError(f"type unsupported yet: {t}") diff --git a/src/py/convert.rs b/src/py/convert.rs index 84d009695..02bf59dbb 100644 --- a/src/py/convert.rs +++ b/src/py/convert.rs @@ -63,17 +63,14 @@ fn basic_value_to_py_object<'py>( value::BasicValue::Int64(v) => v.into_bound_py_any(py)?, value::BasicValue::Float32(v) => v.into_bound_py_any(py)?, value::BasicValue::Float64(v) => v.into_bound_py_any(py)?, + value::BasicValue::Range(v) => pythonize(py, v).into_py_result()?, + value::BasicValue::Uuid(v) => v.as_bytes().into_bound_py_any(py)?, + value::BasicValue::Json(v) => pythonize(py, v).into_py_result()?, value::BasicValue::Vector(v) => v .iter() .map(|v| basic_value_to_py_object(py, v)) .collect::>>()? .into_bound_py_any(py)?, - _ => { - return Err(PyException::new_err(format!( - "unsupported value type: {}", - v.kind() - ))) - } }; Ok(result) } @@ -129,18 +126,19 @@ fn basic_value_from_py_object<'py>( schema::BasicValueType::Int64 => value::BasicValue::Int64(v.extract::()?), schema::BasicValueType::Float32 => value::BasicValue::Float32(v.extract::()?), schema::BasicValueType::Float64 => value::BasicValue::Float64(v.extract::()?), + schema::BasicValueType::Range => value::BasicValue::Range(depythonize(v)?), + schema::BasicValueType::Uuid => { + value::BasicValue::Uuid(uuid::Uuid::from_bytes(v.extract::()?)) + } + schema::BasicValueType::Json => { + value::BasicValue::Json(Arc::from(depythonize::(v)?)) + } schema::BasicValueType::Vector(elem) => value::BasicValue::Vector(Arc::from( v.extract::>>()? .into_iter() .map(|v| basic_value_from_py_object(&elem.element_type, &v)) .collect::>>()?, )), - _ => { - return Err(PyException::new_err(format!( - "unsupported value type: {}", - typ - ))) - } }; Ok(result) }