class Dry::Schema::Messages::YAML
Plain YAML
message backend
@api public
Constants
- EMPTY_CONTEXT
- LOCALE_TOKEN
- TOKEN_REGEXP
Attributes
data[R]
Loaded localized message templates
@return [Hash]
t[R]
Translation function
@return [Proc]
Public Class Methods
build(options = EMPTY_HASH)
click to toggle source
@api private
Calls superclass method
Dry::Schema::Messages::Abstract::build
# File lib/dry/schema/messages/yaml.rb, line 38 def self.build(options = EMPTY_HASH) super do |config| config.default_locale = :en unless config.default_locale config.root = -"%<locale>s.#{config.root}" config.rule_lookup_paths = config.rule_lookup_paths.map { |path| -"%<locale>s.#{path}" } end end
cache()
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 74 def self.cache @cache ||= Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new } end
flat_hash(hash, path = EMPTY_ARRAY, keys = {})
click to toggle source
@api private rubocop: disable Metrics/PerceivedComplexity
# File lib/dry/schema/messages/yaml.rb, line 52 def self.flat_hash(hash, path = EMPTY_ARRAY, keys = {}) hash.each do |key, value| flat_hash(value, [*path, key], keys) if value.is_a?(Hash) if value.is_a?(String) && hash["text"] != value keys[[*path, key].join(DOT)] = { text: value, meta: EMPTY_HASH } elsif value.is_a?(Hash) && value["text"].is_a?(String) keys[[*path, key].join(DOT)] = { text: value["text"], meta: value.reject { _1.eql?("text") }.transform_keys(&:to_sym) } end end keys end
new(data: EMPTY_HASH, config: nil)
click to toggle source
@api private
Calls superclass method
# File lib/dry/schema/messages/yaml.rb, line 84 def initialize(data: EMPTY_HASH, config: nil) super() @data = data @config = config if config @t = proc { |key, locale: default_locale| get("%<locale>s.#{key}", locale: locale) } end
source_cache()
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 79 def self.source_cache @source_cache ||= Concurrent::Map.new end
Public Instance Methods
get(key, options = EMPTY_HASH)
click to toggle source
Get a message for the given key and its options
@param [Symbol] key @param [Hash] options
@return [String]
@api public
# File lib/dry/schema/messages/yaml.rb, line 111 def get(key, options = EMPTY_HASH) data[evaluated_key(key, options)] end
interpolatable_data(key, options, **data)
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 152 def interpolatable_data(key, options, **data) tokens = evaluation_context(key, options).fetch(:tokens) data.select { |k,| tokens.include?(k) } end
interpolate(key, options, **data)
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 158 def interpolate(key, options, **data) evaluator = evaluation_context(key, options).fetch(:evaluator) data.empty? ? evaluator.() : evaluator.(**data) end
key?(key, options = EMPTY_HASH)
click to toggle source
Check if given key is defined
@return [Boolean]
@api public
# File lib/dry/schema/messages/yaml.rb, line 120 def key?(key, options = EMPTY_HASH) data.key?(evaluated_key(key, options)) end
looked_up_paths(predicate, options)
click to toggle source
Get an array of looked up paths
@param [Symbol] predicate @param [Hash] options
@return [String]
@api public
Calls superclass method
Dry::Schema::Messages::Abstract#looked_up_paths
# File lib/dry/schema/messages/yaml.rb, line 99 def looked_up_paths(predicate, options) super.map { |path| path % {locale: options[:locale] || default_locale} } end
merge(overrides)
click to toggle source
Merge messages from an additional path
@param [String] overrides
@return [Messages::I18n]
@api public
# File lib/dry/schema/messages/yaml.rb, line 131 def merge(overrides) if overrides.is_a?(Hash) self.class.new( data: data.merge(self.class.flat_hash(overrides)), config: config ) else self.class.new( data: Array(overrides).reduce(data) { |a, e| a.merge(load_translations(e)) }, config: config ) end end
prepare()
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 146 def prepare @data = config.load_paths.map { |path| load_translations(path) }.reduce({}, :merge) self end
Private Instance Methods
cache()
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 187 def cache @cache ||= self.class.cache[self] end
evaluated_key(key, options)
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 203 def evaluated_key(key, options) return key unless key.include?(LOCALE_TOKEN) key % {locale: options[:locale] || default_locale} end
evaluation_context(key, options)
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 166 def evaluation_context(key, options) cache.fetch_or_store(get(key, options).fetch(:text)) do |input| tokens = input.scan(TOKEN_REGEXP).flatten(1).map(&:to_sym).to_set text = input.gsub("%", "#") # rubocop:disable Security/Eval # rubocop:disable Style/DocumentDynamicEvalDefinition evaluator = eval(<<~RUBY, EMPTY_CONTEXT, __FILE__, __LINE__ + 1) -> (#{tokens.map { |token| "#{token}:" }.join(", ")}) { "#{text}" } RUBY # rubocop:enable Style/DocumentDynamicEvalDefinition # rubocop:enable Security/Eval { tokens: tokens, evaluator: evaluator } end end
load_translations(path)
click to toggle source
@api private
# File lib/dry/schema/messages/yaml.rb, line 192 def load_translations(path) data = self.class.source_cache.fetch_or_store(path) do self.class.flat_hash(::YAML.load_file(path)).freeze end return data unless custom_top_namespace?(path) data.transform_keys { _1.gsub(DEFAULT_MESSAGES_ROOT, config.top_namespace) } end