mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-28 15:09:12 +00:00
add rust lang to repo by add assets/mini-redis
This commit is contained in:
93
zh-CN/assets/mini-redis/src/cmd/get.rs
Normal file
93
zh-CN/assets/mini-redis/src/cmd/get.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use crate::{Connection, Db, Frame, Parse};
|
||||
|
||||
use bytes::Bytes;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
/// Get the value of key.
|
||||
///
|
||||
/// If the key does not exist the special value nil is returned. An error is
|
||||
/// returned if the value stored at key is not a string, because GET only
|
||||
/// handles string values.
|
||||
#[derive(Debug)]
|
||||
pub struct Get {
|
||||
/// Name of the key to get
|
||||
key: String,
|
||||
}
|
||||
|
||||
impl Get {
|
||||
/// Create a new `Get` command which fetches `key`.
|
||||
pub fn new(key: impl ToString) -> Get {
|
||||
Get {
|
||||
key: key.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the key
|
||||
pub fn key(&self) -> &str {
|
||||
&self.key
|
||||
}
|
||||
|
||||
/// Parse a `Get` instance from a received frame.
|
||||
///
|
||||
/// The `Parse` argument provides a cursor-like API to read fields from the
|
||||
/// `Frame`. At this point, the entire frame has already been received from
|
||||
/// the socket.
|
||||
///
|
||||
/// The `GET` string has already been consumed.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns the `Get` value on success. If the frame is malformed, `Err` is
|
||||
/// returned.
|
||||
///
|
||||
/// # Format
|
||||
///
|
||||
/// Expects an array frame containing two entries.
|
||||
///
|
||||
/// ```text
|
||||
/// GET key
|
||||
/// ```
|
||||
pub(crate) fn parse_frames(parse: &mut Parse) -> crate::Result<Get> {
|
||||
// The `GET` string has already been consumed. The next value is the
|
||||
// name of the key to get. If the next value is not a string or the
|
||||
// input is fully consumed, then an error is returned.
|
||||
let key = parse.next_string()?;
|
||||
|
||||
Ok(Get { key })
|
||||
}
|
||||
|
||||
/// Apply the `Get` command to the specified `Db` instance.
|
||||
///
|
||||
/// The response is written to `dst`. This is called by the server in order
|
||||
/// to execute a received command.
|
||||
#[instrument(skip(self, db, dst))]
|
||||
pub(crate) async fn apply(self, db: &Db, dst: &mut Connection) -> crate::Result<()> {
|
||||
// Get the value from the shared database state
|
||||
let response = if let Some(value) = db.get(&self.key) {
|
||||
// If a value is present, it is written to the client in "bulk"
|
||||
// format.
|
||||
Frame::Bulk(value)
|
||||
} else {
|
||||
// If there is no value, `Null` is written.
|
||||
Frame::Null
|
||||
};
|
||||
|
||||
debug!(?response);
|
||||
|
||||
// Write the response back to the client
|
||||
dst.write_frame(&response).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Converts the command into an equivalent `Frame`.
|
||||
///
|
||||
/// This is called by the client when encoding a `Get` command to send to
|
||||
/// the server.
|
||||
pub(crate) fn into_frame(self) -> Frame {
|
||||
let mut frame = Frame::array();
|
||||
frame.push_bulk(Bytes::from("get".as_bytes()));
|
||||
frame.push_bulk(Bytes::from(self.key.into_bytes()));
|
||||
frame
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user