# frozen_string_literal: true require "roundable" module Versions class V1 < Roda module Quote class Base include Roundable attr_reader :amount, :base, :date, :symbols, :result def initialize(date:, amount: 1.0, base: "EUR", symbols: nil) @date = date @amount = amount @base = base @symbols = symbols @result = {} end def perform return false if result.frozen? prepare_rates rebase_rates if must_rebase? result.freeze end def must_rebase? base != "EUR" end def should_round? amount != 1.0 || must_rebase? end def formatted raise NotImplementedError end def not_found? result.empty? end def cache_key raise NotImplementedError end private def data @data ||= fetch_data end def fetch_data raise NotImplementedError end def prepare_rates data.each_with_object(result) do |currency, result| date = currency[:date].to_date.to_s result[date] ||= {} rate = amount * currency[:rate] result[date][currency[:quote]] = should_round? ? round(rate) : rate end end def rebase_rates result.each do |date, rates| rates["EUR"] = amount if symbols.nil? || symbols.include?("EUR") divisor = rates.delete(base) if divisor.nil? || rates.empty? result.delete(date) else result[date] = rates.sort .map! do |quote, rate| [quote, round(amount * rate / divisor)] end .to_h end end end end end end end