net-imap 0.6.7 → 0.6.8
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/.simplecov +0 -3
- data/Gemfile +1 -1
- data/Rakefile +36 -33
- data/lib/net/imap/config/attr_type_coercion.rb +14 -26
- data/lib/net/imap/response_parser/parser_utils.rb +1 -1
- data/lib/net/imap/sequence_set.rb +164 -46
- data/lib/net/imap/utils.rb +49 -0
- data/lib/net/imap.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9405d034ddfa540378feffe20b4818437ca73913b1d82663cdd56d341ca71553
|
|
4
|
+
data.tar.gz: 2df46e36cdb6fc77aa6c88838ae684f7c800b5a643b985880e95d802e912a2fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 554739baaaaa8b0406f729d56447a13d4ced84f33feba90a350851424624483a36765c40f00e34737fe602bd0bd43555a2f480d4f7d9a0af034f791c0c9e0b8a
|
|
7
|
+
data.tar.gz: '06596b9d2da38bbd53dcc0fd990b66b1af5ffbd52af52370b8366188899043f129e63aae7090054090f8a1b29b8e89e7c96402ffc0aa48101d7f95bf09419a96'
|
data/.simplecov
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
|
@@ -20,52 +20,55 @@ task "test:coverage:report" do
|
|
|
20
20
|
formatter SimpleCov::Formatter::HTMLFormatter
|
|
21
21
|
|
|
22
22
|
coverage(:line) do
|
|
23
|
-
minimum
|
|
23
|
+
minimum 95
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
minimum 98, per: group("Config")
|
|
26
|
+
minimum 97, per: group("StringPrep")
|
|
27
|
+
minimum 97, per: group("SASL")
|
|
28
|
+
minimum 95, per: group("Data Types")
|
|
29
|
+
minimum 94, per: group("Parser")
|
|
30
|
+
minimum 92, per: group("Client")
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
minimum 80, per: :file
|
|
33
|
+
minimum 55, per: "lib/net/imap/search_result.rb"
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# NOTE: branch coverage varies more widely between ruby versions
|
|
37
37
|
coverage(:branch) do
|
|
38
|
-
|
|
38
|
+
# eval branch coverage varies too much between runtime environments
|
|
39
|
+
ignore :eval_generated
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
minimum_per_group 85, only: "Config"
|
|
42
|
-
minimum_per_group 80, only: "Client"
|
|
43
|
-
minimum_per_group 80, only: "Parser"
|
|
44
|
-
minimum_per_group 70, only: "SASL"
|
|
45
|
-
minimum_per_group 70, only: "StringPrep"
|
|
41
|
+
minimum 80
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
minimum 90, per: group("Data Types")
|
|
44
|
+
minimum 85, per: group("Config")
|
|
45
|
+
minimum 80, per: group("Client")
|
|
46
|
+
minimum 80, per: group("Parser")
|
|
47
|
+
minimum 70, per: group("SASL")
|
|
48
|
+
minimum 70, per: group("StringPrep")
|
|
49
|
+
|
|
50
|
+
minimum 60, per: :file
|
|
51
|
+
minimum 50, per: "lib/net/imap/sasl/authenticators.rb"
|
|
52
|
+
minimum 50, per: "lib/net/imap/config/attr_accessors.rb"
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
coverage(:method) do
|
|
53
|
-
minimum
|
|
56
|
+
minimum 88
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
minimum 100, per: group("Config")
|
|
59
|
+
minimum 90, per: group("Data Types")
|
|
60
|
+
minimum 90, per: group("StringPrep")
|
|
61
|
+
minimum 85, per: group("Client")
|
|
62
|
+
minimum 80, per: group("Parser")
|
|
63
|
+
minimum 80, per: group("SASL")
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
minimum 65, per: :file
|
|
66
|
+
minimum 60, per: "lib/net/imap/response_parser/parser_utils.rb"
|
|
67
|
+
minimum 55, per: "lib/net/imap/sasl/authenticators.rb"
|
|
68
|
+
minimum 50, per: "lib/net/imap/authenticators.rb"
|
|
69
|
+
minimum 50, per: "lib/net/imap/sasl/anonymous_authenticator.rb"
|
|
70
|
+
minimum 35, per: "lib/net/imap/sasl/protocol_adapters.rb"
|
|
71
|
+
minimum 20, per: "lib/net/imap/response_data.rb"
|
|
69
72
|
end
|
|
70
73
|
end
|
|
71
74
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../utils"
|
|
4
|
+
|
|
3
5
|
module Net
|
|
4
6
|
class IMAP
|
|
5
7
|
class Config
|
|
@@ -28,28 +30,14 @@ module Net
|
|
|
28
30
|
end
|
|
29
31
|
private_class_method :included
|
|
30
32
|
|
|
31
|
-
|
|
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
|
|
45
|
-
else
|
|
46
|
-
def self.safe(&b) nil.instance_eval(&b).freeze end
|
|
47
|
-
end
|
|
48
|
-
private_class_method :safe
|
|
33
|
+
extend Utils
|
|
49
34
|
|
|
50
|
-
Types = Hash.new do |h, type|
|
|
51
|
-
|
|
52
|
-
|
|
35
|
+
Types = Hash.new do |h, type|
|
|
36
|
+
type => Proc | nil
|
|
37
|
+
Utils.shareable{type}
|
|
38
|
+
end
|
|
39
|
+
Types[:boolean] = Boolean = shareable{-> {!!_1}}
|
|
40
|
+
Types[Integer] = shareable{->{Integer(_1)}}
|
|
53
41
|
|
|
54
42
|
def self.attr_accessor(attr, type: nil)
|
|
55
43
|
type = Types[type] or return
|
|
@@ -57,16 +45,16 @@ module Net
|
|
|
57
45
|
define_method :"#{attr}?" do send attr end if type == Boolean
|
|
58
46
|
end
|
|
59
47
|
|
|
60
|
-
NilOrInteger =
|
|
48
|
+
NilOrInteger = shareable{->val { Integer val unless val.nil? }}
|
|
61
49
|
|
|
62
|
-
Enum = ->(*enum) {
|
|
63
|
-
safe_enum =
|
|
50
|
+
Enum = shareable{->(*enum) {
|
|
51
|
+
safe_enum = Utils.shareable{enum}
|
|
64
52
|
expected = -"one of #{safe_enum.map(&:inspect).join(", ")}"
|
|
65
|
-
|
|
53
|
+
Utils.shareable{->val {
|
|
66
54
|
return val if safe_enum.include?(val)
|
|
67
55
|
raise ArgumentError, "expected %s, got %p" % [expected, val]
|
|
68
56
|
}}
|
|
69
|
-
}
|
|
57
|
+
}}
|
|
70
58
|
|
|
71
59
|
end
|
|
72
60
|
end
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require "set" unless defined?(::Set)
|
|
4
4
|
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
5
7
|
module Net
|
|
6
8
|
class IMAP
|
|
7
9
|
|
|
@@ -423,6 +425,8 @@ module Net
|
|
|
423
425
|
# representation and returns +self+.
|
|
424
426
|
#
|
|
425
427
|
class SequenceSet
|
|
428
|
+
include Utils # :nodoc:
|
|
429
|
+
|
|
426
430
|
# The largest possible non-zero unsigned 32-bit integer
|
|
427
431
|
UINT32_MAX = 2**32 - 1
|
|
428
432
|
|
|
@@ -1019,9 +1023,9 @@ module Net
|
|
|
1019
1023
|
# is empty. (+star+ is ignored when +count+ is given.)
|
|
1020
1024
|
#
|
|
1021
1025
|
# Related: #min, #minmax, #slice
|
|
1022
|
-
def max(count = nil, star: :*)
|
|
1023
|
-
if
|
|
1024
|
-
count =
|
|
1026
|
+
def max(count = (unset_count = true; nil), star: :*)
|
|
1027
|
+
if !unset_count
|
|
1028
|
+
count = implicit_int(count)
|
|
1025
1029
|
raise ArgumentError, 'negative count' if count < 0
|
|
1026
1030
|
return remain_frozen_empty if count == 0
|
|
1027
1031
|
if cardinality <= count
|
|
@@ -1046,9 +1050,9 @@ module Net
|
|
|
1046
1050
|
# is empty. (+star+ is ignored when +count+ is given.)
|
|
1047
1051
|
#
|
|
1048
1052
|
# Related: #max, #minmax, #slice
|
|
1049
|
-
def min(count = nil, star: :*)
|
|
1050
|
-
if
|
|
1051
|
-
count =
|
|
1053
|
+
def min(count = (unset_count = true; nil), star: :*)
|
|
1054
|
+
if !unset_count
|
|
1055
|
+
count = implicit_int(count)
|
|
1052
1056
|
raise ArgumentError, 'negative count' if count < 0
|
|
1053
1057
|
slice(0...count) || remain_frozen_empty
|
|
1054
1058
|
elsif (val = min_num)
|
|
@@ -1360,7 +1364,7 @@ module Net
|
|
|
1360
1364
|
#
|
|
1361
1365
|
# Related: #delete, #delete?, #slice!, #subtract, #difference
|
|
1362
1366
|
def delete_at(index)
|
|
1363
|
-
slice!
|
|
1367
|
+
slice! implicit_int index
|
|
1364
1368
|
end
|
|
1365
1369
|
|
|
1366
1370
|
# :call-seq:
|
|
@@ -1376,9 +1380,10 @@ module Net
|
|
|
1376
1380
|
# #string will be regenerated after deletion.
|
|
1377
1381
|
#
|
|
1378
1382
|
# Related: #slice, #delete_at, #delete, #delete?, #subtract, #difference
|
|
1379
|
-
def slice!(index, length = nil)
|
|
1383
|
+
def slice!(index, length = (length_unset = true; nil))
|
|
1380
1384
|
modifying! # short-circuit before slice
|
|
1381
|
-
deleted = slice(index, length)
|
|
1385
|
+
deleted = length_unset ? slice(index) : slice(index, length)
|
|
1386
|
+
subtract deleted if deleted
|
|
1382
1387
|
deleted
|
|
1383
1388
|
end
|
|
1384
1389
|
|
|
@@ -1720,7 +1725,7 @@ module Net
|
|
|
1720
1725
|
#
|
|
1721
1726
|
# Related: #[], #slice, #ordered_at
|
|
1722
1727
|
def at(index)
|
|
1723
|
-
|
|
1728
|
+
export_num sorted_set_num_at implicit_int index
|
|
1724
1729
|
end
|
|
1725
1730
|
|
|
1726
1731
|
# :call-seq: ordered_at(index) -> integer or nil
|
|
@@ -1733,22 +1738,55 @@ module Net
|
|
|
1733
1738
|
#
|
|
1734
1739
|
# Related: #[], #slice, #ordered_at
|
|
1735
1740
|
def ordered_at(index)
|
|
1736
|
-
|
|
1741
|
+
export_num ordered_list_num_at implicit_int index
|
|
1737
1742
|
end
|
|
1738
1743
|
|
|
1739
1744
|
# :call-seq:
|
|
1740
1745
|
# seqset[index] -> integer or :* or nil
|
|
1741
1746
|
# slice(index) -> integer or :* or nil
|
|
1742
|
-
# seqset[
|
|
1743
|
-
# slice(
|
|
1747
|
+
# seqset[index, length] -> sequence set or nil
|
|
1748
|
+
# slice(index, length) -> sequence set or nil
|
|
1744
1749
|
# seqset[range] -> sequence set or nil
|
|
1745
1750
|
# slice(range) -> sequence set or nil
|
|
1746
1751
|
#
|
|
1747
1752
|
# Returns a number or a subset from the _sorted_ set, without modifying
|
|
1748
1753
|
# the set.
|
|
1749
1754
|
#
|
|
1755
|
+
# With a single +index+ argument, returns an integer or +:*+ or nil:
|
|
1756
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1757
|
+
# set[0] #=> 10
|
|
1758
|
+
# set[-1] #=> 26
|
|
1759
|
+
#
|
|
1760
|
+
# With +index+ and +length+ arguments, returns a new SequenceSet or nil:
|
|
1761
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1762
|
+
# set[1, 2] #=> Net::IMAP::SequenceSet["11:12"]
|
|
1763
|
+
# set[-2, 2] #=> Net::IMAP::SequenceSet["23,26"]
|
|
1764
|
+
#
|
|
1765
|
+
# With a single +range+ argument, returns a new SequenceSet or nil:
|
|
1766
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1767
|
+
# set[0...2] #=> Net::IMAP::SequenceSet["10:11"]
|
|
1768
|
+
# set[0..2] #=> Net::IMAP::SequenceSet["11:12"]
|
|
1769
|
+
# set[0..-2] #=> Net::IMAP::SequenceSet["10:15,20:23"]
|
|
1770
|
+
# set[-6..6] #=> Net::IMAP::SequenceSet["15,20"]
|
|
1771
|
+
#
|
|
1772
|
+
# Note that the result is based on the sorted and de-duplicated set, not
|
|
1773
|
+
# on the ordered #entries in #string.
|
|
1774
|
+
#
|
|
1775
|
+
# set = Net::IMAP::SequenceSet["12,20:23,11:16,21"]
|
|
1776
|
+
# set[0] #=> 11
|
|
1777
|
+
# set[-1] #=> 23
|
|
1778
|
+
#
|
|
1779
|
+
# This behaves like <tt>Array#slice</tt> on a virtual array of all of the
|
|
1780
|
+
# monotonically sorted #numbers in +self+:
|
|
1781
|
+
# # WARNING: For illustration only. Do NOT do this with large sets.
|
|
1782
|
+
# sliced_array = seqset.numbers[*args] and
|
|
1783
|
+
# sliced_set = Net::IMAP::SequenceSet(sliced_array)
|
|
1784
|
+
# set.slice(*args) == sliced_set #=> true
|
|
1785
|
+
#
|
|
1786
|
+
# ==== Number lookup by index
|
|
1787
|
+
#
|
|
1750
1788
|
# When an Integer argument +index+ is given, the number at offset +index+
|
|
1751
|
-
# in the sorted set is returned
|
|
1789
|
+
# in the sorted set is returned.
|
|
1752
1790
|
#
|
|
1753
1791
|
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1754
1792
|
# set[0] #=> 10
|
|
@@ -1759,24 +1797,86 @@ module Net
|
|
|
1759
1797
|
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1760
1798
|
# set[-1] #=> 26
|
|
1761
1799
|
# set[-3] #=> 22
|
|
1762
|
-
# set[-
|
|
1763
|
-
#
|
|
1764
|
-
# If +index+ is out of range, +nil+ is returned.
|
|
1800
|
+
# set[-11] #=> 10
|
|
1765
1801
|
#
|
|
1802
|
+
# The range for +index+ is <tt>-cardinality...cardinality</tt>.
|
|
1803
|
+
# If +index+ is out of range, returns +nil+.
|
|
1766
1804
|
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1767
1805
|
# set[11] #=> nil
|
|
1768
1806
|
# set[-12] #=> nil
|
|
1769
1807
|
#
|
|
1770
|
-
#
|
|
1771
|
-
# ordered #entries in #string.
|
|
1808
|
+
# With a single Integer argument, this behaves identically to #at.
|
|
1772
1809
|
#
|
|
1773
|
-
#
|
|
1774
|
-
#
|
|
1775
|
-
#
|
|
1810
|
+
# ==== Subset slice by index and length
|
|
1811
|
+
#
|
|
1812
|
+
# When two Integer arguments, +index+ and +length+ are given, returns a
|
|
1813
|
+
# new SequenceSet containing the +length+ successive numbers beginning at
|
|
1814
|
+
# offset +index+.:
|
|
1815
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1816
|
+
# set[0, 2] #=> Net::IMAP::SequenceSet["10:11"]
|
|
1817
|
+
# set[1, 2] #=> Net::IMAP::SequenceSet["11:12"]
|
|
1818
|
+
#
|
|
1819
|
+
# If <tt>index + length</tt> is greater than #cardinality, returns all
|
|
1820
|
+
# elements from +index+ to the end:
|
|
1821
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1822
|
+
# set[0, 15] #=> Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1823
|
+
# set[5, 10] #=> Net::IMAP::SequenceSet["15,20:23,26"]
|
|
1824
|
+
# set[10, 5] #=> Net::IMAP::SequenceSet["26"]
|
|
1825
|
+
#
|
|
1826
|
+
# If +index+ is equal to #cardinality, returns a new empty SequenceSet.
|
|
1827
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1828
|
+
# set[11, 5] #=> Net::IMAP::SequenceSet.empty
|
|
1829
|
+
#
|
|
1830
|
+
# If +length+ is negative, returns +nil+.
|
|
1831
|
+
# set = Net::IMAP::SequenceSet[1..10]
|
|
1832
|
+
# set[5, -1] #=> nil
|
|
1833
|
+
#
|
|
1834
|
+
# If +index+ is out of range (absolute value greater than #cardinality),
|
|
1835
|
+
# returns +nil+.
|
|
1836
|
+
#
|
|
1837
|
+
# If +index+ is in range and +length+ is zero, returns a new empty
|
|
1838
|
+
# SequenceSet.
|
|
1839
|
+
#
|
|
1840
|
+
# ==== Subset slice by index range
|
|
1841
|
+
#
|
|
1842
|
+
# When a single Range argument +range+ is given, returns a new SequenceSet
|
|
1843
|
+
# containing the successive numbers at the offsets indicated by +range+.
|
|
1844
|
+
#
|
|
1845
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1846
|
+
# set[0...2] #=> Net::IMAP::SequenceSet["10:11"]
|
|
1847
|
+
# set[2..4] #=> Net::IMAP::SequenceSet["12:14"]
|
|
1848
|
+
#
|
|
1849
|
+
# set[-2..-1] #=> Net::IMAP::SequenceSet["23,26"]
|
|
1850
|
+
# set[-4...-2] #=> Net::IMAP::SequenceSet["21:22"]
|
|
1851
|
+
#
|
|
1852
|
+
# set[4..-4] #=> Net::IMAP::SequenceSet["14:15,20:21"]
|
|
1853
|
+
# set[-6...6] #=> Net::IMAP::SequenceSet["15"]
|
|
1854
|
+
#
|
|
1855
|
+
# An end-less range slices until the last number, and a begin-less range
|
|
1856
|
+
# slices from the first number.
|
|
1857
|
+
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
|
1858
|
+
# set[..3] #=> Net::IMAP::SequenceSet["10:13"]
|
|
1859
|
+
# set[..-3] #=> Net::IMAP::SequenceSet["10:15,20:22"]
|
|
1860
|
+
# set[-2..] #=> Net::IMAP::SequenceSet["23,26"]
|
|
1861
|
+
# set[2..] #=> Net::IMAP::SequenceSet["12:15,20:23,26"]
|
|
1776
1862
|
#
|
|
1777
|
-
#
|
|
1778
|
-
|
|
1779
|
-
|
|
1863
|
+
# When +range.begin+ points to a smaller index than +range.end+, a new
|
|
1864
|
+
# empty SequenceSet is returned.
|
|
1865
|
+
#
|
|
1866
|
+
# set = Net::IMAP::SequenceSet[1..10]
|
|
1867
|
+
# set[5.. 4] #=> SequenceSet.empty
|
|
1868
|
+
# set[-4..-5] #=> SequenceSet.empty
|
|
1869
|
+
# set[5..-6] #=> SequenceSet.empty
|
|
1870
|
+
#
|
|
1871
|
+
# If +range.begin+ is out of range (absolute value greater than
|
|
1872
|
+
# #cardinality), returns +nil+.
|
|
1873
|
+
#
|
|
1874
|
+
# This behaves similarly to a slice with +range.begin+ as +index+ and
|
|
1875
|
+
# +range.size+ as +length+, when that both sides of the range are either
|
|
1876
|
+
# negative or non-negative. Note that the minimum +range.size+ is zero,
|
|
1877
|
+
# so this can't return +nil+ for a negative range length.
|
|
1878
|
+
def [](index, length = (length_unset = true; nil))
|
|
1879
|
+
if !length_unset then slice_length(index, length)
|
|
1780
1880
|
elsif index.is_a?(Range) then slice_range(index)
|
|
1781
1881
|
else at(index)
|
|
1782
1882
|
end
|
|
@@ -2282,15 +2382,22 @@ module Net
|
|
|
2282
2382
|
######################################################################{{{2
|
|
2283
2383
|
# Number indexing methods
|
|
2284
2384
|
|
|
2385
|
+
def sorted_set_num_at(index)
|
|
2386
|
+
seek_number_in_minmaxes(minmaxes, index)
|
|
2387
|
+
end
|
|
2388
|
+
|
|
2389
|
+
def ordered_list_num_at(index)
|
|
2390
|
+
seek_number_in_minmaxes(each_entry_minmax, index)
|
|
2391
|
+
end
|
|
2392
|
+
|
|
2285
2393
|
def seek_number_in_minmaxes(minmaxes, index)
|
|
2286
|
-
index = Integer(index.to_int)
|
|
2287
2394
|
if index.negative?
|
|
2288
2395
|
reverse_each_minmax_with_index(minmaxes) do |min, max, idx_min, idx_max|
|
|
2289
|
-
idx_min <= index and return
|
|
2396
|
+
idx_min <= index and return min + (index - idx_min)
|
|
2290
2397
|
end
|
|
2291
2398
|
else
|
|
2292
2399
|
each_minmax_with_index(minmaxes) do |min, _, idx_min, idx_max|
|
|
2293
|
-
index <= idx_max and return
|
|
2400
|
+
index <= idx_max and return min + (index - idx_min)
|
|
2294
2401
|
end
|
|
2295
2402
|
end
|
|
2296
2403
|
nil
|
|
@@ -2316,30 +2423,41 @@ module Net
|
|
|
2316
2423
|
end
|
|
2317
2424
|
|
|
2318
2425
|
def slice_length(start, length)
|
|
2319
|
-
start =
|
|
2320
|
-
length =
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
slice_range(start
|
|
2426
|
+
start = implicit_int(start)
|
|
2427
|
+
length = implicit_int(length)
|
|
2428
|
+
return nil if length.negative?
|
|
2429
|
+
stop = start + length unless start.negative? && start.abs <= length
|
|
2430
|
+
slice_range(start...stop)
|
|
2324
2431
|
end
|
|
2325
2432
|
|
|
2326
2433
|
def slice_range(range)
|
|
2327
|
-
first = range.begin ||
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
max
|
|
2337
|
-
max = :* if max.nil?
|
|
2338
|
-
if max == :* then self & (min..)
|
|
2339
|
-
elsif min <= max then self & (min..max)
|
|
2434
|
+
first = implicit_int(range.begin || 0)
|
|
2435
|
+
rend = implicit_int(range.end) unless range.end.nil?
|
|
2436
|
+
excl = range.exclude_end?
|
|
2437
|
+
last = !(excl && rend == 0) && # (i...0)
|
|
2438
|
+
(excl && rend&.pred || rend || -1) # (i...j) vs (i..j) vs (i...)
|
|
2439
|
+
if !last || first.negative? == last.negative? && last < first
|
|
2440
|
+
remain_frozen_empty if valid_slice_start?(first)
|
|
2441
|
+
elsif (min = sorted_set_num_at(first))
|
|
2442
|
+
max = sorted_set_num_at(last) || (last.negative? ? 0 : STAR_INT)
|
|
2443
|
+
if min <= max then intersection export_minmax_entry [min, max]
|
|
2340
2444
|
else remain_frozen_empty
|
|
2341
2445
|
end
|
|
2446
|
+
elsif first.positive?
|
|
2447
|
+
remain_frozen_empty if valid_slice_start?(first)
|
|
2448
|
+
end
|
|
2449
|
+
end
|
|
2450
|
+
|
|
2451
|
+
# By short-circuiting, this is a small performance improvement over
|
|
2452
|
+
# `offset.abs <= cardinality`. But, slice_range should get a bigger
|
|
2453
|
+
# performance boost by combining this scan with the start offset scan.
|
|
2454
|
+
def valid_slice_start?(offset)
|
|
2455
|
+
offset = offset.abs
|
|
2456
|
+
minmaxes.each do |min, max|
|
|
2457
|
+
offset -= (max - min).succ
|
|
2458
|
+
return true if offset.negative?
|
|
2342
2459
|
end
|
|
2460
|
+
!offset.positive?
|
|
2343
2461
|
end
|
|
2344
2462
|
|
|
2345
2463
|
######################################################################{{{2
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
|
|
4
|
+
# :enddoc:
|
|
5
|
+
|
|
6
|
+
module Net
|
|
7
|
+
class IMAP < Protocol
|
|
8
|
+
|
|
9
|
+
# INTERNAL utility methods. API is unstable and subject to change.
|
|
10
|
+
module Utils
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
# Something like this exists in ruby's C API. Why not in ruby's ruby?
|
|
14
|
+
def implicit_int(input)
|
|
15
|
+
Integer.try_convert(input) or
|
|
16
|
+
raise TypeError, case input
|
|
17
|
+
when nil
|
|
18
|
+
"no implicit conversion from %p to Integer" % [input]
|
|
19
|
+
when true, false
|
|
20
|
+
"no implicit conversion of %p into Integer" % [input]
|
|
21
|
+
else
|
|
22
|
+
"no implicit conversion of %s into Integer" % [input.class.name]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if defined?(Ractor.shareable_proc)
|
|
27
|
+
def shareable
|
|
28
|
+
case obj = yield
|
|
29
|
+
when Proc
|
|
30
|
+
Ractor.shareable_proc(&obj)
|
|
31
|
+
else
|
|
32
|
+
Ractor.make_shareable obj
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# simplecov:disable
|
|
37
|
+
elsif defined?(Ractor.make_shareable)
|
|
38
|
+
def shareable(&b)
|
|
39
|
+
obj = nil.instance_eval(&b).freeze
|
|
40
|
+
Ractor.make_shareable obj
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
def shareable(&b) nil.instance_eval(&b).freeze end
|
|
44
|
+
end
|
|
45
|
+
# simplecov:enable
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/net/imap.rb
CHANGED
|
@@ -933,7 +933,7 @@ module Net
|
|
|
933
933
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
|
934
934
|
#
|
|
935
935
|
class IMAP < Protocol
|
|
936
|
-
VERSION = "0.6.
|
|
936
|
+
VERSION = "0.6.8"
|
|
937
937
|
|
|
938
938
|
# Aliases for supported capabilities, to be used with the #enable command.
|
|
939
939
|
ENABLE_ALIASES = {
|
|
@@ -3702,7 +3702,7 @@ module Net
|
|
|
3702
3702
|
s = Socket.tcp(host, port, :connect_timeout => open_timeout)
|
|
3703
3703
|
s.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, true)
|
|
3704
3704
|
s
|
|
3705
|
-
rescue Errno::ETIMEDOUT
|
|
3705
|
+
rescue Errno::ETIMEDOUT, IO::TimeoutError
|
|
3706
3706
|
raise Net::OpenTimeout, "Timeout to open TCP connection to " +
|
|
3707
3707
|
"#{host}:#{port} (exceeds #{open_timeout} seconds)"
|
|
3708
3708
|
end
|
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.6.
|
|
4
|
+
version: 0.6.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shugo Maeda
|
|
@@ -102,6 +102,7 @@ files:
|
|
|
102
102
|
- lib/net/imap/stringprep/tables.rb
|
|
103
103
|
- lib/net/imap/stringprep/trace.rb
|
|
104
104
|
- lib/net/imap/uidplus_data.rb
|
|
105
|
+
- lib/net/imap/utils.rb
|
|
105
106
|
- lib/net/imap/vanished_data.rb
|
|
106
107
|
- net-imap.gemspec
|
|
107
108
|
- rakelib/benchmarks.rake
|
|
@@ -132,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
132
133
|
- !ruby/object:Gem::Version
|
|
133
134
|
version: '0'
|
|
134
135
|
requirements: []
|
|
135
|
-
rubygems_version: 4.0.
|
|
136
|
+
rubygems_version: 4.0.22
|
|
136
137
|
specification_version: 4
|
|
137
138
|
summary: Ruby client api for Internet Message Access Protocol
|
|
138
139
|
test_files: []
|