module VCR::Normalizers::Body::ClassMethods

def body_from(hash_or_string)

def body_from(hash_or_string)
  return hash_or_string unless hash_or_string.is_a?(Hash)
  hash = hash_or_string
  if hash.has_key?('base64_string')
    string = Base64.decode64(hash['base64_string'])
    force_encode_string(string, hash['encoding'])
  else
    try_encode_string(hash['string'], hash['encoding'])
  end
end

def force_encode_string(string, encoding)

def force_encode_string(string, encoding)
  return string unless encoding
  string.force_encoding(encoding)
end

def force_encode_string(string, encoding)

def force_encode_string(string, encoding)
  string
end

def try_encode_string(string, encoding_name)

def try_encode_string(string, encoding_name)
  return string if encoding_name.nil?
  encoding = Encoding.find(encoding_name)
  return string if string.encoding == encoding
  # ASCII-8BIT just means binary, so encoding to it is nonsensical
  # and yet "\u00f6".encode("ASCII-8BIT") raises an error.
  # Instead, we'll force encode it (essentially just tagging it as binary)
  return string.force_encoding(encoding) if encoding == Encoding::BINARY
  string.encode(encoding)
rescue EncodingError => e
  struct_type = name.split('::').last.downcase
  warn "VCR: got `#{e.class.name}: #{e.message}` while trying to encode the #{string.encoding.name} " +
       "#{struct_type} body to the original body encoding (#{encoding}). Consider using the " +
       "`:preserve_exact_body_bytes` option to work around this."
  return string
end

def try_encode_string(string, encoding)

def try_encode_string(string, encoding)
  string
end