-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MOD-8036 Add tests for 393 and 394 #395
Changes from 6 commits
a85c1c4
e234658
cdb4965
a2451d1
3388925
a6e4203
0f33019
56cf136
fc51c7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,9 @@ macro_rules! redis_command { | |
$firstkey:expr, | ||
$lastkey:expr, | ||
$keystep:expr, | ||
$acl_categories:expr) => {{ | ||
$mandatory_acl_categories:expr | ||
$(, $optional_acl_categories:expr)? | ||
) => {{ | ||
let name = CString::new($command_name).unwrap(); | ||
let flags = CString::new($command_flags).unwrap(); | ||
|
||
|
@@ -37,34 +39,65 @@ macro_rules! redis_command { | |
) | ||
} == $crate::raw::Status::Err as c_int | ||
{ | ||
$crate::raw::redis_log( | ||
$ctx, | ||
&format!("Error: failed to create command {}", $command_name), | ||
); | ||
return $crate::raw::Status::Err as c_int; | ||
} | ||
|
||
if $acl_categories != "" { | ||
let acl_categories = CString::new($acl_categories).unwrap(); | ||
let command = | ||
unsafe { $crate::raw::RedisModule_GetCommand.unwrap()($ctx, name.as_ptr()) }; | ||
if command.is_null() { | ||
$crate::raw::redis_log( | ||
$ctx, | ||
&format!("Error: failed to get command {}", $command_name), | ||
); | ||
return $crate::raw::Status::Err as c_int; | ||
} | ||
|
||
let command = | ||
unsafe { $crate::raw::RedisModule_GetCommand.unwrap()($ctx, name.as_ptr()) }; | ||
if command.is_null() { | ||
return $crate::raw::Status::Err as c_int; | ||
} | ||
if let Some(RM_SetCommandACLCategories) = $crate::raw::RedisModule_SetCommandACLCategories { | ||
let mut acl_categories = CString::new("").unwrap(); | ||
ephraimfeldblum marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$( | ||
if $mandatory_acl_categories != "" && $optional_acl_categories != "" { | ||
acl_categories = CString::new(format!("{} {}", $mandatory_acl_categories, $optional_acl_categories)).unwrap(); | ||
} else if $optional_acl_categories != "" { | ||
acl_categories = CString::new($optional_acl_categories).unwrap(); | ||
} | ||
ephraimfeldblum marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Warn if optional ACL categories are not set, but don't fail. | ||
if RM_SetCommandACLCategories(command, acl_categories.as_ptr()) == $crate::raw::Status::Err as c_int { | ||
$crate::raw::redis_log( | ||
$ctx, | ||
&format!( | ||
"Warning: failed to set command `{}` ACL categories `{}`", | ||
$command_name, acl_categories.to_str().unwrap() | ||
), | ||
); | ||
} else | ||
)? | ||
if $mandatory_acl_categories != "" { | ||
acl_categories = CString::new($mandatory_acl_categories).unwrap(); | ||
|
||
if let Some(RM_SetCommandACLCategories) = | ||
$crate::raw::RedisModule_SetCommandACLCategories | ||
{ | ||
// Fail if mandatory ACL categories are not set. | ||
if RM_SetCommandACLCategories(command, acl_categories.as_ptr()) | ||
== $crate::raw::Status::Err as c_int | ||
{ | ||
$crate::raw::redis_log( | ||
$ctx, | ||
&format!( | ||
"Error: failed to set command {} ACL categories {}", | ||
$command_name, $acl_categories | ||
"Error: failed to set command `{}` mandatory ACL categories `{}`", | ||
iddm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$command_name, $mandatory_acl_categories | ||
), | ||
); | ||
return $crate::raw::Status::Err as c_int; | ||
} | ||
} | ||
} else if $mandatory_acl_categories != "" { | ||
$crate::raw::redis_log( | ||
$ctx, | ||
"Error: Redis version does not support ACL categories", | ||
); | ||
return $crate::raw::Status::Err as c_int; | ||
} | ||
}}; | ||
} | ||
|
@@ -134,7 +167,9 @@ macro_rules! redis_module { | |
data_types: [ | ||
$($data_type:ident),* $(,)* | ||
], | ||
$(acl_category: $acl_category:expr,)* $(,)* | ||
// eg: `acl_category: "name_of_module_acl_category",` | ||
// This will add the specified (optional) ACL categories. | ||
$(acl_category: $module_acl_categories:expr,)* $(,)* | ||
$(init: $init_func:ident,)* $(,)* | ||
$(deinit: $deinit_func:ident,)* $(,)* | ||
$(info: $info_func:ident,)? | ||
|
@@ -146,7 +181,8 @@ macro_rules! redis_module { | |
$firstkey:expr, | ||
$lastkey:expr, | ||
$keystep:expr, | ||
$acl_categories:expr | ||
$mandatory_command_acl_categories:expr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, this is plural but represents just one category; IIRC, there is just one mandatory category now, or am I wrong? Either way, I understand the precaution here of actually passing more than one as a string separated with spaces, but I'd really like to have it more verbose and explicit by having the enum and a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there may be many mandatory categories. mandatory just means that if adding any of these categories fails, the module loading should fail. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, then I'd like to have those not as string literals but as a comma-separated values list, which implements |
||
$(, $optional_command_acl_categories:expr)? | ||
]),* $(,)* | ||
] $(,)* | ||
$(event_handlers: [ | ||
|
@@ -271,17 +307,19 @@ macro_rules! redis_module { | |
)* | ||
|
||
$( | ||
let category = CString::new($acl_category).unwrap(); | ||
if let Some(RM_AddACLCategory) = raw::RedisModule_AddACLCategory { | ||
if RM_AddACLCategory(ctx, category.as_ptr()) == raw::Status::Err as c_int { | ||
raw::redis_log(ctx, &format!("Error: failed to add ACL category {}", $acl_category)); | ||
let categories = CString::new($module_acl_categories).unwrap(); | ||
if RM_AddACLCategory(ctx, categories.as_ptr()) == raw::Status::Err as c_int { | ||
raw::redis_log(ctx, &format!("Error: failed to add ACL categories `{}`", $module_acl_categories)); | ||
return raw::Status::Err as c_int; | ||
} | ||
} else { | ||
raw::redis_log(ctx, "Warning: Redis version does not support adding new ACL categories"); | ||
} | ||
)* | ||
|
||
$( | ||
$crate::redis_command!(ctx, $name, $command, $flags, $firstkey, $lastkey, $keystep, $acl_categories); | ||
$crate::redis_command!(ctx, $name, $command, $flags, $firstkey, $lastkey, $keystep, $mandatory_command_acl_categories $(, $optional_command_acl_categories)?); | ||
)* | ||
|
||
if $crate::commands::register_commands(&context) == raw::Status::Err { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
#!/usr/bin/env sh | ||
cargo test --all --all-targets --no-default-features | ||
cargo test --all --all-targets --no-default-features --features min-redis-compatibility-version-7-4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the simplicity, I'd do two things:
CommandAclCategory
:Where we would add all the already existing, commonly used acl categories which have already existed for a long time, and would always specifying a new one by having the
Other
variant.acl_categories
arguments, as we specify them separately, not all within one argument:mandatory_acl_category
andoptional_acl_category
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the response!
How we want to specify them for redis - this is the implementation detail. The interface here is in Rust, and we should allow the safest, most idiomatic way possible, which is an explicit set of type-safe values. Do you agree? For the user of this macro it shouldn't matter how exactly those end up being sent to the server, the user shouldn't care about this, nor should he know about this, if this is hidden behind the interface. This is not why this crate is simply forwarding the rust types to the C-api, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's the user that decides which categories are mandatory and which are optional, not us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, okay, that I am not discussing anymore. I am talking now about the type safety and the explicit lists.