File Coverage

lib/Google/RestApi/Utils.pm
Criterion Covered Total %
statement 111 115 96.5
branch 38 42 90.4
condition 2 5 40.0
subroutine 26 27 96.3
pod 0 10 0.0
total 177 199 88.9


line stmt bran cond sub pod time code
1             package Google::RestApi::Utils;
2              
3 1     1   23678 use strict;
  1         3  
  1         30  
4 1     1   6 use warnings;
  1         2  
  1         44  
5              
6             our $VERSION = '1.0.3';
7              
8 1     1   6 use feature 'state';
  1         1  
  1         64  
9              
10 1     1   7 use autodie;
  1         2  
  1         8  
11 1     1   6957 use File::Spec::Functions qw( catfile );
  1         10  
  1         63  
12 1     1   8 use File::Basename qw( dirname );
  1         1  
  1         62  
13 1     1   1066 use Hash::Merge ();
  1         7693  
  1         28  
14 1     1   8 use Log::Log4perl qw( :easy );
  1         2  
  1         11  
15 1     1   921 use Scalar::Util qw( blessed );
  1         2  
  1         46  
16 1     1   6 use Type::Params qw( compile compile_named );
  1         2  
  1         9  
17 1     1   451 use Types::Standard qw( Str StrMatch HashRef Any slurpy );
  1         2  
  1         10  
18 1     1   2874 use YAML::Any qw( Dump LoadFile );
  1         3  
  1         7  
19              
20 1     1   785 use Google::RestApi::Types qw( ReadableFile );
  1         17  
  1         9  
21              
22 1     1   618 no autovivification;
  1         3  
  1         8  
23              
24 1     1   55 use Exporter qw(import);
  1         10  
  1         1317  
25             our @EXPORT_OK = qw(
26             named_extra
27             merge_config_file resolve_config_file_path
28             flatten_range
29             bool
30             dim_any dims_any dims_all
31             cl_black cl_white
32             strip
33             );
34             our %EXPORT_TAGS = (all => [ @EXPORT_OK ]);
35              
36             # used by validation with type::params.
37             # similar to allow_extra in params::validate, simply returns the
38             # extra key/value pairs we aren't interested in in the checked
39             # argument hash.
40             sub named_extra {
41 932     932 0 26438 state $check = compile_named(
42             _extra_ => HashRef,
43             validated => slurpy HashRef,
44             );
45 932         6747 my $p = $check->(@_);
46 931         24407 my $extra = delete $p->{_extra_};
47              
48 931         1529 my %p;
49 931 50       2833 %p = %{ $p->{validated} } if $p->{validated}; # these are validated by the caller.
  931         2713  
50 931         3688 @p{ keys %$extra } = values %$extra; # stuff back the ones the caller wasn't interested in.
51 931         3416 return \%p;
52             }
53              
54             sub merge_config_file {
55 301     301 0 4055 state $check = compile_named(
56             config_file => ReadableFile, { optional => 1 },
57             _extra_ => slurpy Any,
58             );
59 301         58009 my $passed_config = named_extra($check->(@_));
60              
61 299         1151 my $config_file = $passed_config->{config_file};
62 299 100       1029 return $passed_config if !$config_file;
63              
64 154         315 my $config_from_file = eval { LoadFile($config_file); };
  154         559  
65 154 50       590627 LOGDIE "Unable to load config file '$config_file': $@" if $@;
66              
67             # left_precedence, the passed config wins over anything in the file.
68             # can't merge coderefs, error comes from Storable buried deep in hash::merge.
69 154         748 my $merged_config = Hash::Merge::merge($passed_config, $config_from_file);
70 154         14116 TRACE("Config used:\n". Dump($merged_config));
71              
72 154         477612 return $merged_config;
73             }
74              
75             # a standard way to store file names in a config and resolve them
76             # to a full path. can be used in Auth configs, possibly others.
77             # see sub RestApi::auth for more.
78             sub resolve_config_file_path {
79 288     288 0 5068 state $check = compile(HashRef, Str);
80 288         3623 my ($config, $file_key) = $check->(@_);
81              
82 288 100       3988 my $config_file = $config->{$file_key} or return;
83 145 100       2025 return $config_file if -f $config_file;
84              
85 143         394 my $full_file_path;
86 143 100 66     1232 if ($file_key ne 'config_file' && $config->{config_file}) {
87 2         129 my $dir = dirname($config->{config_file});
88 2         19 my $path = catfile($dir, $config_file);
89 2 100       70 $full_file_path = $path if -f $path
90             }
91              
92 143 100       528 if (!$full_file_path) {
93 142         474 my $dir = $config->{config_dir};
94 142 100       422 if ($dir) {
95 139         1128 my $path = catfile($dir, $config_file);
96 139 50       2857 $full_file_path = $path if -f $path
97             }
98             }
99            
100 143 100       624 LOGDIE("Unable to resolve config file '$file_key => $config_file' to a full file path")
101             if !$full_file_path;
102              
103             # action at a distance, but is convenient to stuff the real file name in the config here.
104 140         450 $config->{$file_key} = $full_file_path;
105            
106 140         449 return $full_file_path;
107             }
108              
109             # these are just used for debug message just above
110             # to display the original range in a pretty format.
111             sub flatten_range {
112 861     861 0 85516 my $range = shift;
113 861 100       2555 $range = $range->range_to_hash() if blessed($range);
114 861 100       2001 return 'False' if !$range;
115 818 100       3544 return $range if !ref($range);
116 254 100       756 return _flatten_range_hash($range) if ref($range) eq 'HASH';
117 104 50       390 return _flatten_range_array($range) if ref($range) eq 'ARRAY';
118 0         0 LOGDIE("Unable to flatten: " . ref($range));
119             }
120              
121             sub _flatten_range_hash {
122 150     150   291 my $range = shift;
123 150         766 my @flat = map { "$_ => " . flatten_range($range->{$_}); } sort keys %$range;
  287         697  
124 150         450 my $flat = join(', ', @flat);
125 150         705 return "{ $flat }";
126             }
127              
128             sub _flatten_range_array {
129 104     104   196 my $range = shift;
130 104         219 my @flat = map { flatten_range($_); } @$range;
  187         356  
131 104         312 my $flat = join(', ', @flat);
132 104         568 return "[ $flat ]";
133             }
134              
135             # changes perl boolean to json boolean.
136             sub bool {
137 25     25 0 5186 my $bool = shift;
138 25 100       114 return 'true' if !defined $bool; # bold() should turn on bold.
139 12 100       98 return 'false' if $bool =~ qr/^false$/i;
140 10 100       67 return $bool ? 'true' : 'false'; # converts bold(0) to 'false'.
141             }
142              
143             sub dims_any {
144 223     223 0 490 state $check = compile(StrMatch[qr/^(col|row)/i]);
145 223         4163 my ($dims) = $check->(@_);
146 222 100       4012 return $dims =~ /^col/i ? "COLUMNS" : "ROWS";
147             }
148              
149             sub dims_all {
150 3     3 0 7 my $dims = eval { dims_any(@_); };
  3         8  
151 3 100       196 return $dims if $dims;
152 1         9 state $check = compile(StrMatch[qr/^all/i]);
153 1         3398 ($dims) = $check->(@_);
154 1         19 return "ALL";
155             }
156              
157 5     5 0 34 sub cl_black { { red => 0, blue => 0, green => 0, alpha => 1 }; }
158 5     5 0 32 sub cl_white { { red => 1, blue => 1, green => 1, alpha => 1 }; }
159              
160             sub strip {
161 0   0 0 0   my $p = shift // '';
162 0           $p =~ s/^\s+|\s+$//g;
163 0           return $p;
164             }
165              
166             1;