net-imap 0.5.4 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP < Protocol
5
+
6
+ # *NOTE:* <em>UIDPlusData is deprecated and will be removed in the +0.6.0+
7
+ # release.</em> To use AppendUIDData and CopyUIDData before +0.6.0+, set
8
+ # Config#parser_use_deprecated_uidplus_data to +false+.
9
+ #
10
+ # UIDPlusData represents the ResponseCode#data that accompanies the
11
+ # +APPENDUID+ and +COPYUID+ {response codes}[rdoc-ref:ResponseCode].
12
+ #
13
+ # A server that supports +UIDPLUS+ should send UIDPlusData in response to
14
+ # the append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy],
15
+ # move[rdoc-ref:Net::IMAP#move], {uid copy}[rdoc-ref:Net::IMAP#uid_copy],
16
+ # and {uid move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the
17
+ # destination mailbox reports +UIDNOTSTICKY+.
18
+ #
19
+ # Note that append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy]
20
+ # and {uid_copy}[rdoc-ref:Net::IMAP#uid_copy] return UIDPlusData in their
21
+ # TaggedResponse. But move[rdoc-ref:Net::IMAP#copy] and
22
+ # {uid_move}[rdoc-ref:Net::IMAP#uid_move] _should_ send UIDPlusData in an
23
+ # UntaggedResponse response before sending their TaggedResponse. However
24
+ # some servers do send UIDPlusData in the TaggedResponse for +MOVE+
25
+ # commands---this complies with the older +UIDPLUS+ specification but is
26
+ # discouraged by the +MOVE+ extension and disallowed by +IMAP4rev2+.
27
+ #
28
+ # == Required capability
29
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
30
+ # or +IMAP4rev2+ capability.
31
+ #
32
+ class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids)
33
+ ##
34
+ # method: uidvalidity
35
+ # :call-seq: uidvalidity -> nonzero uint32
36
+ #
37
+ # The UIDVALIDITY of the destination mailbox.
38
+
39
+ ##
40
+ # method: source_uids
41
+ # :call-seq: source_uids -> nil or an array of nonzero uint32
42
+ #
43
+ # The UIDs of the copied or moved messages.
44
+ #
45
+ # Note:: Returns +nil+ for Net::IMAP#append.
46
+
47
+ ##
48
+ # method: assigned_uids
49
+ # :call-seq: assigned_uids -> an array of nonzero uint32
50
+ #
51
+ # The newly assigned UIDs of the copied, moved, or appended messages.
52
+ #
53
+ # Note:: This always returns an array, even when it contains only one UID.
54
+
55
+ ##
56
+ # :call-seq: uid_mapping -> nil or a hash
57
+ #
58
+ # Returns a hash mapping each source UID to the newly assigned destination
59
+ # UID.
60
+ #
61
+ # Note:: Returns +nil+ for Net::IMAP#append.
62
+ def uid_mapping
63
+ source_uids&.zip(assigned_uids)&.to_h
64
+ end
65
+ end
66
+
67
+ # >>>
68
+ # *NOTE:* <em>AppendUIDData will replace UIDPlusData for +APPENDUID+ in the
69
+ # +0.6.0+ release.</em> To use AppendUIDData before +0.6.0+, set
70
+ # Config#parser_use_deprecated_uidplus_data to +false+.
71
+ #
72
+ # AppendUIDData represents the ResponseCode#data that accompanies the
73
+ # +APPENDUID+ {response code}[rdoc-ref:ResponseCode].
74
+ #
75
+ # A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send
76
+ # AppendUIDData inside every TaggedResponse returned by the
77
+ # append[rdoc-ref:Net::IMAP#append] command---unless the target mailbox
78
+ # reports +UIDNOTSTICKY+.
79
+ #
80
+ # == Required capability
81
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
82
+ # or +IMAP4rev2+ capability.
83
+ class AppendUIDData < Data.define(:uidvalidity, :assigned_uids)
84
+ def initialize(uidvalidity:, assigned_uids:)
85
+ uidvalidity = Integer(uidvalidity)
86
+ assigned_uids = SequenceSet[assigned_uids]
87
+ NumValidator.ensure_nz_number(uidvalidity)
88
+ if assigned_uids.include_star?
89
+ raise DataFormatError, "uid-set cannot contain '*'"
90
+ end
91
+ super
92
+ end
93
+
94
+ ##
95
+ # attr_reader: uidvalidity
96
+ # :call-seq: uidvalidity -> nonzero uint32
97
+ #
98
+ # The UIDVALIDITY of the destination mailbox.
99
+
100
+ ##
101
+ # attr_reader: assigned_uids
102
+ #
103
+ # A SequenceSet with the newly assigned UIDs of the appended messages.
104
+
105
+ # Returns the number of messages that have been appended.
106
+ def size
107
+ assigned_uids.count_with_duplicates
108
+ end
109
+ end
110
+
111
+ # >>>
112
+ # *NOTE:* <em>CopyUIDData will replace UIDPlusData for +COPYUID+ in the
113
+ # +0.6.0+ release.</em> To use CopyUIDData before +0.6.0+, set
114
+ # Config#parser_use_deprecated_uidplus_data to +false+.
115
+ #
116
+ # CopyUIDData represents the ResponseCode#data that accompanies the
117
+ # +COPYUID+ {response code}[rdoc-ref:ResponseCode].
118
+ #
119
+ # A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send CopyUIDData
120
+ # in response to
121
+ # copy[rdoc-ref:Net::IMAP#copy], {uid_copy}[rdoc-ref:Net::IMAP#uid_copy],
122
+ # move[rdoc-ref:Net::IMAP#copy], and {uid_move}[rdoc-ref:Net::IMAP#uid_move]
123
+ # commands---unless the destination mailbox reports +UIDNOTSTICKY+.
124
+ #
125
+ # Note that copy[rdoc-ref:Net::IMAP#copy] and
126
+ # {uid_copy}[rdoc-ref:Net::IMAP#uid_copy] return CopyUIDData in their
127
+ # TaggedResponse. But move[rdoc-ref:Net::IMAP#copy] and
128
+ # {uid_move}[rdoc-ref:Net::IMAP#uid_move] _should_ send CopyUIDData in an
129
+ # UntaggedResponse response before sending their TaggedResponse. However
130
+ # some servers do send CopyUIDData in the TaggedResponse for +MOVE+
131
+ # commands---this complies with the older +UIDPLUS+ specification but is
132
+ # discouraged by the +MOVE+ extension and disallowed by +IMAP4rev2+.
133
+ #
134
+ # == Required capability
135
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
136
+ # or +IMAP4rev2+ capability.
137
+ class CopyUIDData < Data.define(:uidvalidity, :source_uids, :assigned_uids)
138
+ def initialize(uidvalidity:, source_uids:, assigned_uids:)
139
+ uidvalidity = Integer(uidvalidity)
140
+ source_uids = SequenceSet[source_uids]
141
+ assigned_uids = SequenceSet[assigned_uids]
142
+ NumValidator.ensure_nz_number(uidvalidity)
143
+ if source_uids.include_star? || assigned_uids.include_star?
144
+ raise DataFormatError, "uid-set cannot contain '*'"
145
+ elsif source_uids.count_with_duplicates != assigned_uids.count_with_duplicates
146
+ raise DataFormatError, "mismatched uid-set sizes for %s and %s" % [
147
+ source_uids, assigned_uids
148
+ ]
149
+ end
150
+ super
151
+ end
152
+
153
+ ##
154
+ # attr_reader: uidvalidity
155
+ #
156
+ # The +UIDVALIDITY+ of the destination mailbox (a nonzero unsigned 32 bit
157
+ # integer).
158
+
159
+ ##
160
+ # attr_reader: source_uids
161
+ #
162
+ # A SequenceSet with the original UIDs of the copied or moved messages.
163
+
164
+ ##
165
+ # attr_reader: assigned_uids
166
+ #
167
+ # A SequenceSet with the newly assigned UIDs of the copied or moved
168
+ # messages.
169
+
170
+ # Returns the number of messages that have been copied or moved.
171
+ # source_uids and the assigned_uids will both the same number of UIDs.
172
+ def size
173
+ assigned_uids.count_with_duplicates
174
+ end
175
+
176
+ # :call-seq:
177
+ # assigned_uid_for(source_uid) -> uid
178
+ # self[source_uid] -> uid
179
+ #
180
+ # Returns the UID in the destination mailbox for the message that was
181
+ # copied from +source_uid+ in the source mailbox.
182
+ #
183
+ # This is the reverse of #source_uid_for.
184
+ #
185
+ # Related: source_uid_for, each_uid_pair, uid_mapping
186
+ def assigned_uid_for(source_uid)
187
+ idx = source_uids.find_ordered_index(source_uid) and
188
+ assigned_uids.ordered_at(idx)
189
+ end
190
+ alias :[] :assigned_uid_for
191
+
192
+ # :call-seq:
193
+ # source_uid_for(assigned_uid) -> uid
194
+ #
195
+ # Returns the UID in the source mailbox for the message that was copied to
196
+ # +assigned_uid+ in the source mailbox.
197
+ #
198
+ # This is the reverse of #assigned_uid_for.
199
+ #
200
+ # Related: assigned_uid_for, each_uid_pair, uid_mapping
201
+ def source_uid_for(assigned_uid)
202
+ idx = assigned_uids.find_ordered_index(assigned_uid) and
203
+ source_uids.ordered_at(idx)
204
+ end
205
+
206
+ # Yields a pair of UIDs for each copied message. The first is the
207
+ # message's UID in the source mailbox and the second is the UID in the
208
+ # destination mailbox.
209
+ #
210
+ # Returns an enumerator when no block is given.
211
+ #
212
+ # Please note the warning on uid_mapping before calling methods like
213
+ # +to_h+ or +to_a+ on the returned enumerator.
214
+ #
215
+ # Related: uid_mapping, assigned_uid_for, source_uid_for
216
+ def each_uid_pair
217
+ return enum_for(__method__) unless block_given?
218
+ source_uids.each_ordered_number.lazy
219
+ .zip(assigned_uids.each_ordered_number.lazy) do
220
+ |source_uid, assigned_uid|
221
+ yield source_uid, assigned_uid
222
+ end
223
+ end
224
+ alias each_pair each_uid_pair
225
+ alias each each_uid_pair
226
+
227
+ # :call-seq: uid_mapping -> hash
228
+ #
229
+ # Returns a hash mapping each source UID to the newly assigned destination
230
+ # UID.
231
+ #
232
+ # <em>*Warning:*</em> The hash that is created may consume _much_ more
233
+ # memory than the data used to create it. When handling responses from an
234
+ # untrusted server, check #size before calling this method.
235
+ #
236
+ # Related: each_uid_pair, assigned_uid_for, source_uid_for
237
+ def uid_mapping
238
+ each_uid_pair.to_h
239
+ end
240
+
241
+ end
242
+
243
+ end
244
+ end