File-Raw-JSON

 view release on metacpan or  search on metacpan

lib/File/Raw/JSON.pm  view on Meta::CPAN

    my $bytes = file_json_encode($val);
    my $jsonl = file_json_encode(\@rows, mode => 'lines');
    my $diff  = file_json_encode($val,   pretty => 1, sort_keys => 1);

=back

The trailing key/value list accepts the same options as the plugin
path (see L</OPTIONS> below). Odd-count tails croak; unknown keys
croak.

These are XSUBs in the C<File::Raw::JSON> package; importable on
request via C<use File::Raw::JSON qw(file_json_decode file_json_encode)>
or C<use File::Raw::JSON qw(:codec)>. They share the same yyjson
codec body as the plugin path, so output is byte-identical to a
C<File::Raw::spew(... plugin =E<gt> 'json', ...)> for the same input.

=head1 OPTIONS

The standard plugin tail accepts these keys.

=over 4

=item C<mode>

C<document> (default for the C<json> plugin) or C<lines> (default
for C<jsonl>). Override the plugin's default per call.

=item C<pretty>

Encode: pretty-print with newlines and indent. Default false.

=item C<indent>

Encode: spaces per indent level when C<pretty> is on. Must be 2 or
4 (yyjson constraint). Arbitrary indent strings planned for v0.02.

=item C<sort_keys>

Encode: emit object keys in sorted order. Off by default for speed;
on for diff-friendly output.

=item C<canonical>

Encode: shorthand for C<sort_keys =E<gt> 1> + minimal whitespace.

=item C<utf8>

Treat bytes as UTF-8. Default true.

=item C<relaxed>

Decode: tolerate C<//> and C</* */> comments and trailing commas.

=item C<allow_nonref>

Decode: accept top-level scalars (C<42>, C<"hi">, C<true>). Default
true.

=item C<allow_nan_inf>

Round-trip C<NaN>, C<Infinity>, C<-Infinity>. Non-standard JSON;
default false.

=item C<ordered>

Decode JSON objects as L<Tie::OrderedHash>-tied hashes so insertion
order is preserved on the Perl side. yyjson already preserves source
order on parse; the regular Perl HV randomises iteration since 5.18,
which is what this option works around.

    my $config = file_slurp("config.json", plugin => 'json', ordered => 1);
    # keys(%$config) returns in document order

    my $events = file_slurp("trace.jsonl", plugin => 'jsonl', ordered => 1);
    # each $events->[$i] preserves its original key order

Decode-only flag. The encoder detects the tied storage automatically
and emits keys in insertion order, so a parsed-then-re-encoded ordered
structure round-trips byte-for-byte without any extra flag.

Cost: ordered mode is slower than the default HV path because
maintaining insertion order requires bookkeeping the encoder/decoder
otherwise wouldn't do.  Indicative numbers on a 10k-record JSONL
fixture (10 fields each):

  decode default  vs  decode ordered:   ~4x slower
  encode default  vs  encode ordered:   ~1.25x slower (C ABI iterator)
  round-trip      vs  round-trip:        ~3x slower

The encode side is essentially free; the decode side pays the
AV/HV bookkeeping that maintains the insertion-ordered key list.
Use the option only when order actually matters; the default is
the fast path.

=item C<boolean_class>

Class to bless decoded JSON true/false into. Default
C<File::Raw::JSON::Boolean>. The encoder also recognises
C<JSON::PP::Boolean>, C<Types::Serialiser::Boolean>,
C<Cpanel::JSON::XS::Boolean>, C<JSON::XS::Boolean>, and the
C<boolean> module by name string.

=item C<max_depth>

Decode: croak on nesting deeper than this. Default 512.

=item C<eol>

JSONL only: line terminator on encode. 1-3 bytes, default C<\n>.

=back

=head1 VALUE MAPPING

  JSON                Perl                    Encoded back as
  ----                ----                    ---------------
  null                undef                   null
  true / false        blessed sentinel        matching literal
  integer (IV)        IV                      integer
  integer (UV)        UV                      integer
  float               NV                      float (shortest round-trip)



( run in 0.879 second using v1.01-cache-2.11-cpan-9581c071862 )