fast_cache/storage/
command.rs1use crate::Result;
2use crate::commands::{BorrowedCommandBox, CommandCatalog, OwnedCommandBox};
3use crate::protocol::{BorrowedCommandFrame, Frame, RespCodec};
4
5#[derive(Debug)]
6pub struct Command {
7 inner: OwnedCommandBox,
8}
9
10impl Command {
11 pub(crate) fn new(inner: OwnedCommandBox) -> Self {
12 Self { inner }
13 }
14
15 pub fn from_frame(frame: Frame) -> Result<Self> {
16 let parts = RespCodec::as_command(frame)?.parts;
17 CommandCatalog::parse_owned(&parts)
18 }
19
20 pub fn name(&self) -> &'static str {
21 self.inner.name()
22 }
23
24 pub fn mutates_value(&self) -> bool {
25 self.inner.mutates_value()
26 }
27
28 pub fn route_key(&self) -> Option<&[u8]> {
29 self.inner.route_key()
30 }
31
32 pub(crate) fn to_borrowed_command(&self) -> BorrowedCommand<'_> {
33 BorrowedCommand::new(self.inner.to_borrowed_command())
34 }
35}
36
37#[derive(Debug)]
38pub struct BorrowedCommand<'a> {
39 inner: BorrowedCommandBox<'a>,
40}
41
42impl<'a> BorrowedCommand<'a> {
43 pub(crate) fn new(inner: BorrowedCommandBox<'a>) -> Self {
44 Self { inner }
45 }
46
47 pub fn from_frame(frame: BorrowedCommandFrame<'a>) -> Result<Self> {
48 Self::from_parts(&frame.parts)
49 }
50
51 pub fn from_parts(parts: &[&'a [u8]]) -> Result<Self> {
52 CommandCatalog::parse_borrowed(parts).map(Self::new)
53 }
54
55 pub fn name(&self) -> &'static str {
56 self.inner.name()
57 }
58
59 pub fn mutates_value(&self) -> bool {
60 self.inner.mutates_value()
61 }
62
63 pub fn route_key(&self) -> Option<&'a [u8]> {
64 self.inner.route_key()
65 }
66
67 pub(crate) fn supports_spanned_resp(&self) -> bool {
68 self.inner.supports_spanned_resp()
69 }
70
71 pub fn to_owned_command(&self) -> Command {
72 self.inner.to_owned_command()
73 }
74
75 pub(crate) fn execute_engine<'b>(
76 &'b self,
77 ctx: crate::storage::EngineCommandContext<'b>,
78 ) -> crate::storage::EngineFrameFuture<'b>
79 where
80 'a: 'b,
81 {
82 self.inner.execute_engine(ctx)
83 }
84
85 #[cfg(feature = "server")]
86 pub(crate) fn execute_borrowed_frame(
87 &self,
88 store: &crate::storage::EmbeddedStore,
89 now_ms: u64,
90 ) -> Frame {
91 self.inner.execute_borrowed_frame(store, now_ms)
92 }
93
94 #[cfg(feature = "server")]
95 pub(crate) fn execute_borrowed(
96 &self,
97 ctx: crate::server::commands::BorrowedCommandContext<'_, '_, '_>,
98 ) {
99 self.inner.execute_borrowed(ctx);
100 }
101
102 #[cfg(feature = "server")]
103 pub(crate) fn execute_direct_borrowed(
104 &self,
105 ctx: crate::server::commands::DirectCommandContext,
106 ) -> Frame {
107 self.inner.execute_direct_borrowed(ctx)
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use crate::commands::CommandCatalog;
114 use crate::protocol::Frame;
115
116 use super::{BorrowedCommand, Command};
117
118 #[test]
119 fn parses_set_with_ttl() {
120 let command = Command::from_frame(Frame::Array(vec![
121 Frame::BlobString(b"SET".to_vec()),
122 Frame::BlobString(b"alpha".to_vec()),
123 Frame::BlobString(b"beta".to_vec()),
124 Frame::BlobString(b"EX".to_vec()),
125 Frame::BlobString(b"5".to_vec()),
126 ]))
127 .unwrap();
128
129 assert_eq!(command.name(), "SET");
130 assert!(command.mutates_value());
131 assert_eq!(command.route_key(), Some(b"alpha".as_slice()));
132 }
133
134 #[test]
135 fn parses_get_command() {
136 let command =
137 BorrowedCommand::from_parts(&[b"GET".as_slice(), b"alpha".as_slice()]).unwrap();
138
139 assert_eq!(command.name(), "GET");
140 assert!(!command.mutates_value());
141 assert_eq!(command.route_key(), Some(b"alpha".as_slice()));
142 }
143
144 #[test]
145 fn parses_del_command() {
146 let command = BorrowedCommand::from_parts(&[
147 b"DEL".as_slice(),
148 b"alpha".as_slice(),
149 b"beta".as_slice(),
150 ])
151 .unwrap();
152
153 assert_eq!(command.name(), "DEL");
154 assert!(command.mutates_value());
155 assert_eq!(command.route_key(), Some(b"alpha".as_slice()));
156 assert_eq!(
157 command.to_owned_command().route_key(),
158 Some(b"alpha".as_slice())
159 );
160 }
161
162 #[test]
163 fn parses_borrowed_command_object() {
164 let command = CommandCatalog::parse_borrowed(&[
165 b"SET".as_slice(),
166 b"alpha".as_slice(),
167 b"beta".as_slice(),
168 ])
169 .unwrap();
170
171 assert_eq!(command.name(), "SET");
172 assert!(command.mutates_value());
173 assert_eq!(command.route_key(), Some(b"alpha".as_slice()));
174 assert_eq!(
175 command.to_owned_command().route_key(),
176 Some(b"alpha".as_slice())
177 );
178 }
179}