Skip to content

Commit

Permalink
✨ Convert symbols & ranges in search return opts
Browse files Browse the repository at this point in the history
  • Loading branch information
nevans committed Dec 15, 2024
1 parent f401e79 commit 6fb461c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
24 changes: 22 additions & 2 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,9 @@ def uid_expunge(uid_set)
# ==== Argument translation
#
# [+return+ options]
# Must be an Array. Return option names are strings.
# Must be an Array. Return option names may be either strings or symbols.
# +Range+ elements which begin and end with negative integers are encoded
# for use with +PARTIAL+--any other ranges are converted to SequenceSet.
# Unlike +criteria+, other return option arguments are not automatically
# converted to SequenceSet.
#
Expand Down Expand Up @@ -3265,10 +3267,28 @@ def search_args(keys, charset_arg = nil, return: nil, charset: nil)
end

def convert_return_opts(unconverted)
Array.try_convert(unconverted) or
return_opts = Array.try_convert(unconverted) or
raise TypeError, "expected return options to be Array, got %s" % [
unconverted.class
]
return_opts.map {|opt|
case opt
when Symbol then opt.to_s
when Range then partial_range_last_or_seqset(opt)
else opt
end
}
end

def partial_range_last_or_seqset(range)
case [range.begin, range.end]
in [Integer => first, Integer => last] if first.negative? && last.negative?
# partial-range-last [RFC9394]
first <= last or raise DataFormatError, "empty range: %p" % [range]
"#{first}:#{last}"
else
SequenceSet[range]
end
end

def search_internal(cmd, ...)
Expand Down
12 changes: 12 additions & 0 deletions test/net/imap/test_imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,18 @@ def seqset_coercible.to_sequence_set
)
cmd = server.commands.pop
assert_equal "RETURN (PARTIAL -500:-1) UID 1234:*", cmd.args

assert_equal search_result, imap.search(
["UID", 1234..], return: [:PARTIAL, "-500:-1"]
)
cmd = server.commands.pop
assert_equal "RETURN (PARTIAL -500:-1) UID 1234:*", cmd.args

assert_equal search_result, imap.search(
["UID", 1234..], return: [:PARTIAL, -500..-1, :FOO, 1..]
)
cmd = server.commands.pop
assert_equal "RETURN (PARTIAL -500:-1 FOO 1:*) UID 1234:*", cmd.args
end
end

Expand Down

0 comments on commit 6fb461c

Please sign in to comment.