aws_lite_rs/api/
dynamodb.rs1use crate::{
8 AwsHttpClient, Result,
9 ops::dynamodb::DynamodbOps,
10 types::dynamodb::{
11 DeleteTableInput, DeleteTableOutput, DescribeTableInput, DescribeTableOutput,
12 ListTablesInput, ListTablesOutput, UpdateTableInput, UpdateTableOutput,
13 },
14};
15
16pub struct DynamodbClient<'a> {
18 ops: DynamodbOps<'a>,
19}
20
21impl<'a> DynamodbClient<'a> {
22 pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
24 Self {
25 ops: DynamodbOps::new(client),
26 }
27 }
28
29 pub async fn list_tables(&self, body: &ListTablesInput) -> Result<ListTablesOutput> {
31 self.ops.list_tables(body).await
32 }
33
34 pub async fn describe_table(&self, body: &DescribeTableInput) -> Result<DescribeTableOutput> {
36 self.ops.describe_table(body).await
37 }
38
39 pub async fn update_table(&self, body: &UpdateTableInput) -> Result<UpdateTableOutput> {
41 self.ops.update_table(body).await
42 }
43
44 pub async fn delete_table(&self, body: &DeleteTableInput) -> Result<DeleteTableOutput> {
46 self.ops.delete_table(body).await
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::types::dynamodb::ProvisionedThroughput;
54
55 #[tokio::test]
56 async fn list_tables_returns_names() {
57 let mut mock = crate::MockClient::new();
58 mock.expect_post("/").returning_json(serde_json::json!({
59 "TableNames": ["orders", "users", "products"],
60 "LastEvaluatedTableName": "products"
61 }));
62 let client = crate::AwsHttpClient::from_mock(mock);
63 let result = client
64 .dynamodb()
65 .list_tables(&ListTablesInput::default())
66 .await
67 .unwrap();
68 assert_eq!(result.table_names, vec!["orders", "users", "products"]);
69 assert_eq!(
70 result.last_evaluated_table_name.as_deref(),
71 Some("products")
72 );
73 }
74
75 #[tokio::test]
76 async fn describe_table_returns_details() {
77 let mut mock = crate::MockClient::new();
78 mock.expect_post("/").returning_json(serde_json::json!({
79 "Table": {
80 "TableName": "orders",
81 "TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/orders",
82 "TableId": "abc-123",
83 "TableStatus": "ACTIVE",
84 "CreationDateTime": 1700000000.0,
85 "ItemCount": 42,
86 "TableSizeBytes": 8192,
87 "BillingModeSummary": {
88 "BillingMode": "PAY_PER_REQUEST"
89 },
90 "KeySchema": [{
91 "AttributeName": "pk",
92 "KeyType": "HASH"
93 }],
94 "AttributeDefinitions": [{
95 "AttributeName": "pk",
96 "AttributeType": "S"
97 }]
98 }
99 }));
100 let client = crate::AwsHttpClient::from_mock(mock);
101 let result = client
102 .dynamodb()
103 .describe_table(&DescribeTableInput {
104 table_name: "orders".to_string(),
105 })
106 .await
107 .unwrap();
108 let table = result.table.unwrap();
109 assert_eq!(table.table_name.as_deref(), Some("orders"));
110 assert_eq!(table.table_status.as_deref(), Some("ACTIVE"));
111 assert_eq!(table.item_count, Some(42));
112 assert_eq!(table.key_schema[0].attribute_name, "pk");
113 assert_eq!(table.key_schema[0].key_type, "HASH");
114 assert_eq!(
115 table.billing_mode_summary.unwrap().billing_mode.as_deref(),
116 Some("PAY_PER_REQUEST"),
117 );
118 }
119
120 #[tokio::test]
121 async fn update_table_changes_billing_mode() {
122 let mut mock = crate::MockClient::new();
123 mock.expect_post("/").returning_json(serde_json::json!({
124 "TableDescription": {
125 "TableName": "orders",
126 "TableStatus": "UPDATING",
127 "ProvisionedThroughput": {
128 "ReadCapacityUnits": 10,
129 "WriteCapacityUnits": 5
130 }
131 }
132 }));
133 let client = crate::AwsHttpClient::from_mock(mock);
134 let result = client
135 .dynamodb()
136 .update_table(&UpdateTableInput {
137 table_name: "orders".to_string(),
138 billing_mode: Some("PROVISIONED".to_string()),
139 provisioned_throughput: Some(ProvisionedThroughput {
140 read_capacity_units: 10,
141 write_capacity_units: 5,
142 }),
143 ..Default::default()
144 })
145 .await
146 .unwrap();
147 let desc = result.table_description.unwrap();
148 assert_eq!(desc.table_name.as_deref(), Some("orders"));
149 assert_eq!(desc.table_status.as_deref(), Some("UPDATING"));
150 let tp = desc.provisioned_throughput.unwrap();
151 assert_eq!(tp.read_capacity_units, Some(10));
152 assert_eq!(tp.write_capacity_units, Some(5));
153 }
154
155 #[tokio::test]
156 async fn delete_table_returns_deleting_status() {
157 let mut mock = crate::MockClient::new();
158 mock.expect_post("/").returning_json(serde_json::json!({
159 "TableDescription": {
160 "TableName": "orders",
161 "TableStatus": "DELETING",
162 "TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/orders"
163 }
164 }));
165 let client = crate::AwsHttpClient::from_mock(mock);
166 let result = client
167 .dynamodb()
168 .delete_table(&DeleteTableInput {
169 table_name: "orders".to_string(),
170 })
171 .await
172 .unwrap();
173 let desc = result.table_description.unwrap();
174 assert_eq!(desc.table_name.as_deref(), Some("orders"));
175 assert_eq!(desc.table_status.as_deref(), Some("DELETING"));
176 }
177}