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

Commit 62c47fa

Browse files
gkorlandgavrie
authored andcommitted
fix #55 return the right type on json.num* call
1 parent 4c46496 commit 62c47fa

File tree

2 files changed

+39
-33
lines changed

2 files changed

+39
-33
lines changed

src/lib.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -299,33 +299,39 @@ where
299299

300300
let key = args.next_string()?;
301301
let path = backwards_compat_path(args.next_string()?);
302-
let number: f64 = args.next_string()?.parse()?;
302+
let number = args.next_string()?;
303303

304304
let key = ctx.open_key_writable(&key);
305305

306306
key.get_value::<RedisJSON>(&REDIS_JSON_TYPE)?
307307
.ok_or_else(RedisError::nonexistent_key)
308308
.and_then(|doc| {
309-
doc.value_op(&path, |value| do_json_num_op(&fun, number, value))
309+
doc.value_op(&path, |value| do_json_num_op(&fun, &number, value))
310310
.map(|v| v.to_string().into())
311311
.map_err(|e| e.into())
312312
})
313313
}
314314

315-
fn do_json_num_op<F>(fun: F, number: f64, value: &Value) -> Result<Value, Error>
315+
fn do_json_num_op<F>(fun: F, number: &String, value: &Value) -> Result<Value, Error>
316316
where
317317
F: FnOnce(f64, f64) -> f64,
318318
{
319-
value
320-
.as_f64()
321-
.ok_or_else(|| err_json(value, "number"))
322-
.and_then(|curr_value| {
323-
let res = fun(curr_value, number);
324-
325-
Number::from_f64(res)
326-
.ok_or(Error::from("ERR cannot represent result as Number"))
327-
.map(Value::Number)
328-
})
319+
if let Value::Number(curr_value) = value {
320+
let in_value = serde_json::from_str(number.as_str())?;
321+
if let Value::Number(value) = in_value {
322+
// TODO avoid convert to f64 when not needed
323+
let num_res = fun(curr_value.as_f64().unwrap(), value.as_f64().unwrap());
324+
if curr_value.is_f64() || value.is_f64() {
325+
Ok(num_res.into())
326+
} else {
327+
Ok((num_res as i64).into())
328+
}
329+
} else {
330+
Err(err_json(&in_value, "number"))
331+
}
332+
} else {
333+
Err(err_json(value, "number"))
334+
}
329335
}
330336

331337
fn err_json(value: &Value, expected_value: &'static str) -> Error {

test/pytest/test.py

+20-20
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,10 @@ def testNumIncrCommand(self):
599599
r.flushdb()
600600

601601
self.assertOk(r.execute_command('JSON.SET', 'test', '.', '{ "foo": 0, "bar": "baz" }'))
602-
# self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', 1))
603-
# self.assertEqual('1', r.execute_command('JSON.GET', 'test', '.foo'))
604-
# self.assertEqual('3', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', 2))
605-
# self.assertEqual('3.5', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', .5))
602+
self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', 1))
603+
self.assertEqual('1', r.execute_command('JSON.GET', 'test', '.foo'))
604+
self.assertEqual('3', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', 2))
605+
self.assertEqual('3.5', r.execute_command('JSON.NUMINCRBY', 'test', '.foo', .5))
606606

607607
# test a wrong type
608608
with self.assertRaises(redis.exceptions.ResponseError) as cm:
@@ -612,22 +612,22 @@ def testNumIncrCommand(self):
612612
# with self.assertRaises(redis.exceptions.ResponseError) as cm:
613613
# r.execute_command('JSON.NUMINCRBY', 'test', '.fuzz', 1)
614614
#
615-
# # test issue #9
616-
# self.assertOk(r.execute_command('JSON.SET', 'num', '.', '0'))
617-
# self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'num', '.', 1))
618-
# self.assertEqual('2.5', r.execute_command('JSON.NUMINCRBY', 'num', '.', 1.5))
619-
#
620-
# # test issue 55
621-
# self.assertOk(r.execute_command('JSON.SET', 'foo', '.', '{"foo":0,"bar":42}'))
622-
# # Get the document once
623-
# r.execute_command('JSON.GET', 'foo', '.')
624-
# self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'foo', 'foo', 1))
625-
# self.assertEqual('84', r.execute_command('JSON.NUMMULTBY', 'foo', 'bar', 2))
626-
# res = json.loads(r.execute_command('JSON.GET', 'foo', '.'))
627-
# self.assertEqual(1, res['foo'])
628-
# self.assertEqual(84, res['bar'])
629-
#
630-
#
615+
# test issue #9
616+
self.assertOk(r.execute_command('JSON.SET', 'num', '.', '0'))
617+
self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'num', '.', 1))
618+
self.assertEqual('2.5', r.execute_command('JSON.NUMINCRBY', 'num', '.', 1.5))
619+
620+
# test issue 55
621+
self.assertOk(r.execute_command('JSON.SET', 'foo', '.', '{"foo":0,"bar":42}'))
622+
# Get the document once
623+
r.execute_command('JSON.GET', 'foo', '.')
624+
self.assertEqual('1', r.execute_command('JSON.NUMINCRBY', 'foo', 'foo', 1))
625+
self.assertEqual('84', r.execute_command('JSON.NUMMULTBY', 'foo', 'bar', 2))
626+
res = json.loads(r.execute_command('JSON.GET', 'foo', '.'))
627+
self.assertEqual(1, res['foo'])
628+
self.assertEqual(84, res['bar'])
629+
630+
631631
def testStrCommands(self):
632632
"""Test JSON.STRAPPEND and JSON.STRLEN commands"""
633633

0 commit comments

Comments
 (0)