use lance_jsonb::OwnedJsonb;
use lance_jsonb::RawJsonb;
use lance_jsonb::parse_value;
fn decode_hex(hex: &str) -> Vec<u8> {
(0..hex.len())
.step_by(2)
.map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
.collect()
}
const ENCODE_CASES: &[(&str, &str, &str)] = &[
(r#"null"#, "2000000000000000", r#"null"#),
(r#"true"#, "2000000040000000", r#"true"#),
(r#"false"#, "2000000030000000", r#"false"#),
(r#"0"#, "200000002000000100", r#"0"#),
(r#"-0"#, "200000002000000100", r#"0"#),
(r#"1"#, "20000000200000025001", r#"1"#),
(r#"-1"#, "200000002000000240ff", r#"-1"#),
(r#"127"#, "2000000020000002507f", r#"127"#),
(r#"128"#, "20000000200000025080", r#"128"#),
(r#"255"#, "200000002000000250ff", r#"255"#),
(r#"256"#, "2000000020000003500100", r#"256"#),
(r#"-128"#, "20000000200000024080", r#"-128"#),
(r#"-129"#, "200000002000000340ff7f", r#"-129"#),
(r#"32767"#, "2000000020000003507fff", r#"32767"#),
(r#"32768"#, "2000000020000003508000", r#"32768"#),
(
r#"2147483647"#,
"2000000020000005507fffffff",
r#"2147483647"#,
),
(
r#"2147483648"#,
"20000000200000055080000000",
r#"2147483648"#,
),
(
r#"-2147483649"#,
"200000002000000940ffffffff7fffffff",
r#"-2147483649"#,
),
(
r#"9223372036854775807"#,
"2000000020000009507fffffffffffffff",
r#"9223372036854775807"#,
),
(
r#"-9223372036854775808"#,
"2000000020000009408000000000000000",
r#"-9223372036854775808"#,
),
(
r#"9223372036854775808"#,
"2000000020000009508000000000000000",
r#"9223372036854775808"#,
),
(
r#"18446744073709551615"#,
"200000002000000950ffffffffffffffff",
r#"18446744073709551615"#,
),
(
r#"18446744073709551616"#,
"20000000200000096043f0000000000000",
r#"1.8446744073709552e+19"#,
),
(
r#"-9223372036854775809"#,
"200000002000000960c3e0000000000000",
r#"-9.223372036854776e+18"#,
),
(
r#"123456789012345678901234567890"#,
"20000000200000096045f8ee90ff6c373e",
r#"1.2345678901234568e+29"#,
),
(r#"0.0"#, "2000000020000009600000000000000000", r#"0.0"#),
(r#"-0.0"#, "2000000020000009608000000000000000", r#"-0.0"#),
(r#"1.5"#, "2000000020000009603ff8000000000000", r#"1.5"#),
(r#"-1.5"#, "200000002000000960bff8000000000000", r#"-1.5"#),
(r#"0.1"#, "2000000020000009603fb999999999999a", r#"0.1"#),
(
r#"1e10"#,
"2000000020000009604202a05f20000000",
r#"10000000000.0"#,
),
(r#"1E-7"#, "2000000020000009603e7ad7f29abcaf48", r#"1e-7"#),
(
r#"3.141592653589793"#,
"200000002000000960400921fb54442d18",
r#"3.141592653589793"#,
),
(
r#"1.7976931348623157e308"#,
"2000000020000009607fefffffffffffff",
r#"1.7976931348623157e+308"#,
),
(r#"1e400"#, "200000002000000120", r#"null"#),
(
r#"100.00"#,
"2000000020000009604059000000000000",
r#"100.0"#,
),
(r#"2.50"#, "2000000020000009604004000000000000", r#"2.5"#),
(r#""""#, "2000000010000000", r#""""#),
(r#""a""#, "200000001000000161", r#""a""#),
(
r#""hello world""#,
"200000001000000b68656c6c6f20776f726c64",
r#""hello world""#,
),
(
r#""\u00e9\n\t\"\\""#,
"2000000010000006c3a90a09225c",
r#""é\n\t\"\\""#,
),
(r#""中文""#, "2000000010000006e4b8ade69687", r#""中文""#),
(r#""\ud83d\ude00""#, "2000000010000004f09f9880", r#""😀""#),
(r#"[]"#, "80000000", r#"[]"#),
(r#"{}"#, "40000000", r#"{}"#),
(
r#"[1,2,3]"#,
"80000003200000022000000220000002500150025003",
r#"[1,2,3]"#,
),
(
r#"[null,true,false,"x",1.25,[],{}]"#,
"800000070000000040000000300000001000000120000009500000045000000478603ff40000000000008000000040000000",
r#"[null,true,false,"x",1.25,[],{}]"#,
),
(
r#"{"b":1,"a":2}"#,
"4000000210000001100000012000000220000002616250025001",
r#"{"a":2,"b":1}"#,
),
(
r#"{"k":{"nested":[1,{"deep":"v"}]}}"#,
"4000000110000001500000316b40000001100000065000001f6e657374656480000002200000025000001150014000000110000004100000016465657076",
r#"{"k":{"nested":[1,{"deep":"v"}]}}"#,
),
(
r#"{"z":null,"aa":[1,2],"a":{"y":true,"x":false},"":"empty"}"#,
"4000000410000000100000011000000210000001100000055000001650000010000000006161617a656d7074794000000210000001100000013000000040000000787980000002200000022000000250015002",
r#"{"":"empty","a":{"x":false,"y":true},"aa":[1,2],"z":null}"#,
),
(
r#" { "sp" : [ 1 , 2 ] } "#,
"400000011000000250000010737080000002200000022000000250015002",
r#"{"sp":[1,2]}"#,
),
];
#[test]
fn test_encode_matches_released_layout() {
for (json, hex, text) in ENCODE_CASES {
let expected = decode_hex(hex);
let from_value = parse_value(json.as_bytes()).unwrap().to_vec();
assert_eq!(from_value, expected, "parse_value encoding of {json}");
let from_str = json.parse::<OwnedJsonb>().unwrap().to_vec();
assert_eq!(
from_str, expected,
"OwnedJsonb::from_str encoding of {json}"
);
assert_eq!(
RawJsonb::new(&expected).to_string(),
*text,
"decoding of {json}"
);
}
}
#[test]
fn test_duplicate_object_key_is_rejected() {
assert!(parse_value(br#"{"a":1,"a":2}"#).is_err());
assert!(r#"{"a":1,"a":2}"#.parse::<OwnedJsonb>().is_err());
}
const DECODE_CASES: &[(&str, &str, &str)] = &[
(
"uint64",
"200000002000000950ffffffffffffffff",
r#"18446744073709551615"#,
),
(
"decimal64",
"200000002000000a70ffffffffffffcfc702",
r#"-123.45"#,
),
(
"decimal128",
"2000000020000012700000000000661efdf158f2a82c9f4b870a",
r#"1.2345678901234568e+16"#,
),
(
"decimal256",
"200000002000002270ffffffffffffffffffffffffffffffffffffffffffffffca758afbde0b5ff00003",
r#"-9.87654321e+17"#,
),
("binary", "20000000600000040000ff10", r#""00FF10""#),
("date", "20000000600000051000004a38", r#""2022-01-08""#),
(
"timestamp",
"20000000600000092000060a2418202240",
r#""2023-11-14 22:13:20.123456""#,
),
(
"timestamp_tz",
"200000006000000d3000060a241820224000007080",
r#""2023-11-15 06:13:20.123456 +0800""#,
),
(
"interval",
"2000000060000011400000000e0000000300000000dde878c1",
r#""1 year 2 months 3 days 01:02:03.000001""#,
),
(
"array_mixed",
"80000003600000052000000a6000000310ffffffff70000000000000000700006162",
r#"["1969-12-31",7.0,"6162"]"#,
),
];
#[test]
fn test_decode_extended_values() {
for (name, hex, text) in DECODE_CASES {
let bytes = decode_hex(hex);
assert_eq!(
RawJsonb::new(&bytes).to_string(),
*text,
"decoding of {name}"
);
}
}