mirror of
https://github.com/ruby/ruby.git
synced 2025-08-24 21:44:30 +02:00
192 lines
3.7 KiB
Ruby
192 lines
3.7 KiB
Ruby
# 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
|