class Dry::Schema::Messages::YAML

@api public
Plain YAML message backend

def self.build(options = EMPTY_HASH)

Other tags:
    Api: - private
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

def self.cache

Other tags:
    Api: - private
def self.cache
  @cache ||= Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new }
end

def self.flat_hash(hash, path = EMPTY_ARRAY, keys = {})

Other tags:
    Api: - private
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

def self.source_cache

Other tags:
    Api: - private
def self.source_cache
  @source_cache ||= Concurrent::Map.new
end

def cache

Other tags:
    Api: - private
def cache
  @cache ||= self.class.cache[self]
end

def evaluated_key(key, options)

Other tags:
    Api: - private
def evaluated_key(key, options)
  return key unless key.include?(LOCALE_TOKEN)
  key % {locale: options[:locale] || default_locale}
end

def evaluation_context(key, options)

Other tags:
    Api: - private
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

def get(key, options = EMPTY_HASH)

Other tags:
    Api: - public

Returns:
  • (String) -

Parameters:
  • options (Hash) --
  • key (Symbol) --
def get(key, options = EMPTY_HASH)
  data[evaluated_key(key, options)]
end

def initialize(data: EMPTY_HASH, config: nil)

Other tags:
    Api: - private
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

def interpolatable_data(key, options, **data)

Other tags:
    Api: - private
def interpolatable_data(key, options, **data)
  tokens = evaluation_context(key, options).fetch(:tokens)
  data.select { |k,| tokens.include?(k) }
end

def interpolate(key, options, **data)

Other tags:
    Api: - private
def interpolate(key, options, **data)
  evaluator = evaluation_context(key, options).fetch(:evaluator)
  data.empty? ? evaluator.() : evaluator.(**data)
end

def key?(key, options = EMPTY_HASH)

Other tags:
    Api: - public

Returns:
  • (Boolean) -
def key?(key, options = EMPTY_HASH)
  data.key?(evaluated_key(key, options))
end

def load_translations(path)

Other tags:
    Api: - private
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

def looked_up_paths(predicate, options)

Other tags:
    Api: - public

Returns:
  • (String) -

Parameters:
  • options (Hash) --
  • predicate (Symbol) --
def looked_up_paths(predicate, options)
  super.map { |path| path % {locale: options[:locale] || default_locale} }
end

def merge(overrides)

Other tags:
    Api: - public

Returns:
  • (Messages::I18n) -

Parameters:
  • overrides (String) --
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

def prepare

Other tags:
    Api: - private
def prepare
  @data = config.load_paths.map { |path| load_translations(path) }.reduce({}, :merge)
  self
end