1 package TOML::Tiny::Writer;
5 no warnings qw(experimental);
9 use DateTime::Format::RFC3339;
11 use Scalar::Util qw(looks_like_number);
12 use TOML::Tiny::Grammar;
13 use TOML::Tiny::Util qw(is_strict_array);
24 # Generate simple key/value pairs for scalar data
25 for my $k (grep{ ref($data->{$_}) !~ /HASH|ARRAY/ } sort keys %$data) {
26 my $key = to_toml_key($k);
27 my $val = to_toml($data->{$k}, %param);
28 push @buff, "$key=$val";
31 # For values which are arrays, generate inline arrays for non-table
32 # values, array-of-tables for table values.
33 ARRAY: for my $k (grep{ ref $data->{$_} eq 'ARRAY' } sort keys %$data) {
35 if (!@{$data->{$k}}) {
36 my $key = to_toml_key($k);
37 push @buff, "$key=[]";
44 # Sort table and non-table values into separate containers
45 for my $v (@{$data->{$k}}) {
46 if (ref $v eq 'HASH') {
47 push @table_array, $v;
53 # Non-table values become an inline table
55 my $key = to_toml_key($k);
56 my $val = to_toml(\@inline, %param);
57 push @buff, "$key=$val";
60 # Table values become an array-of-tables
65 push @buff, '', '[[' . join('.', map{ to_toml_key($_) } @KEYS) . ']]';
66 push @buff, to_toml($_);
74 for my $k (grep{ ref $data->{$_} eq 'HASH' } sort keys %$data) {
75 if (!keys(%{$data->{$k}})) {
77 my $key = to_toml_key($k);
78 push @buff, "$key={}";
82 push @buff, '', '[' . join('.', map{ to_toml_key($_) } @KEYS) . ']';
83 push @buff, to_toml($data->{$k}, %param);
90 if (@$data && $param{strict_arrays}) {
91 my ($ok, $err) = is_strict_array($data);
92 die "toml: found heterogenous array, but strict_arrays is set ($err)\n" unless $ok;
95 push @buff, '[' . join(', ', map{ to_toml($_, %param) } @$data) . ']';
101 } elsif ($$_ eq '0') {
104 push @buff, to_toml($$_, %param);
108 when (/JSON::PP::Boolean/) {
109 return $$data ? 'true' : 'false';
113 return $data->stringify;
116 when ('Math::BigInt') {
120 when ('Math::BigFloat') {
126 when (looks_like_number($_)) {
135 return to_toml_string($data);
141 die 'unhandled: '.Dumper($_);
151 if ($str =~ /^[-_A-Za-z0-9]+$/) {
175 $arg =~ s/([\x22\x5c\n\r\t\f\b])/$escape->{$1}/g;
176 $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
178 return '"' . $arg . '"';