From 01bb49f4ae3220a695e21314ba4d92a84fe64b35 Mon Sep 17 00:00:00 2001 From: nick evans Date: Wed, 5 Feb 2025 16:25:11 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20AppendUIDData=20(to=20replace?= =?UTF-8?q?=20UIDPlusData)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/response_data.rb | 1 + lib/net/imap/uidplus_data.rb | 39 ++++++++++++++++++++++++++++++ test/net/imap/test_uidplus_data.rb | 36 +++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/lib/net/imap/response_data.rb b/lib/net/imap/response_data.rb index 40586ebd..37f06c22 100644 --- a/lib/net/imap/response_data.rb +++ b/lib/net/imap/response_data.rb @@ -8,6 +8,7 @@ class IMAP < Protocol autoload :SearchResult, "#{__dir__}/search_result" autoload :SequenceSet, "#{__dir__}/sequence_set" autoload :UIDPlusData, "#{__dir__}/uidplus_data" + autoload :AppendUIDData, "#{__dir__}/uidplus_data" autoload :VanishedData, "#{__dir__}/vanished_data" # Net::IMAP::ContinuationRequest represents command continuation requests. diff --git a/lib/net/imap/uidplus_data.rb b/lib/net/imap/uidplus_data.rb index 687e34c7..dae0bf01 100644 --- a/lib/net/imap/uidplus_data.rb +++ b/lib/net/imap/uidplus_data.rb @@ -60,5 +60,44 @@ def uid_mapping end end + # AppendUIDData represents the ResponseCode#data that accompanies the + # +APPENDUID+ {response code}[rdoc-ref:ResponseCode]. + # + # A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send + # AppendUIDData inside every TaggedResponse returned by the + # append[rdoc-ref:Net::IMAP#append] command---unless the target mailbox + # reports +UIDNOTSTICKY+. + # + # == Required capability + # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]] + # or +IMAP4rev2+ capability. + class AppendUIDData < Data.define(:uidvalidity, :assigned_uids) + def initialize(uidvalidity:, assigned_uids:) + uidvalidity = Integer(uidvalidity) + assigned_uids = SequenceSet[assigned_uids] + NumValidator.ensure_nz_number(uidvalidity) + if assigned_uids.include_star? + raise DataFormatError, "uid-set cannot contain '*'" + end + super + end + + ## + # attr_reader: uidvalidity + # :call-seq: uidvalidity -> nonzero uint32 + # + # The UIDVALIDITY of the destination mailbox. + + ## + # attr_reader: assigned_uids + # + # A SequenceSet with the newly assigned UIDs of the appended messages. + + # Returns the number of messages that have been appended. + def size + assigned_uids.count_with_duplicates + end + end + end end diff --git a/test/net/imap/test_uidplus_data.rb b/test/net/imap/test_uidplus_data.rb index 210a000e..0d693ae9 100644 --- a/test/net/imap/test_uidplus_data.rb +++ b/test/net/imap/test_uidplus_data.rb @@ -44,3 +44,39 @@ class TestUIDPlusData < Test::Unit::TestCase end end + +class TestAppendUIDData < Test::Unit::TestCase + # alias for convenience + AppendUIDData = Net::IMAP::AppendUIDData + SequenceSet = Net::IMAP::SequenceSet + DataFormatError = Net::IMAP::DataFormatError + UINT32_MAX = 2**32 - 1 + + test "#uidvalidity must be valid nz-number" do + assert_equal 1, AppendUIDData.new(1, 99).uidvalidity + assert_equal UINT32_MAX, AppendUIDData.new(UINT32_MAX, 1).uidvalidity + assert_raise DataFormatError do AppendUIDData.new(0, 1) end + assert_raise DataFormatError do AppendUIDData.new(2**32, 1) end + end + + test "#assigned_uids must be a valid uid-set" do + assert_equal SequenceSet[1], AppendUIDData.new(99, "1").assigned_uids + assert_equal SequenceSet[1..9], AppendUIDData.new(1, "1:9").assigned_uids + assert_equal(SequenceSet[UINT32_MAX], + AppendUIDData.new(1, UINT32_MAX.to_s).assigned_uids) + assert_raise DataFormatError do AppendUIDData.new(1, 0) end + assert_raise DataFormatError do AppendUIDData.new(1, "*") end + assert_raise DataFormatError do AppendUIDData.new(1, "1:*") end + end + + test "#size returns the number of UIDs" do + assert_equal(10, AppendUIDData.new(1, "1:10").size) + assert_equal(4_000_000_000, AppendUIDData.new(1, 1..4_000_000_000).size) + end + + test "#assigned_uids is converted to SequenceSet" do + assert_equal SequenceSet[1], AppendUIDData.new(99, "1").assigned_uids + assert_equal SequenceSet[1..4], AppendUIDData.new(1, [1, 2, 3, 4]).assigned_uids + end + +end