sqlx_core_oldapi/any/
value.rs

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