File: | lib/String/CamelSnakeKebab.pm |
Coverage: | 100.0% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package String::CamelSnakeKebab; | |||||
2 | 6 6 6 | 13 3 103 | use strict; | |||
3 | 6 6 6 | 11 5 116 | use warnings; | |||
4 | ||||||
5 | 6 | 24 | 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 | 6 6 | 991 8 | /]}; | |||
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 | 40 | 26 | my ($string) = @_; | |||
22 | 40 | 74 | return uc $string if $UPPER_CASE_HTTP_HEADERS{uc $string}; | |||
23 | 22 | 29 | 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 | 32 | 36 | my ($first_coderef, $rest_coderef, $separator, $string) = @_; | |||
40 | ||||||
41 | 32 | 253 | my ($first, @rest) = split $WORD_SEPARATOR_PATTERN, $string; | |||
42 | ||||||
43 | 32 | 43 | my @words = $first_coderef->($first); | |||
44 | 32 | 49 | push @words, $rest_coderef->($_) for @rest; | |||
45 | ||||||
46 | 32 | 127 | return join $separator, @words; | |||
47 | } | |||||
48 | ||||||
49 | # Need to do this because I can't make lc a code reference via \&CORE::lc | |||||
50 | # unless the user has perl v5.16 | |||||
51 | 18 | 25 | sub lc { lc shift } | |||
52 | 6 | 10 | sub uc { uc shift } | |||
53 | 14 | 24 | sub ucfirst { ucfirst shift } | |||
54 | ||||||
55 | our %CONVERSION_RULES = ( | |||||
56 | 'lower_camel_case' => [ \&lc, \&ucfirst, "" ], | |||||
57 | 'upper_camel_case' => [ \&ucfirst, \&ucfirst, "" ], | |||||
58 | 'lower_snake_case' => [ \&lc, \&lc, "_" ], | |||||
59 | 'upper_snake_case' => [ \&ucfirst, \&ucfirst, "_" ], | |||||
60 | 'constant_case' => [ \&uc, \&uc, "_" ], | |||||
61 | 'kebab_case' => [ \&lc, \&lc, "-" ], | |||||
62 | 'http_header_case' => [ \&http_header_caps, \&http_header_caps, "-" ], | |||||
63 | ); | |||||
64 | ||||||
65 | { | |||||
66 | # Foreach rule, dynamically install a sub in this package | |||||
67 | 6 6 6 | 17 4 351 | no strict 'refs'; | |||
68 | for my $rule ( keys %CONVERSION_RULES ) { | |||||
69 | my $args = $CONVERSION_RULES{$rule}; | |||||
70 | 32 | 51 | *{$rule} = sub { convert_case(@$args, @_) }; | |||
71 | } | |||||
72 | } | |||||
73 | ||||||
74 - 134 | =head1 NAME String::CamelSnakeKebab - word case conversion =head1 SYNPOSIS use String::CamelSnakeKebab qw/:all/; lower_camel_case 'flux-capacitor' # => 'fluxCapacitor upper_camel_case 'flux-capacitor' # => 'FluxCapacitor lower_snake_case 'ASnakeSlithersSlyly' # => 'a_snake_slithers_slyly' upper_snake_case 'ASnakeSlithersSlyly' # => 'A_Snake_Slithers_Slyly' constant_case "I am constant" # => "I_AM_CONSTANT" kebab_case 'Peppers_Meat_Pineapple' # => 'peppers-meat-pineapple' http_header_case "x-ssl-cipher" # => "X-SSL-Cipher" =head1 DESCRIPTION Camel-Snake-Kebab is a Clojure library for word case conversions. This library is ported from the original Clojure. =head1 METHODS =head2 lower_camel_case() =head2 upper_camel_case() =head2 lower_snake_case() =head2 upper_snake_case() =head2 constant_case() =head2 kebab_case() =head2 http_header_case() =head1 SEE ALSO The original Camel Snake Kebab Clojure library: L<https://github.com/qerub/camel-snake-kebab> =head1 AUTHOR Eric Johnson (kablamo) =cut | |||||
135 | ||||||
136 | 1; |