зеркало из https://github.com/github/ruby.git
[ruby/net-imap] move command data formatters to net/imap/command_data
Partially implements #10. https://github.com/ruby/net-imap/commit/24e929fdd2
This commit is contained in:
Родитель
affb51045c
Коммит
4dc7b82427
185
lib/net/imap.rb
185
lib/net/imap.rb
|
@ -22,6 +22,7 @@ begin
|
|||
rescue LoadError
|
||||
end
|
||||
|
||||
require_relative "imap/command_data"
|
||||
require_relative "imap/response_data"
|
||||
require_relative "imap/response_parser"
|
||||
|
||||
|
@ -1612,190 +1613,6 @@ module Net
|
|||
end
|
||||
end
|
||||
|
||||
class RawData # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class Atom # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class QuotedString # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_quoted_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class Literal # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_literal, @data, tag)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class MessageSet # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, format_internal(@data))
|
||||
end
|
||||
|
||||
def validate
|
||||
validate_internal(@data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def format_internal(data)
|
||||
case data
|
||||
when "*"
|
||||
return data
|
||||
when Integer
|
||||
if data == -1
|
||||
return "*"
|
||||
else
|
||||
return data.to_s
|
||||
end
|
||||
when Range
|
||||
return format_internal(data.first) +
|
||||
":" + format_internal(data.last)
|
||||
when Array
|
||||
return data.collect {|i| format_internal(i)}.join(",")
|
||||
when ThreadMember
|
||||
return data.seqno.to_s +
|
||||
":" + data.children.collect {|i| format_internal(i).join(",")}
|
||||
end
|
||||
end
|
||||
|
||||
def validate_internal(data)
|
||||
case data
|
||||
when "*"
|
||||
when Integer
|
||||
NumValidator.ensure_nz_number(data)
|
||||
when Range
|
||||
when Array
|
||||
data.each do |i|
|
||||
validate_internal(i)
|
||||
end
|
||||
when ThreadMember
|
||||
data.children.each do |i|
|
||||
validate_internal(i)
|
||||
end
|
||||
else
|
||||
raise DataFormatError, data.inspect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ClientID # :nodoc:
|
||||
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_data, format_internal(@data), tag)
|
||||
end
|
||||
|
||||
def validate
|
||||
validate_internal(@data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def validate_internal(client_id)
|
||||
client_id.to_h.each do |k,v|
|
||||
unless StringFormatter.valid_string?(k)
|
||||
raise DataFormatError, client_id.inspect
|
||||
end
|
||||
end
|
||||
rescue NoMethodError, TypeError # to_h failed
|
||||
raise DataFormatError, client_id.inspect
|
||||
end
|
||||
|
||||
def format_internal(client_id)
|
||||
return nil if client_id.nil?
|
||||
client_id.to_h.flat_map {|k,v|
|
||||
[StringFormatter.string(k), StringFormatter.nstring(v)]
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module StringFormatter
|
||||
|
||||
LITERAL_REGEX = /[\x80-\xff\r\n]/n
|
||||
|
||||
module_function
|
||||
|
||||
# Allows symbols in addition to strings
|
||||
def valid_string?(str)
|
||||
str.is_a?(Symbol) || str.respond_to?(:to_str)
|
||||
end
|
||||
|
||||
# Allows nil, symbols, and strings
|
||||
def valid_nstring?(str)
|
||||
str.nil? || valid_string?(str)
|
||||
end
|
||||
|
||||
# coerces using +to_s+
|
||||
def string(str)
|
||||
str = str.to_s
|
||||
if str =~ LITERAL_REGEX
|
||||
Literal.new(str)
|
||||
else
|
||||
QuotedString.new(str)
|
||||
end
|
||||
end
|
||||
|
||||
# coerces non-nil using +to_s+
|
||||
def nstring(str)
|
||||
str.nil? ? nil : string(str)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Common validators of number and nz_number types
|
||||
module NumValidator # :nodoc
|
||||
class << self
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Net
|
||||
class IMAP < Protocol
|
||||
|
||||
|
||||
class RawData # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class Atom # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class QuotedString # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_quoted_string, @data)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class Literal # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_literal, @data, tag)
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
end
|
||||
|
||||
class MessageSet # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:put_string, format_internal(@data))
|
||||
end
|
||||
|
||||
def validate
|
||||
validate_internal(@data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def format_internal(data)
|
||||
case data
|
||||
when "*"
|
||||
return data
|
||||
when Integer
|
||||
if data == -1
|
||||
return "*"
|
||||
else
|
||||
return data.to_s
|
||||
end
|
||||
when Range
|
||||
return format_internal(data.first) +
|
||||
":" + format_internal(data.last)
|
||||
when Array
|
||||
return data.collect {|i| format_internal(i)}.join(",")
|
||||
when ThreadMember
|
||||
return data.seqno.to_s +
|
||||
":" + data.children.collect {|i| format_internal(i).join(",")}
|
||||
end
|
||||
end
|
||||
|
||||
def validate_internal(data)
|
||||
case data
|
||||
when "*"
|
||||
when Integer
|
||||
NumValidator.ensure_nz_number(data)
|
||||
when Range
|
||||
when Array
|
||||
data.each do |i|
|
||||
validate_internal(i)
|
||||
end
|
||||
when ThreadMember
|
||||
data.children.each do |i|
|
||||
validate_internal(i)
|
||||
end
|
||||
else
|
||||
raise DataFormatError, data.inspect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ClientID # :nodoc:
|
||||
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_data, format_internal(@data), tag)
|
||||
end
|
||||
|
||||
def validate
|
||||
validate_internal(@data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def validate_internal(client_id)
|
||||
client_id.to_h.each do |k,v|
|
||||
unless StringFormatter.valid_string?(k)
|
||||
raise DataFormatError, client_id.inspect
|
||||
end
|
||||
end
|
||||
rescue NoMethodError, TypeError # to_h failed
|
||||
raise DataFormatError, client_id.inspect
|
||||
end
|
||||
|
||||
def format_internal(client_id)
|
||||
return nil if client_id.nil?
|
||||
client_id.to_h.flat_map {|k,v|
|
||||
[StringFormatter.string(k), StringFormatter.nstring(v)]
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module StringFormatter
|
||||
|
||||
LITERAL_REGEX = /[\x80-\xff\r\n]/n
|
||||
|
||||
module_function
|
||||
|
||||
# Allows symbols in addition to strings
|
||||
def valid_string?(str)
|
||||
str.is_a?(Symbol) || str.respond_to?(:to_str)
|
||||
end
|
||||
|
||||
# Allows nil, symbols, and strings
|
||||
def valid_nstring?(str)
|
||||
str.nil? || valid_string?(str)
|
||||
end
|
||||
|
||||
# coerces using +to_s+
|
||||
def string(str)
|
||||
str = str.to_s
|
||||
if str =~ LITERAL_REGEX
|
||||
Literal.new(str)
|
||||
else
|
||||
QuotedString.new(str)
|
||||
end
|
||||
end
|
||||
|
||||
# coerces non-nil using +to_s+
|
||||
def nstring(str)
|
||||
str.nil? ? nil : string(str)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче