[][src]Attribute Macro iredismodule_macros::rtypedef

#[rtypedef]

This macro will be used to define a module type.

It must be used in impl TypeMethod for T.

It have two attr value.

  • name: A 9 characters data type name that MUST be unique in the Redis Modules ecosystem. Be creative... and there will be no collisions. Use the charset A-Z a-z 9-0, plus the two "-_" characters. A good idea is to use, for example <typename>-<vendor>. For example "tree-AntZ" may mean "Tree data structure by @antirez". To use both lower case and upper case letters helps in order to prevent collisions.
  • encver: Encoding version, which is, the version of the serialization that a module used in order to persist data. As long as the "name" matches, the RDB loading will be dispatched to the type callbacks whatever 'encver' is used, however the module can understand if the encoding it must load are of an older version of the module. For example the module "tree-AntZ" initially used encver=0. Later after an upgrade, it started to serialize data in a different format and to register the type with encver=1. However this module may still load old data produced by an older version if the rdb_load callback is able to check the encver value and act accordingly. The encver must be a positive value between 0 and 1023.
#[rtypedef("hellotype", 0)]
impl TypeMethod for HelloTypeNode {
    fn rdb_load(io: &mut IO, encver: u32) -> Option<Box<Self>> {
        if encver != 0 {
            return None;
        }
        let elements = io.load_unsigned();
        let mut hto = Self::new();
        for _ in 0..elements {
            let ele = io.load_signed();
            hto.push(ele);
        }
        Some(Box::new(hto))
    }
    fn rdb_save(&self, io: &mut IO) {
        let eles: Vec<&i64> = self.iter().collect();
        io.save_unsigned(eles.len() as u64);
        eles.iter().for_each(|v| io.save_signed(**v));
    }
    fn free(_: Box<Self>) {}
    fn aof_rewrite<T: AsRef<str>>(&self, io: &mut IO, key: T) {
        let eles: Vec<&i64> = self.iter().collect();
        let keyname = key.as_ref();
        eles.iter().for_each(|v| {
            io.emit_aof(
                "HELLOTYPE.INSERT",
                &[keyname, &v.to_string()],
            )
        })
    }
    fn mem_usage(&self) -> usize {
        std::mem::size_of::<Self>() * self.len()
    }
    fn digest(&self, digest: &mut Digest) {
        let eles: Vec<&i64> = self.iter().collect();
        eles.iter().for_each(|v| digest.add_long_long(**v));
        digest.end_sequeue();
    }
}

The macro will generate static variable which repersent the data type. The variabe name is generated by switching to uppercase and replace "-" with "_".

The methods of trait will be expand to extern "C" fn and will be used to set the value of RedisModuleTypeMethods fields.

For example. The macro will generate hellotype_rdb_save based on method rdb_save.

unsafe extern "C" fn hellotype_rdb_save(
    rdb: *mut iredismodule::raw::RedisModuleIO,
    value: *mut std::os::raw::c_void,
) {
    use iredismodule::FromPtr;
    let mut io = iredismodule::io::IO::from_ptr(rdb);
    let hto = &*(value as *mut HelloTypeNode);
    hto.rdb_save(&mut io)
}

If the method is ommited, the value will be set none in construct RedisModuleTypeMethods.

pub static HELLOTYPE: iredismodule::rtype::RType<HelloTypeNode> = iredismodule::rtype::RType::new(
    "hellotype",
    0i32,
    iredismodule::raw::RedisModuleTypeMethods {
        version: iredismodule::raw::REDISMODULE_TYPE_METHOD_VERSION as u64,
        rdb_load: Some(hellotype_rdb_load),
        rdb_save: Some(hellotype_rdb_save),
        aof_rewrite: Some(hellotype_aof_rewrite),
        mem_usage: Some(hellotype_mem_usage),
        free: Some(hellotype_free),
        digest: Some(hellotype_digest),
        aux_load: None,
        aux_save: None,
        aux_save_triggers: HelloTypeNode::AUX_SAVE_TRIGGERS as i32,
    },
);

Finally, use `define_macro` to register that data type.
```rust,no_run
define_module! {
    name: "hellotype",
    version: 1,
    data_types: [
        HELLOTYPE,
    ],
    init_funcs: [],
    commands: [
        ...
    ],
}