Module: MetaRPC::Callable

Defined in:
lib/metarpc/callable.rb

Overview

Module used to describe callable JSON RPC methods

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

DYNAMIC_TYPE_SUFFIXES =
{
  nil => :not_nullable_nor_spread,
  '?*' => :nullable_spread,
  '*?' => :spread_nullable,
  '?' => :nullable,
  '*' => :spread
}.freeze
DYNAMIC_TYPE_REGEXP =
/^(\w+)(\?|\?\*|\*\?|\*)?$/.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



4
5
6
7
# File 'lib/metarpc/callable.rb', line 4

def self.included(klass)
  super
  klass.send(:extend, ClassMethods)
end

Instance Method Details

#raise_json_rpc_error(code) ⇒ Object

Raises:



9
10
11
# File 'lib/metarpc/callable.rb', line 9

def raise_json_rpc_error(code)
  raise RPCError.new(code), "Failed to call JSON RPC method: #{code}"
end

#validate_array(args, contract) ⇒ Object



71
72
73
74
75
# File 'lib/metarpc/callable.rb', line 71

def validate_array(args, contract)
  contract.each_with_index do |contract_type, i|
    validate_item(args[i], contract_type)
  end
end

#validate_dynamic_type(item, contract_type) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/metarpc/callable.rb', line 33

def validate_dynamic_type(item, contract_type)
  matched_type = contract_type.match(DYNAMIC_TYPE_REGEXP)
  klass = matched_type[1].constantize
  type_suffix = DYNAMIC_TYPE_SUFFIXES[matched_type[2]]

  case type_suffix
  when :not_nullable_nor_spread
    validate_type(item, klass)
  when :nullable
    validate_type(item, klass, nullable: true)
  when :spread
    validate_spread(item, klass)
  when :nullable_spread
    validate_spread(item, klass, items_nullable: true)
  when :spread_nullable
    validate_spread(item, klass, spread_nullable: true)
  else
    raise_json_rpc_error(:internal_error)
  end
end

#validate_hash(args, contract) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/metarpc/callable.rb', line 77

def validate_hash(args, contract)
  contract.each do |arg_name, contract_type|
    raise_json_rpc_error(:invalid_params) unless args.key?(arg_name)

    validate_item(args[arg_name], contract_type)
  end
end

#validate_item(item, contract_type) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/metarpc/callable.rb', line 54

def validate_item(item, contract_type)
  case contract_type
  when Hash
    validate_hash(item, contract_type)
  when Array
    validate_array(item, contract_type)
  when Class
    raise_json_rpc_error(:invalid_params) unless item.is_a?(contract_type)
  when String
    validate_dynamic_type(item, contract_type)
  else
    raise_json_rpc_error(:internal_error)
  end
rescue NameError
  raise_json_rpc_error(:internal_error)
end

#validate_spread(items, klass, items_nullable: false, spread_nullable: false) ⇒ Object



28
29
30
31
# File 'lib/metarpc/callable.rb', line 28

def validate_spread(items, klass, items_nullable: false, spread_nullable: false)
  raise_json_rpc_error(:invalid_params) if items.nil? && !spread_nullable
  items&.each { |item| validate_type(item, klass, nullable: items_nullable) }
end

#validate_type(item, klass, nullable: false) ⇒ Object



22
23
24
25
26
# File 'lib/metarpc/callable.rb', line 22

def validate_type(item, klass, nullable: false)
  return raise_json_rpc_error(:invalid_params) if item.nil? && !nullable

  raise_json_rpc_error(:invalid_params) unless (item.present? && item.is_a?(klass)) || item.nil?
end