/*
 * Copyright (C) 2017-2019 Eelke Klein
 * Contact: eelke.klein@gmail.com
 *
 * This file is part of the Pgsql module of the pgLab program.
 */
#ifndef ARRAYPARSER_H
#define ARRAYPARSER_H

#include <optional>
#include <tuple>
#include <string>
#include <string_view>

namespace Pgsql {
	/** Class for parsing array values coming from postgresql
	 *
	 * exceptions are used to report serious errors
	 * in production these kind of errors should rarely happen as
	 * they are either a bug in this parser or postgres changed its format.
	 */
	class ArrayParser {
	public:
		/**
		 * \param data The string that needs parsing (warning just the pointer is stored, the string is not copied)
		 */
		ArrayParser(const char *array_string, int length);

		class NextElemResult {
		public:
			bool ok;
			std::optional<std::string_view> value;
		};
		/**
		 *
		 * Usage:
		 *   auto [ok, val] = parser.GetNextElem();
		 *
		 * \return the bool signals if there was a next element when it is true or the end of the array in which
		 *   case it is false. The optional is not set when the next element IS NULL. Otherwise it refers to the
		 *   string value of the element. If the element was quoted it has been stripped of quotes and escapes.
		 */
		NextElemResult GetNextElem();
	private:
		const char *data;
		const char *end;
		std::string temp; // internal buffer for when a value needs escaping
		const char *pos;

		void parseQuotedValue();
		void initializeParse();
		/** Moves pos forward to the first non whitespace character.
		 */
		void skipWhitespace();
	};

} // end namespace Pgsql

#endif // ARRAYPARSER_H
