lib/ecu/labels/label.rb



require_relative "../interfaces/dcm/label"
require_relative "../interfaces/lab/label"

require_relative "value_comparison"
require_relative "value_printer"

class Ecu
  class Label

    BYTESIZE  = { number: 4,
                  string: 25 }

    attr_reader :name, :function, :description

    def init_error(message)
      fail ArgumentError, "Error creating #{name}: " +
        message + "\n" +
        inspect_instance_vars + "\n\n"
    end

    def inspect_instance_vars
      instance_variables
        .map { "#{_1} = #{instance_variable_get(_1)}" }
        .join("\n")
    end

    def type
      self.class.name.split('::').last
    end

    def equality_properties
      fail NotImplementedError, "Must be implemented in child classes"
    end

    def properties
      fail NotImplementedError, "Must be implemented in child classes"
    end

    def <=>(other)
      name <=> other.name if other.respond_to?(:name)
    end

    def hash
      equality_properties.map { |p| self.public_send(p) }.hash
    end

    def to_h
      properties.zip(properties.map { |p| instance_variable_get("@#{p}".to_sym) }).to_h
    end

    def with(hash={})
      return self if hash.empty?
      self.class.new(**to_h.merge(hash))
    end

    def ==(other)
      return false unless other.instance_of?(self.class)
      equality_properties.all? do |p|
        if %i(value xvalue yvalue).include?(p)
          ValueComparison.new(self.public_send(p), other.public_send(p)).eql?
        else
          self.public_send(p) == other.public_send(p)
        end
      end
    end

    def ===(other)
      name == other.name
    end

    def match(selector)
      %i(name function description).any? do |property|
        self.public_send(property) && self.public_send(property).match(selector)
      end
    end

    def valuestats(value, show_avg: false)
      value = [value].flatten
      min, avg, max = value.min, value.avg.round(1), value.max
      if show_avg
        "[#{min};~#{avg};#{max}]"
      else
        "[#{min};#{max}]"
      end
    end

    alias :eql? :==

  end
end