Skip to content

Commit

Permalink
✨ Add AppendUIDData (to replace UIDPlusData)
Browse files Browse the repository at this point in the history
  • Loading branch information
nevans committed Feb 6, 2025
1 parent 85d0aa2 commit 01bb49f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/net/imap/response_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
39 changes: 39 additions & 0 deletions lib/net/imap/uidplus_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
36 changes: 36 additions & 0 deletions test/net/imap/test_uidplus_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 01bb49f

Please sign in to comment.