use crate::TinyOrmError;
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SetOption<T> {
Set(T),
#[default]
NotSet,
}
impl<T> From<T> for SetOption<T> {
fn from(value: T) -> Self {
SetOption::Set(value)
}
}
impl<T> From<SetOption<T>> for Result<T, &'static str> {
fn from(value: SetOption<T>) -> Self {
match value {
SetOption::Set(value) => Ok(value),
SetOption::NotSet => Err("Cannot convert NotSet variant to value"),
}
}
}
impl<T> SetOption<T> {
pub fn inner(self) -> Option<T> {
match self {
SetOption::NotSet => None,
SetOption::Set(value) => Some(value),
}
}
pub fn value(self) -> Result<T, TinyOrmError> {
match self {
SetOption::NotSet => Err(TinyOrmError::SetOptionNotSet),
SetOption::Set(value) => Ok(value),
}
}
pub fn is_set(&self) -> bool {
match self {
SetOption::Set(_) => true,
SetOption::NotSet => false,
}
}
pub fn is_not_set(&self) -> bool {
match self {
SetOption::Set(_) => false,
SetOption::NotSet => true,
}
}
}
#[cfg(not(feature = "sqlx-0.7"))]
use sqlx::decode::Decode;
#[cfg(not(feature = "sqlx-0.7"))]
use sqlx::encode::IsNull;
#[cfg(not(feature = "sqlx-0.7"))]
use sqlx::error::BoxDynError;
#[cfg(not(feature = "sqlx-0.7"))]
use sqlx::{Database, Encode, Type, ValueRef};
#[cfg(not(feature = "sqlx-0.7"))]
impl<'r, DB, T> Decode<'r, DB> for SetOption<T>
where
DB: Database,
T: Decode<'r, DB>,
{
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(SetOption::NotSet);
}
Ok(SetOption::Set(T::decode(value)?))
}
}
#[cfg(not(feature = "sqlx-0.7"))]
impl<DB, T> Type<DB> for SetOption<T>
where
DB: Database,
T: Type<DB>,
{
fn type_info() -> <DB as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<DB as Database>::TypeInfo) -> bool {
T::compatible(ty)
}
}
#[cfg(not(feature = "sqlx-0.7"))]
impl<'q, T, DB: Database> Encode<'q, DB> for SetOption<T>
where
T: Encode<'q, DB>,
{
fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, BoxDynError> {
match self {
SetOption::Set(value) => value.encode(buf),
SetOption::NotSet => Ok(IsNull::Yes),
}
}
fn encode_by_ref(
&self,
buf: &mut <DB as Database>::ArgumentBuffer<'q>,
) -> Result<IsNull, BoxDynError> {
match self {
SetOption::Set(value) => value.encode_by_ref(buf),
SetOption::NotSet => Ok(IsNull::Yes),
}
}
fn produces(&self) -> Option<DB::TypeInfo> {
match self {
SetOption::Set(value) => value.produces(),
SetOption::NotSet => None,
}
}
fn size_hint(&self) -> usize {
match self {
SetOption::Set(value) => value.size_hint(),
SetOption::NotSet => 0,
}
}
}
#[cfg(feature = "sqlx-0.7")]
use sqlx::{encode::IsNull, error::BoxDynError, Database, ValueRef};
#[cfg(feature = "sqlx-0.7")]
impl<DB: Database, T> sqlx::Type<DB> for SetOption<T>
where
T: sqlx::Type<DB>,
{
fn type_info() -> <DB as Database>::TypeInfo {
T::type_info()
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "mysql"))]
use sqlx::{mysql::MySqlValueRef, MySql};
#[cfg(all(feature = "sqlx-0.7", feature = "postgres"))]
use sqlx::{
postgres::{PgArgumentBuffer, PgValueRef},
Postgres,
};
#[cfg(all(feature = "sqlx-0.7", feature = "sqlite"))]
use sqlx::{
sqlite::{SqliteArgumentValue, SqliteValueRef},
Sqlite,
};
#[cfg(all(feature = "sqlx-0.7", feature = "sqlite"))]
impl<'r, T> sqlx::Decode<'r, Sqlite> for SetOption<T>
where
T: sqlx::Decode<'r, Sqlite>,
{
fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(SetOption::NotSet);
}
let decoded = <T as sqlx::Decode<'r, Sqlite>>::decode(value)?;
Ok(SetOption::Set(decoded))
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "postgres"))]
impl<'r, T> sqlx::Decode<'r, Postgres> for SetOption<T>
where
T: sqlx::Decode<'r, Postgres>,
{
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(SetOption::NotSet);
}
let decoded = <T as sqlx::Decode<'r, Postgres>>::decode(value)?;
Ok(SetOption::Set(decoded))
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "mysql"))]
impl<'r, T> sqlx::Decode<'r, MySql> for SetOption<T>
where
T: sqlx::Decode<'r, MySql>,
{
fn decode(value: MySqlValueRef<'r>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(SetOption::NotSet);
}
let decoded = <T as sqlx::Decode<'r, MySql>>::decode(value)?;
Ok(SetOption::Set(decoded))
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "sqlite"))]
impl<'q, T> sqlx::Encode<'q, Sqlite> for SetOption<T>
where
T: sqlx::Encode<'q, Sqlite>,
{
fn encode_by_ref(&self, args: &mut Vec<SqliteArgumentValue<'q>>) -> IsNull {
match self {
SetOption::Set(value) => value.encode_by_ref(args),
SetOption::NotSet => IsNull::Yes,
}
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "postgres"))]
impl<'q, T> sqlx::Encode<'q, Postgres> for SetOption<T>
where
T: sqlx::Encode<'q, Postgres>,
{
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
match self {
SetOption::Set(value) => value.encode_by_ref(buf),
SetOption::NotSet => IsNull::Yes,
}
}
}
#[cfg(all(feature = "sqlx-0.7", feature = "mysql"))]
impl<'q, T> sqlx::Encode<'q, MySql> for SetOption<T>
where
T: sqlx::Encode<'q, MySql>,
{
fn encode_by_ref(&self, args: &mut Vec<u8>) -> IsNull {
match self {
SetOption::Set(value) => value.encode_by_ref(args),
SetOption::NotSet => IsNull::Yes,
}
}
}