File Coverage

blib/lib/Mail/Qmail/Filter/Util.pm
Criterion Covered Total %
statement 26 26 100.0
branch 12 14 85.7
condition 3 5 60.0
subroutine 6 6 100.0
pod 3 3 100.0
total 50 54 92.5


line stmt bran cond sub pod time code
1 2     2   83263 use 5.014;
  2         15  
2 2     2   11 use warnings;
  2         3  
  2         82  
3              
4              
5             our $VERSION = '1.1';
6              
7             use base 'Exporter';
8 2     2   9  
  2         4  
  2         626  
9             our @EXPORT_OK = qw(addresses_to_hash match_address split_address);
10              
11             my $addrs = shift;
12             $addrs = [$addrs] unless ref $addrs;
13 2     2 1 87 my %struct;
14 2 100       7 for ( ref $addrs ? @$addrs : $addrs ) {
15 2         3 my ( $localpart, $domain ) = split_address($_);
16 2 50       8 unless ( length $localpart ) {
17 4         5 $struct{$domain} = ''; # match for whole domain
18 4 100       8 }
19 1         4 else {
20             my $slot = $struct{$domain} //= {};
21             $slot->{$localpart} = '' if ref $slot;
22 3   50     14 }
23 3 50       10 }
24             \%struct;
25             }
26 2         10  
27             my ( $struct, $addr ) = @_;
28             my ( $localpart, $domain ) = split_address($addr);
29             defined( my $slot = $struct->{$domain} ) or return;
30 4     4 1 9 !ref $slot || !length $localpart || defined $slot->{$localpart};
31 4         7 }
32 4 100       14  
33 3 100 66     20 my $lc_addr = lc shift;
34             if ( $lc_addr =~ /\@/ ) {
35             split /\@/, $lc_addr, 2;
36             }
37 8     8 1 16 else {
38 8 100       23 undef, $lc_addr;
39 7         21 }
40             }
41              
42 1         3 1;
43              
44             =head1 NAME
45              
46             Mail::Qmail::Filter::Util -
47             utility functions for Mail::Qmail::Filter modules
48              
49             =head1 SYNOPSIS
50              
51             use Mail::Qmail::Filter::Util qw(addresses_to_hash match_address);
52             use Mo qw(coerce default);
53              
54             has addresses => coerce => \&addresses_to_hash;
55              
56             sub filter {
57             ...
58             if ( match_address( $self->addresses, $address ) ) {
59             ...
60             }
61             ...
62             }
63              
64             =head1 DESCRIPTION
65              
66             This module is not a filter itself, but provides utility functions
67             for other filters, possibly your own.
68              
69             =head1 EXPORTABLE FUNCTIONS
70              
71             =head2 addresses_to_hash
72              
73             Takes a single e-mail address or domain name as string or an array of such
74             strings and turns it into a data structure you can later pass to
75             L</match_address>.
76             Returns a reference to this data structure.
77              
78             =head2 match_address
79              
80             Expects two arguments:
81              
82             =over 4
83              
84             =item 1.
85              
86             the reference returned by L</addresses_to_hash>
87              
88             =item 2.
89              
90             an e-mail address (as a string)
91              
92             =back
93              
94             Will return a true value if the e-mail address given is one of the
95             addresses you had given to L</addresses_to_hash> or if its domain name
96             is one of the domain names you had given to L</addresses_to_hash>.
97              
98             Everything will be compared case-insensitively, because domain names are
99             not case-sensitive anyway, and presumably no-one uses case-sensitive
100             localparts.
101              
102             =head2 split_address
103              
104             Expects a domain name or an e-mail address as its only argument.
105              
106             Returns two values:
107              
108             =over 4
109              
110             =item 1.
111              
112             the local-part of the e-mail address, or L<undef|perlfunc/undef> for
113             domains
114              
115             =item 2.
116              
117             the domain part, converted to lowercase
118              
119             =back
120              
121             =head1 SEE ALSO
122              
123             L<Mail::Qmail::Filter>
124              
125             =head1 LICENSE AND COPYRIGHT
126              
127             Copyright 2019 Martin Sluka.
128              
129             This module is free software; you can redistribute it and/or modify it
130             under the terms of the the Artistic License (2.0). You may obtain a
131             copy of the full license at:
132              
133             L<http://www.perlfoundation.org/artistic_license_2_0>
134              
135             Any use, modification, and distribution of the Standard or Modified
136             Versions is governed by this Artistic License. By using, modifying or
137             distributing the Package, you accept this license. Do not use, modify,
138             or distribute the Package, if you do not accept this license.
139              
140             If your Modified Version has been derived from a Modified Version made
141             by someone other than you, you are nevertheless required to ensure that
142             your Modified Version complies with the requirements of this license.
143              
144             This license does not grant you the right to use any trademark, service
145             mark, tradename, or logo of the Copyright Holder.
146              
147             This license includes the non-exclusive, worldwide, free-of-charge
148             patent license to make, have made, use, offer to sell, sell, import and
149             otherwise transfer the Package with respect to any patent claims
150             licensable by the Copyright Holder that are necessarily infringed by the
151             Package. If you institute patent litigation (including a cross-claim or
152             counterclaim) against any party alleging that the Package constitutes
153             direct or contributory patent infringement, then this Artistic License
154             to you shall terminate on the date that such litigation is filed.
155              
156             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
157             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
158             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
159             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
160             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
161             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
162             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
163             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
164              
165             =cut