jsonfmt: Add error reporting
This commit is contained in:
parent
3ae9347ad2
commit
e0161cd22c
2 changed files with 18 additions and 6 deletions
|
|
@ -12,7 +12,7 @@ static void fujson_fmt_str(pTHX_ fustr *out, const char *stri, size_t len, int u
|
||||||
* strings, I suspect there's room for optimizations in
|
* strings, I suspect there's room for optimizations in
|
||||||
* is_c9strict_utf8_string(). */
|
* is_c9strict_utf8_string(). */
|
||||||
if (utf8 && !is_c9strict_utf8_string(str, len)) {
|
if (utf8 && !is_c9strict_utf8_string(str, len)) {
|
||||||
return; /* TODO: Throw error. */
|
croak("invalid codepoint encountered in string, cannot format to JSON");
|
||||||
}
|
}
|
||||||
|
|
||||||
fustr_write(out, "\"", 1);
|
fustr_write(out, "\"", 1);
|
||||||
|
|
@ -151,9 +151,8 @@ static void fujson_fmt(pTHX_ fustr *out, SV *val) {
|
||||||
} else if (SvPOKp(val)) {
|
} else if (SvPOKp(val)) {
|
||||||
fujson_fmt_str(aTHX_ out, SvPVX(val), SvCUR(val), SvUTF8(val));
|
fujson_fmt_str(aTHX_ out, SvPVX(val), SvCUR(val), SvUTF8(val));
|
||||||
} else if (SvNOKp(val)) { /* Must check before IOKp, because integer conversion might have been lossy */
|
} else if (SvNOKp(val)) { /* Must check before IOKp, because integer conversion might have been lossy */
|
||||||
/* TODO: quadmath? */
|
|
||||||
NV nv = SvNV_nomg(val);
|
NV nv = SvNV_nomg(val);
|
||||||
if (isinfnan(nv)) return; /* TODO: error */
|
if (isinfnan(nv)) croak("unable to format floating point NaN or Inf as JSON");
|
||||||
fustr_reserve(out, NV_DIG+1);
|
fustr_reserve(out, NV_DIG+1);
|
||||||
Gconvert(nv, NV_DIG, 0, out->cur);
|
Gconvert(nv, NV_DIG, 0, out->cur);
|
||||||
out->cur += strlen(out->cur);
|
out->cur += strlen(out->cur);
|
||||||
|
|
@ -165,11 +164,11 @@ static void fujson_fmt(pTHX_ fustr *out, SV *val) {
|
||||||
if (UNLIKELY(SvOBJECT(rv))) { /* TODO: Check for TO_JSON */ }
|
if (UNLIKELY(SvOBJECT(rv))) { /* TODO: Check for TO_JSON */ }
|
||||||
else if (SvTYPE(rv) == SVt_PVHV) fujson_fmt_hv(aTHX_ out, (HV *)rv);
|
else if (SvTYPE(rv) == SVt_PVHV) fujson_fmt_hv(aTHX_ out, (HV *)rv);
|
||||||
else if (SvTYPE(rv) == SVt_PVAV) fujson_fmt_av(aTHX_ out, (AV *)rv);
|
else if (SvTYPE(rv) == SVt_PVAV) fujson_fmt_av(aTHX_ out, (AV *)rv);
|
||||||
else return; /* TODO: error */
|
else croak("unable to format reference '%s' as JSON", SvPV_nolen(val));
|
||||||
} else if (!SvOK(val)) {
|
} else if (!SvOK(val)) {
|
||||||
fustr_write(out, "null", 4);
|
fustr_write(out, "null", 4);
|
||||||
} else {
|
} else {
|
||||||
/* TODO: error */
|
croak("unable to format unknown value '%s' as JSON", SvPV_nolen(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,15 @@ my @tests = (
|
||||||
1844674407370955161 / 10, '1.84467440737096e+17',
|
1844674407370955161 / 10, '1.84467440737096e+17',
|
||||||
);
|
);
|
||||||
|
|
||||||
plan tests => @tests + 6;
|
my @errors = (
|
||||||
|
\1, qr/unable to format reference/,
|
||||||
|
*STDOUT, qr/unable to format unknown value/,
|
||||||
|
'NaN'+0, qr/unable to format floating point NaN or Inf as JSON/,
|
||||||
|
'Inf'+0, qr/unable to format floating point NaN or Inf as JSON/,
|
||||||
|
do { no warnings 'portable'; "\x{ffffffff}" }, qr/invalid codepoint encountered in string/,
|
||||||
|
);
|
||||||
|
|
||||||
|
plan tests => @tests + @errors/2 + 6;
|
||||||
|
|
||||||
for my($in, $exp) (@tests) {
|
for my($in, $exp) (@tests) {
|
||||||
my $out = json_format $in;
|
my $out = json_format $in;
|
||||||
|
|
@ -58,6 +66,11 @@ for my($in, $exp) (@tests) {
|
||||||
ok utf8::is_utf8($out);
|
ok utf8::is_utf8($out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for my ($in, $exp) (@errors) {
|
||||||
|
eval { json_format $in };
|
||||||
|
like $@, $exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# http://e-choroba.eu/18-yapc slide 6
|
# http://e-choroba.eu/18-yapc slide 6
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue