line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::vCard::Precisely::V3::Node; |
2
|
|
|
|
|
|
|
|
3
|
28
|
|
|
28
|
|
7552
|
use Carp; |
|
28
|
|
|
|
|
77
|
|
|
28
|
|
|
|
|
1865
|
|
4
|
28
|
|
|
28
|
|
233
|
use Encode qw( decode_utf8 encode_utf8 is_utf8); |
|
28
|
|
|
|
|
76
|
|
|
28
|
|
|
|
|
1324
|
|
5
|
|
|
|
|
|
|
|
6
|
28
|
|
|
28
|
|
366
|
use 5.12.5; |
|
28
|
|
|
|
|
116
|
|
7
|
28
|
|
|
28
|
|
6729
|
use Text::LineFold; |
|
28
|
|
|
|
|
239828
|
|
|
28
|
|
|
|
|
1594
|
|
8
|
|
|
|
|
|
|
|
9
|
28
|
|
|
28
|
|
216
|
use overload( '""' => \&as_string ); |
|
28
|
|
|
|
|
68
|
|
|
28
|
|
|
|
|
241
|
|
10
|
|
|
|
|
|
|
|
11
|
28
|
|
|
28
|
|
1754
|
use Moose; |
|
28
|
|
|
|
|
69
|
|
|
28
|
|
|
|
|
347
|
|
12
|
28
|
|
|
28
|
|
184630
|
use Moose::Util::TypeConstraints; |
|
28
|
|
|
|
|
64
|
|
|
28
|
|
|
|
|
246
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
enum 'Name' => [ |
15
|
|
|
|
|
|
|
qw( FN N SORT_STRING ORG TITLE ROLE |
16
|
|
|
|
|
|
|
ADR LABEL TEL EMAIL PHOTO LOGO URL SOURCE SOUND |
17
|
|
|
|
|
|
|
TZ GEO KEY NOTE |
18
|
|
|
|
|
|
|
X-SOCIALPROFILE |
19
|
|
|
|
|
|
|
) |
20
|
|
|
|
|
|
|
]; |
21
|
|
|
|
|
|
|
has name => ( is => 'rw', required => 1, isa => 'Name' ); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
subtype 'Content' => as 'Str'; # => where { |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# !is_utf8($_) && decode_utf8($_) =~ m|^[\w\p{ascii}\s]+$|s # It seems these lines |
26
|
|
|
|
|
|
|
#} # Does it need to be more strictly? # do NOT work |
27
|
|
|
|
|
|
|
#=> message {"The value you provided, $_, was not supported"}; # like what I've thought |
28
|
|
|
|
|
|
|
has content => ( is => 'rw', required => 1, isa => 'Content' ); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
subtype 'Preffered' => as 'Int' => where { $_ > 0 and $_ <= 100 } |
31
|
|
|
|
|
|
|
=> message {"The number you provided, $_, was not supported in 'Preffered'"}; |
32
|
|
|
|
|
|
|
has pref => ( is => 'rw', isa => 'Preffered' ); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
subtype 'Type' => as 'Str' => where { |
35
|
|
|
|
|
|
|
m/^(?:work|home|PGP)$/is or #common |
36
|
|
|
|
|
|
|
m|^(?:[a-zA-z0-9\-]+/X-[a-zA-z0-9\-]+)$|s; # does everything pass? |
37
|
|
|
|
|
|
|
} => message {"The text you provided, $_, was not supported in 'Type'"}; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
subtype 'Types' => as 'ArrayRef[Type]'; |
40
|
|
|
|
|
|
|
coerce 'Types' => from 'Str' => via { [$_] }; |
41
|
|
|
|
|
|
|
has types => ( is => 'rw', isa => 'Types', default => sub { [] }, coerce => 1 ); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
subtype 'Language' => as 'Str' => |
44
|
|
|
|
|
|
|
where {m|^[a-z]{2}(?:-[a-z]{2})?$|s} # does it need something strictly? |
45
|
|
|
|
|
|
|
=> message {"The Language you provided, $_, was not supported"}; |
46
|
|
|
|
|
|
|
has language => ( is => 'rw', isa => 'Language' ); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub charset { # DEPRECATED in vCard 3.0 |
49
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
50
|
0
|
|
|
|
|
0
|
croak "'CHARSET' param is DEPRECATED! vCard3.0 will accept just ONLY UTF-8"; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
54
|
28
|
|
|
28
|
|
70232
|
no Moose; |
|
28
|
|
|
|
|
235
|
|
|
28
|
|
|
|
|
206
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub as_string { |
57
|
129
|
|
|
129
|
0
|
300
|
my ($self) = @_; |
58
|
129
|
|
|
|
|
244
|
my @lines; |
59
|
129
|
|
|
|
|
3875
|
my $node = $self->name(); |
60
|
129
|
|
|
|
|
255
|
$node =~ tr/_/-/; |
61
|
|
|
|
|
|
|
|
62
|
129
|
|
33
|
|
|
435
|
push @lines, uc($node) || croak "Empty name"; |
63
|
129
|
100
|
66
|
|
|
3685
|
push @lines, 'TYPE=' . join( ',', map { uc $_ } @{ $self->types() } ) |
|
6
|
|
|
|
|
27
|
|
|
6
|
|
|
|
|
175
|
|
64
|
|
|
|
|
|
|
if ref $self->types() eq 'ARRAY' and $self->types()->[0]; |
65
|
129
|
50
|
|
|
|
3563
|
push @lines, 'PREF=' . $self->pref() if $self->pref(); |
66
|
129
|
50
|
|
|
|
3662
|
push @lines, 'LANGUAGE=' . $self->language() if $self->language(); |
67
|
|
|
|
|
|
|
|
68
|
129
|
|
|
|
|
3649
|
my $content = $self->content(); |
69
|
|
|
|
|
|
|
my $string |
70
|
|
|
|
|
|
|
= join( ';', @lines ) . ':' |
71
|
|
|
|
|
|
|
. ( |
72
|
|
|
|
|
|
|
ref($content) eq 'Array' |
73
|
129
|
0
|
|
|
|
838
|
? map { $node =~ /^(?:LABEL|GEO)$/s ? $content : $self->_escape($_) } @$content |
|
0
|
100
|
|
|
|
0
|
|
|
|
50
|
|
|
|
|
|
74
|
|
|
|
|
|
|
: $node =~ /^(?:LABEL|GEO)$/s ? $content |
75
|
|
|
|
|
|
|
: $self->_escape($content) |
76
|
|
|
|
|
|
|
); |
77
|
129
|
|
|
|
|
346
|
return $self->fold($string); |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub fold { |
81
|
448
|
|
|
448
|
0
|
742
|
my $self = shift; |
82
|
448
|
|
|
|
|
663
|
my $string = shift; |
83
|
448
|
|
|
|
|
973
|
my %arg = @_; |
84
|
448
|
|
|
|
|
1928
|
my $lf = Text::LineFold->new( CharMax => 74, Newline => "\x0D\x0A", TabSize => 1 ) |
85
|
|
|
|
|
|
|
; # line break with 75bytes |
86
|
448
|
|
|
|
|
278664
|
my $decoded = decode_utf8($string); |
87
|
|
|
|
|
|
|
|
88
|
448
|
|
|
|
|
8244
|
$string =~ s/(?<!\r)\n/\t/g; |
89
|
|
|
|
|
|
|
$string |
90
|
448
|
100
|
100
|
|
|
3366
|
= ( $decoded =~ /\P{ascii}+/ || $arg{'-force'} ) |
91
|
|
|
|
|
|
|
? $lf->fold( "", " ", $string ) |
92
|
|
|
|
|
|
|
: $lf->fold( "", " ", $string ); |
93
|
|
|
|
|
|
|
|
94
|
448
|
|
|
|
|
186243
|
$string =~ tr/\t/\n/; |
95
|
|
|
|
|
|
|
|
96
|
448
|
|
|
|
|
8433
|
return $string; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _escape { |
100
|
563
|
|
|
563
|
|
928
|
my $self = shift; |
101
|
563
|
|
|
|
|
790
|
my $txt = shift; |
102
|
563
|
100
|
|
|
|
1333
|
( my $r = $txt ) =~ s/([,;\\])/\\$1/sg if $txt; |
103
|
563
|
|
100
|
|
|
1929
|
return $r || ''; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
1; |