5
5
*/
6
6
7
7
use crate :: error:: Error ;
8
- use crate :: formatter:: FormatOptions ;
8
+ use crate :: formatter:: ReplyFormatOptions ;
9
9
use crate :: key_value:: KeyValue ;
10
10
use crate :: manager:: err_msg_json_path_doesnt_exist_with_param;
11
11
use crate :: manager:: err_msg_json_path_doesnt_exist_with_param_or;
12
12
use crate :: manager:: { Manager , ReadHolder , UpdateInfo , WriteHolder } ;
13
- use crate :: redisjson:: { Format , Path } ;
13
+ use crate :: redisjson:: { Format , Path , ReplyFormat } ;
14
14
use json_path:: select_value:: { SelectValue , SelectValueType } ;
15
15
use redis_module:: { Context , RedisValue } ;
16
16
use redis_module:: { NextArg , RedisError , RedisResult , RedisString , REDIS_OK } ;
@@ -99,25 +99,35 @@ fn default_path(ctx: &Context) -> &str {
99
99
/// [INDENT indentation-string]
100
100
/// [NEWLINE line-break-string]
101
101
/// [SPACE space-string]
102
+ /// [FORMAT {STRING|EXPAND1|EXPAND}] /* default is STRING */
102
103
/// [path ...]
103
104
///
104
- /// TODO add support for multi path
105
105
pub fn json_get < M : Manager > ( manager : M , ctx : & Context , args : Vec < RedisString > ) -> RedisResult {
106
106
let mut args = args. into_iter ( ) . skip ( 1 ) ;
107
107
let key = args. next_arg ( ) ?;
108
108
109
109
// Set Capacity to 1 assuming the common case has one path
110
110
let mut paths: Vec < Path > = Vec :: with_capacity ( 1 ) ;
111
111
112
- let mut format_options = FormatOptions :: new ( is_resp3 ( ctx) ) ;
112
+ let mut format_options = ReplyFormatOptions :: new ( is_resp3 ( ctx) , ReplyFormat :: STRING ) ;
113
113
114
114
while let Ok ( arg) = args. next_str ( ) {
115
115
match arg {
116
116
// fast way to consider arg a path by using the max length of all possible subcommands
117
117
// See #390 for the comparison of this function with/without this optimization
118
118
arg if arg. len ( ) > JSONGET_SUBCOMMANDS_MAXSTRLEN => paths. push ( Path :: new ( arg) ) ,
119
119
arg if arg. eq_ignore_ascii_case ( CMD_ARG_FORMAT ) => {
120
- format_options. format = Format :: from_str ( args. next_str ( ) ?) ?;
120
+ if !format_options. resp3 && paths. is_empty ( ) {
121
+ return Err ( RedisError :: Str (
122
+ "ERR FORMAT argument is not supported on RESP2" ,
123
+ ) ) ;
124
+ }
125
+ // Temporary fix until STRINGS is also supported
126
+ let next = args. next_str ( ) ?;
127
+ if next. eq_ignore_ascii_case ( "STRINGS" ) {
128
+ return Err ( RedisError :: Str ( "ERR wrong reply format" ) ) ;
129
+ }
130
+ format_options. format = ReplyFormat :: from_str ( next) ?;
121
131
}
122
132
arg if arg. eq_ignore_ascii_case ( CMD_ARG_INDENT ) => {
123
133
format_options. indent = Some ( args. next_str ( ) ?)
@@ -596,7 +606,7 @@ pub fn json_mget<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>)
596
606
let path = Path :: new ( path. try_as_str ( ) ?) ;
597
607
let keys = & args[ 1 ..args. len ( ) - 1 ] ;
598
608
599
- let format_options = FormatOptions :: new ( is_resp3 ( ctx) ) ;
609
+ let format_options = ReplyFormatOptions :: new ( is_resp3 ( ctx) , ReplyFormat :: STRING ) ;
600
610
601
611
// Verify that at least one key exists
602
612
if keys. is_empty ( ) {
@@ -736,7 +746,7 @@ where
736
746
737
747
// Convert to RESP2 format return as one JSON array
738
748
let values = to_json_value :: < Number > ( results, Value :: Null ) ;
739
- Ok ( KeyValue :: < M :: V > :: serialize_object ( & values, & FormatOptions :: default ( ) ) . into ( ) )
749
+ Ok ( KeyValue :: < M :: V > :: serialize_object ( & values, & ReplyFormatOptions :: default ( ) ) . into ( ) )
740
750
}
741
751
}
742
752
@@ -1368,7 +1378,7 @@ pub fn json_arr_len<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString
1368
1378
1369
1379
///
1370
1380
/// JSON.ARRPOP <key>
1371
- /// [FORMAT {STRING|JSON |EXPAND}]
1381
+ /// [FORMAT {STRINGS|EXPAND1 |EXPAND}] /* default is STRINGS */
1372
1382
/// [path [index]]
1373
1383
///
1374
1384
pub fn json_arr_pop < M : Manager > ( manager : M , ctx : & Context , args : Vec < RedisString > ) -> RedisResult {
@@ -1377,14 +1387,26 @@ pub fn json_arr_pop<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString
1377
1387
let key = args. next_arg ( ) ?;
1378
1388
1379
1389
let is_resp3 = is_resp3 ( ctx) ;
1380
- let mut format_options = FormatOptions :: new ( is_resp3) ;
1390
+ let mut format_options = ReplyFormatOptions :: new ( is_resp3, ReplyFormat :: STRINGS ) ;
1381
1391
1382
- // Only on RESP3 if the first argument is FORMAT, then the second argument is the format
1383
- // but it's optional so it might be the path
1384
1392
let path = if let Some ( arg) = args. next ( ) {
1385
- if is_resp3 && arg. try_as_str ( ) ?. eq_ignore_ascii_case ( "FORMAT" ) {
1386
- format_options. format = Format :: from_str ( args. next_str ( ) ?) ?;
1387
- args. next ( )
1393
+ if arg. try_as_str ( ) ?. eq_ignore_ascii_case ( CMD_ARG_FORMAT ) {
1394
+ if let Ok ( next) = args. next_str ( ) {
1395
+ format_options. format = ReplyFormat :: from_str ( next) ?;
1396
+ if format_options. format == ReplyFormat :: STRING {
1397
+ // ARRPOP FORMAT STRING is not supported
1398
+ return Err ( RedisError :: Str ( "ERR wrong reply format" ) ) ;
1399
+ }
1400
+ if !format_options. resp3 {
1401
+ return Err ( RedisError :: Str (
1402
+ "ERR FORMAT argument is not supported on RESP2" ,
1403
+ ) ) ;
1404
+ }
1405
+ args. next ( )
1406
+ } else {
1407
+ // If only the FORMAT subcommand is provided, then it's the path
1408
+ Some ( arg)
1409
+ }
1388
1410
} else {
1389
1411
// if it's not FORMAT, then it's the path
1390
1412
Some ( arg)
@@ -1409,12 +1431,13 @@ pub fn json_arr_pop<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString
1409
1431
( path, index)
1410
1432
}
1411
1433
} ;
1434
+ //args.done()?;
1412
1435
1413
1436
let mut redis_key = manager. open_key_write ( ctx, key) ?;
1414
1437
if path. is_legacy ( ) {
1415
- if format_options. format != Format :: STRING {
1438
+ if format_options. format != ReplyFormat :: STRINGS {
1416
1439
return Err ( RedisError :: Str (
1417
- "Legacy paths are supported only with FORMAT STRING " ,
1440
+ "Legacy paths are supported only with FORMAT STRINGS " ,
1418
1441
) ) ;
1419
1442
}
1420
1443
@@ -1429,7 +1452,7 @@ fn json_arr_pop_impl<M>(
1429
1452
ctx : & Context ,
1430
1453
path : & str ,
1431
1454
index : i64 ,
1432
- format_options : & FormatOptions ,
1455
+ format_options : & ReplyFormatOptions ,
1433
1456
) -> RedisResult
1434
1457
where
1435
1458
M : Manager ,
0 commit comments