dynamodb_expression/expression/to_aws.rs
1use aws_sdk_dynamodb::{
2 operation::{
3 delete_item::{
4 builders::{DeleteItemFluentBuilder, DeleteItemInputBuilder},
5 DeleteItemInput,
6 },
7 get_item::{
8 builders::{GetItemFluentBuilder, GetItemInputBuilder},
9 GetItemInput,
10 },
11 put_item::{
12 builders::{PutItemFluentBuilder, PutItemInputBuilder},
13 PutItemInput,
14 },
15 query::{
16 builders::{QueryFluentBuilder, QueryInputBuilder},
17 QueryInput,
18 },
19 scan::{
20 builders::{ScanFluentBuilder, ScanInputBuilder},
21 ScanInput,
22 },
23 update_item::{
24 builders::{UpdateItemFluentBuilder, UpdateItemInputBuilder},
25 UpdateItemInput,
26 },
27 },
28 types::{
29 builders::{
30 ConditionCheckBuilder, DeleteBuilder, GetBuilder, KeysAndAttributesBuilder, PutBuilder,
31 UpdateBuilder,
32 },
33 ConditionCheck, Delete, Get, KeysAndAttributes, Put, Update,
34 },
35 Client,
36};
37
38use super::Expression;
39
40/// Methods related to [`PutItem` operations][1].
41///
42/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html
43impl Expression {
44 /// Uses this [`Expression`] to create a [`PutBuilder`] with the following set:
45 /// * Condition expression
46 /// * Expression attribute names
47 /// * Expression attribute values
48 pub fn to_put_builder(self) -> PutBuilder {
49 Put::builder()
50 .set_condition_expression(self.condition_expression)
51 .set_expression_attribute_names(self.expression_attribute_names)
52 .set_expression_attribute_values(self.expression_attribute_values)
53 }
54
55 /// Uses this [`Expression`] to set the following on a [`PutItemInputBuilder`]:
56 /// * Condition expression
57 /// * Expression attribute names
58 /// * Expression attribute values
59 pub fn to_put_item_input_builder(self) -> PutItemInputBuilder {
60 PutItemInput::builder()
61 .set_condition_expression(self.condition_expression)
62 .set_expression_attribute_names(self.expression_attribute_names)
63 .set_expression_attribute_values(self.expression_attribute_values)
64 }
65
66 /// Uses this [`Expression`] to set the following on a [`PutItemFluentBuilder`]
67 /// before returning it:
68 /// * Condition expression
69 /// * Expression attribute names
70 /// * Expression attribute values
71 pub fn to_put_item_fluent_builder(self, builder: PutItemFluentBuilder) -> PutItemFluentBuilder {
72 builder
73 .set_condition_expression(self.condition_expression)
74 .set_expression_attribute_names(self.expression_attribute_names)
75 .set_expression_attribute_values(self.expression_attribute_values)
76 }
77
78 /// Sets up a [`put_item`][1] using the provided [`Client`] and uses this [`Expression`]
79 /// to set the following on the [`PutItemFluentBuilder`] before returning it:
80 /// * Condition expression
81 /// * Expression attribute names
82 /// * Expression attribute values
83 ///
84 /// # Example
85 ///
86 /// ```no_run
87 /// # async fn example_put_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
88 /// use aws_config::BehaviorVersion;
89 /// use aws_sdk_dynamodb::{types::AttributeValue, Client};
90 /// use dynamodb_expression::{Expression, Path};
91 ///
92 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
93 ///
94 /// let output = Expression::builder()
95 /// .with_condition("name".parse::<Path>()?.attribute_not_exists())
96 /// .build()
97 /// .put_item(&client)
98 /// .table_name("people")
99 /// .item("name", AttributeValue::S(String::from("Jill")))
100 /// .item("age", AttributeValue::N(40.to_string()))
101 /// .send()
102 /// .await?;
103 /// #
104 /// # _ = output;
105 /// # Ok(())
106 /// # }
107 /// ```
108 ///
109 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html
110 pub fn put_item(self, client: &Client) -> PutItemFluentBuilder {
111 self.to_put_item_fluent_builder(client.put_item())
112 }
113}
114
115/// Methods related to [`GetItem` operations][1].
116///
117/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html
118impl Expression {
119 /// Uses this [`Expression`] to create a [`GetBuilder`] with the following set:
120 /// * Projection expression
121 /// * Expression attribute names
122 pub fn to_get_builder(self) -> GetBuilder {
123 Get::builder()
124 .set_projection_expression(self.projection_expression)
125 .set_expression_attribute_names(self.expression_attribute_names)
126 }
127
128 /// Uses this [`Expression`] to set the following on a [`GetItemInputBuilder`]:
129 /// * Projection expression
130 /// * Expression attribute names
131 pub fn to_get_item_input_builder(self) -> GetItemInputBuilder {
132 GetItemInput::builder()
133 .set_projection_expression(self.projection_expression)
134 .set_expression_attribute_names(self.expression_attribute_names)
135 }
136
137 /// Uses this [`Expression`] to set the following on a [`GetItemFluentBuilder`]
138 /// before returning it:
139 /// * Projection expression
140 /// * Expression attribute names
141 pub fn to_get_item_fluent_builder(self, builder: GetItemFluentBuilder) -> GetItemFluentBuilder {
142 builder
143 .set_projection_expression(self.projection_expression)
144 .set_expression_attribute_names(self.expression_attribute_names)
145 }
146
147 /// Sets up a [`get_item`][1] using the provided [`Client`] and uses this [`Expression`]
148 /// to set the following on the [`GetItemFluentBuilder`] before returning it:
149 /// * Projection expression
150 /// * Expression attribute names
151 ///
152 /// # Example
153 ///
154 /// ```no_run
155 /// # async fn example_get_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
156 /// use aws_config::BehaviorVersion;
157 /// use aws_sdk_dynamodb::{types::AttributeValue, Client};
158 /// use dynamodb_expression::Expression;
159 ///
160 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
161 ///
162 /// let output = Expression::builder()
163 /// .with_projection(["name", "age"])
164 /// .build()
165 /// .get_item(&client)
166 /// .table_name("people")
167 /// .key("id", AttributeValue::N(42.to_string()))
168 /// .send()
169 /// .await?;
170 /// #
171 /// # _ = output;
172 /// # Ok(())
173 /// # }
174 /// ```
175 ///
176 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html
177 pub fn get_item(self, client: &Client) -> GetItemFluentBuilder {
178 self.to_get_item_fluent_builder(client.get_item())
179 }
180}
181
182/// Methods related to [`UpdateItem` operations][1].
183///
184/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html
185impl Expression {
186 /// Uses this [`Expression`] to create an [`UpdateBuilder`] with the following set:
187 /// * Update expression
188 /// * Condition expression
189 /// * Expression attribute names
190 /// * Expression attribute values
191 pub fn to_update_builder(self) -> UpdateBuilder {
192 Update::builder()
193 .set_update_expression(self.update_expression)
194 .set_condition_expression(self.condition_expression)
195 .set_expression_attribute_names(self.expression_attribute_names)
196 .set_expression_attribute_values(self.expression_attribute_values)
197 }
198
199 /// Uses this [`Expression`] to create an [`UpdateItemInputBuilder`] with the following set:
200 /// * Update expression
201 /// * Condition expression
202 /// * Expression attribute names
203 /// * Expression attribute values
204 pub fn to_update_item_input_builder(self) -> UpdateItemInputBuilder {
205 UpdateItemInput::builder()
206 .set_update_expression(self.update_expression)
207 .set_condition_expression(self.condition_expression)
208 .set_expression_attribute_names(self.expression_attribute_names)
209 .set_expression_attribute_values(self.expression_attribute_values)
210 }
211
212 /// Uses this [`Expression`] to set the following on an [`UpdateItemFluentBuilder`]
213 /// before returning it:
214 /// * Update expression
215 /// * Condition expression
216 /// * Expression attribute names
217 /// * Expression attribute values
218 pub fn to_update_item_fluent_builder(
219 self,
220 builder: UpdateItemFluentBuilder,
221 ) -> UpdateItemFluentBuilder {
222 builder
223 .set_update_expression(self.update_expression)
224 .set_condition_expression(self.condition_expression)
225 .set_expression_attribute_names(self.expression_attribute_names)
226 .set_expression_attribute_values(self.expression_attribute_values)
227 }
228
229 /// Sets up an [`update_item`][1] using the provided [`Client`] and uses this [`Expression`]
230 /// to set the following on the [`UpdateItemFluentBuilder`] before returning it:
231 /// * Update expression
232 /// * Condition expression
233 /// * Expression attribute names
234 /// * Expression attribute values
235 ///
236 /// # Example
237 ///
238 /// ```no_run
239 /// # async fn example_update_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
240 /// # {
241 /// use aws_config::BehaviorVersion;
242 /// use aws_sdk_dynamodb::{types::AttributeValue, Client};
243 /// use dynamodb_expression::{Expression, Num, Path};
244 ///
245 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
246 ///
247 /// let age: Path = "age".parse()?;
248 /// let output = Expression::builder()
249 /// .with_condition(age.clone().equal(Num::new(40)))
250 /// .with_update(age.math().add(1))
251 /// .build()
252 /// .update_item(&client)
253 /// .table_name("people")
254 /// .key("name", AttributeValue::S(String::from("Jack")))
255 /// .send()
256 /// .await?;
257 /// #
258 /// # _ = output;
259 /// # Ok(())
260 /// # }
261 /// ```
262 ///
263 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html
264 pub fn update_item(self, client: &Client) -> UpdateItemFluentBuilder {
265 self.to_update_item_fluent_builder(client.update_item())
266 }
267}
268
269/// Methods related to [`DeleteItem` operations][1].
270///
271/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html
272impl Expression {
273 /// Uses this [`Expression`] to create a [`DeleteBuilder`] with the following set:
274 /// * Condition expression
275 /// * Expression attribute names
276 /// * Expression attribute values
277 pub fn to_delete_builder(self) -> DeleteBuilder {
278 Delete::builder()
279 .set_condition_expression(self.condition_expression)
280 .set_expression_attribute_names(self.expression_attribute_names)
281 .set_expression_attribute_values(self.expression_attribute_values)
282 }
283
284 /// Uses this [`Expression`] to set the following on a [`DeleteItemInputBuilder`]:
285 /// * Condition expression
286 /// * Expression attribute names
287 /// * Expression attribute values
288 pub fn to_delete_item_input_builder(self) -> DeleteItemInputBuilder {
289 DeleteItemInput::builder()
290 .set_condition_expression(self.condition_expression)
291 .set_expression_attribute_names(self.expression_attribute_names)
292 .set_expression_attribute_values(self.expression_attribute_values)
293 }
294
295 /// Uses this [`Expression`] to set the following on a [`DeleteItemFluentBuilder`]
296 /// before returning it:
297 /// * Condition expression
298 /// * Expression attribute names
299 /// * Expression attribute values
300 pub fn to_delete_item_fluent_builder(
301 self,
302 builder: DeleteItemFluentBuilder,
303 ) -> DeleteItemFluentBuilder {
304 builder
305 .set_condition_expression(self.condition_expression)
306 .set_expression_attribute_names(self.expression_attribute_names)
307 .set_expression_attribute_values(self.expression_attribute_values)
308 }
309
310 /// Sets up a [`delete_item`][1] using the provided [`Client`] and uses this [`Expression`]
311 /// to set the following on the [`DeleteItemFluentBuilder`] before returning it:
312 /// * Condition expression
313 /// * Expression attribute names
314 /// * Expression attribute values
315 ///
316 /// # Example
317 ///
318 /// ```no_run
319 /// # async fn example_delete_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
320 /// # {
321 /// use aws_config::BehaviorVersion;
322 /// use aws_sdk_dynamodb::{types::AttributeValue, Client};
323 /// use dynamodb_expression::{Expression, Num, Path};
324 ///
325 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
326 ///
327 /// let output = Expression::builder()
328 /// .with_condition("age".parse::<Path>()?.less_than(Num::new(20)))
329 /// .build()
330 /// .delete_item(&client)
331 /// .table_name("people")
332 /// .key("name", AttributeValue::S(String::from("Jack")))
333 /// .send()
334 /// .await?;
335 /// #
336 /// # _ = output;
337 /// # Ok(())
338 /// # }
339 /// ```
340 ///
341 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html
342 pub fn delete_item(self, client: &Client) -> DeleteItemFluentBuilder {
343 self.to_delete_item_fluent_builder(client.delete_item())
344 }
345}
346
347/// Methods related to [`Query` operations][1].
348///
349/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
350impl Expression {
351 /// Uses this [`Expression`] to create a [`QueryInputBuilder`] with the following set:
352 /// * Key condition expression
353 /// * Filter expression
354 /// * Projection expression
355 /// * Expression attribute names
356 /// * Expression attribute values
357 pub fn to_query_input_builder(self) -> QueryInputBuilder {
358 QueryInput::builder()
359 .set_key_condition_expression(self.key_condition_expression)
360 .set_filter_expression(self.filter_expression)
361 .set_projection_expression(self.projection_expression)
362 .set_expression_attribute_names(self.expression_attribute_names)
363 .set_expression_attribute_values(self.expression_attribute_values)
364 }
365
366 /// Uses this [`Expression`] to set the following on a [`QueryFluentBuilder`]
367 /// before returning it:
368 /// * Key condition expression
369 /// * Filter expression
370 /// * Projection expression
371 /// * Expression attribute names
372 /// * Expression attribute values
373 pub fn to_query_fluent_builder(self, builder: QueryFluentBuilder) -> QueryFluentBuilder {
374 builder
375 .set_key_condition_expression(self.key_condition_expression)
376 .set_filter_expression(self.filter_expression)
377 .set_projection_expression(self.projection_expression)
378 .set_expression_attribute_names(self.expression_attribute_names)
379 .set_expression_attribute_values(self.expression_attribute_values)
380 }
381
382 /// Sets up a [`query`][1] using the provided [`Client`] and uses this [`Expression`]
383 /// to set the following on the [`QueryFluentBuilder`] before returning it:
384 /// * Key condition expression
385 /// * Filter expression
386 /// * Projection expression
387 /// * Expression attribute names
388 /// * Expression attribute values
389 ///
390 /// # Example
391 ///
392 /// ```no_run
393 /// # async fn example_query() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
394 /// use aws_config::BehaviorVersion;
395 /// use aws_sdk_dynamodb::Client;
396 /// use dynamodb_expression::{Expression, Num, Path};
397 ///
398 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
399 ///
400 /// let output = Expression::builder()
401 /// .with_filter(
402 /// "name"
403 /// .parse::<Path>()?
404 /// .attribute_exists()
405 /// .and("age".parse::<Path>()?.greater_than_or_equal(Num::new(25))),
406 /// )
407 /// .with_projection(["name", "age"])
408 /// .with_key_condition("id".parse::<Path>()?.key().equal(Num::new(42)))
409 /// .build()
410 /// .query(&client)
411 /// .table_name("people")
412 /// .send()
413 /// .await?;
414 /// #
415 /// # _ = output;
416 /// # Ok(())
417 /// # }
418 /// ```
419 ///
420 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
421 pub fn query(self, client: &Client) -> QueryFluentBuilder {
422 self.to_query_fluent_builder(client.query())
423 }
424}
425
426/// Methods related to [`Scan` operations][1].
427///
428/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
429impl Expression {
430 /// Uses this [`Expression`] to create a [`ScanInputBuilder`] with the following set:
431 /// * Filter expression
432 /// * Projection expression
433 /// * Expression attribute names
434 /// * Expression attribute values
435 pub fn to_scan_input_builder(self) -> ScanInputBuilder {
436 ScanInput::builder()
437 .set_filter_expression(self.filter_expression)
438 .set_projection_expression(self.projection_expression)
439 .set_expression_attribute_names(self.expression_attribute_names)
440 .set_expression_attribute_values(self.expression_attribute_values)
441 }
442
443 /// Uses this [`Expression`] to set the following on a [`ScanFluentBuilder`]
444 /// before returning it:
445 /// * Filter expression
446 /// * Projection expression
447 /// * Expression attribute names
448 /// * Expression attribute values
449 pub fn to_scan_fluent_builder(self, builder: ScanFluentBuilder) -> ScanFluentBuilder {
450 builder
451 .set_filter_expression(self.filter_expression)
452 .set_projection_expression(self.projection_expression)
453 .set_expression_attribute_names(self.expression_attribute_names)
454 .set_expression_attribute_values(self.expression_attribute_values)
455 }
456
457 /// Sets up a [`scan`][1] using the provided [`Client`] and uses this [`Expression`]
458 /// to set the following on the [`ScanFluentBuilder`] before returning it:
459 /// * Filter expression
460 /// * Projection expression
461 /// * Expression attribute names
462 /// * Expression attribute values
463 ///
464 /// # Example
465 ///
466 /// ```no_run
467 /// # async fn example_scan() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
468 /// use aws_config::BehaviorVersion;
469 /// use aws_sdk_dynamodb::Client;
470 /// use dynamodb_expression::{Expression, Num, Path};
471 ///
472 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
473 ///
474 /// let output = Expression::builder()
475 /// .with_filter("age".parse::<Path>()?.greater_than_or_equal(Num::new(25)))
476 /// .with_projection(["name", "age"])
477 /// .build()
478 /// .scan(&client)
479 /// .table_name("people")
480 /// .send()
481 /// .await?;
482 /// #
483 /// # _ = output;
484 /// # Ok(())
485 /// # }
486 /// ```
487 ///
488 /// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
489 pub fn scan(self, client: &Client) -> ScanFluentBuilder {
490 self.to_scan_fluent_builder(client.scan())
491 }
492}
493
494impl Expression {
495 /// Uses this [`Expression`] to create a [`KeysAndAttributesBuilder`] with the following set:
496 /// * Projection expression
497 /// * Expression attribute names
498 ///
499 /// # Example
500 ///
501 /// ```no_run
502 /// # async fn example_to_keys_and_attributes_builder(
503 /// # ) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
504 /// use std::collections::HashMap;
505 ///
506 /// use aws_config::BehaviorVersion;
507 /// use aws_sdk_dynamodb::{types::AttributeValue, Client};
508 /// use dynamodb_expression::Expression;
509 ///
510 /// let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
511 ///
512 /// let expression = Expression::builder()
513 /// .with_projection(["name", "age"])
514 /// .build();
515 ///
516 /// let key = HashMap::from([("id".to_string(), AttributeValue::N(42.to_string()))]);
517 ///
518 /// let output = client
519 /// .batch_get_item()
520 /// .request_items(
521 /// "leads",
522 /// expression
523 /// .clone()
524 /// .to_keys_and_attributes_builder()
525 /// .keys(key.clone())
526 /// .build()
527 /// .unwrap(),
528 /// )
529 /// .request_items(
530 /// "customers",
531 /// expression
532 /// .to_keys_and_attributes_builder()
533 /// .keys(key)
534 /// .build()
535 /// .unwrap(),
536 /// )
537 /// .send()
538 /// .await?;
539 ///
540 /// # _ = output;
541 /// # Ok(())
542 /// # }
543 /// ```
544 pub fn to_keys_and_attributes_builder(self) -> KeysAndAttributesBuilder {
545 KeysAndAttributes::builder()
546 .set_projection_expression(self.projection_expression)
547 .set_expression_attribute_names(self.expression_attribute_names)
548 }
549
550 // TODO: Is the a more ergonomic way to use `to_keys_and_attributes_builder()`
551 // that's in line with the rest of this crate?
552
553 // TODO: This ultimately ends up being a part of a `TransactWriteItem`.
554 // See how that gets used in practice.
555 // https://docs.rs/aws-sdk-dynamodb/latest/aws_sdk_dynamodb/types/builders/struct.TransactWriteItemBuilder.html#method.condition_check
556 // ----
557 /// Uses this [`Expression`] to create a [`ConditionCheckBuilder`] with the following set:
558 /// * Condition expression
559 /// * Expression attribute names
560 /// * Expression attribute values
561 pub fn to_condition_check_builder(self) -> ConditionCheckBuilder {
562 ConditionCheck::builder()
563 .set_condition_expression(self.condition_expression)
564 .set_expression_attribute_names(self.expression_attribute_names)
565 .set_expression_attribute_values(self.expression_attribute_values)
566 }
567}
568
569#[cfg(test)]
570mod test {
571 /// Exists to format the doc examples
572 #[allow(dead_code)]
573 async fn example_put_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
574 use crate::{Expression, Path};
575 use aws_config::BehaviorVersion;
576 use aws_sdk_dynamodb::{types::AttributeValue, Client};
577
578 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
579
580 let output = Expression::builder()
581 .with_condition("name".parse::<Path>()?.attribute_not_exists())
582 .build()
583 .put_item(&client)
584 .table_name("people")
585 .item("name", AttributeValue::S(String::from("Jill")))
586 .item("age", AttributeValue::N(40.to_string()))
587 .send()
588 .await?;
589
590 _ = output;
591 Ok(())
592 }
593
594 /// Exists to format the doc examples
595 #[allow(dead_code)]
596 async fn example_get_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
597 use crate::Expression;
598 use aws_config::BehaviorVersion;
599 use aws_sdk_dynamodb::{types::AttributeValue, Client};
600
601 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
602
603 let output = Expression::builder()
604 .with_projection(["name", "age"])
605 .build()
606 .get_item(&client)
607 .table_name("people")
608 .key("id", AttributeValue::N(42.to_string()))
609 .send()
610 .await?;
611
612 _ = output;
613 Ok(())
614 }
615
616 /// Exists to format the doc examples
617 #[allow(dead_code)]
618 async fn example_to_keys_and_attributes_builder(
619 ) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
620 use std::collections::HashMap;
621
622 use crate::Expression;
623 use aws_config::BehaviorVersion;
624 use aws_sdk_dynamodb::{types::AttributeValue, Client};
625
626 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
627
628 let expression = Expression::builder()
629 .with_projection(["name", "age"])
630 .build();
631
632 let key = HashMap::from([("id".to_string(), AttributeValue::N(42.to_string()))]);
633
634 let output = client
635 .batch_get_item()
636 .request_items(
637 "leads",
638 expression
639 .clone()
640 .to_keys_and_attributes_builder()
641 .keys(key.clone())
642 .build()
643 .unwrap(),
644 )
645 .request_items(
646 "customers",
647 expression
648 .to_keys_and_attributes_builder()
649 .keys(key)
650 .build()
651 .unwrap(),
652 )
653 .send()
654 .await?;
655
656 _ = output;
657 Ok(())
658 }
659
660 /// Exists to format the doc examples
661 #[allow(dead_code)]
662 async fn example_scan() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
663 use crate::{Expression, Num, Path};
664 use aws_config::BehaviorVersion;
665 use aws_sdk_dynamodb::Client;
666
667 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
668
669 let output = Expression::builder()
670 .with_filter("age".parse::<Path>()?.greater_than_or_equal(Num::new(25)))
671 .with_projection(["name", "age"])
672 .build()
673 .scan(&client)
674 .table_name("people")
675 .send()
676 .await?;
677
678 _ = output;
679 Ok(())
680 }
681
682 /// Exists to format the doc examples
683 #[allow(dead_code)]
684 async fn example_query() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
685 use crate::{Expression, Num, Path};
686 use aws_config::BehaviorVersion;
687 use aws_sdk_dynamodb::Client;
688
689 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
690
691 let output = Expression::builder()
692 .with_filter(
693 "name"
694 .parse::<Path>()?
695 .attribute_exists()
696 .and("age".parse::<Path>()?.greater_than_or_equal(Num::new(25))),
697 )
698 .with_projection(["name", "age"])
699 .with_key_condition("id".parse::<Path>()?.key().equal(Num::new(42)))
700 .build()
701 .query(&client)
702 .table_name("people")
703 .send()
704 .await?;
705
706 _ = output;
707 Ok(())
708 }
709
710 /// Exists to format the doc examples
711 #[allow(dead_code)]
712 async fn example_update_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
713 {
714 use crate::{Expression, Num, Path};
715 use aws_config::BehaviorVersion;
716 use aws_sdk_dynamodb::{types::AttributeValue, Client};
717
718 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
719
720 let age: Path = "age".parse()?;
721 let output = Expression::builder()
722 .with_condition(age.clone().equal(Num::new(40)))
723 .with_update(age.math().add(1))
724 .build()
725 .update_item(&client)
726 .table_name("people")
727 .key("name", AttributeValue::S(String::from("Jack")))
728 .send()
729 .await?;
730
731 _ = output;
732 Ok(())
733 }
734
735 /// Exists to format the doc examples
736 #[allow(dead_code)]
737 async fn example_delete_item() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
738 {
739 use crate::{Expression, Num, Path};
740 use aws_config::BehaviorVersion;
741 use aws_sdk_dynamodb::{types::AttributeValue, Client};
742
743 let client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await);
744
745 let output = Expression::builder()
746 .with_condition("age".parse::<Path>()?.less_than(Num::new(20)))
747 .build()
748 .delete_item(&client)
749 .table_name("people")
750 .key("name", AttributeValue::S(String::from("Jack")))
751 .send()
752 .await?;
753
754 _ = output;
755 Ok(())
756 }
757
758 #[test]
759 fn scan_input() {
760 use crate::{Expression, Num, Path};
761 use pretty_assertions::assert_eq;
762
763 let expression = Expression::builder()
764 .with_filter(
765 "name".parse::<Path>().unwrap().begins_with("prefix").and(
766 "age"
767 .parse::<Path>()
768 .unwrap()
769 .greater_than_or_equal(Num::new(25)),
770 ),
771 )
772 .with_projection(["name", "age"])
773 .build();
774 assert_eq!(None, expression.condition_expression);
775
776 let filter = expression
777 .filter_expression
778 .as_deref()
779 .expect("A filter expression should be set");
780 assert_eq!("begins_with(#0, :0) AND #1 >= :1", filter);
781 println!("Filter: {filter}");
782
783 let projection = expression
784 .projection_expression
785 .as_deref()
786 .expect("A projection expression should be set");
787 assert_eq!("#0, #1", projection);
788 println!("Projection: {projection}");
789
790 println!("Names: {:?}", expression.expression_attribute_names);
791 println!("Values: {:?}", expression.expression_attribute_values);
792
793 let si = expression.to_scan_input_builder().build().unwrap();
794
795 println!("{si:#?}");
796 }
797
798 #[test]
799 fn query_input() {
800 use crate::{key::Key, path::Name, Expression, Num, Path};
801 use pretty_assertions::{assert_eq, assert_ne};
802
803 let expression = Expression::builder()
804 .with_filter(
805 Path::from(Name::from("name"))
806 .attribute_exists()
807 .and(Path::from(Name::from("age")).greater_than_or_equal(Num::new(2.5))),
808 )
809 .with_projection(["name", "age"])
810 .with_key_condition(Key::from(Name::from("id")).equal(Num::new(42)))
811 .build();
812 assert_eq!(None, expression.condition_expression);
813
814 let filter = expression
815 .filter_expression
816 .as_deref()
817 .expect("A filter expression should be set");
818 assert_ne!("", filter);
819 println!("{filter}");
820
821 let projection = expression
822 .projection_expression
823 .as_deref()
824 .expect("A projection expression should be set");
825 assert_eq!("#0, #1", projection);
826 println!("Projection: {projection}");
827
828 println!("Names: {:?}", expression.expression_attribute_names);
829 println!("Values: {:?}", expression.expression_attribute_values);
830
831 let qi = expression.to_query_input_builder().build().unwrap();
832
833 println!("{qi:#?}");
834 }
835
836 #[test]
837 fn update() {
838 use crate::{Expression, Num, Path};
839 use pretty_assertions::assert_ne;
840
841 let expression = Expression::builder()
842 .with_condition(
843 "name".parse::<Path>().unwrap().attribute_exists().and(
844 "age"
845 .parse::<Path>()
846 .unwrap()
847 .greater_than_or_equal(Num::new(25)),
848 ),
849 )
850 .build();
851
852 let condition = expression
853 .condition_expression
854 .as_deref()
855 .expect("A condition expression should be set");
856 assert_ne!("", condition);
857 println!("{condition}");
858
859 println!("Names: {:?}", expression.expression_attribute_names);
860 println!("Values: {:?}", expression.expression_attribute_values);
861
862 let update = expression.to_update_builder().build();
863
864 println!("{update:#?}");
865 }
866}