Skip to content

Commit 89413ff

Browse files
committed
🥅 Update unknown numeric response-data handling
Unhandled _simple_ numeric responses, which contain only the numeric prefix and the response name, will now simply return the number as the response data. `UnparsedData` was introduced by #200. That struct has been renamed to `UnparsedNumericResponseData`, which represents data for unhandled response types with a numeric prefix. This prefix _is_ parsed but the additional response data is not. A simpler `UnparsedData` struct now represents data for unknown response types _or_ for unknown extensions to response types without a well-defined extension grammar. It is currently only used by `response_data__unhandled`, but future PRs will use it anywhere we can safely extract an unparsed string from the larger response: e.g unknown response code data.
1 parent 7b75be9 commit 89413ff

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

lib/net/imap/response_data.rb

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,45 @@ class UntaggedResponse < Struct.new(:name, :data, :raw_data)
6262
class IgnoredResponse < UntaggedResponse
6363
end
6464

65-
# Net::IMAP::UnparsedData represents data for unknown or unhandled
66-
# response types. UnparsedData is an intentionally unstable API: where
67-
# it is returned, future releases may return a different (incompatible)
68-
# object without deprecation or warning.
69-
class UnparsedData < Struct.new(:number, :unparsed_data)
65+
# **Note:** This represents an intentionally _unstable_ API. Where
66+
# instances of this class are returned, future releases may return a
67+
# different (incompatible) object <em>without deprecation or warning</em>.
68+
#
69+
# Net::IMAP::UnparsedData represents data for unknown response types or
70+
# unknown extensions to response types without a well-defined extension
71+
# grammar.
72+
#
73+
# See also: UnparsedNumericResponseData
74+
class UnparsedData < Struct.new(:unparsed_data)
75+
##
76+
# method: unparsed_data
77+
# :call-seq: unparsed_data -> string
78+
#
79+
# The unparsed data
80+
end
81+
82+
# **Note:** This represents an intentionally _unstable_ API. Where
83+
# instances of this class are returned, future releases may return a
84+
# different (incompatible) object <em>without deprecation or warning</em>.
85+
#
86+
# Net::IMAP::UnparsedNumericResponseData represents data for unhandled
87+
# response types with a numeric prefix. See the documentation for #number.
88+
#
89+
# See also: UnparsedData
90+
class UnparsedNumericResponseData < Struct.new(:number, :unparsed_data)
7091
##
7192
# method: number
7293
# :call-seq: number -> integer
7394
#
7495
# Returns a numeric response data prefix, when available.
7596
#
76-
# Many response types are prefixed with seqno or uid (for message
77-
# data) or a message count (for mailbox data).
97+
# Many response types are prefixed with a non-negative #number. For
98+
# message data, #number may represent a sequence number or a UID. For
99+
# mailbox data, #number may represent a message count.
78100

79101
##
80102
# method: unparsed_data
81-
# :call-seq: string -> string
103+
# :call-seq: unparsed_data -> string
82104
#
83105
# The unparsed data, not including #number or UntaggedResponse#name.
84106
end

lib/net/imap/response_parser.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,11 @@ def response_data__unhandled(klass = UntaggedResponse)
601601
num = number?; SP?
602602
type = tagged_ext_label; SP?
603603
text = remaining_unparsed
604-
data = UnparsedData.new(num, text) if num || text
604+
data =
605+
if num && text then UnparsedNumericResponseData.new(num, text)
606+
elsif text then UnparsedData.new(text)
607+
else num
608+
end
605609
klass.new(type, data, @str)
606610
end
607611

test/net/imap/fixtures/response_parser/quirky_behaviors.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
:response: "* NOOP\r\n"
55
:expected: !ruby/struct:Net::IMAP::IgnoredResponse
66
name: "NOOP"
7+
data:
78
raw_data: "* NOOP\r\n"
89

910
test_invalid_noop_response_with_unparseable_data:
@@ -18,6 +19,15 @@
1819
:response: "* 99 NOOP\r\n"
1920
:expected: !ruby/struct:Net::IMAP::IgnoredResponse
2021
name: "NOOP"
21-
data: !ruby/struct:Net::IMAP::UnparsedData
22-
number: 99
22+
data: 99
2323
raw_data: "* 99 NOOP\r\n"
24+
25+
test_invalid_noop_response_with_numeric_prefix_and_unparseable_data:
26+
:response: "* 86 NOOP froopy snood\r\n"
27+
:expected: !ruby/struct:Net::IMAP::IgnoredResponse
28+
name: "NOOP"
29+
data: !ruby/struct:Net::IMAP::UnparsedNumericResponseData
30+
number: 86
31+
unparsed_data: "froopy snood"
32+
raw_data: "* 86 NOOP froopy snood\r\n"
33+

0 commit comments

Comments
 (0)