Skip to content
This repository was archived by the owner on Apr 20, 2020. It is now read-only.

Commit ea87266

Browse files
committed
Add support for str_len
1 parent efb6508 commit ea87266

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

src/lib.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[macro_use]
22
extern crate redismodule;
33

4-
use redismodule::{Context, RedisResult, NextArg};
4+
use redismodule::{Context, RedisResult, NextArg, RedisValue};
55
use redismodule::native_types::RedisType;
66

77
mod redisjson;
@@ -15,7 +15,7 @@ fn json_set(ctx: &Context, args: Vec<String>) -> RedisResult {
1515
let mut args = args.into_iter().skip(1);
1616

1717
let key = args.next_string()?;
18-
let value = args.next_string()?;
18+
let value = args.next_string()?;
1919

2020
let key = ctx.open_key_writable(&key);
2121

@@ -40,13 +40,28 @@ fn json_get(ctx: &Context, args: Vec<String>) -> RedisResult {
4040
let key = ctx.open_key_writable(&key);
4141

4242
let value = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
43-
Some(doc) => { doc.to_string(&path)?.into() }
43+
Some(doc) => doc.to_string(&path)?.into(),
4444
None => ().into()
4545
};
4646

4747
Ok(value)
4848
}
4949

50+
fn json_strlen(ctx: &Context, args: Vec<String>) -> RedisResult {
51+
let mut args = args.into_iter().skip(1);
52+
let key = args.next_string()?;
53+
let path = args.next_string()?;
54+
55+
let key = ctx.open_key_writable(&key);
56+
57+
let length = match key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)? {
58+
Some(doc) => RedisValue::Integer(doc.str_len(&path)? as i64),
59+
None => ().into()
60+
};
61+
62+
Ok(length)
63+
}
64+
5065
//////////////////////////////////////////////////////
5166

5267
redis_module! {
@@ -58,5 +73,6 @@ redis_module! {
5873
commands: [
5974
["json.set", json_set, "write"],
6075
["json.get", json_get, ""],
76+
["json.strlen", json_strlen, ""],
6177
],
6278
}

src/redisjson.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,35 @@ impl RedisJSON {
5252
pub fn to_string(&self, path: &str) -> Result<String, Error> {
5353
eprintln!("Serializing back to JSON");
5454

55+
let s = match self.get_doc(path)? {
56+
Some(doc) => serde_json::to_string(&doc)?,
57+
None => String::new()
58+
};
59+
60+
Ok(s)
61+
}
62+
63+
pub fn str_len(&self, path: &str) -> Result<usize, Error> {
64+
let s = match self.get_doc(path)? {
65+
Some(doc) => {
66+
if doc.is_string() {
67+
serde_json::to_string(&doc)?.len() - 2 // removes ""
68+
} else {
69+
0 // the value is not a String
70+
}
71+
}
72+
None => 0 // path not found
73+
};
74+
Ok(s)
75+
}
76+
77+
pub fn get_doc(&self, path: &str) -> Result<Option<&Value>, Error> {
5578
// Create a JSONPath selector
5679
let selector = Selector::new(path).map_err(|e| Error {
5780
msg: format!("{}", e),
5881
})?;
5982

60-
let s = match selector.find(&self.data).next() {
61-
Some(doc) => serde_json::to_string(&doc)?,
62-
None => String::new()
63-
};
64-
65-
return Ok(s)
83+
Ok(selector.find(&self.data).next())
6684
}
85+
6786
}

0 commit comments

Comments
 (0)