redis_module/
native_types.rs1use std::cell::RefCell;
2use std::ffi::CString;
3use std::ptr;
4
5use crate::raw;
6
7pub struct RedisType {
8 name: &'static str,
9 version: i32,
10 type_methods: raw::RedisModuleTypeMethods,
11 pub raw_type: RefCell<*mut raw::RedisModuleType>,
12}
13
14unsafe impl Sync for RedisType {}
17
18impl RedisType {
19 #[must_use]
20 pub const fn new(
21 name: &'static str,
22 version: i32,
23 type_methods: raw::RedisModuleTypeMethods,
24 ) -> Self {
25 Self {
26 name,
27 version,
28 type_methods,
29 raw_type: RefCell::new(ptr::null_mut()),
30 }
31 }
32
33 #[allow(clippy::not_unsafe_ptr_arg_deref)]
34 pub fn create_data_type(&self, ctx: *mut raw::RedisModuleCtx) -> Result<(), &str> {
35 if self.name.len() != 9 {
36 let msg = "Redis requires the length of native type names to be exactly 9 characters";
37 redis_log(ctx, format!("{msg}, name is: '{}'", self.name).as_str());
38 return Err(msg);
39 }
40
41 let type_name = CString::new(self.name).unwrap();
42
43 let redis_type = unsafe {
44 raw::RedisModule_CreateDataType.unwrap()(
45 ctx,
46 type_name.as_ptr(),
47 self.version, &mut self.type_methods.clone(),
49 )
50 };
51
52 if redis_type.is_null() {
53 redis_log(ctx, "Error: created data type is null");
54 return Err("Error: created data type is null");
55 }
56
57 *self.raw_type.borrow_mut() = redis_type;
58
59 redis_log(
60 ctx,
61 format!("Created new data type '{}'", self.name).as_str(),
62 );
63
64 Ok(())
65 }
66}
67
68#[allow(clippy::not_unsafe_ptr_arg_deref)]
70pub fn redis_log(ctx: *mut raw::RedisModuleCtx, msg: &str) {
71 let level = CString::new("notice").unwrap(); let msg = CString::new(msg).unwrap();
73 unsafe {
74 raw::RedisModule_Log.unwrap()(ctx, level.as_ptr(), msg.as_ptr());
75 }
76}