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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5300636497a02d1c8bc10b528bf1d3fe8aad9898ba02ba3ab40f2329f9306baf
4
- data.tar.gz: 449230117bc3289dc13cb1531d95a2ae530558a21a405d8f4effb958773da88d
3
+ metadata.gz: 9405d034ddfa540378feffe20b4818437ca73913b1d82663cdd56d341ca71553
4
+ data.tar.gz: 2df46e36cdb6fc77aa6c88838ae684f7c800b5a643b985880e95d802e912a2fd
5
5
  SHA512:
6
- metadata.gz: b034f4ab8fc449890b3eb29c2049c4af1ed5aac42e8943f0a5eb20d4f9eae910740e0c8d590590f3379121c30ac347ce49f5387dcd4985e2dd551292545bd2de
7
- data.tar.gz: 996ab44d2c1f4bf6d5d2e3d141b1890d25a38cddf1e0032726257c63346fc7175bcdd05f3ed97cce3a3ce63d8939154c4d9c4b9e931b035a46d9c4fa1a518450
6
+ metadata.gz: 554739baaaaa8b0406f729d56447a13d4ced84f33feba90a350851424624483a36765c40f00e34737fe602bd0bd43555a2f480d4f7d9a0af034f791c0c9e0b8a
7
+ data.tar.gz: '06596b9d2da38bbd53dcc0fd990b66b1af5ffbd52af52370b8366188899043f129e63aae7090054090f8a1b29b8e89e7c96402ffc0aa48101d7f95bf09419a96'
data/.simplecov CHANGED
@@ -5,9 +5,6 @@ SimpleCov.configure do
5
5
  enable_coverage :method
6
6
  enable_coverage :eval
7
7
 
8
- # eval branch coverage varies too much between runtime environments
9
- ignore_branches :eval_generated
10
-
11
8
  skip "/test/"
12
9
  skip "/rakelib/"
13
10
  cover "lib/**/*.rb"
data/Gemfile CHANGED
@@ -20,5 +20,5 @@ gem "benchmark_driver", require: false
20
20
  gem "vernier", require: false, platform: :mri
21
21
 
22
22
  group :test do
23
- gem "simplecov", ">= 1.0.0", require: false, platforms: %i[mri windows]
23
+ gem "simplecov", ">= 1.2.0", require: false, platforms: %i[mri windows]
24
24
  end
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 95
23
+ minimum 95
24
24
 
25
- minimum_per_group 98, only: "Config"
26
- minimum_per_group 97, only: "StringPrep"
27
- minimum_per_group 97, only: "SASL"
28
- minimum_per_group 95, only: "Data Types"
29
- minimum_per_group 94, only: "Parser"
30
- minimum_per_group 92, only: "Client"
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
- minimum_per_file 80
33
- minimum_per_file 55, only: "lib/net/imap/search_result.rb"
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
- minimum 80
38
+ # eval branch coverage varies too much between runtime environments
39
+ ignore :eval_generated
39
40
 
40
- minimum_per_group 90, only: "Data Types"
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
- minimum_per_file 60
48
- minimum_per_file 50, only: "lib/net/imap/sasl/authenticators.rb"
49
- minimum_per_file 50, only: "lib/net/imap/config/attr_accessors.rb"
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 88
56
+ minimum 88
54
57
 
55
- minimum_per_group 100, only: "Config"
56
- minimum_per_group 90, only: "Data Types"
57
- minimum_per_group 90, only: "StringPrep"
58
- minimum_per_group 85, only: "Client"
59
- minimum_per_group 80, only: "Parser"
60
- minimum_per_group 80, only: "SASL"
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
- minimum_per_file 65
63
- minimum_per_file 60, only: "lib/net/imap/response_parser/parser_utils.rb"
64
- minimum_per_file 55, only: "lib/net/imap/sasl/authenticators.rb"
65
- minimum_per_file 50, only: "lib/net/imap/authenticators.rb"
66
- minimum_per_file 50, only: "lib/net/imap/sasl/anonymous_authenticator.rb"
67
- minimum_per_file 35, only: "lib/net/imap/sasl/protocol_adapters.rb"
68
- minimum_per_file 20, only: "lib/net/imap/response_data.rb"
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
- 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
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| type => Proc | nil; safe{type} end
51
- Types[:boolean] = Boolean = safe{-> {!!_1}}
52
- Types[Integer] = safe{->{Integer(_1)}}
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 = safe{->val { Integer val unless val.nil? }}
48
+ NilOrInteger = shareable{->val { Integer val unless val.nil? }}
61
49
 
62
- Enum = ->(*enum) {
63
- safe_enum = safe{enum}
50
+ Enum = shareable{->(*enum) {
51
+ safe_enum = Utils.shareable{enum}
64
52
  expected = -"one of #{safe_enum.map(&:inspect).join(", ")}"
65
- safe{->val {
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
@@ -186,7 +186,7 @@ module Net
186
186
  end
187
187
 
188
188
  def peek_re?(re)
189
- assert_no_lookahead if Net::IMAP.debug
189
+ assert_no_lookahead if config.debug?
190
190
  re.match?(@str, @pos)
191
191
  end
192
192
 
@@ -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 count
1024
- count = Integer(count.to_int)
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 count
1051
- count = Integer(count.to_int)
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! Integer(index.to_int)
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) and subtract deleted
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
- seek_number_in_minmaxes(minmaxes, index)
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
- seek_number_in_minmaxes(each_entry_minmax, index)
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[start, length] -> sequence set or nil
1743
- # slice(start, length) -> sequence set or nil
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[-6] #=> 15
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
- # The result is based on the sorted and de-duplicated set, not on the
1771
- # ordered #entries in #string.
1808
+ # With a single Integer argument, this behaves identically to #at.
1772
1809
  #
1773
- # set = Net::IMAP::SequenceSet["12,20:23,11:16,21"]
1774
- # set[0] #=> 11
1775
- # set[-1] #=> 23
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
- # Related: #at
1778
- def [](index, length = nil)
1779
- if length then slice_length(index, length)
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 export_num(min + (index - idx_min))
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 export_num(min + (index - idx_min))
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 = Integer(start.to_int)
2320
- length = Integer(length.to_int)
2321
- raise ArgumentError, "length must be positive" unless length.positive?
2322
- last = start + length - 1 unless start.negative? && start.abs <= length
2323
- slice_range(start..last)
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 || 0
2328
- last = range.end || -1
2329
- if range.exclude_end?
2330
- return remain_frozen_empty if last.zero?
2331
- last -= 1 if range.end && last != STAR_INT
2332
- end
2333
- if (first * last).positive? && last < first
2334
- remain_frozen_empty
2335
- elsif (min = at(first))
2336
- max = at(last)
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.7"
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.7
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.20
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: []