File Coverage

blib/lib/Data/Crumbr/Util.pm
Criterion Covered Total %
statement 42 46 91.3
branch 22 28 78.5
condition 7 12 58.3
subroutine 10 10 100.0
pod 3 3 100.0
total 84 99 84.8


line stmt bran cond sub pod time code
1             package Data::Crumbr::Util;
2             $Data::Crumbr::Util::VERSION = '0.1.0';
3             # ABSTRACT: utility functions for Data::Crumbr
4 6     6   178 use 5.018;
  6         17  
5 6     6   27 use strict;
  6         11  
  6         114  
6 6     6   25 use Carp;
  6         1084  
  6         374  
7 6     6   30 use Scalar::Util qw< reftype blessed >;
  6         10  
  6         4169  
8              
9             sub json_leaf_encoder {
10 10     10 1 115 require B;
11 10         28 return \&_json_leaf_encode;
12             }
13              
14             sub _json_leaf_encode {
15 101 50   101   568 return 'null' unless defined $_[0];
16              
17 101         130 my $reftype = ref($_[0]);
18 101 100       191 return '[]' if $reftype eq 'ARRAY';
19 96 100       185 return '{}' if $reftype eq 'HASH';
20 91 100       204 return (${$_[0]} ? 'true' : 'false')
  8 100       36  
21             if $reftype eq 'SCALAR';
22              
23 83 100       220 if (my $package = blessed($_[0])) {
24 2         6 my $reftype = reftype($_[0]);
25 2 100 33     19 return (${$_[0]} ? 'true' : 'false')
  2 50       45  
26             if ($reftype eq 'SCALAR') && ($package =~ /bool/mxsi);
27             }
28              
29 81 50       128 croak "unsupported ref type $reftype" if $reftype;
30              
31 81         91 my $number_flags = B::SVp_IOK() | B::SVp_NOK();
32 81 50 66     700 return $_[0]
      66        
33             if (B::svref_2object(\$_[0])->FLAGS() & $number_flags)
34             && 0 + $_[0] eq $_[0]
35             && $_[0] * 0 == 0;
36              
37 56         183 state $slash_escaped = {
38             0x22 => '"',
39             0x5C => "\\",
40             0x2F => '/',
41             0x08 => 'b',
42             0x0C => 'f',
43             0x0A => 'n',
44             0x0D => 'r',
45             0x09 => 't',
46             };
47             my $string = join '', map {
48 56         151 my $cp = ord($_);
  245         288  
49              
50 245 50 66     976 if (exists $slash_escaped->{$cp}) {
    100          
    50          
51 0         0 "\\$slash_escaped->{$cp}";
52             }
53             elsif ($cp >= 32 && $cp < 128) { # ASCII
54 233         473 $_;
55             }
56             elsif ($cp < 0x10000) { # controls & BML
57 12         52 sprintf "\\u%4.4X", $cp;
58             }
59             else { # beyond BML
60 0         0 my $hi = ($cp - 0x10000) / 0x400 + 0xD800;
61 0         0 my $lo = ($cp - 0x10000) % 0x400 + 0xDC00;
62 0         0 sprintf "\\u%4.4X\\u%4.4X", $hi, $lo;
63             }
64             } split //, $_[0];
65 56         230 return qq<"> . $string . qq<">;
66             } ## end sub _json_leaf_encode
67              
68             sub uri_encoder {
69 3     3 1 2374 require Encode;
70 3         29383 return \&_uri_encoder;
71             }
72              
73             sub _uri_encoder {
74 57     57   975 my $octets = Encode::encode('UTF-8', $_[0], Encode::FB_CROAK());
75             state $is_unreserved =
76 57         2086 {map { $_ => 1 } ('a' .. 'z', 'A' .. 'Z', '0' .. '9', qw< - _ . ~ >)};
  198         438  
77             return join '',
78 57 100       149 map { $is_unreserved->{$_} ? $_ : sprintf('%%%2.2X', ord $_); }
  204         608  
79             split //, $octets;
80             } ## end sub _uri_encoder
81              
82             sub id_encoder {
83 6     6 1 80 return sub { $_[0] };
  6     6   26  
84             }
85              
86             1;
87              
88             __END__
89              
90             =pod
91              
92             =encoding utf-8
93              
94             =head1 NAME
95              
96             Data::Crumbr::Util - utility functions for Data::Crumbr
97              
98             =head1 VERSION
99              
100             version 0.1.0
101              
102             =head1 DESCRIPTION
103              
104             Utility functions for Data::Crumbr.
105              
106             =head2 INTERFACE
107              
108             =over
109              
110             =item B<< id_encoder >>
111              
112             my $encoder = id_encoder();
113              
114             trivial encoding function that just returns its first argument (i.e. no
115             real encoding is performed).
116              
117             =item B<< json_leaf_encoder >>
118              
119             my $encoder = json_leaf_encoder();
120              
121             encoding function that returns a JSON-compliant value, only for leaf
122             values. It works on:
123              
124             =over
125              
126             =item *
127              
128             plain strings, returned after JSON encoding (e.g. tranformation of
129             newlines, etc.)
130              
131             =item *
132              
133             empty array references, in which case string C<[]> is returned
134              
135             =item *
136              
137             empty hash references, in which case string C<{}> is returned
138              
139             =item *
140              
141             null values, in which case string C<null> is returned
142              
143             =back
144              
145             =item B<< uri_encoder >>
146              
147             my $encoder = uri_encoder();
148              
149             encoding function that then encodes strings according to URI encoding
150             (i.e. percent-encoding).
151              
152             =back
153              
154             =head1 AUTHOR
155              
156             Flavio Poletti <polettix@cpan.org>
157              
158             =head1 COPYRIGHT AND LICENSE
159              
160             Copyright (C) 2015 by Flavio Poletti <polettix@cpan.org>
161              
162             This module is free software. You can redistribute it and/or
163             modify it under the terms of the Artistic License 2.0.
164              
165             This program is distributed in the hope that it will be useful,
166             but without any warranty; without even the implied warranty of
167             merchantability or fitness for a particular purpose.
168              
169             =cut