-
Notifications
You must be signed in to change notification settings - Fork 332
/
Copy pathbackward.rs
93 lines (87 loc) · 2.73 KB
/
backward.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* Copyright Redis Ltd. 2016 - present
* Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
* the Server Side Public License v1 (SSPLv1).
*/
use std::vec::Vec;
use redis_module::raw;
use serde_json::map::Map;
use serde_json::Number;
use serde_json::Value;
use crate::error::Error;
#[derive(Debug, PartialEq)]
enum NodeType {
Null,
// used in masks and consistent type checking
String,
Number,
Integer,
Boolean,
Dict,
Array,
KeyVal,
// N_DATETIME = 0x100
// N_BINARY = 0x200
}
impl From<u64> for NodeType {
fn from(n: u64) -> Self {
match n {
0x1u64 => Self::Null,
0x2u64 => Self::String,
0x4u64 => Self::Number,
0x8u64 => Self::Integer,
0x10u64 => Self::Boolean,
0x20u64 => Self::Dict,
0x40u64 => Self::Array,
0x80u64 => Self::KeyVal,
_ => panic!("Can't load old RedisJSON RDB1"),
}
}
}
pub fn json_rdb_load(rdb: *mut raw::RedisModuleIO) -> Result<Value, Error> {
let node_type = raw::load_unsigned(rdb)?.into();
match node_type {
NodeType::Null => Ok(Value::Null),
NodeType::Boolean => {
let buffer = raw::load_string_buffer(rdb)?;
Ok(Value::Bool(buffer.as_ref()[0] == b'1'))
}
NodeType::Integer => {
let n = raw::load_signed(rdb)?;
Ok(Value::Number(n.into()))
}
NodeType::Number => {
let n = raw::load_double(rdb)?;
Ok(Value::Number(
Number::from_f64(n).ok_or_else(|| Error::from("Can't load as float"))?,
))
}
NodeType::String => {
let buffer = raw::load_string_buffer(rdb)?;
Ok(Value::String(buffer.to_string()?))
}
NodeType::Dict => {
let len = raw::load_unsigned(rdb)?;
let mut m = Map::with_capacity(len as usize);
for _ in 0..len {
let t: NodeType = raw::load_unsigned(rdb)?.into();
if t != NodeType::KeyVal {
return Err(Error::from("Can't load old RedisJSON RDB"));
}
let buffer = raw::load_string_buffer(rdb)?;
m.insert(buffer.to_string()?, json_rdb_load(rdb)?);
}
Ok(Value::Object(m))
}
NodeType::Array => {
let len = raw::load_unsigned(rdb)?;
let mut v = Vec::with_capacity(len as usize);
for _ in 0..len {
let nested = json_rdb_load(rdb)?;
v.push(nested);
}
Ok(Value::Array(v))
}
NodeType::KeyVal => Err(Error::from("Can't load old RedisJSON RDB")),
}
}