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