Class: DryValidationParser::ValidationSchemaParser

Inherits:
Object
  • Object
show all
Defined in:
lib/dry_validation_parser/validation_schema_parser.rb

Constant Summary collapse

PREDICATE_TO_TYPE =
{
  array?: "array",
  bool?: "boolean",
  date?: "date",
  date_time?: "datetime",
  decimal?: "decimal",
  float?: "float",
  hash?: "hash",
  int?: "integer",
  nil?: "nil",
  str?: "string",
  time?: "time"
}.freeze
DESCRIPTION_MAPPING =
{
  eql?: "Must be equal to %<value>s",
  max_size?: "Maximum size: %<value>s",
  min_size?: "Minimum size: %<value>s",
  gteq?: "Greater than or equal to %<value>s",
  gt?: "Greater than %<value>s",
  lt?: "Lower than %<value>s",
  lteq?: "Lower than or equal to %<value>s"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeValidationSchemaParser

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of ValidationSchemaParser.



33
34
35
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 33

def initialize
  @keys = {}
end

Instance Attribute Details

#keysObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



30
31
32
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 30

def keys
  @keys
end

Instance Method Details

#call(contract, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



43
44
45
46
47
48
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 43

def call(contract, &block)
  @keys = {}
  visit(contract.schema.to_ast)
  instance_eval(&block) if block_given?
  self
end

#predicate_description(name, value) ⇒ Object



129
130
131
132
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 129

def predicate_description(name, value)
  description = DESCRIPTION_MAPPING[name]
  description ? format(description, value: value) : ""
end

#to_hObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



38
39
40
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 38

def to_h
  { keys: keys }
end

#visit(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



51
52
53
54
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 51

def visit(node, opts = {})
  meth, rest = node
  public_send(:"visit_#{meth}", rest, opts)
end

#visit_and(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



71
72
73
74
75
76
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 71

def visit_and(node, opts = {})
  left, right = node

  visit(left, opts)
  visit(right, opts)
end

#visit_each(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



94
95
96
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 94

def visit_each(node, opts = {})
  visit(node, opts.merge(member: true))
end

#visit_implication(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



86
87
88
89
90
91
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 86

def visit_implication(node, opts = {})
  node.each do |el|
    opts = opts.merge(required: false)
    visit(el, opts)
  end
end

#visit_key(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



99
100
101
102
103
104
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 99

def visit_key(node, opts = {})
  name, rest = node
  opts = opts.merge(key: name)
  opts = opts.merge(required: true)
  visit(rest, opts)
end

#visit_not(_node, opts = {}) ⇒ Object



81
82
83
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 81

def visit_not(_node, opts = {})
  keys[opts[:key]][:nullable] = true
end

#visit_or(_, _) ⇒ Object

Skip or predicate



79
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 79

def visit_or(_, _); end

#visit_predicate(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 107

def visit_predicate(node, opts = {})
  name, rest = node
  key = opts[:key]
  if name.equal?(:key?)
    keys[rest[0][1]] = { required: opts.fetch(:required, true) }
  elsif name.equal?(:array?)
    keys[key][:array] = true
  elsif name.equal?(:included_in?)
    keys[key][:enum] = rest[0][1]
    keys[key][:enum] += [nil] if opts.fetch(:nullable, false)
  elsif PREDICATE_TO_TYPE[name]
    keys[key][:type] = PREDICATE_TO_TYPE[name]
  else
    description = predicate_description(name, rest[0][1].to_s)
    if keys[key][:description].to_s.empty?
      keys[key][:description] = description unless description.to_s.empty?
    else
      keys[key][:description] += ", #{description}" unless description.to_s.empty?
    end
  end
end

#visit_set(node, opts = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/dry_validation_parser/validation_schema_parser.rb', line 57

def visit_set(node, opts = {})
  target = (key = opts[:key]) ? self.class.new : self

  node.map { |child| target.visit(child, opts) }

  return unless key

  target_info = target.to_h
  type = keys[key][:array] ? "array" : "hash"

  keys.update(key => { **keys[key], type: type, **target_info })
end