File Coverage

blib/lib/Protocol/IMAP/FetchResponseParser.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Protocol::IMAP::FetchResponseParser;
2             {
3             $Protocol::IMAP::FetchResponseParser::VERSION = '0.004';
4             }
5 1     1   690 use strict;
  1         2  
  1         32  
6 1     1   6 use warnings;
  1         2  
  1         28  
7 1     1   956 use parent qw(Parser::MGC Mixin::Event::Dispatch);
  1         354  
  1         5  
8              
9             use curry;
10              
11             =pod
12              
13             (key "value")
14             (key {5}
15             12345)
16             (key {5}
17             12345 key2 {6}
18             123456 key3{3}
19             123 key4{5}
20              
21             =cut
22              
23             sub parse {
24             my $self = shift;
25             $self->scope_of('(', sub {
26             +{ map %$_, @{
27             $self->sequence_of(sub {
28             $self->any_of(
29             $self->curry::envelope_section,
30             $self->curry::body_section,
31             $self->curry::generic_section,
32             );
33             }) } }
34             }, ')')
35             }
36              
37             sub nested_section {
38             my $self = shift;
39             $self->any_of(
40             sub { $self->string_or_nil },
41             sub { $self->token_int },
42             sub { $self->token_ident },
43             sub { $self->expect(qr/[a-zA-Z0-9\\_\$-]+/) },
44             sub {
45             $self->scope_of('(', sub {
46             $self->sequence_of(
47             $self->curry::nested_section
48             )
49             }, ')')
50             },
51             )
52             }
53              
54             sub envelope_date { shift->string_or_nil }
55             sub envelope_subject { shift->string_or_nil }
56             sub envelope_from { my $self = shift; $self->address_list }
57             sub envelope_sender { my $self = shift; $self->address_list }
58             sub envelope_reply_to { my $self = shift; $self->address_list }
59             sub envelope_to { my $self = shift; $self->address_list }
60             sub envelope_cc { my $self = shift; $self->address_list }
61             sub envelope_bcc { my $self = shift; $self->address_list }
62             sub envelope_in_reply_to { shift->string_or_nil }
63             sub string_or_nil {
64             my $self = shift;
65             $self->any_of(
66             sub { $self->token_string },
67             sub { $self->expect('NIL'); undef },
68             sub {
69             my $count;
70             $self->scope_of('{', sub {
71             $count = $self->token_int
72             }, '}');
73             $self->commit;
74             $self->invoke_event(literal_data => $count, \my $buf);
75             \$buf
76             },
77             )
78             }
79             sub envelope_message_id {shift->string_or_nil}
80             sub address_list {
81             my $self = shift;
82             $self->any_of(
83             sub { $self->expect('NIL'); undef },
84             sub { $self->scope_of('(', sub {
85             $self->sequence_of(
86             $self->curry::address_elements
87             )
88             }, ')') }
89             )
90             }
91             sub address_elements {
92             my $self = shift;
93             $self->scope_of('(', sub {
94             +{
95             name => $self->address_element, # name
96             source => $self->address_element, # source list
97             mailbox => $self->address_element, # mailbox
98             host => $self->address_element, # host
99             }
100             }, ')')
101             }
102              
103             sub address_element { my $self = shift; $self->string_or_nil }
104             sub envelope_section {
105             my $self = shift;
106             +{
107             lc($self->expect('ENVELOPE')),
108             $self->scope_of('(', sub {
109             +{
110             date => $self->envelope_date,
111             subject => $self->envelope_subject,
112             from => $self->envelope_from,
113             sender => $self->envelope_sender,
114             reply_to => $self->envelope_reply_to,
115             to => $self->envelope_to,
116             cc => $self->envelope_cc,
117             bcc => $self->envelope_bcc,
118             in_reply_to => $self->envelope_in_reply_to,
119             message_id => $self->envelope_message_id
120             }
121             }, ')')
122             }
123             }
124              
125             sub body_type { lc(shift->string_or_nil) }
126             sub body_subtype { lc(shift->string_or_nil) }
127             sub body_id { shift->string_or_nil }
128             sub body_description { shift->string_or_nil }
129             sub body_encoding { lc(shift->string_or_nil) }
130             sub body_size { shift->token_int }
131             sub body_lines { shift->token_int }
132             sub body_parameters {
133             my $self = shift;
134             $self->scope_of('(', sub {
135             +{ @{
136             $self->sequence_of(sub {
137             lc($self->string_or_nil),
138             $self->string_or_nil,
139             }) } }
140             }, ')')
141             }
142              
143             sub body_part {
144             my $self = shift;
145             +{
146             lc($self->expect('BODY')),
147             $self->body_section
148             }
149             }
150              
151             =pod
152              
153             =cut
154              
155             sub body_section {
156             my $self = shift;
157             $self->scope_of('(', sub {
158             $self->sequence_of(sub {
159             $self->any_of(sub {
160             +{
161             type => $self->body_type,
162             subtype => $self->body_subtype,
163             parameters => $self->body_parameters,
164             id => $self->body_id,
165             description => $self->body_description,
166             encoding => $self->body_encoding,
167             size => $self->body_size,
168             lines => $self->body_lines,
169             }
170             }, sub {
171             $self->body_section
172             })
173             })
174             }, ')')
175             }
176              
177             sub generic_section {
178             my $self = shift;
179             +{
180             lc($self->expect(qr/\S+/)),
181             $self->nested_section
182             }
183             }
184              
185             1;