File Coverage

blib/lib/Courriel/Role/HeaderWithAttributes.pm
Criterion Covered Total %
statement 52 52 100.0
branch 7 8 87.5
condition n/a
subroutine 16 16 100.0
pod 0 2 0.0
total 75 78 96.1


line stmt bran cond sub pod time code
1             package Courriel::Role::HeaderWithAttributes;
2              
3 9     9   4567 use strict;
  9         11  
  9         230  
4 9     9   32 use warnings;
  9         11  
  9         198  
5 9     9   32 use namespace::autoclean;
  9         11  
  9         52  
6              
7             our $VERSION = '0.42';
8              
9 9     9   551 use Courriel::HeaderAttribute;
  9         11  
  9         197  
10 9     9   31 use Courriel::Helpers qw( parse_header_with_attributes );
  9         9  
  9         471  
11 9     9   32 use Courriel::Types qw( HashRef NonEmptyStr );
  9         10  
  9         54  
12 9     9   44666 use MooseX::Params::Validate qw( pos_validated_list validated_list );
  9         12  
  9         65  
13 9     9   1792 use Scalar::Util qw( blessed reftype );
  9         11  
  9         438  
14              
15 9     9   4184 use MooseX::Role::Parameterized;
  9         375491  
  9         34  
16              
17             parameter main_value_key => (
18             isa => NonEmptyStr,
19             required => 1,
20             );
21              
22             parameter main_value_method => (
23             isa => NonEmptyStr,
24             );
25              
26             has _attributes => (
27             traits => ['Hash'],
28             is => 'ro',
29             isa => HashRef ['Courriel::HeaderAttribute'],
30             init_arg => 'attributes',
31             default => sub { {} },
32             handles => {
33             attributes => 'elements',
34             _attribute => 'get',
35             _set_attribute => 'set',
36             _has_attributes => 'count',
37             },
38             );
39              
40             around BUILDARGS => sub {
41             my $orig = shift;
42             my $class = shift;
43              
44             my $p = $class->$orig(@_);
45              
46             return $p
47             unless $p->{attributes} && reftype( $p->{attributes} ) eq 'HASH';
48              
49             for my $name ( keys %{ $p->{attributes} } ) {
50             my $lc_name = lc $name;
51             $p->{attributes}{$lc_name} = delete $p->{attributes}{$name};
52              
53             next if blessed( $p->{attributes}{$lc_name} );
54              
55             $p->{attributes}{$lc_name} = Courriel::HeaderAttribute->new(
56             name => $name,
57             value => $p->{attributes}{$name},
58             );
59             }
60              
61             return $p;
62             };
63              
64             sub attribute {
65 80     80 0 90 my $self = shift;
66 80         83 my $key = shift;
67              
68 80 50       147 return unless defined $key;
69              
70 80         2621 return $self->_attribute( lc $key );
71             }
72              
73             {
74             my @spec = ( { isa => NonEmptyStr } );
75              
76             sub attribute_value {
77 40     40 0 51 my $self = shift;
78 40         124 my ($name) = pos_validated_list( \@_, @spec );
79              
80 40         21674 my $attr = $self->attribute($name);
81              
82 40 100       972 return $attr ? $attr->value : undef;
83             }
84             }
85              
86             sub _attributes_as_string {
87 1     1   1 my $self = shift;
88              
89 1         26 my $attr = $self->_attributes;
90              
91 1         2 return join '; ', map { $attr->{$_}->as_string } sort keys %{$attr};
  1         5  
  1         3  
92             }
93              
94             {
95             my @spec = (
96             name => { isa => NonEmptyStr, optional => 1 },
97             value => { isa => NonEmptyStr },
98             );
99              
100             role {
101             my $p = shift;
102              
103             my $main_value_key = $p->main_value_key;
104              
105             method new_from_value => sub {
106 209     209   268 my $class = shift;
        206      
107 209         683 my ( $name, $value ) = validated_list( \@_, @spec );
108              
109 209         211271 my ( $main_value, $attributes )
110             = parse_header_with_attributes($value);
111              
112 209         862 my %p = (
113             value => $value,
114             $main_value_key => $main_value,
115             attributes => $attributes,
116             );
117              
118 209 100       537 $p{name} = $name if defined $name;
119              
120 209         6104 return $class->new(%p);
121             };
122              
123             my $main_value_meth = $p->main_value_method || $p->main_value_key;
124              
125             method as_header_value => sub {
126 2     2   2 my $self = shift;
        2      
127              
128 2         59 my $string = $self->$main_value_meth;
129              
130 2 100       67 if ( $self->_has_attributes ) {
131 1         2 $string .= '; ';
132 1         4 $string .= $self->_attributes_as_string;
133             }
134              
135 2         53 return $string;
136             };
137             }
138             }
139              
140             1;