class Encode::Encoder

Performs encoding while managing state.

Public Class Methods

new(replacer: nil, unordered_objects: true) click to toggle source

When initializing, you can provide options to modify how the encoder functions.

# File lib/object_hash_rb/encode.rb, line 134
def initialize(replacer: nil, unordered_objects: true)
  # OPTIONS
  @replacer = replacer
  @unordered_objects = unordered_objects

  # Used for circular reference handling.
  @context = []
end

Public Instance Methods

encode_cleanup() click to toggle source
# File lib/object_hash_rb/encode.rb, line 143
def encode_cleanup
  @context = []
end
perform_encode(input) click to toggle source

@INTERNAL: Please use ObjectHash.hash() instead. Encodes the input value to match a standardized format.

# File lib/object_hash_rb/encode.rb, line 149
def perform_encode(input)
  # Encode the value.
  result = encode_value(input)

  # Cleanup.
  encode_cleanup

  # Return the encoded value.
  result
end

Private Instance Methods

encode_Array(input) click to toggle source

Each method encodes certain types, and is named after the type it encodes, and is called dynamically based on that, thus the uppercase. rubocop:disable Naming/MethodName

# File lib/object_hash_rb/encode.rb, line 37
def encode_Array(input)
  # Encode each element, then concatenate together.
  "array:#{input.length}:#{input.map { |y| encode_value(y) }.reduce(:+)}"
end
encode_Boolean(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 85
def encode_Boolean(input)
  "bool:#{input}"
end
encode_Circular(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 42
def encode_Circular(input)
  encode_String("[CIRCULAR:#{@context.index(input)}]")
end
encode_DateTime(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 101
def encode_DateTime(input)
  "date:#{input.strftime("%Y-%m-%dT%H:%M:%S.%LZ")}"
end
encode_FalseClass(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 93
def encode_FalseClass(input)
  encode_Boolean(input)
end
encode_Float(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 69
def encode_Float(input)
  return "number:NaN" if input.nan?

  return input.positive? ? "number:Infinity" : "number:-Infinity" if input.infinite?

  encode_Number(input)
end
encode_Hash(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 46
def encode_Hash(input)
  # Keeps track of what elements have been processed already.
  # Used to prevent parsing circular references.
  keys = @unordered_objects ? input.keys.sort : input.keys

  # Check each key and format it.
  "object:#{input.length}:#{keys.map do |key|
    value = input[key]
    return encode_Circular(value) if !@context.empty? && @context.index(value)

    @context.push(input[key])
    "#{encode_value(key)}:#{encode_value(value)},"
  end.reduce(:+)}"
end
encode_Integer(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 65
def encode_Integer(input)
  encode_Number(input)
end
encode_NilClass(_input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 105
def encode_NilClass(_input)
  "Null"
end
encode_Number(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 61
def encode_Number(input)
  "number:#{input}"
end
encode_String(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 77
def encode_String(input)
  "string:#{input.length}:#{input}"
end
encode_Symbol(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 81
def encode_Symbol(input)
  "symbol:#{input}"
end
encode_Time(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 97
def encode_Time(input)
  "date:#{input.strftime("%Y-%m-%dT%H:%M:%S.%LZ")}"
end
encode_TrueClass(input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 89
def encode_TrueClass(input)
  encode_Boolean(input)
end
encode_Undefined(_input) click to toggle source
# File lib/object_hash_rb/encode.rb, line 109
def encode_Undefined(_input)
  "Undefined"
end
encode_value(input) click to toggle source

@param t: Type of the input value.

Allows recursive calls which switch which type is used.
# File lib/object_hash_rb/encode.rb, line 118
def encode_value(input)
  # If the user specified a custom replacer...
  input = @replacer.call(input) unless @replacer.nil?

  begin
    # Call the appropriate method by name, if it exists,
    # and return its result.
    method("encode_#{input.class}").call(input)
  rescue NameError
    raise NoEncoderError, input.class.to_s
  end
end