use core::fmt::{self, Write};
use crate::{
path::Path,
value::{BinarySet, Num, NumSet, Ref, Set, StringSet, Value, ValueOrRef},
};
use super::Update;
#[must_use = "Use in an update expression with `Update::from(add)`"]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Add {
pub(crate) actions: Vec<AddAction>,
}
impl Add {
pub fn new<N, V>(path: N, value: V) -> Self
where
N: Into<Path>,
V: Into<AddValue>,
{
Self::from(AddAction::new(path, value))
}
pub fn and<T>(self, other: T) -> Update
where
T: Into<Update>,
{
Update::from(self).and(other)
}
}
impl fmt::Display for Add {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ADD ")?;
let mut first = true;
self.actions.iter().try_for_each(|action| {
if first {
first = false;
} else {
f.write_str(", ")?;
}
action.fmt(f)
})
}
}
impl From<AddAction> for Add {
fn from(action: AddAction) -> Self {
Self {
actions: vec![action],
}
}
}
#[must_use = "Use in an update expression with `Update::from(add)`"]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddAction {
pub(crate) path: Path,
pub(crate) value: ValueOrRef,
}
impl AddAction {
pub fn new<N, V>(path: N, value: V) -> Self
where
N: Into<Path>,
V: Into<AddValue>,
{
Self {
path: path.into(),
value: match value.into() {
AddValue::Num(num) => Value::Scalar(num.into()).into(),
AddValue::Set(set) => set.into(),
AddValue::Ref(value_ref) => value_ref.into(),
},
}
}
pub fn and<T>(self, other: T) -> Update
where
T: Into<Update>,
{
Update::from(self).and(other)
}
}
impl fmt::Display for AddAction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.path.fmt(f)?;
f.write_char(' ')?;
self.value.fmt(f)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AddValue {
Set(Set),
Num(Num),
Ref(Ref),
}
impl fmt::Display for AddValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Set(value) => value.fmt(f),
Self::Num(value) => value.fmt(f),
Self::Ref(value) => value.fmt(f),
}
}
}
impl From<Set> for AddValue {
fn from(value: Set) -> Self {
Self::Set(value)
}
}
impl From<StringSet> for AddValue {
fn from(value: StringSet) -> Self {
Self::Set(value.into())
}
}
impl From<NumSet> for AddValue {
fn from(value: NumSet) -> Self {
Self::Set(value.into())
}
}
impl From<BinarySet> for AddValue {
fn from(value: BinarySet) -> Self {
Self::Set(value.into())
}
}
impl From<Num> for AddValue {
fn from(value: Num) -> Self {
Self::Num(value)
}
}
impl From<Ref> for AddValue {
fn from(value: Ref) -> Self {
Self::Ref(value)
}
}