require 'quby/compiler/entities' module Quby module Compiler module DSL class ScoreSchemaBuilder < Base def initialize(key:, label:, sbg_key: nil, &block) @score_key = key @score_label = label @score_sbg_key = sbg_key @subschema_params = [] @generated_calculations = [] end def build score_schema = Entities::ScoreSchema.new key: @score_key, label: @score_label, sbg_key: @score_sbg_key, subscore_schemas: @subschema_params [score_schema, @generated_calculations + [generate_score_calculation(score_schema)]] end def subscore(key, label, **options, &block) if block # Generate a key to go with the subscore calculation made from the given block and save it inside the schema calculation_key = :"_#{@score_key}.#{key}" calculation = Entities::ScoreCalculation.new calculation_key, label: "#{@score_label} #{label}", &block @generated_calculations << calculation options.merge!(calculation_key: calculation_key) end @subschema_params << options.merge(key: key, label: label) end private def generate_score_calculation(score_schema) inner_hash_string = score_schema.subscore_schemas.map do |subschema| ":#{subschema.key} => score(:'#{subschema.calculation_key}')" end.join(",\n ") # method-source can only grab whole lines of implementation. For regular questionnaires # this means calculation.sourcecode includes the surrounding score/attention/completion/etc. call. # This surrounding call will be stripped after reading in the source in quby. # We add a fake `score do` call around this generated implementation so the stripping will work correctly score_code_string = "score do\n {#{inner_hash_string}}\nend" Entities::ScoreCalculation.new score_schema.key, label: score_schema.label, sbg_key: score_schema.sbg_key, score: true, ruby_string: score_code_string end end end end end