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:



119
120
121
122
123
124
125
126
# File 'lib/inquirex/accumulator.rb', line 119

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



109
110
111
# File 'lib/inquirex/accumulator.rb', line 109

def payload
  @payload
end

#shapeSymbol (readonly)

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

Returns:

  • (Symbol)

    the current value of shape



109
110
111
# File 'lib/inquirex/accumulator.rb', line 109

def shape
  @shape
end

#targetSymbol (readonly)

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

Returns:

  • (Symbol)

    the current value of target



109
110
111
# File 'lib/inquirex/accumulator.rb', line 109

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:



156
157
158
159
160
161
162
# File 'lib/inquirex/accumulator.rb', line 156

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)


133
134
135
136
137
138
139
140
141
142
# File 'lib/inquirex/accumulator.rb', line 133

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 }



147
148
149
# File 'lib/inquirex/accumulator.rb', line 147

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