Skip to content

Commit 4c601c3

Browse files
committed
✨ Add AppendUIDData (to replace UIDPlusData)
1 parent f1e7433 commit 4c601c3

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

lib/net/imap/response_data.rb

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class IMAP < Protocol
66
autoload :SearchResult, "#{__dir__}/search_result"
77
autoload :SequenceSet, "#{__dir__}/sequence_set"
88
autoload :UIDPlusData, "#{__dir__}/uidplus_data"
9+
autoload :AppendUIDData, "#{__dir__}/uidplus_data"
910

1011
# Net::IMAP::ContinuationRequest represents command continuation requests.
1112
#

lib/net/imap/uidplus_data.rb

+39
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,44 @@ def uid_mapping
6060
end
6161
end
6262

63+
# AppendUIDData represents the ResponseCode#data that accompanies the
64+
# +APPENDUID+ {response code}[rdoc-ref:ResponseCode].
65+
#
66+
# A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send
67+
# AppendUIDData inside every TaggedResponse returned by the
68+
# append[rdoc-ref:Net::IMAP#append] command---unless the target mailbox
69+
# reports +UIDNOTSTICKY+.
70+
#
71+
# == Required capability
72+
# Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
73+
# or +IMAP4rev2+ capability.
74+
class AppendUIDData < Data.define(:uidvalidity, :assigned_uids)
75+
def initialize(uidvalidity:, assigned_uids:)
76+
uidvalidity = Integer(uidvalidity)
77+
assigned_uids = SequenceSet[assigned_uids]
78+
NumValidator.ensure_nz_number(uidvalidity)
79+
if assigned_uids.include_star?
80+
raise DataFormatError, "uid-set cannot contain '*'"
81+
end
82+
super
83+
end
84+
85+
##
86+
# attr_reader: uidvalidity
87+
# :call-seq: uidvalidity -> nonzero uint32
88+
#
89+
# The UIDVALIDITY of the destination mailbox.
90+
91+
##
92+
# attr_reader: assigned_uids
93+
#
94+
# A SequenceSet with the newly assigned UIDs of the appended messages.
95+
96+
# Returns the number of messages that have been appended.
97+
def size
98+
assigned_uids.count_with_duplicates
99+
end
100+
end
101+
63102
end
64103
end

test/net/imap/test_uidplus_data.rb

+36
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,39 @@ class TestUIDPlusData < Test::Unit::TestCase
4444
end
4545

4646
end
47+
48+
class TestAppendUIDData < Test::Unit::TestCase
49+
# alias for convenience
50+
AppendUIDData = Net::IMAP::AppendUIDData
51+
SequenceSet = Net::IMAP::SequenceSet
52+
DataFormatError = Net::IMAP::DataFormatError
53+
UINT32_MAX = 2**32 - 1
54+
55+
test "#uidvalidity must be valid nz-number" do
56+
assert_equal 1, AppendUIDData.new(1, 99).uidvalidity
57+
assert_equal UINT32_MAX, AppendUIDData.new(UINT32_MAX, 1).uidvalidity
58+
assert_raise DataFormatError do AppendUIDData.new(0, 1) end
59+
assert_raise DataFormatError do AppendUIDData.new(2**32, 1) end
60+
end
61+
62+
test "#assigned_uids must be a valid uid-set" do
63+
assert_equal SequenceSet[1], AppendUIDData.new(99, "1").assigned_uids
64+
assert_equal SequenceSet[1..9], AppendUIDData.new(1, "1:9").assigned_uids
65+
assert_equal(SequenceSet[UINT32_MAX],
66+
AppendUIDData.new(1, UINT32_MAX.to_s).assigned_uids)
67+
assert_raise DataFormatError do AppendUIDData.new(1, 0) end
68+
assert_raise DataFormatError do AppendUIDData.new(1, "*") end
69+
assert_raise DataFormatError do AppendUIDData.new(1, "1:*") end
70+
end
71+
72+
test "#size returns the number of UIDs" do
73+
assert_equal(10, AppendUIDData.new(1, "1:10").size)
74+
assert_equal(4_000_000_000, AppendUIDData.new(1, 1..4_000_000_000).size)
75+
end
76+
77+
test "#assigned_uids is converted to SequenceSet" do
78+
assert_equal SequenceSet[1], AppendUIDData.new(99, "1").assigned_uids
79+
assert_equal SequenceSet[1..4], AppendUIDData.new(1, [1, 2, 3, 4]).assigned_uids
80+
end
81+
82+
end

0 commit comments

Comments
 (0)