jsonfmt: Add canonical option

Not as bad as I had expected it to be; managed to keep the
implementation a little bit simpler and cleaner than JSON::XS.
This commit is contained in:
Yorhel 2025-01-29 18:42:27 +01:00
parent 163a60b4ba
commit 1a0fb03205
5 changed files with 115 additions and 23 deletions

View file

@ -65,20 +65,28 @@ sub def($id, $text, @f) {
# Use similar options for fair comparisons.
my $j_cp = Cpanel::JSON::XS->new->allow_nonref->unblessed_bool->convert_blessed;
my $j_pp = JSON::PP->new->allow_nonref->core_bools->convert_blessed;
my $j_xs = JSON::XS->new->allow_nonref->boolean_values([false,true])->convert_blessed;
my $j_si = JSON::SIMD->new->allow_nonref->core_bools->convert_blessed;
use FU::Util 'json_format';
sub jsonfmt($name, $text, $data) {
# Use similar options for fair comparisons.
my $cp = Cpanel::JSON::XS->new->allow_nonref->unblessed_bool->convert_blessed;
my $pp = JSON::PP->new->allow_nonref->core_bools->convert_blessed;
my $xs = JSON::XS->new->allow_nonref->boolean_values([false,true])->convert_blessed;
my $si = JSON::SIMD->new->allow_nonref->core_bools->convert_blessed;
my @opt = ();
if ($name =~ /^canon/) {
$cp = $cp->canonical;
$pp = $pp->canonical;
$xs = $xs->canonical;
$si = $si->canonical;
@opt = (canonical => 1);
}
def "jsonfmt/$name", $text,
'JSON::PP', undef, sub { $j_pp->encode($data) },
'Cpanel::JSON::XS', undef, sub { $j_cp->encode($data) },
'JSON::SIMD', undef, sub { $j_si->encode($data) },
'JSON::XS', undef, sub { $j_xs->encode($data) },
'FU::Util', 'FU', sub { json_format $data };
'JSON::PP', undef, sub { $pp->encode($data) },
'Cpanel::JSON::XS', undef, sub { $cp->encode($data) },
'JSON::SIMD', undef, sub { $si->encode($data) },
'JSON::XS', undef, sub { $xs->encode($data) },
'FU::Util', 'FU', sub { json_format $data, @opt };
}
# From JSON::XS POD.
@ -94,7 +102,8 @@ jsonfmt stru => 'Unicode strings', do { use utf8;
jsonfmt stres => 'String escaping (few)', [ map 'This string needs to "be escaped" a little bit', 1..100 ];
jsonfmt strel => 'String escaping (many)', [ map "This \" \\ needs \b\x01\x02\x03\x04 more", 1..100 ];
jsonfmt canons => 'Canonical hash key ordering (small)', [ map +{ map +("string$_", 1), 'a'..'f' }, 0..100 ];
jsonfmt canonl => 'Canonical hash key ordering (large)', { map +("string$_-something", 1), 'aa'..'zz' };