Skip to main content

embedded_redis/commands/
hget.rs

1//! Abstraction of HGET command.
2//!
3//! For general information about this command, see the [Redis documentation](<https://redis.io/commands/hget/>).
4//!
5//! # Using command object
6//! ```
7//! # async_std::task::block_on(async {
8//!# use core::str::FromStr;
9//!# use core::net::SocketAddr;
10//!# use std_embedded_nal_async::Stack;
11//!# use std_embedded_time::StandardClock;
12//!# use embedded_redis::commands::builder::CommandBuilder;
13//!# use embedded_redis::commands::hget::HashGetCommand;
14//!# use embedded_redis::network::ConnectionHandler;
15//!#
16//! let stack = Stack::default();
17//! let clock = StandardClock::default();
18//!
19//! let mut connection_handler = ConnectionHandler::resp2(SocketAddr::from_str("127.0.0.1:6379").unwrap());
20//! let client = connection_handler.connect(&stack, Some(&clock)).await.unwrap();
21//! client.hset("test_hash", "color", "green").await.unwrap();
22//!
23//! let command = HashGetCommand::new("test_hash", "color");
24//! let response = client.send(command).await.unwrap().unwrap();
25//!
26//! assert_eq!("green", response.as_str().unwrap())
27//! # });
28//! ```
29//!
30//! # Missing key or field
31//! In case key or field is missing. [None] is returned.
32//! ```
33//! # async_std::task::block_on(async {
34//!# use core::str::FromStr;
35//!# use core::net::SocketAddr;
36//!# use std_embedded_nal_async::Stack;
37//!# use std_embedded_time::StandardClock;
38//!# use embedded_redis::commands::builder::CommandBuilder;
39//!# use embedded_redis::commands::hget::HashGetCommand;
40//!# use embedded_redis::network::ConnectionHandler;
41//!#
42//!# let stack = Stack::default();
43//!# let clock = StandardClock::default();
44//!#
45//!# let mut connection_handler = ConnectionHandler::resp2(SocketAddr::from_str("127.0.0.1:6379").unwrap());
46//!# let client = connection_handler.connect(&stack, Some(&clock)).await.unwrap();
47//!#
48//! let command = HashGetCommand::new("not_existing", "field");
49//! let response = client.send(command).await.unwrap();
50//!
51//! assert!(response.is_none())
52//! # });
53//! ```
54//!
55//! # Shorthand
56//! [Client](Client#method.hget) provides a shorthand method for this command.
57//! ```
58//! # async_std::task::block_on(async {
59//!# use core::str::FromStr;
60//!# use bytes::Bytes;
61//!# use core::net::SocketAddr;
62//!# use std_embedded_nal_async::Stack;
63//!# use std_embedded_time::StandardClock;
64//!# use embedded_redis::commands::hset::HashSetCommand;
65//!# use embedded_redis::network::ConnectionHandler;
66//!#
67//!# let stack = Stack::default();
68//!# let clock = StandardClock::default();
69//!#
70//!# let mut connection_handler = ConnectionHandler::resp2(SocketAddr::from_str("127.0.0.1:6379").unwrap());
71//!# let client = connection_handler.connect(&stack, Some(&clock)).await.unwrap();
72//!#
73//!# let _ = client.send(HashSetCommand::new("hash_key", "hash_field", "example")).await;
74//!#
75//! // Using &str arguments
76//! let response = client.hget("hash_key", "hash_field").await.unwrap().unwrap();
77//! assert_eq!("example", response.as_str().unwrap());
78//!
79//! // Using String arguments
80//! let _ = client.hget("hash_key".to_string(), "hash_field".to_string()).await;
81//!
82//! // Using Bytes arguments
83//! let _ = client.hget(Bytes::from_static(b"hash_key"), Bytes::from_static(b"hash_field")).await;
84//! # });
85//! ```
86use crate::commands::auth::AuthCommand;
87use crate::commands::builder::{CommandBuilder, IsNullFrame, ToStringBytes};
88use crate::commands::get::GetResponse;
89use crate::commands::hello::HelloCommand;
90use crate::commands::{Command, ResponseTypeError};
91use crate::network::protocol::Protocol;
92use crate::network::{Client, CommandErrors};
93use bytes::Bytes;
94use embedded_io_async::{Read, Write};
95use embedded_time::Clock;
96
97/// Abstraction for HGET command
98pub struct HashGetCommand {
99    /// Hash key
100    key: Bytes,
101
102    /// Hash field to receive
103    field: Bytes,
104}
105
106impl HashGetCommand {
107    pub fn new<K, F>(key: K, field: F) -> Self
108    where
109        Bytes: From<K>,
110        Bytes: From<F>,
111    {
112        Self {
113            key: key.into(),
114            field: field.into(),
115        }
116    }
117}
118
119impl<F> Command<F> for HashGetCommand
120where
121    F: From<CommandBuilder> + IsNullFrame + ToStringBytes,
122{
123    type Response = Option<GetResponse>;
124
125    fn encode(&self) -> F {
126        CommandBuilder::new("HGET").arg(&self.key).arg(&self.field).into()
127    }
128
129    fn eval_response(&self, frame: F) -> Result<Self::Response, ResponseTypeError> {
130        GetResponse::from_frame(frame)
131    }
132}
133
134impl<'a, T: Read + Write, C: Clock, P: Protocol> Client<'a, T, C, P>
135where
136    AuthCommand: Command<<P as Protocol>::FrameType>,
137    HelloCommand: Command<<P as Protocol>::FrameType>,
138{
139    /// Shorthand for [HashGetCommand]
140    pub async fn hget<K, F>(&self, key: K, field: F) -> Result<Option<GetResponse>, CommandErrors>
141    where
142        <P as Protocol>::FrameType: ToStringBytes,
143        <P as Protocol>::FrameType: IsNullFrame,
144        <P as Protocol>::FrameType: From<CommandBuilder>,
145        Bytes: From<K>,
146        Bytes: From<F>,
147    {
148        self.send(HashGetCommand::new(key, field)).await
149    }
150}