@@ -7,7 +7,11 @@ macro_rules! redis_command {
77 $firstkey: expr,
88 $lastkey: expr,
99 $keystep: expr,
10- $acl_categories: expr) => { {
10+ $mandatory_acl_categories: expr
11+ $( , $optional_acl_categories: expr) ?
12+ ) => { {
13+ use redis_module:: AclCategory ;
14+
1115 let name = CString :: new( $command_name) . unwrap( ) ;
1216 let flags = CString :: new( $command_flags) . unwrap( ) ;
1317
@@ -37,34 +41,67 @@ macro_rules! redis_command {
3741 )
3842 } == $crate:: raw:: Status :: Err as c_int
3943 {
44+ $crate:: raw:: redis_log(
45+ $ctx,
46+ & format!( "Error: failed to create command {}" , $command_name) ,
47+ ) ;
4048 return $crate:: raw:: Status :: Err as c_int;
4149 }
4250
43- if $acl_categories != "" {
44- let acl_categories = CString :: new( $acl_categories) . unwrap( ) ;
51+ let command =
52+ unsafe { $crate:: raw:: RedisModule_GetCommand . unwrap( ) ( $ctx, name. as_ptr( ) ) } ;
53+ if command. is_null( ) {
54+ $crate:: raw:: redis_log(
55+ $ctx,
56+ & format!( "Error: failed to get command {}" , $command_name) ,
57+ ) ;
58+ return $crate:: raw:: Status :: Err as c_int;
59+ }
4560
46- let command =
47- unsafe { $crate:: raw:: RedisModule_GetCommand . unwrap( ) ( $ctx, name. as_ptr( ) ) } ;
48- if command. is_null( ) {
49- return $crate:: raw:: Status :: Err as c_int;
50- }
61+ let mandatory_acl_categories = AclCategory :: from( $mandatory_acl_categories) ;
62+ if let Some ( RM_SetCommandACLCategories ) = $crate:: raw:: RedisModule_SetCommandACLCategories {
63+ let mut acl_categories = CString :: default ( ) ;
64+ $(
65+ let optional_acl_categories = AclCategory :: from( $optional_acl_categories) ;
66+ if mandatory_acl_categories != AclCategory :: None && optional_acl_categories != AclCategory :: None {
67+ acl_categories = CString :: new( format!( "{} {}" , mandatory_acl_categories, optional_acl_categories) ) . unwrap( ) ;
68+ } else if optional_acl_categories != AclCategory :: None {
69+ acl_categories = CString :: new( format!( "{}" , $optional_acl_categories) ) . unwrap( ) ;
70+ }
71+ // Warn if optional ACL categories are not set, but don't fail.
72+ if RM_SetCommandACLCategories ( command, acl_categories. as_ptr( ) ) == $crate:: raw:: Status :: Err as c_int {
73+ $crate:: raw:: redis_log(
74+ $ctx,
75+ & format!(
76+ "Warning: failed to set command `{}` ACL categories `{}`" ,
77+ $command_name, acl_categories. to_str( ) . unwrap( )
78+ ) ,
79+ ) ;
80+ } else
81+ ) ?
82+ if mandatory_acl_categories != AclCategory :: None {
83+ acl_categories = CString :: new( format!( "{}" , mandatory_acl_categories) ) . unwrap( ) ;
5184
52- if let Some ( RM_SetCommandACLCategories ) =
53- $crate:: raw:: RedisModule_SetCommandACLCategories
54- {
85+ // Fail if mandatory ACL categories are not set.
5586 if RM_SetCommandACLCategories ( command, acl_categories. as_ptr( ) )
5687 == $crate:: raw:: Status :: Err as c_int
5788 {
5889 $crate:: raw:: redis_log(
5990 $ctx,
6091 & format!(
61- "Error: failed to set command {} ACL categories {} " ,
62- $command_name, $acl_categories
92+ "Error: failed to set command `{}` mandatory ACL categories `{}` " ,
93+ $command_name, mandatory_acl_categories
6394 ) ,
6495 ) ;
6596 return $crate:: raw:: Status :: Err as c_int;
6697 }
6798 }
99+ } else if mandatory_acl_categories != AclCategory :: None {
100+ $crate:: raw:: redis_log(
101+ $ctx,
102+ "Error: Redis version does not support ACL categories" ,
103+ ) ;
104+ return $crate:: raw:: Status :: Err as c_int;
68105 }
69106 } } ;
70107}
@@ -134,7 +171,11 @@ macro_rules! redis_module {
134171 data_types: [
135172 $( $data_type: ident) ,* $( , ) *
136173 ] ,
137- $( acl_category: $acl_category: expr, ) * $( , ) *
174+ // eg: `acl_category: [ "name_of_module_acl_category", ],`
175+ // This will add the specified (optional) ACL categories.
176+ $( acl_categories: [
177+ $( $module_acl_category: expr, ) *
178+ ] , ) ?
138179 $( init: $init_func: ident, ) * $( , ) *
139180 $( deinit: $deinit_func: ident, ) * $( , ) *
140181 $( info: $info_func: ident, ) ?
@@ -146,7 +187,8 @@ macro_rules! redis_module {
146187 $firstkey: expr,
147188 $lastkey: expr,
148189 $keystep: expr,
149- $acl_categories: expr
190+ $mandatory_command_acl_categories: expr
191+ $( , $optional_command_acl_categories: expr) ?
150192 ] ) ,* $( , ) *
151193 ] $( , ) *
152194 $( event_handlers: [
@@ -271,17 +313,24 @@ macro_rules! redis_module {
271313 ) *
272314
273315 $(
274- let category = CString :: new( $acl_category) . unwrap( ) ;
275- if let Some ( RM_AddACLCategory ) = raw:: RedisModule_AddACLCategory {
276- if RM_AddACLCategory ( ctx, category. as_ptr( ) ) == raw:: Status :: Err as c_int {
277- raw:: redis_log( ctx, & format!( "Error: failed to add ACL category {}" , $acl_category) ) ;
278- return raw:: Status :: Err as c_int;
316+ $(
317+ if let Some ( RM_AddACLCategory ) = raw:: RedisModule_AddACLCategory {
318+ let module_acl_category = AclCategory :: from( $module_acl_category) ;
319+ if module_acl_category != AclCategory :: None {
320+ let category = CString :: new( format!( "{}" , $module_acl_category) ) . unwrap( ) ;
321+ if RM_AddACLCategory ( ctx, category. as_ptr( ) ) == raw:: Status :: Err as c_int {
322+ raw:: redis_log( ctx, & format!( "Error: failed to add ACL category `{}`" , $module_acl_category) ) ;
323+ return raw:: Status :: Err as c_int;
324+ }
325+ }
326+ } else {
327+ raw:: redis_log( ctx, "Warning: Redis version does not support adding new ACL categories" ) ;
279328 }
280- }
281- ) *
329+ ) *
330+ ) ?
282331
283332 $(
284- $crate:: redis_command!( ctx, $name, $command, $flags, $firstkey, $lastkey, $keystep, $acl_categories ) ;
333+ $crate:: redis_command!( ctx, $name, $command, $flags, $firstkey, $lastkey, $keystep, $mandatory_command_acl_categories $ ( , $optional_command_acl_categories ) ? ) ;
285334 ) *
286335
287336 if $crate:: commands:: register_commands( & context) == raw:: Status :: Err {
0 commit comments