Sha256: f98a32b1c6fa5ae3d3c92aa9d5ada566dd2ddaa261d730d1e672257f333d38aa

Contents?: true

Size: 1.86 KB

Versions: 3

Compression:

Stored size: 1.86 KB

Contents

# frozen_string_literal: true

module Grumlin
  module Typing
    TYPES = {
      "g:List" => ->(value) { value.map { |item| cast(item) } },
      "g:Map" => ->(value) { cast_map(value) },
      "g:Vertex" => ->(value) { cast_entity(Grumlin::Vertex, value) },
      "g:Edge" => ->(value) { cast_entity(Grumlin::Edge, value) },
      "g:Int64" => ->(value) { cast_int(value) },
      "g:Int32" => ->(value) { cast_int(value) },
      "g:Traverser" => ->(value) { cast(value[:value]) } # TODO: wtf is bulk?
    }.freeze

    CASTABLE_TYPES = [Hash, String, Integer].freeze

    class << self
      def cast(value)
        verify_type!(value)

        return value unless value.is_a?(Hash)

        type = TYPES[value[:@type]]

        verify_castable_hash!(value, type)

        type.call(value[:@value])
      end

      private

      def castable_type?(value); end

      def verify_type!(value)
        raise TypeError, "#{value.inspect} cannot be casted" unless CASTABLE_TYPES.any? { |t| value.is_a?(t) }
      end

      def verify_castable_hash!(value, type)
        raise TypeError, "#{value} cannot be casted, @type is missing" if value[:@type].nil?
        raise(UnknownTypeError, value[:@type]) if type.nil?
        raise TypeError, "#{value} cannot be casted, @value is missing" if value[:@value].nil?
      end

      def cast_int(value)
        raise TypeError, "#{value} is not an Integer" unless value.is_a?(Integer)

        value
      end

      def cast_entity(entity, value)
        entity.new(**value)
      rescue ArgumentError, TypeError
        raise TypeError, "#{value} cannot be casted to #{entity.name}"
      end

      def cast_map(value)
        Hash[*value].transform_keys(&:to_sym).transform_values { |v| cast(v) }
      rescue ArgumentError
        raise TypeError, "#{value} cannot be casted to Hash"
      end

      def cast_traverser(value); end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
grumlin-0.1.3 lib/grumlin/typing.rb
grumlin-0.1.1 lib/grumlin/typing.rb
grumlin-0.1.0 lib/grumlin/typing.rb