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
FULL_MESSAGE_WHITESPACE =

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(" ").merge(
  ja: "",
  zh: "",
  bn: "",
  th: "",
  lo: "",
  my: ""
)

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) ⇒ 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.



48
49
50
51
52
# File 'lib/dry/schema/message_compiler.rb', line 48

def initialize(messages, **options)
  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.



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

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.



43
44
45
# File 'lib/dry/schema/message_compiler.rb', line 43

def options
  @options
end

Instance Method Details

#append_mapped_size_tokens(tokens) ⇒ 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.



225
226
227
228
229
230
231
# File 'lib/dry/schema/message_compiler.rb', line 225

def append_mapped_size_tokens(tokens)
  # this is a temporary fix for the inconsistency in the "size" errors arguments
  mapped_hash = tokens.each_with_object({}) { |(k, v), h|
    h[k.to_s.gsub("size", "num").to_sym] = v
  }
  tokens.merge(mapped_hash)
end

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



66
67
68
69
70
71
72
73
# File 'lib/dry/schema/message_compiler.rb', line 66

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.



190
191
192
193
194
195
# File 'lib/dry/schema/message_compiler.rb', line 190

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.



198
199
200
201
202
203
204
205
206
# File 'lib/dry/schema/message_compiler.rb', line 198

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

  return text if !text || !full

  rule = options[:path]
  [messages.rule(rule, options) || rule,
   text].join(FULL_MESSAGE_WHITESPACE[template.options[:locale]])
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.



209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/dry/schema/message_compiler.rb', line 209

def message_tokens(args)
  tokens = 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
  args.any? { |e| e.first == :size } ? append_mapped_size_tokens(tokens) : tokens
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.



162
163
164
# File 'lib/dry/schema/message_compiler.rb', line 162

def message_type(*)
  Message
end

#or_translatorObject

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.



119
120
121
122
123
124
# File 'lib/dry/schema/message_compiler.rb', line 119

def or_translator
  @or_translator ||= proc { |k|
    message = messages.translate(k, **default_lookup_options)
    message.is_a?(Hash) ? message[:text] : 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.



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

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.



97
98
99
100
101
102
103
104
105
# File 'lib/dry/schema/message_compiler.rb', line 97

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.



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

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.



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

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.



178
179
180
181
# File 'lib/dry/schema/message_compiler.rb', line 178

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.



167
168
169
170
# File 'lib/dry/schema/message_compiler.rb', line 167

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.



127
128
129
130
# File 'lib/dry/schema/message_compiler.rb', line 127

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.



92
93
94
# File 'lib/dry/schema/message_compiler.rb', line 92

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.



113
114
115
116
# File 'lib/dry/schema/message_compiler.rb', line 113

def visit_or(node, opts)
  left, right = node.map { |n| visit(n, opts) }
  Message::Or[left, right, or_translator]
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.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/dry/schema/message_compiler.rb', line 133

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]

  unless template
    raise MissingMessageError.new(path, messages.looked_up_paths(predicate, options))
  end

  text = message_text(template, tokens, options)

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



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

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

#visit_unexpected_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.



108
109
110
# File 'lib/dry/schema/message_compiler.rb', line 108

def visit_unexpected_key(node, opts)
  visit_predicate([:unexpected_key, []], opts.dup.update(path: Path[node.first]))
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.



184
185
186
187
# File 'lib/dry/schema/message_compiler.rb', line 184

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.



55
56
57
58
59
60
61
62
63
# File 'lib/dry/schema/message_compiler.rb', line 55

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