#include "JsonObjects.hpp" #include namespace telebotxx { namespace impl { template<> bool is(const rapidjson::Value& obj) { return obj.IsInt(); } template<> bool is(const rapidjson::Value& obj) { return obj.IsInt64(); } template<> bool is(const rapidjson::Value& obj) { return obj.IsBool(); } template<> bool is(const rapidjson::Value& obj) { return obj.IsString(); } template<> const int get(const rapidjson::Value& obj) { return obj.GetInt(); } template<> const std::int64_t get(const rapidjson::Value& obj) { return obj.GetInt64(); } template<> const bool get(const rapidjson::Value& obj) { return obj.GetBool(); } template<> const std::string get(const rapidjson::Value& obj) { return obj.GetString(); } } bool check(const rapidjson::Value& obj, const char* name) { if (auto value = parse(obj, name, OPTIONAL)) return *value; else return false; } const rapidjson::Value& parseObject(const rapidjson::Value& parent, const char* name, bool required, bool& found) { if (parent.HasMember(name)) { if (parent[name].IsObject()) { found = true; return parent[name]; } else throw ParseError(std::string("Field '") + name + "' has invalid type"); } else if (required) throw ParseError(std::string("Field '") + name + "' not found"); else { found = false; return parent; } } const rapidjson::Value& parseArray(const rapidjson::Value& parent, const char* name, bool required, bool& found) { if (parent.HasMember(name)) { if (parent[name].IsArray()) { found = true; return parent[name]; } else throw ParseError(std::string("Field '") + name + "' has invalid type"); } else if (required) throw ParseError(std::string("Field '") + name + "' not found"); else { found = false; return parent; } } template <> optional parse(const rapidjson::Value& parent, const char* name, bool required) { optional chat; bool found; auto& obj = parseObject(parent, name, required, found); if (found) { chat.emplace(); chat->setId(require(obj, "id")); chat->setType(chatTypeFromString(require(obj, "type"))); chat->setTitle(allow(obj, "title")); chat->setUsername(parse(obj, "username", OPTIONAL)); chat->setFirstName(parse(obj, "first_name", OPTIONAL)); chat->setLastName(parse(obj, "last_name", OPTIONAL)); chat->setAllAdmins(check(obj, "all_members_are_administrators")); } return chat; } template <> optional parse(const rapidjson::Value& parent, const char* name, bool required) { optional user; bool found; auto& obj = parseObject(parent, name, required, found); if (found) { user.emplace(); user->setId(require(obj, "id")); user->setFirstName(require(obj, "first_name")); user->setLastName(allow(obj, "last_name")); } return user; } PhotoSize parsePhotoSize(const rapidjson::Value& obj) { PhotoSize photo; photo.setFileId(require(obj, "file_id")); photo.setWidth(require(obj, "width")); photo.setHeight(require(obj, "height")); photo.setFileSize(allow(obj, "file_size")); return photo; } template <> optional parse(const rapidjson::Value& parent, const char* name, bool required) { optional photo; bool found; auto& obj = parseObject(parent, name, required, found); if (found) { photo.emplace(parsePhotoSize(obj)); } return photo; } template <> optional parse(const rapidjson::Value& parent, const char* name, bool required) { optional photos; bool found; auto& obj = parseArray(parent, name, required, found); if (found) { photos.emplace(); photos->reserve(obj.GetArray().Size()); for (auto& elem : obj.GetArray()) photos->emplace_back(parsePhotoSize(elem)); } return photos; } template <> optional