# frozen_string_literal: true
module Html2rss
##
# Provides a namespace for attribute post processors.
module AttributePostProcessors
##
# All post processors must inherit from this base class and implement `self.validate_args!` and `#get`.
class Base
# Validates the presence of required options in the context
#
# @param keys [Array] the keys to check for presence
# @param context [Hash] the context containing options
# @raise [MissingOption] if any key is missing
def self.expect_options(keys, context)
keys.each do |key|
unless (options = context[:options]).key?(key)
raise MissingOption, "The `#{key}` option is missing in: #{options.inspect}", [],
cause: nil
end
end
end
# Asserts that the value is of the expected type(s)
#
# @param value [Object] the value to check
# @param types [Array, Class] the expected type(s)
# @param name [String] the name of the option being checked
# @param context [Item::Context] the context
# @raise [InvalidType] if the value is not of the expected type(s)
def self.assert_type(value, types = [], name, context:)
types = [types] unless types.is_a?(Array)
return if types.any? { |type| value.is_a?(type) }
options = context[:options] if context.is_a?(Hash)
options ||= { file: File.basename(caller_locations(1, 1).first.absolute_path) }
raise InvalidType, format('The type of `%s` must be %s, but is: %s in: %s',
name:, types: types.join(' or '), type: value.class, options: options.inspect),
[], cause: nil
end
##
# This method validates the arguments passed to the post processor. Must be implemented by subclasses.
def self.validate_args!(_value, _context)
raise NotImplementedError, 'You must implement the `validate_args!` method in the post processor'
end
# Initializes the post processor
#
# @param value [Object] the value to be processed
# @param context [Item::Context] the context
def initialize(value, context)
klass = self.class
# TODO: get rid of Hash
klass.assert_type(context, [Item::Context, Hash], 'context', context:)
klass.validate_args!(value, context)
@value = value
@context = context
end
attr_reader :value, :context
# Abstract method to be implemented by subclasses
#
# @raise [NotImplementedError] if not implemented in subclass
def get
raise NotImplementedError, 'You must implement the `get` method in the post processor'
end
end
end
end