Skip to main content

rustack_dynamodb_model/
output.rs

1//! DynamoDB output types for the 12 MVP operations.
2//!
3//! All output structs use `PascalCase` JSON field naming to match the DynamoDB
4//! wire protocol (`awsJson1_0`). Optional fields are omitted when `None`,
5//! empty `HashMap`s and `Vec`s are omitted to produce minimal JSON responses.
6
7use std::collections::HashMap;
8
9use serde::{Deserialize, Serialize};
10
11use crate::{
12    attribute_value::AttributeValue,
13    types::{
14        ConsumedCapacity, ItemCollectionMetrics, ItemResponse, KeysAndAttributes, TableDescription,
15        Tag, TimeToLiveDescription, TimeToLiveSpecification, WriteRequest,
16    },
17};
18
19// ---------------------------------------------------------------------------
20// Table management
21// ---------------------------------------------------------------------------
22
23/// Output for the `CreateTable` operation.
24#[derive(Debug, Clone, Default, Serialize, Deserialize)]
25#[serde(rename_all = "PascalCase")]
26pub struct CreateTableOutput {
27    /// The properties of the newly created table.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub table_description: Option<TableDescription>,
30}
31
32/// Output for the `DeleteTable` operation.
33#[derive(Debug, Clone, Default, Serialize, Deserialize)]
34#[serde(rename_all = "PascalCase")]
35pub struct DeleteTableOutput {
36    /// The properties of the table that was deleted.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub table_description: Option<TableDescription>,
39}
40
41/// Output for the `DescribeTable` operation.
42#[derive(Debug, Clone, Default, Serialize, Deserialize)]
43#[serde(rename_all = "PascalCase")]
44pub struct DescribeTableOutput {
45    /// The properties of the table.
46    #[serde(rename = "Table", skip_serializing_if = "Option::is_none")]
47    pub table: Option<TableDescription>,
48}
49
50/// Output for the `UpdateTable` operation.
51#[derive(Debug, Clone, Default, Serialize, Deserialize)]
52#[serde(rename_all = "PascalCase")]
53pub struct UpdateTableOutput {
54    /// The properties of the updated table.
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub table_description: Option<TableDescription>,
57}
58
59/// Output for the `ListTables` operation.
60#[derive(Debug, Clone, Default, Serialize, Deserialize)]
61#[serde(rename_all = "PascalCase")]
62pub struct ListTablesOutput {
63    /// The names of the tables associated with the current account and region.
64    #[serde(default)]
65    pub table_names: Vec<String>,
66
67    /// The name of the last table in the current page of results. Use this
68    /// value as `ExclusiveStartTableName` in a subsequent request to continue.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub last_evaluated_table_name: Option<String>,
71}
72
73// ---------------------------------------------------------------------------
74// Item CRUD
75// ---------------------------------------------------------------------------
76
77/// Output for the `PutItem` operation.
78#[derive(Debug, Clone, Default, Serialize, Deserialize)]
79#[serde(rename_all = "PascalCase")]
80pub struct PutItemOutput {
81    /// The attribute values as they appeared before the `PutItem` operation
82    /// (only returned when `ReturnValues` is specified).
83    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
84    pub attributes: HashMap<String, AttributeValue>,
85
86    /// The capacity units consumed by the operation.
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub consumed_capacity: Option<ConsumedCapacity>,
89
90    /// Information about item collections modified by the operation.
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub item_collection_metrics: Option<ItemCollectionMetrics>,
93}
94
95/// Output for the `GetItem` operation.
96#[derive(Debug, Clone, Default, Serialize, Deserialize)]
97#[serde(rename_all = "PascalCase")]
98pub struct GetItemOutput {
99    /// A map of attribute names to `AttributeValue` objects for the retrieved
100    /// item. Returns `None` if the item does not exist.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub item: Option<HashMap<String, AttributeValue>>,
103
104    /// The capacity units consumed by the operation.
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub consumed_capacity: Option<ConsumedCapacity>,
107}
108
109/// Output for the `UpdateItem` operation.
110#[derive(Debug, Clone, Default, Serialize, Deserialize)]
111#[serde(rename_all = "PascalCase")]
112pub struct UpdateItemOutput {
113    /// The attribute values as they appeared before or after the update
114    /// (depending on the `ReturnValues` setting).
115    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
116    pub attributes: HashMap<String, AttributeValue>,
117
118    /// The capacity units consumed by the operation.
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub consumed_capacity: Option<ConsumedCapacity>,
121
122    /// Information about item collections modified by the operation.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub item_collection_metrics: Option<ItemCollectionMetrics>,
125}
126
127/// Output for the `DeleteItem` operation.
128#[derive(Debug, Clone, Default, Serialize, Deserialize)]
129#[serde(rename_all = "PascalCase")]
130pub struct DeleteItemOutput {
131    /// The attribute values as they appeared before the deletion (only
132    /// returned when `ReturnValues` is `ALL_OLD`).
133    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
134    pub attributes: HashMap<String, AttributeValue>,
135
136    /// The capacity units consumed by the operation.
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub consumed_capacity: Option<ConsumedCapacity>,
139
140    /// Information about item collections modified by the operation.
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub item_collection_metrics: Option<ItemCollectionMetrics>,
143}
144
145// ---------------------------------------------------------------------------
146// Query & Scan
147// ---------------------------------------------------------------------------
148
149/// Output for the `Query` operation.
150#[derive(Debug, Clone, Default, Serialize, Deserialize)]
151#[serde(rename_all = "PascalCase")]
152pub struct QueryOutput {
153    /// An array of item attributes that match the query conditions.
154    /// `None` when `Select=COUNT` (omitted from JSON), `Some(vec)` otherwise
155    /// (always serialized, even when empty).
156    #[serde(default, skip_serializing_if = "Option::is_none")]
157    pub items: Option<Vec<HashMap<String, AttributeValue>>>,
158
159    /// The number of items in the response.
160    pub count: i32,
161
162    /// The number of items evaluated before the filter expression was applied.
163    pub scanned_count: i32,
164
165    /// The primary key of the item where the query operation stopped. Use this
166    /// value as `ExclusiveStartKey` in a subsequent query to continue.
167    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
168    pub last_evaluated_key: HashMap<String, AttributeValue>,
169
170    /// The capacity units consumed by the operation.
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub consumed_capacity: Option<ConsumedCapacity>,
173}
174
175/// Output for the `Scan` operation.
176#[derive(Debug, Clone, Default, Serialize, Deserialize)]
177#[serde(rename_all = "PascalCase")]
178pub struct ScanOutput {
179    /// An array of item attributes that match the scan conditions.
180    /// `None` when `Select=COUNT` (omitted from JSON), `Some(vec)` otherwise
181    /// (always serialized, even when empty).
182    #[serde(default, skip_serializing_if = "Option::is_none")]
183    pub items: Option<Vec<HashMap<String, AttributeValue>>>,
184
185    /// The number of items in the response.
186    pub count: i32,
187
188    /// The number of items evaluated before the filter expression was applied.
189    pub scanned_count: i32,
190
191    /// The primary key of the item where the scan operation stopped. Use this
192    /// value as `ExclusiveStartKey` in a subsequent scan to continue.
193    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
194    pub last_evaluated_key: HashMap<String, AttributeValue>,
195
196    /// The capacity units consumed by the operation.
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub consumed_capacity: Option<ConsumedCapacity>,
199}
200
201// ---------------------------------------------------------------------------
202// Batch operations
203// ---------------------------------------------------------------------------
204
205/// Output for the `BatchGetItem` operation.
206#[derive(Debug, Clone, Default, Serialize, Deserialize)]
207#[serde(rename_all = "PascalCase")]
208pub struct BatchGetItemOutput {
209    /// A map of table names to the items retrieved from each table.
210    #[serde(default)]
211    pub responses: HashMap<String, Vec<HashMap<String, AttributeValue>>>,
212
213    /// A map of tables and their respective keys that were not processed. Use
214    /// these values as `RequestItems` in a subsequent `BatchGetItem` call.
215    #[serde(default)]
216    pub unprocessed_keys: HashMap<String, KeysAndAttributes>,
217
218    /// The capacity units consumed by the operation for each table.
219    #[serde(default, skip_serializing_if = "Vec::is_empty")]
220    pub consumed_capacity: Vec<ConsumedCapacity>,
221}
222
223/// Output for the `BatchWriteItem` operation.
224#[derive(Debug, Clone, Default, Serialize, Deserialize)]
225#[serde(rename_all = "PascalCase")]
226pub struct BatchWriteItemOutput {
227    /// A map of tables and their respective `WriteRequest` objects that were
228    /// not processed. Use these values as `RequestItems` in a subsequent
229    /// `BatchWriteItem` call.
230    #[serde(default)]
231    pub unprocessed_items: HashMap<String, Vec<WriteRequest>>,
232
233    /// A map of tables to item collection metrics for the tables that were
234    /// affected by the operation.
235    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
236    pub item_collection_metrics: HashMap<String, Vec<ItemCollectionMetrics>>,
237
238    /// The capacity units consumed by the operation for each table.
239    #[serde(default, skip_serializing_if = "Vec::is_empty")]
240    pub consumed_capacity: Vec<ConsumedCapacity>,
241}
242
243// ---------------------------------------------------------------------------
244// Tagging
245// ---------------------------------------------------------------------------
246
247/// Output for the `TagResource` operation.
248#[derive(Debug, Clone, Default, Serialize, Deserialize)]
249#[serde(rename_all = "PascalCase")]
250pub struct TagResourceOutput {}
251
252/// Output for the `UntagResource` operation.
253#[derive(Debug, Clone, Default, Serialize, Deserialize)]
254#[serde(rename_all = "PascalCase")]
255pub struct UntagResourceOutput {}
256
257/// Output for the `ListTagsOfResource` operation.
258#[derive(Debug, Clone, Default, Serialize, Deserialize)]
259#[serde(rename_all = "PascalCase")]
260pub struct ListTagsOfResourceOutput {
261    /// The tags associated with the resource.
262    #[serde(skip_serializing_if = "Option::is_none")]
263    pub tags: Option<Vec<Tag>>,
264    /// A pagination token for subsequent requests.
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub next_token: Option<String>,
267}
268
269// ---------------------------------------------------------------------------
270// Time to Live
271// ---------------------------------------------------------------------------
272
273/// Output for the `UpdateTimeToLive` operation.
274#[derive(Debug, Clone, Default, Serialize, Deserialize)]
275#[serde(rename_all = "PascalCase")]
276pub struct UpdateTimeToLiveOutput {
277    /// The TTL specification that was applied.
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub time_to_live_specification: Option<TimeToLiveSpecification>,
280}
281
282/// Output for the `DescribeTimeToLive` operation.
283#[derive(Debug, Clone, Default, Serialize, Deserialize)]
284#[serde(rename_all = "PascalCase")]
285pub struct DescribeTimeToLiveOutput {
286    /// The current TTL description for the table.
287    #[serde(skip_serializing_if = "Option::is_none")]
288    pub time_to_live_description: Option<TimeToLiveDescription>,
289}
290
291// ---------------------------------------------------------------------------
292// Transactions
293// ---------------------------------------------------------------------------
294
295/// Output for the `TransactWriteItems` operation.
296#[derive(Debug, Clone, Default, Serialize, Deserialize)]
297#[serde(rename_all = "PascalCase")]
298pub struct TransactWriteItemsOutput {
299    /// The capacity units consumed by the operation for each table.
300    #[serde(default, skip_serializing_if = "Vec::is_empty")]
301    pub consumed_capacity: Vec<ConsumedCapacity>,
302    /// Item collection metrics for the affected tables.
303    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
304    pub item_collection_metrics: HashMap<String, Vec<ItemCollectionMetrics>>,
305}
306
307/// Output for the `TransactGetItems` operation.
308#[derive(Debug, Clone, Default, Serialize, Deserialize)]
309#[serde(rename_all = "PascalCase")]
310pub struct TransactGetItemsOutput {
311    /// The capacity units consumed by the operation for each table.
312    #[serde(default, skip_serializing_if = "Vec::is_empty")]
313    pub consumed_capacity: Vec<ConsumedCapacity>,
314    /// The items retrieved, in the same order as the input.
315    #[serde(skip_serializing_if = "Option::is_none")]
316    pub responses: Option<Vec<ItemResponse>>,
317}
318
319// ---------------------------------------------------------------------------
320// Describe operations
321// ---------------------------------------------------------------------------
322
323/// Output for the `DescribeLimits` operation.
324#[derive(Debug, Clone, Default, Serialize, Deserialize)]
325#[serde(rename_all = "PascalCase")]
326pub struct DescribeLimitsOutput {
327    /// Maximum read capacity units per account.
328    #[serde(skip_serializing_if = "Option::is_none")]
329    pub account_max_read_capacity_units: Option<i64>,
330    /// Maximum write capacity units per account.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub account_max_write_capacity_units: Option<i64>,
333    /// Maximum read capacity units per table.
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub table_max_read_capacity_units: Option<i64>,
336    /// Maximum write capacity units per table.
337    #[serde(skip_serializing_if = "Option::is_none")]
338    pub table_max_write_capacity_units: Option<i64>,
339}
340
341/// Output for the `DescribeEndpoints` operation.
342#[derive(Debug, Clone, Default, Serialize, Deserialize)]
343#[serde(rename_all = "PascalCase")]
344pub struct DescribeEndpointsOutput {
345    /// The list of endpoints.
346    pub endpoints: Vec<Endpoint>,
347}
348
349/// A DynamoDB endpoint descriptor.
350#[derive(Debug, Clone, Default, Serialize, Deserialize)]
351#[serde(rename_all = "PascalCase")]
352pub struct Endpoint {
353    /// The endpoint address.
354    pub address: String,
355    /// The cache period in minutes.
356    pub cache_period_in_minutes: i64,
357}