Sha256: 4c982a7fc24db7edf22856ae39f6a1bd1a62ce6bf8a5eff547a9c2a9d9e66a6b

Contents?: true

Size: 1.67 KB

Versions: 2

Compression:

Stored size: 1.67 KB

Contents

# frozen_string_literal: true

require 'media_types/scheme/errors'
require 'media_types/scheme/output_iterator_with_predicate'

module MediaTypes
  class Scheme
    class RulesExhaustedGuard

      EMPTY_MARK = ->(_) {}

      class << self
        def call(*args, **opts, &block)
          new(*args, **opts).call(&block)
        end
      end

      def initialize(output, options, rules:)
        self.rules = rules
        self.output = output
        self.options = options
      end

      def call
        unless options.exhaustive
          return iterate(EMPTY_MARK)
        end

        required_rules = rules.required
        # noinspection RubyScope
        result = iterate(->(key) { required_rules.remove(key) })
        return result if required_rules.empty?

        raise_exhausted!(missing_keys: required_rules.keys, backtrace: options.backtrace, found: output)
      end

      def iterate(mark)
        OutputIteratorWithPredicate.call(output, options, rules: rules) do |key, value, options:, context:|
          mark.call(key)

          rules.get(key).validate!(
            value,
            options.trace(key),
            context: context
          )
        end
      end

      private

      attr_accessor :rules, :options, :output

      def raise_exhausted!(missing_keys:, backtrace:, found:)
        raise ExhaustedOutputError, format(
          'Missing keys in output: %<missing_keys>s at [%<backtrace>s]. I did find: %<found>s',
          missing_keys: missing_keys,
          backtrace: backtrace.join('->'),
          found: (found.is_a? Hash) ? found.keys : found.class.name,
        )
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
media_types-2.0.1 lib/media_types/scheme/rules_exhausted_guard.rb
media_types-2.0.0 lib/media_types/scheme/rules_exhausted_guard.rb