From 99b56630f7575e20f55a8601d01d3353732199f3 Mon Sep 17 00:00:00 2001 From: Jeremi Sobierski Date: Tue, 25 Oct 2022 22:20:27 +0200 Subject: [PATCH] adds bytes-accepting versions of key methods --- src/key.rs | 35 ++++++++++++++++++++++++++++++++++- src/lib.rs | 5 ++--- src/raw.rs | 6 +++++- src/redismodule.rs | 10 +++++++--- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/key.rs b/src/key.rs index ef18f9a9..473a58ab 100644 --- a/src/key.rs +++ b/src/key.rs @@ -84,7 +84,19 @@ impl RedisKey { Ok(val) } + pub fn read_bytes(&self) -> Option> { + if self.is_null() { + None + } else { + Some(read_key_bytes(self.key_inner)) + } + } + pub fn hash_get(&self, field: &str) -> Result, RedisError> { + self.hash_bytes_get(field.as_bytes()) + } + + pub fn hash_bytes_get(&self, field: &[u8]) -> Result, RedisError> { let val = if self.is_null() { None } else { @@ -160,6 +172,15 @@ impl RedisKeyWritable { Ok(Some(read_key(self.key_inner)?)) } + pub fn read_bytes(&self) -> Option> { + Some(read_key_bytes(self.key_inner)) + } + + #[allow(clippy::must_use_candidate)] + pub fn hash_bytes_set(&self, field: &[u8], value: RedisString) -> raw::Status { + raw::hash_bytes_set(self.key_inner, field, value.inner) + } + #[allow(clippy::must_use_candidate)] pub fn hash_set(&self, field: &str, value: RedisString) -> raw::Status { raw::hash_set(self.key_inner, field, value.inner) @@ -171,6 +192,10 @@ impl RedisKeyWritable { } pub fn hash_get(&self, field: &str) -> Result, RedisError> { + self.hash_bytes_get(field.as_bytes()) + } + + pub fn hash_bytes_get(&self, field: &[u8]) -> Result, RedisError> { Ok(hash_mget_key(self.ctx, self.key_inner, &[field])? .pop() .expect("hash_mget_key should return vector of same length as input")) @@ -254,7 +279,11 @@ impl RedisKeyWritable { } pub fn write(&self, val: &str) -> RedisResult { - let val_str = RedisString::create(self.ctx, val); + self.write_bytes(val.as_bytes()) + } + + pub fn write_bytes(&self, val: &[u8]) -> RedisResult { + let val_str = RedisString::from_bytes(self.ctx, val); match raw::string_set(self.key_inner, val_str.inner) { raw::Status::Ok => REDIS_OK, raw::Status::Err => Err(RedisError::Str("Error while setting key")), @@ -454,6 +483,10 @@ impl Drop for RedisKeyWritable { } fn read_key(key: *mut raw::RedisModuleKey) -> Result { + String::from_utf8(read_key_bytes(key)).map_err(|e| e.utf8_error()) +} + +fn read_key_bytes(key: *mut raw::RedisModuleKey) -> Vec { let mut length: size_t = 0; from_byte_string( raw::string_dma(key, &mut length, raw::KeyMode::READ), diff --git a/src/lib.rs b/src/lib.rs index 61c89025..a16a40b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ pub use crate::context::InfoContext; use std::os::raw::c_char; -use std::str::Utf8Error; use strum_macros::AsRefStr; extern crate num_traits; @@ -52,14 +51,14 @@ pub enum LogLevel { Warning, } -fn from_byte_string(byte_str: *const c_char, length: size_t) -> Result { +fn from_byte_string(byte_str: *const c_char, length: size_t) -> Vec { let mut vec_str: Vec = Vec::with_capacity(length as usize); for j in 0..length { let byte = unsafe { *byte_str.add(j) } as u8; vec_str.insert(j, byte); } - String::from_utf8(vec_str).map_err(|e| e.utf8_error()) + vec_str } pub fn base_info_func( diff --git a/src/raw.rs b/src/raw.rs index ae122442..d131a141 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -369,8 +369,12 @@ where } } -#[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn hash_set(key: *mut RedisModuleKey, field: &str, value: *mut RedisModuleString) -> Status { + hash_bytes_set(key, field.as_bytes(), value) +} + +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn hash_bytes_set(key: *mut RedisModuleKey, field: &[u8], value: *mut RedisModuleString) -> Status { let field = CString::new(field).unwrap(); unsafe { diff --git a/src/redismodule.rs b/src/redismodule.rs index 1b87d494..4ce97394 100644 --- a/src/redismodule.rs +++ b/src/redismodule.rs @@ -100,10 +100,14 @@ impl RedisString { Self { ctx, inner } } - #[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn create(ctx: *mut raw::RedisModuleCtx, s: &str) -> Self { - let str = CString::new(s).unwrap(); - let inner = unsafe { raw::RedisModule_CreateString.unwrap()(ctx, str.as_ptr(), s.len()) }; + Self::from_bytes(ctx, s.as_bytes()) + } + + #[allow(clippy::not_unsafe_ptr_arg_deref)] + pub fn from_bytes(ctx: *mut raw::RedisModuleCtx, bytes: &[u8]) -> Self { + let str = CString::new(bytes).unwrap(); + let inner = unsafe { raw::RedisModule_CreateString.unwrap()(ctx, str.as_ptr(), bytes.len()) }; Self { ctx, inner } }