use core::fmt::{self, Write};
use crate::{
path::Path,
update::Update,
value::{Value, ValueOrRef},
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IfNotExists {
pub(crate) dst: Path,
pub(crate) src: Option<Path>,
pub(crate) value: ValueOrRef,
}
impl IfNotExists {
pub fn builder<T>(dst: T) -> Builder
where
T: Into<Path>,
{
Builder {
dst: dst.into(),
src: None,
}
}
pub fn and<T>(self, action: T) -> Update
where
T: Into<Update>,
{
Update::from(self).and(action)
}
}
impl fmt::Display for IfNotExists {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.dst.fmt(f)?;
f.write_str(" = if_not_exists(")?;
self.src.as_ref().unwrap_or(&self.dst).fmt(f)?;
f.write_str(", ")?;
self.value.fmt(f)?;
f.write_char(')')
}
}
#[must_use = "Consume this `Builder` by using its `.value()` method"]
#[derive(Debug, Clone)]
pub struct Builder {
dst: Path,
src: Option<Path>,
}
impl Builder {
pub fn src<T>(mut self, src: T) -> Self
where
T: Into<Path>,
{
self.src = Some(src.into());
self
}
#[deprecated(since = "0.2.0-beta.6", note = "Use `.set(value)` instead")]
pub fn assign<T>(self, value: T) -> IfNotExists
where
T: Into<Value>,
{
self.set(value)
}
pub fn set<T>(self, value: T) -> IfNotExists
where
T: Into<Value>,
{
let Self { dst, src } = self;
IfNotExists {
dst,
src,
value: value.into().into(),
}
}
}
#[cfg(test)]
mod test {
use std::error::Error;
use pretty_assertions::assert_eq;
use crate::{
update::{Assign, Set, SetAction},
Num, Path,
};
use super::IfNotExists;
#[test]
fn and() -> Result<(), Box<dyn Error>> {
let if_not_exists: IfNotExists = "foo".parse::<Path>()?.if_not_exists().set("a value");
let assign: Assign = "bar".parse::<Path>()?.set(Num::new(8));
let combined = if_not_exists.clone().and(assign.clone());
assert_eq!(
r#"SET foo = if_not_exists(foo, "a value"), bar = 8"#,
combined.to_string()
);
let combined = if_not_exists.clone().and(SetAction::from(assign.clone()));
assert_eq!(
r#"SET foo = if_not_exists(foo, "a value"), bar = 8"#,
combined.to_string()
);
let set: Set = [
SetAction::from(assign),
SetAction::from("baz".parse::<Path>()?.math().add(1)),
]
.into_iter()
.collect();
let combined = if_not_exists.clone().and(set);
assert_eq!(
r#"SET foo = if_not_exists(foo, "a value"), bar = 8, baz = baz + 1"#,
combined.to_string()
);
let combined = if_not_exists.clone().and("quux".parse::<Path>()?.remove());
assert_eq!(
r#"SET foo = if_not_exists(foo, "a value") REMOVE quux"#,
combined.to_string()
);
let combined = if_not_exists.and("quux".parse::<Path>()?.remove());
assert_eq!(
r#"SET foo = if_not_exists(foo, "a value") REMOVE quux"#,
combined.to_string()
);
Ok(())
}
}