require_relative './unit_conversion/constants' require_relative './unit_conversion/errors' require_relative './unit_conversion/formatters' require_relative './unit_conversion/parsed_number' require_relative './unit_conversion/parsed_unit' require_relative './unit_conversion/conversions' require_relative './unit_conversion/unitwise_patch' require_relative './unit_conversion/value_unit' module UnitConversion class << self def parse(value_string, unit_string = nil) ValueUnit.for(value_string, unit_string) end def convert(quantity, factor, input_unit, output_unit, density = nil) unit_value = parse(quantity, input_unit).scale(factor) if output_unit.present? unit_value = unit_value.convert(output_unit, density) end unit_value.pretty_value end # Given an awkward measurement such as '18 9/10 oz' or '5/24 cup' or '0.09434 cup', # it will round the rational and scale the unit to give a more reasonable, useful measurement, ie # 19 oz, 3 Tbsp, 1 1/2 Tbsp def auto_unit(quantity, units) unit = parse(quantity, units).auto_unit [unit.pretty_value, unit.unit.to_s] end def with_custom_units(unit_map, &block) atom_configs = [] unit_map.each do |custom_unit, value_unit| raise(UnknownUnitError, "#{value_unit.unit} is not valid") unless (value_unit.mass? || value_unit.volume?) base_name = custom_unit.to_s.strip.downcase atom_configs << { names: [base_name, base_name.pluralize, base_name.singularize].uniq, primary_code: "[prlsy_#{base_name[0]}]", scale: { value: value_unit.value.value, unit_code: value_unit.unitwise.unit.to_s }, property: value_unit.mass? ? 'mass' : 'volume' } end Unitwise::with_custom_units(atom_configs, &block) end end end