dynamodb_expression/update/delete.rs
1use core::fmt::{self, Write};
2
3use crate::{
4 path::Path,
5 value::{self, ValueOrRef},
6};
7
8use super::Update;
9
10/// Represents a [`DELETE` statement for an update expression][1], for removing
11/// one or more items from a value that is a [set][2].
12///
13/// Prefer [`Path::delete`] over this.
14///
15/// See also: [`Update`]
16///
17/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.DELETE
18/// [2]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes
19/// [`Update`]: crate::update::Update
20#[must_use = "Use in an update expression with `Update::from(delete)`"]
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct Delete {
23 pub(crate) actions: Vec<DeleteAction>,
24}
25
26impl Delete {
27 /// Creates a [`Delete`] for the specified [`Path`] and items in that [set][1].
28 ///
29 /// Prefer [`Path::delete`] over this.
30 ///
31 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes
32 pub fn new<P, S>(path: P, subset: S) -> Self
33 where
34 P: Into<Path>,
35 S: Into<value::Set>,
36 {
37 Self {
38 actions: vec![DeleteAction::new(path, subset)],
39 }
40 }
41
42 /// Add an additional [`Update`] statement to this `ADD` statement.
43 ///
44 /// ```
45 /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
46 /// use dynamodb_expression::{value::NumSet, Num, Path};
47 /// # use pretty_assertions::assert_eq;
48 ///
49 /// let update = "foo"
50 /// .parse::<Path>()?
51 /// .delete(NumSet::from([7]))
52 /// .and("bar".parse::<Path>()?.set("a value"))
53 /// .and("baz".parse::<Path>()?.remove());
54 /// assert_eq!(r#"SET bar = "a value" REMOVE baz DELETE foo [7]"#, update.to_string());
55 /// #
56 /// # Ok(())
57 /// # }
58 /// ```
59 pub fn and<T>(self, other: T) -> Update
60 where
61 T: Into<Update>,
62 {
63 Update::from(self).and(other)
64 }
65}
66
67impl fmt::Display for Delete {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 f.write_str("DELETE ")?;
70
71 let mut first = true;
72 self.actions.iter().try_for_each(|action| {
73 if first {
74 first = false;
75 } else {
76 f.write_str(", ")?;
77 }
78
79 action.fmt(f)
80 })
81 }
82}
83
84impl From<DeleteAction> for Delete {
85 fn from(action: DeleteAction) -> Self {
86 Self {
87 actions: vec![action],
88 }
89 }
90}
91
92#[must_use = "Use in an update expression with `Update::from(delete)`"]
93#[derive(Debug, Clone, PartialEq, Eq)]
94pub struct DeleteAction {
95 pub(crate) path: Path,
96 pub(crate) subset: ValueOrRef,
97}
98
99impl DeleteAction {
100 /// Creates a [`DeleteAction`] for the specified [`Path`] and items in that [set][1].
101 ///
102 /// Prefer [`Path::delete`] over this.
103 ///
104 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes
105 pub fn new<P, S>(path: P, subset: S) -> Self
106 where
107 P: Into<Path>,
108 S: Into<value::Set>,
109 {
110 Self {
111 path: path.into(),
112 subset: subset.into().into(),
113 }
114 }
115
116 /// Add an additional [`Update`] statement to this `ADD` statement.
117 ///
118 /// ```
119 /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
120 /// use dynamodb_expression::{update::DeleteAction, value::NumSet, Num, Path};
121 /// # use pretty_assertions::assert_eq;
122 ///
123 /// let update = DeleteAction::new("foo".parse::<Path>()?, NumSet::from([7]))
124 /// .and("bar".parse::<Path>()?.set("a value"))
125 /// .and("baz".parse::<Path>()?.remove());
126 /// assert_eq!(r#"SET bar = "a value" REMOVE baz DELETE foo [7]"#, update.to_string());
127 /// #
128 /// # Ok(())
129 /// # }
130 /// ```
131 pub fn and<T>(self, other: T) -> Update
132 where
133 T: Into<Update>,
134 {
135 Update::from(self).and(other)
136 }
137}
138
139impl fmt::Display for DeleteAction {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 self.path.fmt(f)?;
142 f.write_char(' ')?;
143 self.subset.fmt(f)
144 }
145}