module CartoJson class Parser def self.parse(input) p = new input p.parse end def initialize(input) @input = input @parsed = nil end def parse(input=@input) return nil if input.nil? case input when Array @parsed = [] input.each {|element| @parsed << parse_element(element) } when Hash input = Utils.symbolize_keys(input) @parsed = parse_element input when String begin decoded = MultiJson.decode(input, :symbolize_keys => true) rescue MultiJson::DecodeError => e raise InputError, "unable to decode JSON: \"#{e.message}\"" end @parsed = parse decoded else raise InputError, "expected Array, Hash or String, you provided #{input.class}" end @parsed end def parse_element(element) if element[:type].nil? if element[LAT] && element[LNG] element[:type] = 'point' else raise InputError, "cannot determine type for the provided element (type is missing or #{LAT}/#{LNG} are not present)" end end unless TYPES.include? element[:type].to_sym raise InvalidTypeError.new(element[:type].to_sym, "unsupported type: \"#{element[:type]}\", supported types: #{TYPES.join(', ')}") end class_name = element[:type] == 'linestring' ? 'LineString' : element[:type].capitalize CartoJson.const_get(class_name).parse element end end end