net-imap 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/docs/styles.css +11 -1
- data/lib/net/imap/config.rb +5 -3
- data/lib/net/imap/data_lite.rb +11 -10
- data/lib/net/imap/fetch_data.rb +126 -47
- data/lib/net/imap/response_data.rb +118 -100
- data/lib/net/imap/response_parser.rb +13 -2
- data/lib/net/imap/sasl/anonymous_authenticator.rb +3 -3
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +3 -3
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +8 -8
- data/lib/net/imap/sasl/external_authenticator.rb +2 -2
- data/lib/net/imap/sasl/gs2_header.rb +7 -7
- data/lib/net/imap/sasl/login_authenticator.rb +2 -2
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +6 -6
- data/lib/net/imap/sasl/plain_authenticator.rb +7 -7
- data/lib/net/imap/sasl/scram_authenticator.rb +8 -8
- data/lib/net/imap/sasl.rb +1 -1
- data/lib/net/imap/search_result.rb +2 -2
- data/lib/net/imap/stringprep/nameprep.rb +1 -1
- data/lib/net/imap/stringprep/trace.rb +4 -4
- data/lib/net/imap.rb +162 -100
- data/rakelib/rfcs.rake +1 -0
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9b92943c4c4d17210f7374b4f5577f95471038a987540a8cdad2088e6bec25d
|
4
|
+
data.tar.gz: 6a28ce5ca7778cbfa3de48c3451be4d17fe6298a01e2a946725caf022a34dd8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a575e282b7cd6828d56360003b1de29e8ca0e3d55ce733c8de250f781413dc8e9e6a90549c14b9ed21bb46e0cdc88f3e75d92aeaed769d594f93056359ee40d
|
7
|
+
data.tar.gz: 87d57464c32eab235e241c74efea7953b9798b9c40a14f66170e751560943f728aabe852d38c746283cdcb4c03914ee375021c49fec67f653113d3330a6732d2
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Net::IMAP
|
2
2
|
|
3
3
|
Net::IMAP implements Internet Message Access Protocol (IMAP) client
|
4
|
-
functionality. The protocol is described in
|
4
|
+
functionality. The protocol is described in
|
5
|
+
[RFC3501](https://www.rfc-editor.org/rfc/rfc3501),
|
6
|
+
[RFC9051](https://www.rfc-editor.org/rfc/rfc9051) and various extensions.
|
5
7
|
|
6
8
|
## Installation
|
7
9
|
|
data/docs/styles.css
CHANGED
@@ -10,18 +10,28 @@ main .method-detail {
|
|
10
10
|
justify-content: space-between;
|
11
11
|
}
|
12
12
|
|
13
|
-
main .method-header,
|
13
|
+
main .method-header,
|
14
|
+
main .method-controls,
|
15
|
+
.attribute-method-heading {
|
14
16
|
padding: 0.5em;
|
15
17
|
/* border: 1px solid var(--highlight-color); */
|
16
18
|
background: var(--table-header-background-color);
|
17
19
|
line-height: 1.6;
|
18
20
|
}
|
19
21
|
|
22
|
+
.attribute-method-heading .attribute-access-type {
|
23
|
+
float: right;
|
24
|
+
}
|
25
|
+
|
20
26
|
main .method-header {
|
21
27
|
border-right: none;
|
22
28
|
border-radius: 4px 0 0 4px;
|
23
29
|
}
|
24
30
|
|
31
|
+
main .method-heading :any-link {
|
32
|
+
text-decoration: none;
|
33
|
+
}
|
34
|
+
|
25
35
|
main .method-controls {
|
26
36
|
border-left: none;
|
27
37
|
border-radius: 0 4px 4px 0;
|
data/lib/net/imap/config.rb
CHANGED
@@ -75,7 +75,7 @@ module Net
|
|
75
75
|
#
|
76
76
|
# client = Net::IMAP.new(hostname, config: :future)
|
77
77
|
# client.config.sasl_ir # => true
|
78
|
-
# client.config.responses_without_block # => :
|
78
|
+
# client.config.responses_without_block # => :frozen_dup
|
79
79
|
#
|
80
80
|
# The versioned default configs inherit certain specific config options from
|
81
81
|
# Config.global, for example #debug:
|
@@ -109,9 +109,11 @@ module Net
|
|
109
109
|
# [+:future+]
|
110
110
|
# The _planned_ eventual config for some future +x.y+ version.
|
111
111
|
#
|
112
|
-
# For example, to
|
112
|
+
# For example, to disable all currently deprecated behavior:
|
113
113
|
# client = Net::IMAP.new(hostname, config: :future)
|
114
|
-
# client.
|
114
|
+
# client.config.response_without_args # => :frozen_dup
|
115
|
+
# client.responses.frozen? # => true
|
116
|
+
# client.responses.values.all?(&:frozen?) # => true
|
115
117
|
#
|
116
118
|
# == Thread Safety
|
117
119
|
#
|
data/lib/net/imap/data_lite.rb
CHANGED
@@ -29,7 +29,7 @@ module Net
|
|
29
29
|
class IMAP
|
30
30
|
data_or_object = RUBY_VERSION >= "3.2.0" ? ::Data : Object
|
31
31
|
class DataLite < data_or_object
|
32
|
-
def encode_with(coder) coder.map =
|
32
|
+
def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end
|
33
33
|
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
|
34
34
|
end
|
35
35
|
|
@@ -159,28 +159,27 @@ module Net
|
|
159
159
|
|
160
160
|
##
|
161
161
|
def members; self.class.members end
|
162
|
-
def
|
163
|
-
def
|
164
|
-
def hash; [self.class, attributes].hash end
|
162
|
+
def to_h(&block) block ? __to_h__.to_h(&block) : __to_h__ end
|
163
|
+
def hash; [self.class, __to_h__].hash end
|
165
164
|
def ==(other) self.class == other.class && to_h == other.to_h end
|
166
165
|
def eql?(other) self.class == other.class && hash == other.hash end
|
167
|
-
def deconstruct;
|
166
|
+
def deconstruct; __to_h__.values end
|
168
167
|
|
169
168
|
def deconstruct_keys(keys)
|
170
169
|
raise TypeError unless keys.is_a?(Array) || keys.nil?
|
171
|
-
return
|
172
|
-
|
170
|
+
return __to_h__ if keys&.first.nil?
|
171
|
+
__to_h__.slice(*keys)
|
173
172
|
end
|
174
173
|
|
175
174
|
def with(**kwargs)
|
176
175
|
return self if kwargs.empty?
|
177
|
-
self.class.new(**
|
176
|
+
self.class.new(**__to_h__.merge(kwargs))
|
178
177
|
end
|
179
178
|
|
180
179
|
def inspect
|
181
180
|
__inspect_guard__(self) do |seen|
|
182
181
|
return "#<data #{self.class}:...>" if seen
|
183
|
-
attrs =
|
182
|
+
attrs = __to_h__.map {|kv| "%s=%p" % kv }.join(", ")
|
184
183
|
display = ["data", self.class.name, attrs].compact.join(" ")
|
185
184
|
"#<#{display}>"
|
186
185
|
end
|
@@ -190,7 +189,9 @@ module Net
|
|
190
189
|
private
|
191
190
|
|
192
191
|
def initialize_copy(source) super.freeze end
|
193
|
-
def marshal_dump;
|
192
|
+
def marshal_dump; __to_h__ end
|
193
|
+
|
194
|
+
def __to_h__; Hash[members.map {|m| [m, send(m)] }] end
|
194
195
|
|
195
196
|
# Yields +true+ if +obj+ has been seen already, +false+ if it hasn't.
|
196
197
|
# Marks +obj+ as seen inside the block, so circuler references don't
|
data/lib/net/imap/fetch_data.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
module Net
|
4
4
|
class IMAP < Protocol
|
5
5
|
|
6
|
-
# Net::IMAP::
|
7
|
-
# Net::IMAP#fetch
|
8
|
-
#
|
6
|
+
# Net::IMAP::FetchStruct is the superclass for FetchData and UIDFetchData.
|
7
|
+
# Net::IMAP#fetch, Net::IMAP#uid_fetch, Net::IMAP#store, and
|
8
|
+
# Net::IMAP#uid_store all return arrays of FetchStruct objects.
|
9
9
|
#
|
10
10
|
# === Fetch attributes
|
11
11
|
#
|
@@ -63,8 +63,7 @@ module Net
|
|
63
63
|
# * <b><tt>"X-GM-MSGID"</tt></b> --- unique message ID. Access via #attr.
|
64
64
|
# * <b><tt>"X-GM-THRID"</tt></b> --- Thread ID. Access via #attr.
|
65
65
|
#
|
66
|
-
# [
|
67
|
-
# >>>
|
66
|
+
# [NOTE:]
|
68
67
|
# Additional static fields are defined in other \IMAP extensions, but
|
69
68
|
# Net::IMAP can't parse them yet.
|
70
69
|
#
|
@@ -87,34 +86,23 @@ module Net
|
|
87
86
|
# extension]}[https://developers.google.com/gmail/imap/imap-extensions]
|
88
87
|
# * <b><tt>"X-GM-LABELS"</tt></b> --- Gmail labels. Access via #attr.
|
89
88
|
#
|
90
|
-
# [
|
91
|
-
# >>>
|
89
|
+
# [NOTE:]
|
92
90
|
# Additional dynamic fields are defined in other \IMAP extensions, but
|
93
91
|
# Net::IMAP can't parse them yet.
|
94
92
|
#
|
95
93
|
# === Implicitly setting <tt>\Seen</tt> and using +PEEK+
|
96
94
|
#
|
97
|
-
# Unless the mailbox
|
95
|
+
# Unless the mailbox has been opened as read-only, fetching
|
98
96
|
# <tt>BODY[#{section}]</tt> or <tt>BINARY[#{section}]</tt>
|
99
97
|
# will implicitly set the <tt>\Seen</tt> flag. To avoid this, fetch using
|
100
98
|
# <tt>BODY.PEEK[#{section}]</tt> or <tt>BINARY.PEEK[#{section}]</tt>
|
101
99
|
# instead.
|
102
100
|
#
|
103
|
-
#
|
104
|
-
# <tt>
|
101
|
+
# [NOTE:]
|
102
|
+
# The data will always be _returned_ without the <tt>".PEEK"</tt> suffix,
|
103
|
+
# as <tt>BODY[#{specifier}]</tt> or <tt>BINARY[#{section}]</tt>.
|
105
104
|
#
|
106
|
-
class
|
107
|
-
##
|
108
|
-
# method: seqno
|
109
|
-
# :call-seq: seqno -> Integer
|
110
|
-
#
|
111
|
-
# The message sequence number.
|
112
|
-
#
|
113
|
-
# [Note]
|
114
|
-
# This is never the unique identifier (UID), not even for the
|
115
|
-
# Net::IMAP#uid_fetch result. The UID is available from #uid, if it was
|
116
|
-
# returned.
|
117
|
-
|
105
|
+
class FetchStruct < Struct
|
118
106
|
##
|
119
107
|
# method: attr
|
120
108
|
# :call-seq: attr -> hash
|
@@ -123,9 +111,6 @@ module Net
|
|
123
111
|
# corresponding data item. Standard data items have corresponding
|
124
112
|
# accessor methods. The definitions of each attribute type is documented
|
125
113
|
# on its accessor.
|
126
|
-
#
|
127
|
-
# >>>
|
128
|
-
# *Note:* #seqno is not a message attribute.
|
129
114
|
|
130
115
|
# :call-seq: attr_upcase -> hash
|
131
116
|
#
|
@@ -142,7 +127,7 @@ module Net
|
|
142
127
|
#
|
143
128
|
# This is the same as getting the value for <tt>"BODY"</tt> from #attr.
|
144
129
|
#
|
145
|
-
# [
|
130
|
+
# [NOTE:]
|
146
131
|
# Use #message, #part, #header, #header_fields, #header_fields_not,
|
147
132
|
# #text, or #mime to retrieve <tt>BODY[#{section_spec}]</tt> attributes.
|
148
133
|
def body; attr["BODY"] end
|
@@ -235,7 +220,7 @@ module Net
|
|
235
220
|
fields && except and
|
236
221
|
raise ArgumentError, "conflicting 'fields' and 'except' arguments"
|
237
222
|
if fields
|
238
|
-
text = "HEADER.FIELDS (%s)"
|
223
|
+
text = "HEADER.FIELDS (%s)" % [fields.join(" ").upcase]
|
239
224
|
attr_upcase[body_section_attr(part_nums, text, offset: offset)]
|
240
225
|
elsif except
|
241
226
|
text = "HEADER.FIELDS.NOT (%s)" % [except.join(" ").upcase]
|
@@ -308,6 +293,7 @@ module Net
|
|
308
293
|
# This is the same as getting the value for <tt>"BODYSTRUCTURE"</tt> from
|
309
294
|
# #attr.
|
310
295
|
def bodystructure; attr["BODYSTRUCTURE"] end
|
296
|
+
|
311
297
|
alias body_structure bodystructure
|
312
298
|
|
313
299
|
# :call-seq: envelope -> Envelope or nil
|
@@ -320,7 +306,7 @@ module Net
|
|
320
306
|
# #attr.
|
321
307
|
def envelope; attr["ENVELOPE"] end
|
322
308
|
|
323
|
-
# :call-seq: flags -> array of Symbols and Strings
|
309
|
+
# :call-seq: flags -> array of Symbols and Strings, or nil
|
324
310
|
#
|
325
311
|
# A array of flags that are set for this message. System flags are
|
326
312
|
# symbols that have been capitalized by String#capitalize. Keyword flags
|
@@ -328,7 +314,7 @@ module Net
|
|
328
314
|
#
|
329
315
|
# This is the same as getting the value for <tt>"FLAGS"</tt> from #attr.
|
330
316
|
#
|
331
|
-
# [
|
317
|
+
# [NOTE:]
|
332
318
|
# The +FLAGS+ field is dynamic, and can change for a uniquely identified
|
333
319
|
# message.
|
334
320
|
def flags; attr["FLAGS"] end
|
@@ -336,40 +322,41 @@ module Net
|
|
336
322
|
# :call-seq: internaldate -> Time or nil
|
337
323
|
#
|
338
324
|
# The internal date and time of the message on the server. This is not
|
339
|
-
# the date and time in the [RFC5322[https://
|
325
|
+
# the date and time in the [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]]
|
340
326
|
# header, but rather a date and time which reflects when the message was
|
341
327
|
# received.
|
342
328
|
#
|
343
329
|
# This is similar to getting the value for <tt>"INTERNALDATE"</tt> from
|
344
330
|
# #attr.
|
345
331
|
#
|
346
|
-
# [
|
332
|
+
# [NOTE:]
|
347
333
|
# <tt>attr["INTERNALDATE"]</tt> returns a string, and this method
|
348
334
|
# returns a Time object.
|
349
335
|
def internaldate
|
350
336
|
attr["INTERNALDATE"]&.then { IMAP.decode_time _1 }
|
351
337
|
end
|
338
|
+
|
352
339
|
alias internal_date internaldate
|
353
340
|
|
354
|
-
# :call-seq: rfc822 -> String
|
341
|
+
# :call-seq: rfc822 -> String or nil
|
355
342
|
#
|
356
343
|
# Semantically equivalent to #message with no arguments.
|
357
344
|
#
|
358
345
|
# This is the same as getting the value for <tt>"RFC822"</tt> from #attr.
|
359
346
|
#
|
360
|
-
# [
|
347
|
+
# [NOTE:]
|
361
348
|
# +IMAP4rev2+ deprecates <tt>RFC822</tt>.
|
362
349
|
def rfc822; attr["RFC822"] end
|
363
350
|
|
364
|
-
# :call-seq: rfc822_size -> Integer
|
351
|
+
# :call-seq: rfc822_size -> Integer or nil
|
365
352
|
#
|
366
|
-
# A number expressing the [RFC5322[https://
|
353
|
+
# A number expressing the [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]]
|
367
354
|
# size of the message.
|
368
355
|
#
|
369
356
|
# This is the same as getting the value for <tt>"RFC822.SIZE"</tt> from
|
370
357
|
# #attr.
|
371
358
|
#
|
372
|
-
# [
|
359
|
+
# [NOTE:]
|
373
360
|
# \IMAP was originally developed for the older
|
374
361
|
# RFC822[https://www.rfc-editor.org/rfc/rfc822.html] standard, and as a
|
375
362
|
# consequence several fetch items in \IMAP incorporate "RFC822" in their
|
@@ -379,34 +366,45 @@ module Net
|
|
379
366
|
# interpreted as a reference to the updated
|
380
367
|
# RFC5322[https://www.rfc-editor.org/rfc/rfc5322.html] standard.
|
381
368
|
def rfc822_size; attr["RFC822.SIZE"] end
|
382
|
-
alias size rfc822_size
|
383
369
|
|
384
|
-
# :call-seq
|
370
|
+
# NOTE: a bug in rdoc 6.7 prevents us from adding a call-seq to
|
371
|
+
# rfc822_size _and_ aliasing size => rfc822_size. Is it because this
|
372
|
+
# class inherits from Struct?
|
373
|
+
|
374
|
+
# Alias for: rfc822_size
|
375
|
+
def size; rfc822_size end
|
376
|
+
|
377
|
+
|
378
|
+
# :call-seq: rfc822_header -> String or nil
|
385
379
|
#
|
386
380
|
# Semantically equivalent to #header, with no arguments.
|
387
381
|
#
|
388
382
|
# This is the same as getting the value for <tt>"RFC822.HEADER"</tt> from #attr.
|
389
383
|
#
|
390
|
-
# [
|
384
|
+
# [NOTE:]
|
391
385
|
# +IMAP4rev2+ deprecates <tt>RFC822.HEADER</tt>.
|
392
386
|
def rfc822_header; attr["RFC822.HEADER"] end
|
393
387
|
|
394
|
-
# :call-seq: rfc822_text -> String
|
388
|
+
# :call-seq: rfc822_text -> String or nil
|
395
389
|
#
|
396
390
|
# Semantically equivalent to #text, with no arguments.
|
397
391
|
#
|
398
392
|
# This is the same as getting the value for <tt>"RFC822.TEXT"</tt> from
|
399
393
|
# #attr.
|
400
394
|
#
|
401
|
-
# [
|
395
|
+
# [NOTE:]
|
402
396
|
# +IMAP4rev2+ deprecates <tt>RFC822.TEXT</tt>.
|
403
397
|
def rfc822_text; attr["RFC822.TEXT"] end
|
404
398
|
|
405
|
-
# :call-seq: uid -> Integer
|
399
|
+
# :call-seq: uid -> Integer or nil
|
406
400
|
#
|
407
401
|
# A number expressing the unique identifier of the message.
|
408
402
|
#
|
409
403
|
# This is the same as getting the value for <tt>"UID"</tt> from #attr.
|
404
|
+
#
|
405
|
+
# [NOTE:]
|
406
|
+
# For UIDFetchData, this returns the uniqueid at the beginning of the
|
407
|
+
# +UIDFETCH+ response, _not_ the value from #attr.
|
410
408
|
def uid; attr["UID"] end
|
411
409
|
|
412
410
|
# :call-seq:
|
@@ -452,7 +450,7 @@ module Net
|
|
452
450
|
attr[section_attr("BINARY.SIZE", part_nums)]
|
453
451
|
end
|
454
452
|
|
455
|
-
# :call-seq: modseq -> Integer
|
453
|
+
# :call-seq: modseq -> Integer or nil
|
456
454
|
#
|
457
455
|
# The modification sequence number associated with this IMAP message.
|
458
456
|
#
|
@@ -461,7 +459,7 @@ module Net
|
|
461
459
|
# The server must support the +CONDSTORE+ extension
|
462
460
|
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
463
461
|
#
|
464
|
-
# [
|
462
|
+
# [NOTE:]
|
465
463
|
# The +MODSEQ+ field is dynamic, and can change for a uniquely
|
466
464
|
# identified message.
|
467
465
|
def modseq; attr["MODSEQ"] end
|
@@ -508,11 +506,92 @@ module Net
|
|
508
506
|
spec = Array(part).flatten.map { Integer(_1) }
|
509
507
|
spec << text if text
|
510
508
|
spec = spec.join(".")
|
511
|
-
if offset then "%s[%s]<%d>" % [attr, spec, Integer(offset)]
|
512
|
-
else "%s[%s]" % [attr, spec]
|
513
|
-
end
|
509
|
+
if offset then "%s[%s]<%d>" % [attr, spec, Integer(offset)] else "%s[%s]" % [attr, spec] end
|
514
510
|
end
|
511
|
+
end
|
515
512
|
|
513
|
+
# Net::IMAP::FetchData represents the contents of a +FETCH+ response.
|
514
|
+
# Net::IMAP#fetch, Net::IMAP#uid_fetch, Net::IMAP#store, and
|
515
|
+
# Net::IMAP#uid_store all return arrays of FetchData objects, except when
|
516
|
+
# the +UIDONLY+ extension is enabled.
|
517
|
+
#
|
518
|
+
# See FetchStruct documentation for a list of standard message attributes.
|
519
|
+
class FetchData < FetchStruct.new(:seqno, :attr)
|
520
|
+
##
|
521
|
+
# method: seqno
|
522
|
+
# :call-seq: seqno -> Integer
|
523
|
+
#
|
524
|
+
# The message sequence number.
|
525
|
+
#
|
526
|
+
# [NOTE:]
|
527
|
+
# This is not the same as the unique identifier (UID), not even for the
|
528
|
+
# Net::IMAP#uid_fetch result. The UID is available from #uid, if it was
|
529
|
+
# returned.
|
530
|
+
#
|
531
|
+
# [NOTE:]
|
532
|
+
# UIDFetchData will raise a NoMethodError.
|
533
|
+
|
534
|
+
##
|
535
|
+
# method: attr
|
536
|
+
# :call-seq: attr -> hash
|
537
|
+
#
|
538
|
+
# Each key specifies a message attribute, and the value is the
|
539
|
+
# corresponding data item. Standard data items have corresponding
|
540
|
+
# accessor methods. The definitions of each attribute type is documented
|
541
|
+
# on its accessor.
|
542
|
+
#
|
543
|
+
# See FetchStruct documentation for message attribute accessors.
|
544
|
+
#
|
545
|
+
# [NOTE:]
|
546
|
+
# #seqno is not a message attribute.
|
547
|
+
end
|
548
|
+
|
549
|
+
# Net::IMAP::UIDFetchData represents the contents of a +UIDFETCH+ response,
|
550
|
+
# When the +UIDONLY+ extension has been enabled, Net::IMAP#uid_fetch and
|
551
|
+
# Net::IMAP#uid_store will both return an array of UIDFetchData objects.
|
552
|
+
#
|
553
|
+
# UIDFetchData contains the same message attributes as FetchData. However,
|
554
|
+
# +UIDFETCH+ responses return the UID at the beginning of the response,
|
555
|
+
# replacing FetchData#seqno. UIDFetchData never contains a message sequence
|
556
|
+
# number.
|
557
|
+
#
|
558
|
+
# See FetchStruct documentation for a list of standard message attributes.
|
559
|
+
class UIDFetchData < FetchStruct.new(:uid, :attr)
|
560
|
+
##
|
561
|
+
# method: uid
|
562
|
+
# call-seq: uid -> Integer
|
563
|
+
#
|
564
|
+
# A number expressing the unique identifier of the message.
|
565
|
+
#
|
566
|
+
# [NOTE:]
|
567
|
+
# Although #attr may _also_ have a redundant +UID+ attribute, #uid
|
568
|
+
# returns the uniqueid at the beginning of the +UIDFETCH+ response.
|
569
|
+
|
570
|
+
##
|
571
|
+
# method: attr
|
572
|
+
# call-seq: attr -> hash
|
573
|
+
#
|
574
|
+
# Each key specifies a message attribute, and the value is the
|
575
|
+
# corresponding data item. Standard data items have corresponding
|
576
|
+
# accessor methods. The definitions of each attribute type is documented
|
577
|
+
# on its accessor.
|
578
|
+
#
|
579
|
+
# See FetchStruct documentation for message attribute accessors.
|
580
|
+
#
|
581
|
+
# [NOTE:]
|
582
|
+
# #uid is not a message attribute. Although the server may return a
|
583
|
+
# +UID+ message attribute, it is not required to. #uid is taken from
|
584
|
+
# its corresponding +UIDFETCH+ field.
|
585
|
+
|
586
|
+
# UIDFetchData will print a warning if <tt>#attr["UID"]</tt> is present
|
587
|
+
# but not identical to #uid.
|
588
|
+
def initialize(...)
|
589
|
+
super
|
590
|
+
attr and
|
591
|
+
attr_uid = attr["UID"] and
|
592
|
+
attr_uid != uid and
|
593
|
+
warn "#{self.class} UIDs do not match (#{attr_uid} != #{uid})"
|
594
|
+
end
|
516
595
|
end
|
517
596
|
end
|
518
597
|
end
|