use std::borrow::Cow;
use sqlx_core::error::BoxDynError;
use sqlx_core::value::{Value, ValueRef};
use spg_embedded::Value as EngineValue;
use crate::database::Spg;
use crate::type_info::{Kind, SpgTypeInfo};
#[derive(Debug, Clone)]
pub struct SpgValue {
inner: EngineValue,
type_info: SpgTypeInfo,
}
impl SpgValue {
#[must_use]
pub fn new(inner: EngineValue, type_info: SpgTypeInfo) -> Self {
Self { inner, type_info }
}
#[must_use]
pub const fn engine(&self) -> &EngineValue {
&self.inner
}
}
impl Value for SpgValue {
type Database = Spg;
fn as_ref(&self) -> SpgValueRef<'_> {
SpgValueRef::new(&self.inner, self.type_info.clone())
}
fn type_info(&self) -> Cow<'_, SpgTypeInfo> {
Cow::Borrowed(&self.type_info)
}
fn is_null(&self) -> bool {
matches!(self.inner, EngineValue::Null)
}
}
#[derive(Debug, Clone)]
pub struct SpgValueRef<'r> {
inner: &'r EngineValue,
type_info: SpgTypeInfo,
}
impl<'r> SpgValueRef<'r> {
#[must_use]
pub fn new(inner: &'r EngineValue, type_info: SpgTypeInfo) -> Self {
Self { inner, type_info }
}
#[must_use]
pub const fn engine(&self) -> &'r EngineValue {
self.inner
}
#[must_use]
pub const fn kind(&self) -> Kind {
self.type_info.kind()
}
}
impl<'r> ValueRef<'r> for SpgValueRef<'r> {
type Database = Spg;
fn to_owned(&self) -> SpgValue {
SpgValue {
inner: self.inner.clone(),
type_info: self.type_info.clone(),
}
}
fn type_info(&self) -> Cow<'_, SpgTypeInfo> {
Cow::Borrowed(&self.type_info)
}
fn is_null(&self) -> bool {
matches!(self.inner, EngineValue::Null)
}
}
#[must_use]
#[allow(dead_code)]
pub fn engine_value_kind(v: &EngineValue) -> Kind {
match v {
EngineValue::Null => Kind::Null,
EngineValue::SmallInt(_) => Kind::SmallInt,
EngineValue::Int(_) => Kind::Int,
EngineValue::BigInt(_) => Kind::BigInt,
EngineValue::Bool(_) => Kind::Bool,
EngineValue::Text(_) => Kind::Text,
EngineValue::Bytes(_) => Kind::Bytes,
EngineValue::Float(_) => Kind::Float,
EngineValue::Date(_) => Kind::Date,
EngineValue::Timestamp(_) => Kind::Timestamp,
EngineValue::Json(_) => Kind::Json,
EngineValue::Uuid(_) => Kind::Uuid,
EngineValue::Numeric { .. } => Kind::Numeric,
EngineValue::Vector(_) | EngineValue::Sq8Vector(_) | EngineValue::HalfVector(_) => {
Kind::Vector
}
EngineValue::TsVector(_) => Kind::TsVector,
_ => Kind::Null,
}
}
#[allow(dead_code)]
fn _box_dyn_marker() -> Option<BoxDynError> {
None
}