fu/FU/Util.pod
Yorhel 1a0fb03205 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.
2025-01-29 18:46:27 +01:00

81 lines
2.7 KiB
Text

=head1 NAME
FU::Util - Miscellaneous utility functions that really should have been part of
a core Perl installation but aren't for some reason because the Perl community
doesn't believe in the concept of a "batteries included" standard library.
</rant>
=head1 SYNOPSIS
use FU::Util qw/json_format/;
my $data = json_format [1, 2, 3];
=head1 DESCRIPTION
=head2 JSON parsing & formatting
This module comes with a custom C-based JSON parser and formatter. These
functions conform strictly to L<RFC-8259|https://tools.ietf.org/html/rfc8259>,
non-standard extensions are not supported and never will be. It also happens to
be pretty fast, refer to L<FU::Benchmarks> for some numbers.
JSON booleans are decoded into C<builtin::true> and C<builtin::false>. When
formatting, those builtin constants are the I<only> recognized boolean values -
alternative representations such as C<JSON::PP::true> and C<JSON::PP::false>
are not recognized and attempting to format such values will croak.
=over
=item json_format($scalar, %options)
Format a Perl value as JSON.
With the default options, this function behaves roughly similar to:
JSON::PP->new->allow_nonref->core_bools->convert_blessed->encode($scalar);
This function croaks when attempting to format a floating point C<NaN> or
C<Inf>.
Some modules escape the slash character in encoded strings to prevent a
potential XSS vulnerability when embedding JSON inside C<< <script> ..
</script> >> tags. This function does I<not> do that because it might not even
be sufficient. The following is probably an improvement:
json_format($data) =~ s{</}{<\\/}rg =~ s/<!--/<\\u0021--/rg;
The following C<%options> are supported:
=over
=item canonical
When set to a true value, write hash keys in deterministic (sorted) order. This
option currently has no effect on tied hashes.
=item utf8
When set to a true value, returns a UTF-8 encoded byte string instead of a Perl
Unicode string.
=item max_size
Maximum permitted size, in bytes, of the generated JSON string. Defaults to 1 GiB.
=item max_depth
Maximum permitted nesting depth of Perl values. Defaults to 512.
=back
=back
(Why the hell yet another JSON codec when CPAN is already full of them!? Well,
L<JSON::XS> is pretty cool but isn't going to be updated to support Perl's new
builtin booleans. L<JSON::PP> is slow and while L<Cpanel::JSON::XS> is
perfectly adequate, its codebase is a little too messy for my taste - too many
unnecessary features and C<#ifdef>s to support ancient perls and esoteric
configurations. Still, if you need anything not provided by these functions,
L<JSON::PP> and L<Cpanel::JSON::XS> are perfectly fine alternatives.
L<JSON::SIMD> and L<Mojo::JSON> also look like good and maintained candidates.)