33 lines
847 B
Ruby
33 lines
847 B
Ruby
![]() |
module UnitConversion
|
||
|
|
||
|
UNIT_PARSING_REGEX = /^(?<value>(?:-?[0-9]+)?(?:\.?[0-9]*)?)\s*(?<unit>[a-z\/.\-()0-9]+)$/
|
||
|
|
||
|
class UnparseableUnitError < StandardError
|
||
|
end
|
||
|
|
||
|
class UnknownUnitError < UnparseableUnitError
|
||
|
end
|
||
|
|
||
|
class << self
|
||
|
|
||
|
def parse(unit_string)
|
||
|
match = UNIT_PARSING_REGEX.match(unit_string.to_s.strip)
|
||
|
|
||
|
if match && match[:value].present? && match[:unit].present?
|
||
|
begin
|
||
|
Unitwise(match[:value].to_f, match[:unit])
|
||
|
rescue Unitwise::ExpressionError => err
|
||
|
raise UnknownUnitError, err.message
|
||
|
end
|
||
|
else
|
||
|
raise UnparseableUnitError, "'#{unit_string}' does not appear to be a valid measurement of the form <value> <units> (ie '5 cup' or '223 gram/cup')"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def density?(unit)
|
||
|
unit.compatible_with? Unitwise(1, 'g/ml')
|
||
|
end
|
||
|
|
||
|
end
|
||
|
end
|