net-imap 0.5.9 → 0.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/lib/net/imap/config/attr_type_coercion.rb +19 -6
- data/lib/net/imap/esearch_result.rb +42 -3
- data/lib/net/imap/flags.rb +1 -1
- data/lib/net/imap/search_result.rb +2 -3
- data/lib/net/imap/sequence_set.rb +94 -28
- data/lib/net/imap/vanished_data.rb +10 -1
- data/lib/net/imap.rb +18 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7f77489a5f69bb5cf159039328259e7a0e52d18453b8777ab312b7051ec0542
|
4
|
+
data.tar.gz: d2417b81c84dd93424983354ed42995bfc5af9ac30c8c115c75595a7746e5fc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d20e857ab3284f3c2748da9b7324909d99f87cf8bfe52f44f2e77ba49154a34d39f3008106388e8c2cc644b83a72a1c71ef042617b780173a8dbb49e2c11bc6f
|
7
|
+
data.tar.gz: a60ec27b5db745e3b77d7e9aa2fb75091941a84b4a6b39bf27bfd640361ca082b1861f3828efdfc31fa54090b3f851b68ba8cf5f11def050a4c49b319ce0b42d
|
data/Gemfile
CHANGED
@@ -16,6 +16,7 @@ gem "test-unit-ruby-core", git: "https://github.com/ruby/test-unit-ruby-core"
|
|
16
16
|
|
17
17
|
gem "benchmark", require: false
|
18
18
|
gem "benchmark-driver", require: false
|
19
|
+
gem "vernier", require: false, platform: :mri
|
19
20
|
|
20
21
|
group :test do
|
21
22
|
gem "simplecov", require: false
|
@@ -28,10 +28,22 @@ module Net
|
|
28
28
|
end
|
29
29
|
private_class_method :included
|
30
30
|
|
31
|
-
if defined?(Ractor.
|
32
|
-
def self.safe(
|
31
|
+
if defined?(Ractor.shareable_proc)
|
32
|
+
def self.safe(&b)
|
33
|
+
case obj = b.call
|
34
|
+
when Proc
|
35
|
+
Ractor.shareable_proc(&obj)
|
36
|
+
else
|
37
|
+
Ractor.make_shareable obj
|
38
|
+
end
|
39
|
+
end
|
40
|
+
elsif defined?(Ractor.make_shareable)
|
41
|
+
def self.safe(&b)
|
42
|
+
obj = nil.instance_eval(&b).freeze
|
43
|
+
Ractor.make_shareable obj
|
44
|
+
end
|
33
45
|
else
|
34
|
-
def self.safe(
|
46
|
+
def self.safe(&b) nil.instance_eval(&b).freeze end
|
35
47
|
end
|
36
48
|
private_class_method :safe
|
37
49
|
|
@@ -48,10 +60,11 @@ module Net
|
|
48
60
|
NilOrInteger = safe{->val { Integer val unless val.nil? }}
|
49
61
|
|
50
62
|
Enum = ->(*enum) {
|
51
|
-
|
52
|
-
|
63
|
+
sh_enum = Ractor.make_shareable(enum)
|
64
|
+
safe_enum = safe{sh_enum}
|
65
|
+
expected = -"one of #{safe_enum.map(&:inspect).join(", ")}"
|
53
66
|
safe{->val {
|
54
|
-
return val if
|
67
|
+
return val if safe_enum.include?(val)
|
55
68
|
raise ArgumentError, "expected %s, got %p" % [expected, val]
|
56
69
|
}}
|
57
70
|
}
|
@@ -39,12 +39,49 @@ module Net
|
|
39
39
|
# numbers or UIDs, +to_a+ returns that set as an array of integers.
|
40
40
|
#
|
41
41
|
# When both #all and #partial are +nil+, either because the server
|
42
|
-
# returned no results or because +ALL+
|
43
|
-
# the IMAP#search +RETURN+ options, #to_a returns an empty array.
|
42
|
+
# returned no results or because neither +ALL+ or +PARTIAL+ were included
|
43
|
+
# in the IMAP#search +RETURN+ options, #to_a returns an empty array.
|
44
44
|
#
|
45
45
|
# Note that SearchResult also implements +to_a+, so it can be used without
|
46
46
|
# checking if the server returned +SEARCH+ or +ESEARCH+ data.
|
47
|
-
|
47
|
+
#
|
48
|
+
# Related: #each, #to_sequence_set, #all, #partial
|
49
|
+
def to_a; to_sequence_set.numbers end
|
50
|
+
|
51
|
+
# :call-seq: to_sequence_set -> SequenceSet or nil
|
52
|
+
#
|
53
|
+
# When either #all or #partial contains a SequenceSet of message sequence
|
54
|
+
# numbers or UIDs, +to_sequence_set+ returns that sequence set.
|
55
|
+
#
|
56
|
+
# When both #all and #partial are +nil+, either because the server
|
57
|
+
# returned no results or because neither +ALL+ or +PARTIAL+ were included
|
58
|
+
# in the IMAP#search +RETURN+ options, #to_sequence_set returns
|
59
|
+
# SequenceSet.empty.
|
60
|
+
#
|
61
|
+
# Note that SearchResult also implements +to_sequence_set+, so it can be
|
62
|
+
# used without checking if the server returned +SEARCH+ or +ESEARCH+ data.
|
63
|
+
#
|
64
|
+
# Related: #each, #to_a, #all, #partial
|
65
|
+
def to_sequence_set
|
66
|
+
all || partial&.to_sequence_set || SequenceSet.empty
|
67
|
+
end
|
68
|
+
|
69
|
+
# When either #all or #partial contains a SequenceSet of message sequence
|
70
|
+
# numbers or UIDs, +each+ yields each integer in the set.
|
71
|
+
#
|
72
|
+
# When both #all and #partial are +nil+, either because the server
|
73
|
+
# returned no results or because +ALL+ and +PARTIAL+ were not included in
|
74
|
+
# the IMAP#search +RETURN+ options, #each does not yield.
|
75
|
+
#
|
76
|
+
# Note that SearchResult also implements +#each+, so it can be used
|
77
|
+
# without checking if the server returned +SEARCH+ or +ESEARCH+ data.
|
78
|
+
#
|
79
|
+
# Related: #to_sequence_set, #to_a, #all, #partial
|
80
|
+
def each(&)
|
81
|
+
return to_enum(__callee__) unless block_given?
|
82
|
+
to_sequence_set.each_number(&)
|
83
|
+
self
|
84
|
+
end
|
48
85
|
|
49
86
|
##
|
50
87
|
# attr_reader: tag
|
@@ -161,6 +198,8 @@ module Net
|
|
161
198
|
#
|
162
199
|
# See also: ESearchResult#to_a.
|
163
200
|
def to_a; results&.numbers || [] end
|
201
|
+
|
202
|
+
alias to_sequence_set results
|
164
203
|
end
|
165
204
|
|
166
205
|
# :call-seq: partial -> PartialResult or nil
|
data/lib/net/imap/flags.rb
CHANGED
@@ -60,9 +60,8 @@ module Net
|
|
60
60
|
# [3, 5, 7] == Net::IMAP::SearchResult[3, 5, 7, modseq: 99] # => true
|
61
61
|
#
|
62
62
|
def ==(other)
|
63
|
-
(
|
64
|
-
|
65
|
-
other.is_a?(Array)) &&
|
63
|
+
other.is_a?(Array) &&
|
64
|
+
modseq == (other.modseq if other.respond_to?(:modseq)) &&
|
66
65
|
size == other.size &&
|
67
66
|
sort == other.sort
|
68
67
|
end
|
@@ -84,7 +84,7 @@ module Net
|
|
84
84
|
#
|
85
85
|
# # Other inputs are normalized
|
86
86
|
# set = Net::IMAP::SequenceSet([1, 2, [3..7, 5], 6..10, 2048, 1024])
|
87
|
-
# set.valid_string #=> "1:10,
|
87
|
+
# set.valid_string #=> "1:10,1024,2048"
|
88
88
|
# set.frozen? #=> false
|
89
89
|
#
|
90
90
|
# unfrozen = set
|
@@ -107,7 +107,7 @@ module Net
|
|
107
107
|
#
|
108
108
|
# # Other inputs are normalized
|
109
109
|
# set = Net::IMAP::SequenceSet[1, 2, [3..7, 5], 6..10, 2048, 1024]
|
110
|
-
# set.valid_string #=> "1:10,
|
110
|
+
# set.valid_string #=> "1:10,1024,2048"
|
111
111
|
# set.frozen? #=> true
|
112
112
|
#
|
113
113
|
# frozen = set
|
@@ -396,6 +396,23 @@ module Net
|
|
396
396
|
STARS = [:*, ?*, -1].freeze
|
397
397
|
private_constant :STARS
|
398
398
|
|
399
|
+
INSPECT_MAX_LEN = 512
|
400
|
+
INSPECT_TRUNCATE_LEN = 16
|
401
|
+
private_constant :INSPECT_MAX_LEN, :INSPECT_TRUNCATE_LEN
|
402
|
+
|
403
|
+
# /(,\d+){100}\z/ is shockingly slow on huge strings.
|
404
|
+
# /(,\d{0,10}){100}\z/ is ok, but ironically, Regexp.linear_time? is false.
|
405
|
+
#
|
406
|
+
# This unrolls all nested quantifiers. It's much harder to read, but it's
|
407
|
+
# also the fastest out of all the versions I tested.
|
408
|
+
nz_uint32 = /[1-9](?:\d(?:\d(?:\d(?:\d(?:\d(?:\d(?:\d(?:\d(?:\d)?)?)?)?)?)?)?)?)?/
|
409
|
+
num_or_star = /#{nz_uint32}|\*/
|
410
|
+
entry = /#{num_or_star}(?::#{num_or_star})?/
|
411
|
+
entries = ([entry] * INSPECT_TRUNCATE_LEN).join(",")
|
412
|
+
INSPECT_ABRIDGED_HEAD_RE = /\A#{entries},/
|
413
|
+
INSPECT_ABRIDGED_TAIL_RE = /,#{entries}\z/
|
414
|
+
private_constant :INSPECT_ABRIDGED_HEAD_RE, :INSPECT_ABRIDGED_TAIL_RE
|
415
|
+
|
399
416
|
class << self
|
400
417
|
|
401
418
|
# :call-seq:
|
@@ -427,14 +444,14 @@ module Net
|
|
427
444
|
# +to_sequence_set+, calls +obj.to_sequence_set+ and returns the result.
|
428
445
|
# Otherwise returns +nil+.
|
429
446
|
#
|
430
|
-
# If +obj.to_sequence_set+ doesn't return a SequenceSet
|
431
|
-
# raised.
|
447
|
+
# If +obj.to_sequence_set+ doesn't return a SequenceSet or +nil+, an
|
448
|
+
# exception is raised.
|
432
449
|
#
|
433
450
|
# Related: Net::IMAP::SequenceSet(), ::new, ::[]
|
434
451
|
def try_convert(obj)
|
435
452
|
return obj if obj.is_a?(SequenceSet)
|
436
453
|
return nil unless obj.respond_to?(:to_sequence_set)
|
437
|
-
obj = obj.to_sequence_set
|
454
|
+
return nil unless obj = obj.to_sequence_set
|
438
455
|
return obj if obj.is_a?(SequenceSet)
|
439
456
|
raise DataFormatError, "invalid object returned from to_sequence_set"
|
440
457
|
end
|
@@ -465,7 +482,7 @@ module Net
|
|
465
482
|
# set = Net::IMAP::SequenceSet.new("1,2,3:7,5,6:10,2048,1024")
|
466
483
|
# set.valid_string #=> "1,2,3:7,5,6:10,2048,1024"
|
467
484
|
# set = Net::IMAP::SequenceSet.new(1, 2, 3..7, 5, 6..10, 2048, 1024)
|
468
|
-
# set.valid_string #=> "1:10,
|
485
|
+
# set.valid_string #=> "1:10,1024,2048"
|
469
486
|
#
|
470
487
|
# With no arguments (or +nil+) creates an empty sequence set. Note that
|
471
488
|
# an empty sequence set is invalid in the \IMAP grammar.
|
@@ -530,7 +547,10 @@ module Net
|
|
530
547
|
# accepted by ::new.
|
531
548
|
def replace(other)
|
532
549
|
case other
|
533
|
-
when SequenceSet then
|
550
|
+
when SequenceSet then
|
551
|
+
modifying! # short circuit before doing any work
|
552
|
+
@tuples = other.deep_copy_tuples
|
553
|
+
@string = other.instance_variable_get(:@string)
|
534
554
|
when String then self.string = other
|
535
555
|
else clear; merge other
|
536
556
|
end
|
@@ -559,29 +579,31 @@ module Net
|
|
559
579
|
# If the set was created from a single string, it is not normalized. If
|
560
580
|
# the set is updated the string will be normalized.
|
561
581
|
#
|
562
|
-
# Related: #valid_string, #normalized_string, #to_s
|
582
|
+
# Related: #valid_string, #normalized_string, #to_s, #inspect
|
563
583
|
def string; @string ||= normalized_string if valid? end
|
564
584
|
|
565
585
|
# Returns an array with #normalized_string when valid and an empty array
|
566
586
|
# otherwise.
|
567
587
|
def deconstruct; valid? ? [normalized_string] : [] end
|
568
588
|
|
569
|
-
# Assigns a new string to #string and resets #elements to match.
|
570
|
-
#
|
571
|
-
#
|
589
|
+
# Assigns a new string to #string and resets #elements to match.
|
590
|
+
# Assigning +nil+ or an empty string are equivalent to calling #clear.
|
591
|
+
#
|
592
|
+
# Non-empty strings are validated but not normalized.
|
572
593
|
#
|
573
|
-
# Use #add or #
|
594
|
+
# Use #add, #merge, or #append to add a string to an existing set.
|
574
595
|
#
|
575
596
|
# Related: #replace, #clear
|
576
|
-
def string=(
|
577
|
-
if
|
597
|
+
def string=(input)
|
598
|
+
if input.nil?
|
578
599
|
clear
|
579
|
-
|
580
|
-
modifying! #
|
581
|
-
str = String.try_convert(str) or raise ArgumentError, "not a string"
|
600
|
+
elsif (str = String.try_convert(input))
|
601
|
+
modifying! # short-circuit before parsing the string
|
582
602
|
tuples = str_to_tuples str
|
583
603
|
@tuples, @string = [], -str
|
584
604
|
tuples_add tuples
|
605
|
+
else
|
606
|
+
raise ArgumentError, "expected a string or nil, got #{input.class}"
|
585
607
|
end
|
586
608
|
str
|
587
609
|
end
|
@@ -590,7 +612,7 @@ module Net
|
|
590
612
|
# string when the set is empty. Note that an empty set is invalid in the
|
591
613
|
# \IMAP syntax.
|
592
614
|
#
|
593
|
-
# Related: #valid_string, #normalized_string, #
|
615
|
+
# Related: #string, #valid_string, #normalized_string, #inspect
|
594
616
|
def to_s; string || "" end
|
595
617
|
|
596
618
|
# Freezes and returns the set. A frozen SequenceSet is Ractor-safe.
|
@@ -1623,21 +1645,60 @@ module Net
|
|
1623
1645
|
#
|
1624
1646
|
# Returns +nil+ when the set is empty.
|
1625
1647
|
#
|
1626
|
-
# Related: #normalize!, #normalize
|
1648
|
+
# Related: #normalize!, #normalize, #string, #to_s
|
1627
1649
|
def normalized_string
|
1628
1650
|
@tuples.empty? ? nil : -@tuples.map { tuple_to_str _1 }.join(",")
|
1629
1651
|
end
|
1630
1652
|
|
1653
|
+
# Returns an inspection string for the SequenceSet.
|
1654
|
+
#
|
1655
|
+
# Net::IMAP::SequenceSet.new.inspect
|
1656
|
+
# #=> "Net::IMAP::SequenceSet()"
|
1657
|
+
#
|
1658
|
+
# Net::IMAP::SequenceSet(1..5, 1024, 15, 2000).inspect
|
1659
|
+
# #=> 'Net::IMAP::SequenceSet("1:5,15,1024,2000")'
|
1660
|
+
#
|
1661
|
+
# Frozen sets have slightly different output:
|
1662
|
+
#
|
1663
|
+
# Net::IMAP::SequenceSet.empty.inspect
|
1664
|
+
# #=> "Net::IMAP::SequenceSet.empty"
|
1665
|
+
#
|
1666
|
+
# Net::IMAP::SequenceSet[1..5, 1024, 15, 2000].inspect
|
1667
|
+
# #=> 'Net::IMAP::SequenceSet["1:5,15,1024,2000"]'
|
1668
|
+
#
|
1669
|
+
# Large sets (by number of #entries) have abridged output, with only the
|
1670
|
+
# first and last entries:
|
1671
|
+
#
|
1672
|
+
# Net::IMAP::SequenceSet(((1..5000) % 2).to_a).inspect
|
1673
|
+
# #=> #<Net::IMAP::SequenceSet 2500 entries "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,...(2468 entries omitted)...,4969,4971,4973,4975,4977,4979,4981,4983,4985,4987,4989,4991,4993,4995,4997,4999">
|
1674
|
+
#
|
1675
|
+
# Related: #to_s, #string
|
1631
1676
|
def inspect
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1677
|
+
case (count = count_entries)
|
1678
|
+
when 0
|
1679
|
+
(frozen? ? "%s.empty" : "%s()") % [self.class]
|
1680
|
+
when ..INSPECT_MAX_LEN
|
1681
|
+
(frozen? ? "%s[%p]" : "%s(%p)") % [self.class, to_s]
|
1636
1682
|
else
|
1637
|
-
|
1683
|
+
if @string
|
1684
|
+
head = @string[INSPECT_ABRIDGED_HEAD_RE]
|
1685
|
+
tail = @string[INSPECT_ABRIDGED_TAIL_RE]
|
1686
|
+
else
|
1687
|
+
head = export_string_entries(@tuples.first(INSPECT_TRUNCATE_LEN)) + ","
|
1688
|
+
tail = "," + export_string_entries(@tuples.last(INSPECT_TRUNCATE_LEN))
|
1689
|
+
end
|
1690
|
+
'#<%s %d entries "%s...(%d entries omitted)...%s"%s>' % [
|
1691
|
+
self.class, count,
|
1692
|
+
head, count - INSPECT_TRUNCATE_LEN * 2, tail,
|
1693
|
+
frozen? ? " (frozen)" : "",
|
1694
|
+
]
|
1638
1695
|
end
|
1639
1696
|
end
|
1640
1697
|
|
1698
|
+
private def count_entries
|
1699
|
+
@string ? @string.count(",") + 1 : @tuples.count
|
1700
|
+
end
|
1701
|
+
|
1641
1702
|
##
|
1642
1703
|
# :method: to_sequence_set
|
1643
1704
|
# :call-seq: to_sequence_set -> self
|
@@ -1676,6 +1737,8 @@ module Net
|
|
1676
1737
|
|
1677
1738
|
attr_reader :tuples # :nodoc:
|
1678
1739
|
|
1740
|
+
def deep_copy_tuples; @tuples.map { _1.dup } end # :nodoc:
|
1741
|
+
|
1679
1742
|
private
|
1680
1743
|
|
1681
1744
|
def remain_frozen(set) frozen? ? set.freeze : set end
|
@@ -1683,13 +1746,12 @@ module Net
|
|
1683
1746
|
|
1684
1747
|
# frozen clones are shallow copied
|
1685
1748
|
def initialize_clone(other)
|
1686
|
-
other.
|
1749
|
+
@tuples = other.deep_copy_tuples unless other.frozen?
|
1750
|
+
super
|
1687
1751
|
end
|
1688
1752
|
|
1689
1753
|
def initialize_dup(other)
|
1690
|
-
|
1691
|
-
@tuples = other.tuples.map(&:dup)
|
1692
|
-
@string = other.string&.-@
|
1754
|
+
@tuples = other.deep_copy_tuples
|
1693
1755
|
super
|
1694
1756
|
end
|
1695
1757
|
|
@@ -1741,6 +1803,10 @@ module Net
|
|
1741
1803
|
def to_tuple_int(obj) STARS.include?(obj) ? STAR_INT : nz_number(obj) end
|
1742
1804
|
def from_tuple_int(num) num == STAR_INT ? :* : num end
|
1743
1805
|
|
1806
|
+
def export_string_entries(entries)
|
1807
|
+
-entries.map { tuple_to_str _1 }.join(",")
|
1808
|
+
end
|
1809
|
+
|
1744
1810
|
def tuple_to_str(tuple) tuple.uniq.map{ from_tuple_int _1 }.join(":") end
|
1745
1811
|
def str_to_tuples(str) str.split(",", -1).map! { str_to_tuple _1 } end
|
1746
1812
|
def str_to_tuple(str)
|
@@ -19,7 +19,7 @@ module Net
|
|
19
19
|
# * +uids+ will be converted by SequenceSet.[].
|
20
20
|
# * +earlier+ will be converted to +true+ or +false+
|
21
21
|
def initialize(uids:, earlier:)
|
22
|
-
uids = SequenceSet[uids]
|
22
|
+
uids = SequenceSet[uids] unless uids.equal? SequenceSet.empty
|
23
23
|
earlier = !!earlier
|
24
24
|
super
|
25
25
|
end
|
@@ -51,6 +51,15 @@ module Net
|
|
51
51
|
# See SequenceSet#numbers.
|
52
52
|
def to_a; uids.numbers end
|
53
53
|
|
54
|
+
# Yields each UID in #uids and returns +self+. Returns an Enumerator when
|
55
|
+
# no block is given.
|
56
|
+
#
|
57
|
+
# See SequenceSet#each_number.
|
58
|
+
def each(&)
|
59
|
+
return to_enum unless block_given?
|
60
|
+
uids.each_number(&)
|
61
|
+
self
|
62
|
+
end
|
54
63
|
end
|
55
64
|
end
|
56
65
|
end
|
data/lib/net/imap.rb
CHANGED
@@ -788,7 +788,7 @@ module Net
|
|
788
788
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
789
789
|
#
|
790
790
|
class IMAP < Protocol
|
791
|
-
VERSION = "0.5.
|
791
|
+
VERSION = "0.5.11"
|
792
792
|
|
793
793
|
# Aliases for supported capabilities, to be used with the #enable command.
|
794
794
|
ENABLE_ALIASES = {
|
@@ -2110,8 +2110,8 @@ module Net
|
|
2110
2110
|
end
|
2111
2111
|
|
2112
2112
|
# call-seq:
|
2113
|
-
# uid_expunge
|
2114
|
-
# uid_expunge
|
2113
|
+
# uid_expunge(uid_set) -> array of message sequence numbers
|
2114
|
+
# uid_expunge(uid_set) -> VanishedData of UIDs
|
2115
2115
|
#
|
2116
2116
|
# Sends a {UID EXPUNGE command [RFC4315 §2.1]}[https://www.rfc-editor.org/rfc/rfc4315#section-2.1]
|
2117
2117
|
# {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
|
@@ -2961,6 +2961,18 @@ module Net
|
|
2961
2961
|
# command parameters defined by the extension will implicitly enable it.
|
2962
2962
|
# See {[RFC7162 §3.1]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1].
|
2963
2963
|
#
|
2964
|
+
# [+QRESYNC+ {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html]]
|
2965
|
+
# *NOTE:* Enabling QRESYNC will replace +EXPUNGE+ with +VANISHED+, but
|
2966
|
+
# the extension arguments to #select, #examine, and #uid_fetch are not
|
2967
|
+
# supported yet.
|
2968
|
+
#
|
2969
|
+
# Adds quick resynchronization options to #select, #examine, and
|
2970
|
+
# #uid_fetch. +QRESYNC+ _must_ be explicitly enabled before using any of
|
2971
|
+
# the extension's command parameters. All +EXPUNGE+ responses will be
|
2972
|
+
# replaced with +VANISHED+ responses. Enabling +QRESYNC+ implicitly
|
2973
|
+
# enables +CONDSTORE+ as well.
|
2974
|
+
# See {[RFC7162 §3.2]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.2].
|
2975
|
+
#
|
2964
2976
|
# [+:utf8+ --- an alias for <tt>"UTF8=ACCEPT"</tt>]
|
2965
2977
|
#
|
2966
2978
|
# In a future release, <tt>enable(:utf8)</tt> will enable either
|
@@ -3672,6 +3684,9 @@ module Net
|
|
3672
3684
|
end
|
3673
3685
|
|
3674
3686
|
def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
|
3687
|
+
if partial && !cmd.start_with?("UID ")
|
3688
|
+
raise ArgumentError, "partial can only be used with uid_fetch"
|
3689
|
+
end
|
3675
3690
|
set = SequenceSet[set]
|
3676
3691
|
if partial
|
3677
3692
|
mod ||= []
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-imap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
|
-
rubygems_version: 3.6.
|
132
|
+
rubygems_version: 3.6.9
|
133
133
|
specification_version: 4
|
134
134
|
summary: Ruby client api for Internet Message Access Protocol
|
135
135
|
test_files: []
|