|
14 | 14 | //! AWS typed values feel more natural and ergonomic in Rust. Where a conversion is not available you can implement `Attribute` for your own
|
15 | 15 | //! types to leverage higher level functionality.
|
16 | 16 | //!
|
17 |
| -//! The [Item](trait.Item.html) type |
| 17 | +//! The [Item](trait.Item.html) trait |
18 | 18 | //! provides conversion interfaces for complex types which represent
|
19 | 19 | //! DynamoDB's notion of "items".
|
20 | 20 | //!
|
21 |
| -//! 💡 A cargo feature named "derive" makes it easy to derive `Item` instances for your custom types. This feature is enabled by default. |
| 21 | +//! 💡 A cargo feature named `"derive"` makes it easy to derive `Item` instances for your custom types. This feature is enabled by default. |
22 | 22 | //!
|
23 | 23 | //!
|
24 | 24 | //! ```rust,no_run
|
|
33 | 33 | //! order_id: Uuid,
|
34 | 34 | //! color: Option<String>,
|
35 | 35 | //! }
|
| 36 | +//! ``` |
36 | 37 | //!
|
37 |
| -//! #[derive(Item)] |
38 |
| -//! struct ShoppingCart { |
39 |
| -//! #[dynomite(partition_key)] |
40 |
| -//! id: Uuid, |
41 |
| -//! // A separate struct to store data without any id |
42 |
| -//! #[dynomite(flatten)] |
43 |
| -//! data: ShoppingCartData, |
44 |
| -//! // Collect all other additional attributes into a map |
45 |
| -//! // Beware that the order of declaration will affect the order of |
46 |
| -//! // evaluation, so this "wildcard" flatten clause should be the last member |
47 |
| -//! #[dynomite(flatten)] |
48 |
| -//! remaining_props: Attributes, |
49 |
| -//! } |
| 38 | +//! ## Attributes |
| 39 | +//! |
| 40 | +//! ### `#[derive(Item)]` |
| 41 | +//! Used to define a top-level DynamoDB item. |
| 42 | +//! Generates a `<ItemName>Key` struct with only `partition_key/sort_key` |
| 43 | +//! fields to be used for type-safe primary key construction. |
| 44 | +//! This automatically derives [`Attributes`](#deriveattributes) too. |
50 | 45 | //!
|
51 |
| -//! // `Attributes` doesn't require neither of #[dynomite(partition_key/sort_key)] |
| 46 | +//! For the `Order` struct from the example higher this will generate an `OrderKey` |
| 47 | +//! struct like this: |
| 48 | +//! |
| 49 | +//! ```rust |
| 50 | +//! # use uuid::Uuid; |
| 51 | +//! # use dynomite::Attributes; |
52 | 52 | //! #[derive(Attributes)]
|
53 |
| -//! struct ShoppingCartData { |
54 |
| -//! // use Default value of the field if it is absent in DynamoDb |
55 |
| -//! #[dynomite(default)] |
56 |
| -//! orders: Vec<Order>, |
57 |
| -//! name: String, |
| 53 | +//! struct OrderKey { |
| 54 | +//! user: Uuid, |
| 55 | +//! order_id: Uuid, |
| 56 | +//! } |
| 57 | +//! ``` |
| 58 | +//! |
| 59 | +//! Use it to safely and conveniently construct the primary key: |
| 60 | +//! |
| 61 | +//! ```rust |
| 62 | +//! # #[derive(dynomite::Attributes)] |
| 63 | +//! # struct Order {} |
| 64 | +//! # #[derive(Attributes)] |
| 65 | +//! # struct OrderKey { |
| 66 | +//! # user: Uuid, |
| 67 | +//! # order_id: Uuid, |
| 68 | +//! # } |
| 69 | +//! use dynomite::{Attributes, FromAttributes, dynamodb::{GetItemInput, DynamoDb}}; |
| 70 | +//! use std::error::Error; |
| 71 | +//! use uuid::Uuid; |
| 72 | +//! |
| 73 | +//! async fn get_order( |
| 74 | +//! client: impl DynamoDb, |
| 75 | +//! user: Uuid, |
| 76 | +//! order_id: Uuid, |
| 77 | +//! ) -> Result<Option<Order>, Box<dyn Error>> { |
| 78 | +//! // Use the generated `OrderKey` struct to create a primary key |
| 79 | +//! let key = OrderKey { user, order_id }; |
| 80 | +//! // Convert stronly-typed `OrderKey` to a map of `rusoto_dynamodb::AttributeValue` |
| 81 | +//! let key: Attributes = key.into(); |
| 82 | +//! |
| 83 | +//! let result = client.get_item(GetItemInput { |
| 84 | +//! table_name: "orders".into(), |
| 85 | +//! key, |
| 86 | +//! ..Default::default() |
| 87 | +//! }).await?; |
| 88 | +//! |
| 89 | +//! Ok(result.item.map(|item| { |
| 90 | +//! Order::from_attrs(item).expect("Invalid order, db corruption?") |
| 91 | +//! })) |
58 | 92 | //! }
|
59 | 93 | //! ```
|
60 | 94 | //!
|
| 95 | +//! - `#[dynomite(partition_key)]` - required attribute, expected to be applied the target |
| 96 | +//! [partition attribute][partition-key] field with a derivable DynamoDB attribute value |
| 97 | +//! of String, Number or Binary |
| 98 | +//! |
| 99 | +//! - `#[dynomite(sort_key)]` - optional attribute, may be applied to one target |
| 100 | +//! [sort attribute](sort-key) field with an derivable DynamoDB attribute value |
| 101 | +//! of String, Number or Binary |
| 102 | +//! |
| 103 | +//! - All other attributes are the same as for [`#[derive(Attributes)]`](#deriveattributes) |
| 104 | +//! |
| 105 | +//! ### `#[derive(Attributes)]` |
| 106 | +//! |
| 107 | +//! Used to derive an implementation of `From/IntoAttributes` trait to allow for |
| 108 | +//! serializing/deserializing map-like types into [`AttributeValue`] |
| 109 | +//! |
| 110 | +//! - `#[dynomite(rename = "actualName")]` - optional attribute, may be applied to any item |
| 111 | +//! attribute field, useful when the DynamoDB table you're interfacing with has |
| 112 | +//! attributes whose names don't following Rust's naming conventions |
| 113 | +//! |
| 114 | +//! - `#[dynomite(default)]` - use [`Default::default`] implementation of the field type |
| 115 | +//! if the attribute is absent when deserializing from `Attributes` |
| 116 | +//! |
| 117 | +//! ``` |
| 118 | +//! use dynomite::Attributes; |
| 119 | +//! |
| 120 | +//! #[derive(Attributes)] |
| 121 | +//! struct Todos { |
| 122 | +//! // use Default value of the field if it is absent in DynamoDb (empty vector) |
| 123 | +//! #[dynomite(default)] |
| 124 | +//! items: Vec<String>, |
| 125 | +//! list_name: String, |
| 126 | +//! } |
| 127 | +//! ``` |
| 128 | +//! |
| 129 | +//! - `#[dynomite(flatten)]` - flattens the fields of other struct that also derives `Attributes` |
| 130 | +//! into the current struct. |
| 131 | +//! |
| 132 | +//! 💡 If this attribute is placed onto a field, no other `dynomite` attributes |
| 133 | +//! are alowed on this field (this restriction may be relaxed in future). |
| 134 | +//! |
| 135 | +//! This is reminiscent of [`#[serde(flatten)]`](serde-flatten). The order of |
| 136 | +//! declaration of `flatten`ed fields matters, if the struct has to fields with |
| 137 | +//! `#[dynomite(flatten)]` attribute the one that appears higher in code will |
| 138 | +//! be evaluated before the other one. This is crucial when you want to collect |
| 139 | +//! additional properties into a map: |
| 140 | +//! |
| 141 | +//! ``` |
| 142 | +//! use dynomite::{Attributes, Item}; |
| 143 | +//! |
| 144 | +//! #[derive(Item)] |
| 145 | +//! struct ShoppingCart { |
| 146 | +//! #[dynomite(partition_key)] |
| 147 | +//! id: String, |
| 148 | +//! // A separate struct to store data without any id |
| 149 | +//! #[dynomite(flatten)] |
| 150 | +//! data: ShoppingCartData, |
| 151 | +//! // Collect all other additional attributes into a map |
| 152 | +//! // Beware that the order of declaration will affect the order of |
| 153 | +//! // evaluation, so this "wildcard" flatten clause should be the last member |
| 154 | +//! #[dynomite(flatten)] |
| 155 | +//! remaining_props: Attributes, |
| 156 | +//! } |
| 157 | +//! |
| 158 | +//! // `Attributes` doesn't require neither of #[dynomite(partition_key/sort_key)] |
| 159 | +//! #[derive(Attributes)] |
| 160 | +//! struct ShoppingCartData { |
| 161 | +//! name: String, |
| 162 | +//! total_price: u32, |
| 163 | +//! } |
| 164 | +//! ``` |
| 165 | +//! |
61 | 166 | //! ## Rusoto extensions
|
62 | 167 | //!
|
63 | 168 | //! By importing the [dynomite::DynamoDbExt](trait.DynamoDbExt.html) trait, dynomite
|
|
110 | 215 | //! default-features = false
|
111 | 216 | //! features = ["feature-you-want"]
|
112 | 217 | //! ```
|
| 218 | +//! |
| 219 | +//! [partition-key]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey |
| 220 | +//! [sort-key]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.SecondaryIndexes |
| 221 | +//! [`Default::default`]: https://doc.rust-lang.org/stable/std/default/trait.Default.html#tymethod.default |
| 222 | +//! [`AttributeValue`]: https://docs.rs/rusoto_dynamodb/*/rusoto_dynamodb/struct.AttributeValue.html |
113 | 223 |
|
114 | 224 | #![deny(missing_docs)]
|
115 | 225 | // reexported
|
|
0 commit comments