diff options
Diffstat (limited to 'src/tgbot/Parser.h')
-rw-r--r-- | src/tgbot/Parser.h | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/tgbot/Parser.h b/src/tgbot/Parser.h new file mode 100644 index 0000000..48a7cea --- /dev/null +++ b/src/tgbot/Parser.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015 Oleg Morozenkov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef TGBOT_CPP_PARSER_H +#define TGBOT_CPP_PARSER_H + +#include <string> + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> + +#include "tgbot/types/User.h" +#include "tgbot/types/GroupChat.h" +#include "tgbot/types/Message.h" +#include "tgbot/types/PhotoSize.h" +#include "tgbot/types/Audio.h" +#include "tgbot/types/Document.h" +#include "tgbot/types/Sticker.h" +#include "tgbot/types/Video.h" +#include "tgbot/types/Contact.h" +#include "tgbot/types/Location.h" +#include "tgbot/types/Update.h" +#include "tgbot/types/UserProfilePhotos.h" +#include "tgbot/types/ReplyKeyboardMarkup.h" +#include "tgbot/types/ReplyKeyboardHide.h" +#include "tgbot/types/ForceReply.h" +#include "tgbot/types/GenericReply.h" + +namespace TgBot { + +class Parser { + +public: + User::Ptr parseUser(const boost::property_tree::ptree& data) const; + std::string parseUser(const User::Ptr& object) const; + GroupChat::Ptr parseGroupChat(const boost::property_tree::ptree& data) const; + std::string parseGroupChat(const GroupChat::Ptr& object) const; + Message::Ptr parseMessage(const boost::property_tree::ptree& data) const; + std::string parseMessage(const Message::Ptr& object) const; + PhotoSize::Ptr parsePhotoSize(const boost::property_tree::ptree& data) const; + std::string parsePhotoSize(const PhotoSize::Ptr& object) const; + Audio::Ptr parseAudio(const boost::property_tree::ptree& data) const; + std::string parseAudio(const Audio::Ptr& object) const; + Document::Ptr parseDocument(const boost::property_tree::ptree& data) const; + std::string parseDocument(const Document::Ptr& object) const; + Sticker::Ptr parseSticker(const boost::property_tree::ptree& data) const; + std::string parseSticker(const Sticker::Ptr& object) const; + Video::Ptr parseVideo(const boost::property_tree::ptree& data) const; + std::string parseVideo(const Video::Ptr& object) const; + Contact::Ptr parseContact(const boost::property_tree::ptree& data) const; + std::string parseContact(const Contact::Ptr& object) const; + Location::Ptr parseLocation(const boost::property_tree::ptree& data) const; + std::string parseLocation(const Location::Ptr& object) const; + Update::Ptr parseUpdate(const boost::property_tree::ptree& data) const; + std::string parseUpdate(const Update::Ptr& object) const; + UserProfilePhotos::Ptr parseUserProfilePhotos(const boost::property_tree::ptree& data) const; + std::string parseUserProfilePhotos(const UserProfilePhotos::Ptr& object) const; + ReplyKeyboardMarkup::Ptr parseReplyKeyboardMarkup(const boost::property_tree::ptree& data) const; + std::string parseReplyKeyboardMarkup(const ReplyKeyboardMarkup::Ptr& object) const; + ReplyKeyboardHide::Ptr parseReplyKeyboardHide(const boost::property_tree::ptree& data) const; + std::string parseReplyKeyboardHide(const ReplyKeyboardHide::Ptr& object) const; + ForceReply::Ptr parseForceReply(const boost::property_tree::ptree& data) const; + std::string parseForceReply(const ForceReply::Ptr& object) const; + GenericChat::Ptr parseGenericChat(const boost::property_tree::ptree& data) const; + std::string parseGenericChat(const GenericChat::Ptr& object) const; + GenericReply::Ptr parseGenericReply(const boost::property_tree::ptree& data) const; + std::string parseGenericReply(const GenericReply::Ptr& object) const; + + inline boost::property_tree::ptree parseJson(const std::string& json) const { + boost::property_tree::ptree tree; + std::istringstream input(json); + boost::property_tree::read_json(input, tree); + return tree; + } + + template<typename T> + std::shared_ptr<T> tryParse(std::shared_ptr<T> (Parser::*const parseFunc)(const boost::property_tree::ptree&) const, const boost::property_tree::ptree& data, const std::string& keyName) const { + auto treeItem = data.find(keyName); + if (treeItem == data.not_found()) { + return std::shared_ptr<T>(); + } + return (this->*parseFunc)(treeItem->second); + } + + template<typename T> + std::vector<std::shared_ptr<T>> parseArray(std::shared_ptr<T> (Parser::*const parseFunc)(const boost::property_tree::ptree&) const, const boost::property_tree::ptree& data, const std::string& keyName) const { + std::vector<std::shared_ptr<T>> result; + auto treeItem = data.find(keyName); + if (treeItem == data.not_found()) { + return result; + } + for (const std::pair<const std::string, boost::property_tree::ptree>& innerTreeItem : treeItem->second) { + result.push_back((this->*parseFunc)(innerTreeItem.second)); + } + return result; + } + + template<typename T> + std::vector<std::vector<std::shared_ptr<T>>> parse2DArray(std::shared_ptr<T> (Parser::*const parseFunc)(const boost::property_tree::ptree&) const, const boost::property_tree::ptree& data, const std::string& keyName) const { + std::vector<std::vector<std::shared_ptr<T>>> result; + auto treeItem = data.find(keyName); + if (treeItem == data.not_found()) { + return result; + } + for (const std::pair<const std::string, boost::property_tree::ptree>& innerTreeItem : treeItem->second) { + std::vector<std::shared_ptr<T>> innerResult; + for (const std::pair<const std::string, boost::property_tree::ptree>& innerInnerTreeItem : innerTreeItem.second) { + innerResult.push_back((this->*parseFunc)(innerInnerTreeItem.second)); + } + result.push_back(innerResult); + } + return result; + } + + template<typename T> + std::string parseArray(std::string (Parser::*const parseFunc)(const std::shared_ptr<T>&) const, const std::vector<std::shared_ptr<T>>& objects) const { + std::string result; + result += '['; + for (const std::shared_ptr<T>& item : objects) { + result += (this->*parseFunc)(item); + result += ','; + } + result.erase(result.length() - 1); + result += ']'; + return result; + } + + template<typename T> + std::string parse2DArray(std::string (Parser::*const parseFunc)(const std::shared_ptr<T>&) const, const std::vector<std::vector<std::shared_ptr<T>>>& objects) const { + std::string result; + result += '['; + for (const std::vector<std::shared_ptr<T>>& item : objects) { + result += parseArray(parseFunc, item); + result += ','; + } + result.erase(result.length() - 1); + result += ']'; + return result; + } + +private: + template<typename T> + void appendToJson(std::string& json, const std::string& varName, const T& value) const { + if (value == 0) { + return; + } + json += '"'; + json += varName; + json += "\":"; + json += value; + json += ','; + } + + void appendToJson(std::string& json, const std::string& varName, const std::string& value) const; +}; + +} + +#endif //TGBOT_CPP_PARSER_H |