Skip to content

Commit c465aad

Browse files
committed
impl TryFrom<&[u8]> for NumberAny
1 parent eccf28e commit c465aad

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

crates/jiter/src/number_decoder.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,29 @@ impl From<NumberAny> for f64 {
133133
}
134134
}
135135

136+
impl TryFrom<&[u8]> for NumberAny {
137+
type Error = JsonError;
138+
139+
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
140+
let first = *value.first().ok_or_else(|| json_error!(InvalidNumber, 0))?;
141+
let (int_parse, index) = IntParse::parse(value, 0, first)?;
142+
let (number, index) = match int_parse {
143+
IntParse::Int(int) => (Self::Int(int), index),
144+
IntParse::Float => {
145+
let (f, index) = NumberFloat::decode(value, 0, first, false)?;
146+
(Self::Float(f), index)
147+
}
148+
_ => return json_err!(InvalidNumber, index),
149+
};
150+
151+
if index == value.len() {
152+
Ok(number)
153+
} else {
154+
json_err!(InvalidNumber, index)
155+
}
156+
}
157+
}
158+
136159
impl AbstractNumberDecoder for NumberAny {
137160
type Output = NumberAny;
138161

crates/jiter/tests/main.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,50 @@ fn test_number_int_try_from_bytes() {
14181418
assert_eq!(e.to_string(), "number out of range at index 4301");
14191419
}
14201420

1421+
#[test]
1422+
fn test_number_any_try_from_bytes() {
1423+
let n: NumberAny = b"123".as_ref().try_into().unwrap();
1424+
assert_eq!(n, NumberAny::Int(NumberInt::Int(123)));
1425+
1426+
let n: NumberAny = b"0".as_ref().try_into().unwrap();
1427+
assert_eq!(n, NumberAny::Int(NumberInt::Int(0)));
1428+
1429+
let n: NumberAny = b"123.456".as_ref().try_into().unwrap();
1430+
assert_eq!(n, NumberAny::Float(123.456));
1431+
1432+
let n: NumberAny = b"123.45e2".as_ref().try_into().unwrap();
1433+
assert_eq!(n, NumberAny::Float(12345.0));
1434+
1435+
let twenty_nines = "9".repeat(29);
1436+
let n: NumberAny = twenty_nines.as_bytes().try_into().unwrap();
1437+
match n {
1438+
NumberAny::Int(NumberInt::BigInt(v)) => assert_eq!(v.to_string(), twenty_nines),
1439+
_ => panic!("expected big int"),
1440+
}
1441+
1442+
let e = NumberAny::try_from(b"x23".as_ref()).unwrap_err();
1443+
assert_eq!(e.to_string(), "invalid number at index 0");
1444+
1445+
let e = NumberAny::try_from(b"".as_ref()).unwrap_err();
1446+
assert_eq!(e.to_string(), "invalid number at index 0");
1447+
1448+
let e = NumberAny::try_from(b"2x3".as_ref()).unwrap_err();
1449+
assert_eq!(e.to_string(), "invalid number at index 1");
1450+
1451+
let e = NumberAny::try_from(b"123 ".as_ref()).unwrap_err();
1452+
assert_eq!(e.to_string(), "invalid number at index 3");
1453+
1454+
let e = NumberAny::try_from(b"123.1 ".as_ref()).unwrap_err();
1455+
assert_eq!(e.to_string(), "invalid number at index 5");
1456+
1457+
let e = NumberAny::try_from(b"0123".as_ref()).unwrap_err();
1458+
assert_eq!(e.to_string(), "invalid number at index 1");
1459+
1460+
let too_long = "9".repeat(4309);
1461+
let e = NumberAny::try_from(too_long.as_bytes()).unwrap_err();
1462+
assert_eq!(e.to_string(), "number out of range at index 4301");
1463+
}
1464+
14211465
#[test]
14221466
fn jiter_skip_whole_object() {
14231467
let mut jiter = Jiter::new(br#"{"x": 1}"#);

0 commit comments

Comments
 (0)