1 package TOML::Tiny::Writer;
5 no warnings qw(experimental);
9 use Scalar::Util qw(looks_like_number);
10 use TOML::Tiny::Grammar;
11 use TOML::Tiny::Util qw(is_strict_array);
22 # Generate simple key/value pairs for scalar data
23 for my $k (grep{ ref($data->{$_}) !~ /HASH|ARRAY/ } sort keys %$data) {
24 my $key = to_toml_key($k);
25 my $val = to_toml($data->{$k}, %param);
26 push @buff, "$key=$val";
29 # For values which are arrays, generate inline arrays for non-table
30 # values, array-of-tables for table values.
31 ARRAY: for my $k (grep{ ref $data->{$_} eq 'ARRAY' } sort keys %$data) {
33 if (!@{$data->{$k}}) {
34 my $key = to_toml_key($k);
35 push @buff, "$key=[]";
42 # Sort table and non-table values into separate containers
43 for my $v (@{$data->{$k}}) {
44 if (ref $v eq 'HASH') {
45 push @table_array, $v;
51 # Non-table values become an inline table
53 my $key = to_toml_key($k);
54 my $val = to_toml(\@inline, %param);
55 push @buff, "$key=$val";
58 # Table values become an array-of-tables
63 push @buff, '', '[[' . join('.', map{ to_toml_key($_) } @KEYS) . ']]';
64 push @buff, to_toml($_);
72 for my $k (grep{ ref $data->{$_} eq 'HASH' } sort keys %$data) {
73 if (!keys(%{$data->{$k}})) {
75 my $key = to_toml_key($k);
76 push @buff, "$key={}";
80 push @buff, '', '[' . join('.', map{ to_toml_key($_) } @KEYS) . ']';
81 push @buff, to_toml($data->{$k}, %param);
88 if (@$data && $param{strict_arrays}) {
89 my ($ok, $err) = is_strict_array($data);
90 die "toml: found heterogenous array, but strict_arrays is set ($err)\n" unless $ok;
93 push @buff, '[' . join(', ', map{ to_toml($_, %param) } @$data) . ']';
99 } elsif ($$_ eq '0') {
102 push @buff, to_toml($$_, %param);
106 when (/JSON::PP::Boolean/) {
107 return $$data ? 'true' : 'false';
111 return $data->stringify;
114 when ('Math::BigInt') {
118 when ('Math::BigFloat') {
124 when (looks_like_number($_)) {
133 return to_toml_string($data);
139 die 'unhandled: '.Dumper($_);
149 if ($str =~ /^[-_A-Za-z0-9]+$/) {
173 $arg =~ s/([\x22\x5c\n\r\t\f\b])/$escape->{$1}/g;
174 $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
176 return '"' . $arg . '"';