File Coverage

blib/lib/Text/vCard/Precisely/V4/Node.pm
Criterion Covered Total %
statement 33 35 94.2
branch 12 20 60.0
condition 5 9 55.5
subroutine 7 7 100.0
pod 0 1 0.0
total 57 72 79.1


line stmt bran cond sub pod time code
1             package Text::vCard::Precisely::V4::Node;
2              
3 14     14   105 use Carp;
  14         36  
  14         883  
4 14     14   90 use Encode qw(decode_utf8);
  14         30  
  14         831  
5              
6 14     14   90 use Moose;
  14         31  
  14         135  
7 14     14   98115 use Moose::Util::TypeConstraints;
  14         38  
  14         134  
8              
9             extends 'Text::vCard::Precisely::V3::Node';
10              
11             enum 'Name' => [
12             qw( FN
13             ADR TEL EMAIL PHOTO LOGO URL
14             TZ GEO NICKNAME IMPP LANG XML KEY NOTE
15             ORG TITLE ROLE CATEGORIES
16             SOURCE SOUND FBURL CALADRURI CALURI
17             RELATED X-SOCIALPROFILE
18             )
19             ];
20             has name => ( is => 'rw', required => 1, isa => 'Name' );
21              
22             subtype 'SortAs' => as 'Str' =>
23 14     14   31266 where { use utf8; decode_utf8($_) =~ m|^[\p{ascii}\w\s]+$|s } # Does everything pass?
  14         36  
  14         123  
24             => message {"The SORT-AS you provided, $_, was not supported"};
25             has sort_as => ( is => 'rw', isa => 'Maybe[SortAs]' );
26              
27             subtype 'PIDNum' => as 'Num' => where {m/^\d(?:.\d)?$/s}
28             => message {"The PID you provided, $_, was not supported"};
29             has pid => ( is => 'rw', isa => subtype 'PID' => as 'ArrayRef[PIDNum]' );
30              
31             subtype 'ALTID' => as 'Int' => where { $_ > 0 and $_ <= 100 }
32             => message {"The number you provided, $_, was not supported in 'ALTID'"};
33             has altID => ( is => 'rw', isa => 'ALTID' );
34              
35             subtype 'MediaType' => as 'Str' =>
36             where {m{^(?:application|audio|example|image|message|model|multipart|text|video)/[\w+\-\.]+$}is}
37             => message {"The MediaType you provided, $_, was not supported"};
38             has media_type => ( is => 'rw', isa => 'MediaType' );
39              
40             sub as_string {
41 73     73 0 152 my ($self) = @_;
42 73         157 my @lines;
43 73   33     2244 push @lines, $self->name() || croak "Empty name";
44 73 50       2170 push @lines, 'ALTID=' . $self->altID() if $self->altID();
45 73 50       2112 push @lines, 'PID=' . join ',', @{ $self->pid() } if $self->pid();
  0         0  
46 73 100 66     2145 push @lines, 'TYPE="' . join( ',', map { uc $_ } @{ $self->types() } ) . '"'
  3         17  
  3         92  
47             if ref $self->types() eq 'ARRAY' and $self->types()->[0];
48 73 50       2207 push @lines, 'PREF=' . $self->pref() if $self->pref();
49 73 50       2259 push @lines, 'MEDIATYPE=' . $self->media_type() if $self->media_type();
50 73 50       2220 push @lines, 'LANGUAGE=' . $self->language() if $self->language();
51 73 100 66     2177 push @lines, 'SORT-AS="' . $self->sort_as() . '"'
52             if $self->sort_as()
53             and $self->name() =~ /^(?:FN|ORG)$/;
54              
55 73         2229 my $content = $self->content();
56             my $string
57             = join( ';', @lines ) . ':'
58             . (
59             ref($content) eq 'Array'
60 73 0       2269 ? map { $self->name() eq 'GEO' ? $content : $self->_escape($_) } @$content
  0 100       0  
    50          
61             : $self->name() eq 'GEO' ? $content
62             : $self->_escape($content)
63             );
64 73         265 return $self->fold($string);
65             }
66              
67             __PACKAGE__->meta->make_immutable;
68 14     14   15548 no Moose;
  14         39  
  14         84  
69              
70             1;