net-imap 0.4.12 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,400 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "config/attr_accessors"
4
+ require_relative "config/attr_inheritance"
5
+ require_relative "config/attr_type_coercion"
6
+
7
+ module Net
8
+ class IMAP
9
+
10
+ # Net::IMAP::Config <em>(available since +v0.4.13+)</em> stores
11
+ # configuration options for Net::IMAP clients. The global configuration can
12
+ # be seen at either Net::IMAP.config or Net::IMAP::Config.global, and the
13
+ # client-specific configuration can be seen at Net::IMAP#config.
14
+ #
15
+ # When creating a new client, all unhandled keyword arguments to
16
+ # Net::IMAP.new are delegated to Config.new. Every client has its own
17
+ # config.
18
+ #
19
+ # debug_client = Net::IMAP.new(hostname, debug: true)
20
+ # quiet_client = Net::IMAP.new(hostname, debug: false)
21
+ # debug_client.config.debug? # => true
22
+ # quiet_client.config.debug? # => false
23
+ #
24
+ # == Inheritance
25
+ #
26
+ # Configs have a parent[rdoc-ref:Config::AttrInheritance#parent] config, and
27
+ # any attributes which have not been set locally will inherit the parent's
28
+ # value. Every client creates its own specific config. By default, client
29
+ # configs inherit from Config.global.
30
+ #
31
+ # plain_client = Net::IMAP.new(hostname)
32
+ # debug_client = Net::IMAP.new(hostname, debug: true)
33
+ # quiet_client = Net::IMAP.new(hostname, debug: false)
34
+ #
35
+ # plain_client.config.inherited?(:debug) # => true
36
+ # debug_client.config.inherited?(:debug) # => false
37
+ # quiet_client.config.inherited?(:debug) # => false
38
+ #
39
+ # plain_client.config.debug? # => false
40
+ # debug_client.config.debug? # => true
41
+ # quiet_client.config.debug? # => false
42
+ #
43
+ # # Net::IMAP.debug is delegated to Net::IMAP::Config.global.debug
44
+ # Net::IMAP.debug = true
45
+ # plain_client.config.debug? # => true
46
+ # debug_client.config.debug? # => true
47
+ # quiet_client.config.debug? # => false
48
+ #
49
+ # Net::IMAP.debug = false
50
+ # plain_client.config.debug = true
51
+ # plain_client.config.inherited?(:debug) # => false
52
+ # plain_client.config.debug? # => true
53
+ # plain_client.config.reset(:debug)
54
+ # plain_client.config.inherited?(:debug) # => true
55
+ # plain_client.config.debug? # => false
56
+ #
57
+ # == Versioned defaults
58
+ #
59
+ # The effective default configuration for a specific +x.y+ version of
60
+ # +net-imap+ can be loaded with the +config+ keyword argument to
61
+ # Net::IMAP.new. Requesting default configurations for previous versions
62
+ # enables extra backward compatibility with those versions:
63
+ #
64
+ # client = Net::IMAP.new(hostname, config: 0.3)
65
+ # client.config.sasl_ir # => false
66
+ # client.config.responses_without_block # => :silence_deprecation_warning
67
+ #
68
+ # client = Net::IMAP.new(hostname, config: 0.4)
69
+ # client.config.sasl_ir # => true
70
+ # client.config.responses_without_block # => :silence_deprecation_warning
71
+ #
72
+ # client = Net::IMAP.new(hostname, config: 0.5)
73
+ # client.config.sasl_ir # => true
74
+ # client.config.responses_without_block # => :warn
75
+ #
76
+ # client = Net::IMAP.new(hostname, config: :future)
77
+ # client.config.sasl_ir # => true
78
+ # client.config.responses_without_block # => :raise
79
+ #
80
+ # The versioned default configs inherit certain specific config options from
81
+ # Config.global, for example #debug:
82
+ #
83
+ # client = Net::IMAP.new(hostname, config: 0.4)
84
+ # Net::IMAP.debug = false
85
+ # client.config.debug? # => false
86
+ #
87
+ # Net::IMAP.debug = true
88
+ # client.config.debug? # => true
89
+ #
90
+ # Use #load_defaults to globally behave like a specific version:
91
+ # client = Net::IMAP.new(hostname)
92
+ # client.config.sasl_ir # => true
93
+ # Net::IMAP.config.load_defaults 0.3
94
+ # client.config.sasl_ir # => false
95
+ #
96
+ # === Named defaults
97
+ # In addition to +x.y+ version numbers, the following aliases are supported:
98
+ #
99
+ # [+:default+]
100
+ # An alias for +:current+.
101
+ #
102
+ # >>>
103
+ # *NOTE*: This is _not_ the same as Config.default. It inherits some
104
+ # attributes from Config.global, for example: #debug.
105
+ # [+:current+]
106
+ # An alias for the current +x.y+ version's defaults.
107
+ # [+:next+]
108
+ # The _planned_ config for the next +x.y+ version.
109
+ # [+:future+]
110
+ # The _planned_ eventual config for some future +x.y+ version.
111
+ #
112
+ # For example, to raise exceptions for all current deprecations:
113
+ # client = Net::IMAP.new(hostname, config: :future)
114
+ # client.responses # raises an ArgumentError
115
+ #
116
+ # == Thread Safety
117
+ #
118
+ # *NOTE:* Updates to config objects are not synchronized for thread-safety.
119
+ #
120
+ class Config
121
+ # Array of attribute names that are _not_ loaded by #load_defaults.
122
+ DEFAULT_TO_INHERIT = %i[debug].freeze
123
+ private_constant :DEFAULT_TO_INHERIT
124
+
125
+ # The default config, which is hardcoded and frozen.
126
+ def self.default; @default end
127
+
128
+ # The global config object. Also available from Net::IMAP.config.
129
+ def self.global; @global if defined?(@global) end
130
+
131
+ # A hash of hard-coded configurations, indexed by version number or name.
132
+ def self.version_defaults; @version_defaults end
133
+ @version_defaults = {}
134
+
135
+ # :call-seq:
136
+ # Net::IMAP::Config[number] -> versioned config
137
+ # Net::IMAP::Config[symbol] -> named config
138
+ # Net::IMAP::Config[hash] -> new frozen config
139
+ # Net::IMAP::Config[config] -> same config
140
+ #
141
+ # Given a version number, returns the default configuration for the target
142
+ # version. See Config@Versioned+defaults.
143
+ #
144
+ # Given a version name, returns the default configuration for the target
145
+ # version. See Config@Named+defaults.
146
+ #
147
+ # Given a Hash, creates a new _frozen_ config which inherits from
148
+ # Config.global. Use Config.new for an unfrozen config.
149
+ #
150
+ # Given a config, returns that same config.
151
+ def self.[](config)
152
+ if config.is_a?(Config) then config
153
+ elsif config.nil? && global.nil? then nil
154
+ elsif config.respond_to?(:to_hash) then new(global, **config).freeze
155
+ else
156
+ version_defaults.fetch(config) do
157
+ case config
158
+ when Numeric
159
+ raise RangeError, "unknown config version: %p" % [config]
160
+ when Symbol
161
+ raise KeyError, "unknown config name: %p" % [config]
162
+ else
163
+ raise TypeError, "no implicit conversion of %s to %s" % [
164
+ config.class, Config
165
+ ]
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ include AttrAccessors
172
+ include AttrInheritance
173
+ include AttrTypeCoercion
174
+
175
+ # The debug mode (boolean). The default value is +false+.
176
+ #
177
+ # When #debug is +true+:
178
+ # * Data sent to and received from the server will be logged.
179
+ # * ResponseParser will print warnings with extra detail for parse
180
+ # errors. _This may include recoverable errors._
181
+ # * ResponseParser makes extra assertions.
182
+ #
183
+ # *NOTE:* Versioned default configs inherit #debug from Config.global, and
184
+ # #load_defaults will not override #debug.
185
+ attr_accessor :debug, type: :boolean
186
+
187
+ # method: debug?
188
+ # :call-seq: debug? -> boolean
189
+ #
190
+ # Alias for #debug
191
+
192
+ # Seconds to wait until a connection is opened.
193
+ #
194
+ # If the IMAP object cannot open a connection within this time,
195
+ # it raises a Net::OpenTimeout exception.
196
+ #
197
+ # See Net::IMAP.new.
198
+ #
199
+ # The default value is +30+ seconds.
200
+ attr_accessor :open_timeout, type: Integer
201
+
202
+ # Seconds to wait until an IDLE response is received, after
203
+ # the client asks to leave the IDLE state.
204
+ #
205
+ # See Net::IMAP#idle and Net::IMAP#idle_done.
206
+ #
207
+ # The default value is +5+ seconds.
208
+ attr_accessor :idle_response_timeout, type: Integer
209
+
210
+ # Whether to use the +SASL-IR+ extension when the server and \SASL
211
+ # mechanism both support it. Can be overridden by the +sasl_ir+ keyword
212
+ # parameter to Net::IMAP#authenticate.
213
+ #
214
+ # <em>(Support for +SASL-IR+ was added in +v0.4.0+.)</em>
215
+ #
216
+ # ==== Valid options
217
+ #
218
+ # [+false+ <em>(original behavior, before support was added)</em>]
219
+ # Do not use +SASL-IR+, even when it is supported by the server and the
220
+ # mechanism.
221
+ #
222
+ # [+true+ <em>(default since +v0.4+)</em>]
223
+ # Use +SASL-IR+ when it is supported by the server and the mechanism.
224
+ attr_accessor :sasl_ir, type: :boolean
225
+
226
+ # Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
227
+ # capability is present. When enforced, Net::IMAP will raise a
228
+ # LoginDisabledError when that capability is present.
229
+ #
230
+ # <em>(Support for +LOGINDISABLED+ was added in +v0.5.0+.)</em>
231
+ #
232
+ # ==== Valid options
233
+ #
234
+ # [+false+ <em>(original behavior, before support was added)</em>]
235
+ # Send the +LOGIN+ command without checking for +LOGINDISABLED+.
236
+ #
237
+ # [+:when_capabilities_cached+]
238
+ # Enforce the requirement when Net::IMAP#capabilities_cached? is true,
239
+ # but do not send a +CAPABILITY+ command to discover the capabilities.
240
+ #
241
+ # [+true+ <em>(default since +v0.5+)</em>]
242
+ # Only send the +LOGIN+ command if the +LOGINDISABLED+ capability is not
243
+ # present. When capabilities are unknown, Net::IMAP will automatically
244
+ # send a +CAPABILITY+ command first before sending +LOGIN+.
245
+ #
246
+ attr_accessor :enforce_logindisabled, type: [
247
+ false, :when_capabilities_cached, true
248
+ ]
249
+
250
+ # Controls the behavior of Net::IMAP#responses when called without any
251
+ # arguments (+type+ or +block+).
252
+ #
253
+ # ==== Valid options
254
+ #
255
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
256
+ # Returns the mutable responses hash (without any warnings).
257
+ # <em>This is not thread-safe.</em>
258
+ #
259
+ # [+:warn+ <em>(default since +v0.5+)</em>]
260
+ # Prints a warning and returns the mutable responses hash.
261
+ # <em>This is not thread-safe.</em>
262
+ #
263
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
264
+ # Returns a frozen copy of the unhandled responses hash, with frozen
265
+ # array values.
266
+ #
267
+ # Note that calling IMAP#responses with a +type+ and without a block is
268
+ # not configurable and always behaves like +:frozen_dup+.
269
+ #
270
+ # <em>(+:frozen_dup+ config option was added in +v0.4.17+)</em>
271
+ #
272
+ # [+:raise+]
273
+ # Raise an ArgumentError with the deprecation warning.
274
+ #
275
+ # Note: #responses_without_args is an alias for #responses_without_block.
276
+ attr_accessor :responses_without_block, type: [
277
+ :silence_deprecation_warning, :warn, :frozen_dup, :raise,
278
+ ]
279
+
280
+ alias responses_without_args responses_without_block # :nodoc:
281
+ alias responses_without_args= responses_without_block= # :nodoc:
282
+
283
+ ##
284
+ # :attr_accessor: responses_without_args
285
+ #
286
+ # Alias for responses_without_block
287
+
288
+ # Creates a new config object and initialize its attribute with +attrs+.
289
+ #
290
+ # If +parent+ is not given, the global config is used by default.
291
+ #
292
+ # If a block is given, the new config object is yielded to it.
293
+ def initialize(parent = Config.global, **attrs)
294
+ super(parent)
295
+ update(**attrs)
296
+ yield self if block_given?
297
+ end
298
+
299
+ # :call-seq: update(**attrs) -> self
300
+ #
301
+ # Assigns all of the provided +attrs+ to this config, and returns +self+.
302
+ #
303
+ # An ArgumentError is raised unless every key in +attrs+ matches an
304
+ # assignment method on Config.
305
+ #
306
+ # >>>
307
+ # *NOTE:* #update is not atomic. If an exception is raised due to an
308
+ # invalid attribute value, +attrs+ may be partially applied.
309
+ def update(**attrs)
310
+ unless (bad = attrs.keys.reject { respond_to?(:"#{_1}=") }).empty?
311
+ raise ArgumentError, "invalid config options: #{bad.join(", ")}"
312
+ end
313
+ attrs.each do send(:"#{_1}=", _2) end
314
+ self
315
+ end
316
+
317
+ # :call-seq:
318
+ # with(**attrs) -> config
319
+ # with(**attrs) {|config| } -> result
320
+ #
321
+ # Without a block, returns a new config which inherits from self. With a
322
+ # block, yields the new config and returns the block's result.
323
+ #
324
+ # If no keyword arguments are given, an ArgumentError will be raised.
325
+ #
326
+ # If +self+ is frozen, the copy will also be frozen.
327
+ def with(**attrs)
328
+ attrs.empty? and
329
+ raise ArgumentError, "expected keyword arguments, none given"
330
+ copy = new(**attrs)
331
+ copy.freeze if frozen?
332
+ block_given? ? yield(copy) : copy
333
+ end
334
+
335
+ # :call-seq: load_defaults(version) -> self
336
+ #
337
+ # Resets the current config to behave like the versioned default
338
+ # configuration for +version+. #parent will not be changed.
339
+ #
340
+ # Some config attributes default to inheriting from their #parent (which
341
+ # is usually Config.global) and are left unchanged, for example: #debug.
342
+ #
343
+ # See Config@Versioned+defaults and Config@Named+defaults.
344
+ def load_defaults(version)
345
+ [Numeric, Symbol, String].any? { _1 === version } or
346
+ raise ArgumentError, "expected number or symbol, got %p" % [version]
347
+ update(**Config[version].defaults_hash)
348
+ end
349
+
350
+ # :call-seq: to_h -> hash
351
+ #
352
+ # Returns all config attributes in a hash.
353
+ def to_h; data.members.to_h { [_1, send(_1)] } end
354
+
355
+ protected
356
+
357
+ def defaults_hash
358
+ to_h.reject {|k,v| DEFAULT_TO_INHERIT.include?(k) }
359
+ end
360
+
361
+ @default = new(
362
+ debug: false,
363
+ open_timeout: 30,
364
+ idle_response_timeout: 5,
365
+ sasl_ir: true,
366
+ enforce_logindisabled: true,
367
+ responses_without_block: :warn,
368
+ ).freeze
369
+
370
+ @global = default.new
371
+
372
+ version_defaults[:default] = Config[default.send(:defaults_hash)]
373
+ version_defaults[:current] = Config[:default]
374
+
375
+ version_defaults[0] = Config[:current].dup.update(
376
+ sasl_ir: false,
377
+ responses_without_block: :silence_deprecation_warning,
378
+ enforce_logindisabled: false,
379
+ ).freeze
380
+ version_defaults[0.0] = Config[0]
381
+ version_defaults[0.1] = Config[0]
382
+ version_defaults[0.2] = Config[0]
383
+ version_defaults[0.3] = Config[0]
384
+
385
+ version_defaults[0.4] = Config[0.3].dup.update(
386
+ sasl_ir: true,
387
+ ).freeze
388
+
389
+ version_defaults[0.5] = Config[:current]
390
+
391
+ version_defaults[0.6] = Config[0.5].dup.update(
392
+ responses_without_block: :frozen_dup,
393
+ ).freeze
394
+ version_defaults[:next] = Config[0.6]
395
+ version_defaults[:future] = Config[:next]
396
+
397
+ version_defaults.freeze
398
+ end
399
+ end
400
+ end
@@ -186,7 +186,7 @@ module Net
186
186
 
187
187
  # Ensure argument is 'number' or raise DataFormatError
188
188
  def ensure_number(num)
189
- return if valid_number?(num)
189
+ return num if valid_number?(num)
190
190
 
191
191
  msg = "number must be unsigned 32-bit integer: #{num}"
192
192
  raise DataFormatError, msg
@@ -194,7 +194,7 @@ module Net
194
194
 
195
195
  # Ensure argument is 'nz_number' or raise DataFormatError
196
196
  def ensure_nz_number(num)
197
- return if valid_nz_number?(num)
197
+ return num if valid_nz_number?(num)
198
198
 
199
199
  msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
200
200
  raise DataFormatError, msg
@@ -202,7 +202,7 @@ module Net
202
202
 
203
203
  # Ensure argument is 'mod_sequence_value' or raise DataFormatError
204
204
  def ensure_mod_sequence_value(num)
205
- return if valid_mod_sequence_value?(num)
205
+ return num if valid_mod_sequence_value?(num)
206
206
 
207
207
  msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
208
208
  raise DataFormatError, msg
@@ -16,8 +16,8 @@ module Net
16
16
  #
17
17
  # ==== Obsolete arguments
18
18
  #
19
- # Using obsolete arguments does not a warning. Obsolete arguments will be
20
- # deprecated by a future release.
19
+ # Use of obsolete arguments does not print a warning. Obsolete arguments
20
+ # will be deprecated by a future release.
21
21
  #
22
22
  # If a second positional argument is given and it is a hash (or is
23
23
  # convertible via +#to_hash+), it is converted to keyword arguments.
@@ -83,10 +83,12 @@ module Net
83
83
  elsif deprecated.empty?
84
84
  super host, port: port_or_options
85
85
  elsif deprecated.shift
86
- warn "DEPRECATED: Call Net::IMAP.new with keyword options", uplevel: 1
86
+ warn("DEPRECATED: Call Net::IMAP.new with keyword options",
87
+ uplevel: 1, category: :deprecated)
87
88
  super host, port: port_or_options, ssl: create_ssl_params(*deprecated)
88
89
  else
89
- warn "DEPRECATED: Call Net::IMAP.new with keyword options", uplevel: 1
90
+ warn("DEPRECATED: Call Net::IMAP.new with keyword options",
91
+ uplevel: 1, category: :deprecated)
90
92
  super host, port: port_or_options, ssl: false
91
93
  end
92
94
  end
@@ -113,7 +115,8 @@ module Net
113
115
  elsif deprecated.first.respond_to?(:to_hash)
114
116
  super(**Hash.try_convert(deprecated.first))
115
117
  else
116
- warn "DEPRECATED: Call Net::IMAP#starttls with keyword options", uplevel: 1
118
+ warn("DEPRECATED: Call Net::IMAP#starttls with keyword options",
119
+ uplevel: 1, category: :deprecated)
117
120
  super(**create_ssl_params(*deprecated))
118
121
  end
119
122
  end
@@ -7,6 +7,12 @@ module Net
7
7
  class Error < StandardError
8
8
  end
9
9
 
10
+ class LoginDisabledError < Error
11
+ def initialize(msg = "Remote server has disabled the LOGIN command", ...)
12
+ super
13
+ end
14
+ end
15
+
10
16
  # Error raised when data is in the incorrect format.
11
17
  class DataFormatError < Error
12
18
  end
@@ -939,7 +939,8 @@ module Net
939
939
  # for something else?
940
940
  #++
941
941
  def media_subtype
942
- warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
942
+ warn("media_subtype is obsolete, use subtype instead.\n",
943
+ uplevel: 1, category: :deprecated)
943
944
  return subtype
944
945
  end
945
946
  end
@@ -984,7 +985,8 @@ module Net
984
985
  # generate a warning message to +stderr+, then return
985
986
  # the value of +subtype+.
986
987
  def media_subtype
987
- warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
988
+ warn("media_subtype is obsolete, use subtype instead.\n",
989
+ uplevel: 1, category: :deprecated)
988
990
  return subtype
989
991
  end
990
992
  end
@@ -1040,77 +1042,6 @@ module Net
1040
1042
  end
1041
1043
  end
1042
1044
 
1043
- # BodyTypeAttachment is not used and will be removed in an upcoming release.
1044
- #
1045
- # === Bug Analysis
1046
- #
1047
- # \IMAP body structures are parenthesized lists and assign their fields
1048
- # positionally, so missing fields change the interpretation of all
1049
- # following fields. Additionally, different body types have a different
1050
- # number of required fields, followed by optional "extension" fields.
1051
- #
1052
- # BodyTypeAttachment was previously returned when a "message/rfc822" part,
1053
- # which should be sent as <tt>body-type-msg</tt> with ten required fields,
1054
- # was actually sent as a <tt>body-type-basic</tt> with _seven_ required
1055
- # fields.
1056
- #
1057
- # basic => type, subtype, param, id, desc, enc, octets, md5=nil, dsp=nil, lang=nil, loc=nil, *ext
1058
- # msg => type, subtype, param, id, desc, enc, octets, envelope, body, lines, md5=nil, ...
1059
- #
1060
- # Normally, +envelope+ and +md5+ are incompatible, but Net::IMAP leniently
1061
- # allowed buggy servers to send +NIL+ for +envelope+. As a result, when a
1062
- # server sent a <tt>message/rfc822</tt> part with +NIL+ for +md5+ and a
1063
- # non-<tt>NIL</tt> +dsp+, Net::IMAP misinterpreted the
1064
- # <tt>Content-Disposition</tt> as if it were a strange body type. In all
1065
- # reported cases, the <tt>Content-Disposition</tt> was "attachment", so
1066
- # BodyTypeAttachment was created as the workaround.
1067
- #
1068
- # === Current behavior
1069
- #
1070
- # When interpreted strictly, +envelope+ and +md5+ are incompatible. So the
1071
- # current parsing algorithm peeks ahead after it has received the seventh
1072
- # body field. If the next token is not the start of an +envelope+, we assume
1073
- # the server has incorrectly sent us a <tt>body-type-basic</tt> and return
1074
- # BodyTypeBasic. As a result, what was previously BodyTypeMessage#body =>
1075
- # BodyTypeAttachment is now BodyTypeBasic#disposition => ContentDisposition.
1076
- #
1077
- class BodyTypeAttachment < Struct.new(:dsp_type, :_unused_, :param)
1078
- # *invalid for BodyTypeAttachment*
1079
- def media_type
1080
- warn(<<~WARN, uplevel: 1)
1081
- BodyTypeAttachment#media_type is obsolete. Use dsp_type instead.
1082
- WARN
1083
- dsp_type
1084
- end
1085
-
1086
- # *invalid for BodyTypeAttachment*
1087
- def subtype
1088
- warn("BodyTypeAttachment#subtype is obsolete.\n", uplevel: 1)
1089
- nil
1090
- end
1091
-
1092
- ##
1093
- # method: dsp_type
1094
- # :call-seq: dsp_type -> string
1095
- #
1096
- # Returns the content disposition type, as defined by
1097
- # [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
1098
-
1099
- ##
1100
- # method: param
1101
- # :call-seq: param -> hash
1102
- #
1103
- # Returns a hash representing parameters of the Content-Disposition
1104
- # field, as defined by [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
1105
-
1106
- ##
1107
- def multipart?
1108
- return false
1109
- end
1110
- end
1111
-
1112
- deprecate_constant :BodyTypeAttachment
1113
-
1114
1045
  # Net::IMAP::BodyTypeMultipart represents body structures of messages and
1115
1046
  # message parts, when <tt>Content-Type</tt> is <tt>multipart/*</tt>.
1116
1047
  class BodyTypeMultipart < Struct.new(:media_type, :subtype,
@@ -1182,29 +1113,11 @@ module Net
1182
1113
  # generate a warning message to +stderr+, then return
1183
1114
  # the value of +subtype+.
1184
1115
  def media_subtype
1185
- warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
1116
+ warn("media_subtype is obsolete, use subtype instead.\n",
1117
+ uplevel: 1, category: :deprecated)
1186
1118
  return subtype
1187
1119
  end
1188
1120
  end
1189
1121
 
1190
- # === Obsolete
1191
- # BodyTypeExtension is not used and will be removed in an upcoming release.
1192
- #
1193
- # >>>
1194
- # BodyTypeExtension was (incorrectly) used for <tt>message/*</tt> parts
1195
- # (besides <tt>message/rfc822</tt>, which correctly uses BodyTypeMessage).
1196
- #
1197
- # Net::IMAP now (correctly) parses all message types (other than
1198
- # <tt>message/rfc822</tt> or <tt>message/global</tt>) as BodyTypeBasic.
1199
- class BodyTypeExtension < Struct.new(:media_type, :subtype,
1200
- :params, :content_id,
1201
- :description, :encoding, :size)
1202
- def multipart?
1203
- return false
1204
- end
1205
- end
1206
-
1207
- deprecate_constant :BodyTypeExtension
1208
-
1209
1122
  end
1210
1123
  end
@@ -154,7 +154,7 @@ module Net
154
154
  end
155
155
 
156
156
  # To be used conditionally:
157
- # assert_no_lookahead if Net::IMAP.debug
157
+ # assert_no_lookahead if config.debug?
158
158
  def assert_no_lookahead
159
159
  @token.nil? or
160
160
  parse_error("assertion failed: expected @token.nil?, actual %s: %p",
@@ -181,23 +181,23 @@ module Net
181
181
  end
182
182
 
183
183
  def peek_str?(str)
184
- assert_no_lookahead if Net::IMAP.debug
184
+ assert_no_lookahead if config.debug?
185
185
  @str[@pos, str.length] == str
186
186
  end
187
187
 
188
188
  def peek_re(re)
189
- assert_no_lookahead if Net::IMAP.debug
189
+ assert_no_lookahead if config.debug?
190
190
  re.match(@str, @pos)
191
191
  end
192
192
 
193
193
  def accept_re(re)
194
- assert_no_lookahead if Net::IMAP.debug
194
+ assert_no_lookahead if config.debug?
195
195
  re.match(@str, @pos) and @pos = $~.end(0)
196
196
  $~
197
197
  end
198
198
 
199
199
  def match_re(re, name)
200
- assert_no_lookahead if Net::IMAP.debug
200
+ assert_no_lookahead if config.debug?
201
201
  if re.match(@str, @pos)
202
202
  @pos = $~.end(0)
203
203
  $~
@@ -212,7 +212,7 @@ module Net
212
212
 
213
213
  def parse_error(fmt, *args)
214
214
  msg = format(fmt, *args)
215
- if IMAP.debug
215
+ if config.debug?
216
216
  local_path = File.dirname(__dir__)
217
217
  tok = @token ? "%s: %p" % [@token.symbol, @token.value] : "nil"
218
218
  warn "%s %s: %s" % [self.class, __method__, msg]