Skip to content

Commit 7e7f9bb

Browse files
committed
✨ Convert symbols & ranges in search return opts
1 parent d8a2e6c commit 7e7f9bb

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

lib/net/imap.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,9 @@ def uid_expunge(uid_set)
20202020
# ==== Argument translation
20212021
#
20222022
# [+return+ options]
2023-
# Must be an Array. Return option names are strings.
2023+
# Must be an Array. Return option names may be either strings or symbols.
2024+
# +Range+ elements which begin and end with negative integers are encoded
2025+
# for use with +PARTIAL+--any other ranges are converted to SequenceSet.
20242026
# Unlike +criteria+, other return option arguments are not automatically
20252027
# converted to SequenceSet.
20262028
#
@@ -3294,10 +3296,28 @@ def search_args(keys, charset_arg = nil, return: nil, charset: nil)
32943296
end
32953297

32963298
def convert_return_opts(unconverted)
3297-
Array.try_convert(unconverted) or
3299+
return_opts = Array.try_convert(unconverted) or
32983300
raise TypeError, "expected return options to be Array, got %s" % [
32993301
unconverted.class
33003302
]
3303+
return_opts.map {|opt|
3304+
case opt
3305+
when Symbol then opt.to_s
3306+
when Range then partial_range_last_or_seqset(opt)
3307+
else opt
3308+
end
3309+
}
3310+
end
3311+
3312+
def partial_range_last_or_seqset(range)
3313+
case [range.begin, range.end]
3314+
in [Integer => first, Integer => last] if first.negative? && last.negative?
3315+
# partial-range-last [RFC9394]
3316+
first <= last or raise DataFormatError, "empty range: %p" % [range]
3317+
"#{first}:#{last}"
3318+
else
3319+
SequenceSet[range]
3320+
end
33013321
end
33023322

33033323
def search_internal(cmd, ...)

test/net/imap/test_imap.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,18 @@ def seqset_coercible.to_sequence_set
12771277
)
12781278
cmd = server.commands.pop
12791279
assert_equal "RETURN (PARTIAL -500:-1) UID 1234:*", cmd.args
1280+
1281+
assert_equal search_result, imap.search(
1282+
["UID", 1234..], return: [:PARTIAL, "-500:-1"]
1283+
)
1284+
cmd = server.commands.pop
1285+
assert_equal "RETURN (PARTIAL -500:-1) UID 1234:*", cmd.args
1286+
1287+
assert_equal search_result, imap.search(
1288+
["UID", 1234..], return: [:PARTIAL, -500..-1, :FOO, 1..]
1289+
)
1290+
cmd = server.commands.pop
1291+
assert_equal "RETURN (PARTIAL -500:-1 FOO 1:*) UID 1234:*", cmd.args
12801292
end
12811293
end
12821294

0 commit comments

Comments
 (0)