net-imap 0.4.4 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP
5
+
6
+ # An array of sequence numbers returned by Net::IMAP#search, or unique
7
+ # identifiers returned by Net::IMAP#uid_search.
8
+ #
9
+ # For backward compatibility, SearchResult inherits from Array.
10
+ class SearchResult < Array
11
+
12
+ # Returns a frozen SearchResult populated with the given +seq_nums+.
13
+ #
14
+ # Net::IMAP::SearchResult[1, 3, 5, modseq: 9]
15
+ # # => Net::IMAP::SearchResult[1, 3, 5, modseq: 9]
16
+ def self.[](*seq_nums, modseq: nil)
17
+ new(seq_nums, modseq: modseq)
18
+ end
19
+
20
+ # A modification sequence number, as described by the +CONDSTORE+
21
+ # extension in {[RFC7162
22
+ # §3.1.6]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1.6].
23
+ attr_reader :modseq
24
+
25
+ # Returns a frozen SearchResult populated with the given +seq_nums+.
26
+ #
27
+ # Net::IMAP::SearchResult.new([1, 3, 5], modseq: 9)
28
+ # # => Net::IMAP::SearchResult[1, 3, 5, modseq: 9]
29
+ def initialize(seq_nums, modseq: nil)
30
+ super(seq_nums.to_ary.map { Integer _1 })
31
+ @modseq = Integer modseq if modseq
32
+ freeze
33
+ end
34
+
35
+ # Returns a frozen copy of +other+.
36
+ def initialize_copy(other); super; freeze end
37
+
38
+ # Returns whether +other+ is a SearchResult with the same values and the
39
+ # same #modseq. The order of numbers is irrelevant.
40
+ #
41
+ # Net::IMAP::SearchResult[123, 456, modseq: 789] ==
42
+ # Net::IMAP::SearchResult[123, 456, modseq: 789]
43
+ # # => true
44
+ # Net::IMAP::SearchResult[123, 456, modseq: 789] ==
45
+ # Net::IMAP::SearchResult[456, 123, modseq: 789]
46
+ # # => true
47
+ #
48
+ # Net::IMAP::SearchResult[123, 456, modseq: 789] ==
49
+ # Net::IMAP::SearchResult[987, 654, modseq: 789]
50
+ # # => false
51
+ # Net::IMAP::SearchResult[123, 456, modseq: 789] ==
52
+ # Net::IMAP::SearchResult[1, 2, 3, modseq: 9999]
53
+ # # => false
54
+ #
55
+ # SearchResult can be compared directly with Array, if #modseq is nil and
56
+ # the array is sorted.
57
+ #
58
+ # Net::IMAP::SearchResult[9, 8, 6, 4, 1] == [1, 4, 6, 8, 9] # => true
59
+ # Net::IMAP::SearchResult[3, 5, 7, modseq: 99] == [3, 5, 7] # => false
60
+ #
61
+ # Note that Array#== does require matching order and ignores #modseq.
62
+ #
63
+ # [9, 8, 6, 4, 1] == Net::IMAP::SearchResult[1, 4, 6, 8, 9] # => false
64
+ # [3, 5, 7] == Net::IMAP::SearchResult[3, 5, 7, modseq: 99] # => true
65
+ #
66
+ def ==(other)
67
+ (modseq ?
68
+ other.is_a?(self.class) && modseq == other.modseq :
69
+ other.is_a?(Array)) &&
70
+ size == other.size &&
71
+ sort == other.sort
72
+ end
73
+
74
+ # Hash equality. Unlike #==, order will be taken into account.
75
+ def hash
76
+ return super if modseq.nil?
77
+ [super, self.class, modseq].hash
78
+ end
79
+
80
+ # Hash equality. Unlike #==, order will be taken into account.
81
+ def eql?(other)
82
+ return super if modseq.nil?
83
+ self.class == other.class && hash == other.hash
84
+ end
85
+
86
+ # Returns a string that represents the SearchResult.
87
+ #
88
+ # Net::IMAP::SearchResult[123, 456, 789].inspect
89
+ # # => "[123, 456, 789]"
90
+ #
91
+ # Net::IMAP::SearchResult[543, 210, 678, modseq: 2048].inspect
92
+ # # => "Net::IMAP::SearchResult[543, 210, 678, modseq: 2048]"
93
+ #
94
+ def inspect
95
+ return super if modseq.nil?
96
+ "%s[%s, modseq: %p]" % [self.class, join(", "), modseq]
97
+ end
98
+
99
+ # Returns a string that follows the formal \IMAP syntax.
100
+ #
101
+ # data = Net::IMAP::SearchResult[2, 8, 32, 128, 256, 512]
102
+ # data.to_s # => "* SEARCH 2 8 32 128 256 512"
103
+ # data.to_s("SEARCH") # => "* SEARCH 2 8 32 128 256 512"
104
+ # data.to_s("SORT") # => "* SORT 2 8 32 128 256 512"
105
+ # data.to_s(nil) # => "2 8 32 128 256 512"
106
+ #
107
+ # data = Net::IMAP::SearchResult[1, 3, 16, 1024, modseq: 2048].to_s
108
+ # data.to_s # => "* SEARCH 1 3 16 1024 (MODSEQ 2048)"
109
+ # data.to_s("SORT") # => "* SORT 1 3 16 1024 (MODSEQ 2048)"
110
+ # data.to_s # => "1 3 16 1024 (MODSEQ 2048)"
111
+ #
112
+ def to_s(type = "SEARCH")
113
+ str = +""
114
+ str << "* %s " % [type.to_str] unless type.nil?
115
+ str << join(" ")
116
+ str << " (MODSEQ %d)" % [modseq] if modseq
117
+ -str
118
+ end
119
+
120
+ # Converts the SearchResult into a SequenceSet.
121
+ #
122
+ # Net::IMAP::SearchResult[9, 1, 2, 4, 10, 12, 3, modseq: 123_456]
123
+ # .to_sequence_set
124
+ # # => Net::IMAP::SequenceSet["1:4,9:10,12"]
125
+ def to_sequence_set; SequenceSet[*self] end
126
+
127
+ def pretty_print(pp)
128
+ return super if modseq.nil?
129
+ pp.text self.class.name + "["
130
+ pp.group_sub do
131
+ pp.nest(2) do
132
+ pp.breakable ""
133
+ each do |num|
134
+ pp.pp num
135
+ pp.text ","
136
+ pp.fill_breakable
137
+ end
138
+ pp.breakable ""
139
+ pp.text "modseq: "
140
+ pp.pp modseq
141
+ end
142
+ pp.breakable ""
143
+ pp.text "]"
144
+ end
145
+ end
146
+
147
+ end
148
+
149
+ end
150
+ end