Class: Dry::Schema::MessageCompiler Private

Inherits:
Object
  • Object
show all
Extended by:
Initializer
Includes:
Extensions::Hints::MessageCompilerMethods
Defined in:
lib/dry/schema/message_compiler.rb,
lib/dry/schema/message_compiler/visitor_opts.rb

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

Defined Under Namespace

Classes: VisitorOpts

Constant Summary collapse

DEFAULT_PREDICATE_RESOLVERS =

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

Hash
.new(resolve_predicate).update(key?: resolve_key_predicate).freeze
EMPTY_OPTS =

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

VisitorOpts.new
EMPTY_MESSAGE_SET =

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

MessageSet.new(EMPTY_ARRAY).freeze

Constants included from Extensions::Hints::MessageCompilerMethods

Extensions::Hints::MessageCompilerMethods::HINT_OTHER_EXCLUSION, Extensions::Hints::MessageCompilerMethods::HINT_TYPE_EXCLUSION

Instance Attribute Summary collapse

Attributes included from Extensions::Hints::MessageCompilerMethods

#hints

Instance Method Summary collapse

Methods included from Extensions::Hints::MessageCompilerMethods

#exclude?, #filter, #hints?, #visit_each

Constructor Details

#initialize(messages, options = EMPTY_HASH) ⇒ MessageCompiler

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 MessageCompiler.



44
45
46
47
48
# File 'lib/dry/schema/message_compiler.rb', line 44

def initialize(messages, options = EMPTY_HASH)
  super
  @options = options
  @default_lookup_options = options[:locale] ? { locale: locale } : EMPTY_HASH
end

Instance Attribute Details

#default_lookup_optionsObject (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.



41
42
43
# File 'lib/dry/schema/message_compiler.rb', line 41

def default_lookup_options
  @default_lookup_options
end

#optionsObject (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.



39
40
41
# File 'lib/dry/schema/message_compiler.rb', line 39

def options
  @options
end

Instance Method Details

#call(ast) ⇒ 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.



62
63
64
65
66
67
68
69
# File 'lib/dry/schema/message_compiler.rb', line 62

def call(ast)
  return EMPTY_MESSAGE_SET if ast.empty?

  current_messages = EMPTY_ARRAY.dup
  compiled_messages = ast.map { |node| visit(node, EMPTY_OPTS.dup(current_messages)) }

  MessageSet[compiled_messages, failures: options.fetch(:failures, true)]
end

#lookup_options(arg_vals:, input:) ⇒ 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.



171
172
173
174
175
176
# File 'lib/dry/schema/message_compiler.rb', line 171

def lookup_options(arg_vals:, input:)
  default_lookup_options.merge(
    arg_type: arg_vals.size == 1 && arg_vals[0].class,
    val_type: input.equal?(Undefined) ? NilClass : input.class
  )
end

#message_text(template, tokens, options) ⇒ 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.



179
180
181
182
183
184
185
186
# File 'lib/dry/schema/message_compiler.rb', line 179

def message_text(template, tokens, options)
  text = template[template.data(tokens)]

  return text unless full

  rule = options[:path]
  "#{messages.rule(rule, options) || rule} #{text}"
end

#message_tokens(args) ⇒ 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.



189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/dry/schema/message_compiler.rb', line 189

def message_tokens(args)
  args.each_with_object({}) do |arg, hash|
    case arg[1]
    when Array
      hash[arg[0]] = arg[1].join(LIST_SEPARATOR)
    when Range
      hash["#{arg[0]}_left".to_sym] = arg[1].first
      hash["#{arg[0]}_right".to_sym] = arg[1].last
    else
      hash[arg[0]] = arg[1]
    end
  end
end

#message_typeObject

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.



143
144
145
# File 'lib/dry/schema/message_compiler.rb', line 143

def message_type(*)
  Message
end

#visit(node, opts = EMPTY_OPTS.dup) ⇒ 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.



72
73
74
# File 'lib/dry/schema/message_compiler.rb', line 72

def visit(node, opts = EMPTY_OPTS.dup)
  __send__(:"visit_#{node[0]}", node[1], 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.



93
94
95
96
97
98
99
100
101
# File 'lib/dry/schema/message_compiler.rb', line 93

def visit_and(node, opts)
  left, right = node.map { |n| visit(n, opts) }

  if right
    [left, right]
  else
    left
  end
end

#visit_failure(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.



77
78
79
80
# File 'lib/dry/schema/message_compiler.rb', line 77

def visit_failure(node, opts)
  rule, other = node
  visit(other, opts.(rule: rule))
end

#visit_hintObject

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.



83
84
85
# File 'lib/dry/schema/message_compiler.rb', line 83

def visit_hint(*)
  nil
end

#visit_implication(node, *args) ⇒ 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.



159
160
161
162
# File 'lib/dry/schema/message_compiler.rb', line 159

def visit_implication(node, *args)
  _, right = node
  visit(right, *args)
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.



148
149
150
151
# File 'lib/dry/schema/message_compiler.rb', line 148

def visit_key(node, opts)
  name, other = node
  visit(other, opts.(path: name))
end

#visit_namespace(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.



117
118
119
120
# File 'lib/dry/schema/message_compiler.rb', line 117

def visit_namespace(node, opts)
  ns, rest = node
  self.class.new(messages.namespaced(ns), options).visit(rest, opts)
end

#visit_not(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.



88
89
90
# File 'lib/dry/schema/message_compiler.rb', line 88

def visit_not(node, opts)
  visit(node, opts.(not: true))
end

#visit_or(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.



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dry/schema/message_compiler.rb', line 104

def visit_or(node, opts)
  left, right = node.map { |n| visit(n, opts) }

  if [left, right].flatten.map(&:path).uniq.size == 1
    Message::Or.new(left, right, proc { |k| messages.translate(k, default_lookup_options) })
  elsif right.is_a?(Array)
    right
  else
    [left, right].flatten.max
  end
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.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/dry/schema/message_compiler.rb', line 123

def visit_predicate(node, opts)
  predicate, args = node

  tokens = message_tokens(args)
  path, *arg_vals, input = predicate_resolvers[predicate].(args, opts)

  options = opts.dup.update(
    path: path.last, **tokens, **lookup_options(arg_vals: arg_vals, input: input)
  ).to_h

  template, meta = messages[predicate, options] || raise(MissingMessageError, path)

  text = message_text(template, tokens, options)

  message_type(options).new(
    text: text, path: path, predicate: predicate, args: arg_vals, input: input, meta: meta
  )
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.



154
155
156
# File 'lib/dry/schema/message_compiler.rb', line 154

def visit_set(node, opts)
  node.map { |el| visit(el, opts) }
end

#visit_xor(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.



165
166
167
168
# File 'lib/dry/schema/message_compiler.rb', line 165

def visit_xor(node, opts)
  left, right = node
  [visit(left, opts), visit(right, opts)].uniq
end

#with(new_options) ⇒ 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
55
56
57
58
59
# File 'lib/dry/schema/message_compiler.rb', line 51

def with(new_options)
  return self if new_options.empty?

  updated_opts = options.merge(new_options)

  return self if updated_opts.eql?(options)

  self.class.new(messages, updated_opts)
end