File Coverage

blib/lib/IRC/Toolkit/Case.pm
Criterion Covered Total %
statement 45 51 88.2
branch 10 12 83.3
condition 9 10 90.0
subroutine 9 9 100.0
pod 4 4 100.0
total 77 86 89.5


line stmt bran cond sub pod time code
1             package IRC::Toolkit::Case;
2             $IRC::Toolkit::Case::VERSION = '0.092002';
3 5     5   13844 use strictures 2;
  5         1211  
  5         142  
4 5     5   711 no warnings 'once';
  5         7  
  5         115  
5 5     5   17 use Carp 'carp';
  5         6  
  5         200  
6              
7 5     5   1153 use parent 'Exporter::Tiny';
  5         648  
  5         19  
8             our @EXPORT = qw/
9             lc_irc
10             uc_irc
11             eq_irc
12              
13             rfc1459
14              
15             irc_str
16             /;
17              
18              
19 5     5   9810 use Sub::Infix;
  5         8445  
  5         1915  
20             *rfc1459 = &infix(sub { eq_irc( $_[0], $_[1], 'rfc1459' ) });
21              
22              
23             ## The prototypes are unfortunate, but I pulled these out of an old
24             ## and very large bot project ... and was too scared to remove them.
25              
26             sub lc_irc ($;$) {
27 6     6 1 11 my ($string, $casemap) = @_;
28 6   100     28 $casemap = lc( $casemap || 'rfc1459' );
29              
30             CASE: {
31 6 100       6 if ($casemap eq 'rfc1459') {
  6         15  
32 1         1 $string =~ tr/A-Z[]\\~/a-z{}|^/;
33             last CASE
34 1         2 }
35              
36 5 100 66     22 if ($casemap eq 'strict-rfc1459' || $casemap eq 'strict') {
37 1         2 $string =~ tr/A-Z[]\\/a-z{}|/;
38             last CASE
39 1         1 }
40              
41 4 50       6 if ($casemap eq 'ascii') {
42 4         6 $string =~ tr/A-Z/a-z/;
43             last CASE
44 4         7 }
45              
46 0         0 carp "Unknown CASEMAP $casemap, defaulted to rfc1459";
47 0         0 $casemap = 'rfc1459';
48             redo CASE
49 0         0 }
50              
51             $string
52 6         19 }
53              
54             sub uc_irc ($;$) {
55 36     36 1 33 my ($string, $casemap) = @_;
56 36   100     68 $casemap = lc( $casemap || 'rfc1459' );
57              
58             CASE: {
59 36 100       25 if ($casemap eq 'rfc1459') {
  36         53  
60 15         16 $string =~ tr/a-z{}|^/A-Z[]\\~/;
61             last CASE
62 15         14 }
63              
64 21 100 100     88 if ($casemap eq 'strict-rfc1459' || $casemap eq 'strict') {
65 5         6 $string =~ tr/a-z{}|/A-Z[]\\/;
66             last CASE
67 5         5 }
68              
69 16 50       20 if ($casemap eq 'ascii') {
70 16         17 $string =~ tr/a-z/A-Z/;
71             last CASE
72 16         27 }
73              
74 0         0 carp "Unknown CASEMAP $casemap, defaulted to rfc1459";
75 0         0 $casemap = 'rfc1459';
76             redo CASE
77 0         0 }
78              
79             $string
80 36         153 }
81              
82             sub eq_irc ($$;$) {
83 10     10 1 11 my ($first, $second, $casemap) = @_;
84 10         13 uc_irc($first, $casemap) eq uc_irc($second, $casemap);
85             }
86              
87             sub irc_str {
88 3     3 1 442 require IRC::Toolkit::Case::MappedString;
89 3         9 IRC::Toolkit::Case::MappedString->new(@_)
90             }
91              
92             print
93             qq[ Also, every now and then I talk about a game I've enjoyed],
94             qq[ and rofer doesn't have time for it, Capn v1.02 doesn't understand],
95             qq[ the human concept of fun/entertainment, c[_] only plays retro-games],
96             qq[ made in his native homeland of Moria and avenj would rather shoot],
97             qq[ rifles while vaping\n]
98             unless caller; 1;
99              
100             =pod
101              
102             =head1 NAME
103              
104             IRC::Toolkit::Case - IRC case-folding utilities
105              
106             =head1 SYNOPSIS
107              
108             use IRC::Toolkit::Case;
109              
110             my $lower = lc_irc( $string, 'rfc1459' );
111              
112             my $upper = uc_irc( $string, 'ascii' );
113              
114             if (eq_irc($first, $second, 'strict-rfc1459')) {
115             ...
116             }
117              
118             # Or use the '|rfc1459|' operator if using RFC1459 rules:
119             if ($first |rfc1459| $second) {
120              
121             }
122              
123             =head1 DESCRIPTION
124              
125             IRC case-folding utilities.
126              
127             IRC daemons typically announce their casemap in B (via the
128             B directive). This should be one of C,
129             C, or C:
130              
131             'ascii' a-z --> A-Z
132             'rfc1459' a-z{}|^ --> A-Z[]\~ (default)
133             'strict-rfc1459' a-z{}| --> A-Z[]\
134              
135             If told to convert/compare an unknown casemap, these functions will warn and
136             default to RFC1459 rules.
137              
138             If you're building a class that tracks an IRC casemapping and manipulates
139             strings accordingly, you may also want to see L.
140              
141             =head2 rfc1459 operator
142              
143             The infix operator C<|rfc1459|> is provided as a convenience for string
144             comparison (using RFC1459 rules):
145              
146             if ($first |rfc1459| $second) { ... }
147             # Same as:
148             if (eq_irc($first, $second)) { ... }
149              
150             =head2 lc_irc
151              
152             Takes a string and an optional casemap.
153              
154             Returns the lowercased string.
155              
156             =head2 uc_irc
157              
158             Takes a string and an optional casemap.
159              
160             Returns the uppercased string.
161              
162             =head2 eq_irc
163              
164             Takes a pair of strings and an optional casemap.
165              
166             Returns boolean true if the strings are equal
167             (per the rules specified by the given casemap).
168              
169             =head2 irc_str
170              
171             my $str = irc_str( strict => 'Nick^[Abc]' );
172             if ( $str eq 'nick^{abc}' ) {
173             # true
174             }
175              
176             Takes a casemap and string; if only one argument is provided, it is taken to
177             be the string and a C casemap is assumed.
178              
179             Produces overloaded objects (see L) that can
180             be stringified or compared; string comparison operators use the specified
181             casemap.
182              
183             =head1 AUTHOR
184              
185             Jon Portnoy
186              
187             Inspired by L, copyright Chris Williams, Hinrik et al
188              
189             Licensed under the same terms as Perl.
190              
191             =cut