@@ -537,7 +537,7 @@ module Net
537537 # ==== RFC9394: +PARTIAL+
538538 # - Updates #search, #uid_search with the +PARTIAL+ return option which adds
539539 # ESearchResult#partial return data.
540- # - TODO: Updates #uid_fetch with the +partial+ modifier.
540+ # - Updates #uid_fetch with the +partial+ modifier.
541541 #
542542 # == References
543543 #
@@ -2439,7 +2439,7 @@ def fetch(...)
24392439 end
24402440
24412441 # :call-seq:
2442- # uid_fetch(set, attr, changedsince: nil) -> array of FetchData
2442+ # uid_fetch(set, attr, changedsince: nil, partial: nil ) -> array of FetchData
24432443 #
24442444 # Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
24452445 # to retrieve data associated with a message in the mailbox.
@@ -2456,11 +2456,42 @@ def fetch(...)
24562456 #
24572457 # +changedsince+ (optional) behaves the same as with #fetch.
24582458 #
2459+ # +partial+ is an optional range to limit the number of results returned.
2460+ # It's useful when +set+ contains an unknown number of messages.
2461+ # <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
2462+ # order), <tt>501..1000</tt> the second 500, and so on. +partial+ may also
2463+ # be negative: <tt>-500..-1</tt> selects the last 500 messages in +set+.
2464+ # <em>Requires the +PARTIAL+ capabability.</em>
2465+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
2466+ #
2467+ # For example:
2468+ #
2469+ # # Without partial, the size of the results may be unknown beforehand:
2470+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS))
2471+ # # ... maybe wait for a long time ... and allocate a lot of memory ...
2472+ # results.size # => 0..2**32-1
2473+ # process results # may also take a long time and use a lot of memory...
2474+ #
2475+ # # Using partial, the results may be paginated:
2476+ # loop do
2477+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS),
2478+ # partial: 1..500)
2479+ # # fetch should return quickly and allocate little memory
2480+ # results.size # => 0..500
2481+ # break if results.empty?
2482+ # next_uid_to_fetch = results.last.uid + 1
2483+ # process results
2484+ # end
2485+ #
24592486 # Related: #fetch, FetchData
24602487 #
24612488 # ==== Capabilities
24622489 #
2463- # Same as #fetch.
2490+ # The server's capabilities must include +PARTIAL+
2491+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
2492+ # +partial+ argument.
2493+ #
2494+ # Otherwise, the same as #fetch.
24642495 def uid_fetch ( ...)
24652496 fetch_internal ( "UID FETCH" , ...)
24662497 end
@@ -3435,8 +3466,12 @@ def search_internal(cmd, ...)
34353466 end
34363467 end
34373468
3438- def fetch_internal ( cmd , set , attr , mod = nil , changedsince : nil )
3469+ def fetch_internal ( cmd , set , attr , mod = nil , partial : nil , changedsince : nil )
34393470 set = SequenceSet [ set ]
3471+ if partial
3472+ mod ||= [ ]
3473+ mod << "PARTIAL" << partial_range ( partial )
3474+ end
34403475 if changedsince
34413476 mod ||= [ ]
34423477 mod << "CHANGEDSINCE" << Integer ( changedsince )
0 commit comments