net-imap 0.5.9 → 0.5.10
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/flags.rb +1 -1
- data/lib/net/imap/sequence_set.rb +91 -25
- data/lib/net/imap.rb +1 -1
- 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: 261794e07175481d35e146b718183fc057a3a54e2fd9958b25918c6bd4178ec4
|
4
|
+
data.tar.gz: 2568eb1d284b3f1662d1cf0c1bc79eb65722fa3ba8dc03072b52fbd3716c9294
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 357279f77c69c27b78924847216afad6c806abb7bfee5f0c95aab6c397cb10298440a59cb32b9f75a4174e6965d6bfe48a5e847e20d9098845033e8453f73302
|
7
|
+
data.tar.gz: e3c29888d787de23a843bfb9ff9194d1fa136763e9d9bcf36800953362f7611c489da1f9150ee2a23baa571125f4f2af2cebe4ee4666447783e355bd9995eb3a
|
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
|
data/lib/net/imap/flags.rb
CHANGED
@@ -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:
|
@@ -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)
|
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.10"
|
792
792
|
|
793
793
|
# Aliases for supported capabilities, to be used with the #enable command.
|
794
794
|
ENABLE_ALIASES = {
|
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.10
|
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: []
|