sqlx_core_oldapi/any/
value.rs

1use std::borrow::Cow;
2
3use crate::any::{Any, AnyTypeInfo};
4use crate::database::HasValueRef;
5use crate::decode::Decode;
6use crate::error::mismatched_types;
7use crate::type_info::TypeInfo;
8use crate::types::Type;
9use crate::value::{Value, ValueRef};
10
11#[cfg(feature = "postgres")]
12use crate::postgres::{PgValue, PgValueRef};
13
14#[cfg(feature = "mysql")]
15use crate::mysql::{MySqlValue, MySqlValueRef};
16
17#[cfg(feature = "sqlite")]
18use crate::sqlite::{SqliteValue, SqliteValueRef};
19
20#[cfg(feature = "mssql")]
21use crate::mssql::{MssqlValue, MssqlValueRef};
22
23#[cfg(feature = "odbc")]
24use crate::odbc::{OdbcValue, OdbcValueRef};
25
26pub struct AnyValue {
27    pub(crate) kind: AnyValueKind,
28    pub(crate) type_info: AnyTypeInfo,
29}
30
31pub(crate) enum AnyValueKind {
32    #[cfg(feature = "postgres")]
33    Postgres(PgValue),
34
35    #[cfg(feature = "mysql")]
36    MySql(MySqlValue),
37
38    #[cfg(feature = "sqlite")]
39    Sqlite(SqliteValue),
40
41    #[cfg(feature = "mssql")]
42    Mssql(MssqlValue),
43
44    #[cfg(feature = "odbc")]
45    Odbc(OdbcValue),
46}
47
48pub struct AnyValueRef<'r> {
49    pub(crate) kind: AnyValueRefKind<'r>,
50    pub(crate) type_info: AnyTypeInfo,
51}
52
53pub(crate) enum AnyValueRefKind<'r> {
54    #[cfg(feature = "postgres")]
55    Postgres(PgValueRef<'r>),
56
57    #[cfg(feature = "mysql")]
58    MySql(MySqlValueRef<'r>),
59
60    #[cfg(feature = "sqlite")]
61    Sqlite(SqliteValueRef<'r>),
62
63    #[cfg(feature = "mssql")]
64    Mssql(MssqlValueRef<'r>),
65
66    #[cfg(feature = "odbc")]
67    Odbc(OdbcValueRef<'r>),
68}
69
70impl Value for AnyValue {
71    type Database = Any;
72
73    fn as_ref(&self) -> <Self::Database as HasValueRef<'_>>::ValueRef {
74        match &self.kind {
75            #[cfg(feature = "postgres")]
76            AnyValueKind::Postgres(value) => value.as_ref().into(),
77
78            #[cfg(feature = "mysql")]
79            AnyValueKind::MySql(value) => value.as_ref().into(),
80
81            #[cfg(feature = "sqlite")]
82            AnyValueKind::Sqlite(value) => value.as_ref().into(),
83
84            #[cfg(feature = "mssql")]
85            AnyValueKind::Mssql(value) => value.as_ref().into(),
86
87            #[cfg(feature = "odbc")]
88            AnyValueKind::Odbc(value) => value.as_ref().into(),
89        }
90    }
91
92    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
93        Cow::Borrowed(&self.type_info)
94    }
95
96    fn is_null(&self) -> bool {
97        match &self.kind {
98            #[cfg(feature = "postgres")]
99            AnyValueKind::Postgres(value) => value.is_null(),
100
101            #[cfg(feature = "mysql")]
102            AnyValueKind::MySql(value) => value.is_null(),
103
104            #[cfg(feature = "sqlite")]
105            AnyValueKind::Sqlite(value) => value.is_null(),
106
107            #[cfg(feature = "mssql")]
108            AnyValueKind::Mssql(value) => value.is_null(),
109
110            #[cfg(feature = "odbc")]
111            AnyValueKind::Odbc(value) => value.is_null(),
112        }
113    }
114
115    fn try_decode<'r, T>(&'r self) -> crate::error::Result<T>
116    where
117        T: Decode<'r, Self::Database> + Type<Self::Database>,
118    {
119        if !self.is_null() {
120            let ty = self.type_info();
121
122            if !ty.is_null() && !T::compatible(&ty) {
123                return Err(crate::error::Error::Decode(mismatched_types::<
124                    Self::Database,
125                    T,
126                >(&ty)));
127            }
128        }
129
130        self.try_decode_unchecked()
131    }
132}
133
134impl<'r> ValueRef<'r> for AnyValueRef<'r> {
135    type Database = Any;
136
137    fn to_owned(&self) -> AnyValue {
138        match &self.kind {
139            #[cfg(feature = "postgres")]
140            AnyValueRefKind::Postgres(value) => ValueRef::to_owned(value).into(),
141
142            #[cfg(feature = "mysql")]
143            AnyValueRefKind::MySql(value) => ValueRef::to_owned(value).into(),
144
145            #[cfg(feature = "sqlite")]
146            AnyValueRefKind::Sqlite(value) => ValueRef::to_owned(value).into(),
147
148            #[cfg(feature = "mssql")]
149            AnyValueRefKind::Mssql(value) => ValueRef::to_owned(value).into(),
150
151            #[cfg(feature = "odbc")]
152            AnyValueRefKind::Odbc(value) => ValueRef::to_owned(value).into(),
153        }
154    }
155
156    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
157        Cow::Borrowed(&self.type_info)
158    }
159
160    fn is_null(&self) -> bool {
161        match &self.kind {
162            #[cfg(feature = "postgres")]
163            AnyValueRefKind::Postgres(value) => value.is_null(),
164
165            #[cfg(feature = "mysql")]
166            AnyValueRefKind::MySql(value) => value.is_null(),
167
168            #[cfg(feature = "sqlite")]
169            AnyValueRefKind::Sqlite(value) => value.is_null(),
170
171            #[cfg(feature = "mssql")]
172            AnyValueRefKind::Mssql(value) => value.is_null(),
173
174            #[cfg(feature = "odbc")]
175            AnyValueRefKind::Odbc(value) => value.is_null(),
176        }
177    }
178}