diff options
Diffstat (limited to 'server-v1/source/EpistmoolServer/Protocol/Command.cpp')
-rw-r--r-- | server-v1/source/EpistmoolServer/Protocol/Command.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/server-v1/source/EpistmoolServer/Protocol/Command.cpp b/server-v1/source/EpistmoolServer/Protocol/Command.cpp new file mode 100644 index 0000000..a108e0e --- /dev/null +++ b/server-v1/source/EpistmoolServer/Protocol/Command.cpp @@ -0,0 +1,200 @@ +#include "Command.hpp" + +#include <QJsonObject> +#include <QMetaEnum> +#include <array> + +using namespace Epistmool::Server; + +namespace { +auto kKindTraits = []() { + using enum ProtocolMessage::Kind; + std::array<ProtocolMessage::KindTrait, static_cast<size_t>(KindCOUNT)> array; + + array[SessionAuth] = { .isC2S = true, .hasReply = true }; + array[SessionDestroy] = { .isC2S = true, .hasReply = true }; + + array[WorkspaceCreate] = { .isC2S = true, .hasReply = true }; + array[WorkspaceOpen] = { .isC2S = true, .hasReply = true }; + array[WorkspaceFetchIndex] = { .isC2S = true, .hasReply = true }; + + array[WorkspaceFetchKnowledge] = { .isC2S = true, .hasReply = true }; + array[WorkspaceUpdateKnowledge] = { .isC2S = true, .hasReply = true }; + array[WorkspaceCreateKnowledge] = { .isC2S = true, .hasReply = true }; + array[WorkspaceDeleteKnowledge] = { .isC2S = true, .hasReply = true }; + + array[WorkspaceFetchKeyword] = { .isC2S = true, .hasReply = true }; + array[WorkspaceUpdateKeyword] = { .isC2S = true, .hasReply = true }; + array[WorkspaceCreateKeyword] = { .isC2S = true, .hasReply = true }; + array[WorkspaceDeleteKeyword] = { .isC2S = true, .hasReply = true }; + + array[NotificationWorkspaceUpdated] = { .isC2S = false, .hasReply = false }; + array[NotificationKnowledgeUpdated] = { .isC2S = false, .hasReply = false }; + + return array; +}(); +} + +std::unique_ptr<ProtocolRequest> ProtocolMessage::createRequest(Kind kind) +{ + switch(kind) { + case SessionAuth: return std::make_unique<ProtocolRequest_SessionAuth>(); + case SessionDestroy: return nullptr; + + case WorkspaceCreate: return nullptr; + case WorkspaceOpen: return nullptr; + case WorkspaceFetchIndex: return nullptr; + + case WorkspaceFetchKnowledge: return nullptr; + case WorkspaceUpdateKnowledge: return nullptr; + case WorkspaceCreateKnowledge: return nullptr; + case WorkspaceDeleteKnowledge: return nullptr; + + case WorkspaceFetchKeyword: return nullptr; + case WorkspaceUpdateKeyword: return nullptr; + case WorkspaceCreateKeyword: return nullptr; + case WorkspaceDeleteKeyword: return nullptr; + + case NotificationWorkspaceUpdated: return nullptr; + case NotificationKnowledgeUpdated: return nullptr; + + default: return nullptr; + } +} + +std::unique_ptr<ProtocolReply> ProtocolMessage::createReply(Kind kind) +{ + switch(kind) { + case SessionAuth: return std::make_unique<ProtocolReply_SessionAuth>(); + case SessionDestroy: return nullptr; + + case WorkspaceCreate: return nullptr; + case WorkspaceOpen: return nullptr; + case WorkspaceFetchIndex: return nullptr; + + case WorkspaceFetchKnowledge: return nullptr; + case WorkspaceUpdateKnowledge: return nullptr; + case WorkspaceCreateKnowledge: return nullptr; + case WorkspaceDeleteKnowledge: return nullptr; + + case WorkspaceFetchKeyword: return nullptr; + case WorkspaceUpdateKeyword: return nullptr; + case WorkspaceCreateKeyword: return nullptr; + case WorkspaceDeleteKeyword: return nullptr; + + case NotificationWorkspaceUpdated: return nullptr; + case NotificationKnowledgeUpdated: return nullptr; + + default: return nullptr; + } +} + +const ProtocolMessage::KindTrait& ProtocolMessage::getKindTrait(Kind kind) +{ + return kKindTraits[kind]; +} + +ProtocolMessage::ProtocolMessage(Kind kind, Variant variant) + : kind{ kind } + , variant{ variant } +{ +} + +ProtocolRequest::ProtocolRequest(Kind kind) + : ProtocolMessage(kind, RequestVariant) +{ +} + +QJsonObject ProtocolRequest::serialize(const ProtocolRequest& msg) +{ + QJsonObject object; + object.insert("method", QMetaEnum::fromType<Kind>().valueToKey(msg.kind)); + + QJsonObject fields; + msg.serializeFields(fields); + + return object; +} + +std::unique_ptr<ProtocolRequest> ProtocolRequest::deserialize(const QJsonObject& object) +{ + bool ok; + auto methodName = object.value("method").toString().toStdString(); + auto method = static_cast<Kind>(QMetaEnum::fromType<Kind>().keysToValue(methodName.c_str(), &ok)); + if (!ok) return nullptr; + + auto msg = createRequest(method); + + auto fieldsVal = object.value("fields"); + if (!fieldsVal.isObject()) return nullptr; + msg->deserializeFields(fieldsVal.toObject()); + + return msg; +} + +ProtocolReply::ProtocolReply(Kind kind) + : ProtocolMessage(kind, ReplyVariant) +{ +} + +QJsonObject ProtocolReply::serialize(const ProtocolReply& msg) +{ + QJsonObject object; + object.insert("method", QMetaEnum::fromType<Kind>().valueToKey(msg.kind)); + object.insert("sequence", msg.sequence); + + QJsonObject fields; + msg.serializeFields(fields); + + return object; +} + +std::unique_ptr<ProtocolReply> ProtocolReply::deserialize(const QJsonObject& object) +{ + bool ok; + auto methodName = object.value("method").toString().toStdString(); + auto method = static_cast<Kind>(QMetaEnum::fromType<Kind>().keysToValue(methodName.c_str(), &ok)); + if (!ok) return nullptr; + + auto msg = createReply(method); + + msg->sequence = object.value("sequence").toInt(-1); + + auto fieldsVal = object.value("fields"); + if (!fieldsVal.isObject()) return nullptr; + msg->deserializeFields(fieldsVal.toObject()); + + return msg; +} + +ProtocolRequest_SessionAuth::ProtocolRequest_SessionAuth() + : ProtocolRequest(SessionAuth) {} + +void ProtocolRequest_SessionAuth::serializeFields(QJsonObject& object) const +{ + ProtocolRequest::serializeFields(object); + object.insert("session", theSession); + object.insert("createIfInvalid", createIfInvalid); +} + +void ProtocolRequest_SessionAuth::deserializeFields(const QJsonObject& object) +{ + ProtocolRequest::deserializeFields(object); + theSession = object.value("session").toInt(); + createIfInvalid = object.value("createIfInvalid").toBool(); +} + +ProtocolReply_SessionAuth::ProtocolReply_SessionAuth() + : ProtocolReply(SessionAuth) {} + +void ProtocolReply_SessionAuth::serializeFields(QJsonObject& object) const +{ + ProtocolReply::serializeFields(object); + object.insert("session", theSession); +} + +void ProtocolReply_SessionAuth::deserializeFields(const QJsonObject& object) +{ + ProtocolReply::deserializeFields(object); + theSession = object.value("session").toInt(); +} |