/* * Copyright (C) 2024 Petr Mironychev * * This file is part of QodeAssist. * * QodeAssist is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * QodeAssist is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with QodeAssist. If not, see . */ #include "ChatSerializer.hpp" #include "Logger.hpp" #include #include #include #include namespace QodeAssist::Chat { const QString ChatSerializer::VERSION = "0.1"; SerializationResult ChatSerializer::saveToFile(const ChatModel *model, const QString &filePath) { if (!ensureDirectoryExists(filePath)) { return {false, "Failed to create directory structure"}; } QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { return {false, QString("Failed to open file for writing: %1").arg(filePath)}; } QJsonObject root = serializeChat(model); QJsonDocument doc(root); if (file.write(doc.toJson(QJsonDocument::Indented)) == -1) { return {false, QString("Failed to write to file: %1").arg(file.errorString())}; } return {true, QString()}; } SerializationResult ChatSerializer::loadFromFile(ChatModel *model, const QString &filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { return {false, QString("Failed to open file for reading: %1").arg(filePath)}; } QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error); if (error.error != QJsonParseError::NoError) { return {false, QString("JSON parse error: %1").arg(error.errorString())}; } QJsonObject root = doc.object(); QString version = root["version"].toString(); if (!validateVersion(version)) { return {false, QString("Unsupported version: %1").arg(version)}; } if (!deserializeChat(model, root)) { return {false, "Failed to deserialize chat data"}; } return {true, QString()}; } QJsonObject ChatSerializer::serializeMessage(const ChatModel::Message &message) { QJsonObject messageObj; messageObj["role"] = static_cast(message.role); messageObj["content"] = message.content; messageObj["id"] = message.id; return messageObj; } ChatModel::Message ChatSerializer::deserializeMessage(const QJsonObject &json) { ChatModel::Message message; message.role = static_cast(json["role"].toInt()); message.content = json["content"].toString(); message.id = json["id"].toString(); return message; } QJsonObject ChatSerializer::serializeChat(const ChatModel *model) { QJsonArray messagesArray; for (const auto &message : model->getChatHistory()) { messagesArray.append(serializeMessage(message)); } QJsonObject root; root["version"] = VERSION; root["messages"] = messagesArray; return root; } bool ChatSerializer::deserializeChat(ChatModel *model, const QJsonObject &json) { QJsonArray messagesArray = json["messages"].toArray(); QVector messages; messages.reserve(messagesArray.size()); for (const auto &messageValue : messagesArray) { messages.append(deserializeMessage(messageValue.toObject())); } model->clear(); for (const auto &message : messages) { model->addMessage(message.content, message.role, message.id); } return true; } bool ChatSerializer::ensureDirectoryExists(const QString &filePath) { QFileInfo fileInfo(filePath); QDir dir = fileInfo.dir(); return dir.exists() || dir.mkpath("."); } bool ChatSerializer::validateVersion(const QString &version) { return version == VERSION; } } // namespace QodeAssist::Chat