-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathdemo.rs
131 lines (120 loc) · 4.28 KB
/
demo.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#[macro_use]
extern crate dynomite;
#[macro_use]
extern crate dynomite_derive;
extern crate futures;
extern crate rusoto_core;
extern crate tokio;
extern crate uuid;
use std::sync::Arc;
use dynamodb::{
AttributeDefinition, CreateTableInput, DynamoDb, DynamoDbClient, GetItemInput,
KeySchemaElement, ProvisionedThroughput, PutItemInput, ScanInput,
};
// dynomite re-exports `rusoto_dynamodb` for convenience
use dynomite::dynamodb;
// this enables extension methods on `DynamoDB` clients
use dynomite::DynamoDbExt;
// this enables a types to be coersed from attribute maps
use dynomite::FromAttributes;
// this enables `Item` methods on types which Item is implemented or derived for
use dynomite::Item;
use futures::{Future, Stream};
use tokio::runtime::Runtime;
use uuid::Uuid;
#[derive(Item, Debug, Clone)]
pub struct Book {
#[hash]
id: Uuid,
title: String,
}
// this will create a rust book shelf in your aws account!
fn main() {
let mut rt = Runtime::new().expect("failed to initialize futures runtime");
// create rusoto client
let client = Arc::new(DynamoDbClient::new(Default::default()));
// create a book table with a single string (S) primary key.
// if this table does not already exists
// this may take a second or two to provision.
// it will fail if this table already exists but that's okay,
// this is just an example :)
let table_name = "books".to_string();
let _ = rt.block_on(client.create_table(CreateTableInput {
table_name: table_name.clone(),
key_schema: vec![KeySchemaElement {
attribute_name: "id".into(),
key_type: "HASH".into(),
}],
attribute_definitions: vec![AttributeDefinition {
attribute_name: "id".into(),
attribute_type: "S".into(),
}],
provisioned_throughput: ProvisionedThroughput {
read_capacity_units: 1,
write_capacity_units: 1,
},
..CreateTableInput::default()
}));
let book = Book {
id: Uuid::new_v4(),
title: "rust".into(),
};
// print the key for this book
// requires bringing `dynomite::Item` into scope
println!("book.key() {:#?}", book.key());
// add a book to the shelf
println!(
"put_item() result {:#?}",
rt.block_on(client.put_item(PutItemInput {
table_name: table_name.clone(),
item: book.clone().into(), // <= convert book into it's attribute map representation
..PutItemInput::default()
}))
);
println!(
"put_item() result {:#?}",
rt.block_on(
client.put_item(PutItemInput {
table_name: table_name.clone(),
// convert book into it's attribute map representation
item: Book {
id: Uuid::new_v4(),
title: "rust and beyond".into(),
}
.into(),
..PutItemInput::default()
})
)
);
// scan through all pages of results in the books table for books who's title is "rust"
println!(
"scan result {:#?}",
rt.block_on(
client
.clone()
.stream_scan(ScanInput {
limit: Some(1), // to demonstrate we're getting through more than one page
table_name: table_name.clone(),
filter_expression: Some("title = :title".into()),
expression_attribute_values: Some(attr_map!(
":title" => "rust".to_string()
)),
..ScanInput::default()
})
.for_each(|item| Ok(println!("stream_scan() item {:#?}", Book::from_attrs(item)))) // attempt to convert a attribute map to a book type
),
);
// get the "rust' book by the Book type's generated key
println!(
"get_item() result {:#?}",
rt.block_on(
client
.get_item(GetItemInput {
table_name: table_name.clone(),
key: book.clone().key(), // get a book by key
..GetItemInput::default()
})
.map(|result| result.item.map(Book::from_attrs)) // attempt to convert a attribute map to a book type
)
);
}