sqlx_core/any/
value.rs

1use std::borrow::Cow;
2
3use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind};
4use crate::database::Database;
5use crate::error::BoxDynError;
6use crate::types::Type;
7use crate::value::{Value, ValueRef};
8
9#[derive(Clone, Debug)]
10#[non_exhaustive]
11pub enum AnyValueKind<'a> {
12    Null(AnyTypeInfoKind),
13    Bool(bool),
14    SmallInt(i16),
15    Integer(i32),
16    BigInt(i64),
17    Real(f32),
18    Double(f64),
19    Text(Cow<'a, str>),
20    Blob(Cow<'a, [u8]>),
21}
22
23impl AnyValueKind<'_> {
24    fn type_info(&self) -> AnyTypeInfo {
25        AnyTypeInfo {
26            kind: match self {
27                AnyValueKind::Null(_) => AnyTypeInfoKind::Null,
28                AnyValueKind::Bool(_) => AnyTypeInfoKind::Bool,
29                AnyValueKind::SmallInt(_) => AnyTypeInfoKind::SmallInt,
30                AnyValueKind::Integer(_) => AnyTypeInfoKind::Integer,
31                AnyValueKind::BigInt(_) => AnyTypeInfoKind::BigInt,
32                AnyValueKind::Real(_) => AnyTypeInfoKind::Real,
33                AnyValueKind::Double(_) => AnyTypeInfoKind::Double,
34                AnyValueKind::Text(_) => AnyTypeInfoKind::Text,
35                AnyValueKind::Blob(_) => AnyTypeInfoKind::Blob,
36            },
37        }
38    }
39
40    pub(in crate::any) fn unexpected<Expected: Type<Any>>(&self) -> Result<Expected, BoxDynError> {
41        Err(format!("expected {}, got {:?}", Expected::type_info(), self).into())
42    }
43
44    pub(in crate::any) fn try_integer<T>(&self) -> Result<T, BoxDynError>
45    where
46        T: Type<Any> + TryFrom<i16> + TryFrom<i32> + TryFrom<i64>,
47        BoxDynError: From<<T as TryFrom<i16>>::Error>,
48        BoxDynError: From<<T as TryFrom<i32>>::Error>,
49        BoxDynError: From<<T as TryFrom<i64>>::Error>,
50    {
51        Ok(match self {
52            AnyValueKind::SmallInt(i) => (*i).try_into()?,
53            AnyValueKind::Integer(i) => (*i).try_into()?,
54            AnyValueKind::BigInt(i) => (*i).try_into()?,
55            _ => return self.unexpected(),
56        })
57    }
58}
59
60#[derive(Clone, Debug)]
61pub struct AnyValue {
62    #[doc(hidden)]
63    pub kind: AnyValueKind<'static>,
64}
65
66#[derive(Clone, Debug)]
67pub struct AnyValueRef<'a> {
68    pub(crate) kind: AnyValueKind<'a>,
69}
70
71impl Value for AnyValue {
72    type Database = Any;
73
74    fn as_ref(&self) -> <Self::Database as Database>::ValueRef<'_> {
75        AnyValueRef {
76            kind: match &self.kind {
77                AnyValueKind::Null(k) => AnyValueKind::Null(*k),
78                AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
79                AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
80                AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
81                AnyValueKind::BigInt(i) => AnyValueKind::BigInt(*i),
82                AnyValueKind::Real(r) => AnyValueKind::Real(*r),
83                AnyValueKind::Double(d) => AnyValueKind::Double(*d),
84                AnyValueKind::Text(t) => AnyValueKind::Text(Cow::Borrowed(t)),
85                AnyValueKind::Blob(b) => AnyValueKind::Blob(Cow::Borrowed(b)),
86            },
87        }
88    }
89
90    fn type_info(&self) -> Cow<'_, <Self::Database as Database>::TypeInfo> {
91        Cow::Owned(self.kind.type_info())
92    }
93
94    fn is_null(&self) -> bool {
95        matches!(self.kind, AnyValueKind::Null(_))
96    }
97}
98
99impl<'a> ValueRef<'a> for AnyValueRef<'a> {
100    type Database = Any;
101
102    fn to_owned(&self) -> <Self::Database as Database>::Value {
103        AnyValue {
104            kind: match &self.kind {
105                AnyValueKind::Null(k) => AnyValueKind::Null(*k),
106                AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
107                AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
108                AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
109                AnyValueKind::BigInt(i) => AnyValueKind::BigInt(*i),
110                AnyValueKind::Real(r) => AnyValueKind::Real(*r),
111                AnyValueKind::Double(d) => AnyValueKind::Double(*d),
112                AnyValueKind::Text(t) => AnyValueKind::Text(Cow::Owned(t.to_string())),
113                AnyValueKind::Blob(b) => AnyValueKind::Blob(Cow::Owned(b.to_vec())),
114            },
115        }
116    }
117
118    fn type_info(&self) -> Cow<'_, <Self::Database as Database>::TypeInfo> {
119        Cow::Owned(self.kind.type_info())
120    }
121
122    fn is_null(&self) -> bool {
123        matches!(self.kind, AnyValueKind::Null(_))
124    }
125}