refactor(eventsub): generate entire files (#5897)

This commit is contained in:
nerix
2025-02-05 16:53:25 +01:00
committed by GitHub
parent 5e3412c3bb
commit 449aefc6bc
54 changed files with 972 additions and 922 deletions
+20 -18
View File
@@ -1,3 +1,21 @@
generate_json_impls(
OUTPUT_SOURCES eventsub_generated_sources
BASE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/.."
FORCE ${FORCE_JSON_GENERATION}
HEADERS
include/twitch-eventsub-ws/messages/metadata.hpp
include/twitch-eventsub-ws/payloads/channel-ban-v1.hpp
include/twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp
include/twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp
include/twitch-eventsub-ws/payloads/channel-moderate-v2.hpp
include/twitch-eventsub-ws/payloads/channel-update-v1.hpp
include/twitch-eventsub-ws/payloads/session-welcome.hpp
include/twitch-eventsub-ws/payloads/stream-offline-v1.hpp
include/twitch-eventsub-ws/payloads/stream-online-v1.hpp
include/twitch-eventsub-ws/payloads/subscription.hpp
)
set(SOURCE_FILES
session.cpp
@@ -6,20 +24,11 @@ set(SOURCE_FILES
json.cpp
string.cpp
payloads/subscription.cpp
payloads/session-welcome.cpp
# Subscription types
# Subscription types (only additional functions)
payloads/channel-ban-v1.cpp
payloads/stream-online-v1.cpp
payloads/stream-offline-v1.cpp
payloads/channel-update-v1.cpp
payloads/channel-chat-notification-v1.cpp
payloads/channel-chat-message-v1.cpp
payloads/channel-moderate-v2.cpp
# Add your new subscription type source file above this line
messages/metadata.cpp
${eventsub_generated_sources}
)
add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})
@@ -43,13 +52,6 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$<BOOL:${MSVC}>:BOOST_CONTAINER_NO_LIB>
)
# Hack to get the include directories from Python
get_target_property(_inc_dirs ${PROJECT_NAME} INCLUDE_DIRECTORIES)
list(APPEND _inc_dirs ${Boost_INCLUDE_DIRS})
list(APPEND _inc_dirs ${OPENSSL_INCLUDE_DIR})
list(JOIN _inc_dirs ";" _inc_dir)
add_custom_target(_ast_includes echo "@@INCLUDE_DIRS=${_inc_dir}")
if (MSVC)
# Add bigobj
target_compile_options(${PROJECT_NAME} PRIVATE /EHsc /bigobj)
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/messages/metadata.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/messages/metadata.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::messages {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Metadata, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Metadata>, const boost::json::value &jvRoot)
{
@@ -104,6 +105,5 @@ boost::json::result_for<Metadata, boost::json::value>::type tag_invoke(
.subscriptionVersion = std::move(subscriptionVersion),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::messages
@@ -0,0 +1,306 @@
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/channel-ban-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::channel_ban::v1 {
boost::json::result_for<Event, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Event>, const boost::json::value &jvRoot)
{
if (!jvRoot.is_object())
{
static const error::ApplicationErrorCategory errorMustBeObject{
"Event must be an object"};
return boost::system::error_code{129, errorMustBeObject};
}
const auto &root = jvRoot.get_object();
const auto *jvbroadcasterUserID = root.if_contains("broadcaster_user_id");
if (jvbroadcasterUserID == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserID{
"Missing required key broadcaster_user_id"};
return boost::system::error_code{129,
error_missing_field_broadcasterUserID};
}
auto broadcasterUserID =
boost::json::try_value_to<std::string>(*jvbroadcasterUserID);
if (broadcasterUserID.has_error())
{
return broadcasterUserID.error();
}
const auto *jvbroadcasterUserLogin =
root.if_contains("broadcaster_user_login");
if (jvbroadcasterUserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserLogin{
"Missing required key broadcaster_user_login"};
return boost::system::error_code{
129, error_missing_field_broadcasterUserLogin};
}
auto broadcasterUserLogin =
boost::json::try_value_to<std::string>(*jvbroadcasterUserLogin);
if (broadcasterUserLogin.has_error())
{
return broadcasterUserLogin.error();
}
const auto *jvbroadcasterUserName =
root.if_contains("broadcaster_user_name");
if (jvbroadcasterUserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserName{
"Missing required key broadcaster_user_name"};
return boost::system::error_code{
129, error_missing_field_broadcasterUserName};
}
auto broadcasterUserName =
boost::json::try_value_to<std::string>(*jvbroadcasterUserName);
if (broadcasterUserName.has_error())
{
return broadcasterUserName.error();
}
const auto *jvmoderatorUserID = root.if_contains("moderator_user_id");
if (jvmoderatorUserID == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserID{
"Missing required key moderator_user_id"};
return boost::system::error_code{129,
error_missing_field_moderatorUserID};
}
auto moderatorUserID =
boost::json::try_value_to<std::string>(*jvmoderatorUserID);
if (moderatorUserID.has_error())
{
return moderatorUserID.error();
}
const auto *jvmoderatorUserLogin = root.if_contains("moderator_user_login");
if (jvmoderatorUserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserLogin{
"Missing required key moderator_user_login"};
return boost::system::error_code{
129, error_missing_field_moderatorUserLogin};
}
auto moderatorUserLogin =
boost::json::try_value_to<std::string>(*jvmoderatorUserLogin);
if (moderatorUserLogin.has_error())
{
return moderatorUserLogin.error();
}
const auto *jvmoderatorUserName = root.if_contains("moderator_user_name");
if (jvmoderatorUserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserName{
"Missing required key moderator_user_name"};
return boost::system::error_code{129,
error_missing_field_moderatorUserName};
}
auto moderatorUserName =
boost::json::try_value_to<std::string>(*jvmoderatorUserName);
if (moderatorUserName.has_error())
{
return moderatorUserName.error();
}
const auto *jvuserID = root.if_contains("user_id");
if (jvuserID == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_userID{
"Missing required key user_id"};
return boost::system::error_code{129, error_missing_field_userID};
}
auto userID = boost::json::try_value_to<std::string>(*jvuserID);
if (userID.has_error())
{
return userID.error();
}
const auto *jvuserLogin = root.if_contains("user_login");
if (jvuserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_userLogin{"Missing required key user_login"};
return boost::system::error_code{129, error_missing_field_userLogin};
}
auto userLogin = boost::json::try_value_to<std::string>(*jvuserLogin);
if (userLogin.has_error())
{
return userLogin.error();
}
const auto *jvuserName = root.if_contains("user_name");
if (jvuserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_userName{"Missing required key user_name"};
return boost::system::error_code{129, error_missing_field_userName};
}
auto userName = boost::json::try_value_to<std::string>(*jvuserName);
if (userName.has_error())
{
return userName.error();
}
const auto *jvreason = root.if_contains("reason");
if (jvreason == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_reason{
"Missing required key reason"};
return boost::system::error_code{129, error_missing_field_reason};
}
auto reason = boost::json::try_value_to<std::string>(*jvreason);
if (reason.has_error())
{
return reason.error();
}
const auto *jvisPermanent = root.if_contains("is_permanent");
if (jvisPermanent == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_isPermanent{
"Missing required key is_permanent"};
return boost::system::error_code{129, error_missing_field_isPermanent};
}
auto isPermanent = boost::json::try_value_to<bool>(*jvisPermanent);
if (isPermanent.has_error())
{
return isPermanent.error();
}
const auto *jvbannedAt = root.if_contains("banned_at");
if (jvbannedAt == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_bannedAt{"Missing required key banned_at"};
return boost::system::error_code{129, error_missing_field_bannedAt};
}
auto bannedAt =
boost::json::try_value_to<std::chrono::system_clock::time_point>(
*jvbannedAt, AsISO8601());
if (bannedAt.has_error())
{
return bannedAt.error();
}
std::optional<std::chrono::system_clock::time_point> endsAt = std::nullopt;
const auto *jvendsAt = root.if_contains("ends_at");
if (jvendsAt != nullptr && !jvendsAt->is_null())
{
auto tendsAt =
boost::json::try_value_to<std::chrono::system_clock::time_point>(
*jvendsAt, AsISO8601());
if (tendsAt.has_error())
{
return tendsAt.error();
}
endsAt = std::move(tendsAt.value());
}
return Event{
.broadcasterUserID = std::move(broadcasterUserID.value()),
.broadcasterUserLogin = std::move(broadcasterUserLogin.value()),
.broadcasterUserName = std::move(broadcasterUserName.value()),
.moderatorUserID = std::move(moderatorUserID.value()),
.moderatorUserLogin = std::move(moderatorUserLogin.value()),
.moderatorUserName = std::move(moderatorUserName.value()),
.userID = std::move(userID.value()),
.userLogin = std::move(userLogin.value()),
.userName = std::move(userName.value()),
.reason = std::move(reason.value()),
.isPermanent = std::move(isPermanent.value()),
.bannedAt = std::move(bannedAt.value()),
.endsAt = std::move(endsAt),
};
}
boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Payload>, const boost::json::value &jvRoot)
{
if (!jvRoot.is_object())
{
static const error::ApplicationErrorCategory errorMustBeObject{
"Payload must be an object"};
return boost::system::error_code{129, errorMustBeObject};
}
const auto &root = jvRoot.get_object();
const auto *jvsubscription = root.if_contains("subscription");
if (jvsubscription == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_subscription{
"Missing required key subscription"};
return boost::system::error_code{129, error_missing_field_subscription};
}
auto subscription =
boost::json::try_value_to<subscription::Subscription>(*jvsubscription);
if (subscription.has_error())
{
return subscription.error();
}
const auto *jvevent = root.if_contains("event");
if (jvevent == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_event{
"Missing required key event"};
return boost::system::error_code{129, error_missing_field_event};
}
auto event = boost::json::try_value_to<Event>(*jvevent);
if (event.has_error())
{
return event.error();
}
return Payload{
.subscription = std::move(subscription.value()),
.event = std::move(event.value()),
};
}
} // namespace chatterino::eventsub::lib::payload::channel_ban::v1
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::channel_chat_message::v1 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Badge, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Badge>, const boost::json::value &jvRoot)
{
@@ -929,6 +930,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::channel_chat_message::v1
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::channel_chat_notification::v1 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Badge, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Badge>, const boost::json::value &jvRoot)
{
@@ -1840,6 +1841,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::channel_chat_notification::v1
@@ -1,14 +1,13 @@
#include "twitch-eventsub-ws/payloads/channel-moderate-v2.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/channel-moderate-v2.hpp"
#include <boost/json.hpp>
#include <unordered_map>
namespace chatterino::eventsub::lib::payload::channel_moderate::v2 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Action, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Action>, const boost::json::value &jvRoot)
{
@@ -1835,6 +1834,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::channel_moderate::v2
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/channel-update-v1.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/channel-update-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::channel_update::v1 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Event, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Event>, const boost::json::value &jvRoot)
{
@@ -210,6 +211,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::channel_update::v1
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/session-welcome.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/session-welcome.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::session_welcome {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Payload>, const boost::json::value &jvRoot)
{
@@ -52,6 +53,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.id = std::move(id.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::session_welcome
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/stream-offline-v1.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/stream-offline-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::stream_offline::v1 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Event, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Event>, const boost::json::value &jvRoot)
{
@@ -129,6 +130,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::stream_offline::v1
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/stream-online-v1.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/stream-online-v1.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::stream_online::v1 {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Event, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Event>, const boost::json::value &jvRoot)
{
@@ -177,6 +178,5 @@ boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::stream_online::v1
@@ -1,12 +1,13 @@
#include "twitch-eventsub-ws/payloads/subscription.hpp"
// WARNING: This file is automatically generated. Any changes will be lost.
#include "twitch-eventsub-ws/chrono.hpp" // IWYU pragma: keep
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/payloads/subscription.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::subscription {
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Transport, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Transport>, const boost::json::value &jvRoot)
{
@@ -181,6 +182,5 @@ boost::json::result_for<Subscription, boost::json::value>::type tag_invoke(
.cost = std::move(cost.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::subscription
@@ -1,10 +1,5 @@
#include "twitch-eventsub-ws/payloads/channel-ban-v1.hpp"
#include "twitch-eventsub-ws/chrono.hpp"
#include "twitch-eventsub-ws/errors.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::channel_ban::v1 {
std::chrono::system_clock::duration Event::timeoutDuration() const
@@ -17,301 +12,4 @@ std::chrono::system_clock::duration Event::timeoutDuration() const
return *this->endsAt - this->bannedAt;
}
// DESERIALIZATION IMPLEMENTATION START
boost::json::result_for<Event, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Event>, const boost::json::value &jvRoot)
{
if (!jvRoot.is_object())
{
static const error::ApplicationErrorCategory errorMustBeObject{
"Event must be an object"};
return boost::system::error_code{129, errorMustBeObject};
}
const auto &root = jvRoot.get_object();
const auto *jvbroadcasterUserID = root.if_contains("broadcaster_user_id");
if (jvbroadcasterUserID == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserID{
"Missing required key broadcaster_user_id"};
return boost::system::error_code{129,
error_missing_field_broadcasterUserID};
}
auto broadcasterUserID =
boost::json::try_value_to<std::string>(*jvbroadcasterUserID);
if (broadcasterUserID.has_error())
{
return broadcasterUserID.error();
}
const auto *jvbroadcasterUserLogin =
root.if_contains("broadcaster_user_login");
if (jvbroadcasterUserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserLogin{
"Missing required key broadcaster_user_login"};
return boost::system::error_code{
129, error_missing_field_broadcasterUserLogin};
}
auto broadcasterUserLogin =
boost::json::try_value_to<std::string>(*jvbroadcasterUserLogin);
if (broadcasterUserLogin.has_error())
{
return broadcasterUserLogin.error();
}
const auto *jvbroadcasterUserName =
root.if_contains("broadcaster_user_name");
if (jvbroadcasterUserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_broadcasterUserName{
"Missing required key broadcaster_user_name"};
return boost::system::error_code{
129, error_missing_field_broadcasterUserName};
}
auto broadcasterUserName =
boost::json::try_value_to<std::string>(*jvbroadcasterUserName);
if (broadcasterUserName.has_error())
{
return broadcasterUserName.error();
}
const auto *jvmoderatorUserID = root.if_contains("moderator_user_id");
if (jvmoderatorUserID == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserID{
"Missing required key moderator_user_id"};
return boost::system::error_code{129,
error_missing_field_moderatorUserID};
}
auto moderatorUserID =
boost::json::try_value_to<std::string>(*jvmoderatorUserID);
if (moderatorUserID.has_error())
{
return moderatorUserID.error();
}
const auto *jvmoderatorUserLogin = root.if_contains("moderator_user_login");
if (jvmoderatorUserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserLogin{
"Missing required key moderator_user_login"};
return boost::system::error_code{
129, error_missing_field_moderatorUserLogin};
}
auto moderatorUserLogin =
boost::json::try_value_to<std::string>(*jvmoderatorUserLogin);
if (moderatorUserLogin.has_error())
{
return moderatorUserLogin.error();
}
const auto *jvmoderatorUserName = root.if_contains("moderator_user_name");
if (jvmoderatorUserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_moderatorUserName{
"Missing required key moderator_user_name"};
return boost::system::error_code{129,
error_missing_field_moderatorUserName};
}
auto moderatorUserName =
boost::json::try_value_to<std::string>(*jvmoderatorUserName);
if (moderatorUserName.has_error())
{
return moderatorUserName.error();
}
const auto *jvuserID = root.if_contains("user_id");
if (jvuserID == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_userID{
"Missing required key user_id"};
return boost::system::error_code{129, error_missing_field_userID};
}
auto userID = boost::json::try_value_to<std::string>(*jvuserID);
if (userID.has_error())
{
return userID.error();
}
const auto *jvuserLogin = root.if_contains("user_login");
if (jvuserLogin == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_userLogin{"Missing required key user_login"};
return boost::system::error_code{129, error_missing_field_userLogin};
}
auto userLogin = boost::json::try_value_to<std::string>(*jvuserLogin);
if (userLogin.has_error())
{
return userLogin.error();
}
const auto *jvuserName = root.if_contains("user_name");
if (jvuserName == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_userName{"Missing required key user_name"};
return boost::system::error_code{129, error_missing_field_userName};
}
auto userName = boost::json::try_value_to<std::string>(*jvuserName);
if (userName.has_error())
{
return userName.error();
}
const auto *jvreason = root.if_contains("reason");
if (jvreason == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_reason{
"Missing required key reason"};
return boost::system::error_code{129, error_missing_field_reason};
}
auto reason = boost::json::try_value_to<std::string>(*jvreason);
if (reason.has_error())
{
return reason.error();
}
const auto *jvisPermanent = root.if_contains("is_permanent");
if (jvisPermanent == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_isPermanent{
"Missing required key is_permanent"};
return boost::system::error_code{129, error_missing_field_isPermanent};
}
auto isPermanent = boost::json::try_value_to<bool>(*jvisPermanent);
if (isPermanent.has_error())
{
return isPermanent.error();
}
const auto *jvbannedAt = root.if_contains("banned_at");
if (jvbannedAt == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_bannedAt{"Missing required key banned_at"};
return boost::system::error_code{129, error_missing_field_bannedAt};
}
auto bannedAt =
boost::json::try_value_to<std::chrono::system_clock::time_point>(
*jvbannedAt, AsISO8601());
if (bannedAt.has_error())
{
return bannedAt.error();
}
std::optional<std::chrono::system_clock::time_point> endsAt = std::nullopt;
const auto *jvendsAt = root.if_contains("ends_at");
if (jvendsAt != nullptr && !jvendsAt->is_null())
{
auto tendsAt =
boost::json::try_value_to<std::chrono::system_clock::time_point>(
*jvendsAt, AsISO8601());
if (tendsAt.has_error())
{
return tendsAt.error();
}
endsAt = std::move(tendsAt.value());
}
return Event{
.broadcasterUserID = std::move(broadcasterUserID.value()),
.broadcasterUserLogin = std::move(broadcasterUserLogin.value()),
.broadcasterUserName = std::move(broadcasterUserName.value()),
.moderatorUserID = std::move(moderatorUserID.value()),
.moderatorUserLogin = std::move(moderatorUserLogin.value()),
.moderatorUserName = std::move(moderatorUserName.value()),
.userID = std::move(userID.value()),
.userLogin = std::move(userLogin.value()),
.userName = std::move(userName.value()),
.reason = std::move(reason.value()),
.isPermanent = std::move(isPermanent.value()),
.bannedAt = std::move(bannedAt.value()),
.endsAt = std::move(endsAt),
};
}
boost::json::result_for<Payload, boost::json::value>::type tag_invoke(
boost::json::try_value_to_tag<Payload>, const boost::json::value &jvRoot)
{
if (!jvRoot.is_object())
{
static const error::ApplicationErrorCategory errorMustBeObject{
"Payload must be an object"};
return boost::system::error_code{129, errorMustBeObject};
}
const auto &root = jvRoot.get_object();
const auto *jvsubscription = root.if_contains("subscription");
if (jvsubscription == nullptr)
{
static const error::ApplicationErrorCategory
error_missing_field_subscription{
"Missing required key subscription"};
return boost::system::error_code{129, error_missing_field_subscription};
}
auto subscription =
boost::json::try_value_to<subscription::Subscription>(*jvsubscription);
if (subscription.has_error())
{
return subscription.error();
}
const auto *jvevent = root.if_contains("event");
if (jvevent == nullptr)
{
static const error::ApplicationErrorCategory error_missing_field_event{
"Missing required key event"};
return boost::system::error_code{129, error_missing_field_event};
}
auto event = boost::json::try_value_to<Event>(*jvevent);
if (event.has_error())
{
return event.error();
}
return Payload{
.subscription = std::move(subscription.value()),
.event = std::move(event.value()),
};
}
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::channel_ban::v1
@@ -1,81 +0,0 @@
#!/usr/bin/env bash
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
subscription_name="$1"
subscription_version="$2"
usage() {
>&2 echo "Usage: $0 <name> <version> (e.g. $0 channel.ban v1)"
exit 1
}
if [ -z "$subscription_name" ]; then
>&2 echo "Missing subscription name"
usage
fi
if [ -z "$subscription_version" ]; then
>&2 echo "Missing subscription version"
usage
fi
# Clean up subscription name
dashed_subscription_name="$(echo "$subscription_name" | sed 's/\./-/g')"
underscored_subscription_name="$(echo "$subscription_name" | sed 's/\./_/g')"
echo "Subscription name: $subscription_name ($dashed_subscription_name)"
echo "Subscription version: $subscription_version"
header_file_name="${dashed_subscription_name}-${subscription_version}.hpp"
source_file_name="${dashed_subscription_name}-${subscription_version}.cpp"
# Write the header file
cat > "$SCRIPT_DIR/../../include/twitch-eventsub-ws/payloads/$header_file_name" << EOF
#pragma once
#include "twitch-eventsub-ws/payloads/subscription.hpp"
#include <boost/json.hpp>
#include <string>
namespace chatterino::eventsub::lib::payload::$underscored_subscription_name::$subscription_version {
/// json_transform=snake_case
struct Event {
// TODO: Fill in your subscription-specific event here
};
struct Payload {
const subscription::Subscription subscription;
const Event event;
};
// DESERIALIZATION DEFINITION START
// DESERIALIZATION DEFINITION END
} // namespace chatterino::eventsub::lib::payload::$underscored_subscription_name::$subscription_version
EOF
# Write the source file
cat > "$SCRIPT_DIR/$source_file_name" << EOF
#include "twitch-eventsub-ws/payloads/$header_file_name"
#include "twitch-eventsub-ws/errors.hpp"
#include <boost/json.hpp>
namespace chatterino::eventsub::lib::payload::$underscored_subscription_name::$subscription_version {
// DESERIALIZATION IMPLEMENTATION START
// DESERIALIZATION IMPLEMENTATION END
} // namespace chatterino::eventsub::lib::payload::$underscored_subscription_name::$subscription_version
EOF
echo "Steps that are left for you:"
echo "1. Add a virtual method to the Listener class in include/twitch-eventsub-ws/listener.hpp"
echo "2. Add a handler for this subscription in src/session.cpp's NOTIFICATION_HANDLERS"
echo "3. Add payloads/${source_file_name} to src/CMakeLists.txt"
+1
View File
@@ -1,5 +1,6 @@
#include "twitch-eventsub-ws/session.hpp"
#include "twitch-eventsub-ws/errors.hpp"
#include "twitch-eventsub-ws/listener.hpp"
#include "twitch-eventsub-ws/messages/metadata.hpp"
#include "twitch-eventsub-ws/payloads/channel-ban-v1.hpp"