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}