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
24pub struct AnyValue {
25    pub(crate) kind: AnyValueKind,
26    pub(crate) type_info: AnyTypeInfo,
27}
28
29pub(crate) enum AnyValueKind {
30    #[cfg(feature = "postgres")]
31    Postgres(PgValue),
32
33    #[cfg(feature = "mysql")]
34    MySql(MySqlValue),
35
36    #[cfg(feature = "sqlite")]
37    Sqlite(SqliteValue),
38
39    #[cfg(feature = "mssql")]
40    Mssql(MssqlValue),
41}
42
43pub struct AnyValueRef<'r> {
44    pub(crate) kind: AnyValueRefKind<'r>,
45    pub(crate) type_info: AnyTypeInfo,
46}
47
48pub(crate) enum AnyValueRefKind<'r> {
49    #[cfg(feature = "postgres")]
50    Postgres(PgValueRef<'r>),
51
52    #[cfg(feature = "mysql")]
53    MySql(MySqlValueRef<'r>),
54
55    #[cfg(feature = "sqlite")]
56    Sqlite(SqliteValueRef<'r>),
57
58    #[cfg(feature = "mssql")]
59    Mssql(MssqlValueRef<'r>),
60}
61
62impl Value for AnyValue {
63    type Database = Any;
64
65    fn as_ref(&self) -> <Self::Database as HasValueRef<'_>>::ValueRef {
66        match &self.kind {
67            #[cfg(feature = "postgres")]
68            AnyValueKind::Postgres(value) => value.as_ref().into(),
69
70            #[cfg(feature = "mysql")]
71            AnyValueKind::MySql(value) => value.as_ref().into(),
72
73            #[cfg(feature = "sqlite")]
74            AnyValueKind::Sqlite(value) => value.as_ref().into(),
75
76            #[cfg(feature = "mssql")]
77            AnyValueKind::Mssql(value) => value.as_ref().into(),
78        }
79    }
80
81    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
82        Cow::Borrowed(&self.type_info)
83    }
84
85    fn is_null(&self) -> bool {
86        match &self.kind {
87            #[cfg(feature = "postgres")]
88            AnyValueKind::Postgres(value) => value.is_null(),
89
90            #[cfg(feature = "mysql")]
91            AnyValueKind::MySql(value) => value.is_null(),
92
93            #[cfg(feature = "sqlite")]
94            AnyValueKind::Sqlite(value) => value.is_null(),
95
96            #[cfg(feature = "mssql")]
97            AnyValueKind::Mssql(value) => value.is_null(),
98        }
99    }
100
101    fn try_decode<'r, T>(&'r self) -> Result<T, Error>
102    where
103        T: Decode<'r, Self::Database> + Type<Self::Database>,
104    {
105        if !self.is_null() {
106            let ty = self.type_info();
107
108            if !ty.is_null() && !T::compatible(&ty) {
109                return Err(Error::Decode(mismatched_types::<T>(&ty)));
110            }
111        }
112
113        self.try_decode_unchecked()
114    }
115}
116
117impl<'r> ValueRef<'r> for AnyValueRef<'r> {
118    type Database = Any;
119
120    fn to_owned(&self) -> AnyValue {
121        match &self.kind {
122            #[cfg(feature = "postgres")]
123            AnyValueRefKind::Postgres(value) => ValueRef::to_owned(value).into(),
124
125            #[cfg(feature = "mysql")]
126            AnyValueRefKind::MySql(value) => ValueRef::to_owned(value).into(),
127
128            #[cfg(feature = "sqlite")]
129            AnyValueRefKind::Sqlite(value) => ValueRef::to_owned(value).into(),
130
131            #[cfg(feature = "mssql")]
132            AnyValueRefKind::Mssql(value) => ValueRef::to_owned(value).into(),
133        }
134    }
135
136    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
137        Cow::Borrowed(&self.type_info)
138    }
139
140    fn is_null(&self) -> bool {
141        match &self.kind {
142            #[cfg(feature = "postgres")]
143            AnyValueRefKind::Postgres(value) => value.is_null(),
144
145            #[cfg(feature = "mysql")]
146            AnyValueRefKind::MySql(value) => value.is_null(),
147
148            #[cfg(feature = "sqlite")]
149            AnyValueRefKind::Sqlite(value) => value.is_null(),
150
151            #[cfg(feature = "mssql")]
152            AnyValueRefKind::Mssql(value) => value.is_null(),
153        }
154    }
155}