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