Skip to content

Commit

Permalink
Add type templates Optional<T> and Required<T>, simplify parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
uralm1 committed Nov 17, 2024
1 parent 66b89bf commit d5a2690
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 107 deletions.
21 changes: 21 additions & 0 deletions include/tgbot/Optional.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef TGBOT_OPTIONAL_H
#define TGBOT_OPTIONAL_H

#include <boost/optional.hpp>

namespace TgBot {

template<typename T>
using Optional = boost::optional<T>;

// use for: OptionalPtr<std::shared/unique_ptr<TYPE>>
// for pointers, we assume optional value == nullptr (or not owned, etc)
template<typename T>
using OptionalPtr = T;

template<typename T>
using Required = T;

}

#endif //TGBOT_OPTIONAL_H
15 changes: 14 additions & 1 deletion include/tgbot/TgTypeParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define TGBOT_TGTYPEPARSER_H

#include "tgbot/export.h"
#include "tgbot/Optional.h"
#include "tgbot/types/Update.h"
#include "tgbot/types/WebhookInfo.h"
#include "tgbot/types/User.h"
Expand Down Expand Up @@ -898,7 +899,19 @@ class TGBOT_API TgTypeParser {

private:
inline void removeLastComma(std::string& input) const {
input.erase(input.length() - 1);
if (!input.empty() && input.back() == ',') input.erase(input.length() - 1);
}

template<typename T>
inline void appendToJson(std::string& json, const std::string& varName, const Optional<T>& value) const {
if (!value) {
return;
}
json += '"';
json += varName;
json += R"(":)";
json += *(value);
json += ',';
}

template<typename T>
Expand Down
5 changes: 3 additions & 2 deletions include/tgbot/types/ForceReply.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define TGBOT_FORCEREPLY_H

#include "tgbot/types/GenericReply.h"
#include "tgbot/Optional.h"

#include <memory>
#include <string>
Expand Down Expand Up @@ -35,14 +36,14 @@ class ForceReply : public GenericReply {
/**
* @brief Optional. The placeholder to be shown in the input field when the reply is active; 1-64 characters
*/
std::string inputFieldPlaceholder;
Optional<std::string> inputFieldPlaceholder;

/**
* @brief Optional. Use this parameter if you want to force reply from specific users only.
*
* Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply to a message in the same chat and forum topic, sender of the original message.
*/
bool selective;
Optional<bool> selective;
};
}

Expand Down
21 changes: 11 additions & 10 deletions include/tgbot/types/InlineKeyboardButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "tgbot/types/LoginUrl.h"
#include "tgbot/types/SwitchInlineQueryChosenChat.h"
#include "tgbot/types/CallbackGame.h"
#include "tgbot/Optional.h"

#include <memory>
#include <string>
Expand All @@ -26,68 +27,68 @@ class InlineKeyboardButton {
/**
* @brief Label text on the button
*/
std::string text;
Required<std::string> text;

/**
* @brief Optional. HTTP or tg:// URL to be opened when the button is pressed.
*
* Links tg://user?id=<user_id> can be used to mention a user by their identifier without using a username, if this is allowed by their privacy settings.
*/
std::string url;
Optional<std::string> url;

/**
* @brief Optional. Data to be sent in a [callback query](https://core.telegram.org/bots/api#callbackquery) to the bot when button is pressed, 1-64 bytes
*/
std::string callbackData;
Optional<std::string> callbackData;

/**
* @brief Optional. Description of the [Web App](https://core.telegram.org/bots/webapps) that will be launched when the user presses the button.
*
* The Web App will be able to send an arbitrary message on behalf of the user using the method Api::answerWebAppQuery.
* Available only in private chats between a user and the bot.
*/
WebAppInfo::Ptr webApp;
OptionalPtr<WebAppInfo::Ptr> webApp;

/**
* @brief Optional. An HTTPS URL used to automatically authorize the user.
*
* Can be used as a replacement for the [Telegram Login Widget](https://core.telegram.org/widgets/login).
*/
LoginUrl::Ptr loginUrl;
OptionalPtr<LoginUrl::Ptr> loginUrl;

/**
* @brief Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot's username and the specified inline query in the input field.
*
* May be empty, in which case just the bot's username will be inserted.
*/
std::string switchInlineQuery;
Optional<std::string> switchInlineQuery;

/**
* @brief Optional. If set, pressing the button will insert the bot's username and the specified inline query in the current chat's input field.
*
* May be empty, in which case only the bot's username will be inserted.
* This offers a quick way for the user to open your bot in inline mode in the same chat - good for selecting something from multiple options.
*/
std::string switchInlineQueryCurrentChat;
Optional<std::string> switchInlineQueryCurrentChat;

/**
* @brief Optional. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field
*/
SwitchInlineQueryChosenChat::Ptr switchInlineQueryChosenChat;
OptionalPtr<SwitchInlineQueryChosenChat::Ptr> switchInlineQueryChosenChat;

/**
* @brief Optional. Description of the game that will be launched when the user presses the button.
*
* NOTE: This type of button must always be the first button in the first row.
*/
CallbackGame::Ptr callbackGame;
OptionalPtr<CallbackGame::Ptr> callbackGame;

/**
* @brief Optional. Specify True, to send a [Pay button](https://core.telegram.org/bots/api#payments).
*
* NOTE: This type of button must always be the first button in the first row and can only be used in invoice messages.
*/
bool pay;
Optional<bool> pay;
};
}

Expand Down
13 changes: 7 additions & 6 deletions include/tgbot/types/LinkPreviewOptions.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#ifndef TGBOT_LINKPREVIEWOPTIONS_H
#define TGBOT_LINKPREVIEWOPTIONS_H

#include "tgbot/Optional.h"

#include <memory>
#include <string>
#include <boost/optional.hpp>

namespace TgBot {

Expand All @@ -20,29 +21,29 @@ class LinkPreviewOptions {
/**
* @brief Optional. True, if the link preview is disabled
*/
boost::optional<bool> isDisabled;
Optional<bool> isDisabled;

/**
* @brief Optional. URL to use for the link preview.
*
* If empty, then the first URL found in the message text will be used
*/
boost::optional<std::string> url;
Optional<std::string> url;

/**
* @brief Optional. True, if the media in the link preview is supposed to be shrunk; ignored if the URL isn't explicitly specified or media size change isn't supported for the preview
*/
boost::optional<bool> preferSmallMedia;
Optional<bool> preferSmallMedia;

/**
* @brief Optional. True, if the media in the link preview is supposed to be enlarged; ignored if the URL isn't explicitly specified or media size change isn't supported for the preview
*/
boost::optional<bool> preferLargeMedia;
Optional<bool> preferLargeMedia;

/**
* @brief Optional. True, if the link preview must be shown above the message text; otherwise, the link preview will be shown below the message text
*/
boost::optional<bool> showAboveText;
Optional<bool> showAboveText;
};
}

Expand Down
10 changes: 6 additions & 4 deletions include/tgbot/types/LoginUrl.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef TGBOT_LOGINURL_H
#define TGBOT_LOGINURL_H

#include "tgbot/Optional.h"

#include <memory>
#include <string>

Expand All @@ -27,12 +29,12 @@ class LoginUrl {
*
* NOTE: You must always check the hash of the received data to verify the authentication and the integrity of the data as described in https://core.telegram.org/widgets/login#checking-authorization
*/
std::string url;
Required<std::string> url;

/**
* @brief Optional. New text of the button in forwarded messages.
*/
std::string forwardText;
Optional<std::string> forwardText;

/**
* @brief Optional. Username of a bot, which will be used for user authorization.
Expand All @@ -41,12 +43,12 @@ class LoginUrl {
* The url's domain must be the same as the domain linked with the bot.
* See https://core.telegram.org/widgets/login#linking-your-domain-to-the-bot for more details.
*/
std::string botUsername;
Optional<std::string> botUsername;

/**
* @brief Optional. Pass True to request the permission for your bot to send messages to the user.
*/
bool requestWriteAccess;
Optional<bool> requestWriteAccess;
};
}

Expand Down
15 changes: 8 additions & 7 deletions include/tgbot/types/MessageEntity.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef TGBOT_MESSAGEENTITY_H
#define TGBOT_MESSAGEENTITY_H

#include "tgbot/Optional.h"
#include "tgbot/types/User.h"

#include <cstdint>
Expand Down Expand Up @@ -33,40 +34,40 @@ class MessageEntity {
*
* Currently, can be Type::Mention (@username), Type::Hashtag (#hashtag), Type::Cashtag ($USD), Type::BotCommand (/start@jobs_bot), Type::Url (https://telegram.org), Type::Email (do-not-reply@telegram.org), Type::PhoneNumber (+1-212-555-0123), Type::Bold (bold text), Type::Italic (italic text), Type::Underline (underlined text), Type::Strikethrough (strikethrough text), Type::Spoiler (spoiler message), Type::Blockquote (block quotation), Type::Code (monowidth string), Type::Pre (monowidth block), Type::TextLink (for clickable text URLs), Type::TextMention (for users [without usernames](https://telegram.org/blog/edit#new-mentions)), Type::CustomEmoji (for inline custom emoji stickers)
*/
Type type;
Required<Type> type;

/**
* @brief Offset in [UTF-16 code units](https://core.telegram.org/api/entities#entity-length) to the start of the entity
*
*/
std::int32_t offset;
Required<std::int32_t> offset;

/**
* @brief Length of the entity in [UTF-16 code units](https://core.telegram.org/api/entities#entity-length)
*/
std::int32_t length;
Required<std::int32_t> length;

/**
* @brief Optional. For Type::TextLink only, URL that will be opened after user taps on the text
*/
std::string url;
Optional<std::string> url;

/**
* @brief Optional. For Type::TextMention only, the mentioned user
*/
User::Ptr user;
OptionalPtr<User::Ptr> user;

/**
* @brief Optional. For Type::Pre only, the programming language of the entity text
*/
std::string language;
Optional<std::string> language;

/**
* @brief Optional. For Type::CustomEmoji only, unique identifier of the custom emoji.
*
* Use Api::getCustomEmojiStickers to get full information about the sticker
*/
std::string customEmojiId;
Optional<std::string> customEmojiId;
};
}

Expand Down
13 changes: 7 additions & 6 deletions include/tgbot/types/ReplyKeyboardMarkup.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef TGBOT_REPLYKEYBOARDMARKUP_H
#define TGBOT_REPLYKEYBOARDMARKUP_H

#include "tgbot/Optional.h"
#include "tgbot/types/GenericReply.h"
#include "tgbot/types/KeyboardButton.h"

Expand All @@ -23,34 +24,34 @@ class ReplyKeyboardMarkup : public GenericReply {
/**
* @brief Array of button rows, each represented by an Array of KeyboardButton objects
*/
std::vector<std::vector<KeyboardButton::Ptr>> keyboard;
Required<std::vector<std::vector<KeyboardButton::Ptr>>> keyboard;

/**
* @brief Optional. Requests clients to always show the keyboard when the regular keyboard is hidden.
*
* Defaults to false, in which case the custom keyboard can be hidden and opened with a keyboard icon.
*/
bool isPersistent;
Optional<bool> isPersistent;

/**
* @brief Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons).
*
* Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard.
*/
bool resizeKeyboard;
Optional<bool> resizeKeyboard;

/**
* @brief Optional. Requests clients to hide the keyboard as soon as it's been used.
*
* The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat - the user can press a special button in the input field to see the custom keyboard again.
* Defaults to false.
*/
bool oneTimeKeyboard;
Optional<bool> oneTimeKeyboard;

/**
* @brief Optional. The placeholder to be shown in the input field when the keyboard is active; 1-64 characters
*/
std::string inputFieldPlaceholder;
Optional<std::string> inputFieldPlaceholder;

/**
* @brief Optional. Use this parameter if you want to show the keyboard to specific users only.
Expand All @@ -59,7 +60,7 @@ class ReplyKeyboardMarkup : public GenericReply {
* Example: A user requests to change the bot's language, bot replies to the request with a keyboard to select the new language.
* Other users in the group don't see the keyboard.
*/
bool selective;
Optional<bool> selective;
};
}

Expand Down
5 changes: 3 additions & 2 deletions include/tgbot/types/ReplyKeyboardRemove.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef TGBOT_REPLYKEYBOARDREMOVE_H
#define TGBOT_REPLYKEYBOARDREMOVE_H

#include "tgbot/Optional.h"
#include "tgbot/types/GenericReply.h"

#include <memory>
Expand All @@ -23,15 +24,15 @@ class ReplyKeyboardRemove : public GenericReply {
/**
* @brief Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to hide the keyboard from sight but keep it accessible, use oneTimeKeyboard in ReplyKeyboardMarkup)
*/
bool removeKeyboard;
Required<bool> removeKeyboard;

/**
* @brief Optional. Use this parameter if you want to remove the keyboard for specific users only.
*
* Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply to a message in the same chat and forum topic, sender of the original message.
* Example: A user votes in a poll, bot returns confirmation message in reply to the vote and removes the keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
*/
bool selective;
Optional<bool> selective;
};
}

Expand Down
Loading

0 comments on commit d5a2690

Please sign in to comment.