Class: Dry::Validation::InputProcessorCompiler

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/validation/input_processor_compiler.rb

Direct Known Subclasses

JSON, Params, Sanitizer, InputProcessorCompiler::Form

Defined Under Namespace

Classes: Form, JSON, Params, Sanitizer

Constant Summary collapse

DEFAULT_TYPE_NODE =
[:definition, [String, {}]].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInputProcessorCompiler

Returns a new instance of InputProcessorCompiler.



11
12
13
# File 'lib/dry/validation/input_processor_compiler.rb', line 11

def initialize
  @type_compiler = Dry::Types::Compiler.new(Dry::Types)
end

Instance Attribute Details

#type_compilerObject (readonly)

Returns the value of attribute type_compiler.



7
8
9
# File 'lib/dry/validation/input_processor_compiler.rb', line 7

def type_compiler
  @type_compiler
end

Instance Method Details

#call(ast) ⇒ Object



15
16
17
# File 'lib/dry/validation/input_processor_compiler.rb', line 15

def call(ast)
  type_compiler.(hash_node(schema_ast(ast)))
end

#constructor(type) ⇒ Object



40
41
42
43
# File 'lib/dry/validation/input_processor_compiler.rb', line 40

def constructor(type)
  fn_id = type.__send__(:register_fn, type.fn)
  [:constructor, [[:definition, [type.primitive, {}]], fn_id, {}]]
end

#schema_ast(ast) ⇒ Object



19
20
21
# File 'lib/dry/validation/input_processor_compiler.rb', line 19

def schema_ast(ast)
  ast.map { |node| visit(node) }
end

#type(predicate, args) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/dry/validation/input_processor_compiler.rb', line 117

def type(predicate, args)
  default = self.class::PREDICATE_MAP[:default]

  type_value = if predicate == :type?
                 const = args[0]
                 self.class::CONST_MAP[const] || Types.identifier(const)
               else
                 self.class::PREDICATE_MAP[predicate] || default
               end

  require 'dry/types/compat/int' unless Types.container.key?(type_value)

  Types[type_value].to_ast
end

#visit(node, *args) ⇒ Object



23
24
25
# File 'lib/dry/validation/input_processor_compiler.rb', line 23

def visit(node, *args)
  send(:"visit_#{node[0]}", node[1], *args)
end

#visit_and(node, first = true) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/dry/validation/input_processor_compiler.rb', line 54

def visit_and(node, first = true)
  if first
    name, type = node.map { |n| visit(n, false) }.uniq

    if name.is_a?(Array)
      type
    else
      [:member, [name, type]]
    end
  else
    result = node.map { |n| visit(n, first) }.uniq

    if result.size == 1
      result.first
    else
      result.select { |r| r != self.class::DEFAULT_TYPE_NODE }.last
    end
  end
end

#visit_each(node, *args) ⇒ Object



103
104
105
# File 'lib/dry/validation/input_processor_compiler.rb', line 103

def visit_each(node, *args)
  array_node(visit(node, *args))
end

#visit_implication(node, *args) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/dry/validation/input_processor_compiler.rb', line 74

def visit_implication(node, *args)
  left, right = node

  key = visit(left)

  if key.is_a?(Symbol)
    [:member, [key, visit(right, false)]]
  else
    [:sum, [key, visit(right, false), {}]]
  end
end

#visit_key(node, *args) ⇒ Object



90
91
92
93
# File 'lib/dry/validation/input_processor_compiler.rb', line 90

def visit_key(node, *args)
  _, other = node
  visit(other, *args)
end

#visit_not(node, *args) ⇒ Object



86
87
88
# File 'lib/dry/validation/input_processor_compiler.rb', line 86

def visit_not(node, *args)
  visit(node, *args)
end

#visit_or(node, *args) ⇒ Object



49
50
51
52
# File 'lib/dry/validation/input_processor_compiler.rb', line 49

def visit_or(node, *args)
  left, right = node
  [:sum, [visit(left, *args), visit(right, *args), {}]]
end

#visit_predicate(node) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/dry/validation/input_processor_compiler.rb', line 107

def visit_predicate(node, *)
  id, args = node

  if id == :key?
    args[0][1]
  else
    type(id, args.map(&:last))
  end
end

#visit_rule(node, *args) ⇒ Object



27
28
29
30
# File 'lib/dry/validation/input_processor_compiler.rb', line 27

def visit_rule(node, *args)
  _, rule = node
  visit(rule, *args)
end

#visit_schema(schema, *args) ⇒ Object



45
46
47
# File 'lib/dry/validation/input_processor_compiler.rb', line 45

def visit_schema(schema, *args)
  hash_node(schema.input_processor_ast(identifier))
end

#visit_set(node) ⇒ Object



99
100
101
# File 'lib/dry/validation/input_processor_compiler.rb', line 99

def visit_set(node, *)
  hash_node(node.map { |n| visit(n) })
end

#visit_type(type, *args) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/dry/validation/input_processor_compiler.rb', line 32

def visit_type(type, *args)
  if type.is_a?(Types::Constructor)
    constructor(type)
  elsif type.respond_to?(:rule)
    visit(type.rule.to_ast, *args)
  end
end

#visit_val(node, *args) ⇒ Object



95
96
97
# File 'lib/dry/validation/input_processor_compiler.rb', line 95

def visit_val(node, *args)
  visit(node, *args)
end