net-imap 0.4.20 → 0.5.0
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.
Potentially problematic release.
This version of net-imap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +7 -1
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +11 -0
- data/lib/net/imap/config/attr_type_coercion.rb +21 -25
- data/lib/net/imap/config.rb +38 -162
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/deprecated_client_options.rb +6 -3
- data/lib/net/imap/errors.rb +6 -33
- data/lib/net/imap/response_data.rb +60 -96
- data/lib/net/imap/response_parser.rb +18 -45
- data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
- data/lib/net/imap/sasl/authenticators.rb +8 -4
- data/lib/net/imap/sasl/client_adapter.rb +77 -26
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +1 -1
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +213 -51
- data/lib/net/imap/sasl/login_authenticator.rb +2 -1
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl.rb +6 -3
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/sequence_set.rb +128 -273
- data/lib/net/imap.rb +68 -159
- data/net-imap.gemspec +1 -1
- metadata +7 -6
- data/lib/net/imap/response_reader.rb +0 -75
- data/lib/net/imap/uidplus_data.rb +0 -326
@@ -14,13 +14,6 @@ module Net
|
|
14
14
|
# receive a SequenceSet as an argument, for example IMAP#search, IMAP#fetch,
|
15
15
|
# and IMAP#store.
|
16
16
|
#
|
17
|
-
# == EXPERIMENTAL API
|
18
|
-
#
|
19
|
-
# SequenceSet is currently experimental. Only two methods, ::[] and
|
20
|
-
# #valid_string, are considered stable. Although the API isn't expected to
|
21
|
-
# change much, any other methods may be removed or changed without
|
22
|
-
# deprecation.
|
23
|
-
#
|
24
17
|
# == Creating sequence sets
|
25
18
|
#
|
26
19
|
# SequenceSet.new with no arguments creates an empty sequence set. Note
|
@@ -37,7 +30,8 @@ module Net
|
|
37
30
|
#
|
38
31
|
# SequenceSet.new may receive a single optional argument: a non-zero 32 bit
|
39
32
|
# unsigned integer, a range, a <tt>sequence-set</tt> formatted string,
|
40
|
-
# another sequence set,
|
33
|
+
# another sequence set, a Set (containing only numbers or <tt>*</tt>), or an
|
34
|
+
# Array containing any of these (array inputs may be nested).
|
41
35
|
#
|
42
36
|
# set = Net::IMAP::SequenceSet.new(1)
|
43
37
|
# set.valid_string #=> "1"
|
@@ -60,20 +54,18 @@ module Net
|
|
60
54
|
# set = Net::IMAP::SequenceSet[1, 2, [3..7, 5], 6..10, 2048, 1024]
|
61
55
|
# set.valid_string #=> "1:10,55,1024:2048"
|
62
56
|
#
|
63
|
-
# ==
|
64
|
-
#
|
65
|
-
# Sometimes the order of the set's members is significant, such as with the
|
66
|
-
# +ESORT+, <tt>CONTEXT=SORT</tt>, and +UIDPLUS+ extensions. So, when a
|
67
|
-
# sequence set is created by the parser or with a single string value, that
|
68
|
-
# #string representation is preserved.
|
57
|
+
# == Normalized form
|
69
58
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
59
|
+
# When a sequence set is created with a single String value, that #string
|
60
|
+
# representation is preserved. SequenceSet's internal representation
|
61
|
+
# implicitly sorts all entries, de-duplicates numbers, and coalesces
|
62
|
+
# adjacent or overlapping ranges. Most enumeration methods and offset-based
|
63
|
+
# methods use this normalized representation. Most modification methods
|
64
|
+
# will convert #string to its normalized form.
|
75
65
|
#
|
76
|
-
#
|
66
|
+
# In some cases the order of the string representation is significant, such
|
67
|
+
# as the +ESORT+, <tt>CONTEXT=SORT</tt>, and +UIDPLUS+ extensions. Use
|
68
|
+
# #entries or #each_entry to enumerate the set in its original order. To
|
77
69
|
# preserve #string order while modifying a set, use #append, #string=, or
|
78
70
|
# #replace.
|
79
71
|
#
|
@@ -166,7 +158,7 @@ module Net
|
|
166
158
|
# - #===:
|
167
159
|
# Returns whether a given object is fully contained within +self+, or
|
168
160
|
# +nil+ if the object cannot be converted to a compatible type.
|
169
|
-
# - #cover
|
161
|
+
# - #cover? (aliased as #===):
|
170
162
|
# Returns whether a given object is fully contained within +self+.
|
171
163
|
# - #intersect? (aliased as #overlap?):
|
172
164
|
# Returns whether +self+ and a given object have any common elements.
|
@@ -178,7 +170,7 @@ module Net
|
|
178
170
|
#
|
179
171
|
# <i>Set membership:</i>
|
180
172
|
# - #include? (aliased as #member?):
|
181
|
-
# Returns whether a given
|
173
|
+
# Returns whether a given object (nz-number, range, or <tt>*</tt>) is
|
182
174
|
# contained by the set.
|
183
175
|
# - #include_star?: Returns whether the set contains <tt>*</tt>.
|
184
176
|
#
|
@@ -187,41 +179,30 @@ module Net
|
|
187
179
|
# - #max: Returns the maximum number in the set.
|
188
180
|
# - #minmax: Returns the minimum and maximum numbers in the set.
|
189
181
|
#
|
190
|
-
# <i>Accessing value by offset
|
182
|
+
# <i>Accessing value by offset:</i>
|
191
183
|
# - #[] (aliased as #slice): Returns the number or consecutive subset at a
|
192
|
-
# given offset or range of offsets
|
193
|
-
# - #at: Returns the number at a given offset
|
194
|
-
# - #find_index: Returns the given number's offset in the
|
195
|
-
#
|
196
|
-
# <i>Accessing value by offset in ordered entries</i>
|
197
|
-
# - #ordered_at: Returns the number at a given offset in the ordered entries.
|
198
|
-
# - #find_ordered_index: Returns the index of the given number's first
|
199
|
-
# occurrence in entries.
|
184
|
+
# given offset or range of offsets.
|
185
|
+
# - #at: Returns the number at a given offset.
|
186
|
+
# - #find_index: Returns the given number's offset in the set
|
200
187
|
#
|
201
188
|
# <i>Set cardinality:</i>
|
202
189
|
# - #count (aliased as #size): Returns the count of numbers in the set.
|
203
|
-
# Duplicated numbers are not counted.
|
204
190
|
# - #empty?: Returns whether the set has no members. \IMAP syntax does not
|
205
191
|
# allow empty sequence sets.
|
206
192
|
# - #valid?: Returns whether the set has any members.
|
207
193
|
# - #full?: Returns whether the set contains every possible value, including
|
208
194
|
# <tt>*</tt>.
|
209
195
|
#
|
210
|
-
# <i>Denormalized properties:</i>
|
211
|
-
# - #has_duplicates?: Returns whether the ordered entries repeat any
|
212
|
-
# numbers.
|
213
|
-
# - #count_duplicates: Returns the count of repeated numbers in the ordered
|
214
|
-
# entries.
|
215
|
-
# - #count_with_duplicates: Returns the count of numbers in the ordered
|
216
|
-
# entries, including any repeated numbers.
|
217
|
-
#
|
218
196
|
# === Methods for Iterating
|
219
197
|
#
|
220
|
-
# <i>Normalized (sorted and coalesced):</i>
|
221
198
|
# - #each_element: Yields each number and range in the set, sorted and
|
222
199
|
# coalesced, and returns +self+.
|
223
200
|
# - #elements (aliased as #to_a): Returns an Array of every number and range
|
224
201
|
# in the set, sorted and coalesced.
|
202
|
+
# - #each_entry: Yields each number and range in the set, unsorted and
|
203
|
+
# without deduplicating numbers or coalescing ranges, and returns +self+.
|
204
|
+
# - #entries: Returns an Array of every number and range in the set,
|
205
|
+
# unsorted and without deduplicating numbers or coalescing ranges.
|
225
206
|
# - #each_range:
|
226
207
|
# Yields each element in the set as a Range and returns +self+.
|
227
208
|
# - #ranges: Returns an Array of every element in the set, converting
|
@@ -231,25 +212,17 @@ module Net
|
|
231
212
|
# ranges into all of their contained numbers.
|
232
213
|
# - #to_set: Returns a Set containing all of the #numbers in the set.
|
233
214
|
#
|
234
|
-
# <i>Order preserving:</i>
|
235
|
-
# - #each_entry: Yields each number and range in the set, unsorted and
|
236
|
-
# without deduplicating numbers or coalescing ranges, and returns +self+.
|
237
|
-
# - #entries: Returns an Array of every number and range in the set,
|
238
|
-
# unsorted and without deduplicating numbers or coalescing ranges.
|
239
|
-
# - #each_ordered_number: Yields each number in the ordered entries and
|
240
|
-
# returns +self+.
|
241
|
-
#
|
242
215
|
# === Methods for \Set Operations
|
243
216
|
# These methods do not modify +self+.
|
244
217
|
#
|
245
218
|
# - #| (aliased as #union and #+): Returns a new set combining all members
|
246
|
-
# from +self+ with all members from the other
|
219
|
+
# from +self+ with all members from the other object.
|
247
220
|
# - #& (aliased as #intersection): Returns a new set containing all members
|
248
|
-
# common to +self+ and the other
|
221
|
+
# common to +self+ and the other object.
|
249
222
|
# - #- (aliased as #difference): Returns a copy of +self+ with all members
|
250
|
-
# in the other
|
223
|
+
# in the other object removed.
|
251
224
|
# - #^ (aliased as #xor): Returns a new set containing all members from
|
252
|
-
# +self+ and the other
|
225
|
+
# +self+ and the other object except those common to both.
|
253
226
|
# - #~ (aliased as #complement): Returns a new set containing all members
|
254
227
|
# that are not in +self+
|
255
228
|
# - #limit: Returns a copy of +self+ which has replaced <tt>*</tt> with a
|
@@ -258,39 +231,28 @@ module Net
|
|
258
231
|
# === Methods for Assigning
|
259
232
|
# These methods add or replace elements in +self+.
|
260
233
|
#
|
261
|
-
#
|
262
|
-
#
|
263
|
-
# These methods always update #string to be fully sorted and coalesced.
|
264
|
-
#
|
265
|
-
# - #add (aliased as #<<): Adds a given element to the set; returns +self+.
|
266
|
-
# - #add?: If the given element is not fully included the set, adds it and
|
234
|
+
# - #add (aliased as #<<): Adds a given object to the set; returns +self+.
|
235
|
+
# - #add?: If the given object is not an element in the set, adds it and
|
267
236
|
# returns +self+; otherwise, returns +nil+.
|
268
|
-
# - #merge:
|
269
|
-
# - #
|
270
|
-
#
|
271
|
-
# <i>Order preserving:</i>
|
272
|
-
#
|
273
|
-
# These methods _may_ cause #string to not be sorted or coalesced.
|
274
|
-
#
|
275
|
-
# - #append: Adds the given entry to the set, appending it to the existing
|
237
|
+
# - #merge: Merges multiple elements into the set; returns +self+.
|
238
|
+
# - #append: Adds a given object to the set, appending it to the existing
|
276
239
|
# string, and returns +self+.
|
277
240
|
# - #string=: Assigns a new #string value and replaces #elements to match.
|
278
241
|
# - #replace: Replaces the contents of the set with the contents
|
279
242
|
# of a given object.
|
243
|
+
# - #complement!: Replaces the contents of the set with its own #complement.
|
280
244
|
#
|
281
245
|
# === Methods for Deleting
|
282
|
-
# These methods remove elements from +self
|
283
|
-
# sorted and coalesced.
|
246
|
+
# These methods remove elements from +self+.
|
284
247
|
#
|
285
248
|
# - #clear: Removes all elements in the set; returns +self+.
|
286
|
-
# - #delete: Removes a given
|
287
|
-
# - #delete?: If the given
|
249
|
+
# - #delete: Removes a given object from the set; returns +self+.
|
250
|
+
# - #delete?: If the given object is an element in the set, removes it and
|
288
251
|
# returns it; otherwise, returns +nil+.
|
289
252
|
# - #delete_at: Removes the number at a given offset.
|
290
253
|
# - #slice!: Removes the number or consecutive numbers at a given offset or
|
291
254
|
# range of offsets.
|
292
|
-
# - #subtract: Removes
|
293
|
-
# +self+.
|
255
|
+
# - #subtract: Removes each given object from the set; returns +self+.
|
294
256
|
# - #limit!: Replaces <tt>*</tt> with a given maximum value and removes all
|
295
257
|
# members over that maximum; returns +self+.
|
296
258
|
#
|
@@ -321,18 +283,14 @@ module Net
|
|
321
283
|
private_constant :STAR_INT, :STARS
|
322
284
|
|
323
285
|
COERCIBLE = ->{ _1.respond_to? :to_sequence_set }
|
324
|
-
|
325
|
-
private_constant :COERCIBLE, :ENUMABLE
|
286
|
+
private_constant :COERCIBLE
|
326
287
|
|
327
288
|
class << self
|
328
289
|
|
329
290
|
# :call-seq:
|
330
|
-
# SequenceSet[*
|
331
|
-
#
|
332
|
-
# Returns a frozen SequenceSet, constructed from +inputs+.
|
291
|
+
# SequenceSet[*values] -> valid frozen sequence set
|
333
292
|
#
|
334
|
-
#
|
335
|
-
# returned.
|
293
|
+
# Returns a frozen SequenceSet, constructed from +values+.
|
336
294
|
#
|
337
295
|
# An empty SequenceSet is invalid and will raise a DataFormatError.
|
338
296
|
#
|
@@ -360,7 +318,7 @@ module Net
|
|
360
318
|
# raised.
|
361
319
|
def try_convert(obj)
|
362
320
|
return obj if obj.is_a?(SequenceSet)
|
363
|
-
return nil unless
|
321
|
+
return nil unless respond_to?(:to_sequence_set)
|
364
322
|
obj = obj.to_sequence_set
|
365
323
|
return obj if obj.is_a?(SequenceSet)
|
366
324
|
raise DataFormatError, "invalid object returned from to_sequence_set"
|
@@ -698,7 +656,7 @@ module Net
|
|
698
656
|
alias complement :~
|
699
657
|
|
700
658
|
# :call-seq:
|
701
|
-
# add(
|
659
|
+
# add(object) -> self
|
702
660
|
# self << other -> self
|
703
661
|
#
|
704
662
|
# Adds a range or number to the set and returns +self+.
|
@@ -706,8 +664,8 @@ module Net
|
|
706
664
|
# #string will be regenerated. Use #merge to add many elements at once.
|
707
665
|
#
|
708
666
|
# Related: #add?, #merge, #union
|
709
|
-
def add(
|
710
|
-
tuple_add input_to_tuple
|
667
|
+
def add(object)
|
668
|
+
tuple_add input_to_tuple object
|
711
669
|
normalize!
|
712
670
|
end
|
713
671
|
alias << add
|
@@ -716,29 +674,28 @@ module Net
|
|
716
674
|
#
|
717
675
|
# Unlike #add, #merge, or #union, the new value is appended to #string.
|
718
676
|
# This may result in a #string which has duplicates or is out-of-order.
|
719
|
-
def append(
|
677
|
+
def append(object)
|
720
678
|
modifying!
|
721
|
-
tuple = input_to_tuple
|
679
|
+
tuple = input_to_tuple object
|
722
680
|
entry = tuple_to_str tuple
|
723
|
-
string unless empty? # write @string before tuple_add
|
724
681
|
tuple_add tuple
|
725
|
-
@string = -(
|
682
|
+
@string = -(string ? "#{@string},#{entry}" : entry)
|
726
683
|
self
|
727
684
|
end
|
728
685
|
|
729
|
-
# :call-seq: add?(
|
686
|
+
# :call-seq: add?(object) -> self or nil
|
730
687
|
#
|
731
688
|
# Adds a range or number to the set and returns +self+. Returns +nil+
|
732
|
-
# when the
|
689
|
+
# when the object is already included in the set.
|
733
690
|
#
|
734
691
|
# #string will be regenerated. Use #merge to add many elements at once.
|
735
692
|
#
|
736
693
|
# Related: #add, #merge, #union, #include?
|
737
|
-
def add?(
|
738
|
-
add
|
694
|
+
def add?(object)
|
695
|
+
add object unless include? object
|
739
696
|
end
|
740
697
|
|
741
|
-
# :call-seq: delete(
|
698
|
+
# :call-seq: delete(object) -> self
|
742
699
|
#
|
743
700
|
# Deletes the given range or number from the set and returns +self+.
|
744
701
|
#
|
@@ -746,8 +703,8 @@ module Net
|
|
746
703
|
# many elements at once.
|
747
704
|
#
|
748
705
|
# Related: #delete?, #delete_at, #subtract, #difference
|
749
|
-
def delete(
|
750
|
-
tuple_subtract input_to_tuple
|
706
|
+
def delete(object)
|
707
|
+
tuple_subtract input_to_tuple object
|
751
708
|
normalize!
|
752
709
|
end
|
753
710
|
|
@@ -783,8 +740,8 @@ module Net
|
|
783
740
|
# #string will be regenerated after deletion.
|
784
741
|
#
|
785
742
|
# Related: #delete, #delete_at, #subtract, #difference, #disjoint?
|
786
|
-
def delete?(
|
787
|
-
tuple = input_to_tuple
|
743
|
+
def delete?(object)
|
744
|
+
tuple = input_to_tuple object
|
788
745
|
if tuple.first == tuple.last
|
789
746
|
return unless include_tuple? tuple
|
790
747
|
tuple_subtract tuple
|
@@ -828,31 +785,33 @@ module Net
|
|
828
785
|
deleted
|
829
786
|
end
|
830
787
|
|
831
|
-
# Merges all of the elements that appear in any of the +
|
788
|
+
# Merges all of the elements that appear in any of the +inputs+ into the
|
832
789
|
# set, and returns +self+.
|
833
790
|
#
|
834
|
-
# The +
|
835
|
-
# 32 bit unsigned integers, ranges, <tt>sequence-set</tt>
|
836
|
-
# strings, other sequence sets, or enumerables containing any of
|
791
|
+
# The +inputs+ may be any objects that would be accepted by ::new:
|
792
|
+
# non-zero 32 bit unsigned integers, ranges, <tt>sequence-set</tt>
|
793
|
+
# formatted strings, other sequence sets, or enumerables containing any of
|
794
|
+
# these.
|
837
795
|
#
|
838
|
-
# #string will be regenerated after all
|
796
|
+
# #string will be regenerated after all inputs have been merged.
|
839
797
|
#
|
840
798
|
# Related: #add, #add?, #union
|
841
|
-
def merge(*
|
842
|
-
tuples_add input_to_tuples
|
799
|
+
def merge(*inputs)
|
800
|
+
tuples_add input_to_tuples inputs
|
843
801
|
normalize!
|
844
802
|
end
|
845
803
|
|
846
|
-
# Removes all of the elements that appear in any of the given +
|
847
|
-
# the set, and returns +self+.
|
804
|
+
# Removes all of the elements that appear in any of the given +objects+
|
805
|
+
# from the set, and returns +self+.
|
848
806
|
#
|
849
|
-
# The +
|
850
|
-
# 32 bit unsigned integers, ranges, <tt>sequence-set</tt>
|
851
|
-
# strings, other sequence sets, or enumerables containing any of
|
807
|
+
# The +objects+ may be any objects that would be accepted by ::new:
|
808
|
+
# non-zero 32 bit unsigned integers, ranges, <tt>sequence-set</tt>
|
809
|
+
# formatted strings, other sequence sets, or enumerables containing any of
|
810
|
+
# these.
|
852
811
|
#
|
853
812
|
# Related: #difference
|
854
|
-
def subtract(*
|
855
|
-
tuples_subtract input_to_tuples
|
813
|
+
def subtract(*objects)
|
814
|
+
tuples_subtract input_to_tuples objects
|
856
815
|
normalize!
|
857
816
|
end
|
858
817
|
|
@@ -876,8 +835,8 @@ module Net
|
|
876
835
|
# <tt>*</tt> translates to an endless range. Use #limit to translate both
|
877
836
|
# cases to a maximum value.
|
878
837
|
#
|
879
|
-
#
|
880
|
-
#
|
838
|
+
# If the original input was unordered or contains overlapping ranges, the
|
839
|
+
# returned ranges will be ordered and coalesced.
|
881
840
|
#
|
882
841
|
# Net::IMAP::SequenceSet["2,5:9,6,*,12:11"].elements
|
883
842
|
# #=> [2, 5..9, 11..12, :*]
|
@@ -895,7 +854,7 @@ module Net
|
|
895
854
|
# translates to <tt>:*..</tt>. Use #limit to set <tt>*</tt> to a maximum
|
896
855
|
# value.
|
897
856
|
#
|
898
|
-
# The returned ranges will be
|
857
|
+
# The returned ranges will be ordered and coalesced, even when the input
|
899
858
|
# #string is not. <tt>*</tt> will sort last. See #normalize.
|
900
859
|
#
|
901
860
|
# Net::IMAP::SequenceSet["2,5:9,6,*,12:11"].ranges
|
@@ -944,7 +903,9 @@ module Net
|
|
944
903
|
# Related: #entries, #each_element
|
945
904
|
def each_entry(&block) # :yields: integer or range or :*
|
946
905
|
return to_enum(__method__) unless block_given?
|
947
|
-
|
906
|
+
return each_element(&block) unless @string
|
907
|
+
@string.split(",").each do yield tuple_to_entry str_to_tuple _1 end
|
908
|
+
self
|
948
909
|
end
|
949
910
|
|
950
911
|
# Yields each number or range (or <tt>:*</tt>) in #elements to the block
|
@@ -962,16 +923,6 @@ module Net
|
|
962
923
|
|
963
924
|
private
|
964
925
|
|
965
|
-
def each_entry_tuple(&block)
|
966
|
-
return to_enum(__method__) unless block_given?
|
967
|
-
if @string
|
968
|
-
@string.split(",") do block.call str_to_tuple _1 end
|
969
|
-
else
|
970
|
-
@tuples.each(&block)
|
971
|
-
end
|
972
|
-
self
|
973
|
-
end
|
974
|
-
|
975
926
|
def tuple_to_entry((min, max))
|
976
927
|
if min == STAR_INT then :*
|
977
928
|
elsif max == STAR_INT then min..
|
@@ -1003,34 +954,17 @@ module Net
|
|
1003
954
|
# Returns an enumerator when called without a block (even if the set
|
1004
955
|
# contains <tt>*</tt>).
|
1005
956
|
#
|
1006
|
-
# Related: #numbers
|
957
|
+
# Related: #numbers
|
1007
958
|
def each_number(&block) # :yields: integer
|
1008
959
|
return to_enum(__method__) unless block_given?
|
1009
960
|
raise RangeError, '%s contains "*"' % [self.class] if include_star?
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
# If the set contains a <tt>*</tt>, RangeError will be raised.
|
1016
|
-
#
|
1017
|
-
# Returns an enumerator when called without a block (even if the set
|
1018
|
-
# contains <tt>*</tt>).
|
1019
|
-
#
|
1020
|
-
# Related: #entries, #each_number
|
1021
|
-
def each_ordered_number(&block)
|
1022
|
-
return to_enum(__method__) unless block_given?
|
1023
|
-
raise RangeError, '%s contains "*"' % [self.class] if include_star?
|
1024
|
-
each_entry_tuple do each_number_in_tuple _1, _2, &block end
|
1025
|
-
end
|
1026
|
-
|
1027
|
-
private def each_number_in_tuple(min, max, &block)
|
1028
|
-
if min == STAR_INT then yield :*
|
1029
|
-
elsif min == max then yield min
|
1030
|
-
elsif max != STAR_INT then (min..max).each(&block)
|
1031
|
-
else
|
1032
|
-
raise RangeError, "#{SequenceSet} cannot enumerate range with '*'"
|
961
|
+
each_element do |elem|
|
962
|
+
case elem
|
963
|
+
when Range then elem.each(&block)
|
964
|
+
when Integer then block.(elem)
|
965
|
+
end
|
1033
966
|
end
|
967
|
+
self
|
1034
968
|
end
|
1035
969
|
|
1036
970
|
# Returns a Set with all of the #numbers in the sequence set.
|
@@ -1044,10 +978,8 @@ module Net
|
|
1044
978
|
|
1045
979
|
# Returns the count of #numbers in the set.
|
1046
980
|
#
|
1047
|
-
# <tt>*</tt>
|
1048
|
-
#
|
1049
|
-
#
|
1050
|
-
# Related: #count_with_duplicates
|
981
|
+
# If <tt>*</tt> and <tt>2**32 - 1</tt> (the maximum 32-bit unsigned
|
982
|
+
# integer value) are both in the set, they will only be counted once.
|
1051
983
|
def count
|
1052
984
|
@tuples.sum(@tuples.count) { _2 - _1 } +
|
1053
985
|
(include_star? && include?(UINT32_MAX) ? -1 : 0)
|
@@ -1055,87 +987,33 @@ module Net
|
|
1055
987
|
|
1056
988
|
alias size count
|
1057
989
|
|
1058
|
-
# Returns the
|
1059
|
-
#
|
1060
|
-
#
|
1061
|
-
# <tt>*</tt> will be counted as <tt>2**32 - 1</tt> (the maximum 32-bit
|
1062
|
-
# unsigned integer value).
|
1063
|
-
#
|
1064
|
-
# When #string is normalized, this behaves the same as #count.
|
1065
|
-
#
|
1066
|
-
# Related: #entries, #count_duplicates, #has_duplicates?
|
1067
|
-
def count_with_duplicates
|
1068
|
-
return count unless @string
|
1069
|
-
each_entry_tuple.sum {|min, max|
|
1070
|
-
max - min + ((max == STAR_INT && min != STAR_INT) ? 0 : 1)
|
1071
|
-
}
|
1072
|
-
end
|
1073
|
-
|
1074
|
-
# Returns the count of repeated numbers in the ordered #entries, the
|
1075
|
-
# difference between #count_with_duplicates and #count.
|
1076
|
-
#
|
1077
|
-
# When #string is normalized, this is zero.
|
1078
|
-
#
|
1079
|
-
# Related: #entries, #count_with_duplicates, #has_duplicates?
|
1080
|
-
def count_duplicates
|
1081
|
-
return 0 unless @string
|
1082
|
-
count_with_duplicates - count
|
1083
|
-
end
|
1084
|
-
|
1085
|
-
# :call-seq: has_duplicates? -> true | false
|
1086
|
-
#
|
1087
|
-
# Returns whether or not the ordered #entries repeat any numbers.
|
1088
|
-
#
|
1089
|
-
# Always returns +false+ when #string is normalized.
|
1090
|
-
#
|
1091
|
-
# Related: #entries, #count_with_duplicates, #count_duplicates?
|
1092
|
-
def has_duplicates?
|
1093
|
-
return false unless @string
|
1094
|
-
count_with_duplicates != count
|
1095
|
-
end
|
1096
|
-
|
1097
|
-
# Returns the (sorted and deduplicated) index of +number+ in the set, or
|
1098
|
-
# +nil+ if +number+ isn't in the set.
|
990
|
+
# Returns the index of +number+ in the set, or +nil+ if +number+ isn't in
|
991
|
+
# the set.
|
1099
992
|
#
|
1100
|
-
# Related: #[]
|
993
|
+
# Related: #[]
|
1101
994
|
def find_index(number)
|
1102
995
|
number = to_tuple_int number
|
1103
|
-
each_tuple_with_index
|
996
|
+
each_tuple_with_index do |min, max, idx_min|
|
1104
997
|
number < min and return nil
|
1105
998
|
number <= max and return from_tuple_int(idx_min + (number - min))
|
1106
999
|
end
|
1107
1000
|
nil
|
1108
1001
|
end
|
1109
1002
|
|
1110
|
-
# Returns the first index of +number+ in the ordered #entries, or
|
1111
|
-
# +nil+ if +number+ isn't in the set.
|
1112
|
-
#
|
1113
|
-
# Related: #find_index
|
1114
|
-
def find_ordered_index(number)
|
1115
|
-
number = to_tuple_int number
|
1116
|
-
each_tuple_with_index(each_entry_tuple) do |min, max, idx_min|
|
1117
|
-
if min <= number && number <= max
|
1118
|
-
return from_tuple_int(idx_min + (number - min))
|
1119
|
-
end
|
1120
|
-
end
|
1121
|
-
nil
|
1122
|
-
end
|
1123
|
-
|
1124
1003
|
private
|
1125
1004
|
|
1126
|
-
def each_tuple_with_index
|
1005
|
+
def each_tuple_with_index
|
1127
1006
|
idx_min = 0
|
1128
|
-
tuples.each do |min, max|
|
1129
|
-
idx_max = idx_min + (max - min)
|
1130
|
-
yield min, max, idx_min, idx_max
|
1007
|
+
@tuples.each do |min, max|
|
1008
|
+
yield min, max, idx_min, (idx_max = idx_min + (max - min))
|
1131
1009
|
idx_min = idx_max + 1
|
1132
1010
|
end
|
1133
1011
|
idx_min
|
1134
1012
|
end
|
1135
1013
|
|
1136
|
-
def reverse_each_tuple_with_index
|
1014
|
+
def reverse_each_tuple_with_index
|
1137
1015
|
idx_max = -1
|
1138
|
-
tuples.reverse_each do |min, max|
|
1016
|
+
@tuples.reverse_each do |min, max|
|
1139
1017
|
yield min, max, (idx_min = idx_max - (max - min)), idx_max
|
1140
1018
|
idx_max = idx_min - 1
|
1141
1019
|
end
|
@@ -1146,38 +1024,18 @@ module Net
|
|
1146
1024
|
|
1147
1025
|
# :call-seq: at(index) -> integer or nil
|
1148
1026
|
#
|
1149
|
-
# Returns
|
1150
|
-
#
|
1151
|
-
#
|
1152
|
-
# +index+ is interpreted the same as in #[], except that #at only allows a
|
1153
|
-
# single integer argument.
|
1027
|
+
# Returns a number from +self+, without modifying the set. Behaves the
|
1028
|
+
# same as #[], except that #at only allows a single integer argument.
|
1154
1029
|
#
|
1155
|
-
# Related: #[], #slice
|
1030
|
+
# Related: #[], #slice
|
1156
1031
|
def at(index)
|
1157
|
-
lookup_number_by_tuple_index(tuples, index)
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
# :call-seq: ordered_at(index) -> integer or nil
|
1161
|
-
#
|
1162
|
-
# Returns the number at the given +index+ in the ordered #entries, without
|
1163
|
-
# modifying the set.
|
1164
|
-
#
|
1165
|
-
# +index+ is interpreted the same as in #at (and #[]), except that
|
1166
|
-
# #ordered_at applies to the ordered #entries, not the sorted set.
|
1167
|
-
#
|
1168
|
-
# Related: #[], #slice, #ordered_at
|
1169
|
-
def ordered_at(index)
|
1170
|
-
lookup_number_by_tuple_index(each_entry_tuple, index)
|
1171
|
-
end
|
1172
|
-
|
1173
|
-
private def lookup_number_by_tuple_index(tuples, index)
|
1174
1032
|
index = Integer(index.to_int)
|
1175
1033
|
if index.negative?
|
1176
|
-
reverse_each_tuple_with_index
|
1034
|
+
reverse_each_tuple_with_index do |min, max, idx_min, idx_max|
|
1177
1035
|
idx_min <= index and return from_tuple_int(min + (index - idx_min))
|
1178
1036
|
end
|
1179
1037
|
else
|
1180
|
-
each_tuple_with_index
|
1038
|
+
each_tuple_with_index do |min, _, idx_min, idx_max|
|
1181
1039
|
index <= idx_max and return from_tuple_int(min + (index - idx_min))
|
1182
1040
|
end
|
1183
1041
|
end
|
@@ -1192,18 +1050,17 @@ module Net
|
|
1192
1050
|
# seqset[range] -> sequence set or nil
|
1193
1051
|
# slice(range) -> sequence set or nil
|
1194
1052
|
#
|
1195
|
-
# Returns a number or a subset from
|
1196
|
-
# the set.
|
1053
|
+
# Returns a number or a subset from +self+, without modifying the set.
|
1197
1054
|
#
|
1198
1055
|
# When an Integer argument +index+ is given, the number at offset +index+
|
1199
|
-
#
|
1056
|
+
# is returned:
|
1200
1057
|
#
|
1201
1058
|
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
1202
1059
|
# set[0] #=> 10
|
1203
1060
|
# set[5] #=> 15
|
1204
1061
|
# set[10] #=> 26
|
1205
1062
|
#
|
1206
|
-
# If +index+ is negative, it counts relative to the end of
|
1063
|
+
# If +index+ is negative, it counts relative to the end of +self+:
|
1207
1064
|
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
|
1208
1065
|
# set[-1] #=> 26
|
1209
1066
|
# set[-3] #=> 22
|
@@ -1215,14 +1072,13 @@ module Net
|
|
1215
1072
|
# set[11] #=> nil
|
1216
1073
|
# set[-12] #=> nil
|
1217
1074
|
#
|
1218
|
-
# The result is based on the sorted and de-duplicated
|
1219
|
-
#
|
1075
|
+
# The result is based on the normalized set—sorted and de-duplicated—not
|
1076
|
+
# on the assigned value of #string.
|
1220
1077
|
#
|
1221
1078
|
# set = Net::IMAP::SequenceSet["12,20:23,11:16,21"]
|
1222
1079
|
# set[0] #=> 11
|
1223
1080
|
# set[-1] #=> 23
|
1224
1081
|
#
|
1225
|
-
# Related: #at
|
1226
1082
|
def [](index, length = nil)
|
1227
1083
|
if length then slice_length(index, length)
|
1228
1084
|
elsif index.is_a?(Range) then slice_range(index)
|
@@ -1392,29 +1248,30 @@ module Net
|
|
1392
1248
|
super
|
1393
1249
|
end
|
1394
1250
|
|
1395
|
-
def input_to_tuple(
|
1396
|
-
|
1397
|
-
case
|
1398
|
-
when *STARS, Integer then [int = to_tuple_int(
|
1399
|
-
when Range then range_to_tuple(
|
1400
|
-
when String then str_to_tuple(
|
1251
|
+
def input_to_tuple(obj)
|
1252
|
+
obj = input_try_convert obj
|
1253
|
+
case obj
|
1254
|
+
when *STARS, Integer then [int = to_tuple_int(obj), int]
|
1255
|
+
when Range then range_to_tuple(obj)
|
1256
|
+
when String then str_to_tuple(obj)
|
1401
1257
|
else
|
1402
|
-
raise DataFormatError, "expected number or range, got %p" % [
|
1258
|
+
raise DataFormatError, "expected number or range, got %p" % [obj]
|
1403
1259
|
end
|
1404
1260
|
end
|
1405
1261
|
|
1406
|
-
def input_to_tuples(
|
1407
|
-
|
1408
|
-
case
|
1409
|
-
when *STARS, Integer, Range then [input_to_tuple(
|
1410
|
-
when String then str_to_tuples
|
1411
|
-
when SequenceSet then
|
1412
|
-
when
|
1262
|
+
def input_to_tuples(obj)
|
1263
|
+
obj = input_try_convert obj
|
1264
|
+
case obj
|
1265
|
+
when *STARS, Integer, Range then [input_to_tuple(obj)]
|
1266
|
+
when String then str_to_tuples obj
|
1267
|
+
when SequenceSet then obj.tuples
|
1268
|
+
when Set then obj.map { [to_tuple_int(_1)] * 2 }
|
1269
|
+
when Array then obj.flat_map { input_to_tuples _1 }
|
1413
1270
|
when nil then []
|
1414
1271
|
else
|
1415
1272
|
raise DataFormatError,
|
1416
1273
|
"expected nz-number, range, string, or enumerable; " \
|
1417
|
-
"got %p" % [
|
1274
|
+
"got %p" % [obj]
|
1418
1275
|
end
|
1419
1276
|
end
|
1420
1277
|
|
@@ -1422,8 +1279,7 @@ module Net
|
|
1422
1279
|
# String, Set, Array, or... any type of object.
|
1423
1280
|
def input_try_convert(input)
|
1424
1281
|
SequenceSet.try_convert(input) ||
|
1425
|
-
|
1426
|
-
input.respond_to?(:to_int) && Integer(input.to_int) ||
|
1282
|
+
Integer.try_convert(input) ||
|
1427
1283
|
String.try_convert(input) ||
|
1428
1284
|
input
|
1429
1285
|
end
|
@@ -1478,8 +1334,8 @@ module Net
|
|
1478
1334
|
modifying!
|
1479
1335
|
min, max = tuple
|
1480
1336
|
lower, lower_idx = tuple_gte_with_index(min - 1)
|
1481
|
-
if lower.nil? then tuples <<
|
1482
|
-
elsif (max + 1) < lower.first then tuples.insert(lower_idx,
|
1337
|
+
if lower.nil? then tuples << tuple
|
1338
|
+
elsif (max + 1) < lower.first then tuples.insert(lower_idx, tuple)
|
1483
1339
|
else tuple_coalesce(lower, lower_idx, min, max)
|
1484
1340
|
end
|
1485
1341
|
end
|
@@ -1553,12 +1409,11 @@ module Net
|
|
1553
1409
|
end
|
1554
1410
|
|
1555
1411
|
def nz_number(num)
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
num
|
1412
|
+
String === num && !/\A[1-9]\d*\z/.match?(num) and
|
1413
|
+
raise DataFormatError, "%p is not a valid nz-number" % [num]
|
1414
|
+
NumValidator.ensure_nz_number Integer num
|
1415
|
+
rescue TypeError # To catch errors from Integer()
|
1416
|
+
raise DataFormatError, $!.message
|
1562
1417
|
end
|
1563
1418
|
|
1564
1419
|
# intentionally defined after the class implementation
|