2016-02-02 15:48:20 -06:00
|
|
|
module UnitConversion
|
|
|
|
class ParsedUnit
|
|
|
|
|
|
|
|
attr_reader :original_unit, :unit
|
|
|
|
|
|
|
|
def initialize(str)
|
|
|
|
@original_unit = str
|
|
|
|
@unit = normalize_unit_names(str)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
unit.gsub(/[a-z_\[\]]+/) do |match|
|
|
|
|
if aliases = UNIT_ALIASES[match.to_sym]
|
|
|
|
aliases.first
|
|
|
|
else
|
|
|
|
match
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def density?
|
|
|
|
compatible? 'g/ml'
|
|
|
|
end
|
|
|
|
|
|
|
|
def volume?
|
|
|
|
compatible? 'ml'
|
|
|
|
end
|
|
|
|
|
|
|
|
def mass?
|
|
|
|
compatible? 'g'
|
|
|
|
end
|
|
|
|
|
|
|
|
def metric?
|
|
|
|
METRIC_UNIT_ALIASES.keys.include? unit.to_sym
|
|
|
|
end
|
|
|
|
|
|
|
|
def unitwise(value = 1)
|
|
|
|
begin
|
|
|
|
Unitwise(value, unit)
|
|
|
|
rescue Unitwise::ExpressionError => err
|
|
|
|
raise UnknownUnitError, err.message
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def compatible?(unit_str)
|
|
|
|
begin
|
|
|
|
unitwise.compatible_with? Unitwise(1, unit_str)
|
2018-09-14 19:32:49 -05:00
|
|
|
rescue UnknownUnitError, TypeError, Unitwise::ConversionError, Unitwise::ExpressionError
|
2016-02-02 15:48:20 -06:00
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def normalize_unit_names(unit_description)
|
|
|
|
return unit_description.to_s if UNIT_ALIASES.include?(unit_description.to_sym)
|
|
|
|
|
|
|
|
# fluid ounce is the only known unit with a space; fix it up before the following replacement
|
|
|
|
unit_description = unit_description.gsub(/fl oz/i, 'floz')
|
|
|
|
|
2016-03-10 16:06:39 -06:00
|
|
|
# if a cubic unit is found, map it to unit3 (ex 'cubic inches' is converted to 'inches3')
|
|
|
|
unit_description = unit_description.gsub(/cubic\s+(\w+)/i, '\13')
|
|
|
|
|
2016-02-02 15:48:20 -06:00
|
|
|
unit_description.downcase.gsub(/[a-z_\[\]]+/) do |match|
|
|
|
|
UNIT_ALIAS_MAP[match] || match
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|