module Stark::ProtocolHelpers

Constants

COERCION_FROM_STRING
COERCION_TO_STRING
THRIFT_TO_RUBY

Public Instance Methods

expect(ip, expected, actual) { || ... } click to toggle source
# File lib/stark/protocol_helpers.rb, line 26
def expect(ip, expected, actual)
  return nil if actual == ::Thrift::Types::STOP

  if expected == actual
    yield
  elsif expected == ::Thrift::Types::STRING
    COERCION_TO_STRING[actual][ip]
  elsif actual == ::Thrift::Types::STRING
    COERCION_FROM_STRING[expected][ip.read_string]
  else
    ip.skip actual
    nil
  end
end
expect_list(ip, expected) { |actual, size| ... } click to toggle source
# File lib/stark/protocol_helpers.rb, line 47
def expect_list(ip, expected)
  actual, size = ip.read_list_begin
  if valid_element_type?(expected, actual)
    yield actual, size
  else
    size.times { ip.skip actual }
    nil
  end
ensure
  ip.read_list_end
end
expect_map(ip, expected_key, expected_value) { |actual_key, actual_value, size| ... } click to toggle source
# File lib/stark/protocol_helpers.rb, line 59
def expect_map(ip, expected_key, expected_value)
  actual_key, actual_value, size = ip.read_map_begin
  if valid_element_type?(expected_key, actual_key) &&
      valid_element_type?(expected_value, actual_value)
    yield actual_key, actual_value, size
  else
    size.times do
      ip.skip actual_key
      ip.skip actual_value
    end
    nil
  end
ensure
  ip.read_map_end
end
expect_set(ip, expected) { |actual, size| ... } click to toggle source
# File lib/stark/protocol_helpers.rb, line 75
def expect_set(ip, expected)
  actual, size = ip.read_set_begin
  if valid_element_type?(expected, actual)
    yield actual, size
  else
    size.times { ip.skip actual }
    nil
  end
ensure
  ip.read_set_end
end
hash_cast(obj) click to toggle source
# File lib/stark/protocol_helpers.rb, line 87
def hash_cast(obj)
  return obj if obj.kind_of? Hash
  return obj.to_h if obj.respond_to? :to_h

  raise TypeError, "Unable to convert #{obj.class} to Hash"
end
valid_element_type?(expected, actual) click to toggle source
# File lib/stark/protocol_helpers.rb, line 41
def valid_element_type?(expected, actual)
  expected == actual ||
    expected == ::Thrift::Types::STRING ||
    actual == ::Thrift::Types::STRING
end
value_for_write(val, expected, additional = nil) click to toggle source
# File lib/stark/protocol_helpers.rb, line 107
def value_for_write(val, expected, additional = nil)
  return val if val.nil?

  ruby_types = nil
  if additional
    case expected
    when ::Thrift::Types::STRUCT
      if Class === additional && # Struct or Exception
        (additional < Stark::Struct || additional < Stark::Exception)
        ruby_types = [additional]
      end
    when ::Thrift::Types::I32
      if Hash === additional # Enum hash
        ruby_types = [Symbol]
      end
    end
  else
    ruby_types = THRIFT_TO_RUBY[expected]
  end

  raise TypeError, "Unknown Thrift type #{expected}" unless ruby_types

  return val if ruby_types.any? {|t| t === val }

  if String === val
    obj = COERCION_FROM_STRING[expected][val]
    raise TypeError, "Cannot coerce #{val.class} to #{ruby_types.join(' ')}" unless obj
    return obj
  end

  case expected
  when ::Thrift::Types::BOOL
    return val
  when ::Thrift::Types::STRING
    return val.to_s
  when ::Thrift::Types::MAP
    return val.to_hash if val.respond_to?(:to_hash)
  when ::Thrift::Types::SET
    return Set.new(val.to_a) if val.respond_to?(:to_a)
  when ::Thrift::Types::LIST
    return val.to_a if val.respond_to?(:to_a)
  when ::Thrift::Types::BYTE, ::Thrift::Types::I16, ::Thrift::Types::I64
    return val.to_i if val.respond_to?(:to_i)
  when ::Thrift::Types::I32
    if Hash === additional # Enum hash
      return val.to_sym if val.respond_to?(:to_sym)
    end
    if additional
      return additional[val.to_i] if val.respond_to?(:to_i)
    else
      return val.to_i
    end
  when ::Thrift::Types::DOUBLE
    return val.to_f if val.respond_to?(:to_f)
  end
  raise TypeError, "Unexpected type #{val.class} (#{val.inspect}); was expecting #{ruby_types.join(' ')}"
end