File Coverage

File:lib/String/CamelSnakeKebab.pm
Coverage:100.0%

linestmtbrancondsubtimecode
1package 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
15our $VERSION = "0.04";
16
17our %UPPER_CASE_HTTP_HEADERS = map { $_ => 1 }
18    qw/ CSP ATT WAP IP HTTP CPU DNT SSL UA TE WWW XSS MD5 /;
19
20sub 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
27our $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
38sub 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
55our %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
1361;