Skip to content

Commit dcbbce5

Browse files
committed
⚡️ Speed up resp-text-code parsing
Convert resp_text_code case statement to use strings. This leads to significant performance improvements, in my benchmarks.
1 parent 6dda581 commit dcbbce5

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

lib/net/imap/response_parser.rb

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,44 +1473,48 @@ def resp_text
14731473
end
14741474
end
14751475

1476-
# See https://www.rfc-editor.org/errata/rfc3501
1476+
# RFC3501 (See https://www.rfc-editor.org/errata/rfc3501):
1477+
# resp-text-code = "ALERT" /
1478+
# "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
1479+
# capability-data / "PARSE" /
1480+
# "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
1481+
# "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1482+
# "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1483+
# "UNSEEN" SP nz-number /
1484+
# atom [SP 1*<any TEXT-CHAR except "]">]
1485+
# capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
1486+
# *(SP capability)
14771487
#
1478-
# resp-text-code = "ALERT" /
1479-
# "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
1480-
# capability-data / "PARSE" /
1481-
# "PERMANENTFLAGS" SP "("
1482-
# [flag-perm *(SP flag-perm)] ")" /
1483-
# "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1484-
# "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1485-
# "UNSEEN" SP nz-number /
1486-
# atom [SP 1*<any TEXT-CHAR except "]">]
1488+
# RFC4315 (UIDPLUS), RFC9051 (IMAP4rev2):
1489+
# resp-code-apnd = "APPENDUID" SP nz-number SP append-uid
1490+
# resp-code-copy = "COPYUID" SP nz-number SP uid-set SP uid-set
1491+
# resp-text-code =/ resp-code-apnd / resp-code-copy / "UIDNOTSTICKY"
14871492
#
1488-
# +UIDPLUS+ ABNF:: https://www.rfc-editor.org/rfc/rfc4315.html#section-4
1489-
# resp-text-code =/ resp-code-apnd / resp-code-copy / "UIDNOTSTICKY"
1493+
# RFC7162 (CONDSTORE):
1494+
# resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value /
1495+
# "NOMODSEQ" /
1496+
# "MODIFIED" SP sequence-set
14901497
def resp_text_code
1491-
token = match(T_ATOM)
1492-
name = token.value.upcase
1498+
name = resp_text_code__name
14931499
case name
1494-
when /\A(?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\z/n
1500+
when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE", "NOMODSEQ"
14951501
result = ResponseCode.new(name, nil)
1496-
when /\A(?:BADCHARSET)\z/n
1502+
when "BADCHARSET"
14971503
result = ResponseCode.new(name, charset_list)
1498-
when /\A(?:CAPABILITY)\z/ni
1504+
when "CAPABILITY"
14991505
result = ResponseCode.new(name, capability__list)
1500-
when /\A(?:PERMANENTFLAGS)\z/n
1501-
match(T_SPACE)
1506+
when "PERMANENTFLAGS"
1507+
SP!
15021508
result = ResponseCode.new(name, flag_list)
1503-
when /\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\z/n
1504-
match(T_SPACE)
1509+
when "UIDVALIDITY", "UIDNEXT", "UNSEEN"
1510+
SP!
15051511
result = ResponseCode.new(name, number)
1506-
when /\A(?:APPENDUID)\z/n
1512+
when "APPENDUID"
15071513
result = ResponseCode.new(name, resp_code_apnd__data)
1508-
when /\A(?:COPYUID)\z/n
1514+
when "COPYUID"
15091515
result = ResponseCode.new(name, resp_code_copy__data)
15101516
else
1511-
token = lookahead
1512-
if token.symbol == T_SPACE
1513-
shift_token
1517+
if SP?
15141518
result = ResponseCode.new(name, text_chars_except_rbra)
15151519
else
15161520
result = ResponseCode.new(name, nil)
@@ -1519,6 +1523,8 @@ def resp_text_code
15191523
return result
15201524
end
15211525

1526+
alias resp_text_code__name case_insensitive__atom
1527+
15221528
# 1*<any TEXT-CHAR except "]">
15231529
def text_chars_except_rbra
15241530
match_re(CTEXT_REGEXP, '1*<any TEXT-CHAR except "]">')[0]

0 commit comments

Comments
 (0)