module Mail::Utilities

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/mail/utilities.rbs

module Mail::Utilities
  def dasherize: (Symbol str) -> String
end

def self.binary_unsafe_to_crlf(string) #:nodoc:

:nodoc:
def self.binary_unsafe_to_crlf(string) #:nodoc:
  string.gsub(TO_CRLF_REGEX, Constants::CRLF)
end

def self.binary_unsafe_to_lf(string) #:nodoc:

:nodoc:
def self.binary_unsafe_to_lf(string) #:nodoc:
  string.gsub(/\r\n|\r/, Constants::LF)
end

def self.safe_for_line_ending_conversion?(string) #:nodoc:

:nodoc:
def self.safe_for_line_ending_conversion?(string) #:nodoc:
  if string.encoding == Encoding::BINARY
    string.ascii_only?
  else
    string.valid_encoding?
  end
end

def self.to_crlf(string)

when parsing emails with \n line endings instead of the required \r\n.
encoding 8bit and base64 Content-Transfer-Encoding and for convenience
Convert line endings to \r\n unless the string is binary. Used for
def self.to_crlf(string)
  string = string.to_s
  if safe_for_line_ending_conversion? string
    binary_unsafe_to_crlf string
  else
    string
  end
end

def self.to_lf(string)

sendmail delivery and for decoding 8bit Content-Transfer-Encoding.
Convert line endings to \n unless the string is binary. Used for
def self.to_lf(string)
  string = string.to_s
  if safe_for_line_ending_conversion? string
    binary_unsafe_to_lf string
  else
    string
  end
end

def atom_safe?( str )

Returns true if the string supplied is free from characters not allowed as an ATOM
def atom_safe?( str )
  not Constants::ATOM_UNSAFE === str
end

def blank?(value)

This logic is mostly shared with ActiveSupport's blank?

and arrays and hashes that have nothing in them.
A blank includes things like '', ' ', nil,
Returns true if the object is considered blank.
def blank?(value)
  if value.kind_of?(NilClass)
    true
  elsif value.kind_of?(String)
    value !~ /\S/
  else
    value.respond_to?(:empty?) ? value.empty? : !value
  end
end

def bracket( str )

bracket( 'This is a string' ) #=> ''

Example:

Wraps a string in angle brackets and escapes any that are in the string itself
def bracket( str )
  Utilities.bracket( str )
end

def capitalize_field( str )

capitalize_field( string ) #=> 'Resent-From-Field'
string = 'resent-from-field'

Example:

Capitalizes a string that is joined by hyphens correctly.
def capitalize_field( str )
  str.to_s.split("-").map { |v| v.capitalize }.join("-")
end

def constantize( str )

constantize("hello-there-mate") #=> "HelloThereMate"
constantize("hello-there") #=> "HelloThere"
constantize("hello") #=> "Hello"

Example:

Takes an underscored word and turns it into a class name
def constantize( str )
  str.to_s.split(/[-_]/).map { |v| v.capitalize }.to_s
end

def convert_to_encoding(encoding)

def convert_to_encoding(encoding)
  if encoding.is_a?(Encoding)
    encoding
  else
    # Fall back to ASCII for charsets that Ruby doesn't recognize
    begin
      Encoding.find(encoding)
    rescue ArgumentError
      Encoding::BINARY
    end
  end
end

def dasherize( str )

Experimental RBS support (using type sampling data from the type_fusion project).

def dasherize: (Symbol str) -> String

This signature was generated using 1 sample from 1 application.

dasherize( string ) #=> 'resent-from-field'
string = :resent_from_field

Example:

a field name.
Swaps out all underscores (_) for hyphens (-) good for stringing from symbols
def dasherize( str )
  str.to_s.tr(Constants::UNDERSCORE, Constants::HYPHEN)
end

def dquote( str )

dquote(string #=> '"This is \"a string\"'
string = 'This is "a string"'

dquote(string) #=> '"This is a string"'
string = 'This is a string'

Example:

unless it is already wrapped.
Wraps supplied string in double quotes and applies \-escaping as necessary,
def dquote( str )
  '"' + unquote(str).gsub(/[\\"]/n) {|s| '\\' + s } + '"'
end

def escape_paren( str )

escape_paren( str ) #=> 'This is \(a\) string'
str = 'This is (a) string'

Example:

Escape parenthesies in a string
def escape_paren( str )
  Utilities.escape_paren( str )
end

def generate_message_id

def generate_message_id
  "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
end

def map_lines( str, &block )

def map_lines( str, &block )
  str.each_line.map(&block)
end

def map_with_index( enum, &block )

def map_with_index( enum, &block )
  enum.each_with_index.map(&block)
end

def match_to_s( obj1, obj2 )

match_to_s( obj1, obj2 ) #=> true
obj1 = :this_IS_an_object
obj2 = "This_is_An_object"

Example:

Matches two objects with their to_s values case insensitively
def match_to_s( obj1, obj2 )
  obj1.to_s.casecmp(obj2.to_s) == 0
end

def paren( str )

paren( 'This is a string' ) #=> '(This is a string)'

Example:

Wraps a string in parenthesis and escapes any that are in the string itself.
def paren( str )
  Utilities.paren( str )
end

def quote_atom( str )

in double quotes, otherwise returns the string unmodified
If the string supplied has ATOM unsafe characters in it, will return the string quoted
def quote_atom( str )
  atom_safe?( str ) ? str : dquote(str)
end

def quote_phrase( str )

in double quotes, otherwise returns the string unmodified
If the string supplied has PHRASE unsafe characters in it, will return the string quoted
def quote_phrase( str )
  if str.respond_to?(:force_encoding)
    original_encoding = str.encoding
    ascii_str = str.to_s.dup.force_encoding('ASCII-8BIT')
    if Constants::PHRASE_UNSAFE === ascii_str
      dquote(ascii_str).force_encoding(original_encoding)
    else
      str
    end
  else
    Constants::PHRASE_UNSAFE === str ? dquote(str) : str
  end
end

def quote_token( str )

in double quotes, otherwise returns the string unmodified
If the string supplied has TOKEN unsafe characters in it, will return the string quoted
def quote_token( str )
  if str.respond_to?(:force_encoding)
    original_encoding = str.encoding
    ascii_str = str.to_s.dup.force_encoding('ASCII-8BIT')
    if token_safe?( ascii_str )
      str
    else
      dquote(ascii_str).force_encoding(original_encoding)
    end
  else
    token_safe?( str ) ? str : dquote(str)
  end
end

def token_safe?( str )

Returns true if the string supplied is free from characters not allowed as a TOKEN
def token_safe?( str )
  not Constants::TOKEN_UNSAFE === str
end

def transcode_to_scrubbed_utf8(str)

def transcode_to_scrubbed_utf8(str)
  decoded = str.encode(Encoding::UTF_8, :undef => :replace, :invalid => :replace, :replace => "�")
  decoded.valid_encoding? ? decoded : decoded.encode(Encoding::UTF_16LE, :invalid => :replace, :replace => "�").encode(Encoding::UTF_8)
end

def unbracket( str )

unbracket( str ) #=> 'This is a string'
str = ''

Example:

Unwraps a string from being wrapped in parenthesis
def unbracket( str )
  if str.start_with?('<') && str.end_with?('>')
    str.slice(1..-2)
  else
    str
  end
end

def underscoreize( str )

underscoreize ( string ) #=> 'resent_from_field'
string = :resent_from_field

Example:

a field name.
Swaps out all hyphens (-) for underscores (_) good for stringing to symbols
def underscoreize( str )
  str.to_s.downcase.tr(Constants::HYPHEN, Constants::UNDERSCORE)
end

def unescape( str )

unescape(string) #=> '"This is "a string""'
string = '"This is \"a string\""'

unescape(string) #=> 'This is "a string"'
string = 'This is \"a string\"'

Example:

Removes any \-escaping.
def unescape( str )
  str.gsub(/\\(.)/, '\1')
end

def unparen( str )

unparen( str ) #=> 'This is a string'
str = '(This is a string)'

Example:

Unwraps a string from being wrapped in parenthesis
def unparen( str )
  if str.start_with?('(') && str.end_with?(')')
    str.slice(1..-2)
  else
    str
  end
end

def unquote( str )

unqoute(string) #=> 'This is "a string"'
string = '"This is \"a string\""'

unquote(string) #=> 'This is a string'
string = '"This is a string"'

Example:

removes any \-escaping.
Unwraps supplied string from inside double quotes and
def unquote( str )
  if str =~ /^"(.*?)"$/
    unescape($1)
  else
    str
  end
end

def uri_escape( str )

def uri_escape( str )
  uri_parser.escape(str)
end

def uri_parser

def uri_parser
  @uri_parser ||= URI.const_defined?(:DEFAULT_PARSER) ? URI::DEFAULT_PARSER : URI
end

def uri_unescape( str )

def uri_unescape( str )
  uri_parser.unescape(str)
end