net-imap 0.5.6 → 0.5.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/lib/net/imap/config/attr_type_coercion.rb +23 -22
- data/lib/net/imap/config.rb +101 -19
- data/lib/net/imap/connection_state.rb +48 -0
- data/lib/net/imap/errors.rb +33 -0
- data/lib/net/imap/response_reader.rb +73 -0
- data/lib/net/imap/sequence_set.rb +253 -97
- data/lib/net/imap.rb +218 -47
- metadata +5 -3
@@ -108,11 +108,15 @@ module Net
|
|
108
108
|
# When a set includes <tt>*</tt>, some methods may have surprising behavior.
|
109
109
|
#
|
110
110
|
# For example, #complement treats <tt>*</tt> as its own number. This way,
|
111
|
-
# the #intersection of a set and its #complement will always be empty.
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
111
|
+
# the #intersection of a set and its #complement will always be empty. And
|
112
|
+
# <tt>*</tt> is sorted as greater than any other number in the set. This is
|
113
|
+
# not how an \IMAP server interprets the set: it will convert <tt>*</tt> to
|
114
|
+
# the number of messages in the mailbox, the +UID+ of the last message in
|
115
|
+
# the mailbox, or +UIDNEXT+, as appropriate. Several methods have an
|
116
|
+
# argument for how <tt>*</tt> should be interpreted.
|
117
|
+
#
|
118
|
+
# But, for example, this means that there may be overlap between a set and
|
119
|
+
# its complement after #limit is applied to each:
|
116
120
|
#
|
117
121
|
# ~Net::IMAP::SequenceSet["*"] == Net::IMAP::SequenceSet[1..(2**32-1)]
|
118
122
|
# ~Net::IMAP::SequenceSet[1..5] == Net::IMAP::SequenceSet["6:*"]
|
@@ -174,14 +178,14 @@ module Net
|
|
174
178
|
#
|
175
179
|
# <i>Set membership:</i>
|
176
180
|
# - #include? (aliased as #member?):
|
177
|
-
# Returns whether a given
|
181
|
+
# Returns whether a given element (nz-number, range, or <tt>*</tt>) is
|
178
182
|
# contained by the set.
|
179
183
|
# - #include_star?: Returns whether the set contains <tt>*</tt>.
|
180
184
|
#
|
181
185
|
# <i>Minimum and maximum value elements:</i>
|
182
|
-
# - #min: Returns the
|
183
|
-
# - #max: Returns the
|
184
|
-
# - #minmax: Returns the
|
186
|
+
# - #min: Returns one or more of the lowest numbers in the set.
|
187
|
+
# - #max: Returns one or more of the highest numbers in the set.
|
188
|
+
# - #minmax: Returns the lowest and highest numbers in the set.
|
185
189
|
#
|
186
190
|
# <i>Accessing value by offset in sorted set:</i>
|
187
191
|
# - #[] (aliased as #slice): Returns the number or consecutive subset at a
|
@@ -239,15 +243,19 @@ module Net
|
|
239
243
|
# These methods do not modify +self+.
|
240
244
|
#
|
241
245
|
# - #| (aliased as #union and #+): Returns a new set combining all members
|
242
|
-
# from +self+ with all members from the other
|
246
|
+
# from +self+ with all members from the other set.
|
243
247
|
# - #& (aliased as #intersection): Returns a new set containing all members
|
244
|
-
# common to +self+ and the other
|
248
|
+
# common to +self+ and the other set.
|
245
249
|
# - #- (aliased as #difference): Returns a copy of +self+ with all members
|
246
|
-
# in the other
|
250
|
+
# in the other set removed.
|
247
251
|
# - #^ (aliased as #xor): Returns a new set containing all members from
|
248
|
-
# +self+ and the other
|
252
|
+
# +self+ and the other set except those common to both.
|
249
253
|
# - #~ (aliased as #complement): Returns a new set containing all members
|
250
254
|
# that are not in +self+
|
255
|
+
# - #above: Return a copy of +self+ which only contains numbers above a
|
256
|
+
# given number.
|
257
|
+
# - #below: Return a copy of +self+ which only contains numbers below a
|
258
|
+
# given value.
|
251
259
|
# - #limit: Returns a copy of +self+ which has replaced <tt>*</tt> with a
|
252
260
|
# given maximum value and removed all members over that maximum.
|
253
261
|
#
|
@@ -258,17 +266,17 @@ module Net
|
|
258
266
|
#
|
259
267
|
# These methods always update #string to be fully sorted and coalesced.
|
260
268
|
#
|
261
|
-
# - #add (aliased as #<<): Adds a given
|
262
|
-
# - #add?: If the given
|
269
|
+
# - #add (aliased as #<<): Adds a given element to the set; returns +self+.
|
270
|
+
# - #add?: If the given element is not fully included the set, adds it and
|
263
271
|
# returns +self+; otherwise, returns +nil+.
|
264
|
-
# - #merge:
|
272
|
+
# - #merge: Adds all members of the given sets into this set; returns +self+.
|
265
273
|
# - #complement!: Replaces the contents of the set with its own #complement.
|
266
274
|
#
|
267
275
|
# <i>Order preserving:</i>
|
268
276
|
#
|
269
277
|
# These methods _may_ cause #string to not be sorted or coalesced.
|
270
278
|
#
|
271
|
-
# - #append: Adds
|
279
|
+
# - #append: Adds the given entry to the set, appending it to the existing
|
272
280
|
# string, and returns +self+.
|
273
281
|
# - #string=: Assigns a new #string value and replaces #elements to match.
|
274
282
|
# - #replace: Replaces the contents of the set with the contents
|
@@ -279,13 +287,14 @@ module Net
|
|
279
287
|
# sorted and coalesced.
|
280
288
|
#
|
281
289
|
# - #clear: Removes all elements in the set; returns +self+.
|
282
|
-
# - #delete: Removes a given
|
283
|
-
# - #delete?: If the given
|
290
|
+
# - #delete: Removes a given element from the set; returns +self+.
|
291
|
+
# - #delete?: If the given element is included in the set, removes it and
|
284
292
|
# returns it; otherwise, returns +nil+.
|
285
293
|
# - #delete_at: Removes the number at a given offset.
|
286
294
|
# - #slice!: Removes the number or consecutive numbers at a given offset or
|
287
295
|
# range of offsets.
|
288
|
-
# - #subtract: Removes
|
296
|
+
# - #subtract: Removes all members of the given sets from this set; returns
|
297
|
+
# +self+.
|
289
298
|
# - #limit!: Replaces <tt>*</tt> with a given maximum value and removes all
|
290
299
|
# members over that maximum; returns +self+.
|
291
300
|
#
|
@@ -318,9 +327,12 @@ module Net
|
|
318
327
|
class << self
|
319
328
|
|
320
329
|
# :call-seq:
|
321
|
-
# SequenceSet[*
|
330
|
+
# SequenceSet[*inputs] -> valid frozen sequence set
|
331
|
+
#
|
332
|
+
# Returns a frozen SequenceSet, constructed from +inputs+.
|
322
333
|
#
|
323
|
-
#
|
334
|
+
# When only a single valid frozen SequenceSet is given, that same set is
|
335
|
+
# returned.
|
324
336
|
#
|
325
337
|
# An empty SequenceSet is invalid and will raise a DataFormatError.
|
326
338
|
#
|
@@ -563,26 +575,52 @@ module Net
|
|
563
575
|
empty? || input_to_tuples(other).none? { intersect_tuple? _1 }
|
564
576
|
end
|
565
577
|
|
566
|
-
# :call-seq:
|
578
|
+
# :call-seq:
|
579
|
+
# max(star: :*) => integer or star or nil
|
580
|
+
# max(count, star: :*) => SequenceSet
|
567
581
|
#
|
568
582
|
# Returns the maximum value in +self+, +star+ when the set includes
|
569
583
|
# <tt>*</tt>, or +nil+ when the set is empty.
|
570
|
-
|
571
|
-
|
584
|
+
#
|
585
|
+
# When +count+ is given, a new SequenceSet is returned, containing only
|
586
|
+
# the last +count+ numbers. An empty SequenceSet is returned when +self+
|
587
|
+
# is empty. (+star+ is ignored when +count+ is given.)
|
588
|
+
#
|
589
|
+
# Related: #min, #minmax, #slice
|
590
|
+
def max(count = nil, star: :*)
|
591
|
+
if count
|
592
|
+
slice(-[count, size].min..) || remain_frozen_empty
|
593
|
+
elsif (val = @tuples.last&.last)
|
594
|
+
val == STAR_INT ? star : val
|
595
|
+
end
|
572
596
|
end
|
573
597
|
|
574
|
-
# :call-seq:
|
598
|
+
# :call-seq:
|
599
|
+
# min(star: :*) => integer or star or nil
|
600
|
+
# min(count, star: :*) => SequenceSet
|
575
601
|
#
|
576
602
|
# Returns the minimum value in +self+, +star+ when the only value in the
|
577
603
|
# set is <tt>*</tt>, or +nil+ when the set is empty.
|
578
|
-
|
579
|
-
|
604
|
+
#
|
605
|
+
# When +count+ is given, a new SequenceSet is returned, containing only
|
606
|
+
# the first +count+ numbers. An empty SequenceSet is returned when +self+
|
607
|
+
# is empty. (+star+ is ignored when +count+ is given.)
|
608
|
+
#
|
609
|
+
# Related: #max, #minmax, #slice
|
610
|
+
def min(count = nil, star: :*)
|
611
|
+
if count
|
612
|
+
slice(0...count) || remain_frozen_empty
|
613
|
+
elsif (val = @tuples.first&.first)
|
614
|
+
val != STAR_INT ? val : star
|
615
|
+
end
|
580
616
|
end
|
581
617
|
|
582
618
|
# :call-seq: minmax(star: :*) => nil or [integer, integer or star]
|
583
619
|
#
|
584
620
|
# Returns a 2-element array containing the minimum and maximum numbers in
|
585
621
|
# +self+, or +nil+ when the set is empty.
|
622
|
+
#
|
623
|
+
# Related: #min, #max
|
586
624
|
def minmax(star: :*); [min(star: star), max(star: star)] unless empty? end
|
587
625
|
|
588
626
|
# Returns false when the set is empty.
|
@@ -609,7 +647,14 @@ module Net
|
|
609
647
|
# Net::IMAP::SequenceSet["1:5"] | 2 | [4..6, 99]
|
610
648
|
# #=> Net::IMAP::SequenceSet["1:6,99"]
|
611
649
|
#
|
612
|
-
# Related: #add, #merge
|
650
|
+
# Related: #add, #merge, #&, #-, #^, #~
|
651
|
+
#
|
652
|
+
# ==== Set identities
|
653
|
+
#
|
654
|
+
# <tt>lhs | rhs</tt> is equivalent to:
|
655
|
+
# * <tt>rhs | lhs</tt> (commutative)
|
656
|
+
# * <tt>~(~lhs & ~rhs)</tt> (De Morgan's Law)
|
657
|
+
# * <tt>(lhs & rhs) ^ (lhs ^ rhs)</tt>
|
613
658
|
def |(other) remain_frozen dup.merge other end
|
614
659
|
alias :+ :|
|
615
660
|
alias union :|
|
@@ -628,7 +673,17 @@ module Net
|
|
628
673
|
# Net::IMAP::SequenceSet[1..5] - 2 - 4 - 6
|
629
674
|
# #=> Net::IMAP::SequenceSet["1,3,5"]
|
630
675
|
#
|
631
|
-
# Related: #subtract
|
676
|
+
# Related: #subtract, #|, #&, #^, #~
|
677
|
+
#
|
678
|
+
# ==== Set identities
|
679
|
+
#
|
680
|
+
# <tt>lhs - rhs</tt> is equivalent to:
|
681
|
+
# * <tt>~r - ~l</tt>
|
682
|
+
# * <tt>lhs & ~rhs</tt>
|
683
|
+
# * <tt>~(~lhs | rhs)</tt>
|
684
|
+
# * <tt>lhs & (lhs ^ rhs)</tt>
|
685
|
+
# * <tt>lhs ^ (lhs & rhs)</tt>
|
686
|
+
# * <tt>rhs ^ (lhs | rhs)</tt>
|
632
687
|
def -(other) remain_frozen dup.subtract other end
|
633
688
|
alias difference :-
|
634
689
|
|
@@ -646,7 +701,17 @@ module Net
|
|
646
701
|
# Net::IMAP::SequenceSet[1..5] & [2, 4, 6]
|
647
702
|
# #=> Net::IMAP::SequenceSet["2,4"]
|
648
703
|
#
|
649
|
-
#
|
704
|
+
# Related: #intersect?, #|, #-, #^, #~
|
705
|
+
#
|
706
|
+
# ==== Set identities
|
707
|
+
#
|
708
|
+
# <tt>lhs & rhs</tt> is equivalent to:
|
709
|
+
# * <tt>rhs & lhs</tt> (commutative)
|
710
|
+
# * <tt>~(~lhs | ~rhs)</tt> (De Morgan's Law)
|
711
|
+
# * <tt>lhs - ~rhs</tt>
|
712
|
+
# * <tt>lhs - (lhs - rhs)</tt>
|
713
|
+
# * <tt>lhs - (lhs ^ rhs)</tt>
|
714
|
+
# * <tt>lhs ^ (lhs - rhs)</tt>
|
650
715
|
def &(other)
|
651
716
|
remain_frozen dup.subtract SequenceSet.new(other).complement!
|
652
717
|
end
|
@@ -666,9 +731,17 @@ module Net
|
|
666
731
|
# Net::IMAP::SequenceSet[1..5] ^ [2, 4, 6]
|
667
732
|
# #=> Net::IMAP::SequenceSet["1,3,5:6"]
|
668
733
|
#
|
669
|
-
#
|
670
|
-
#
|
671
|
-
|
734
|
+
# Related: #|, #&, #-, #~
|
735
|
+
#
|
736
|
+
# ==== Set identities
|
737
|
+
#
|
738
|
+
# <tt>lhs ^ rhs</tt> is equivalent to:
|
739
|
+
# * <tt>rhs ^ lhs</tt> (commutative)
|
740
|
+
# * <tt>~lhs ^ ~rhs</tt>
|
741
|
+
# * <tt>(lhs | rhs) - (lhs & rhs)</tt>
|
742
|
+
# * <tt>(lhs - rhs) | (rhs - lhs)</tt>
|
743
|
+
# * <tt>(lhs ^ other) ^ (other ^ rhs)</tt>
|
744
|
+
def ^(other) remain_frozen (dup | other).subtract(self & other) end
|
672
745
|
alias xor :^
|
673
746
|
|
674
747
|
# :call-seq:
|
@@ -685,21 +758,29 @@ module Net
|
|
685
758
|
# ~Net::IMAP::SequenceSet["6:99,223:*"]
|
686
759
|
# #=> Net::IMAP::SequenceSet["1:5,100:222"]
|
687
760
|
#
|
688
|
-
# Related: #complement
|
761
|
+
# Related: #complement!, #|, #&, #-, #^
|
762
|
+
#
|
763
|
+
# ==== Set identities
|
764
|
+
#
|
765
|
+
# <tt>~set</tt> is equivalent to:
|
766
|
+
# * <tt>full - set</tt>, where "full" is Net::IMAP::SequenceSet.full
|
689
767
|
def ~; remain_frozen dup.complement! end
|
690
768
|
alias complement :~
|
691
769
|
|
692
770
|
# :call-seq:
|
693
|
-
# add(
|
771
|
+
# add(element) -> self
|
694
772
|
# self << other -> self
|
695
773
|
#
|
696
774
|
# Adds a range or number to the set and returns +self+.
|
697
775
|
#
|
698
776
|
# #string will be regenerated. Use #merge to add many elements at once.
|
699
777
|
#
|
700
|
-
#
|
701
|
-
|
702
|
-
|
778
|
+
# Use #append to append new elements to #string. See
|
779
|
+
# Net::IMAP@Ordered+and+Normalized+Sets.
|
780
|
+
#
|
781
|
+
# Related: #add?, #merge, #union, #append
|
782
|
+
def add(element)
|
783
|
+
tuple_add input_to_tuple element
|
703
784
|
normalize!
|
704
785
|
end
|
705
786
|
alias << add
|
@@ -708,9 +789,13 @@ module Net
|
|
708
789
|
#
|
709
790
|
# Unlike #add, #merge, or #union, the new value is appended to #string.
|
710
791
|
# This may result in a #string which has duplicates or is out-of-order.
|
711
|
-
|
792
|
+
#
|
793
|
+
# See Net::IMAP@Ordered+and+Normalized+Sets.
|
794
|
+
#
|
795
|
+
# Related: #add, #merge, #union
|
796
|
+
def append(entry)
|
712
797
|
modifying!
|
713
|
-
tuple = input_to_tuple
|
798
|
+
tuple = input_to_tuple entry
|
714
799
|
entry = tuple_to_str tuple
|
715
800
|
string unless empty? # write @string before tuple_add
|
716
801
|
tuple_add tuple
|
@@ -718,19 +803,19 @@ module Net
|
|
718
803
|
self
|
719
804
|
end
|
720
805
|
|
721
|
-
# :call-seq: add?(
|
806
|
+
# :call-seq: add?(element) -> self or nil
|
722
807
|
#
|
723
808
|
# Adds a range or number to the set and returns +self+. Returns +nil+
|
724
|
-
# when the
|
809
|
+
# when the element is already included in the set.
|
725
810
|
#
|
726
811
|
# #string will be regenerated. Use #merge to add many elements at once.
|
727
812
|
#
|
728
813
|
# Related: #add, #merge, #union, #include?
|
729
|
-
def add?(
|
730
|
-
add
|
814
|
+
def add?(element)
|
815
|
+
add element unless include? element
|
731
816
|
end
|
732
817
|
|
733
|
-
# :call-seq: delete(
|
818
|
+
# :call-seq: delete(element) -> self
|
734
819
|
#
|
735
820
|
# Deletes the given range or number from the set and returns +self+.
|
736
821
|
#
|
@@ -738,8 +823,8 @@ module Net
|
|
738
823
|
# many elements at once.
|
739
824
|
#
|
740
825
|
# Related: #delete?, #delete_at, #subtract, #difference
|
741
|
-
def delete(
|
742
|
-
tuple_subtract input_to_tuple
|
826
|
+
def delete(element)
|
827
|
+
tuple_subtract input_to_tuple element
|
743
828
|
normalize!
|
744
829
|
end
|
745
830
|
|
@@ -775,8 +860,8 @@ module Net
|
|
775
860
|
# #string will be regenerated after deletion.
|
776
861
|
#
|
777
862
|
# Related: #delete, #delete_at, #subtract, #difference, #disjoint?
|
778
|
-
def delete?(
|
779
|
-
tuple = input_to_tuple
|
863
|
+
def delete?(element)
|
864
|
+
tuple = input_to_tuple element
|
780
865
|
if tuple.first == tuple.last
|
781
866
|
return unless include_tuple? tuple
|
782
867
|
tuple_subtract tuple
|
@@ -820,33 +905,31 @@ module Net
|
|
820
905
|
deleted
|
821
906
|
end
|
822
907
|
|
823
|
-
# Merges all of the elements that appear in any of the +
|
908
|
+
# Merges all of the elements that appear in any of the +sets+ into the
|
824
909
|
# set, and returns +self+.
|
825
910
|
#
|
826
|
-
# The +
|
827
|
-
#
|
828
|
-
#
|
829
|
-
# these.
|
911
|
+
# The +sets+ may be any objects that would be accepted by ::new: non-zero
|
912
|
+
# 32 bit unsigned integers, ranges, <tt>sequence-set</tt> formatted
|
913
|
+
# strings, other sequence sets, or enumerables containing any of these.
|
830
914
|
#
|
831
|
-
# #string will be regenerated after all
|
915
|
+
# #string will be regenerated after all sets have been merged.
|
832
916
|
#
|
833
917
|
# Related: #add, #add?, #union
|
834
|
-
def merge(*
|
835
|
-
tuples_add input_to_tuples
|
918
|
+
def merge(*sets)
|
919
|
+
tuples_add input_to_tuples sets
|
836
920
|
normalize!
|
837
921
|
end
|
838
922
|
|
839
|
-
# Removes all of the elements that appear in any of the given +
|
840
|
-
#
|
923
|
+
# Removes all of the elements that appear in any of the given +sets+ from
|
924
|
+
# the set, and returns +self+.
|
841
925
|
#
|
842
|
-
# The +
|
843
|
-
#
|
844
|
-
#
|
845
|
-
# these.
|
926
|
+
# The +sets+ may be any objects that would be accepted by ::new: non-zero
|
927
|
+
# 32 bit unsigned integers, ranges, <tt>sequence-set</tt> formatted
|
928
|
+
# strings, other sequence sets, or enumerables containing any of these.
|
846
929
|
#
|
847
930
|
# Related: #difference
|
848
|
-
def subtract(*
|
849
|
-
tuples_subtract input_to_tuples
|
931
|
+
def subtract(*sets)
|
932
|
+
tuples_subtract input_to_tuples sets
|
850
933
|
normalize!
|
851
934
|
end
|
852
935
|
|
@@ -858,21 +941,21 @@ module Net
|
|
858
941
|
# This is useful when the given order is significant, for example in a
|
859
942
|
# ESEARCH response to IMAP#sort.
|
860
943
|
#
|
944
|
+
# See Net::IMAP@Ordered+and+Normalized+Sets.
|
945
|
+
#
|
861
946
|
# Related: #each_entry, #elements
|
862
947
|
def entries; each_entry.to_a end
|
863
948
|
|
864
949
|
# Returns an array of ranges and integers and <tt>:*</tt>.
|
865
950
|
#
|
866
951
|
# The returned elements are sorted and coalesced, even when the input
|
867
|
-
# #string is not. <tt>*</tt> will sort last. See #normalize
|
952
|
+
# #string is not. <tt>*</tt> will sort last. See #normalize,
|
953
|
+
# Net::IMAP@Ordered+and+Normalized+Sets.
|
868
954
|
#
|
869
955
|
# By itself, <tt>*</tt> translates to <tt>:*</tt>. A range containing
|
870
956
|
# <tt>*</tt> translates to an endless range. Use #limit to translate both
|
871
957
|
# cases to a maximum value.
|
872
958
|
#
|
873
|
-
# The returned elements will be sorted and coalesced, even when the input
|
874
|
-
# #string is not. <tt>*</tt> will sort last. See #normalize.
|
875
|
-
#
|
876
959
|
# Net::IMAP::SequenceSet["2,5:9,6,*,12:11"].elements
|
877
960
|
# #=> [2, 5..9, 11..12, :*]
|
878
961
|
#
|
@@ -883,15 +966,13 @@ module Net
|
|
883
966
|
# Returns an array of ranges
|
884
967
|
#
|
885
968
|
# The returned elements are sorted and coalesced, even when the input
|
886
|
-
# #string is not. <tt>*</tt> will sort last. See #normalize
|
969
|
+
# #string is not. <tt>*</tt> will sort last. See #normalize,
|
970
|
+
# Net::IMAP@Ordered+and+Normalized+Sets.
|
887
971
|
#
|
888
972
|
# <tt>*</tt> translates to an endless range. By itself, <tt>*</tt>
|
889
973
|
# translates to <tt>:*..</tt>. Use #limit to set <tt>*</tt> to a maximum
|
890
974
|
# value.
|
891
975
|
#
|
892
|
-
# The returned ranges will be sorted and coalesced, even when the input
|
893
|
-
# #string is not. <tt>*</tt> will sort last. See #normalize.
|
894
|
-
#
|
895
976
|
# Net::IMAP::SequenceSet["2,5:9,6,*,12:11"].ranges
|
896
977
|
# #=> [2..2, 5..9, 11..12, :*..]
|
897
978
|
# Net::IMAP::SequenceSet["123,999:*,456:789"].ranges
|
@@ -903,7 +984,7 @@ module Net
|
|
903
984
|
# Returns a sorted array of all of the number values in the sequence set.
|
904
985
|
#
|
905
986
|
# The returned numbers are sorted and de-duplicated, even when the input
|
906
|
-
# #string is not. See #normalize.
|
987
|
+
# #string is not. See #normalize, Net::IMAP@Ordered+and+Normalized+Sets.
|
907
988
|
#
|
908
989
|
# Net::IMAP::SequenceSet["2,5:9,6,12:11"].numbers
|
909
990
|
# #=> [2, 5, 6, 7, 8, 9, 11, 12]
|
@@ -935,6 +1016,8 @@ module Net
|
|
935
1016
|
# no sorting, deduplication, or coalescing. When #string is in its
|
936
1017
|
# normalized form, this will yield the same values as #each_element.
|
937
1018
|
#
|
1019
|
+
# See Net::IMAP@Ordered+and+Normalized+Sets.
|
1020
|
+
#
|
938
1021
|
# Related: #entries, #each_element
|
939
1022
|
def each_entry(&block) # :yields: integer or range or :*
|
940
1023
|
return to_enum(__method__) unless block_given?
|
@@ -945,7 +1028,7 @@ module Net
|
|
945
1028
|
# and returns self. Returns an enumerator when called without a block.
|
946
1029
|
#
|
947
1030
|
# The returned numbers are sorted and de-duplicated, even when the input
|
948
|
-
# #string is not. See #normalize.
|
1031
|
+
# #string is not. See #normalize, Net::IMAP@Ordered+and+Normalized+Sets.
|
949
1032
|
#
|
950
1033
|
# Related: #elements, #each_entry
|
951
1034
|
def each_element # :yields: integer or range or :*
|
@@ -1239,20 +1322,76 @@ module Net
|
|
1239
1322
|
def slice_range(range)
|
1240
1323
|
first = range.begin || 0
|
1241
1324
|
last = range.end || -1
|
1242
|
-
|
1325
|
+
if range.exclude_end?
|
1326
|
+
return remain_frozen_empty if last.zero?
|
1327
|
+
last -= 1 if range.end && last != STAR_INT
|
1328
|
+
end
|
1243
1329
|
if (first * last).positive? && last < first
|
1244
|
-
|
1330
|
+
remain_frozen_empty
|
1245
1331
|
elsif (min = at(first))
|
1246
1332
|
max = at(last)
|
1333
|
+
max = :* if max.nil?
|
1247
1334
|
if max == :* then self & (min..)
|
1248
1335
|
elsif min <= max then self & (min..max)
|
1249
|
-
else
|
1336
|
+
else remain_frozen_empty
|
1250
1337
|
end
|
1251
1338
|
end
|
1252
1339
|
end
|
1253
1340
|
|
1254
1341
|
public
|
1255
1342
|
|
1343
|
+
# Returns a copy of +self+ which only contains the numbers above +num+.
|
1344
|
+
#
|
1345
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].above(10) # to_s => "11:22,50"
|
1346
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].above(20) # to_s => "21:22,50
|
1347
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].above(30) # to_s => "50"
|
1348
|
+
#
|
1349
|
+
# This returns the same result as #intersection with <tt>((num+1)..)</tt>
|
1350
|
+
# or #difference with <tt>(..num)</tt>.
|
1351
|
+
#
|
1352
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] & (11..) # to_s => "11:22,50"
|
1353
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] - (..10) # to_s => "11:22,50"
|
1354
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] & (21..) # to_s => "21:22,50"
|
1355
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] - (..20) # to_s => "21:22,50"
|
1356
|
+
#
|
1357
|
+
# Related: #above, #-, #&
|
1358
|
+
def above(num)
|
1359
|
+
NumValidator.valid_nz_number?(num) or
|
1360
|
+
raise ArgumentError, "not a valid sequence set number"
|
1361
|
+
difference(..num)
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
# Returns a copy of +self+ which only contains numbers below +num+.
|
1365
|
+
#
|
1366
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].below(10) # to_s => "5"
|
1367
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].below(20) # to_s => "5,10:19"
|
1368
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].below(30) # to_s => "5,10:22"
|
1369
|
+
#
|
1370
|
+
# This returns the same result as #intersection with <tt>(..(num-1))</tt>
|
1371
|
+
# or #difference with <tt>(num..)</tt>.
|
1372
|
+
#
|
1373
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] & (..9) # to_s => "5"
|
1374
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] - (10..) # to_s => "5"
|
1375
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] & (..19) # to_s => "5,10:19"
|
1376
|
+
# Net::IMAP::SequenceSet["5,10:22,50"] - (20..) # to_s => "5,10:19"
|
1377
|
+
#
|
1378
|
+
# When the set does not contain <tt>*</tt>, #below is identical to #limit
|
1379
|
+
# with <tt>max: num - 1</tt>. When the set does contain <tt>*</tt>,
|
1380
|
+
# #below always drops it from the result. Use #limit when the IMAP
|
1381
|
+
# semantics for <tt>*</tt> must be enforced.
|
1382
|
+
#
|
1383
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].below(30) # to_s => "5,10:22"
|
1384
|
+
# Net::IMAP::SequenceSet["5,10:22,50"].limit(max: 29) # to_s => "5,10:22"
|
1385
|
+
# Net::IMAP::SequenceSet["5,10:22,*"].below(30) # to_s => "5,10:22"
|
1386
|
+
# Net::IMAP::SequenceSet["5,10:22,*"].limit(max: 29) # to_s => "5,10:22,29"
|
1387
|
+
#
|
1388
|
+
# Related: #above, #-, #&, #limit
|
1389
|
+
def below(num)
|
1390
|
+
NumValidator.valid_nz_number?(num) or
|
1391
|
+
raise ArgumentError, "not a valid sequence set number"
|
1392
|
+
difference(num..)
|
1393
|
+
end
|
1394
|
+
|
1256
1395
|
# Returns a frozen SequenceSet with <tt>*</tt> converted to +max+, numbers
|
1257
1396
|
# and ranges over +max+ removed, and ranges containing +max+ converted to
|
1258
1397
|
# end at +max+.
|
@@ -1270,6 +1409,7 @@ module Net
|
|
1270
1409
|
# Net::IMAP::SequenceSet["500:*"].limit(max: 37)
|
1271
1410
|
# #=> Net::IMAP::SequenceSet["37"]
|
1272
1411
|
#
|
1412
|
+
# Related: #limit!
|
1273
1413
|
def limit(max:)
|
1274
1414
|
max = to_tuple_int(max)
|
1275
1415
|
if empty? then self.class.empty
|
@@ -1311,6 +1451,7 @@ module Net
|
|
1311
1451
|
#
|
1312
1452
|
# The returned set's #string is sorted and deduplicated. Adjacent or
|
1313
1453
|
# overlapping elements will be merged into a single larger range.
|
1454
|
+
# See Net::IMAP@Ordered+and+Normalized+Sets.
|
1314
1455
|
#
|
1315
1456
|
# Net::IMAP::SequenceSet["1:5,3:7,10:9,10:11"].normalize
|
1316
1457
|
# #=> Net::IMAP::SequenceSet["1:7,9:11"]
|
@@ -1323,7 +1464,7 @@ module Net
|
|
1323
1464
|
end
|
1324
1465
|
|
1325
1466
|
# Resets #string to be sorted, deduplicated, and coalesced. Returns
|
1326
|
-
# +self+.
|
1467
|
+
# +self+. See Net::IMAP@Ordered+and+Normalized+Sets.
|
1327
1468
|
#
|
1328
1469
|
# Related: #normalize, #normalized_string
|
1329
1470
|
def normalize!
|
@@ -1333,11 +1474,13 @@ module Net
|
|
1333
1474
|
|
1334
1475
|
# Returns a normalized +sequence-set+ string representation, sorted
|
1335
1476
|
# and deduplicated. Adjacent or overlapping elements will be merged into
|
1336
|
-
# a single larger range.
|
1477
|
+
# a single larger range. See Net::IMAP@Ordered+and+Normalized+Sets.
|
1337
1478
|
#
|
1338
1479
|
# Net::IMAP::SequenceSet["1:5,3:7,10:9,10:11"].normalized_string
|
1339
1480
|
# #=> "1:7,9:11"
|
1340
1481
|
#
|
1482
|
+
# Returns +nil+ when the set is empty.
|
1483
|
+
#
|
1341
1484
|
# Related: #normalize!, #normalize
|
1342
1485
|
def normalized_string
|
1343
1486
|
@tuples.empty? ? nil : -@tuples.map { tuple_to_str _1 }.join(",")
|
@@ -1367,6 +1510,18 @@ module Net
|
|
1367
1510
|
imap.__send__(:put_string, valid_string)
|
1368
1511
|
end
|
1369
1512
|
|
1513
|
+
# For YAML serialization
|
1514
|
+
def encode_with(coder) # :nodoc:
|
1515
|
+
# we can perfectly reconstruct from the string
|
1516
|
+
coder['string'] = to_s
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
# For YAML deserialization
|
1520
|
+
def init_with(coder) # :nodoc:
|
1521
|
+
@tuples = []
|
1522
|
+
self.string = coder['string']
|
1523
|
+
end
|
1524
|
+
|
1370
1525
|
protected
|
1371
1526
|
|
1372
1527
|
attr_reader :tuples # :nodoc:
|
@@ -1374,6 +1529,7 @@ module Net
|
|
1374
1529
|
private
|
1375
1530
|
|
1376
1531
|
def remain_frozen(set) frozen? ? set.freeze : set end
|
1532
|
+
def remain_frozen_empty; frozen? ? SequenceSet.empty : SequenceSet.new end
|
1377
1533
|
|
1378
1534
|
# frozen clones are shallow copied
|
1379
1535
|
def initialize_clone(other)
|
@@ -1386,30 +1542,30 @@ module Net
|
|
1386
1542
|
super
|
1387
1543
|
end
|
1388
1544
|
|
1389
|
-
def input_to_tuple(
|
1390
|
-
|
1391
|
-
case
|
1392
|
-
when *STARS, Integer then [int = to_tuple_int(
|
1393
|
-
when Range then range_to_tuple(
|
1394
|
-
when String then str_to_tuple(
|
1545
|
+
def input_to_tuple(entry)
|
1546
|
+
entry = input_try_convert entry
|
1547
|
+
case entry
|
1548
|
+
when *STARS, Integer then [int = to_tuple_int(entry), int]
|
1549
|
+
when Range then range_to_tuple(entry)
|
1550
|
+
when String then str_to_tuple(entry)
|
1395
1551
|
else
|
1396
|
-
raise DataFormatError, "expected number or range, got %p" % [
|
1552
|
+
raise DataFormatError, "expected number or range, got %p" % [entry]
|
1397
1553
|
end
|
1398
1554
|
end
|
1399
1555
|
|
1400
|
-
def input_to_tuples(
|
1401
|
-
|
1402
|
-
case
|
1403
|
-
when *STARS, Integer, Range then [input_to_tuple(
|
1404
|
-
when String then str_to_tuples
|
1405
|
-
when SequenceSet then
|
1406
|
-
when Set then
|
1407
|
-
when Array then
|
1556
|
+
def input_to_tuples(set)
|
1557
|
+
set = input_try_convert set
|
1558
|
+
case set
|
1559
|
+
when *STARS, Integer, Range then [input_to_tuple(set)]
|
1560
|
+
when String then str_to_tuples set
|
1561
|
+
when SequenceSet then set.tuples
|
1562
|
+
when Set then set.map { [to_tuple_int(_1)] * 2 }
|
1563
|
+
when Array then set.flat_map { input_to_tuples _1 }
|
1408
1564
|
when nil then []
|
1409
1565
|
else
|
1410
1566
|
raise DataFormatError,
|
1411
1567
|
"expected nz-number, range, string, or enumerable; " \
|
1412
|
-
"got %p" % [
|
1568
|
+
"got %p" % [set]
|
1413
1569
|
end
|
1414
1570
|
end
|
1415
1571
|
|