class Eco::API::Common::People::DefaultParsers::NumericParser < Eco::API::Common::Loaders::Parser attribute :number def parser(value, deps) parse_number(value, attr: deps['attr']) end def serializer(value, _deps) value.is_a?(Array) ? value.map(&:to_s) : value.to_s end private def parse_number(value, attr:) return value.map {|val| parse_number(val, attr: attr)}.compact if value.is_a?(Enumerable) return nil if blank?(value) value = value.to_s.strip return wrong!(value, attr: attr) unless number?(value) value.to_f rescue ArgumentError, TypeError nil end def number?(value) true if Float(value) rescue ArgumentError, TypeError false end def wrong!(value, attr:, desc: "Can't make a number out of") return if wrong(attr).key?(value) wrong(attr)[value] = value log(:warn) { "#{desc} '#{value}' for '#{attr}'" } nil end def wrong(attr = nil) @wrong ||= {} return @wrong if attr.nil? @wrong[attr] ||= {} end def blank?(value) return true if value.nil? return true if value.to_s.strip.empty? false end end