use core::fmt;
use crate::{Text, ValueType};
#[derive(Clone, PartialEq)]
pub struct Value<'stmt> {
kind: Kind<'stmt>,
}
impl<'stmt> Value<'stmt> {
#[inline]
pub(crate) fn kind(&self) -> &Kind<'stmt> {
&self.kind
}
}
#[derive(Clone, Copy, PartialEq)]
pub(crate) enum Kind<'stmt> {
Integer(i64),
Float(f64),
Text(&'stmt Text),
Blob(&'stmt [u8]),
}
impl<'stmt> Value<'stmt> {
#[inline]
pub const fn integer(value: i64) -> Self {
Self {
kind: Kind::Integer(value),
}
}
#[inline]
pub const fn float(value: f64) -> Self {
Self {
kind: Kind::Float(value),
}
}
#[inline]
pub fn text<T>(value: &'stmt T) -> Self
where
T: ?Sized + AsRef<Text>,
{
Self {
kind: Kind::Text(value.as_ref()),
}
}
#[inline]
pub const fn blob(value: &'stmt [u8]) -> Self {
Self {
kind: Kind::Blob(value),
}
}
#[inline]
pub const fn as_integer(&self) -> Option<i64> {
if let Kind::Integer(value) = self.kind {
return Some(value);
}
None
}
#[inline]
pub const fn as_float(&self) -> Option<f64> {
if let Kind::Float(value) = self.kind {
return Some(value);
}
None
}
#[inline]
pub const fn as_text(&self) -> Option<&'stmt Text> {
if let Kind::Text(value) = self.kind {
return Some(value);
}
None
}
#[inline]
pub const fn as_blob(&self) -> Option<&'stmt [u8]> {
if let Kind::Blob(value) = self.kind {
return Some(value);
}
None
}
#[inline]
pub const fn column_type(&self) -> ValueType {
match &self.kind {
Kind::Blob(_) => ValueType::BLOB,
Kind::Float(_) => ValueType::FLOAT,
Kind::Integer(_) => ValueType::INTEGER,
Kind::Text(_) => ValueType::TEXT,
}
}
}
impl fmt::Debug for Value<'_> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
Kind::Integer(value) => write!(f, "{value}"),
Kind::Float(value) => write!(f, "{value}"),
Kind::Text(value) => write!(f, "{value:?}"),
Kind::Blob(value) => {
write!(f, "b\"")?;
for byte in value {
write!(f, "\\x{:02x}", byte)?;
}
write!(f, "\"")
}
}
}
}