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}