dynamodb_expression/update/set/
mod.rs1mod assign;
2pub mod if_not_exists;
3pub mod list_append;
4pub mod math;
5mod set_action;
6
7pub use self::assign::Assign;
8pub use self::if_not_exists::IfNotExists;
9pub use self::list_append::ListAppend;
10pub use self::math::Math;
11pub use self::set_action::SetAction;
12
13use core::fmt;
14
15use super::Update;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct Set {
56 pub(crate) actions: Vec<SetAction>,
57}
58
59impl Set {
60 pub fn and<T>(self, other: T) -> Update
78 where
79 T: Into<Update>,
80 {
81 Update::from(self).and(other)
82 }
83}
84
85impl fmt::Display for Set {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.write_str("SET ")?;
88
89 let mut first = true;
90 self.actions.iter().try_for_each(|action| {
91 if first {
92 first = false
93 } else {
94 f.write_str(", ")?;
95 }
96
97 action.fmt(f)
98 })
99 }
100}
101
102impl<T> From<T> for Set
103where
104 T: Into<SetAction>,
105{
106 fn from(value: T) -> Self {
107 Self {
108 actions: vec![value.into()],
109 }
110 }
111}
112
113impl<T> FromIterator<T> for Set
114where
115 T: Into<SetAction>,
116{
117 fn from_iter<I>(iter: I) -> Self
118 where
119 I: IntoIterator<Item = T>,
120 {
121 Self {
122 actions: iter.into_iter().map(Into::into).collect(),
123 }
124 }
125}
126
127#[cfg(test)]
128mod test {
129 use pretty_assertions::assert_eq;
130
131 use crate::{Num, Path};
132
133 use super::{Assign, IfNotExists, ListAppend, Math, Set, SetAction};
134
135 #[test]
136 fn from() -> Result<(), Box<dyn std::error::Error>> {
137 let assign: Assign = "foo".parse::<Path>()?.set(Num::new(8));
138 let if_not_exists: IfNotExists = "bar".parse::<Path>()?.if_not_exists().set(Num::new(7));
139 let math: Math = "baz".parse::<Path>()?.math().add(1);
140 let list_append: ListAppend = "quux".parse::<Path>()?.list_append().list(["d", "e", "f"]);
141
142 let _set = [
143 Set::from(assign.clone()),
144 Set::from(if_not_exists),
145 Set::from(math),
146 Set::from(list_append),
147 ];
148
149 let _set = Set::from(SetAction::from(assign));
150
151 Ok(())
152 }
153
154 #[test]
155 fn and() -> Result<(), Box<dyn std::error::Error>> {
156 let assign: Assign = "bar".parse::<Path>()?.set(Num::new(8));
157 let set: Set = Set::from("foo".parse::<Path>()?.set("a value"));
158
159 let combined = set.clone().and(assign.clone());
162 assert_eq!(r#"SET foo = "a value", bar = 8"#, combined.to_string());
163
164 let combined = set.clone().and(SetAction::from(assign.clone()));
167 assert_eq!(r#"SET foo = "a value", bar = 8"#, combined.to_string());
168
169 let set_2: Set = [
172 SetAction::from(assign),
173 SetAction::from("baz".parse::<Path>()?.if_not_exists().set(Num::new(7))),
174 ]
175 .into_iter()
176 .collect();
177 let combined = set.clone().and(set_2);
178 assert_eq!(
179 r#"SET foo = "a value", bar = 8, baz = if_not_exists(baz, 7)"#,
180 combined.to_string()
181 );
182
183 let combined = set.clone().and("quux".parse::<Path>()?.remove());
186 assert_eq!(r#"SET foo = "a value" REMOVE quux"#, combined.to_string());
187
188 let combined = set.and("quux".parse::<Path>()?.remove());
191 assert_eq!(r#"SET foo = "a value" REMOVE quux"#, combined.to_string());
192
193 Ok(())
194 }
195}