NAME
File::Serialize - DWIM file serialization/deserialization
VERSION
version 1.5.1
SYNOPSIS
use File::Serialize { pretty => 1 };
my $data = { foo => 'bar' };
serialize_file '/path/to/file.json' => $data;
...;
$data_copy = deserialize_file '/path/to/file.json';
DESCRIPTION
File::Serialize provides a common, simple interface to file serialization -- you provide the file path, the data to serialized, and the module takes care of the rest. Even the serialization format, unless specified explicitly as part of the options, is detected from the file extension.
IMPORT
File::Serialize imports the three functions serialize_file
, deserialize_file
and transerialize_file
into the current namespace. A default set of options can be set for both by passing a hashref as an argument to the 'use' statement.
use File::Serialize { pretty => 1 };
SUPPORTED SERIALIZERS
File::Serialize will pick the serializer to use based on the extension of the filename or the explicitly given format
. If several serializers are registered for the format, the available serializer with the highest precedence number will be used.
- YAML
- JSON
- TOML
- XML
- jsony
- Markdown
OPTIONS
File::Serialize recognizes a set of options that, if applicable, will be passed to the serializer.
- format => $serializer
-
Explicitly provides the serializer to use.
my $data = deserialize_file $path, { format => 'json' };
- add_extension => $boolean
-
If true, the canonical extension of the serializing format will be appended to the file. Requires the parameter
format
to be given as well.# will create 'foo.yml', 'foo.json' and 'foo.toml' serialize_file 'foo', $data, { format => $_, add_extension => 1 } for qw/ yaml json toml /;
- pretty => $boolean
-
The serialization will be formatted for human consumption.
- canonical => $boolean
-
Serializes the data using its canonical representation.
- utf8 => $boolean
-
If set to a
true
value, file will be read/written out using Path::Tiny'sslurp_utf8
andspew_utf8
method ( which sets abinmode
of:encoding(UTF-8)
). Otherwise, Path::Tiny'sslurp
andspew
methods are used.Defaults to being
true
because, after all, this is the twenty-first century. - allow_nonref => $boolean
-
If set to true, allow to serialize non-ref data.
Defaults to
true
.
FUNCTIONS
serialize_file $path, $data, $options
my $data = { foo => 'bar' };
serialize_file '/path/to/file.json' => $data;
If the $path
is '-
', the serialized data will be printed to STDOUT. If it a scalar ref, the serialized data will be assigned to that variable.
serialize_file \my $serialized => $data;
print $serialized;
deserialize_file $path, $options
my $data = deserialize_file '/path/to/file.json';
If the $path
is '-
', the serialized data will be read from STDIN. If it a scalar ref, the serialized data will be read from that variable.
my $json = '{"foo":1}';
my $data = deserialize_file \$json;
transerialize_file $input, @transformation_chain
transerialize_file
is a convenient wrapper that allows you to deserialize a file, apply any number of transformations to its content and re-serialize the result.
$input
can be a filename, a Path::Tiny object or the raw data structure to be worked on.
transerialize_file 'foo.json' => 'foo.yaml';
# equivalent to
serialize_file 'foo.yaml' => deserialize_file 'foo.json'
Each element of the @transformation_chain
can be
- $coderef
-
A transformation step. The current data is available both via
$_
and as the first argument to the sub, and the transformed data is going to be whatever the sub returns.my $data = { tshirt => { price => 18 }, hoodie => { price => 50 }, }; transerialize_file $data => sub { my %inventory = %$_; +{ %inventory{ grep { $inventory{$_}{price} <= 20 } keys %inventory } } } => 'inexpensive.json'; # chaining transforms transerialize_file $data => sub { my %inventory = %$_; +{ map { $_ => $inventory{$_}{price} } keys %inventory } } => sub { my %inventory = %$_; +{ %inventory{ grep { $inventory{$_} <= 20 } keys %inventory } } } => 'inexpensive.json'; # same as above, but with Perl 5.20 signatures and List::Util pair* # helpers transerialize_file $data => sub($inventory) { +{ pairmap { $a => $b->{price} } %$inventory } } => sub($inventory) { +{ pairgrep { $b <= 20 } %$inventory } } => 'inexpensive.json';
If you prefer to have your transform functions modify the structure in-place in
$_
and don't want to have to explicitly return it, you can set the global variable$File::Serialize::implicit_transform
totrue
. WARNING: this changes the behavior of ALL transforms. - \%destinations
-
A hashref of destination file with their options. The current state of the data will be serialized to those destination. If no options need to be passed, the value can be
undef
.transerialize_file $data => { 'beginning.json' => { pretty => 1 }, 'beginning.yml' => undef } => sub { ... } => { 'end.json' => { pretty => 1 }, 'end.yml' => undef };
- [ \@subchain1, \@subchain2, ... ]
-
Run the subchains given in
@branches
on the current data. Must be the last step of the chain.my @data = 1..10; transerialize_file \@data => { 'all.json' => undef } => [ [ sub { [ grep { $_ % 2 } @$_ ] } => 'odd.json' ], [ sub { [ grep { not $_ % 2 } @$_ ] } => 'even.json' ], ];
- ( $filename, $options )
-
Has to be the final step(s) of the chain. Just like the arguments of
serialize_file
.$filename
can be a string or a Path::Tiny object.$options
is optional. - \$result
-
Has to be the final step of the chain. Will assign the transformed data to
$result
instead of serializing to a file.
ADDING A SERIALIZER
Serializers are added by creating a File::Serialize::Serializer::* class that implement the File::Serialize::Serializer role. See the documentation for the role for more details.
AUTHOR
Yanick Champoux <yanick@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2021, 2019, 2017, 2016, 2015 by Yanick Champoux.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.