Skip to content

Commit d6ff9e7

Browse files
Merge pull request #2205 from redis/DOC-5790-rust-dt-tces
DOC-5791 DOC-5792 Rust string and hash data type TCEs
2 parents 4afe633 + 8708bad commit d6ff9e7

File tree

5 files changed

+704
-1
lines changed

5 files changed

+704
-1
lines changed

content/develop/data-types/strings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ the [`MSET`]({{< relref "/commands/mset" >}}) and [`MGET`]({{< relref "/commands
7676

7777
When [`MGET`]({{< relref "/commands/mget" >}}) is used, Redis returns an array of values.
7878

79-
### Strings as counters
79+
## Strings as counters
8080
Even if strings are the basic values of Redis, there are interesting operations
8181
you can perform with them. For instance, one is atomic increment:
8282

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// EXAMPLE: hash_tutorial
2+
#[cfg(test)]
3+
mod tests {
4+
use redis::AsyncCommands;
5+
6+
#[tokio::test]
7+
async fn run() {
8+
let mut r = match redis::Client::open("redis://127.0.0.1") {
9+
Ok(client) => {
10+
match client.get_multiplexed_async_connection().await {
11+
Ok(conn) => conn,
12+
Err(e) => {
13+
println!("Failed to connect to Redis: {e}");
14+
return;
15+
}
16+
}
17+
},
18+
Err(e) => {
19+
println!("Failed to create Redis client: {e}");
20+
return;
21+
}
22+
};
23+
// REMOVE_START
24+
let _: () = r.flushall().await.expect("Failed to flushall");
25+
// REMOVE_END
26+
27+
// STEP_START set_get_all
28+
let hash_fields = [
29+
("model", "Deimos"),
30+
("brand", "Ergonom"),
31+
("type", "Enduro bikes"),
32+
("price", "4972"),
33+
];
34+
35+
if let Ok(res) = r.hset_multiple("bike:1", &hash_fields).await {
36+
let res: String = res;
37+
println!("{res}"); // >>> OK
38+
// REMOVE_START
39+
assert_eq!(res, "OK");
40+
// REMOVE_END
41+
}
42+
43+
match r.hget("bike:1", "model").await {
44+
Ok(res) => {
45+
let res: String = res;
46+
println!("{res}"); // >>> Deimos
47+
// REMOVE_START
48+
assert_eq!(res, "Deimos");
49+
// REMOVE_END
50+
},
51+
Err(e) => {
52+
println!("Error getting bike:1 model: {e}");
53+
return;
54+
}
55+
};
56+
57+
match r.hget("bike:1", "price").await {
58+
Ok(res) => {
59+
let res: String = res;
60+
println!("{res}"); // >>> 4972
61+
// REMOVE_START
62+
assert_eq!(res, "4972");
63+
// REMOVE_END
64+
},
65+
Err(e) => {
66+
println!("Error getting bike:1 price: {e}");
67+
return;
68+
}
69+
};
70+
71+
match r.hgetall("bike:1").await {
72+
Ok(res) => {
73+
let res: Vec<(String, String)> = res;
74+
println!("{res:?}");
75+
// >>> [("model", "Deimos"), ("brand", "Ergonom"), ("type", "Enduro bikes"), ("price", "4972")]
76+
// REMOVE_START
77+
assert_eq!(res.len(), 4);
78+
assert_eq!(res[0].0, "model");
79+
assert_eq!(res[0].1, "Deimos");
80+
assert_eq!(res[1].0, "brand");
81+
assert_eq!(res[1].1, "Ergonom");
82+
assert_eq!(res[2].0, "type");
83+
assert_eq!(res[2].1, "Enduro bikes");
84+
assert_eq!(res[3].0, "price");
85+
assert_eq!(res[3].1, "4972");
86+
// REMOVE_END
87+
},
88+
Err(e) => {
89+
println!("Error getting bike:1: {e}");
90+
return;
91+
}
92+
};
93+
// STEP_END
94+
95+
// STEP_START hmget
96+
match r.hmget("bike:1", &["model", "price"]).await {
97+
Ok(res) => {
98+
let res: Vec<String> = res;
99+
println!("{res:?}"); // >>> ["Deimos", "4972"]
100+
// REMOVE_START
101+
assert_eq!(res.len(), 2);
102+
assert_eq!(res[0], "Deimos");
103+
assert_eq!(res[1], "4972");
104+
// REMOVE_END
105+
},
106+
Err(e) => {
107+
println!("Error getting bike:1: {e}");
108+
return;
109+
}
110+
};
111+
// STEP_END
112+
113+
// STEP_START hincrby
114+
if let Ok(res) = r.hincr("bike:1", "price", 100).await {
115+
let res: i32 = res;
116+
println!("{res}"); // >>> 5072
117+
// REMOVE_START
118+
assert_eq!(res, 5072);
119+
// REMOVE_END
120+
}
121+
122+
if let Ok(res) = r.hincr("bike:1", "price", -100).await {
123+
let res: i32 = res;
124+
println!("{res}"); // >>> 4972
125+
// REMOVE_START
126+
assert_eq!(res, 4972);
127+
// REMOVE_END
128+
}
129+
// STEP_END
130+
131+
// STEP_START incrby_get_mget
132+
if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
133+
let res: i32 = res;
134+
println!("{res}"); // >>> 1
135+
// REMOVE_START
136+
assert_eq!(res, 1);
137+
// REMOVE_END
138+
}
139+
140+
if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
141+
let res: i32 = res;
142+
println!("{res}"); // >>> 2
143+
// REMOVE_START
144+
assert_eq!(res, 2);
145+
// REMOVE_END
146+
}
147+
148+
if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
149+
let res: i32 = res;
150+
println!("{res}"); // >>> 3
151+
// REMOVE_START
152+
assert_eq!(res, 3);
153+
// REMOVE_END
154+
}
155+
156+
if let Ok(res) = r.hincr("bike:1:stats", "crashes", 1).await {
157+
let res: i32 = res;
158+
println!("{res}"); // >>> 1
159+
// REMOVE_START
160+
assert_eq!(res, 1);
161+
// REMOVE_END
162+
}
163+
164+
if let Ok(res) = r.hincr("bike:1:stats", "owners", 1).await {
165+
let res: i32 = res;
166+
println!("{res}"); // >>> 1
167+
// REMOVE_START
168+
assert_eq!(res, 1);
169+
// REMOVE_END
170+
}
171+
172+
match r.hget("bike:1:stats", "rides").await {
173+
Ok(res) => {
174+
let res: i32 = res;
175+
println!("{res}"); // >>> 3
176+
// REMOVE_START
177+
assert_eq!(res, 3);
178+
// REMOVE_END
179+
},
180+
Err(e) => {
181+
println!("Error getting bike:1:stats rides: {e}");
182+
return;
183+
}
184+
};
185+
186+
match r.hmget("bike:1:stats", &["crashes", "owners"]).await {
187+
Ok(res) => {
188+
let res: Vec<i32> = res;
189+
println!("{res:?}"); // >>> [1, 1]
190+
// REMOVE_START
191+
assert_eq!(res.len(), 2);
192+
assert_eq!(res[0], 1);
193+
assert_eq!(res[1], 1);
194+
// REMOVE_END
195+
},
196+
Err(e) => {
197+
println!("Error getting bike:1:stats crashes and owners: {e}");
198+
return;
199+
}
200+
};
201+
// STEP_END
202+
}
203+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
2+
// EXAMPLE: set_tutorial
3+
#[cfg(test)]
4+
mod tests {
5+
use redis::{AsyncCommands, ExistenceCheck};
6+
7+
#[tokio::test]
8+
async fn run() {
9+
let mut r = match redis::Client::open("redis://127.0.0.1") {
10+
Ok(client) => {
11+
match client.get_multiplexed_async_connection().await {
12+
Ok(conn) => conn,
13+
Err(e) => {
14+
println!("Failed to connect to Redis: {e}");
15+
return;
16+
}
17+
}
18+
},
19+
Err(e) => {
20+
println!("Failed to create Redis client: {e}");
21+
return;
22+
}
23+
};
24+
25+
// STEP_START set_get
26+
if let Ok(res) = r.set("bike:1", "Deimos").await {
27+
let res: String = res;
28+
println!("{res}"); // >>> OK
29+
// REMOVE_START
30+
assert_eq!(res, "OK");
31+
// REMOVE_END
32+
}
33+
34+
match r.get("bike:1").await {
35+
Ok(res) => {
36+
let res: String = res;
37+
println!("{res}"); // >>> Deimos
38+
// REMOVE_START
39+
assert_eq!(res, "Deimos");
40+
// REMOVE_END
41+
},
42+
Err(e) => {
43+
println!("Error getting foo: {e}");
44+
return;
45+
}
46+
};
47+
// STEP_END
48+
49+
// STEP_START setnx_xx
50+
if let Ok(res) = r.set_options("bike:1", "bike", redis::SetOptions::default().conditional_set(ExistenceCheck::NX)).await {
51+
let res: bool = res;
52+
println!("{res}"); // >>> false
53+
// REMOVE_START
54+
assert!(!res);
55+
// REMOVE_END
56+
}
57+
58+
match r.get("bike:1").await {
59+
Ok(res) => {
60+
let res: String = res;
61+
println!("{res}"); // >>> Deimos
62+
// REMOVE_START
63+
assert_eq!(res, "Deimos");
64+
// REMOVE_END
65+
},
66+
Err(e) => {
67+
println!("Error getting foo: {e}");
68+
return;
69+
}
70+
};
71+
72+
if let Ok(res) = r.set_options("bike:1", "bike", redis::SetOptions::default().conditional_set(ExistenceCheck::XX)).await {
73+
let res: String = res;
74+
println!("{res}"); // >>> OK
75+
// REMOVE_START
76+
assert_eq!(res, "OK");
77+
// REMOVE_END
78+
}
79+
80+
match r.get("bike:1").await {
81+
Ok(res) => {
82+
let res: String = res;
83+
println!("{res}"); // >>> bike
84+
// REMOVE_START
85+
assert_eq!(res, "bike");
86+
// REMOVE_END
87+
},
88+
Err(e) => {
89+
println!("Error getting foo: {e}");
90+
return;
91+
}
92+
};
93+
// STEP_END
94+
95+
// STEP_START mset
96+
if let Ok(res) = r.mset(&[("bike:1", "Deimos"), ("bike:2", "Ares"), ("bike:3", "Vanth")]).await {
97+
let res: String = res;
98+
println!("{res}"); // >>> OK
99+
// REMOVE_START
100+
assert_eq!(res, "OK");
101+
// REMOVE_END
102+
}
103+
104+
match r.mget(&["bike:1", "bike:2", "bike:3"]).await {
105+
Ok(res) => {
106+
let res: Vec<String> = res;
107+
println!("{res:?}"); // >>> ["Deimos", "Ares", "Vanth"]
108+
// REMOVE_START
109+
assert_eq!(res.len(), 3);
110+
assert_eq!(res[0], "Deimos");
111+
assert_eq!(res[1], "Ares");
112+
assert_eq!(res[2], "Vanth");
113+
// REMOVE_END
114+
},
115+
Err(e) => {
116+
println!("Error getting foo: {e}");
117+
return;
118+
}
119+
};
120+
// STEP_END
121+
122+
// STEP_START incr
123+
if let Ok(res) = r.set("total_crashes", 0).await {
124+
let res: String = res;
125+
println!("{res}"); // >>> OK
126+
// REMOVE_START
127+
assert_eq!(res, "OK");
128+
// REMOVE_END
129+
}
130+
131+
if let Ok(res) = r.incr("total_crashes", 1).await {
132+
let res: i32 = res;
133+
println!("{res}"); // >>> 1
134+
// REMOVE_START
135+
assert_eq!(res, 1);
136+
// REMOVE_END
137+
}
138+
139+
if let Ok(res) = r.incr("total_crashes", 10).await {
140+
let res: i32 = res;
141+
println!("{res}"); // >>> 11
142+
// REMOVE_START
143+
assert_eq!(res, 11);
144+
// REMOVE_END
145+
}
146+
// STEP_END
147+
}
148+
}

0 commit comments

Comments
 (0)