1
1
use bytes:: Bytes ;
2
+ use tokio:: time:: Duration ;
2
3
3
4
use crate :: commands:: executable:: Executable ;
4
5
use crate :: commands:: { CommandParser , CommandParserError } ;
@@ -21,8 +22,10 @@ pub struct Set {
21
22
22
23
#[ derive( Debug , PartialEq ) ]
23
24
pub enum SetBehavior {
24
- Nx , // Only set the key if it does not already exist.
25
- Xx , // Only set the key if it already exists.
25
+ /// Only set the key if it does not already exist.
26
+ Nx ,
27
+ /// Only set the key if it already exists.
28
+ Xx ,
26
29
}
27
30
28
31
#[ derive( Debug , PartialEq ) ]
@@ -34,10 +37,18 @@ pub enum Ttl {
34
37
KeepTtl , // Retain the time to live associated with the key.
35
38
}
36
39
40
+ impl Ttl {
41
+ pub fn duration ( & self ) -> Duration {
42
+ match self {
43
+ Ttl :: Ex ( seconds) => Duration :: from_secs ( * seconds) ,
44
+ _ => Duration :: from_secs ( 1 ) ,
45
+ }
46
+ }
47
+ }
48
+
37
49
impl Executable for Set {
38
50
fn exec ( self , store : Store ) -> Result < Frame , Error > {
39
51
let mut store = store. lock ( ) ;
40
-
41
52
let value = store. get ( & self . key ) ;
42
53
43
54
match self . behavior {
@@ -46,7 +57,10 @@ impl Executable for Set {
46
57
_ => { }
47
58
}
48
59
49
- store. set ( self . key , self . value ) ;
60
+ match self . ttl {
61
+ Some ( ttl) => store. set_with_ttl ( self . key , self . value , ttl. duration ( ) ) ,
62
+ None => store. set ( self . key , self . value ) ,
63
+ } ;
50
64
51
65
let res = if self . get {
52
66
value. map_or ( Frame :: NullBulkString , Frame :: Bulk )
@@ -69,10 +83,16 @@ impl TryFrom<&mut CommandParser> for Set {
69
83
let mut behavior = None ;
70
84
let mut get = false ;
71
85
72
- while parser. has_more ( ) {
73
- let opt = parser. next_string ( ) ?;
86
+ loop {
87
+ let option = match parser. next_string ( ) {
88
+ Ok ( option) => option,
89
+ Err ( CommandParserError :: EndOfStream ) => {
90
+ break ;
91
+ }
92
+ Err ( err) => return Err ( err. into ( ) ) ,
93
+ } ;
74
94
75
- match opt . as_str ( ) {
95
+ match option . as_str ( ) {
76
96
// TTL options
77
97
"EX" if ttl. is_none ( ) => {
78
98
let val = parser. next_integer ( ) ?;
@@ -111,7 +131,7 @@ impl TryFrom<&mut CommandParser> for Set {
111
131
_ => {
112
132
return Err ( CommandParserError :: InvalidCommandArgument {
113
133
command : "SET" . to_string ( ) ,
114
- argument : opt ,
134
+ argument : option ,
115
135
}
116
136
. into ( ) )
117
137
}
0 commit comments