Skip to content

Commit d5a2690

Browse files
committed
Add type templates Optional<T> and Required<T>, simplify parsers
1 parent 66b89bf commit d5a2690

13 files changed

+153
-107
lines changed

Diff for: include/tgbot/Optional.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef TGBOT_OPTIONAL_H
2+
#define TGBOT_OPTIONAL_H
3+
4+
#include <boost/optional.hpp>
5+
6+
namespace TgBot {
7+
8+
template<typename T>
9+
using Optional = boost::optional<T>;
10+
11+
// use for: OptionalPtr<std::shared/unique_ptr<TYPE>>
12+
// for pointers, we assume optional value == nullptr (or not owned, etc)
13+
template<typename T>
14+
using OptionalPtr = T;
15+
16+
template<typename T>
17+
using Required = T;
18+
19+
}
20+
21+
#endif //TGBOT_OPTIONAL_H

Diff for: include/tgbot/TgTypeParser.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define TGBOT_TGTYPEPARSER_H
33

44
#include "tgbot/export.h"
5+
#include "tgbot/Optional.h"
56
#include "tgbot/types/Update.h"
67
#include "tgbot/types/WebhookInfo.h"
78
#include "tgbot/types/User.h"
@@ -898,7 +899,19 @@ class TGBOT_API TgTypeParser {
898899

899900
private:
900901
inline void removeLastComma(std::string& input) const {
901-
input.erase(input.length() - 1);
902+
if (!input.empty() && input.back() == ',') input.erase(input.length() - 1);
903+
}
904+
905+
template<typename T>
906+
inline void appendToJson(std::string& json, const std::string& varName, const Optional<T>& value) const {
907+
if (!value) {
908+
return;
909+
}
910+
json += '"';
911+
json += varName;
912+
json += R"(":)";
913+
json += *(value);
914+
json += ',';
902915
}
903916

904917
template<typename T>

Diff for: include/tgbot/types/ForceReply.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define TGBOT_FORCEREPLY_H
33

44
#include "tgbot/types/GenericReply.h"
5+
#include "tgbot/Optional.h"
56

67
#include <memory>
78
#include <string>
@@ -35,14 +36,14 @@ class ForceReply : public GenericReply {
3536
/**
3637
* @brief Optional. The placeholder to be shown in the input field when the reply is active; 1-64 characters
3738
*/
38-
std::string inputFieldPlaceholder;
39+
Optional<std::string> inputFieldPlaceholder;
3940

4041
/**
4142
* @brief Optional. Use this parameter if you want to force reply from specific users only.
4243
*
4344
* 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.
4445
*/
45-
bool selective;
46+
Optional<bool> selective;
4647
};
4748
}
4849

Diff for: include/tgbot/types/InlineKeyboardButton.h

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "tgbot/types/LoginUrl.h"
66
#include "tgbot/types/SwitchInlineQueryChosenChat.h"
77
#include "tgbot/types/CallbackGame.h"
8+
#include "tgbot/Optional.h"
89

910
#include <memory>
1011
#include <string>
@@ -26,68 +27,68 @@ class InlineKeyboardButton {
2627
/**
2728
* @brief Label text on the button
2829
*/
29-
std::string text;
30+
Required<std::string> text;
3031

3132
/**
3233
* @brief Optional. HTTP or tg:// URL to be opened when the button is pressed.
3334
*
3435
* 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.
3536
*/
36-
std::string url;
37+
Optional<std::string> url;
3738

3839
/**
3940
* @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
4041
*/
41-
std::string callbackData;
42+
Optional<std::string> callbackData;
4243

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

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

5859
/**
5960
* @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.
6061
*
6162
* May be empty, in which case just the bot's username will be inserted.
6263
*/
63-
std::string switchInlineQuery;
64+
Optional<std::string> switchInlineQuery;
6465

6566
/**
6667
* @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.
6768
*
6869
* May be empty, in which case only the bot's username will be inserted.
6970
* 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.
7071
*/
71-
std::string switchInlineQueryCurrentChat;
72+
Optional<std::string> switchInlineQueryCurrentChat;
7273

7374
/**
7475
* @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
7576
*/
76-
SwitchInlineQueryChosenChat::Ptr switchInlineQueryChosenChat;
77+
OptionalPtr<SwitchInlineQueryChosenChat::Ptr> switchInlineQueryChosenChat;
7778

7879
/**
7980
* @brief Optional. Description of the game that will be launched when the user presses the button.
8081
*
8182
* NOTE: This type of button must always be the first button in the first row.
8283
*/
83-
CallbackGame::Ptr callbackGame;
84+
OptionalPtr<CallbackGame::Ptr> callbackGame;
8485

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

Diff for: include/tgbot/types/LinkPreviewOptions.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#ifndef TGBOT_LINKPREVIEWOPTIONS_H
22
#define TGBOT_LINKPREVIEWOPTIONS_H
33

4+
#include "tgbot/Optional.h"
5+
46
#include <memory>
57
#include <string>
6-
#include <boost/optional.hpp>
78

89
namespace TgBot {
910

@@ -20,29 +21,29 @@ class LinkPreviewOptions {
2021
/**
2122
* @brief Optional. True, if the link preview is disabled
2223
*/
23-
boost::optional<bool> isDisabled;
24+
Optional<bool> isDisabled;
2425

2526
/**
2627
* @brief Optional. URL to use for the link preview.
2728
*
2829
* If empty, then the first URL found in the message text will be used
2930
*/
30-
boost::optional<std::string> url;
31+
Optional<std::string> url;
3132

3233
/**
3334
* @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
3435
*/
35-
boost::optional<bool> preferSmallMedia;
36+
Optional<bool> preferSmallMedia;
3637

3738
/**
3839
* @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
3940
*/
40-
boost::optional<bool> preferLargeMedia;
41+
Optional<bool> preferLargeMedia;
4142

4243
/**
4344
* @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
4445
*/
45-
boost::optional<bool> showAboveText;
46+
Optional<bool> showAboveText;
4647
};
4748
}
4849

Diff for: include/tgbot/types/LoginUrl.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef TGBOT_LOGINURL_H
22
#define TGBOT_LOGINURL_H
33

4+
#include "tgbot/Optional.h"
5+
46
#include <memory>
57
#include <string>
68

@@ -27,12 +29,12 @@ class LoginUrl {
2729
*
2830
* 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
2931
*/
30-
std::string url;
32+
Required<std::string> url;
3133

3234
/**
3335
* @brief Optional. New text of the button in forwarded messages.
3436
*/
35-
std::string forwardText;
37+
Optional<std::string> forwardText;
3638

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

4648
/**
4749
* @brief Optional. Pass True to request the permission for your bot to send messages to the user.
4850
*/
49-
bool requestWriteAccess;
51+
Optional<bool> requestWriteAccess;
5052
};
5153
}
5254

Diff for: include/tgbot/types/MessageEntity.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef TGBOT_MESSAGEENTITY_H
22
#define TGBOT_MESSAGEENTITY_H
33

4+
#include "tgbot/Optional.h"
45
#include "tgbot/types/User.h"
56

67
#include <cstdint>
@@ -33,40 +34,40 @@ class MessageEntity {
3334
*
3435
* Currently, can be Type::Mention (@username), Type::Hashtag (#hashtag), Type::Cashtag ($USD), Type::BotCommand (/start@jobs_bot), Type::Url (https://telegram.org), Type::Email ([email protected]), 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)
3536
*/
36-
Type type;
37+
Required<Type> type;
3738

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

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

4950
/**
5051
* @brief Optional. For Type::TextLink only, URL that will be opened after user taps on the text
5152
*/
52-
std::string url;
53+
Optional<std::string> url;
5354

5455
/**
5556
* @brief Optional. For Type::TextMention only, the mentioned user
5657
*/
57-
User::Ptr user;
58+
OptionalPtr<User::Ptr> user;
5859

5960
/**
6061
* @brief Optional. For Type::Pre only, the programming language of the entity text
6162
*/
62-
std::string language;
63+
Optional<std::string> language;
6364

6465
/**
6566
* @brief Optional. For Type::CustomEmoji only, unique identifier of the custom emoji.
6667
*
6768
* Use Api::getCustomEmojiStickers to get full information about the sticker
6869
*/
69-
std::string customEmojiId;
70+
Optional<std::string> customEmojiId;
7071
};
7172
}
7273

Diff for: include/tgbot/types/ReplyKeyboardMarkup.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef TGBOT_REPLYKEYBOARDMARKUP_H
22
#define TGBOT_REPLYKEYBOARDMARKUP_H
33

4+
#include "tgbot/Optional.h"
45
#include "tgbot/types/GenericReply.h"
56
#include "tgbot/types/KeyboardButton.h"
67

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

2829
/**
2930
* @brief Optional. Requests clients to always show the keyboard when the regular keyboard is hidden.
3031
*
3132
* Defaults to false, in which case the custom keyboard can be hidden and opened with a keyboard icon.
3233
*/
33-
bool isPersistent;
34+
Optional<bool> isPersistent;
3435

3536
/**
3637
* @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).
3738
*
3839
* Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard.
3940
*/
40-
bool resizeKeyboard;
41+
Optional<bool> resizeKeyboard;
4142

4243
/**
4344
* @brief Optional. Requests clients to hide the keyboard as soon as it's been used.
4445
*
4546
* 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.
4647
* Defaults to false.
4748
*/
48-
bool oneTimeKeyboard;
49+
Optional<bool> oneTimeKeyboard;
4950

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

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

Diff for: include/tgbot/types/ReplyKeyboardRemove.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef TGBOT_REPLYKEYBOARDREMOVE_H
22
#define TGBOT_REPLYKEYBOARDREMOVE_H
33

4+
#include "tgbot/Optional.h"
45
#include "tgbot/types/GenericReply.h"
56

67
#include <memory>
@@ -23,15 +24,15 @@ class ReplyKeyboardRemove : public GenericReply {
2324
/**
2425
* @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)
2526
*/
26-
bool removeKeyboard;
27+
Required<bool> removeKeyboard;
2728

2829
/**
2930
* @brief Optional. Use this parameter if you want to remove the keyboard for specific users only.
3031
*
3132
* 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.
3233
* 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.
3334
*/
34-
bool selective;
35+
Optional<bool> selective;
3536
};
3637
}
3738

0 commit comments

Comments
 (0)