app/models/coupdoeil/hovercard/option.rb



# frozen_string_literal: true
module Coupdoeil
  class Hovercard
    class Option
      InvalidOptionError = Class.new(StandardError)

      class << self
        attr_accessor :bit_size, :key

        def into_bits(value) = parse(value)

        def inherited(subclass)
          super
          subclass.class_eval do
            @key = name.demodulize.underscore.to_sym
          end
        end
      end

      attr_reader :value

      def initialize(value)
        value = value.to_s if value.is_a? Symbol
        @value = value
      end

      def validate! = raise(NotImplementedError)

      private

      def raise_invalid_option(message)
        raise InvalidOptionError,
              "Invalid value '#{value}' (#{value.class.name}) for #{self.class.key} option. #{message}"
      end

      def validate_inclusion!
        values = self.class.const_get("VALUES")
        return if value.in?(values)

        values_sentence = values.to_sentence(two_words_connector: " or ", last_word_connector: " or ")
        raise_invalid_option "Value must be one of: #{values_sentence}"
      end
    end
  end
end