Class: Inquirex::Accumulation

Inherits:
Object
  • Object
show all
Defined in:
lib/inquirex/accumulator.rb

Overview

Per-step declaration of how a single answer contributes to one accumulator. A Node may carry zero or more Accumulation entries, one per target accumulator.

Supported shapes (exactly one must be set):

lookup:        Hash of answer_value => amount (for :enum)
per_selection: Hash of option_value => amount (for :multi_enum, summed)
per_unit:      Numeric rate multiplied by the answer (for numeric types)
flat:          Numeric amount added if the step has any answer

Constant Summary collapse

SHAPES =

Valid accumulation shapes; exactly one must be declared per entry.

%i[lookup per_selection per_unit flat].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target:, shape:, payload:) ⇒ Accumulation

Returns a new instance of Accumulation.

Parameters:

  • target (Symbol, String)

    accumulator name to contribute to

  • shape (Symbol, String)

    one of SHAPES

  • payload (Hash, Numeric)

    shape-specific data (Hash for :lookup/:per_selection)

Raises:



77
78
79
80
81
82
83
84
# File 'lib/inquirex/accumulator.rb', line 77

def initialize(target:, shape:, payload:)
  @target = target.to_sym
  @shape = shape.to_sym
  raise Errors::DefinitionError, "Unknown accumulator shape: #{shape.inspect}" unless SHAPES.include?(@shape)

  @payload = self.class.send(:normalize_payload, @shape, payload).freeze
  freeze
end

Instance Attribute Details

#payloadObject (readonly)

shape-specific data (Hash or Numeric)

Returns:

  • (Object)

    the current value of payload



67
68
69
# File 'lib/inquirex/accumulator.rb', line 67

def payload
  @payload
end

#shapeSymbol (readonly)

one of :lookup, :per_selection, :per_unit, :flat

Returns:

  • (Symbol)

    the current value of shape



67
68
69
# File 'lib/inquirex/accumulator.rb', line 67

def shape
  @shape
end

#targetSymbol (readonly)

accumulator name to contribute to (e.g. :price)

Returns:

  • (Symbol)

    the current value of target



67
68
69
# File 'lib/inquirex/accumulator.rb', line 67

def target
  @target
end

Class Method Details

.from_h(target, hash) ⇒ Accumulation

Parses a single-key Hash like { "lookup" => {...} } into an Accumulation.

Parameters:

  • target (Symbol, String)

    accumulator name

  • hash (Hash)

    serialized shape (string or symbol keys)

Returns:

Raises:



114
115
116
117
118
119
120
# File 'lib/inquirex/accumulator.rb', line 114

def self.from_h(target, hash)
  pair = hash.to_a.find { |k, _| SHAPES.include?(k.to_sym) }
  raise Errors::SerializationError, "Invalid accumulation entry: #{hash.inspect}" unless pair

  shape_key, payload = pair
  new(target: target, shape: shape_key.to_sym, payload: payload)
end

Instance Method Details

#contribution(answer) ⇒ Numeric

Computes this accumulation's contribution given the step's answer. Returns 0 when the answer is absent or does not match the shape.

Parameters:

  • answer (Object)

    the user's answer for the owning step

Returns:

  • (Numeric)


91
92
93
94
95
96
97
98
99
100
# File 'lib/inquirex/accumulator.rb', line 91

def contribution(answer)
  return 0 if answer.nil?

  case @shape
  when :lookup        then lookup_amount(answer)
  when :per_selection then selection_amount(answer)
  when :per_unit      then unit_amount(answer)
  when :flat          then flat_amount(answer)
  end
end

#to_hHash{String => Object}

Serializes to the single-key shape Hash that .from_h accepts.

Returns:

  • (Hash{String => Object})

    e.g. { "per_unit" => 50 }



105
106
107
# File 'lib/inquirex/accumulator.rb', line 105

def to_h
  { @shape.to_s => serialize_payload }
end