use crate::Value;
use sea_query::Nullable;
use std::fmt::Debug;
pub use ActiveValue::{NotSet, Set, Unchanged};
#[derive(Clone, Debug)]
pub enum ActiveValue<V>
where
V: Into<Value>,
{
Set(V),
Unchanged(V),
NotSet,
}
#[deprecated(
since = "0.5.0",
note = "Please use [`ActiveValue::NotSet`] or [`NotSet`]"
)]
#[allow(non_snake_case)]
pub fn Unset<V>(_: Option<bool>) -> ActiveValue<V>
where
V: Into<Value>,
{
ActiveValue::not_set()
}
pub trait IntoActiveValue<V>
where
V: Into<Value>,
{
fn into_active_value(self) -> ActiveValue<V>;
}
impl<V> IntoActiveValue<V> for Option<V>
where
V: IntoActiveValue<V> + Into<Value> + Nullable,
{
fn into_active_value(self) -> ActiveValue<V> {
match self {
Some(value) => Set(value),
None => NotSet,
}
}
}
impl<V> IntoActiveValue<Option<V>> for Option<Option<V>>
where
V: IntoActiveValue<V> + Into<Value> + Nullable,
{
fn into_active_value(self) -> ActiveValue<Option<V>> {
match self {
Some(value) => Set(value),
None => NotSet,
}
}
}
macro_rules! impl_into_active_value {
($ty: ty) => {
impl IntoActiveValue<$ty> for $ty {
fn into_active_value(self) -> ActiveValue<$ty> {
Set(self)
}
}
};
}
impl_into_active_value!(bool);
impl_into_active_value!(i8);
impl_into_active_value!(i16);
impl_into_active_value!(i32);
impl_into_active_value!(i64);
impl_into_active_value!(u8);
impl_into_active_value!(u16);
impl_into_active_value!(u32);
impl_into_active_value!(u64);
impl_into_active_value!(f32);
impl_into_active_value!(f64);
impl_into_active_value!(&'static str);
impl_into_active_value!(String);
impl_into_active_value!(Vec<u8>);
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
impl_into_active_value!(crate::prelude::Json);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::Date);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::Time);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::DateTime);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::DateTimeWithTimeZone);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::DateTimeUtc);
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::DateTimeLocal);
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
impl_into_active_value!(crate::prelude::Decimal);
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
impl_into_active_value!(crate::prelude::BigDecimal);
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
impl_into_active_value!(crate::prelude::Uuid);
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
impl_into_active_value!(crate::prelude::TimeDate);
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
impl_into_active_value!(crate::prelude::TimeTime);
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
impl_into_active_value!(crate::prelude::TimeDateTime);
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
impl_into_active_value!(crate::prelude::TimeDateTimeWithTimeZone);
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
impl_into_active_value!(crate::prelude::IpNetwork);
impl<V> Default for ActiveValue<V>
where
V: Into<Value>,
{
fn default() -> Self {
Self::NotSet
}
}
impl<V> ActiveValue<V>
where
V: Into<Value>,
{
pub fn set(value: V) -> Self {
Self::Set(value)
}
pub fn is_set(&self) -> bool {
matches!(self, Self::Set(_))
}
pub fn unchanged(value: V) -> Self {
Self::Unchanged(value)
}
pub fn is_unchanged(&self) -> bool {
matches!(self, Self::Unchanged(_))
}
pub fn not_set() -> Self {
Self::default()
}
pub fn is_not_set(&self) -> bool {
matches!(self, Self::NotSet)
}
pub fn take(&mut self) -> Option<V> {
match std::mem::take(self) {
ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),
ActiveValue::NotSet => None,
}
}
pub fn unwrap(self) -> V {
match self {
ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,
ActiveValue::NotSet => panic!("Cannot unwrap ActiveValue::NotSet"),
}
}
pub fn into_value(self) -> Option<Value> {
match self {
ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value.into()),
ActiveValue::NotSet => None,
}
}
pub fn into_wrapped_value(self) -> ActiveValue<Value> {
match self {
Self::Set(value) => ActiveValue::set(value.into()),
Self::Unchanged(value) => ActiveValue::unchanged(value.into()),
Self::NotSet => ActiveValue::not_set(),
}
}
pub fn reset(&mut self) {
*self = match self.take() {
Some(value) => ActiveValue::Set(value),
None => ActiveValue::NotSet,
};
}
pub fn set_ne(&mut self, value: V)
where
V: PartialEq,
{
match self {
ActiveValue::Unchanged(current) if &value == current => {}
_ => *self = ActiveValue::Set(value),
}
}
pub fn set_if_not_equals(&mut self, value: V)
where
V: PartialEq,
{
self.set_ne(value);
}
pub fn set_ne_and(&mut self, value: V, f: impl FnOnce(&V) -> bool)
where
V: PartialEq,
{
match self {
ActiveValue::Unchanged(current) if &value == current => {}
ActiveValue::Set(_) if !f(&value) => {}
_ => *self = ActiveValue::Set(value),
}
}
pub fn set_if_not_equals_and(&mut self, value: V, f: impl FnOnce(&V) -> bool)
where
V: PartialEq,
{
self.set_ne_and(value, f);
}
pub fn try_as_ref(&self) -> Option<&V> {
match self {
ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),
ActiveValue::NotSet => None,
}
}
}
impl<V> std::convert::AsRef<V> for ActiveValue<V>
where
V: Into<Value>,
{
fn as_ref(&self) -> &V {
match self {
ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,
ActiveValue::NotSet => panic!("Cannot borrow ActiveValue::NotSet"),
}
}
}
impl<V> PartialEq for ActiveValue<V>
where
V: Into<Value> + std::cmp::PartialEq,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(ActiveValue::Set(l), ActiveValue::Set(r)) => l == r,
(ActiveValue::Unchanged(l), ActiveValue::Unchanged(r)) => l == r,
(ActiveValue::NotSet, ActiveValue::NotSet) => true,
_ => false,
}
}
}
impl<V> From<ActiveValue<V>> for ActiveValue<Option<V>>
where
V: Into<Value> + Nullable,
{
fn from(value: ActiveValue<V>) -> Self {
match value {
ActiveValue::Set(value) => ActiveValue::set(Some(value)),
ActiveValue::Unchanged(value) => ActiveValue::unchanged(Some(value)),
ActiveValue::NotSet => ActiveValue::not_set(),
}
}
}