File Coverage

blib/lib/String/CamelSnakeKebab.pm
Criterion Covered Total %
statement 25 25 100.0
branch 4 4 100.0
condition n/a
subroutine 10 10 100.0
pod 0 5 0.0
total 39 44 88.6


line stmt bran cond sub pod time code
1             package String::CamelSnakeKebab;
2 3     3   327188 use strict;
  3         7  
  3         77  
3 3     3   14 use warnings;
  3         8  
  3         130  
4              
5 3         40 use Sub::Exporter -setup => { exports => [qw/
6             lower_camel_case
7             upper_camel_case
8             lower_snake_case
9             upper_snake_case
10             constant_case
11             kebab_case
12             http_header_case
13 3     3   2777 /]};
  3         50627  
14              
15             our $VERSION = "0.04";
16              
17             our %UPPER_CASE_HTTP_HEADERS = map { $_ => 1 }
18             qw/ CSP ATT WAP IP HTTP CPU DNT SSL UA TE WWW XSS MD5 /;
19              
20             sub http_header_caps {
21 20     20 0 38 my ($string) = @_;
22 20 100       103 return uc $string if $UPPER_CASE_HTTP_HEADERS{uc $string};
23 11         35 return ucfirst $string;
24             }
25              
26             # A pattern that matches all known word separators
27             our $WORD_SEPARATOR_PATTERN = qr/
28             (?:
29             \s+ |
30             _ |
31             - |
32             (?<=[A-Z])(?=[A-Z][a-z]) |
33             (?<=[^A-Z_-])(?=[A-Z]) |
34             (?<=[A-Za-z0-9])(?=[^A-Za-z0-9])
35             )
36             /x;
37              
38             sub convert_case {
39 17     17 0 41 my ($first_coderef, $rest_coderef, $separator, $string) = @_;
40              
41 17 100       64 return '' if $string eq '';
42              
43 16         243 my ($first, @rest) = split $WORD_SEPARATOR_PATTERN, $string;
44              
45 16         40 my @words = $first_coderef->($first);
46 16         48 push @words, $rest_coderef->($_) for @rest;
47              
48 16         127 return join $separator, @words;
49             }
50              
51             # Need to do this because I can't make lc a code reference via \&CORE::lc
52             # unless the user has perl v5.16
53 9     9 0 25 sub lc { lc shift }
54 3     3 0 8 sub uc { uc shift }
55 7     7 0 40 sub ucfirst { ucfirst shift }
56              
57             our %CONVERSION_RULES = (
58             'lower_camel_case' => [ \&lc, \&ucfirst, "" ],
59             'upper_camel_case' => [ \&ucfirst, \&ucfirst, "" ],
60             'lower_snake_case' => [ \&lc, \&lc, "_" ],
61             'upper_snake_case' => [ \&ucfirst, \&ucfirst, "_" ],
62             'constant_case' => [ \&uc, \&uc, "_" ],
63             'kebab_case' => [ \&lc, \&lc, "-" ],
64             'http_header_case' => [ \&http_header_caps, \&http_header_caps, "-" ],
65             );
66              
67             {
68             # Foreach rule, dynamically install a sub in this package
69 3     3   3376 no strict 'refs';
  3         13  
  3         483  
70             for my $rule ( keys %CONVERSION_RULES ) {
71             my $args = $CONVERSION_RULES{$rule};
72 17     17   33243 *{$rule} = sub { convert_case(@$args, @_) };
73             }
74             }
75              
76             =head1 NAME
77              
78             String::CamelSnakeKebab - word case conversion
79              
80             =head1 SYNPOSIS
81              
82             use String::CamelSnakeKebab qw/:all/;
83              
84             lower_camel_case 'flux-capacitor'
85             # => 'fluxCapacitor
86              
87             upper_camel_case 'flux-capacitor'
88             # => 'FluxCapacitor
89              
90             lower_snake_case 'ASnakeSlithersSlyly'
91             # => 'a_snake_slithers_slyly'
92              
93             upper_snake_case 'ASnakeSlithersSlyly'
94             # => 'A_Snake_Slithers_Slyly'
95              
96             constant_case "I am constant"
97             # => "I_AM_CONSTANT"
98              
99             kebab_case 'Peppers_Meat_Pineapple'
100             # => 'peppers-meat-pineapple'
101              
102             http_header_case "x-ssl-cipher"
103             # => "X-SSL-Cipher"
104              
105              
106             =head1 DESCRIPTION
107              
108             Camel-Snake-Kebab is a Clojure library for word case conversions. This library
109             is ported from the original Clojure.
110              
111             =head1 METHODS
112              
113             =head2 lower_camel_case()
114              
115             =head2 upper_camel_case()
116              
117             =head2 lower_snake_case()
118              
119             =head2 upper_snake_case()
120              
121             =head2 constant_case()
122              
123             =head2 kebab_case()
124              
125             =head2 http_header_case()
126              
127              
128             =head1 SEE ALSO
129              
130             The original Camel Snake Kebab Clojure library: L
131              
132             =head1 AUTHOR
133              
134             Eric Johnson (kablamo)
135              
136             =cut
137              
138             1;