💥 Replace MessageSet with SequenceSet #282
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There are some small differences in how
MessageSet
andSequenceSet
behave. I'll add a backward incompatibility warning to the release notes.But, although the following list of changes does seem long, I don't think the changes should break much (if any) existing code. Most of the changes are bugfixes or allow something new to work that didn't work before.
These are the differences that I've noted (there may be others):
Validation
SequenceSet does almost all of its validation during construction. The only invalid SequenceSet is an empty SequenceSet. MessageSet only validates when
validate
is called. In practice, this shouldn't make much of a difference.MessageSet does not validate ranges at all. This can result in exceptions while sending the data, which might leave the connection in a weird state, with a partially sent command. It can also result in invalid ranges being sent, e.g:
MessageSet.new("foo".."bar")
.Invalid inputs to MessageSet
Fail to validate
Some values can be formatted by MessageSet, but raise an exception when validating. SequenceSet allows these:
-1
by itself or in array (MessageSet only allows -1 to validate in a range)Fail to validate or format
SequenceSet allows inputs that MessageSet doesn't:
Set
of numbers ornz-number
formatted strings*
can be input as a Symbol, in addition to a string or-1
Range
nz-number
formatted strings,:*
, or"*"
"1:#{range.end}"
"#{range.begin}:*"
Net::IMAP::SearchResult
implements#to_sequence_set
Buggy MessageSet formatting
The MessageSet handling for
Net::IMAP::ThreadMember
is not quite right, and it has no tests.ThreadMember#to_sequence_set
has a test that covers these bugs, and I believe it has the correct behavior.Since ranges are not validated, and integers aren't re-validated during formatting, zero and negative numbers in a range will be output directly. Only
-1
is special-cased.Invalid inputs to SequenceSet
SequenceSet raises an exception for backwards ranges, e.g:
5..3
or-1..55
. While these are syntactically similar to IMAPsequence-set
, the semantics are very different:5:3
is the same as3,4,5
(5..3).to_a
is empty.Normalization
Normalized form is semantically equivalent, except when the order of entries is significant.
Note that
Net::IMAP::UIDPlusData
still uses arrays instead ofSequenceSet
, andNet::IMAP::ResponseParser
preserves any response'ssequence-set
order.