Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/develop/data-types/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ the [`MSET`]({{< relref "/commands/mset" >}}) and [`MGET`]({{< relref "/commands

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

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

Expand Down
203 changes: 203 additions & 0 deletions local_examples/rust-async/dt-hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// EXAMPLE: hash_tutorial
#[cfg(test)]
mod tests {
use redis::AsyncCommands;

#[tokio::test]
async fn run() {
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_multiplexed_async_connection().await {
Ok(conn) => conn,
Err(e) => {
println!("Failed to connect to Redis: {e}");
return;
}
}
},
Err(e) => {
println!("Failed to create Redis client: {e}");
return;
}
};
// REMOVE_START
let _: () = r.flushall().await.expect("Failed to flushall");
// REMOVE_END

// STEP_START set_get_all
let hash_fields = [
("model", "Deimos"),
("brand", "Ergonom"),
("type", "Enduro bikes"),
("price", "4972"),
];

if let Ok(res) = r.hset_multiple("bike:1", &hash_fields).await {
let res: String = res;
println!("{res}"); // >>> OK
// REMOVE_START
assert_eq!(res, "OK");
// REMOVE_END
}

match r.hget("bike:1", "model").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> Deimos
// REMOVE_START
assert_eq!(res, "Deimos");
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1 model: {e}");
return;
}
};

match r.hget("bike:1", "price").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> 4972
// REMOVE_START
assert_eq!(res, "4972");
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1 price: {e}");
return;
}
};

match r.hgetall("bike:1").await {
Ok(res) => {
let res: Vec<(String, String)> = res;
println!("{res:?}");
// >>> [("model", "Deimos"), ("brand", "Ergonom"), ("type", "Enduro bikes"), ("price", "4972")]
// REMOVE_START
assert_eq!(res.len(), 4);
assert_eq!(res[0].0, "model");
assert_eq!(res[0].1, "Deimos");
assert_eq!(res[1].0, "brand");
assert_eq!(res[1].1, "Ergonom");
assert_eq!(res[2].0, "type");
assert_eq!(res[2].1, "Enduro bikes");
assert_eq!(res[3].0, "price");
assert_eq!(res[3].1, "4972");
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1: {e}");
return;
}
};
// STEP_END

// STEP_START hmget
match r.hmget("bike:1", &["model", "price"]).await {
Ok(res) => {
let res: Vec<String> = res;
println!("{res:?}"); // >>> ["Deimos", "4972"]
// REMOVE_START
assert_eq!(res.len(), 2);
assert_eq!(res[0], "Deimos");
assert_eq!(res[1], "4972");
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1: {e}");
return;
}
};
// STEP_END

// STEP_START hincrby
if let Ok(res) = r.hincr("bike:1", "price", 100).await {
let res: i32 = res;
println!("{res}"); // >>> 5072
// REMOVE_START
assert_eq!(res, 5072);
// REMOVE_END
}

if let Ok(res) = r.hincr("bike:1", "price", -100).await {
let res: i32 = res;
println!("{res}"); // >>> 4972
// REMOVE_START
assert_eq!(res, 4972);
// REMOVE_END
}
// STEP_END

// STEP_START incrby_get_mget
if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 1
// REMOVE_START
assert_eq!(res, 1);
// REMOVE_END
}

if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 2
// REMOVE_START
assert_eq!(res, 2);
// REMOVE_END
}

if let Ok(res) = r.hincr("bike:1:stats", "rides", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 3
// REMOVE_START
assert_eq!(res, 3);
// REMOVE_END
}

if let Ok(res) = r.hincr("bike:1:stats", "crashes", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 1
// REMOVE_START
assert_eq!(res, 1);
// REMOVE_END
}

if let Ok(res) = r.hincr("bike:1:stats", "owners", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 1
// REMOVE_START
assert_eq!(res, 1);
// REMOVE_END
}

match r.hget("bike:1:stats", "rides").await {
Ok(res) => {
let res: i32 = res;
println!("{res}"); // >>> 3
// REMOVE_START
assert_eq!(res, 3);
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1:stats rides: {e}");
return;
}
};

match r.hmget("bike:1:stats", &["crashes", "owners"]).await {
Ok(res) => {
let res: Vec<i32> = res;
println!("{res:?}"); // >>> [1, 1]
// REMOVE_START
assert_eq!(res.len(), 2);
assert_eq!(res[0], 1);
assert_eq!(res[1], 1);
// REMOVE_END
},
Err(e) => {
println!("Error getting bike:1:stats crashes and owners: {e}");
return;
}
};
// STEP_END
}
}
148 changes: 148 additions & 0 deletions local_examples/rust-async/dt-string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@

// EXAMPLE: set_tutorial
#[cfg(test)]
mod tests {
use redis::{AsyncCommands, ExistenceCheck};

#[tokio::test]
async fn run() {
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_multiplexed_async_connection().await {
Ok(conn) => conn,
Err(e) => {
println!("Failed to connect to Redis: {e}");
return;
}
}
},
Err(e) => {
println!("Failed to create Redis client: {e}");
return;
}
};

// STEP_START set_get
if let Ok(res) = r.set("bike:1", "Deimos").await {
let res: String = res;
println!("{res}"); // >>> OK
// REMOVE_START
assert_eq!(res, "OK");
// REMOVE_END
}

match r.get("bike:1").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> Deimos
// REMOVE_START
assert_eq!(res, "Deimos");
// REMOVE_END
},
Err(e) => {
println!("Error getting foo: {e}");
return;
}
};
// STEP_END

// STEP_START setnx_xx
if let Ok(res) = r.set_options("bike:1", "bike", redis::SetOptions::default().conditional_set(ExistenceCheck::NX)).await {
let res: bool = res;
println!("{res}"); // >>> false
// REMOVE_START
assert!(!res);
// REMOVE_END
}

match r.get("bike:1").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> Deimos
// REMOVE_START
assert_eq!(res, "Deimos");
// REMOVE_END
},
Err(e) => {
println!("Error getting foo: {e}");
return;
}
};

if let Ok(res) = r.set_options("bike:1", "bike", redis::SetOptions::default().conditional_set(ExistenceCheck::XX)).await {
let res: String = res;
println!("{res}"); // >>> OK
// REMOVE_START
assert_eq!(res, "OK");
// REMOVE_END
}

match r.get("bike:1").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> bike
// REMOVE_START
assert_eq!(res, "bike");
// REMOVE_END
},
Err(e) => {
println!("Error getting foo: {e}");
return;
}
};
// STEP_END

// STEP_START mset
if let Ok(res) = r.mset(&[("bike:1", "Deimos"), ("bike:2", "Ares"), ("bike:3", "Vanth")]).await {
let res: String = res;
println!("{res}"); // >>> OK
// REMOVE_START
assert_eq!(res, "OK");
// REMOVE_END
}

match r.mget(&["bike:1", "bike:2", "bike:3"]).await {
Ok(res) => {
let res: Vec<String> = res;
println!("{res:?}"); // >>> ["Deimos", "Ares", "Vanth"]
// REMOVE_START
assert_eq!(res.len(), 3);
assert_eq!(res[0], "Deimos");
assert_eq!(res[1], "Ares");
assert_eq!(res[2], "Vanth");
// REMOVE_END
},
Err(e) => {
println!("Error getting foo: {e}");
return;
}
};
// STEP_END

// STEP_START incr
if let Ok(res) = r.set("total_crashes", 0).await {
let res: String = res;
println!("{res}"); // >>> OK
// REMOVE_START
assert_eq!(res, "OK");
// REMOVE_END
}

if let Ok(res) = r.incr("total_crashes", 1).await {
let res: i32 = res;
println!("{res}"); // >>> 1
// REMOVE_START
assert_eq!(res, 1);
// REMOVE_END
}

if let Ok(res) = r.incr("total_crashes", 10).await {
let res: i32 = res;
println!("{res}"); // >>> 11
// REMOVE_START
assert_eq!(res, 11);
// REMOVE_END
}
// STEP_END
}
}
Loading