Skip to content

Commit

Permalink
🔧🗑️ Deprecate UIDPlusData, with config to upgrade
Browse files Browse the repository at this point in the history
This config attribute causes the parser to use the new AppendUIDData and
CopyUIDData classes instead of CopyUIDData.

AppendUIDData and CopyUIDData are _mostly_ backward-compatible with
UIDPlusData.  Most applications should be able to upgrade with no
changes.

UIDPlusData will be removed in +v0.6+.
  • Loading branch information
nevans committed Feb 6, 2025
1 parent 8f41dea commit 60f5776
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
29 changes: 29 additions & 0 deletions lib/net/imap/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,32 @@ def self.[](config)
#
# Alias for responses_without_block

# Whether ResponseParser should use the deprecated UIDPlusData or
# CopyUIDData for +COPYUID+ response codes, and UIDPlusData or
# AppendUIDData for +APPENDUID+ response codes.
#
# AppendUIDData and CopyUIDData are _mostly_ backward-compatible with
# UIDPlusData. Most applications should be able to upgrade with little
# or no changes.
#
# <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
#
# <em>(Config option added in +v0.4.19+ and +v0.5.6+.)</em>
#
# <em>UIDPlusData will be removed in +v0.6+ and this config setting will
# be ignored.</em>
#
# ==== Valid options
#
# [+true+ <em>(original default)</em>]
# ResponseParser only uses UIDPlusData.
#
# [+false+ <em>(planned default for +v0.6+)</em>]
# ResponseParser _only_ uses AppendUIDData and CopyUIDData.
attr_accessor :parser_use_deprecated_uidplus_data, type: [
true, false
]

# Creates a new config object and initialize its attribute with +attrs+.
#
# If +parent+ is not given, the global config is used by default.
Expand Down Expand Up @@ -367,6 +393,7 @@ def defaults_hash
sasl_ir: true,
enforce_logindisabled: true,
responses_without_block: :warn,
parser_use_deprecated_uidplus_data: true,
).freeze

@global = default.new
Expand All @@ -378,6 +405,7 @@ def defaults_hash
sasl_ir: false,
responses_without_block: :silence_deprecation_warning,
enforce_logindisabled: false,
parser_use_deprecated_uidplus_data: true,
).freeze
version_defaults[0.0] = Config[0]
version_defaults[0.1] = Config[0]
Expand All @@ -392,6 +420,7 @@ def defaults_hash

version_defaults[0.6] = Config[0.5].dup.update(
responses_without_block: :frozen_dup,
parser_use_deprecated_uidplus_data: false,
).freeze
version_defaults[:next] = Config[0.6]
version_defaults[:future] = Config[:next]
Expand Down
12 changes: 8 additions & 4 deletions lib/net/imap/response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2001,11 +2001,10 @@ def charset__list
#
# n.b, uniqueid ⊂ uid-set. To avoid inconsistent return types, we always
# match uid_set even if that returns a single-member array.
#
def resp_code_apnd__data
validity = number; SP!
dst_uids = uid_set # uniqueid ⊂ uid-set
UIDPlus(validity, nil, dst_uids)
AppendUID(validity, dst_uids)
end

# already matched: "COPYUID"
Expand All @@ -2015,10 +2014,15 @@ def resp_code_copy__data
validity = number; SP!
src_uids = uid_set; SP!
dst_uids = uid_set
UIDPlus(validity, src_uids, dst_uids)
CopyUID(validity, src_uids, dst_uids)
end

def UIDPlus(validity, src_uids, dst_uids)
def AppendUID(...) DeprecatedUIDPlus(...) || AppendUIDData.new(...) end
def CopyUID(...) DeprecatedUIDPlus(...) || CopyUIDData.new(...) end

# TODO: remove this code in the v0.6.0 release
def DeprecatedUIDPlus(validity, src_uids = nil, dst_uids)
return unless config.parser_use_deprecated_uidplus_data
src_uids &&= src_uids.each_ordered_number.to_a
dst_uids = dst_uids.each_ordered_number.to_a
UIDPlusData.new(validity, src_uids, dst_uids)
Expand Down
14 changes: 14 additions & 0 deletions lib/net/imap/uidplus_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
module Net
class IMAP < Protocol

# *NOTE:* <em>UIDPlusData is deprecated and will be removed in the +0.6.0+
# release.</em> To use AppendUIDData and CopyUIDData before +0.6.0+, set
# Config#parser_use_deprecated_uidplus_data to +false+.
#
# UIDPlusData represents the ResponseCode#data that accompanies the
# +APPENDUID+ and +COPYUID+ {response codes}[rdoc-ref:ResponseCode].
#
Expand Down Expand Up @@ -60,6 +64,11 @@ def uid_mapping
end
end

# >>>
# *NOTE:* <em>AppendUIDData will replace UIDPlusData for +APPENDUID+ in the
# +0.6.0+ release.</em> To use AppendUIDData before +0.6.0+, set
# Config#parser_use_deprecated_uidplus_data to +false+.
#
# AppendUIDData represents the ResponseCode#data that accompanies the
# +APPENDUID+ {response code}[rdoc-ref:ResponseCode].
#
Expand Down Expand Up @@ -99,6 +108,11 @@ def size
end
end

# >>>
# *NOTE:* <em>CopyUIDData will replace UIDPlusData for +COPYUID+ in the
# +0.6.0+ release.</em> To use CopyUIDData before +0.6.0+, set
# Config#parser_use_deprecated_uidplus_data to +false+.
#
# CopyUIDData represents the ResponseCode#data that accompanies the
# +COPYUID+ {response code}[rdoc-ref:ResponseCode].
#
Expand Down
37 changes: 37 additions & 0 deletions test/net/imap/test_imap_response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,24 @@ def test_fetch_binary_and_binary_size
end
end

test "APPENDUID with parser_use_deprecated_uidplus_data = true" do
parser = Net::IMAP::ResponseParser.new(config: {
parser_use_deprecated_uidplus_data: true,
})
response = parser.parse("A004 OK [APPENDUID 1 101:200] Done\r\n")
uidplus = response.data.code.data
assert_instance_of Net::IMAP::UIDPlusData, uidplus
assert_equal 100, uidplus.assigned_uids.size
end

test "APPENDUID with parser_use_deprecated_uidplus_data = false" do
parser = Net::IMAP::ResponseParser.new(config: {
parser_use_deprecated_uidplus_data: false,
})
response = parser.parse("A004 OK [APPENDUID 1 10] Done\r\n")
assert_instance_of Net::IMAP::AppendUIDData, response.data.code.data
end

test "COPYUID with backwards ranges" do
parser = Net::IMAP::ResponseParser.new
response = parser.parse(
Expand Down Expand Up @@ -241,4 +259,23 @@ def test_fetch_binary_and_binary_size
end
end

test "COPYUID with parser_use_deprecated_uidplus_data = true" do
parser = Net::IMAP::ResponseParser.new(config: {
parser_use_deprecated_uidplus_data: true,
})
response = parser.parse("A004 OK [copyUID 1 101:200 1:100] Done\r\n")
uidplus = response.data.code.data
assert_instance_of Net::IMAP::UIDPlusData, uidplus
assert_equal 100, uidplus.assigned_uids.size
assert_equal 100, uidplus.source_uids.size
end

test "COPYUID with parser_use_deprecated_uidplus_data = false" do
parser = Net::IMAP::ResponseParser.new(config: {
parser_use_deprecated_uidplus_data: false,
})
response = parser.parse("A004 OK [COPYUID 1 101 1] Done\r\n")
assert_instance_of Net::IMAP::CopyUIDData, response.data.code.data
end

end

0 comments on commit 60f5776

Please sign in to comment.