sqlx-core-oldapi 0.6.53

Core of SQLx, the rust SQL toolkit. Not intended to be used directly.
Documentation
use std::borrow::Cow;

use crate::any::{Any, AnyTypeInfo};
use crate::database::HasValueRef;
use crate::decode::Decode;
use crate::error::mismatched_types;
use crate::type_info::TypeInfo;
use crate::types::Type;
use crate::value::{Value, ValueRef};

#[cfg(feature = "postgres")]
use crate::postgres::{PgValue, PgValueRef};

#[cfg(feature = "mysql")]
use crate::mysql::{MySqlValue, MySqlValueRef};

#[cfg(feature = "sqlite")]
use crate::sqlite::{SqliteValue, SqliteValueRef};

#[cfg(feature = "mssql")]
use crate::mssql::{MssqlValue, MssqlValueRef};

#[cfg(feature = "odbc")]
use crate::odbc::{OdbcValue, OdbcValueRef};

pub struct AnyValue {
    pub(crate) kind: AnyValueKind,
    pub(crate) type_info: AnyTypeInfo,
}

pub(crate) enum AnyValueKind {
    #[cfg(feature = "postgres")]
    Postgres(PgValue),

    #[cfg(feature = "mysql")]
    MySql(MySqlValue),

    #[cfg(feature = "sqlite")]
    Sqlite(SqliteValue),

    #[cfg(feature = "mssql")]
    Mssql(MssqlValue),

    #[cfg(feature = "odbc")]
    Odbc(OdbcValue),
}

pub struct AnyValueRef<'r> {
    pub(crate) kind: AnyValueRefKind<'r>,
    pub(crate) type_info: AnyTypeInfo,
}

pub(crate) enum AnyValueRefKind<'r> {
    #[cfg(feature = "postgres")]
    Postgres(PgValueRef<'r>),

    #[cfg(feature = "mysql")]
    MySql(MySqlValueRef<'r>),

    #[cfg(feature = "sqlite")]
    Sqlite(SqliteValueRef<'r>),

    #[cfg(feature = "mssql")]
    Mssql(MssqlValueRef<'r>),

    #[cfg(feature = "odbc")]
    Odbc(OdbcValueRef<'r>),
}

impl Value for AnyValue {
    type Database = Any;

    fn as_ref(&self) -> <Self::Database as HasValueRef<'_>>::ValueRef {
        match &self.kind {
            #[cfg(feature = "postgres")]
            AnyValueKind::Postgres(value) => value.as_ref().into(),

            #[cfg(feature = "mysql")]
            AnyValueKind::MySql(value) => value.as_ref().into(),

            #[cfg(feature = "sqlite")]
            AnyValueKind::Sqlite(value) => value.as_ref().into(),

            #[cfg(feature = "mssql")]
            AnyValueKind::Mssql(value) => value.as_ref().into(),

            #[cfg(feature = "odbc")]
            AnyValueKind::Odbc(value) => value.as_ref().into(),
        }
    }

    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
        Cow::Borrowed(&self.type_info)
    }

    fn is_null(&self) -> bool {
        match &self.kind {
            #[cfg(feature = "postgres")]
            AnyValueKind::Postgres(value) => value.is_null(),

            #[cfg(feature = "mysql")]
            AnyValueKind::MySql(value) => value.is_null(),

            #[cfg(feature = "sqlite")]
            AnyValueKind::Sqlite(value) => value.is_null(),

            #[cfg(feature = "mssql")]
            AnyValueKind::Mssql(value) => value.is_null(),

            #[cfg(feature = "odbc")]
            AnyValueKind::Odbc(value) => value.is_null(),
        }
    }

    fn try_decode<'r, T>(&'r self) -> crate::error::Result<T>
    where
        T: Decode<'r, Self::Database> + Type<Self::Database>,
    {
        if !self.is_null() {
            let ty = self.type_info();

            if !ty.is_null() && !T::compatible(&ty) {
                return Err(crate::error::Error::Decode(mismatched_types::<
                    Self::Database,
                    T,
                >(&ty)));
            }
        }

        self.try_decode_unchecked()
    }
}

impl<'r> ValueRef<'r> for AnyValueRef<'r> {
    type Database = Any;

    fn to_owned(&self) -> AnyValue {
        match &self.kind {
            #[cfg(feature = "postgres")]
            AnyValueRefKind::Postgres(value) => ValueRef::to_owned(value).into(),

            #[cfg(feature = "mysql")]
            AnyValueRefKind::MySql(value) => ValueRef::to_owned(value).into(),

            #[cfg(feature = "sqlite")]
            AnyValueRefKind::Sqlite(value) => ValueRef::to_owned(value).into(),

            #[cfg(feature = "mssql")]
            AnyValueRefKind::Mssql(value) => ValueRef::to_owned(value).into(),

            #[cfg(feature = "odbc")]
            AnyValueRefKind::Odbc(value) => ValueRef::to_owned(value).into(),
        }
    }

    fn type_info(&self) -> Cow<'_, AnyTypeInfo> {
        Cow::Borrowed(&self.type_info)
    }

    fn is_null(&self) -> bool {
        match &self.kind {
            #[cfg(feature = "postgres")]
            AnyValueRefKind::Postgres(value) => value.is_null(),

            #[cfg(feature = "mysql")]
            AnyValueRefKind::MySql(value) => value.is_null(),

            #[cfg(feature = "sqlite")]
            AnyValueRefKind::Sqlite(value) => value.is_null(),

            #[cfg(feature = "mssql")]
            AnyValueRefKind::Mssql(value) => value.is_null(),

            #[cfg(feature = "odbc")]
            AnyValueRefKind::Odbc(value) => value.is_null(),
        }
    }
}

macro_rules! impl_try_from_any_value_ref {
    ($(
        #[cfg(feature = $feature:literal)]
        $db_name:ident => $value_ref:ty,
    )*) => {
        $(
            #[cfg(feature = $feature)]
            impl<'r> TryFrom<AnyValueRef<'r>> for $value_ref {
                type Error = crate::error::Error;

                fn try_from(value: AnyValueRef<'r>) -> Result<Self, Self::Error> {
                    #[allow(unreachable_patterns)]
                    match value.kind {
                        AnyValueRefKind::$db_name(value) => Ok(value),
                        _ => Err(crate::error::Error::Configuration(
                            format!("Expected {}, got {:?}", stringify!($value_ref), value.type_info()).into(),
                        )),
                    }
                }
            }
        )*
    };
}

impl_try_from_any_value_ref! {
    #[cfg(feature = "postgres")]
    Postgres => PgValueRef<'r>,

    #[cfg(feature = "mysql")]
    MySql => MySqlValueRef<'r>,

    #[cfg(feature = "sqlite")]
    Sqlite => SqliteValueRef<'r>,

    #[cfg(feature = "mssql")]
    Mssql => MssqlValueRef<'r>,

    #[cfg(feature = "odbc")]
    Odbc => OdbcValueRef<'r>,
}