Page MenuHomePhorge

No OneTemporary

Size
221 KB
Referenced Files
None
Subscribers
None
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf00726..b249e38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,68 +1,68 @@
cmake_minimum_required(VERSION 3.8)
if(NOT DEFINED PROJECT_NAME)
if(NOT DEFINED libkazv_INSTALL_HEADERS)
set(libkazv_INSTALL_HEADERS ON)
endif()
endif()
project(libkazv)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pthread")
option(libkazv_BUILD_TESTS "Build tests" ON)
option(libkazv_BUILD_EXAMPLES "Build examples" ON)
option(libkazv_OUTPUT_LEVEL "Output level: Debug>=90, Info>=70, Quiet>=20, no output=1" 0)
# Build shared libraries by default
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif()
find_package(Boost REQUIRED)
include(FetchContent)
set(USE_SYSTEM_CURL ON)
set(BUILD_CPR_TESTS OFF)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/whoshuu/cpr.git GIT_TAG c8d33915dbd88ad6c92b258869b03aba06587ff9) # the commit hash for 1.5.0
FetchContent_MakeAvailable(cpr)
if(libkazv_BUILD_TESTS)
FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2 GIT_TAG v2.13.0)
FetchContent_MakeAvailable(Catch2)
endif()
set(JSON_BuildTests OFF)
FetchContent_Declare(nlohmann_json GIT_REPOSITORY https://github.com/nlohmann/json GIT_TAG v3.9.1)
FetchContent_MakeAvailable(nlohmann_json)
set(immer_BUILD_TESTS OFF)
set(immer_BUILD_EXAMPLES OFF)
set(immer_BUILD_DOCS OFF)
set(immer_BUILD_EXTRAS OFF)
FetchContent_Declare(immer GIT_REPOSITORY https://github.com/arximboldi/immer GIT_TAG 2076affd9d814afc019ba8cd8c2b18a6c79c9589)
FetchContent_MakeAvailable(immer)
set(zug_BUILD_TESTS OFF)
set(zug_BUILD_EXAMPLES OFF)
set(zug_BUILD_DOCS OFF)
FetchContent_Declare(zug GIT_REPOSITORY https://github.com/arximboldi/zug GIT_TAG 0bf540906165143eb8b195284c588be29438a16b)
FetchContent_MakeAvailable(zug)
# Do not let the option()s override variables here
cmake_policy(SET CMP0077 NEW)
set(lager_BUILD_TESTS OFF)
set(lager_BUILD_EXAMPLES OFF)
set(lager_BUILD_DOCS OFF)
set(lager_EMBED_RESOURCES_PATH OFF)
FetchContent_Declare(lager GIT_REPOSITORY https://github.com/arximboldi/lager GIT_TAG a112eed88789bb2986b7924b5b1e71c8a410f81a)
FetchContent_MakeAvailable(lager)
if(libkazv_OUTPUT_LEVEL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLIBKAZV_OUTPUT_LEVEL=${libkazv_OUTPUT_LEVEL}")
endif()
add_subdirectory(src)
diff --git a/gtad/data.hpp.mustache b/gtad/data.hpp.mustache
index c4885d9..4422d6e 100644
--- a/gtad/data.hpp.mustache
+++ b/gtad/data.hpp.mustache
@@ -1,66 +1,68 @@
{{>preamble}}
#pragma once
#include "types.hpp"
{{#imports}}
#include {{_}}{{/imports}}
namespace Kazv {
{{#models}}
{{#model}}
{{>docCommentShort}}
struct {{name}}{{#parents?}} : {{#parents}}{{name}}{{>cjoin}}{{/parents}}{{/parents?}}
{ {{#vars}}
{{>docCommentShort}}
{{>maybeOmittableType}} {{nameCamelCase}};
{{/vars}}{{#propertyMap}}
{{>docCommentShort}}
{{>maybeOmittableType}} {{nameCamelCase}};
{{/propertyMap}}
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<{{qualifiedName}}> {
{{#in?}}
static void to_json(json& jo, const {{qualifiedName}} &pod)
{
{{#parents}}{{!assume no more one parent}}
jo = static_cast<const {{name}} &>(pod);
{{/parents}}
{{#propertyMap}}
addPropertyMapToJson(jo, pod.{{nameCamelCase}});
{{/propertyMap}}
{{#vars}}
{{#required?}}jo["{{baseName}}"s] = pod.{{nameCamelCase}};{{/required?}}
{{^required?}}addToJsonIfNeeded(jo, "{{baseName}}"s, pod.{{nameCamelCase}});{{/required?}}
{{/vars}}
}
{{/in?}}
{{#out?}}
static void from_json(const json &jo, {{qualifiedName}}& result)
{
{{#parents}}
static_cast<{{name}} &{{!of the parent!}}>(result) = jo;
{{/parents}}
{{#vars}}
- result.{{nameCamelCase}} = jo.at("{{baseName}}"s);
+ if (jo.contains("{{baseName}}"s)) {
+ result.{{nameCamelCase}} = jo.at("{{baseName}}"s);
+ }
{{/vars}}
{{#propertyMap}}
result.{{nameCamelCase}} = jo;
{{/propertyMap}}
}
{{/out?}}
};
}
namespace Kazv
{
{{/model}}
{{/models}}
} // namespace Kazv
diff --git a/gtad/operation.hpp.mustache b/gtad/operation.hpp.mustache
index 5f759eb..ba2d205 100644
--- a/gtad/operation.hpp.mustache
+++ b/gtad/operation.hpp.mustache
@@ -1,148 +1,150 @@
{{>preamble}}
#pragma once
#include "basejob.hpp"
{{#imports}}
#include {{_}}{{/imports}}
namespace Kazv {
{{#operations.operation}}
/*!{{>docCommentSummary}}{{#description}}
* {{_}}{{/description}}
*/
class {{camelCaseOperationId}}Job : public BaseJob {
public:
{{#models}}
// Inner data structures
{{#model}}
{{>docCommentShort}}
struct {{name}}{{#parents?}} :
{{#parents}}{{name}}{{>cjoin}}{{/parents}}{{/parents?}}
{
{{#vars}}
{{>docCommentShort}}
{{>maybeOmittableType}} {{nameCamelCase}};
{{/vars}}
{{#propertyMap}}
{{>docCommentShort}}
{{>maybeOmittableType}} {{nameCamelCase}};
{{/propertyMap}}
};
{{/model}}
{{/models}}
// Construction/destruction
{{#allParams?}}
/*!{{>docCommentSummary}}
{{#allParams}}
* \param {{nameCamelCase}}{{#description}}
* {{_}}{{/description}}{{#_join}}
* {{/_join}}
{{/allParams}}
*/
{{/allParams?}}{{^allParams?}}
{{#summary}}
/// {{summary}}
{{/summary}}
{{/allParams?}}
explicit {{camelCaseOperationId}}Job(std::string serverUrl
{{^skipAuth}}, std::string _accessToken{{/skipAuth}}
{{#allParams?}},{{/allParams?}}
{{#allParams}}{{>joinedParamDecl}}{{/allParams}});
{{^hasBody?}}
{{/hasBody?}}
{{#responses}}{{#normalResponse?}}{{#allProperties?}}
// Result properties
{{#headers}}
/*
{{>nonInlineResponseSignature}}
{
return reply()->rawHeader("{{baseName}}");
}
*/ {{/headers}}
{{#inlineResponse}}
{{>docCommentShort}}
static {{dataType.name}} {{paramName}}(Response r)
{
return
{{#producesNonJson?}}
std::get<Bytes>(r.body)
{{/producesNonJson?}}
{{^producesNonJson?}}
std::move(jsonBody(r).get()).get<{{dataType.name}}>()
{{/producesNonJson?}}
;
}
{{/inlineResponse}}
{{#properties}}
{{!there's nothing in #properties if the response is inline}}
{{>nonInlineResponseSignature}};
{{/properties}}
{{/allProperties?}}{{/normalResponse?}}{{/responses}}
static BaseJob::Query buildQuery(
{{#queryParams}}{{>joinedParamDef}}{{/queryParams}});
static BaseJob::Body buildBody({{#allParams}}{{>joinedParamDef}}{{/allParams}});
static bool success(Response r);
{{#producesNonJson?}}
static const immer::array<std::string> expectedContentTypes;
{{/producesNonJson?}}
};
} {{! namespace Kazv}}
namespace nlohmann
{
using namespace Kazv;
{{#models.model}}
template<>
struct adl_serializer<{{qualifiedName}}> {
{{#in?}}
static void to_json(json& jo, const {{qualifiedName}} &pod)
{
{{#parents}}{{!assume no more one parent}}
jo = static_cast<const {{name}} &>(pod);
//nlohmann::to_json(jo, static_cast<const {{name}} &>(pod));
{{/parents}}
{{#propertyMap}}
addPropertyMapToJson(jo, pod.{{nameCamelCase}});
{{/propertyMap}}
{{#vars}}
{{#required?}}jo["{{baseName}}"s] = pod.{{nameCamelCase}};{{/required?}}
{{^required?}}addToJsonIfNeeded(jo, "{{baseName}}"s, pod.{{nameCamelCase}});{{/required?}}
{{/vars}}
}
{{/in?}}
{{#out?}}
static void from_json(const json &jo, {{qualifiedName}}& result)
{
{{#parents}}
static_cast<{{name}} &{{!of the parent!}}>(result) = jo;
//nlohmann::from_json(jo, static_cast<const {{name}} &{{!of the parent!}}>(result));
{{/parents}}
{{#vars}}
- result.{{nameCamelCase}} = jo.at("{{baseName}}"s);
+ if (jo.contains("{{baseName}}"s)) {
+ result.{{nameCamelCase}} = jo.at("{{baseName}}"s);
+ }
{{/vars}}
{{#propertyMap}}
result.{{nameCamelCase}} = jo;
{{/propertyMap}}
}
{{/out?}}
};
{{/models.model}}
}
namespace Kazv
{
{{/operations.operation}}
} // namespace Kazv
diff --git a/src/application-service/definitions/location.hpp b/src/application-service/definitions/location.hpp
index b780193..baa23af 100644
--- a/src/application-service/definitions/location.hpp
+++ b/src/application-service/definitions/location.hpp
@@ -1,55 +1,61 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct ThirdPartyLocation
{
/// An alias for a matrix room.
std::string alias;
/// The protocol ID that the third party location is a part of.
std::string protocol;
/// Information used to identify this third party location.
JsonWrap fields;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<ThirdPartyLocation> {
static void to_json(json& jo, const ThirdPartyLocation &pod)
{
jo["alias"s] = pod.alias;
jo["protocol"s] = pod.protocol;
jo["fields"s] = pod.fields;
}
static void from_json(const json &jo, ThirdPartyLocation& result)
{
- result.alias = jo.at("alias"s);
- result.protocol = jo.at("protocol"s);
- result.fields = jo.at("fields"s);
+ if (jo.contains("alias"s)) {
+ result.alias = jo.at("alias"s);
+ }
+ if (jo.contains("protocol"s)) {
+ result.protocol = jo.at("protocol"s);
+ }
+ if (jo.contains("fields"s)) {
+ result.fields = jo.at("fields"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/application-service/definitions/protocol.hpp b/src/application-service/definitions/protocol.hpp
index 105f25c..eee82d7 100644
--- a/src/application-service/definitions/protocol.hpp
+++ b/src/application-service/definitions/protocol.hpp
@@ -1,170 +1,192 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Definition of valid values for a field.
struct FieldType
{
/// A regular expression for validation of a field's value. This may be relatively
/// coarse to verify the value as the application service providing this protocol
/// may apply additional validation or filtering.
std::string regexp;
/// An placeholder serving as a valid example of the field value.
std::string placeholder;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<FieldType> {
static void to_json(json& jo, const FieldType &pod)
{
jo["regexp"s] = pod.regexp;
jo["placeholder"s] = pod.placeholder;
}
static void from_json(const json &jo, FieldType& result)
{
- result.regexp = jo.at("regexp"s);
- result.placeholder = jo.at("placeholder"s);
+ if (jo.contains("regexp"s)) {
+ result.regexp = jo.at("regexp"s);
+ }
+ if (jo.contains("placeholder"s)) {
+ result.placeholder = jo.at("placeholder"s);
+ }
}
};
}
namespace Kazv
{
struct ProtocolInstance
{
/// A human-readable description for the protocol, such as the name.
std::string desc;
/// An optional content URI representing the protocol. Overrides the one provided
/// at the higher level Protocol object.
std::string icon;
/// Preset values for ``fields`` the client may use to search by.
JsonWrap fields;
/// A unique identifier across all instances.
std::string networkId;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<ProtocolInstance> {
static void to_json(json& jo, const ProtocolInstance &pod)
{
jo["desc"s] = pod.desc;
addToJsonIfNeeded(jo, "icon"s, pod.icon);
jo["fields"s] = pod.fields;
jo["network_id"s] = pod.networkId;
}
static void from_json(const json &jo, ProtocolInstance& result)
{
- result.desc = jo.at("desc"s);
- result.icon = jo.at("icon"s);
- result.fields = jo.at("fields"s);
- result.networkId = jo.at("network_id"s);
+ if (jo.contains("desc"s)) {
+ result.desc = jo.at("desc"s);
+ }
+ if (jo.contains("icon"s)) {
+ result.icon = jo.at("icon"s);
+ }
+ if (jo.contains("fields"s)) {
+ result.fields = jo.at("fields"s);
+ }
+ if (jo.contains("network_id"s)) {
+ result.networkId = jo.at("network_id"s);
+ }
}
};
}
namespace Kazv
{
struct ThirdPartyProtocol
{
/// Fields which may be used to identify a third party user. These should be
/// ordered to suggest the way that entities may be grouped, where higher
/// groupings are ordered first. For example, the name of a network should be
/// searched before the nickname of a user.
immer::array<std::string> userFields;
/// Fields which may be used to identify a third party location. These should be
/// ordered to suggest the way that entities may be grouped, where higher
/// groupings are ordered first. For example, the name of a network should be
/// searched before the name of a channel.
immer::array<std::string> locationFields;
/// A content URI representing an icon for the third party protocol.
std::string icon;
/// The type definitions for the fields defined in the ``user_fields`` and
/// ``location_fields``. Each entry in those arrays MUST have an entry here. The
/// ``string`` key for this object is field name itself.
///
/// May be an empty object if no fields are defined.
immer::map<std::string, FieldType> fieldTypes;
/// A list of objects representing independent instances of configuration.
/// For example, multiple networks on IRC if multiple are provided by the
/// same application service.
immer::array<ProtocolInstance> instances;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<ThirdPartyProtocol> {
static void to_json(json& jo, const ThirdPartyProtocol &pod)
{
jo["user_fields"s] = pod.userFields;
jo["location_fields"s] = pod.locationFields;
jo["icon"s] = pod.icon;
jo["field_types"s] = pod.fieldTypes;
jo["instances"s] = pod.instances;
}
static void from_json(const json &jo, ThirdPartyProtocol& result)
{
- result.userFields = jo.at("user_fields"s);
- result.locationFields = jo.at("location_fields"s);
- result.icon = jo.at("icon"s);
- result.fieldTypes = jo.at("field_types"s);
- result.instances = jo.at("instances"s);
+ if (jo.contains("user_fields"s)) {
+ result.userFields = jo.at("user_fields"s);
+ }
+ if (jo.contains("location_fields"s)) {
+ result.locationFields = jo.at("location_fields"s);
+ }
+ if (jo.contains("icon"s)) {
+ result.icon = jo.at("icon"s);
+ }
+ if (jo.contains("field_types"s)) {
+ result.fieldTypes = jo.at("field_types"s);
+ }
+ if (jo.contains("instances"s)) {
+ result.instances = jo.at("instances"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/application-service/definitions/user.hpp b/src/application-service/definitions/user.hpp
index 893e531..ffa965a 100644
--- a/src/application-service/definitions/user.hpp
+++ b/src/application-service/definitions/user.hpp
@@ -1,55 +1,61 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct ThirdPartyUser
{
/// A Matrix User ID represting a third party user.
std::string userid;
/// The protocol ID that the third party location is a part of.
std::string protocol;
/// Information used to identify this third party location.
JsonWrap fields;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<ThirdPartyUser> {
static void to_json(json& jo, const ThirdPartyUser &pod)
{
jo["userid"s] = pod.userid;
jo["protocol"s] = pod.protocol;
jo["fields"s] = pod.fields;
}
static void from_json(const json &jo, ThirdPartyUser& result)
{
- result.userid = jo.at("userid"s);
- result.protocol = jo.at("protocol"s);
- result.fields = jo.at("fields"s);
+ if (jo.contains("userid"s)) {
+ result.userid = jo.at("userid"s);
+ }
+ if (jo.contains("protocol"s)) {
+ result.protocol = jo.at("protocol"s);
+ }
+ if (jo.contains("fields"s)) {
+ result.fields = jo.at("fields"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/client/client.cpp b/src/client/client.cpp
index 6e7a53e..1bd6440 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -1,98 +1,95 @@
#include <lager/util.hpp>
#include <lager/context.hpp>
#include <functional>
#include "client.hpp"
#include "csapi/login.hpp"
#include "types.hpp"
#include "debug.hpp"
#include "job/jobinterface.hpp"
namespace Kazv
{
Client::Effect loginEffect(Client::LoginAction a)
{
return
[=](auto &&ctx) {
LoginJob job(a.serverUrl,
"m.login.password"s, // type
UserIdentifier{ "m.id.user"s, json{{"user", a.username}} }, // identifier
a.password,
{}, // token, not used
{}, // device id, not used
a.deviceName.value_or("libkazv"));
auto &jobHandler = lager::get<JobInterface &>(ctx);
- auto res = jobHandler.fetch(job);
- dbgClient << "Result validity: " << res.valid() << std::endl;
- auto r = res.get();
- if (job.success(r)) {
- dbgClient << "Job success" << std::endl;
- const json &j = jsonBody(r).get();
- try {
- std::string serverUrl = j.contains("well_known")
- ? j.at("well_known").at("m.homeserver").at("base_url").get<std::string>()
- : a.serverUrl;
- ctx.dispatch(Client::LoadUserInfoAction{
- serverUrl,
- j.at("user_id"),
- j.at("access_token"),
- j.at("device_id"),
- /* loggedIn = */ true
+ jobHandler.fetch(
+ job,
+ [=](std::shared_future<BaseJob::Response> res) {
+ auto r = res.get();
+ if (LoginJob::success(r)) {
+ dbgClient << "Job success" << std::endl;
+ const json &j = jsonBody(r).get();
+ std::string serverUrl = j.contains("well_known")
+ ? j.at("well_known").at("m.homeserver").at("base_url").get<std::string>()
+ : a.serverUrl;
+ ctx.dispatch(Client::LoadUserInfoAction{
+ serverUrl,
+ j.at("user_id"),
+ j.at("access_token"),
+ j.at("device_id"),
+ /* loggedIn = */ true
});
- } catch (const json::out_of_range &e) {
- dbgClient << "Json error: " << e.what() << std::endl;
- ctx.dispatch(Error::SetErrorAction{e.what()});
- }
- }
+ }
+ });
};
}
lager::effect<Client::Action> logoutEffect(Client::LogoutAction a)
{
return
[=](auto &&ctx) {
ctx.dispatch(Client::LoadUserInfoAction{
""s,
""s,
""s,
""s,
/* loggedIn = */ true
});
};
}
auto Client::update(Client m, Action a) -> Result
{
dbgClient << "Client::update()" << std::endl;
return
std::visit(lager::visitor{
[=](Error::Action a) mutable -> Result {
m.error = Error::update(m.error, a);
return {std::move(m), lager::noop};
},
[=](LoginAction a) mutable -> Result {
return {std::move(m), loginEffect(std::move(a))};
},
[=](LogoutAction a) mutable -> Result {
return {std::move(m), logoutEffect(std::move(a))};
},
[=](LoadUserInfoAction a) mutable -> Result {
dbgClient << "LoadUserInfoAction: " << a.userId << std::endl;
m.serverUrl = a.serverUrl;
m.userId = a.userId;
m.token = a.token;
m.deviceId = a.deviceId;
m.loggedIn = a.loggedIn;
return { std::move(m),
[](auto &&ctx) {
ctx.dispatch(Error::SetErrorAction{Error::NoError{}});
}
};
},
}, std::move(a));
}
}
diff --git a/src/csapi/admin.hpp b/src/csapi/admin.hpp
index 5eed428..9a2627b 100644
--- a/src/csapi/admin.hpp
+++ b/src/csapi/admin.hpp
@@ -1,140 +1,150 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Gets information about a particular user.
*
* Gets information about a particular user.
*
* This API may be restricted to only be called by the user being looked
* up, or by a server admin. Server-local administrator privileges are not
* specified in this document.
*/
class GetWhoIsJob : public BaseJob {
public:
// Inner data structures
/// Gets information about a particular user.
///
/// This API may be restricted to only be called by the user being looked
/// up, or by a server admin. Server-local administrator privileges are not
/// specified in this document.
struct ConnectionInfo
{
/// Most recently seen IP address of the session.
std::string ip;
/// Unix timestamp that the session was last active.
std::optional<std::int_fast64_t> lastSeen;
/// User agent string last seen in the session.
std::string userAgent;
};
/// Gets information about a particular user.
///
/// This API may be restricted to only be called by the user being looked
/// up, or by a server admin. Server-local administrator privileges are not
/// specified in this document.
struct SessionInfo
{
/// Information particular connections in the session.
immer::array<ConnectionInfo> connections;
};
/// Gets information about a particular user.
///
/// This API may be restricted to only be called by the user being looked
/// up, or by a server admin. Server-local administrator privileges are not
/// specified in this document.
struct DeviceInfo
{
/// A user's sessions (i.e. what they did with an access token from one login).
immer::array<SessionInfo> sessions;
};
// Construction/destruction
/*! \brief Gets information about a particular user.
*
* \param userId
* The user to look up.
*/
explicit GetWhoIsJob(std::string serverUrl
, std::string _accessToken
,
std::string userId );
// Result properties
/// The Matrix user ID of the user.
static std::string userId(Response r);
/// Each key is an identifier for one of the user's devices.
static immer::map<std::string, DeviceInfo> devices(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string userId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetWhoIsJob::ConnectionInfo> {
static void from_json(const json &jo, GetWhoIsJob::ConnectionInfo& result)
{
- result.ip = jo.at("ip"s);
- result.lastSeen = jo.at("last_seen"s);
- result.userAgent = jo.at("user_agent"s);
+ if (jo.contains("ip"s)) {
+ result.ip = jo.at("ip"s);
+ }
+ if (jo.contains("last_seen"s)) {
+ result.lastSeen = jo.at("last_seen"s);
+ }
+ if (jo.contains("user_agent"s)) {
+ result.userAgent = jo.at("user_agent"s);
+ }
}
};
template<>
struct adl_serializer<GetWhoIsJob::SessionInfo> {
static void from_json(const json &jo, GetWhoIsJob::SessionInfo& result)
{
- result.connections = jo.at("connections"s);
+ if (jo.contains("connections"s)) {
+ result.connections = jo.at("connections"s);
+ }
}
};
template<>
struct adl_serializer<GetWhoIsJob::DeviceInfo> {
static void from_json(const json &jo, GetWhoIsJob::DeviceInfo& result)
{
- result.sessions = jo.at("sessions"s);
+ if (jo.contains("sessions"s)) {
+ result.sessions = jo.at("sessions"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/administrative_contact.hpp b/src/csapi/administrative_contact.hpp
index 29ff1b9..0f8182b 100644
--- a/src/csapi/administrative_contact.hpp
+++ b/src/csapi/administrative_contact.hpp
@@ -1,563 +1,571 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/request_msisdn_validation.hpp"
#include "csapi/definitions/request_token_response.hpp"
#include "csapi/definitions/request_email_validation.hpp"
#include "csapi/definitions/auth_data.hpp"
namespace Kazv {
/*! \brief Gets a list of a user's third party identifiers.
*
* Gets a list of the third party identifiers that the homeserver has
* associated with the user's account.
*
* This is *not* the same as the list of third party identifiers bound to
* the user's Matrix ID in identity servers.
*
* Identifiers in this list may be used by the homeserver as, for example,
* identifiers that it will accept to reset the user's account password.
*/
class GetAccount3PIDsJob : public BaseJob {
public:
// Inner data structures
/// Gets a list of the third party identifiers that the homeserver has
/// associated with the user's account.
///
/// This is *not* the same as the list of third party identifiers bound to
/// the user's Matrix ID in identity servers.
///
/// Identifiers in this list may be used by the homeserver as, for example,
/// identifiers that it will accept to reset the user's account password.
struct ThirdPartyIdentifier
{
/// The medium of the third party identifier.
std::string medium;
/// The third party identifier address.
std::string address;
/// The timestamp, in milliseconds, when the identifier was
/// validated by the identity server.
std::int_fast64_t validatedAt;
/// The timestamp, in milliseconds, when the homeserver associated the third party identifier with the user.
std::int_fast64_t addedAt;
};
// Construction/destruction
/// Gets a list of a user's third party identifiers.
explicit GetAccount3PIDsJob(std::string serverUrl
, std::string _accessToken
);
// Result properties
/// Gets a list of the third party identifiers that the homeserver has
/// associated with the user's account.
///
/// This is *not* the same as the list of third party identifiers bound to
/// the user's Matrix ID in identity servers.
///
/// Identifiers in this list may be used by the homeserver as, for example,
/// identifiers that it will accept to reset the user's account password.
static immer::array<ThirdPartyIdentifier> threepids(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody();
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetAccount3PIDsJob::ThirdPartyIdentifier> {
static void from_json(const json &jo, GetAccount3PIDsJob::ThirdPartyIdentifier& result)
{
- result.medium = jo.at("medium"s);
- result.address = jo.at("address"s);
- result.validatedAt = jo.at("validated_at"s);
- result.addedAt = jo.at("added_at"s);
+ if (jo.contains("medium"s)) {
+ result.medium = jo.at("medium"s);
+ }
+ if (jo.contains("address"s)) {
+ result.address = jo.at("address"s);
+ }
+ if (jo.contains("validated_at"s)) {
+ result.validatedAt = jo.at("validated_at"s);
+ }
+ if (jo.contains("added_at"s)) {
+ result.addedAt = jo.at("added_at"s);
+ }
}
};
}
namespace Kazv
{
/*! \brief Adds contact information to the user's account.
*
* Adds contact information to the user's account.
*
* This endpoint is deprecated in favour of the more specific ``/3pid/add``
* and ``/3pid/bind`` endpoints.
*
* .. Note::
* Previously this endpoint supported a ``bind`` parameter. This parameter
* has been removed, making this endpoint behave as though it was ``false``.
* This results in this endpoint being an equivalent to ``/3pid/bind`` rather
* than dual-purpose.
*/
class Post3PIDsJob : public BaseJob {
public:
// Inner data structures
/// The third party credentials to associate with the account.
struct ThreePidCredentials
{
/// The client secret used in the session with the identity server.
std::string clientSecret;
/// The identity server to use.
std::string idServer;
/// An access token previously registered with the identity server. Servers
/// can treat this as optional to distinguish between r0.5-compatible clients
/// and this specification version.
std::string idAccessToken;
/// The session identifier given by the identity server.
std::string sid;
};
// Construction/destruction
/*! \brief Adds contact information to the user's account.
*
* \param threePidCreds
* The third party credentials to associate with the account.
*/
explicit Post3PIDsJob(std::string serverUrl
, std::string _accessToken
,
ThreePidCredentials threePidCreds );
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(ThreePidCredentials threePidCreds);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<Post3PIDsJob::ThreePidCredentials> {
static void to_json(json& jo, const Post3PIDsJob::ThreePidCredentials &pod)
{
jo["client_secret"s] = pod.clientSecret;
jo["id_server"s] = pod.idServer;
jo["id_access_token"s] = pod.idAccessToken;
jo["sid"s] = pod.sid;
}
};
}
namespace Kazv
{
/*! \brief Adds contact information to the user's account.
*
* This API endpoint uses the `User-Interactive Authentication API`_.
*
* Adds contact information to the user's account. Homeservers should use 3PIDs added
* through this endpoint for password resets instead of relying on the identity server.
*
* Homeservers should prevent the caller from adding a 3PID to their account if it has
* already been added to another user's account on the homeserver.
*/
class Add3PIDJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Adds contact information to the user's account.
*
* \param clientSecret
* The client secret used in the session with the homeserver.
*
* \param sid
* The session identifier given by the homeserver.
*
* \param auth
* Additional authentication information for the
* user-interactive authentication API.
*/
explicit Add3PIDJob(std::string serverUrl
, std::string _accessToken
,
std::string clientSecret , std::string sid , std::optional<AuthenticationData> auth = std::nullopt);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string clientSecret, std::string sid, std::optional<AuthenticationData> auth);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Binds a 3PID to the user's account through an Identity Service.
*
* Binds a 3PID to the user's account through the specified identity server.
*
* Homeservers should not prevent this request from succeeding if another user
* has bound the 3PID. Homeservers should simply proxy any errors received by
* the identity server to the caller.
*
* Homeservers should track successful binds so they can be unbound later.
*/
class Bind3PIDJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Binds a 3PID to the user's account through an Identity Service.
*
* \param clientSecret
* The client secret used in the session with the identity server.
*
* \param idServer
* The identity server to use.
*
* \param idAccessToken
* An access token previously registered with the identity server.
*
* \param sid
* The session identifier given by the identity server.
*/
explicit Bind3PIDJob(std::string serverUrl
, std::string _accessToken
,
std::string clientSecret , std::string idServer , std::string idAccessToken , std::string sid );
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string clientSecret, std::string idServer, std::string idAccessToken, std::string sid);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Deletes a third party identifier from the user's account
*
* Removes a third party identifier from the user's account. This might not
* cause an unbind of the identifier from the identity server.
*
* Unlike other endpoints, this endpoint does not take an ``id_access_token``
* parameter because the homeserver is expected to sign the request to the
* identity server instead.
*/
class Delete3pidFromAccountJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Deletes a third party identifier from the user's account
*
* \param medium
* The medium of the third party identifier being removed.
*
* \param address
* The third party address being removed.
*
* \param idServer
* The identity server to unbind from. If not provided, the homeserver
* MUST use the ``id_server`` the identifier was added through. If the
* homeserver does not know the original ``id_server``, it MUST return
* a ``id_server_unbind_result`` of ``no-support``.
*/
explicit Delete3pidFromAccountJob(std::string serverUrl
, std::string _accessToken
,
std::string medium , std::string address , std::string idServer = {});
// Result properties
/// An indicator as to whether or not the homeserver was able to unbind
/// the 3PID from the identity server. ``success`` indicates that the
/// indentity server has unbound the identifier whereas ``no-support``
/// indicates that the identity server refuses to support the request
/// or the homeserver was not able to determine an identity server to
/// unbind from.
static std::string idServerUnbindResult(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string medium, std::string address, std::string idServer);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Removes a user's third party identifier from an identity server.
*
* Removes a user's third party identifier from the provided identity server
* without removing it from the homeserver.
*
* Unlike other endpoints, this endpoint does not take an ``id_access_token``
* parameter because the homeserver is expected to sign the request to the
* identity server instead.
*/
class Unbind3pidFromAccountJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Removes a user's third party identifier from an identity server.
*
* \param medium
* The medium of the third party identifier being removed.
*
* \param address
* The third party address being removed.
*
* \param idServer
* The identity server to unbind from. If not provided, the homeserver
* MUST use the ``id_server`` the identifier was added through. If the
* homeserver does not know the original ``id_server``, it MUST return
* a ``id_server_unbind_result`` of ``no-support``.
*/
explicit Unbind3pidFromAccountJob(std::string serverUrl
, std::string _accessToken
,
std::string medium , std::string address , std::string idServer = {});
// Result properties
/// An indicator as to whether or not the identity server was able to unbind
/// the 3PID. ``success`` indicates that the identity server has unbound the
/// identifier whereas ``no-support`` indicates that the identity server
/// refuses to support the request or the homeserver was not able to determine
/// an identity server to unbind from.
static std::string idServerUnbindResult(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string medium, std::string address, std::string idServer);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Begins the validation process for an email address for association with the user's account.
*
* The homeserver must check that the given email address is **not**
* already associated with an account on this homeserver. This API should
* be used to request validation tokens when adding an email address to an
* account. This API's parameters and response are identical to that of
* the |/register/email/requestToken|_ endpoint. The homeserver should validate
* the email itself, either by sending a validation email itself or by using
* a service it has control over.
*/
class RequestTokenTo3PIDEmailJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Begins the validation process for an email address for association with the user's account.
*
* \param body
* The homeserver must check that the given email address is **not**
* already associated with an account on this homeserver. This API should
* be used to request validation tokens when adding an email address to an
* account. This API's parameters and response are identical to that of
* the |/register/email/requestToken|_ endpoint. The homeserver should validate
* the email itself, either by sending a validation email itself or by using
* a service it has control over.
*/
explicit RequestTokenTo3PIDEmailJob(std::string serverUrl
,
EmailValidationData body );
// Result properties
/// An email was sent to the given address. Note that this may be an
/// email containing the validation token or it may be informing the
/// user of an error.
static RequestTokenResponse data(Response r)
{
return
std::move(jsonBody(r).get()).get<RequestTokenResponse>()
;
}
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(EmailValidationData body);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Begins the validation process for a phone number for association with the user's account.
*
* The homeserver must check that the given phone number is **not**
* already associated with an account on this homeserver. This API should
* be used to request validation tokens when adding a phone number to an
* account. This API's parameters and response are identical to that of
* the |/register/msisdn/requestToken|_ endpoint. The homeserver should validate
* the phone number itself, either by sending a validation message itself or by using
* a service it has control over.
*/
class RequestTokenTo3PIDMSISDNJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Begins the validation process for a phone number for association with the user's account.
*
* \param body
* The homeserver must check that the given phone number is **not**
* already associated with an account on this homeserver. This API should
* be used to request validation tokens when adding a phone number to an
* account. This API's parameters and response are identical to that of
* the |/register/msisdn/requestToken|_ endpoint. The homeserver should validate
* the phone number itself, either by sending a validation message itself or by using
* a service it has control over.
*/
explicit RequestTokenTo3PIDMSISDNJob(std::string serverUrl
,
MsisdnValidationData body );
// Result properties
/// An SMS message was sent to the given phone number.
static RequestTokenResponse data(Response r)
{
return
std::move(jsonBody(r).get()).get<RequestTokenResponse>()
;
}
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(MsisdnValidationData body);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/capabilities.hpp b/src/csapi/capabilities.hpp
index 02e03e8..72c0133 100644
--- a/src/csapi/capabilities.hpp
+++ b/src/csapi/capabilities.hpp
@@ -1,121 +1,131 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Gets information about the server's capabilities.
*
* Gets information about the server's supported feature set
* and other relevant capabilities.
*/
class GetCapabilitiesJob : public BaseJob {
public:
// Inner data structures
/// Capability to indicate if the user can change their password.
struct ChangePasswordCapability
{
/// True if the user can change their password, false otherwise.
bool enabled;
};
/// The room versions the server supports.
struct RoomVersionsCapability
{
/// The default room version the server is using for new rooms.
std::string defaultVersion;
/// A detailed description of the room versions the server supports.
immer::map<std::string, std::string> available;
};
/// The custom capabilities the server supports, using the
/// Java package naming convention.
struct Capabilities
{
/// Capability to indicate if the user can change their password.
std::optional<ChangePasswordCapability> changePassword;
/// The room versions the server supports.
std::optional<RoomVersionsCapability> roomVersions;
/// The custom capabilities the server supports, using the
/// Java package naming convention.
immer::map<std::string, JsonWrap> additionalProperties;
};
// Construction/destruction
/// Gets information about the server's capabilities.
explicit GetCapabilitiesJob(std::string serverUrl
, std::string _accessToken
);
// Result properties
/// The custom capabilities the server supports, using the
/// Java package naming convention.
static Capabilities capabilities(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody();
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetCapabilitiesJob::ChangePasswordCapability> {
static void from_json(const json &jo, GetCapabilitiesJob::ChangePasswordCapability& result)
{
- result.enabled = jo.at("enabled"s);
+ if (jo.contains("enabled"s)) {
+ result.enabled = jo.at("enabled"s);
+ }
}
};
template<>
struct adl_serializer<GetCapabilitiesJob::RoomVersionsCapability> {
static void from_json(const json &jo, GetCapabilitiesJob::RoomVersionsCapability& result)
{
- result.defaultVersion = jo.at("default"s);
- result.available = jo.at("available"s);
+ if (jo.contains("default"s)) {
+ result.defaultVersion = jo.at("default"s);
+ }
+ if (jo.contains("available"s)) {
+ result.available = jo.at("available"s);
+ }
}
};
template<>
struct adl_serializer<GetCapabilitiesJob::Capabilities> {
static void from_json(const json &jo, GetCapabilitiesJob::Capabilities& result)
{
- result.changePassword = jo.at("m.change_password"s);
- result.roomVersions = jo.at("m.room_versions"s);
+ if (jo.contains("m.change_password"s)) {
+ result.changePassword = jo.at("m.change_password"s);
+ }
+ if (jo.contains("m.room_versions"s)) {
+ result.roomVersions = jo.at("m.room_versions"s);
+ }
result.additionalProperties = jo;
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/auth_data.hpp b/src/csapi/definitions/auth_data.hpp
index 9ce2396..d3d2177 100644
--- a/src/csapi/definitions/auth_data.hpp
+++ b/src/csapi/definitions/auth_data.hpp
@@ -1,52 +1,56 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Used by clients to submit authentication information to the interactive-authentication API
struct AuthenticationData
{
/// The login type that the client is attempting to complete.
std::string type;
/// The value of the session key given by the homeserver.
std::string session;
/// Keys dependent on the login type
immer::map<std::string, JsonWrap> authInfo;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<AuthenticationData> {
static void to_json(json& jo, const AuthenticationData &pod)
{
addPropertyMapToJson(jo, pod.authInfo);
jo["type"s] = pod.type;
addToJsonIfNeeded(jo, "session"s, pod.session);
}
static void from_json(const json &jo, AuthenticationData& result)
{
- result.type = jo.at("type"s);
- result.session = jo.at("session"s);
+ if (jo.contains("type"s)) {
+ result.type = jo.at("type"s);
+ }
+ if (jo.contains("session"s)) {
+ result.session = jo.at("session"s);
+ }
result.authInfo = jo;
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/client_device.hpp b/src/csapi/definitions/client_device.hpp
index 6c0936b..8e6e3ce 100644
--- a/src/csapi/definitions/client_device.hpp
+++ b/src/csapi/definitions/client_device.hpp
@@ -1,65 +1,73 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// A client device
struct Device
{
/// Identifier of this device.
std::string deviceId;
/// Display name set by the user for this device. Absent if no name has been
/// set.
std::string displayName;
/// The IP address where this device was last seen. (May be a few minutes out
/// of date, for efficiency reasons).
std::string lastSeenIp;
/// The timestamp (in milliseconds since the unix epoch) when this devices
/// was last seen. (May be a few minutes out of date, for efficiency
/// reasons).
std::optional<std::int_fast64_t> lastSeenTs;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<Device> {
static void to_json(json& jo, const Device &pod)
{
jo["device_id"s] = pod.deviceId;
addToJsonIfNeeded(jo, "display_name"s, pod.displayName);
addToJsonIfNeeded(jo, "last_seen_ip"s, pod.lastSeenIp);
addToJsonIfNeeded(jo, "last_seen_ts"s, pod.lastSeenTs);
}
static void from_json(const json &jo, Device& result)
{
- result.deviceId = jo.at("device_id"s);
- result.displayName = jo.at("display_name"s);
- result.lastSeenIp = jo.at("last_seen_ip"s);
- result.lastSeenTs = jo.at("last_seen_ts"s);
+ if (jo.contains("device_id"s)) {
+ result.deviceId = jo.at("device_id"s);
+ }
+ if (jo.contains("display_name"s)) {
+ result.displayName = jo.at("display_name"s);
+ }
+ if (jo.contains("last_seen_ip"s)) {
+ result.lastSeenIp = jo.at("last_seen_ip"s);
+ }
+ if (jo.contains("last_seen_ts"s)) {
+ result.lastSeenTs = jo.at("last_seen_ts"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/device_keys.hpp b/src/csapi/definitions/device_keys.hpp
index b6e90c0..55342d6 100644
--- a/src/csapi/definitions/device_keys.hpp
+++ b/src/csapi/definitions/device_keys.hpp
@@ -1,75 +1,85 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Device identity keys
struct DeviceKeys
{
/// The ID of the user the device belongs to. Must match the user ID used
/// when logging in.
std::string userId;
/// The ID of the device these keys belong to. Must match the device ID used
/// when logging in.
std::string deviceId;
/// The encryption algorithms supported by this device.
immer::array<std::string> algorithms;
/// Public identity keys. The names of the properties should be in the
/// format ``<algorithm>:<device_id>``. The keys themselves should be
/// encoded as specified by the key algorithm.
immer::map<std::string, std::string> keys;
/// Signatures for the device key object. A map from user ID, to a map from
/// ``<algorithm>:<device_id>`` to the signature.
///
/// The signature is calculated using the process described at `Signing
/// JSON`_.
immer::map<std::string, immer::map<std::string, std::string>> signatures;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<DeviceKeys> {
static void to_json(json& jo, const DeviceKeys &pod)
{
jo["user_id"s] = pod.userId;
jo["device_id"s] = pod.deviceId;
jo["algorithms"s] = pod.algorithms;
jo["keys"s] = pod.keys;
jo["signatures"s] = pod.signatures;
}
static void from_json(const json &jo, DeviceKeys& result)
{
- result.userId = jo.at("user_id"s);
- result.deviceId = jo.at("device_id"s);
- result.algorithms = jo.at("algorithms"s);
- result.keys = jo.at("keys"s);
- result.signatures = jo.at("signatures"s);
+ if (jo.contains("user_id"s)) {
+ result.userId = jo.at("user_id"s);
+ }
+ if (jo.contains("device_id"s)) {
+ result.deviceId = jo.at("device_id"s);
+ }
+ if (jo.contains("algorithms"s)) {
+ result.algorithms = jo.at("algorithms"s);
+ }
+ if (jo.contains("keys"s)) {
+ result.keys = jo.at("keys"s);
+ }
+ if (jo.contains("signatures"s)) {
+ result.signatures = jo.at("signatures"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/event-schemas/schema/core-event-schema/unsigned_prop.hpp b/src/csapi/definitions/event-schemas/schema/core-event-schema/unsigned_prop.hpp
index 8964454..5df7de6 100644
--- a/src/csapi/definitions/event-schemas/schema/core-event-schema/unsigned_prop.hpp
+++ b/src/csapi/definitions/event-schemas/schema/core-event-schema/unsigned_prop.hpp
@@ -1,57 +1,63 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Contains optional extra information about the event.
struct UnsignedData
{
/// The time in milliseconds that has elapsed since the event was sent. This field is generated by the local homeserver, and may be incorrect if the local time on at least one of the two servers is out of sync, which can cause the age to either be negative or greater than it actually is.
std::optional<int> age;
/// The event that redacted this event, if any.
JsonWrap redactedBecause;
/// The client-supplied transaction ID, for example, provided via
/// ``PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}``,
/// if the client being given the event is the same one which sent it.
std::string transactionId;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<UnsignedData> {
static void to_json(json& jo, const UnsignedData &pod)
{
addToJsonIfNeeded(jo, "age"s, pod.age);
addToJsonIfNeeded(jo, "redacted_because"s, pod.redactedBecause);
addToJsonIfNeeded(jo, "transaction_id"s, pod.transactionId);
}
static void from_json(const json &jo, UnsignedData& result)
{
- result.age = jo.at("age"s);
- result.redactedBecause = jo.at("redacted_because"s);
- result.transactionId = jo.at("transaction_id"s);
+ if (jo.contains("age"s)) {
+ result.age = jo.at("age"s);
+ }
+ if (jo.contains("redacted_because"s)) {
+ result.redactedBecause = jo.at("redacted_because"s);
+ }
+ if (jo.contains("transaction_id"s)) {
+ result.transactionId = jo.at("transaction_id"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/event-schemas/schema/m.room.member.hpp b/src/csapi/definitions/event-schemas/schema/m.room.member.hpp
index cca84f9..4457d80 100644
--- a/src/csapi/definitions/event-schemas/schema/m.room.member.hpp
+++ b/src/csapi/definitions/event-schemas/schema/m.room.member.hpp
@@ -1,362 +1,390 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/event-schemas/schema/stripped_state.hpp"
#include "csapi/definitions/event-schemas/schema/core-event-schema/unsigned_prop.hpp"
namespace Kazv {
/// A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.
struct SignedData
{
/// The invited matrix user ID. Must be equal to the user_id property of the event.
std::string mxid;
/// A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.
immer::map<std::string, immer::map<std::string, std::string>> signatures;
/// The token property of the containing third_party_invite object.
std::string token;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<SignedData> {
static void to_json(json& jo, const SignedData &pod)
{
jo["mxid"s] = pod.mxid;
jo["signatures"s] = pod.signatures;
jo["token"s] = pod.token;
}
static void from_json(const json &jo, SignedData& result)
{
- result.mxid = jo.at("mxid"s);
- result.signatures = jo.at("signatures"s);
- result.token = jo.at("token"s);
+ if (jo.contains("mxid"s)) {
+ result.mxid = jo.at("mxid"s);
+ }
+ if (jo.contains("signatures"s)) {
+ result.signatures = jo.at("signatures"s);
+ }
+ if (jo.contains("token"s)) {
+ result.token = jo.at("token"s);
+ }
}
};
}
namespace Kazv
{
struct Invite
{
/// A name which can be displayed to represent the user instead of their third party identifier
std::string displayName;
/// A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.
SignedData signedData;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<Invite> {
static void to_json(json& jo, const Invite &pod)
{
jo["display_name"s] = pod.displayName;
jo["signed"s] = pod.signedData;
}
static void from_json(const json &jo, Invite& result)
{
- result.displayName = jo.at("display_name"s);
- result.signedData = jo.at("signed"s);
+ if (jo.contains("display_name"s)) {
+ result.displayName = jo.at("display_name"s);
+ }
+ if (jo.contains("signed"s)) {
+ result.signedData = jo.at("signed"s);
+ }
}
};
}
namespace Kazv
{
struct EventContent
{
/// The avatar URL for this user, if any.
std::string avatarUrl;
/// The display name for this user, if any.
Variant displayname;
/// The membership state of the user.
std::string membership;
/// Flag indicating if the room containing this event was created with the intention of being a direct chat. See `Direct Messaging`_.
std::optional<bool> isDirect;
std::optional<Invite> thirdPartyInvite;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<EventContent> {
static void to_json(json& jo, const EventContent &pod)
{
addToJsonIfNeeded(jo, "avatar_url"s, pod.avatarUrl);
addToJsonIfNeeded(jo, "displayname"s, pod.displayname);
jo["membership"s] = pod.membership;
addToJsonIfNeeded(jo, "is_direct"s, pod.isDirect);
addToJsonIfNeeded(jo, "third_party_invite"s, pod.thirdPartyInvite);
}
static void from_json(const json &jo, EventContent& result)
{
- result.avatarUrl = jo.at("avatar_url"s);
- result.displayname = jo.at("displayname"s);
- result.membership = jo.at("membership"s);
- result.isDirect = jo.at("is_direct"s);
- result.thirdPartyInvite = jo.at("third_party_invite"s);
+ if (jo.contains("avatar_url"s)) {
+ result.avatarUrl = jo.at("avatar_url"s);
+ }
+ if (jo.contains("displayname"s)) {
+ result.displayname = jo.at("displayname"s);
+ }
+ if (jo.contains("membership"s)) {
+ result.membership = jo.at("membership"s);
+ }
+ if (jo.contains("is_direct"s)) {
+ result.isDirect = jo.at("is_direct"s);
+ }
+ if (jo.contains("third_party_invite"s)) {
+ result.thirdPartyInvite = jo.at("third_party_invite"s);
+ }
}
};
}
namespace Kazv
{
/// Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.
///
/// The following membership states are specified:
///
/// - ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.
///
/// - ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.
///
/// - ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).
///
/// - ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).
///
/// - ``knock`` - This is a reserved word, which currently has no meaning.
///
/// The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
///
/// This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data.
/// If present, this contains an array of ``StrippedState`` Events. These events provide information
/// on a subset of state events such as the room name.
///
/// The user for which a membership applies is represented by the ``state_key``. Under some conditions,
/// the ``sender`` and ``state_key`` may not match - this may be interpreted as the ``sender`` affecting
/// the membership state of the ``state_key`` user.
///
/// The ``membership`` for a given user can change over time. The table below represents the various changes
/// over time and how clients and servers must interpret those changes. Previous membership can be retrieved
/// from the ``prev_content`` object on an event. If not present, the user's previous membership must be assumed
/// as ``leave``.
///
/// .. TODO: Improve how this table is written? We use a csv-table to get around vertical header restrictions.
///
/// .. csv-table::
/// :header-rows: 1
/// :stub-columns: 1
///
/// "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``"
/// "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented."
/// "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented."
/// "from ``leave``","New invitation sent.","User joined.","No change.","User was banned.","Not implemented."
/// "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented."
/// "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented."
struct TheCurrentMembershipStateOfAUserInTheRoom : JsonWrap
{
/// Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.
///
/// The following membership states are specified:
///
/// - ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.
///
/// - ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.
///
/// - ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).
///
/// - ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).
///
/// - ``knock`` - This is a reserved word, which currently has no meaning.
///
/// The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
///
/// This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data.
/// If present, this contains an array of ``StrippedState`` Events. These events provide information
/// on a subset of state events such as the room name.
///
/// The user for which a membership applies is represented by the ``state_key``. Under some conditions,
/// the ``sender`` and ``state_key`` may not match - this may be interpreted as the ``sender`` affecting
/// the membership state of the ``state_key`` user.
///
/// The ``membership`` for a given user can change over time. The table below represents the various changes
/// over time and how clients and servers must interpret those changes. Previous membership can be retrieved
/// from the ``prev_content`` object on an event. If not present, the user's previous membership must be assumed
/// as ``leave``.
///
/// .. TODO: Improve how this table is written? We use a csv-table to get around vertical header restrictions.
///
/// .. csv-table::
/// :header-rows: 1
/// :stub-columns: 1
///
/// "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``"
/// "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented."
/// "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented."
/// "from ``leave``","New invitation sent.","User joined.","No change.","User was banned.","Not implemented."
/// "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented."
/// "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented."
std::optional<EventContent> content;
/// The ``user_id`` this membership event relates to. In all cases except for when ``membership`` is
/// ``join``, the user ID sending the event does not need to match the user ID in the ``state_key``,
/// unlike other events. Regular authorisation rules still apply.
std::string stateKey;
/// Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.
///
/// The following membership states are specified:
///
/// - ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.
///
/// - ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.
///
/// - ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).
///
/// - ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).
///
/// - ``knock`` - This is a reserved word, which currently has no meaning.
///
/// The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
///
/// This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data.
/// If present, this contains an array of ``StrippedState`` Events. These events provide information
/// on a subset of state events such as the room name.
///
/// The user for which a membership applies is represented by the ``state_key``. Under some conditions,
/// the ``sender`` and ``state_key`` may not match - this may be interpreted as the ``sender`` affecting
/// the membership state of the ``state_key`` user.
///
/// The ``membership`` for a given user can change over time. The table below represents the various changes
/// over time and how clients and servers must interpret those changes. Previous membership can be retrieved
/// from the ``prev_content`` object on an event. If not present, the user's previous membership must be assumed
/// as ``leave``.
///
/// .. TODO: Improve how this table is written? We use a csv-table to get around vertical header restrictions.
///
/// .. csv-table::
/// :header-rows: 1
/// :stub-columns: 1
///
/// "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``"
/// "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented."
/// "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented."
/// "from ``leave``","New invitation sent.","User joined.","No change.","User was banned.","Not implemented."
/// "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented."
/// "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented."
std::string type;
/// Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.
///
/// The following membership states are specified:
///
/// - ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.
///
/// - ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.
///
/// - ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).
///
/// - ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).
///
/// - ``knock`` - This is a reserved word, which currently has no meaning.
///
/// The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
///
/// This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data.
/// If present, this contains an array of ``StrippedState`` Events. These events provide information
/// on a subset of state events such as the room name.
///
/// The user for which a membership applies is represented by the ``state_key``. Under some conditions,
/// the ``sender`` and ``state_key`` may not match - this may be interpreted as the ``sender`` affecting
/// the membership state of the ``state_key`` user.
///
/// The ``membership`` for a given user can change over time. The table below represents the various changes
/// over time and how clients and servers must interpret those changes. Previous membership can be retrieved
/// from the ``prev_content`` object on an event. If not present, the user's previous membership must be assumed
/// as ``leave``.
///
/// .. TODO: Improve how this table is written? We use a csv-table to get around vertical header restrictions.
///
/// .. csv-table::
/// :header-rows: 1
/// :stub-columns: 1
///
/// "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``"
/// "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented."
/// "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented."
/// "from ``leave``","New invitation sent.","User joined.","No change.","User was banned.","Not implemented."
/// "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented."
/// "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented."
JsonWrap unsignedData;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<TheCurrentMembershipStateOfAUserInTheRoom> {
static void to_json(json& jo, const TheCurrentMembershipStateOfAUserInTheRoom &pod)
{
jo = static_cast<const JsonWrap &>(pod);
addToJsonIfNeeded(jo, "content"s, pod.content);
addToJsonIfNeeded(jo, "state_key"s, pod.stateKey);
addToJsonIfNeeded(jo, "type"s, pod.type);
addToJsonIfNeeded(jo, "unsigned"s, pod.unsignedData);
}
static void from_json(const json &jo, TheCurrentMembershipStateOfAUserInTheRoom& result)
{
static_cast<JsonWrap &>(result) = jo;
- result.content = jo.at("content"s);
- result.stateKey = jo.at("state_key"s);
- result.type = jo.at("type"s);
- result.unsignedData = jo.at("unsigned"s);
+ if (jo.contains("content"s)) {
+ result.content = jo.at("content"s);
+ }
+ if (jo.contains("state_key"s)) {
+ result.stateKey = jo.at("state_key"s);
+ }
+ if (jo.contains("type"s)) {
+ result.type = jo.at("type"s);
+ }
+ if (jo.contains("unsigned"s)) {
+ result.unsignedData = jo.at("unsigned"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/event-schemas/schema/stripped_state.hpp b/src/csapi/definitions/event-schemas/schema/stripped_state.hpp
index 174767c..21b95b2 100644
--- a/src/csapi/definitions/event-schemas/schema/stripped_state.hpp
+++ b/src/csapi/definitions/event-schemas/schema/stripped_state.hpp
@@ -1,62 +1,70 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// A stripped down state event, with only the ``type``, ``state_key``,
/// ``sender``, and ``content`` keys.
struct StrippedState
{
/// The ``content`` for the event.
JsonWrap content;
/// The ``state_key`` for the event.
std::string stateKey;
/// The ``type`` for the event.
std::string type;
/// The ``sender`` for the event.
std::string sender;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<StrippedState> {
static void to_json(json& jo, const StrippedState &pod)
{
jo["content"s] = pod.content;
jo["state_key"s] = pod.stateKey;
jo["type"s] = pod.type;
jo["sender"s] = pod.sender;
}
static void from_json(const json &jo, StrippedState& result)
{
- result.content = jo.at("content"s);
- result.stateKey = jo.at("state_key"s);
- result.type = jo.at("type"s);
- result.sender = jo.at("sender"s);
+ if (jo.contains("content"s)) {
+ result.content = jo.at("content"s);
+ }
+ if (jo.contains("state_key"s)) {
+ result.stateKey = jo.at("state_key"s);
+ }
+ if (jo.contains("type"s)) {
+ result.type = jo.at("type"s);
+ }
+ if (jo.contains("sender"s)) {
+ result.sender = jo.at("sender"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/event_batch.hpp b/src/csapi/definitions/event_batch.hpp
index 2fa82fe..1a6b723 100644
--- a/src/csapi/definitions/event_batch.hpp
+++ b/src/csapi/definitions/event_batch.hpp
@@ -1,43 +1,45 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct EventBatch
{
/// List of events.
EventList events;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<EventBatch> {
static void to_json(json& jo, const EventBatch &pod)
{
addToJsonIfNeeded(jo, "events"s, pod.events);
}
static void from_json(const json &jo, EventBatch& result)
{
- result.events = jo.at("events"s);
+ if (jo.contains("events"s)) {
+ result.events = jo.at("events"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/event_filter.hpp b/src/csapi/definitions/event_filter.hpp
index 5dac8ff..8dc4259 100644
--- a/src/csapi/definitions/event_filter.hpp
+++ b/src/csapi/definitions/event_filter.hpp
@@ -1,67 +1,77 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct EventFilter
{
/// The maximum number of events to return.
std::optional<int> limit;
/// A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the ``'senders'`` filter.
immer::array<std::string> notSenders;
/// A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the ``'types'`` filter. A '*' can be used as a wildcard to match any sequence of characters.
immer::array<std::string> notTypes;
/// A list of senders IDs to include. If this list is absent then all senders are included.
immer::array<std::string> senders;
/// A list of event types to include. If this list is absent then all event types are included. A ``'*'`` can be used as a wildcard to match any sequence of characters.
immer::array<std::string> types;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<EventFilter> {
static void to_json(json& jo, const EventFilter &pod)
{
addToJsonIfNeeded(jo, "limit"s, pod.limit);
addToJsonIfNeeded(jo, "not_senders"s, pod.notSenders);
addToJsonIfNeeded(jo, "not_types"s, pod.notTypes);
addToJsonIfNeeded(jo, "senders"s, pod.senders);
addToJsonIfNeeded(jo, "types"s, pod.types);
}
static void from_json(const json &jo, EventFilter& result)
{
- result.limit = jo.at("limit"s);
- result.notSenders = jo.at("not_senders"s);
- result.notTypes = jo.at("not_types"s);
- result.senders = jo.at("senders"s);
- result.types = jo.at("types"s);
+ if (jo.contains("limit"s)) {
+ result.limit = jo.at("limit"s);
+ }
+ if (jo.contains("not_senders"s)) {
+ result.notSenders = jo.at("not_senders"s);
+ }
+ if (jo.contains("not_types"s)) {
+ result.notTypes = jo.at("not_types"s);
+ }
+ if (jo.contains("senders"s)) {
+ result.senders = jo.at("senders"s);
+ }
+ if (jo.contains("types"s)) {
+ result.types = jo.at("types"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/openid_token.hpp b/src/csapi/definitions/openid_token.hpp
index bcbddba..d81856a 100644
--- a/src/csapi/definitions/openid_token.hpp
+++ b/src/csapi/definitions/openid_token.hpp
@@ -1,65 +1,73 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct OpenidToken
{
/// An access token the consumer may use to verify the identity of
/// the person who generated the token. This is given to the federation
/// API ``GET /openid/userinfo`` to verify the user's identity.
std::string accessToken;
/// The string ``Bearer``.
std::string tokenType;
/// The homeserver domain the consumer should use when attempting to
/// verify the user's identity.
std::string matrixServerName;
/// The number of seconds before this token expires and a new one must
/// be generated.
int expiresIn;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<OpenidToken> {
static void to_json(json& jo, const OpenidToken &pod)
{
jo["access_token"s] = pod.accessToken;
jo["token_type"s] = pod.tokenType;
jo["matrix_server_name"s] = pod.matrixServerName;
jo["expires_in"s] = pod.expiresIn;
}
static void from_json(const json &jo, OpenidToken& result)
{
- result.accessToken = jo.at("access_token"s);
- result.tokenType = jo.at("token_type"s);
- result.matrixServerName = jo.at("matrix_server_name"s);
- result.expiresIn = jo.at("expires_in"s);
+ if (jo.contains("access_token"s)) {
+ result.accessToken = jo.at("access_token"s);
+ }
+ if (jo.contains("token_type"s)) {
+ result.tokenType = jo.at("token_type"s);
+ }
+ if (jo.contains("matrix_server_name"s)) {
+ result.matrixServerName = jo.at("matrix_server_name"s);
+ }
+ if (jo.contains("expires_in"s)) {
+ result.expiresIn = jo.at("expires_in"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/public_rooms_response.hpp b/src/csapi/definitions/public_rooms_response.hpp
index 7e237cb..d305bf0 100644
--- a/src/csapi/definitions/public_rooms_response.hpp
+++ b/src/csapi/definitions/public_rooms_response.hpp
@@ -1,148 +1,174 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct PublicRoomsChunk
{
/// Aliases of the room. May be empty.
immer::array<std::string> aliases;
/// The canonical alias of the room, if any.
std::string canonicalAlias;
/// The name of the room, if any.
std::string name;
/// The number of members joined to the room.
int numJoinedMembers;
/// The ID of the room.
std::string roomId;
/// The topic of the room, if any.
std::string topic;
/// Whether the room may be viewed by guest users without joining.
bool worldReadable;
/// Whether guest users may join the room and participate in it.
/// If they can, they will be subject to ordinary power level
/// rules like any other user.
bool guestCanJoin;
/// The URL for the room's avatar, if one is set.
std::string avatarUrl;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PublicRoomsChunk> {
static void to_json(json& jo, const PublicRoomsChunk &pod)
{
addToJsonIfNeeded(jo, "aliases"s, pod.aliases);
addToJsonIfNeeded(jo, "canonical_alias"s, pod.canonicalAlias);
addToJsonIfNeeded(jo, "name"s, pod.name);
jo["num_joined_members"s] = pod.numJoinedMembers;
jo["room_id"s] = pod.roomId;
addToJsonIfNeeded(jo, "topic"s, pod.topic);
jo["world_readable"s] = pod.worldReadable;
jo["guest_can_join"s] = pod.guestCanJoin;
addToJsonIfNeeded(jo, "avatar_url"s, pod.avatarUrl);
}
static void from_json(const json &jo, PublicRoomsChunk& result)
{
- result.aliases = jo.at("aliases"s);
- result.canonicalAlias = jo.at("canonical_alias"s);
- result.name = jo.at("name"s);
- result.numJoinedMembers = jo.at("num_joined_members"s);
- result.roomId = jo.at("room_id"s);
- result.topic = jo.at("topic"s);
- result.worldReadable = jo.at("world_readable"s);
- result.guestCanJoin = jo.at("guest_can_join"s);
- result.avatarUrl = jo.at("avatar_url"s);
+ if (jo.contains("aliases"s)) {
+ result.aliases = jo.at("aliases"s);
+ }
+ if (jo.contains("canonical_alias"s)) {
+ result.canonicalAlias = jo.at("canonical_alias"s);
+ }
+ if (jo.contains("name"s)) {
+ result.name = jo.at("name"s);
+ }
+ if (jo.contains("num_joined_members"s)) {
+ result.numJoinedMembers = jo.at("num_joined_members"s);
+ }
+ if (jo.contains("room_id"s)) {
+ result.roomId = jo.at("room_id"s);
+ }
+ if (jo.contains("topic"s)) {
+ result.topic = jo.at("topic"s);
+ }
+ if (jo.contains("world_readable"s)) {
+ result.worldReadable = jo.at("world_readable"s);
+ }
+ if (jo.contains("guest_can_join"s)) {
+ result.guestCanJoin = jo.at("guest_can_join"s);
+ }
+ if (jo.contains("avatar_url"s)) {
+ result.avatarUrl = jo.at("avatar_url"s);
+ }
}
};
}
namespace Kazv
{
/// A list of the rooms on the server.
struct PublicRoomsResponse
{
/// A paginated chunk of public rooms.
immer::array<PublicRoomsChunk> chunk;
/// A pagination token for the response. The absence of this token
/// means there are no more results to fetch and the client should
/// stop paginating.
std::string nextBatch;
/// A pagination token that allows fetching previous results. The
/// absence of this token means there are no results before this
/// batch, i.e. this is the first batch.
std::string prevBatch;
/// An estimate on the total number of public rooms, if the
/// server has an estimate.
std::optional<int> totalRoomCountEstimate;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PublicRoomsResponse> {
static void to_json(json& jo, const PublicRoomsResponse &pod)
{
jo["chunk"s] = pod.chunk;
addToJsonIfNeeded(jo, "next_batch"s, pod.nextBatch);
addToJsonIfNeeded(jo, "prev_batch"s, pod.prevBatch);
addToJsonIfNeeded(jo, "total_room_count_estimate"s, pod.totalRoomCountEstimate);
}
static void from_json(const json &jo, PublicRoomsResponse& result)
{
- result.chunk = jo.at("chunk"s);
- result.nextBatch = jo.at("next_batch"s);
- result.prevBatch = jo.at("prev_batch"s);
- result.totalRoomCountEstimate = jo.at("total_room_count_estimate"s);
+ if (jo.contains("chunk"s)) {
+ result.chunk = jo.at("chunk"s);
+ }
+ if (jo.contains("next_batch"s)) {
+ result.nextBatch = jo.at("next_batch"s);
+ }
+ if (jo.contains("prev_batch"s)) {
+ result.prevBatch = jo.at("prev_batch"s);
+ }
+ if (jo.contains("total_room_count_estimate"s)) {
+ result.totalRoomCountEstimate = jo.at("total_room_count_estimate"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/push_condition.hpp b/src/csapi/definitions/push_condition.hpp
index 1afb7c8..d95ad34 100644
--- a/src/csapi/definitions/push_condition.hpp
+++ b/src/csapi/definitions/push_condition.hpp
@@ -1,74 +1,82 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct PushCondition
{
/// The kind of condition to apply. See `conditions <#conditions>`_ for
/// more information on the allowed kinds and how they work.
std::string kind;
/// Required for ``event_match`` conditions. The dot-separated field of the
/// event to match.
///
/// Required for ``sender_notification_permission`` conditions. The field in
/// the power level event the user needs a minimum power level for. Fields
/// must be specified under the ``notifications`` property in the power level
/// event's ``content``.
std::string key;
/// Required for ``event_match`` conditions. The glob-style pattern to
/// match against. Patterns with no special glob characters should be
/// treated as having asterisks prepended and appended when testing the
/// condition.
std::string pattern;
/// Required for ``room_member_count`` conditions. A decimal integer
/// optionally prefixed by one of, ==, <, >, >= or <=. A prefix of < matches
/// rooms where the member count is strictly less than the given number and
/// so forth. If no prefix is present, this parameter defaults to ==.
std::string is;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PushCondition> {
static void to_json(json& jo, const PushCondition &pod)
{
jo["kind"s] = pod.kind;
addToJsonIfNeeded(jo, "key"s, pod.key);
addToJsonIfNeeded(jo, "pattern"s, pod.pattern);
addToJsonIfNeeded(jo, "is"s, pod.is);
}
static void from_json(const json &jo, PushCondition& result)
{
- result.kind = jo.at("kind"s);
- result.key = jo.at("key"s);
- result.pattern = jo.at("pattern"s);
- result.is = jo.at("is"s);
+ if (jo.contains("kind"s)) {
+ result.kind = jo.at("kind"s);
+ }
+ if (jo.contains("key"s)) {
+ result.key = jo.at("key"s);
+ }
+ if (jo.contains("pattern"s)) {
+ result.pattern = jo.at("pattern"s);
+ }
+ if (jo.contains("is"s)) {
+ result.is = jo.at("is"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/push_rule.hpp b/src/csapi/definitions/push_rule.hpp
index 1fd3928..1663cce 100644
--- a/src/csapi/definitions/push_rule.hpp
+++ b/src/csapi/definitions/push_rule.hpp
@@ -1,76 +1,88 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/push_condition.hpp"
namespace Kazv {
struct PushRule
{
/// The actions to perform when this rule is matched.
immer::array<Variant> actions;
/// Whether this is a default rule, or has been set explicitly.
bool isDefault;
/// Whether the push rule is enabled or not.
bool enabled;
/// The ID of this rule.
std::string ruleId;
/// The conditions that must hold true for an event in order for a rule to be
/// applied to an event. A rule with no conditions always matches. Only
/// applicable to ``underride`` and ``override`` rules.
immer::array<PushCondition> conditions;
/// The glob-style pattern to match against. Only applicable to ``content``
/// rules.
std::string pattern;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PushRule> {
static void to_json(json& jo, const PushRule &pod)
{
jo["actions"s] = pod.actions;
jo["default"s] = pod.isDefault;
jo["enabled"s] = pod.enabled;
jo["rule_id"s] = pod.ruleId;
addToJsonIfNeeded(jo, "conditions"s, pod.conditions);
addToJsonIfNeeded(jo, "pattern"s, pod.pattern);
}
static void from_json(const json &jo, PushRule& result)
{
- result.actions = jo.at("actions"s);
- result.isDefault = jo.at("default"s);
- result.enabled = jo.at("enabled"s);
- result.ruleId = jo.at("rule_id"s);
- result.conditions = jo.at("conditions"s);
- result.pattern = jo.at("pattern"s);
+ if (jo.contains("actions"s)) {
+ result.actions = jo.at("actions"s);
+ }
+ if (jo.contains("default"s)) {
+ result.isDefault = jo.at("default"s);
+ }
+ if (jo.contains("enabled"s)) {
+ result.enabled = jo.at("enabled"s);
+ }
+ if (jo.contains("rule_id"s)) {
+ result.ruleId = jo.at("rule_id"s);
+ }
+ if (jo.contains("conditions"s)) {
+ result.conditions = jo.at("conditions"s);
+ }
+ if (jo.contains("pattern"s)) {
+ result.pattern = jo.at("pattern"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/push_ruleset.hpp b/src/csapi/definitions/push_ruleset.hpp
index 4b1a629..c52ad0e 100644
--- a/src/csapi/definitions/push_ruleset.hpp
+++ b/src/csapi/definitions/push_ruleset.hpp
@@ -1,67 +1,77 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/push_rule.hpp"
namespace Kazv {
struct PushRuleset
{
immer::array<PushRule> content;
immer::array<PushRule> override;
immer::array<PushRule> room;
immer::array<PushRule> sender;
immer::array<PushRule> underride;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PushRuleset> {
static void to_json(json& jo, const PushRuleset &pod)
{
addToJsonIfNeeded(jo, "content"s, pod.content);
addToJsonIfNeeded(jo, "override"s, pod.override);
addToJsonIfNeeded(jo, "room"s, pod.room);
addToJsonIfNeeded(jo, "sender"s, pod.sender);
addToJsonIfNeeded(jo, "underride"s, pod.underride);
}
static void from_json(const json &jo, PushRuleset& result)
{
- result.content = jo.at("content"s);
- result.override = jo.at("override"s);
- result.room = jo.at("room"s);
- result.sender = jo.at("sender"s);
- result.underride = jo.at("underride"s);
+ if (jo.contains("content"s)) {
+ result.content = jo.at("content"s);
+ }
+ if (jo.contains("override"s)) {
+ result.override = jo.at("override"s);
+ }
+ if (jo.contains("room"s)) {
+ result.room = jo.at("room"s);
+ }
+ if (jo.contains("sender"s)) {
+ result.sender = jo.at("sender"s);
+ }
+ if (jo.contains("underride"s)) {
+ result.underride = jo.at("underride"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/request_email_validation.hpp b/src/csapi/definitions/request_email_validation.hpp
index 1bd79c7..7556b15 100644
--- a/src/csapi/definitions/request_email_validation.hpp
+++ b/src/csapi/definitions/request_email_validation.hpp
@@ -1,58 +1,62 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/../../identity/definitions/request_email_validation.hpp"
namespace Kazv {
struct EmailValidationData : RequestEmailValidation
{
/// The hostname of the identity server to communicate with. May optionally
/// include a port. This parameter is ignored when the homeserver handles
/// 3PID verification.
///
/// This parameter is deprecated with a plan to be removed in a future specification
/// version for ``/account/password`` and ``/register`` requests.
std::string idServer;
/// An access token previously registered with the identity server. Servers
/// can treat this as optional to distinguish between r0.5-compatible clients
/// and this specification version.
///
/// Required if an ``id_server`` is supplied.
std::string idAccessToken;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<EmailValidationData> {
static void to_json(json& jo, const EmailValidationData &pod)
{
jo = static_cast<const RequestEmailValidation &>(pod);
addToJsonIfNeeded(jo, "id_server"s, pod.idServer);
addToJsonIfNeeded(jo, "id_access_token"s, pod.idAccessToken);
}
static void from_json(const json &jo, EmailValidationData& result)
{
static_cast<RequestEmailValidation &>(result) = jo;
- result.idServer = jo.at("id_server"s);
- result.idAccessToken = jo.at("id_access_token"s);
+ if (jo.contains("id_server"s)) {
+ result.idServer = jo.at("id_server"s);
+ }
+ if (jo.contains("id_access_token"s)) {
+ result.idAccessToken = jo.at("id_access_token"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/request_msisdn_validation.hpp b/src/csapi/definitions/request_msisdn_validation.hpp
index 6699207..39ec2fb 100644
--- a/src/csapi/definitions/request_msisdn_validation.hpp
+++ b/src/csapi/definitions/request_msisdn_validation.hpp
@@ -1,58 +1,62 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/../../identity/definitions/request_msisdn_validation.hpp"
namespace Kazv {
struct MsisdnValidationData : RequestMsisdnValidation
{
/// The hostname of the identity server to communicate with. May optionally
/// include a port. This parameter is ignored when the homeserver handles
/// 3PID verification.
///
/// This parameter is deprecated with a plan to be removed in a future specification
/// version for ``/account/password`` and ``/register`` requests.
std::string idServer;
/// An access token previously registered with the identity server. Servers
/// can treat this as optional to distinguish between r0.5-compatible clients
/// and this specification version.
///
/// Required if an ``id_server`` is supplied.
std::string idAccessToken;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<MsisdnValidationData> {
static void to_json(json& jo, const MsisdnValidationData &pod)
{
jo = static_cast<const RequestMsisdnValidation &>(pod);
addToJsonIfNeeded(jo, "id_server"s, pod.idServer);
addToJsonIfNeeded(jo, "id_access_token"s, pod.idAccessToken);
}
static void from_json(const json &jo, MsisdnValidationData& result)
{
static_cast<RequestMsisdnValidation &>(result) = jo;
- result.idServer = jo.at("id_server"s);
- result.idAccessToken = jo.at("id_access_token"s);
+ if (jo.contains("id_server"s)) {
+ result.idServer = jo.at("id_server"s);
+ }
+ if (jo.contains("id_access_token"s)) {
+ result.idAccessToken = jo.at("id_access_token"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/request_token_response.hpp b/src/csapi/definitions/request_token_response.hpp
index 718ae08..12e41ee 100644
--- a/src/csapi/definitions/request_token_response.hpp
+++ b/src/csapi/definitions/request_token_response.hpp
@@ -1,60 +1,64 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct RequestTokenResponse
{
/// The session ID. Session IDs are opaque strings that must consist entirely
/// of the characters ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255
/// characters and they must not be empty.
std::string sid;
/// An optional field containing a URL where the client must submit the
/// validation token to, with identical parameters to the Identity Service
/// API's ``POST /validate/email/submitToken`` endpoint (without the requirement
/// for an access token). The homeserver must send this token to the user (if
/// applicable), who should then be prompted to provide it to the client.
///
/// If this field is not present, the client can assume that verification
/// will happen without the client's involvement provided the homeserver
/// advertises this specification version in the ``/versions`` response
/// (ie: r0.5.0).
std::string submitUrl;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RequestTokenResponse> {
static void to_json(json& jo, const RequestTokenResponse &pod)
{
jo["sid"s] = pod.sid;
addToJsonIfNeeded(jo, "submit_url"s, pod.submitUrl);
}
static void from_json(const json &jo, RequestTokenResponse& result)
{
- result.sid = jo.at("sid"s);
- result.submitUrl = jo.at("submit_url"s);
+ if (jo.contains("sid"s)) {
+ result.sid = jo.at("sid"s);
+ }
+ if (jo.contains("submit_url"s)) {
+ result.submitUrl = jo.at("submit_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/room_event_batch.hpp b/src/csapi/definitions/room_event_batch.hpp
index 7485376..ad5c61a 100644
--- a/src/csapi/definitions/room_event_batch.hpp
+++ b/src/csapi/definitions/room_event_batch.hpp
@@ -1,43 +1,45 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct RoomEventBatch
{
/// List of events.
EventList events;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RoomEventBatch> {
static void to_json(json& jo, const RoomEventBatch &pod)
{
addToJsonIfNeeded(jo, "events"s, pod.events);
}
static void from_json(const json &jo, RoomEventBatch& result)
{
- result.events = jo.at("events"s);
+ if (jo.contains("events"s)) {
+ result.events = jo.at("events"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/room_event_filter.hpp b/src/csapi/definitions/room_event_filter.hpp
index 3be3a8f..c3e0af6 100644
--- a/src/csapi/definitions/room_event_filter.hpp
+++ b/src/csapi/definitions/room_event_filter.hpp
@@ -1,73 +1,83 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/event_filter.hpp"
namespace Kazv {
struct RoomEventFilter : EventFilter
{
/// If ``true``, enables lazy-loading of membership events. See
/// `Lazy-loading room members <#lazy-loading-room-members>`_
/// for more information. Defaults to ``false``.
std::optional<bool> lazyLoadMembers;
/// If ``true``, sends all membership events for all events, even if they have already
/// been sent to the client. Does not
/// apply unless ``lazy_load_members`` is ``true``. See
/// `Lazy-loading room members <#lazy-loading-room-members>`_
/// for more information. Defaults to ``false``.
std::optional<bool> includeRedundantMembers;
/// A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` filter.
immer::array<std::string> notRooms;
/// A list of room IDs to include. If this list is absent then all rooms are included.
immer::array<std::string> rooms;
/// If ``true``, includes only events with a ``url`` key in their content. If ``false``, excludes those events. If omitted, ``url`` key is not considered for filtering.
std::optional<bool> containsUrl;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RoomEventFilter> {
static void to_json(json& jo, const RoomEventFilter &pod)
{
jo = static_cast<const EventFilter &>(pod);
addToJsonIfNeeded(jo, "lazy_load_members"s, pod.lazyLoadMembers);
addToJsonIfNeeded(jo, "include_redundant_members"s, pod.includeRedundantMembers);
addToJsonIfNeeded(jo, "not_rooms"s, pod.notRooms);
addToJsonIfNeeded(jo, "rooms"s, pod.rooms);
addToJsonIfNeeded(jo, "contains_url"s, pod.containsUrl);
}
static void from_json(const json &jo, RoomEventFilter& result)
{
static_cast<EventFilter &>(result) = jo;
- result.lazyLoadMembers = jo.at("lazy_load_members"s);
- result.includeRedundantMembers = jo.at("include_redundant_members"s);
- result.notRooms = jo.at("not_rooms"s);
- result.rooms = jo.at("rooms"s);
- result.containsUrl = jo.at("contains_url"s);
+ if (jo.contains("lazy_load_members"s)) {
+ result.lazyLoadMembers = jo.at("lazy_load_members"s);
+ }
+ if (jo.contains("include_redundant_members"s)) {
+ result.includeRedundantMembers = jo.at("include_redundant_members"s);
+ }
+ if (jo.contains("not_rooms"s)) {
+ result.notRooms = jo.at("not_rooms"s);
+ }
+ if (jo.contains("rooms"s)) {
+ result.rooms = jo.at("rooms"s);
+ }
+ if (jo.contains("contains_url"s)) {
+ result.containsUrl = jo.at("contains_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/state_event_batch.hpp b/src/csapi/definitions/state_event_batch.hpp
index 37e699f..9abfd55 100644
--- a/src/csapi/definitions/state_event_batch.hpp
+++ b/src/csapi/definitions/state_event_batch.hpp
@@ -1,43 +1,45 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct StateEventBatch
{
/// List of events.
EventList events;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<StateEventBatch> {
static void to_json(json& jo, const StateEventBatch &pod)
{
addToJsonIfNeeded(jo, "events"s, pod.events);
}
static void from_json(const json &jo, StateEventBatch& result)
{
- result.events = jo.at("events"s);
+ if (jo.contains("events"s)) {
+ result.events = jo.at("events"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/sync_filter.hpp b/src/csapi/definitions/sync_filter.hpp
index 5e68e75..da3695c 100644
--- a/src/csapi/definitions/sync_filter.hpp
+++ b/src/csapi/definitions/sync_filter.hpp
@@ -1,136 +1,160 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/room_event_filter.hpp"
#include "csapi/definitions/event_filter.hpp"
namespace Kazv {
/// Filters to be applied to room data.
struct RoomFilter
{
/// A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` filter. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data``
immer::array<std::string> notRooms;
/// A list of room IDs to include. If this list is absent then all rooms are included. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data``
immer::array<std::string> rooms;
/// The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.
RoomEventFilter ephemeral;
/// Include rooms that the user has left in the sync, default false
std::optional<bool> includeLeave;
/// The state events to include for rooms.
RoomEventFilter state;
/// The message and state update events to include for rooms.
RoomEventFilter timeline;
/// The per user account data to include for rooms.
RoomEventFilter accountData;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RoomFilter> {
static void to_json(json& jo, const RoomFilter &pod)
{
addToJsonIfNeeded(jo, "not_rooms"s, pod.notRooms);
addToJsonIfNeeded(jo, "rooms"s, pod.rooms);
addToJsonIfNeeded(jo, "ephemeral"s, pod.ephemeral);
addToJsonIfNeeded(jo, "include_leave"s, pod.includeLeave);
addToJsonIfNeeded(jo, "state"s, pod.state);
addToJsonIfNeeded(jo, "timeline"s, pod.timeline);
addToJsonIfNeeded(jo, "account_data"s, pod.accountData);
}
static void from_json(const json &jo, RoomFilter& result)
{
- result.notRooms = jo.at("not_rooms"s);
- result.rooms = jo.at("rooms"s);
- result.ephemeral = jo.at("ephemeral"s);
- result.includeLeave = jo.at("include_leave"s);
- result.state = jo.at("state"s);
- result.timeline = jo.at("timeline"s);
- result.accountData = jo.at("account_data"s);
+ if (jo.contains("not_rooms"s)) {
+ result.notRooms = jo.at("not_rooms"s);
+ }
+ if (jo.contains("rooms"s)) {
+ result.rooms = jo.at("rooms"s);
+ }
+ if (jo.contains("ephemeral"s)) {
+ result.ephemeral = jo.at("ephemeral"s);
+ }
+ if (jo.contains("include_leave"s)) {
+ result.includeLeave = jo.at("include_leave"s);
+ }
+ if (jo.contains("state"s)) {
+ result.state = jo.at("state"s);
+ }
+ if (jo.contains("timeline"s)) {
+ result.timeline = jo.at("timeline"s);
+ }
+ if (jo.contains("account_data"s)) {
+ result.accountData = jo.at("account_data"s);
+ }
}
};
}
namespace Kazv
{
struct Filter
{
/// List of event fields to include. If this list is absent then all fields are included. The entries may include '.' characters to indicate sub-fields. So ['content.body'] will include the 'body' field of the 'content' object. A literal '.' character in a field name may be escaped using a '\\'. A server may include more fields than were requested.
immer::array<std::string> eventFields;
/// The format to use for events. 'client' will return the events in a format suitable for clients. 'federation' will return the raw event as received over federation. The default is 'client'.
std::string eventFormat;
/// The presence updates to include.
EventFilter presence;
/// The user account data that isn't associated with rooms to include.
EventFilter accountData;
/// Filters to be applied to room data.
RoomFilter room;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<Filter> {
static void to_json(json& jo, const Filter &pod)
{
addToJsonIfNeeded(jo, "event_fields"s, pod.eventFields);
addToJsonIfNeeded(jo, "event_format"s, pod.eventFormat);
addToJsonIfNeeded(jo, "presence"s, pod.presence);
addToJsonIfNeeded(jo, "account_data"s, pod.accountData);
addToJsonIfNeeded(jo, "room"s, pod.room);
}
static void from_json(const json &jo, Filter& result)
{
- result.eventFields = jo.at("event_fields"s);
- result.eventFormat = jo.at("event_format"s);
- result.presence = jo.at("presence"s);
- result.accountData = jo.at("account_data"s);
- result.room = jo.at("room"s);
+ if (jo.contains("event_fields"s)) {
+ result.eventFields = jo.at("event_fields"s);
+ }
+ if (jo.contains("event_format"s)) {
+ result.eventFormat = jo.at("event_format"s);
+ }
+ if (jo.contains("presence"s)) {
+ result.presence = jo.at("presence"s);
+ }
+ if (jo.contains("account_data"s)) {
+ result.accountData = jo.at("account_data"s);
+ }
+ if (jo.contains("room"s)) {
+ result.room = jo.at("room"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/third_party_signed.hpp b/src/csapi/definitions/third_party_signed.hpp
index a7f41df..cdefbff 100644
--- a/src/csapi/definitions/third_party_signed.hpp
+++ b/src/csapi/definitions/third_party_signed.hpp
@@ -1,62 +1,70 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// A signature of an ``m.third_party_invite`` token to prove that this user
/// owns a third party identity which has been invited to the room.
struct ThirdPartySigned
{
/// The Matrix ID of the user who issued the invite.
std::string sender;
/// The Matrix ID of the invitee.
std::string mxid;
/// The state key of the m.third_party_invite event.
std::string token;
/// A signatures object containing a signature of the entire signed object.
immer::map<std::string, immer::map<std::string, std::string>> signatures;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<ThirdPartySigned> {
static void to_json(json& jo, const ThirdPartySigned &pod)
{
jo["sender"s] = pod.sender;
jo["mxid"s] = pod.mxid;
jo["token"s] = pod.token;
jo["signatures"s] = pod.signatures;
}
static void from_json(const json &jo, ThirdPartySigned& result)
{
- result.sender = jo.at("sender"s);
- result.mxid = jo.at("mxid"s);
- result.token = jo.at("token"s);
- result.signatures = jo.at("signatures"s);
+ if (jo.contains("sender"s)) {
+ result.sender = jo.at("sender"s);
+ }
+ if (jo.contains("mxid"s)) {
+ result.mxid = jo.at("mxid"s);
+ }
+ if (jo.contains("token"s)) {
+ result.token = jo.at("token"s);
+ }
+ if (jo.contains("signatures"s)) {
+ result.signatures = jo.at("signatures"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/timeline_batch.hpp b/src/csapi/definitions/timeline_batch.hpp
index 9db0bfc..b31a577 100644
--- a/src/csapi/definitions/timeline_batch.hpp
+++ b/src/csapi/definitions/timeline_batch.hpp
@@ -1,49 +1,53 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/room_event_batch.hpp"
namespace Kazv {
struct Timeline : RoomEventBatch
{
/// True if the number of events returned was limited by the ``limit`` on the filter.
std::optional<bool> limited;
/// A token that can be supplied to the ``from`` parameter of the rooms/{roomId}/messages endpoint.
std::string prevBatch;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<Timeline> {
static void to_json(json& jo, const Timeline &pod)
{
jo = static_cast<const RoomEventBatch &>(pod);
addToJsonIfNeeded(jo, "limited"s, pod.limited);
addToJsonIfNeeded(jo, "prev_batch"s, pod.prevBatch);
}
static void from_json(const json &jo, Timeline& result)
{
static_cast<RoomEventBatch &>(result) = jo;
- result.limited = jo.at("limited"s);
- result.prevBatch = jo.at("prev_batch"s);
+ if (jo.contains("limited"s)) {
+ result.limited = jo.at("limited"s);
+ }
+ if (jo.contains("prev_batch"s)) {
+ result.prevBatch = jo.at("prev_batch"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/user_identifier.hpp b/src/csapi/definitions/user_identifier.hpp
index 52df3d1..896dc1e 100644
--- a/src/csapi/definitions/user_identifier.hpp
+++ b/src/csapi/definitions/user_identifier.hpp
@@ -1,46 +1,48 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Identification information for a user
struct UserIdentifier
{
/// The type of identification. See `Identifier types`_ for supported values and additional property descriptions.
std::string type;
/// Identification information for a user
JsonWrap additionalProperties;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<UserIdentifier> {
static void to_json(json& jo, const UserIdentifier &pod)
{
addPropertyMapToJson(jo, pod.additionalProperties);
jo["type"s] = pod.type;
}
static void from_json(const json &jo, UserIdentifier& result)
{
- result.type = jo.at("type"s);
+ if (jo.contains("type"s)) {
+ result.type = jo.at("type"s);
+ }
result.additionalProperties = jo;
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/wellknown/full.hpp b/src/csapi/definitions/wellknown/full.hpp
index 2dc7460..c292856 100644
--- a/src/csapi/definitions/wellknown/full.hpp
+++ b/src/csapi/definitions/wellknown/full.hpp
@@ -1,56 +1,60 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
#include "csapi/definitions/wellknown/identity_server.hpp"
#include "csapi/definitions/wellknown/homeserver.hpp"
namespace Kazv {
/// Used by clients to determine the homeserver, identity server, and other
/// optional components they should be interacting with.
struct DiscoveryInformation
{
/// Used by clients to determine the homeserver, identity server, and other
/// optional components they should be interacting with.
HomeserverInformation homeserver;
/// Used by clients to determine the homeserver, identity server, and other
/// optional components they should be interacting with.
std::optional<IdentityServerInformation> identityServer;
/// Application-dependent keys using Java package naming convention.
immer::map<std::string, JsonWrap> additionalProperties;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<DiscoveryInformation> {
static void to_json(json& jo, const DiscoveryInformation &pod)
{
addPropertyMapToJson(jo, pod.additionalProperties);
jo["m.homeserver"s] = pod.homeserver;
addToJsonIfNeeded(jo, "m.identity_server"s, pod.identityServer);
}
static void from_json(const json &jo, DiscoveryInformation& result)
{
- result.homeserver = jo.at("m.homeserver"s);
- result.identityServer = jo.at("m.identity_server"s);
+ if (jo.contains("m.homeserver"s)) {
+ result.homeserver = jo.at("m.homeserver"s);
+ }
+ if (jo.contains("m.identity_server"s)) {
+ result.identityServer = jo.at("m.identity_server"s);
+ }
result.additionalProperties = jo;
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/wellknown/homeserver.hpp b/src/csapi/definitions/wellknown/homeserver.hpp
index e435770..93d6a68 100644
--- a/src/csapi/definitions/wellknown/homeserver.hpp
+++ b/src/csapi/definitions/wellknown/homeserver.hpp
@@ -1,43 +1,45 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Used by clients to discover homeserver information.
struct HomeserverInformation
{
/// The base URL for the homeserver for client-server connections.
std::string baseUrl;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<HomeserverInformation> {
static void to_json(json& jo, const HomeserverInformation &pod)
{
jo["base_url"s] = pod.baseUrl;
}
static void from_json(const json &jo, HomeserverInformation& result)
{
- result.baseUrl = jo.at("base_url"s);
+ if (jo.contains("base_url"s)) {
+ result.baseUrl = jo.at("base_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/definitions/wellknown/identity_server.hpp b/src/csapi/definitions/wellknown/identity_server.hpp
index 6b3bc39..f9fff01 100644
--- a/src/csapi/definitions/wellknown/identity_server.hpp
+++ b/src/csapi/definitions/wellknown/identity_server.hpp
@@ -1,43 +1,45 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
/// Used by clients to discover identity server information.
struct IdentityServerInformation
{
/// The base URL for the identity server for client-server connections.
std::string baseUrl;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<IdentityServerInformation> {
static void to_json(json& jo, const IdentityServerInformation &pod)
{
jo["base_url"s] = pod.baseUrl;
}
static void from_json(const json &jo, IdentityServerInformation& result)
{
- result.baseUrl = jo.at("base_url"s);
+ if (jo.contains("base_url"s)) {
+ result.baseUrl = jo.at("base_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/keys.hpp b/src/csapi/keys.hpp
index 2e18c99..8bcc602 100644
--- a/src/csapi/keys.hpp
+++ b/src/csapi/keys.hpp
@@ -1,326 +1,330 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/device_keys.hpp"
namespace Kazv {
/*! \brief Upload end-to-end encryption keys.
*
* Publishes end-to-end encryption keys for the device.
*/
class UploadKeysJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Upload end-to-end encryption keys.
*
* \param deviceKeys
* Identity keys for the device. May be absent if no new
* identity keys are required.
*
* \param oneTimeKeys
* One-time public keys for "pre-key" messages. The names of
* the properties should be in the format
* ``<algorithm>:<key_id>``. The format of the key is determined
* by the `key algorithm <#key-algorithms>`_.
*
* May be absent if no new one-time keys are required.
*/
explicit UploadKeysJob(std::string serverUrl
, std::string _accessToken
,
std::optional<DeviceKeys> deviceKeys = std::nullopt, immer::map<std::string, Variant> oneTimeKeys = {});
// Result properties
/// For each key algorithm, the number of unclaimed one-time keys
/// of that type currently held on the server for this device.
static immer::map<std::string, int> oneTimeKeyCounts(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::optional<DeviceKeys> deviceKeys, immer::map<std::string, Variant> oneTimeKeys);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Download device identity keys.
*
* Returns the current devices and identity keys for the given users.
*/
class QueryKeysJob : public BaseJob {
public:
// Inner data structures
/// Additional data added to the device key information
/// by intermediate servers, and not covered by the
/// signatures.
struct UnsignedDeviceInfo
{
/// The display name which the user set on the device.
std::string deviceDisplayName;
};
/// Returns the current devices and identity keys for the given users.
struct DeviceInformation :
DeviceKeys
{
/// Additional data added to the device key information
/// by intermediate servers, and not covered by the
/// signatures.
std::optional<UnsignedDeviceInfo> unsignedData;
};
// Construction/destruction
/*! \brief Download device identity keys.
*
* \param deviceKeys
* The keys to be downloaded. A map from user ID, to a list of
* device IDs, or to an empty list to indicate all devices for the
* corresponding user.
*
* \param timeout
* The time (in milliseconds) to wait when downloading keys from
* remote servers. 10 seconds is the recommended default.
*
* \param token
* If the client is fetching keys as a result of a device update received
* in a sync request, this should be the 'since' token of that sync request,
* or any later sync token. This allows the server to ensure its response
* contains the keys advertised by the notification in that sync.
*/
explicit QueryKeysJob(std::string serverUrl
, std::string _accessToken
,
immer::map<std::string, immer::array<std::string>> deviceKeys , std::optional<int> timeout = std::nullopt, std::string token = {});
// Result properties
/// If any remote homeservers could not be reached, they are
/// recorded here. The names of the properties are the names of
/// the unreachable servers.
///
/// If the homeserver could be reached, but the user or device
/// was unknown, no failure is recorded. Instead, the corresponding
/// user or device is missing from the ``device_keys`` result.
static immer::map<std::string, JsonWrap> failures(Response r);
/// Information on the queried devices. A map from user ID, to a
/// map from device ID to device information. For each device,
/// the information returned will be the same as uploaded via
/// ``/keys/upload``, with the addition of an ``unsigned``
/// property.
static immer::map<std::string, immer::map<std::string, DeviceInformation>> deviceKeys(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(immer::map<std::string, immer::array<std::string>> deviceKeys, std::optional<int> timeout, std::string token);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<QueryKeysJob::UnsignedDeviceInfo> {
static void from_json(const json &jo, QueryKeysJob::UnsignedDeviceInfo& result)
{
- result.deviceDisplayName = jo.at("device_display_name"s);
+ if (jo.contains("device_display_name"s)) {
+ result.deviceDisplayName = jo.at("device_display_name"s);
+ }
}
};
template<>
struct adl_serializer<QueryKeysJob::DeviceInformation> {
static void from_json(const json &jo, QueryKeysJob::DeviceInformation& result)
{
static_cast<DeviceKeys &>(result) = jo;
//nlohmann::from_json(jo, static_cast<const DeviceKeys &>(result));
- result.unsignedData = jo.at("unsigned"s);
+ if (jo.contains("unsigned"s)) {
+ result.unsignedData = jo.at("unsigned"s);
+ }
}
};
}
namespace Kazv
{
/*! \brief Claim one-time encryption keys.
*
* Claims one-time keys for use in pre-key messages.
*/
class ClaimKeysJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Claim one-time encryption keys.
*
* \param oneTimeKeys
* The keys to be claimed. A map from user ID, to a map from
* device ID to algorithm name.
*
* \param timeout
* The time (in milliseconds) to wait when downloading keys from
* remote servers. 10 seconds is the recommended default.
*/
explicit ClaimKeysJob(std::string serverUrl
, std::string _accessToken
,
immer::map<std::string, immer::map<std::string, std::string>> oneTimeKeys , std::optional<int> timeout = std::nullopt);
// Result properties
/// If any remote homeservers could not be reached, they are
/// recorded here. The names of the properties are the names of
/// the unreachable servers.
///
/// If the homeserver could be reached, but the user or device
/// was unknown, no failure is recorded. Instead, the corresponding
/// user or device is missing from the ``one_time_keys`` result.
static immer::map<std::string, JsonWrap> failures(Response r);
/// One-time keys for the queried devices. A map from user ID, to a
/// map from devices to a map from ``<algorithm>:<key_id>`` to the key object.
///
/// See the `key algorithms <#key-algorithms>`_ section for information
/// on the Key Object format.
static immer::map<std::string, immer::map<std::string, Variant>> oneTimeKeys(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(immer::map<std::string, immer::map<std::string, std::string>> oneTimeKeys, std::optional<int> timeout);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Query users with recent device key updates.
*
* Gets a list of users who have updated their device identity keys since a
* previous sync token.
*
* The server should include in the results any users who:
*
* * currently share a room with the calling user (ie, both users have
* membership state ``join``); *and*
* * added new device identity keys or removed an existing device with
* identity keys, between ``from`` and ``to``.
*/
class GetKeysChangesJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Query users with recent device key updates.
*
* \param from
* The desired start point of the list. Should be the ``next_batch`` field
* from a response to an earlier call to |/sync|. Users who have not
* uploaded new device identity keys since this point, nor deleted
* existing devices with identity keys since then, will be excluded
* from the results.
*
* \param to
* The desired end point of the list. Should be the ``next_batch``
* field from a recent call to |/sync| - typically the most recent
* such call. This may be used by the server as a hint to check its
* caches are up to date.
*/
explicit GetKeysChangesJob(std::string serverUrl
, std::string _accessToken
,
std::string from , std::string to );
// Result properties
/// The Matrix User IDs of all users who updated their device
/// identity keys.
static immer::array<std::string> changed(Response r);
/// The Matrix User IDs of all users who may have left all
/// the end-to-end encrypted rooms they previously shared
/// with the user.
static immer::array<std::string> left(Response r);
static BaseJob::Query buildQuery(
std::string from, std::string to);
static BaseJob::Body buildBody(std::string from, std::string to);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/login.hpp b/src/csapi/login.hpp
index 50e97e3..533ebf0 100644
--- a/src/csapi/login.hpp
+++ b/src/csapi/login.hpp
@@ -1,189 +1,191 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/wellknown/full.hpp"
#include "csapi/definitions/user_identifier.hpp"
namespace Kazv {
/*! \brief Get the supported login types to authenticate users
*
* Gets the homeserver's supported login types to authenticate users. Clients
* should pick one of these and supply it as the ``type`` when logging in.
*/
class GetLoginFlowsJob : public BaseJob {
public:
// Inner data structures
/// Gets the homeserver's supported login types to authenticate users. Clients
/// should pick one of these and supply it as the ``type`` when logging in.
struct LoginFlow
{
/// The login type. This is supplied as the ``type`` when
/// logging in.
std::string type;
};
// Construction/destruction
/// Get the supported login types to authenticate users
explicit GetLoginFlowsJob(std::string serverUrl
);
// Result properties
/// The homeserver's supported login types
static immer::array<LoginFlow> flows(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody();
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetLoginFlowsJob::LoginFlow> {
static void from_json(const json &jo, GetLoginFlowsJob::LoginFlow& result)
{
- result.type = jo.at("type"s);
+ if (jo.contains("type"s)) {
+ result.type = jo.at("type"s);
+ }
}
};
}
namespace Kazv
{
/*! \brief Authenticates the user.
*
* Authenticates the user, and issues an access token they can
* use to authorize themself in subsequent requests.
*
* If the client does not supply a ``device_id``, the server must
* auto-generate one.
*
* The returned access token must be associated with the ``device_id``
* supplied by the client or generated by the server. The server may
* invalidate any access token previously associated with that device. See
* `Relationship between access tokens and devices`_.
*/
class LoginJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Authenticates the user.
*
* \param type
* The login type being used.
*
* \param identifier
* Authenticates the user, and issues an access token they can
* use to authorize themself in subsequent requests.
*
* If the client does not supply a ``device_id``, the server must
* auto-generate one.
*
* The returned access token must be associated with the ``device_id``
* supplied by the client or generated by the server. The server may
* invalidate any access token previously associated with that device. See
* `Relationship between access tokens and devices`_.
*
* \param password
* Required when ``type`` is ``m.login.password``. The user's
* password.
*
* \param token
* Required when ``type`` is ``m.login.token``. Part of `Token-based`_ login.
*
* \param deviceId
* ID of the client device. If this does not correspond to a
* known client device, a new device will be created. The server
* will auto-generate a device_id if this is not specified.
*
* \param initialDeviceDisplayName
* A display name to assign to the newly-created device. Ignored
* if ``device_id`` corresponds to a known device.
*/
explicit LoginJob(std::string serverUrl
,
std::string type , std::optional<UserIdentifier> identifier = std::nullopt, std::string password = {}, std::string token = {}, std::string deviceId = {}, std::string initialDeviceDisplayName = {});
// Result properties
/// The fully-qualified Matrix ID for the account.
static std::string userId(Response r);
/// An access token for the account.
/// This access token can then be used to authorize other requests.
static std::string accessToken(Response r);
/// The server_name of the homeserver on which the account has
/// been registered.
///
/// **Deprecated**. Clients should extract the server_name from
/// ``user_id`` (by splitting at the first colon) if they require
/// it. Note also that ``homeserver`` is not spelt this way.
static std::string homeServer(Response r);
/// ID of the logged-in device. Will be the same as the
/// corresponding parameter in the request, if one was specified.
static std::string deviceId(Response r);
/// Optional client configuration provided by the server. If present,
/// clients SHOULD use the provided object to reconfigure themselves,
/// optionally validating the URLs within. This object takes the same
/// form as the one returned from .well-known autodiscovery.
static std::optional<DiscoveryInformation> wellKnown(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string type, std::optional<UserIdentifier> identifier, std::string password, std::string token, std::string deviceId, std::string initialDeviceDisplayName);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/notifications.hpp b/src/csapi/notifications.hpp
index ab9bf01..72f3b40 100644
--- a/src/csapi/notifications.hpp
+++ b/src/csapi/notifications.hpp
@@ -1,112 +1,124 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Gets a list of events that the user has been notified about
*
* This API is used to paginate through the list of events that the
* user has been, or would have been notified about.
*/
class GetNotificationsJob : public BaseJob {
public:
// Inner data structures
/// This API is used to paginate through the list of events that the
/// user has been, or would have been notified about.
struct Notification
{
/// The action(s) to perform when the conditions for this rule are met.
/// See `Push Rules: API`_.
immer::array<Variant> actions;
/// The Event object for the event that triggered the notification.
JsonWrap event;
/// The profile tag of the rule that matched this event.
std::string profileTag;
/// Indicates whether the user has sent a read receipt indicating
/// that they have read this message.
bool read;
/// The ID of the room in which the event was posted.
std::string roomId;
/// The unix timestamp at which the event notification was sent,
/// in milliseconds.
int ts;
};
// Construction/destruction
/*! \brief Gets a list of events that the user has been notified about
*
* \param from
* Pagination token given to retrieve the next set of events.
*
* \param limit
* Limit on the number of events to return in this request.
*
* \param only
* Allows basic filtering of events returned. Supply ``highlight``
* to return only events where the notification had the highlight
* tweak set.
*/
explicit GetNotificationsJob(std::string serverUrl
, std::string _accessToken
,
std::string from = {}, std::optional<int> limit = std::nullopt, std::string only = {});
// Result properties
/// The token to supply in the ``from`` param of the next
/// ``/notifications`` request in order to request more
/// events. If this is absent, there are no more results.
static std::string nextToken(Response r);
/// The list of events that triggered notifications.
static immer::array<Notification> notifications(Response r);
static BaseJob::Query buildQuery(
std::string from, std::optional<int> limit, std::string only);
static BaseJob::Body buildBody(std::string from, std::optional<int> limit, std::string only);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetNotificationsJob::Notification> {
static void from_json(const json &jo, GetNotificationsJob::Notification& result)
{
- result.actions = jo.at("actions"s);
- result.event = jo.at("event"s);
- result.profileTag = jo.at("profile_tag"s);
- result.read = jo.at("read"s);
- result.roomId = jo.at("room_id"s);
- result.ts = jo.at("ts"s);
+ if (jo.contains("actions"s)) {
+ result.actions = jo.at("actions"s);
+ }
+ if (jo.contains("event"s)) {
+ result.event = jo.at("event"s);
+ }
+ if (jo.contains("profile_tag"s)) {
+ result.profileTag = jo.at("profile_tag"s);
+ }
+ if (jo.contains("read"s)) {
+ result.read = jo.at("read"s);
+ }
+ if (jo.contains("room_id"s)) {
+ result.roomId = jo.at("room_id"s);
+ }
+ if (jo.contains("ts"s)) {
+ result.ts = jo.at("ts"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/old_sync.hpp b/src/csapi/old_sync.hpp
index ab848f0..4d13601 100644
--- a/src/csapi/old_sync.hpp
+++ b/src/csapi/old_sync.hpp
@@ -1,295 +1,315 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/event-schemas/schema/m.room.member.hpp"
namespace Kazv {
/*! \brief Listen on the event stream.
*
* This will listen for new events and return them to the caller. This will
* block until an event is received, or until the ``timeout`` is reached.
*
* This endpoint was deprecated in r0 of this specification. Clients
* should instead call the |/sync|_ API with a ``since`` parameter. See
* the `migration guide
* <https://matrix.org/docs/guides/client-server-migrating-from-v1.html#deprecated-endpoints>`_.
*/
class GetEventsJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Listen on the event stream.
*
* \param from
* The token to stream from. This token is either from a previous
* request to this API or from the initial sync API.
*
* \param timeout
* The maximum time in milliseconds to wait for an event.
*/
explicit GetEventsJob(std::string serverUrl
, std::string _accessToken
,
std::string from = {}, std::optional<int> timeout = std::nullopt);
// Result properties
/// A token which correlates to the first value in ``chunk``. This
/// is usually the same token supplied to ``from=``.
static std::string start(Response r);
/// A token which correlates to the last value in ``chunk``. This
/// token should be used in the next request to ``/events``.
static std::string end(Response r);
/// An array of events.
static EventList chunk(Response r);
static BaseJob::Query buildQuery(
std::string from, std::optional<int> timeout);
static BaseJob::Body buildBody(std::string from, std::optional<int> timeout);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Get the user's current state.
*
* This returns the full state for this user, with an optional limit on the
* number of messages per room to return.
*
* This endpoint was deprecated in r0 of this specification. Clients
* should instead call the |/sync|_ API with no ``since`` parameter. See
* the `migration guide
* <https://matrix.org/docs/guides/client-server-migrating-from-v1.html#deprecated-endpoints>`_.
*/
class InitialSyncJob : public BaseJob {
public:
// Inner data structures
/// The pagination chunk for this room.
struct PaginationChunk
{
/// A token which correlates to the first value in ``chunk``.
/// Used for pagination.
std::string start;
/// A token which correlates to the last value in ``chunk``.
/// Used for pagination.
std::string end;
/// If the user is a member of the room this will be a
/// list of the most recent messages for this room. If
/// the user has left the room this will be the
/// messages that preceeded them leaving. This array
/// will consist of at most ``limit`` elements.
EventList chunk;
};
/// This returns the full state for this user, with an optional limit on the
/// number of messages per room to return.
///
/// This endpoint was deprecated in r0 of this specification. Clients
/// should instead call the |/sync|_ API with no ``since`` parameter. See
/// the `migration guide
/// <https://matrix.org/docs/guides/client-server-migrating-from-v1.html#deprecated-endpoints>`_.
struct RoomInfo
{
/// The ID of this room.
std::string roomId;
/// The user's membership state in this room.
std::string membership;
/// The invite event if ``membership`` is ``invite``
std::optional<TheCurrentMembershipStateOfAUserInTheRoom> invite;
/// The pagination chunk for this room.
std::optional<PaginationChunk> messages;
/// If the user is a member of the room this will be the
/// current state of the room as a list of events. If the
/// user has left the room this will be the state of the
/// room when they left it.
EventList state;
/// Whether this room is visible to the ``/publicRooms`` API
/// or not."
std::string visibility;
/// The private data that this user has attached to
/// this room.
EventList accountData;
};
// Construction/destruction
/*! \brief Get the user's current state.
*
* \param limit
* The maximum number of messages to return for each room.
*
* \param archived
* Whether to include rooms that the user has left. If ``false`` then
* only rooms that the user has been invited to or has joined are
* included. If set to ``true`` then rooms that the user has left are
* included as well. By default this is ``false``.
*/
explicit InitialSyncJob(std::string serverUrl
, std::string _accessToken
,
std::optional<int> limit = std::nullopt, std::optional<bool> archived = std::nullopt);
// Result properties
/// A token which correlates to the last value in ``chunk``. This
/// token should be used with the ``/events`` API to listen for new
/// events.
static std::string end(Response r);
/// A list of presence events.
static EventList presence(Response r);
/// This returns the full state for this user, with an optional limit on the
/// number of messages per room to return.
///
/// This endpoint was deprecated in r0 of this specification. Clients
/// should instead call the |/sync|_ API with no ``since`` parameter. See
/// the `migration guide
/// <https://matrix.org/docs/guides/client-server-migrating-from-v1.html#deprecated-endpoints>`_.
static immer::array<RoomInfo> rooms(Response r);
/// The global private data created by this user.
static EventList accountData(Response r);
static BaseJob::Query buildQuery(
std::optional<int> limit, std::optional<bool> archived);
static BaseJob::Body buildBody(std::optional<int> limit, std::optional<bool> archived);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<InitialSyncJob::PaginationChunk> {
static void from_json(const json &jo, InitialSyncJob::PaginationChunk& result)
{
- result.start = jo.at("start"s);
- result.end = jo.at("end"s);
- result.chunk = jo.at("chunk"s);
+ if (jo.contains("start"s)) {
+ result.start = jo.at("start"s);
+ }
+ if (jo.contains("end"s)) {
+ result.end = jo.at("end"s);
+ }
+ if (jo.contains("chunk"s)) {
+ result.chunk = jo.at("chunk"s);
+ }
}
};
template<>
struct adl_serializer<InitialSyncJob::RoomInfo> {
static void from_json(const json &jo, InitialSyncJob::RoomInfo& result)
{
- result.roomId = jo.at("room_id"s);
- result.membership = jo.at("membership"s);
- result.invite = jo.at("invite"s);
- result.messages = jo.at("messages"s);
- result.state = jo.at("state"s);
- result.visibility = jo.at("visibility"s);
- result.accountData = jo.at("account_data"s);
+ if (jo.contains("room_id"s)) {
+ result.roomId = jo.at("room_id"s);
+ }
+ if (jo.contains("membership"s)) {
+ result.membership = jo.at("membership"s);
+ }
+ if (jo.contains("invite"s)) {
+ result.invite = jo.at("invite"s);
+ }
+ if (jo.contains("messages"s)) {
+ result.messages = jo.at("messages"s);
+ }
+ if (jo.contains("state"s)) {
+ result.state = jo.at("state"s);
+ }
+ if (jo.contains("visibility"s)) {
+ result.visibility = jo.at("visibility"s);
+ }
+ if (jo.contains("account_data"s)) {
+ result.accountData = jo.at("account_data"s);
+ }
}
};
}
namespace Kazv
{
/*! \brief Get a single event by event ID.
*
* Get a single event based on ``event_id``. You must have permission to
* retrieve this event e.g. by being a member in the room for this event.
*
* This endpoint was deprecated in r0 of this specification. Clients
* should instead call the |/rooms/{roomId}/event/{eventId}|_ API
* or the |/rooms/{roomId}/context/{eventId}|_ API.
*/
class GetOneEventJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Get a single event by event ID.
*
* \param eventId
* The event ID to get.
*/
explicit GetOneEventJob(std::string serverUrl
, std::string _accessToken
,
std::string eventId );
// Result properties
/// The full event.
static JsonWrap data(Response r)
{
return
std::move(jsonBody(r).get()).get<JsonWrap>()
;
}
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string eventId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/pusher.hpp b/src/csapi/pusher.hpp
index 6282475..f169c39 100644
--- a/src/csapi/pusher.hpp
+++ b/src/csapi/pusher.hpp
@@ -1,250 +1,270 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Gets the current pushers for the authenticated user
*
* Gets all currently active pushers for the authenticated user.
*/
class GetPushersJob : public BaseJob {
public:
// Inner data structures
/// A dictionary of information for the pusher implementation
/// itself.
struct PusherData
{
/// Required if ``kind`` is ``http``. The URL to use to send
/// notifications to.
std::string url;
/// The format to use when sending notifications to the Push
/// Gateway.
std::string format;
};
/// Gets all currently active pushers for the authenticated user.
struct Pusher
{
/// This is a unique identifier for this pusher. See ``/set`` for
/// more detail.
/// Max length, 512 bytes.
std::string pushkey;
/// The kind of pusher. ``"http"`` is a pusher that
/// sends HTTP pokes.
std::string kind;
/// This is a reverse-DNS style identifier for the application.
/// Max length, 64 chars.
std::string appId;
/// A string that will allow the user to identify what application
/// owns this pusher.
std::string appDisplayName;
/// A string that will allow the user to identify what device owns
/// this pusher.
std::string deviceDisplayName;
/// This string determines which set of device specific rules this
/// pusher executes.
std::string profileTag;
/// The preferred language for receiving notifications (e.g. 'en'
/// or 'en-US')
std::string lang;
/// A dictionary of information for the pusher implementation
/// itself.
PusherData data;
};
// Construction/destruction
/// Gets the current pushers for the authenticated user
explicit GetPushersJob(std::string serverUrl
, std::string _accessToken
);
// Result properties
/// An array containing the current pushers for the user
static immer::array<Pusher> pushers(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody();
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetPushersJob::PusherData> {
static void from_json(const json &jo, GetPushersJob::PusherData& result)
{
- result.url = jo.at("url"s);
- result.format = jo.at("format"s);
+ if (jo.contains("url"s)) {
+ result.url = jo.at("url"s);
+ }
+ if (jo.contains("format"s)) {
+ result.format = jo.at("format"s);
+ }
}
};
template<>
struct adl_serializer<GetPushersJob::Pusher> {
static void from_json(const json &jo, GetPushersJob::Pusher& result)
{
- result.pushkey = jo.at("pushkey"s);
- result.kind = jo.at("kind"s);
- result.appId = jo.at("app_id"s);
- result.appDisplayName = jo.at("app_display_name"s);
- result.deviceDisplayName = jo.at("device_display_name"s);
- result.profileTag = jo.at("profile_tag"s);
- result.lang = jo.at("lang"s);
- result.data = jo.at("data"s);
+ if (jo.contains("pushkey"s)) {
+ result.pushkey = jo.at("pushkey"s);
+ }
+ if (jo.contains("kind"s)) {
+ result.kind = jo.at("kind"s);
+ }
+ if (jo.contains("app_id"s)) {
+ result.appId = jo.at("app_id"s);
+ }
+ if (jo.contains("app_display_name"s)) {
+ result.appDisplayName = jo.at("app_display_name"s);
+ }
+ if (jo.contains("device_display_name"s)) {
+ result.deviceDisplayName = jo.at("device_display_name"s);
+ }
+ if (jo.contains("profile_tag"s)) {
+ result.profileTag = jo.at("profile_tag"s);
+ }
+ if (jo.contains("lang"s)) {
+ result.lang = jo.at("lang"s);
+ }
+ if (jo.contains("data"s)) {
+ result.data = jo.at("data"s);
+ }
}
};
}
namespace Kazv
{
/*! \brief Modify a pusher for this user on the homeserver.
*
* This endpoint allows the creation, modification and deletion of `pushers`_
* for this user ID. The behaviour of this endpoint varies depending on the
* values in the JSON body.
*/
class PostPusherJob : public BaseJob {
public:
// Inner data structures
/// A dictionary of information for the pusher implementation
/// itself. If ``kind`` is ``http``, this should contain ``url``
/// which is the URL to use to send notifications to.
struct PusherData
{
/// Required if ``kind`` is ``http``. The URL to use to send
/// notifications to. MUST be an HTTPS URL with a path of
/// ``/_matrix/push/v1/notify``.
std::string url;
/// The format to send notifications in to Push Gateways if the
/// ``kind`` is ``http``. The details about what fields the
/// homeserver should send to the push gateway are defined in the
/// `Push Gateway Specification`_. Currently the only format
/// available is 'event_id_only'.
std::string format;
};
// Construction/destruction
/*! \brief Modify a pusher for this user on the homeserver.
*
* \param pushkey
* This is a unique identifier for this pusher. The value you
* should use for this is the routing or destination address
* information for the notification, for example, the APNS token
* for APNS or the Registration ID for GCM. If your notification
* client has no such concept, use any unique identifier.
* Max length, 512 bytes.
*
* If the ``kind`` is ``"email"``, this is the email address to
* send notifications to.
*
* \param kind
* The kind of pusher to configure. ``"http"`` makes a pusher that
* sends HTTP pokes. ``"email"`` makes a pusher that emails the
* user with unread notifications. ``null`` deletes the pusher.
*
* \param appId
* This is a reverse-DNS style identifier for the application.
* It is recommended that this end with the platform, such that
* different platform versions get different app identifiers.
* Max length, 64 chars.
*
* If the ``kind`` is ``"email"``, this is ``"m.email"``.
*
* \param appDisplayName
* A string that will allow the user to identify what application
* owns this pusher.
*
* \param deviceDisplayName
* A string that will allow the user to identify what device owns
* this pusher.
*
* \param lang
* The preferred language for receiving notifications (e.g. 'en'
* or 'en-US').
*
* \param data
* A dictionary of information for the pusher implementation
* itself. If ``kind`` is ``http``, this should contain ``url``
* which is the URL to use to send notifications to.
*
* \param profileTag
* This string determines which set of device specific rules this
* pusher executes.
*
* \param append
* If true, the homeserver should add another pusher with the
* given pushkey and App ID in addition to any others with
* different user IDs. Otherwise, the homeserver must remove any
* other pushers with the same App ID and pushkey for different
* users. The default is ``false``.
*/
explicit PostPusherJob(std::string serverUrl
, std::string _accessToken
,
std::string pushkey , std::string kind , std::string appId , std::string appDisplayName , std::string deviceDisplayName , std::string lang , PusherData data , std::string profileTag = {}, std::optional<bool> append = std::nullopt);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string pushkey, std::string kind, std::string appId, std::string appDisplayName, std::string deviceDisplayName, std::string lang, PusherData data, std::string profileTag, std::optional<bool> append);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<PostPusherJob::PusherData> {
static void to_json(json& jo, const PostPusherJob::PusherData &pod)
{
addToJsonIfNeeded(jo, "url"s, pod.url);
addToJsonIfNeeded(jo, "format"s, pod.format);
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/room_initial_sync.hpp b/src/csapi/room_initial_sync.hpp
index a7338de..d4536e3 100644
--- a/src/csapi/room_initial_sync.hpp
+++ b/src/csapi/room_initial_sync.hpp
@@ -1,119 +1,125 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Snapshot the current state of a room and its most recent messages.
*
* Get a copy of the current state and the most recent messages in a room.
*
* This endpoint was deprecated in r0 of this specification. There is no
* direct replacement; the relevant information is returned by the
* |/sync|_ API. See the `migration guide
* <https://matrix.org/docs/guides/client-server-migrating-from-v1.html#deprecated-endpoints>`_.
*/
class RoomInitialSyncJob : public BaseJob {
public:
// Inner data structures
/// The pagination chunk for this room.
struct PaginationChunk
{
/// A token which correlates to the first value in ``chunk``.
/// Used for pagination.
std::string start;
/// A token which correlates to the last value in ``chunk``.
/// Used for pagination.
std::string end;
/// If the user is a member of the room this will be a
/// list of the most recent messages for this room. If
/// the user has left the room this will be the
/// messages that preceeded them leaving. This array
/// will consist of at most ``limit`` elements.
EventList chunk;
};
// Construction/destruction
/*! \brief Snapshot the current state of a room and its most recent messages.
*
* \param roomId
* The room to get the data.
*/
explicit RoomInitialSyncJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId );
// Result properties
/// The ID of this room.
static std::string roomId(Response r);
/// The user's membership state in this room.
static std::string membership(Response r);
/// The pagination chunk for this room.
static std::optional<PaginationChunk> messages(Response r);
/// If the user is a member of the room this will be the
/// current state of the room as a list of events. If the
/// user has left the room this will be the state of the
/// room when they left it.
static EventList state(Response r);
/// Whether this room is visible to the ``/publicRooms`` API
/// or not."
static std::string visibility(Response r);
/// The private data that this user has attached to this room.
static EventList accountData(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string roomId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RoomInitialSyncJob::PaginationChunk> {
static void from_json(const json &jo, RoomInitialSyncJob::PaginationChunk& result)
{
- result.start = jo.at("start"s);
- result.end = jo.at("end"s);
- result.chunk = jo.at("chunk"s);
+ if (jo.contains("start"s)) {
+ result.start = jo.at("start"s);
+ }
+ if (jo.contains("end"s)) {
+ result.end = jo.at("end"s);
+ }
+ if (jo.contains("chunk"s)) {
+ result.chunk = jo.at("chunk"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/rooms.hpp b/src/csapi/rooms.hpp
index ca44e11..b95ab89 100644
--- a/src/csapi/rooms.hpp
+++ b/src/csapi/rooms.hpp
@@ -1,308 +1,312 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/event-schemas/schema/m.room.member.hpp"
namespace Kazv {
/*! \brief Get a single event by event ID.
*
* Get a single event based on ``roomId/eventId``. You must have permission to
* retrieve this event e.g. by being a member in the room for this event.
*/
class GetOneRoomEventJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Get a single event by event ID.
*
* \param roomId
* The ID of the room the event is in.
*
* \param eventId
* The event ID to get.
*/
explicit GetOneRoomEventJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId , std::string eventId );
// Result properties
/// The full event.
static JsonWrap data(Response r)
{
return
std::move(jsonBody(r).get()).get<JsonWrap>()
;
}
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string roomId, std::string eventId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Get the state identified by the type and key.
*
* .. For backwards compatibility with older links...
* .. _`get-matrix-client-r0-rooms-roomid-state-eventtype`:
*
* Looks up the contents of a state event in a room. If the user is
* joined to the room then the state is taken from the current
* state of the room. If the user has left the room then the state is
* taken from the state of the room when they left.
*/
class GetRoomStateWithKeyJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Get the state identified by the type and key.
*
* \param roomId
* The room to look up the state in.
*
* \param eventType
* The type of state to look up.
*
* \param stateKey
* The key of the state to look up. Defaults to an empty string. When
* an empty string, the trailing slash on this endpoint is optional.
*/
explicit GetRoomStateWithKeyJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId , std::string eventType , std::string stateKey );
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string roomId, std::string eventType, std::string stateKey);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Get all state events in the current state of a room.
*
* Get the state events for the current state of a room.
*/
class GetRoomStateJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Get all state events in the current state of a room.
*
* \param roomId
* The room to look up the state for.
*/
explicit GetRoomStateJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId );
// Result properties
/// The current state of the room
static EventList data(Response r)
{
return
std::move(jsonBody(r).get()).get<EventList>()
;
}
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string roomId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Get the m.room.member events for the room.
*
* Get the list of members for this room.
*/
class GetMembersByRoomJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Get the m.room.member events for the room.
*
* \param roomId
* The room to get the member events for.
*
* \param at
* The point in time (pagination token) to return members for in the room.
* This token can be obtained from a ``prev_batch`` token returned for
* each room by the sync API. Defaults to the current state of the room,
* as determined by the server.
*
* \param membership
* The kind of membership to filter for. Defaults to no filtering if
* unspecified. When specified alongside ``not_membership``, the two
* parameters create an 'or' condition: either the membership *is*
* the same as ``membership`` **or** *is not* the same as ``not_membership``.
*
* \param notMembership
* The kind of membership to exclude from the results. Defaults to no
* filtering if unspecified.
*/
explicit GetMembersByRoomJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId , std::string at = {}, std::string membership = {}, std::string notMembership = {});
// Result properties
/// Get the list of members for this room.
static immer::array<TheCurrentMembershipStateOfAUserInTheRoom> chunk(Response r);
static BaseJob::Query buildQuery(
std::string at, std::string membership, std::string notMembership);
static BaseJob::Body buildBody(std::string roomId, std::string at, std::string membership, std::string notMembership);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Gets the list of currently joined users and their profile data.
*
* This API returns a map of MXIDs to member info objects for members of the room. The current user must be in the room for it to work, unless it is an Application Service in which case any of the AS's users must be in the room. This API is primarily for Application Services and should be faster to respond than ``/members`` as it can be implemented more efficiently on the server.
*/
class GetJoinedMembersByRoomJob : public BaseJob {
public:
// Inner data structures
/// This API returns a map of MXIDs to member info objects for members of the room. The current user must be in the room for it to work, unless it is an Application Service in which case any of the AS's users must be in the room. This API is primarily for Application Services and should be faster to respond than ``/members`` as it can be implemented more efficiently on the server.
struct RoomMember
{
/// The display name of the user this object is representing.
std::string displayName;
/// The mxc avatar url of the user this object is representing.
std::string avatarUrl;
};
// Construction/destruction
/*! \brief Gets the list of currently joined users and their profile data.
*
* \param roomId
* The room to get the members of.
*/
explicit GetJoinedMembersByRoomJob(std::string serverUrl
, std::string _accessToken
,
std::string roomId );
// Result properties
/// A map from user ID to a RoomMember object.
static immer::map<std::string, RoomMember> joined(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string roomId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetJoinedMembersByRoomJob::RoomMember> {
static void from_json(const json &jo, GetJoinedMembersByRoomJob::RoomMember& result)
{
- result.displayName = jo.at("display_name"s);
- result.avatarUrl = jo.at("avatar_url"s);
+ if (jo.contains("display_name"s)) {
+ result.displayName = jo.at("display_name"s);
+ }
+ if (jo.contains("avatar_url"s)) {
+ result.avatarUrl = jo.at("avatar_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/search.hpp b/src/csapi/search.hpp
index e79646f..aa41ec8 100644
--- a/src/csapi/search.hpp
+++ b/src/csapi/search.hpp
@@ -1,373 +1,413 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/room_event_filter.hpp"
namespace Kazv {
/*! \brief Perform a server-side search.
*
* Performs a full text search across different categories.
*/
class SearchJob : public BaseJob {
public:
// Inner data structures
/// Configures whether any context for the events
/// returned are included in the response.
struct IncludeEventContext
{
/// How many events before the result are
/// returned. By default, this is ``5``.
std::optional<int> beforeLimit;
/// How many events after the result are
/// returned. By default, this is ``5``.
std::optional<int> afterLimit;
/// Requests that the server returns the
/// historic profile information for the users
/// that sent the events that were returned.
/// By default, this is ``false``.
std::optional<bool> includeProfile;
};
/// Configuration for group.
struct Group
{
/// Key that defines the group.
std::string key;
};
/// Requests that the server partitions the result set
/// based on the provided list of keys.
struct Groupings
{
/// List of groups to request.
immer::array<Group> groupBy;
};
/// Mapping of category name to search criteria.
struct RoomEventsCriteria
{
/// The string to search events for
std::string searchTerm;
/// The keys to search. Defaults to all.
immer::array<std::string> keys;
/// This takes a `filter`_.
RoomEventFilter filter;
/// The order in which to search for results.
/// By default, this is ``"rank"``.
std::string orderBy;
/// Configures whether any context for the events
/// returned are included in the response.
std::optional<IncludeEventContext> eventContext;
/// Requests the server return the current state for
/// each room returned.
std::optional<bool> includeState;
/// Requests that the server partitions the result set
/// based on the provided list of keys.
std::optional<Groupings> groupings;
};
/// Describes which categories to search in and their criteria.
struct Categories
{
/// Mapping of category name to search criteria.
std::optional<RoomEventsCriteria> roomEvents;
};
/// Performs a full text search across different categories.
struct UserProfile
{
/// Performs a full text search across different categories.
std::string displayname;
/// Performs a full text search across different categories.
std::string avatarUrl;
};
/// Context for result, if requested.
struct EventContext
{
/// Pagination token for the start of the chunk
std::string start;
/// Pagination token for the end of the chunk
std::string end;
/// The historic profile information of the
/// users that sent the events returned.
///
/// The ``string`` key is the user ID for which
/// the profile belongs to.
immer::map<std::string, UserProfile> profileInfo;
/// Events just before the result.
EventList eventsBefore;
/// Events just after the result.
EventList eventsAfter;
};
/// The result object.
struct Result
{
/// A number that describes how closely this result matches the search. Higher is closer.
std::optional<double> rank;
/// The event that matched.
JsonWrap result;
/// Context for result, if requested.
std::optional<EventContext> context;
};
/// The results for a particular group value.
struct GroupValue
{
/// Token that can be used to get the next batch
/// of results in the group, by passing as the
/// `next_batch` parameter to the next call. If
/// this field is absent, there are no more
/// results in this group.
std::string nextBatch;
/// Key that can be used to order different
/// groups.
std::optional<int> order;
/// Which results are in this group.
immer::array<std::string> results;
};
/// Mapping of category name to search criteria.
struct ResultRoomEvents
{
/// An approximate count of the total number of results found.
std::optional<int> count;
/// List of words which should be highlighted, useful for stemming which may change the query terms.
immer::array<std::string> highlights;
/// List of results in the requested order.
immer::array<Result> results;
/// The current state for every room in the results.
/// This is included if the request had the
/// ``include_state`` key set with a value of ``true``.
///
/// The ``string`` key is the room ID for which the ``State
/// Event`` array belongs to.
immer::map<std::string, EventList> state;
/// Any groups that were requested.
///
/// The outer ``string`` key is the group key requested (eg: ``room_id``
/// or ``sender``). The inner ``string`` key is the grouped value (eg:
/// a room's ID or a user's ID).
immer::map<std::string, immer::map<std::string, GroupValue>> groups;
/// Token that can be used to get the next batch of
/// results, by passing as the `next_batch` parameter to
/// the next call. If this field is absent, there are no
/// more results.
std::string nextBatch;
};
/// Describes which categories to search in and their criteria.
struct ResultCategories
{
/// Mapping of category name to search criteria.
std::optional<ResultRoomEvents> roomEvents;
};
// Construction/destruction
/*! \brief Perform a server-side search.
*
* \param searchCategories
* Describes which categories to search in and their criteria.
*
* \param nextBatch
* The point to return events from. If given, this should be a
* ``next_batch`` result from a previous call to this endpoint.
*/
explicit SearchJob(std::string serverUrl
, std::string _accessToken
,
Categories searchCategories , std::string nextBatch = {});
// Result properties
/// Describes which categories to search in and their criteria.
static ResultCategories searchCategories(Response r);
static BaseJob::Query buildQuery(
std::string nextBatch);
static BaseJob::Body buildBody(Categories searchCategories, std::string nextBatch);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<SearchJob::IncludeEventContext> {
static void to_json(json& jo, const SearchJob::IncludeEventContext &pod)
{
addToJsonIfNeeded(jo, "before_limit"s, pod.beforeLimit);
addToJsonIfNeeded(jo, "after_limit"s, pod.afterLimit);
addToJsonIfNeeded(jo, "include_profile"s, pod.includeProfile);
}
};
template<>
struct adl_serializer<SearchJob::Group> {
static void to_json(json& jo, const SearchJob::Group &pod)
{
addToJsonIfNeeded(jo, "key"s, pod.key);
}
};
template<>
struct adl_serializer<SearchJob::Groupings> {
static void to_json(json& jo, const SearchJob::Groupings &pod)
{
addToJsonIfNeeded(jo, "group_by"s, pod.groupBy);
}
};
template<>
struct adl_serializer<SearchJob::RoomEventsCriteria> {
static void to_json(json& jo, const SearchJob::RoomEventsCriteria &pod)
{
jo["search_term"s] = pod.searchTerm;
addToJsonIfNeeded(jo, "keys"s, pod.keys);
addToJsonIfNeeded(jo, "filter"s, pod.filter);
addToJsonIfNeeded(jo, "order_by"s, pod.orderBy);
addToJsonIfNeeded(jo, "event_context"s, pod.eventContext);
addToJsonIfNeeded(jo, "include_state"s, pod.includeState);
addToJsonIfNeeded(jo, "groupings"s, pod.groupings);
}
};
template<>
struct adl_serializer<SearchJob::Categories> {
static void to_json(json& jo, const SearchJob::Categories &pod)
{
addToJsonIfNeeded(jo, "room_events"s, pod.roomEvents);
}
};
template<>
struct adl_serializer<SearchJob::UserProfile> {
static void from_json(const json &jo, SearchJob::UserProfile& result)
{
- result.displayname = jo.at("displayname"s);
- result.avatarUrl = jo.at("avatar_url"s);
+ if (jo.contains("displayname"s)) {
+ result.displayname = jo.at("displayname"s);
+ }
+ if (jo.contains("avatar_url"s)) {
+ result.avatarUrl = jo.at("avatar_url"s);
+ }
}
};
template<>
struct adl_serializer<SearchJob::EventContext> {
static void from_json(const json &jo, SearchJob::EventContext& result)
{
- result.start = jo.at("start"s);
- result.end = jo.at("end"s);
- result.profileInfo = jo.at("profile_info"s);
- result.eventsBefore = jo.at("events_before"s);
- result.eventsAfter = jo.at("events_after"s);
+ if (jo.contains("start"s)) {
+ result.start = jo.at("start"s);
+ }
+ if (jo.contains("end"s)) {
+ result.end = jo.at("end"s);
+ }
+ if (jo.contains("profile_info"s)) {
+ result.profileInfo = jo.at("profile_info"s);
+ }
+ if (jo.contains("events_before"s)) {
+ result.eventsBefore = jo.at("events_before"s);
+ }
+ if (jo.contains("events_after"s)) {
+ result.eventsAfter = jo.at("events_after"s);
+ }
}
};
template<>
struct adl_serializer<SearchJob::Result> {
static void from_json(const json &jo, SearchJob::Result& result)
{
- result.rank = jo.at("rank"s);
- result.result = jo.at("result"s);
- result.context = jo.at("context"s);
+ if (jo.contains("rank"s)) {
+ result.rank = jo.at("rank"s);
+ }
+ if (jo.contains("result"s)) {
+ result.result = jo.at("result"s);
+ }
+ if (jo.contains("context"s)) {
+ result.context = jo.at("context"s);
+ }
}
};
template<>
struct adl_serializer<SearchJob::GroupValue> {
static void from_json(const json &jo, SearchJob::GroupValue& result)
{
- result.nextBatch = jo.at("next_batch"s);
- result.order = jo.at("order"s);
- result.results = jo.at("results"s);
+ if (jo.contains("next_batch"s)) {
+ result.nextBatch = jo.at("next_batch"s);
+ }
+ if (jo.contains("order"s)) {
+ result.order = jo.at("order"s);
+ }
+ if (jo.contains("results"s)) {
+ result.results = jo.at("results"s);
+ }
}
};
template<>
struct adl_serializer<SearchJob::ResultRoomEvents> {
static void from_json(const json &jo, SearchJob::ResultRoomEvents& result)
{
- result.count = jo.at("count"s);
- result.highlights = jo.at("highlights"s);
- result.results = jo.at("results"s);
- result.state = jo.at("state"s);
- result.groups = jo.at("groups"s);
- result.nextBatch = jo.at("next_batch"s);
+ if (jo.contains("count"s)) {
+ result.count = jo.at("count"s);
+ }
+ if (jo.contains("highlights"s)) {
+ result.highlights = jo.at("highlights"s);
+ }
+ if (jo.contains("results"s)) {
+ result.results = jo.at("results"s);
+ }
+ if (jo.contains("state"s)) {
+ result.state = jo.at("state"s);
+ }
+ if (jo.contains("groups"s)) {
+ result.groups = jo.at("groups"s);
+ }
+ if (jo.contains("next_batch"s)) {
+ result.nextBatch = jo.at("next_batch"s);
+ }
}
};
template<>
struct adl_serializer<SearchJob::ResultCategories> {
static void from_json(const json &jo, SearchJob::ResultCategories& result)
{
- result.roomEvents = jo.at("room_events"s);
+ if (jo.contains("room_events"s)) {
+ result.roomEvents = jo.at("room_events"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/sync.hpp b/src/csapi/sync.hpp
index 09e1ee0..9f8762b 100644
--- a/src/csapi/sync.hpp
+++ b/src/csapi/sync.hpp
@@ -1,433 +1,471 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
#include "csapi/definitions/event-schemas/schema/stripped_state.hpp"
#include "csapi/definitions/event_batch.hpp"
#include "csapi/definitions/timeline_batch.hpp"
#include "csapi/definitions/state_event_batch.hpp"
namespace Kazv {
/*! \brief Synchronise the client's state and receive new messages.
*
* Synchronise the client's state with the latest state on the server.
* Clients use this API when they first log in to get an initial snapshot
* of the state on the server, and then continue to call this API to get
* incremental deltas to the state, and to receive new messages.
*
* *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_
* for more information. Lazy-loading members is only supported on a ``StateFilter``
* for this endpoint. When lazy-loading is enabled, servers MUST include the
* syncing user's own membership event when they join a room, or when the
* full state of rooms is requested, to aid discovering the user's avatar &
* displayname.
*
* Like other members, the user's own membership event is eligible
* for being considered redundant by the server. When a sync is ``limited``,
* the server MUST return membership events for events in the gap
* (between ``since`` and the start of the returned timeline), regardless
* as to whether or not they are redundant. This ensures that joins/leaves
* and profile changes which occur during the gap are not lost.
*/
class SyncJob : public BaseJob {
public:
// Inner data structures
/// Information about the room which clients may need to
/// correctly render it to users.
struct RoomSummary
{
/// The users which can be used to generate a room name
/// if the room does not have one. Required if the room's
/// ``m.room.name`` or ``m.room.canonical_alias`` state events
/// are unset or empty.
///
/// This should be the first 5 members of the room, ordered
/// by stream ordering, which are joined or invited. The
/// list must never include the client's own user ID. When
/// no joined or invited members are available, this should
/// consist of the banned and left users. More than 5 members
/// may be provided, however less than 5 should only be provided
/// when there are less than 5 members to represent.
///
/// When lazy-loading room members is enabled, the membership
/// events for the heroes MUST be included in the ``state``,
/// unless they are redundant. When the list of users changes,
/// the server notifies the client by sending a fresh list of
/// heroes. If there are no changes since the last sync, this
/// field may be omitted.
immer::array<std::string> mHeroes;
/// The number of users with ``membership`` of ``join``,
/// including the client's own user ID. If this field has
/// not changed since the last sync, it may be omitted.
/// Required otherwise.
std::optional<int> mJoinedMemberCount;
/// The number of users with ``membership`` of ``invite``.
/// If this field has not changed since the last sync, it
/// may be omitted. Required otherwise.
std::optional<int> mInvitedMemberCount;
};
/// Counts of unread notifications for this room. See the
/// `Receiving notifications section <#receiving-notifications>`_
/// for more information on how these are calculated.
struct UnreadNotificationCounts
{
/// The number of unread notifications for this room with the highlight flag set
std::optional<int> highlightCount;
/// The total number of unread notifications for this room
std::optional<int> notificationCount;
};
/// Synchronise the client's state with the latest state on the server.
/// Clients use this API when they first log in to get an initial snapshot
/// of the state on the server, and then continue to call this API to get
/// incremental deltas to the state, and to receive new messages.
///
/// *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_
/// for more information. Lazy-loading members is only supported on a ``StateFilter``
/// for this endpoint. When lazy-loading is enabled, servers MUST include the
/// syncing user's own membership event when they join a room, or when the
/// full state of rooms is requested, to aid discovering the user's avatar &
/// displayname.
///
/// Like other members, the user's own membership event is eligible
/// for being considered redundant by the server. When a sync is ``limited``,
/// the server MUST return membership events for events in the gap
/// (between ``since`` and the start of the returned timeline), regardless
/// as to whether or not they are redundant. This ensures that joins/leaves
/// and profile changes which occur during the gap are not lost.
struct JoinedRoom
{
/// Information about the room which clients may need to
/// correctly render it to users.
std::optional<RoomSummary> summary;
/// Updates to the state, between the time indicated by
/// the ``since`` parameter, and the start of the
/// ``timeline`` (or all state up to the start of the
/// ``timeline``, if ``since`` is not given, or
/// ``full_state`` is true).
///
/// N.B. state updates for ``m.room.member`` events will
/// be incomplete if ``lazy_load_members`` is enabled in
/// the ``/sync`` filter, and only return the member events
/// required to display the senders of the timeline events
/// in this response.
std::optional<StateEventBatch> state;
/// The timeline of messages and state changes in the
/// room.
Timeline timeline;
/// The ephemeral events in the room that aren't
/// recorded in the timeline or state of the room.
/// e.g. typing.
std::optional<EventBatch> ephemeral;
/// The private data that this user has attached to
/// this room.
std::optional<EventBatch> accountData;
/// Counts of unread notifications for this room. See the
/// `Receiving notifications section <#receiving-notifications>`_
/// for more information on how these are calculated.
std::optional<UnreadNotificationCounts> unreadNotifications;
};
/// The state of a room that the user has been invited
/// to. These state events may only have the ``sender``,
/// ``type``, ``state_key`` and ``content`` keys
/// present. These events do not replace any state that
/// the client already has for the room, for example if
/// the client has archived the room. Instead the
/// client should keep two separate copies of the
/// state: the one from the ``invite_state`` and one
/// from the archived ``state``. If the client joins
/// the room then the current state will be given as a
/// delta against the archived ``state`` not the
/// ``invite_state``.
struct InviteState
{
/// The StrippedState events that form the invite state.
immer::array<StrippedState> events;
};
/// Synchronise the client's state with the latest state on the server.
/// Clients use this API when they first log in to get an initial snapshot
/// of the state on the server, and then continue to call this API to get
/// incremental deltas to the state, and to receive new messages.
///
/// *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_
/// for more information. Lazy-loading members is only supported on a ``StateFilter``
/// for this endpoint. When lazy-loading is enabled, servers MUST include the
/// syncing user's own membership event when they join a room, or when the
/// full state of rooms is requested, to aid discovering the user's avatar &
/// displayname.
///
/// Like other members, the user's own membership event is eligible
/// for being considered redundant by the server. When a sync is ``limited``,
/// the server MUST return membership events for events in the gap
/// (between ``since`` and the start of the returned timeline), regardless
/// as to whether or not they are redundant. This ensures that joins/leaves
/// and profile changes which occur during the gap are not lost.
struct InvitedRoom
{
/// The state of a room that the user has been invited
/// to. These state events may only have the ``sender``,
/// ``type``, ``state_key`` and ``content`` keys
/// present. These events do not replace any state that
/// the client already has for the room, for example if
/// the client has archived the room. Instead the
/// client should keep two separate copies of the
/// state: the one from the ``invite_state`` and one
/// from the archived ``state``. If the client joins
/// the room then the current state will be given as a
/// delta against the archived ``state`` not the
/// ``invite_state``.
std::optional<InviteState> inviteState;
};
/// Synchronise the client's state with the latest state on the server.
/// Clients use this API when they first log in to get an initial snapshot
/// of the state on the server, and then continue to call this API to get
/// incremental deltas to the state, and to receive new messages.
///
/// *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_
/// for more information. Lazy-loading members is only supported on a ``StateFilter``
/// for this endpoint. When lazy-loading is enabled, servers MUST include the
/// syncing user's own membership event when they join a room, or when the
/// full state of rooms is requested, to aid discovering the user's avatar &
/// displayname.
///
/// Like other members, the user's own membership event is eligible
/// for being considered redundant by the server. When a sync is ``limited``,
/// the server MUST return membership events for events in the gap
/// (between ``since`` and the start of the returned timeline), regardless
/// as to whether or not they are redundant. This ensures that joins/leaves
/// and profile changes which occur during the gap are not lost.
struct LeftRoom
{
/// The state updates for the room up to the start of the timeline.
std::optional<StateEventBatch> state;
/// The timeline of messages and state changes in the
/// room up to the point when the user left.
Timeline timeline;
/// The private data that this user has attached to
/// this room.
std::optional<EventBatch> accountData;
};
/// Updates to rooms.
struct Rooms
{
/// The rooms that the user has joined, mapped as room ID to
/// room information.
immer::map<std::string, JoinedRoom> join;
/// The rooms that the user has been invited to, mapped as room ID to
/// room information.
immer::map<std::string, InvitedRoom> invite;
/// The rooms that the user has left or been banned from, mapped as room ID to
/// room information.
immer::map<std::string, LeftRoom> leave;
};
// Construction/destruction
/*! \brief Synchronise the client's state and receive new messages.
*
* \param filter
* The ID of a filter created using the filter API or a filter JSON
* object encoded as a string. The server will detect whether it is
* an ID or a JSON object by whether the first character is a ``"{"``
* open brace. Passing the JSON inline is best suited to one off
* requests. Creating a filter using the filter API is recommended for
* clients that reuse the same filter multiple times, for example in
* long poll requests.
*
* See `Filtering <#filtering>`_ for more information.
*
* \param since
* A point in time to continue a sync from.
*
* \param fullState
* Controls whether to include the full state for all rooms the user
* is a member of.
*
* If this is set to ``true``, then all state events will be returned,
* even if ``since`` is non-empty. The timeline will still be limited
* by the ``since`` parameter. In this case, the ``timeout`` parameter
* will be ignored and the query will return immediately, possibly with
* an empty timeline.
*
* If ``false``, and ``since`` is non-empty, only state which has
* changed since the point indicated by ``since`` will be returned.
*
* By default, this is ``false``.
*
* \param setPresence
* Controls whether the client is automatically marked as online by
* polling this API. If this parameter is omitted then the client is
* automatically marked as online when it uses this API. Otherwise if
* the parameter is set to "offline" then the client is not marked as
* being online when it uses this API. When set to "unavailable", the
* client is marked as being idle.
*
* \param timeout
* The maximum time to wait, in milliseconds, before returning this
* request. If no events (or other data) become available before this
* time elapses, the server will return a response with empty fields.
*
* By default, this is ``0``, so the server will return immediately
* even if the response is empty.
*/
explicit SyncJob(std::string serverUrl
, std::string _accessToken
,
std::string filter = {}, std::string since = {}, std::optional<bool> fullState = std::nullopt, std::string setPresence = {}, std::optional<int> timeout = std::nullopt);
// Result properties
/// The batch token to supply in the ``since`` param of the next
/// ``/sync`` request.
static std::string nextBatch(Response r);
/// Updates to rooms.
static std::optional<Rooms> rooms(Response r);
/// The updates to the presence status of other users.
static std::optional<EventBatch> presence(Response r);
/// The global private data created by this user.
static std::optional<EventBatch> accountData(Response r);
/// Information on the send-to-device messages for the client
/// device, as defined in |send_to_device_sync|_.
static JsonWrap toDevice(Response r);
/// Information on end-to-end device updates, as specified in
/// |device_lists_sync|_.
static JsonWrap deviceLists(Response r);
/// Information on end-to-end encryption keys, as specified
/// in |device_lists_sync|_.
static immer::map<std::string, int> deviceOneTimeKeysCount(Response r);
static BaseJob::Query buildQuery(
std::string filter, std::string since, std::optional<bool> fullState, std::string setPresence, std::optional<int> timeout);
static BaseJob::Body buildBody(std::string filter, std::string since, std::optional<bool> fullState, std::string setPresence, std::optional<int> timeout);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<SyncJob::RoomSummary> {
static void from_json(const json &jo, SyncJob::RoomSummary& result)
{
- result.mHeroes = jo.at("m.heroes"s);
- result.mJoinedMemberCount = jo.at("m.joined_member_count"s);
- result.mInvitedMemberCount = jo.at("m.invited_member_count"s);
+ if (jo.contains("m.heroes"s)) {
+ result.mHeroes = jo.at("m.heroes"s);
+ }
+ if (jo.contains("m.joined_member_count"s)) {
+ result.mJoinedMemberCount = jo.at("m.joined_member_count"s);
+ }
+ if (jo.contains("m.invited_member_count"s)) {
+ result.mInvitedMemberCount = jo.at("m.invited_member_count"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::UnreadNotificationCounts> {
static void from_json(const json &jo, SyncJob::UnreadNotificationCounts& result)
{
- result.highlightCount = jo.at("highlight_count"s);
- result.notificationCount = jo.at("notification_count"s);
+ if (jo.contains("highlight_count"s)) {
+ result.highlightCount = jo.at("highlight_count"s);
+ }
+ if (jo.contains("notification_count"s)) {
+ result.notificationCount = jo.at("notification_count"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::JoinedRoom> {
static void from_json(const json &jo, SyncJob::JoinedRoom& result)
{
- result.summary = jo.at("summary"s);
- result.state = jo.at("state"s);
- result.timeline = jo.at("timeline"s);
- result.ephemeral = jo.at("ephemeral"s);
- result.accountData = jo.at("account_data"s);
- result.unreadNotifications = jo.at("unread_notifications"s);
+ if (jo.contains("summary"s)) {
+ result.summary = jo.at("summary"s);
+ }
+ if (jo.contains("state"s)) {
+ result.state = jo.at("state"s);
+ }
+ if (jo.contains("timeline"s)) {
+ result.timeline = jo.at("timeline"s);
+ }
+ if (jo.contains("ephemeral"s)) {
+ result.ephemeral = jo.at("ephemeral"s);
+ }
+ if (jo.contains("account_data"s)) {
+ result.accountData = jo.at("account_data"s);
+ }
+ if (jo.contains("unread_notifications"s)) {
+ result.unreadNotifications = jo.at("unread_notifications"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::InviteState> {
static void from_json(const json &jo, SyncJob::InviteState& result)
{
- result.events = jo.at("events"s);
+ if (jo.contains("events"s)) {
+ result.events = jo.at("events"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::InvitedRoom> {
static void from_json(const json &jo, SyncJob::InvitedRoom& result)
{
- result.inviteState = jo.at("invite_state"s);
+ if (jo.contains("invite_state"s)) {
+ result.inviteState = jo.at("invite_state"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::LeftRoom> {
static void from_json(const json &jo, SyncJob::LeftRoom& result)
{
- result.state = jo.at("state"s);
- result.timeline = jo.at("timeline"s);
- result.accountData = jo.at("account_data"s);
+ if (jo.contains("state"s)) {
+ result.state = jo.at("state"s);
+ }
+ if (jo.contains("timeline"s)) {
+ result.timeline = jo.at("timeline"s);
+ }
+ if (jo.contains("account_data"s)) {
+ result.accountData = jo.at("account_data"s);
+ }
}
};
template<>
struct adl_serializer<SyncJob::Rooms> {
static void from_json(const json &jo, SyncJob::Rooms& result)
{
- result.join = jo.at("join"s);
- result.invite = jo.at("invite"s);
- result.leave = jo.at("leave"s);
+ if (jo.contains("join"s)) {
+ result.join = jo.at("join"s);
+ }
+ if (jo.contains("invite"s)) {
+ result.invite = jo.at("invite"s);
+ }
+ if (jo.contains("leave"s)) {
+ result.leave = jo.at("leave"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/tags.hpp b/src/csapi/tags.hpp
index 98fd245..17f653a 100644
--- a/src/csapi/tags.hpp
+++ b/src/csapi/tags.hpp
@@ -1,185 +1,187 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief List the tags for a room.
*
* List the tags set by a user on a room.
*/
class GetRoomTagsJob : public BaseJob {
public:
// Inner data structures
/// List the tags set by a user on a room.
struct Tag
{
/// A number in a range ``[0,1]`` describing a relative
/// position of the room under the given tag.
std::optional<float> order;
/// List the tags set by a user on a room.
JsonWrap additionalProperties;
};
// Construction/destruction
/*! \brief List the tags for a room.
*
* \param userId
* The id of the user to get tags for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
* The ID of the room to get tags for.
*/
explicit GetRoomTagsJob(std::string serverUrl
, std::string _accessToken
,
std::string userId , std::string roomId );
// Result properties
/// List the tags set by a user on a room.
static immer::map<std::string, Tag> tags(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string userId, std::string roomId);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<GetRoomTagsJob::Tag> {
static void from_json(const json &jo, GetRoomTagsJob::Tag& result)
{
- result.order = jo.at("order"s);
+ if (jo.contains("order"s)) {
+ result.order = jo.at("order"s);
+ }
result.additionalProperties = jo;
}
};
}
namespace Kazv
{
/*! \brief Add a tag to a room.
*
* Add a tag to the room.
*/
class SetRoomTagJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Add a tag to a room.
*
* \param userId
* The id of the user to add a tag for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
* The ID of the room to add a tag to.
*
* \param tag
* The tag to add.
*
* \param order
* A number in a range ``[0,1]`` describing a relative
* position of the room under the given tag.
*
* \param additionalProperties
* Add a tag to the room.
*/
explicit SetRoomTagJob(std::string serverUrl
, std::string _accessToken
,
std::string userId , std::string roomId , std::string tag , std::optional<float> order = std::nullopt, JsonWrap additionalProperties = {});
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string userId, std::string roomId, std::string tag, std::optional<float> order, JsonWrap additionalProperties);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
/*! \brief Remove a tag from the room.
*
* Remove a tag from the room.
*/
class DeleteRoomTagJob : public BaseJob {
public:
// Construction/destruction
/*! \brief Remove a tag from the room.
*
* \param userId
* The id of the user to remove a tag for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
* The ID of the room to remove a tag from.
*
* \param tag
* The tag to remove.
*/
explicit DeleteRoomTagJob(std::string serverUrl
, std::string _accessToken
,
std::string userId , std::string roomId , std::string tag );
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string userId, std::string roomId, std::string tag);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/csapi/users.hpp b/src/csapi/users.hpp
index 7a25017..ec87b7f 100644
--- a/src/csapi/users.hpp
+++ b/src/csapi/users.hpp
@@ -1,109 +1,115 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "basejob.hpp"
namespace Kazv {
/*! \brief Searches the user directory.
*
* Performs a search for users. The homeserver may
* determine which subset of users are searched, however the homeserver
* MUST at a minimum consider the users the requesting user shares a
* room with and those who reside in public rooms (known to the homeserver).
* The search MUST consider local users to the homeserver, and SHOULD
* query remote users as part of the search.
*
* The search is performed case-insensitively on user IDs and display
* names preferably using a collation determined based upon the
* ``Accept-Language`` header provided in the request, if present.
*/
class SearchUserDirectoryJob : public BaseJob {
public:
// Inner data structures
/// Performs a search for users. The homeserver may
/// determine which subset of users are searched, however the homeserver
/// MUST at a minimum consider the users the requesting user shares a
/// room with and those who reside in public rooms (known to the homeserver).
/// The search MUST consider local users to the homeserver, and SHOULD
/// query remote users as part of the search.
///
/// The search is performed case-insensitively on user IDs and display
/// names preferably using a collation determined based upon the
/// ``Accept-Language`` header provided in the request, if present.
struct User
{
/// The user's matrix user ID.
std::string userId;
/// The display name of the user, if one exists.
std::string displayName;
/// The avatar url, as an MXC, if one exists.
std::string avatarUrl;
};
// Construction/destruction
/*! \brief Searches the user directory.
*
* \param searchTerm
* The term to search for
*
* \param limit
* The maximum number of results to return. Defaults to 10.
*/
explicit SearchUserDirectoryJob(std::string serverUrl
, std::string _accessToken
,
std::string searchTerm , std::optional<int> limit = std::nullopt);
// Result properties
/// Ordered by rank and then whether or not profile info is available.
static immer::array<User> results(Response r);
/// Indicates if the result list has been truncated by the limit.
static bool limited(Response r);
static BaseJob::Query buildQuery(
);
static BaseJob::Body buildBody(std::string searchTerm, std::optional<int> limit);
static bool success(Response r);
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<SearchUserDirectoryJob::User> {
static void from_json(const json &jo, SearchUserDirectoryJob::User& result)
{
- result.userId = jo.at("user_id"s);
- result.displayName = jo.at("display_name"s);
- result.avatarUrl = jo.at("avatar_url"s);
+ if (jo.contains("user_id"s)) {
+ result.userId = jo.at("user_id"s);
+ }
+ if (jo.contains("display_name"s)) {
+ result.displayName = jo.at("display_name"s);
+ }
+ if (jo.contains("avatar_url"s)) {
+ result.avatarUrl = jo.at("avatar_url"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/examples/basic/main.cpp b/src/examples/basic/main.cpp
index f2aaea0..8d301c3 100644
--- a/src/examples/basic/main.cpp
+++ b/src/examples/basic/main.cpp
@@ -1,34 +1,39 @@
#include <string>
#include <iostream>
#include <lager/store.hpp>
-#include <lager/event_loop/manual.hpp>
+#include <lager/event_loop/boost_asio.hpp>
+#include <boost/asio.hpp>
#include <client/client.hpp>
#include <job/cprjobhandler.hpp>
using namespace std::string_literals;
int main()
{
- Kazv::Descendent<Kazv::JobInterface> jobHandler(Kazv::CprJobHandler{});
+ boost::asio::io_context ioContext;
+
+ Kazv::Descendent<Kazv::JobInterface> jobHandler(Kazv::CprJobHandler{ioContext.get_executor()});
auto store = lager::make_store<Kazv::Client::Action>(
Kazv::Client{},
&Kazv::Client::update,
- lager::with_manual_event_loop{},
+ lager::with_boost_asio_event_loop{ioContext.get_executor()},
lager::with_deps(std::ref(*jobHandler.data())));
std::string homeserver;
std::string username;
std::string password;
std::cout << "Homeserver: ";
std::getline(std::cin, homeserver);
std::cout << "Username: ";
std::getline(std::cin, username);
std::cout << "Password: ";
std::getline(std::cin, password);
store.dispatch(Kazv::Client::LoginAction{homeserver, username, password, "libkazv basic example"s});
- std::cout << "Token: " << store.get().token << std::endl;
+
+ ioContext.run();
+ std::cout << "Token: " << store.get().token << std::endl;
}
diff --git a/src/identity/definitions/request_email_validation.hpp b/src/identity/definitions/request_email_validation.hpp
index 30bb221..fdfef8d 100644
--- a/src/identity/definitions/request_email_validation.hpp
+++ b/src/identity/definitions/request_email_validation.hpp
@@ -1,73 +1,81 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct RequestEmailValidation
{
/// A unique string generated by the client, and used to identify the
/// validation attempt. It must be a string consisting of the characters
/// ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
/// must not be empty.
std::string clientSecret;
/// The email address to validate.
std::string email;
/// The server will only send an email if the ``send_attempt``
/// is a number greater than the most recent one which it has seen,
/// scoped to that ``email`` + ``client_secret`` pair. This is to
/// avoid repeatedly sending the same email in the case of request
/// retries between the POSTing user and the identity server.
/// The client should increment this value if they desire a new
/// email (e.g. a reminder) to be sent. If they do not, the server
/// should respond with success but not resend the email.
int sendAttempt;
/// Optional. When the validation is completed, the identity server will
/// redirect the user to this URL. This option is ignored when submitting
/// 3PID validation information through a POST request.
std::string nextLink;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RequestEmailValidation> {
static void to_json(json& jo, const RequestEmailValidation &pod)
{
jo["client_secret"s] = pod.clientSecret;
jo["email"s] = pod.email;
jo["send_attempt"s] = pod.sendAttempt;
addToJsonIfNeeded(jo, "next_link"s, pod.nextLink);
}
static void from_json(const json &jo, RequestEmailValidation& result)
{
- result.clientSecret = jo.at("client_secret"s);
- result.email = jo.at("email"s);
- result.sendAttempt = jo.at("send_attempt"s);
- result.nextLink = jo.at("next_link"s);
+ if (jo.contains("client_secret"s)) {
+ result.clientSecret = jo.at("client_secret"s);
+ }
+ if (jo.contains("email"s)) {
+ result.email = jo.at("email"s);
+ }
+ if (jo.contains("send_attempt"s)) {
+ result.sendAttempt = jo.at("send_attempt"s);
+ }
+ if (jo.contains("next_link"s)) {
+ result.nextLink = jo.at("next_link"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/identity/definitions/request_msisdn_validation.hpp b/src/identity/definitions/request_msisdn_validation.hpp
index 6a61f44..4d2dcd6 100644
--- a/src/identity/definitions/request_msisdn_validation.hpp
+++ b/src/identity/definitions/request_msisdn_validation.hpp
@@ -1,79 +1,89 @@
/******************************************************************************
* THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
*/
#pragma once
#include "types.hpp"
namespace Kazv {
struct RequestMsisdnValidation
{
/// A unique string generated by the client, and used to identify the
/// validation attempt. It must be a string consisting of the characters
/// ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
/// must not be empty.
std::string clientSecret;
/// The two-letter uppercase ISO-3166-1 alpha-2 country code that the
/// number in ``phone_number`` should be parsed as if it were dialled from.
std::string country;
/// The phone number to validate.
std::string phoneNumber;
/// The server will only send an SMS if the ``send_attempt`` is a
/// number greater than the most recent one which it has seen,
/// scoped to that ``country`` + ``phone_number`` + ``client_secret``
/// triple. This is to avoid repeatedly sending the same SMS in
/// the case of request retries between the POSTing user and the
/// identity server. The client should increment this value if
/// they desire a new SMS (e.g. a reminder) to be sent.
int sendAttempt;
/// Optional. When the validation is completed, the identity server will
/// redirect the user to this URL. This option is ignored when submitting
/// 3PID validation information through a POST request.
std::string nextLink;
};
}
namespace nlohmann
{
using namespace Kazv;
template<>
struct adl_serializer<RequestMsisdnValidation> {
static void to_json(json& jo, const RequestMsisdnValidation &pod)
{
jo["client_secret"s] = pod.clientSecret;
jo["country"s] = pod.country;
jo["phone_number"s] = pod.phoneNumber;
jo["send_attempt"s] = pod.sendAttempt;
addToJsonIfNeeded(jo, "next_link"s, pod.nextLink);
}
static void from_json(const json &jo, RequestMsisdnValidation& result)
{
- result.clientSecret = jo.at("client_secret"s);
- result.country = jo.at("country"s);
- result.phoneNumber = jo.at("phone_number"s);
- result.sendAttempt = jo.at("send_attempt"s);
- result.nextLink = jo.at("next_link"s);
+ if (jo.contains("client_secret"s)) {
+ result.clientSecret = jo.at("client_secret"s);
+ }
+ if (jo.contains("country"s)) {
+ result.country = jo.at("country"s);
+ }
+ if (jo.contains("phone_number"s)) {
+ result.phoneNumber = jo.at("phone_number"s);
+ }
+ if (jo.contains("send_attempt"s)) {
+ result.sendAttempt = jo.at("send_attempt"s);
+ }
+ if (jo.contains("next_link"s)) {
+ result.nextLink = jo.at("next_link"s);
+ }
}
};
}
namespace Kazv
{
} // namespace Kazv
diff --git a/src/job/cprjobhandler.cpp b/src/job/cprjobhandler.cpp
index 9fb9d9b..693e987 100644
--- a/src/job/cprjobhandler.cpp
+++ b/src/job/cprjobhandler.cpp
@@ -1,60 +1,75 @@
#include <cpr/cpr.h>
#include "cprjobhandler.hpp"
namespace Kazv
{
+ CprJobHandler::CprJobHandler(boost::asio::io_context::executor_type executor)
+ : executor(std::move(executor))
+ {
+ }
+
CprJobHandler::~CprJobHandler() = default;
- std::future<BaseJob::Response> CprJobHandler::fetch(const BaseJob &job)
+ void CprJobHandler::async(std::function<void()> func)
+ {
+ std::thread([func=std::move(func), guard=boost::asio::executor_work_guard(executor)]() {
+ func();
+ }).detach();
+ }
+
+ void CprJobHandler::fetch(const BaseJob &job, std::function<void(std::shared_future<BaseJob::Response>)> userCallback)
{
cpr::Url url{job.url()};
cpr::Body body(job.requestBody());
BaseJob::Header origHeader = job.requestHeader();
cpr::Header header(origHeader.get().begin(), origHeader.get().end());
cpr::Parameters params;
BaseJob::Query query = job.requestQuery();
BaseJob::ReturnType returnType = job.returnType();
BaseJob::Method method = job.requestMethod();
if (! query.empty()) {
// from cpr/parameters.cpp
cpr::CurlHolder holder;
for (const auto kv : query) {
std::string key = kv.first;
std::string value = kv.second;
params.AddParameter(cpr::Parameter(std::move(key), std::move(value)), holder);
}
}
auto callback = [returnType](cpr::Response r) -> BaseJob::Response {
BaseJob::Body body = r.text;
if (returnType == BaseJob::ReturnType::Json) {
try {
body = BaseJob::JsonBody(std::move(json::parse(r.text)));
} catch (const json::exception &) {
// the response is not valid json
}
}
return { r.status_code, body, BaseJob::Header(r.header.begin(), r.header.end()) };
};
- return std::visit(lager::visitor{
+ std::shared_future<BaseJob::Response> res = std::visit(lager::visitor{
[=](BaseJob::Get) {
return cpr::GetCallback(callback, url, header, body, params);
},
[=](BaseJob::Post) {
return cpr::PostCallback(callback, url, header, body, params);
},
[=](BaseJob::Put) {
return cpr::PutCallback(callback, url, header, body, params);
},
[=](BaseJob::Delete) {
return cpr::DeleteCallback(callback, url, header, body, params);
}
- }, method);
+ }, method).share();
+ async([=]() {
+ userCallback(res);
+ });
}
}
diff --git a/src/job/cprjobhandler.hpp b/src/job/cprjobhandler.hpp
index f3537f8..208f2ad 100644
--- a/src/job/cprjobhandler.hpp
+++ b/src/job/cprjobhandler.hpp
@@ -1,13 +1,19 @@
#pragma once
+#include <boost/asio.hpp>
#include "jobinterface.hpp"
namespace Kazv
{
struct CprJobHandler : public JobInterface
{
+ CprJobHandler(boost::asio::io_context::executor_type executor);
~CprJobHandler() override;
- std::future<BaseJob::Response> fetch(const BaseJob &job) override;
+ void async(std::function<void()> func) override;
+ void fetch(const BaseJob &job,
+ std::function<void(std::shared_future<BaseJob::Response>)> callback) override;
+ private:
+ boost::asio::io_context::executor_type executor;
};
}
diff --git a/src/job/jobinterface.hpp b/src/job/jobinterface.hpp
index 38643cb..4cd1139 100644
--- a/src/job/jobinterface.hpp
+++ b/src/job/jobinterface.hpp
@@ -1,13 +1,18 @@
#pragma once
+#include <functional>
+
#include "basejob.hpp"
namespace Kazv
{
struct JobInterface
{
virtual ~JobInterface() = default;
- virtual std::future<BaseJob::Response> fetch(const BaseJob &job) = 0;
+ virtual void async(std::function<void()> func) = 0;
+ /// makes an async fetch.
+ /// callback will not block the current thread.
+ virtual void fetch(const BaseJob &job, std::function<void(std::shared_future<BaseJob::Response>)> callback) = 0;
};
}
diff --git a/src/tests/basejobtest.cpp b/src/tests/basejobtest.cpp
index 911c2b3..c56be9f 100644
--- a/src/tests/basejobtest.cpp
+++ b/src/tests/basejobtest.cpp
@@ -1,28 +1,34 @@
#include <catch2/catch.hpp>
#include <iostream>
#include <future>
#include <job/basejob.hpp>
#include <job/cprjobhandler.hpp>
#include "tests.hpp"
using namespace Kazv;
TEST_CASE("Base job should fetch correctly", "[basejob]")
{
+ boost::asio::io_context ioContext;
BaseJob job(TEST_SERVER_URL, "/.well-known/matrix/client", BaseJob::Get{});
- CprJobHandler h;
- auto futureResponse = h.fetch(job);
- BaseJob::Response r = futureResponse.get();
- if (r.statusCode == 200) {
- REQUIRE( BaseJob::isBodyJson(r.body) );
+ CprJobHandler h(ioContext.get_executor());
+ h.fetch(
+ job,
+ [](auto futureResponse) {
+ BaseJob::Response r = futureResponse.get();
- json j = std::get<BaseJob::JsonBody>(r.body).get();
+ if (r.statusCode == 200) {
+ REQUIRE( BaseJob::isBodyJson(r.body) );
- REQUIRE_NOTHROW( (j["m.homeserver"]["base_url"]) );
- REQUIRE( (j["m.homeserver"]["base_url"].size() > 0) );
- }
+ json j = std::get<BaseJob::JsonBody>(r.body).get();
+
+ REQUIRE_NOTHROW( (j["m.homeserver"]["base_url"]) );
+ REQUIRE( (j["m.homeserver"]["base_url"].size() > 0) );
+ }
+ });
+ ioContext.run();
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 19, 1:15 AM (19 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1763955
Default Alt Text
(221 KB)

Event Timeline