#include "ShipLayoutBlueprintSerializer.h" #include #include #include "toml.hpp" #include "Rotation.h" namespace { std::string rotationToString(Rotation r) { switch (r) { case Rotation::North: return "north"; case Rotation::East: return "east"; case Rotation::South: return "south"; case Rotation::West: return "west"; } return "north"; } Rotation parseRotation(const std::string& s) { if (s == "east") { return Rotation::East; } if (s == "south") { return Rotation::South; } if (s == "west") { return Rotation::West; } return Rotation::North; } } // namespace namespace ShipLayoutBlueprintSerializer { std::string serialize(const std::vector& blueprints) { toml::array bpArr; for (const ShipLayoutBlueprint& bp : blueprints) { toml::array modArr; for (const PlacedModule& pm : bp.modules) { toml::table modTbl; modTbl.insert("type", pm.moduleId); modTbl.insert("x", static_cast(pm.position.x())); modTbl.insert("y", static_cast(pm.position.y())); modTbl.insert("rotation", rotationToString(pm.rotation)); modArr.push_back(std::move(modTbl)); } toml::table bpTbl; bpTbl.insert("name", bp.name.toStdString()); bpTbl.insert("ship_type", bp.shipType); bpTbl.insert("modules", std::move(modArr)); bpArr.push_back(std::move(bpTbl)); } toml::table root; root.insert("blueprint", std::move(bpArr)); std::ostringstream oss; oss << root; return oss.str(); } std::vector deserialize(const std::string& tomlContent) { toml::table root; try { root = toml::parse(tomlContent); } catch (const toml::parse_error& e) { std::ostringstream msg; msg << "TOML parse error: " << e.description() << " at " << e.source().begin; throw std::runtime_error(msg.str()); } std::vector result; const toml::array* bpArr = root["blueprint"].as_array(); if (!bpArr) { return result; } for (std::size_t i = 0; i < bpArr->size(); ++i) { const toml::table* bpTbl = (*bpArr)[i].as_table(); if (!bpTbl) { continue; } const std::optional name = (*bpTbl)["name"].value(); const std::optional shipType = (*bpTbl)["ship_type"].value(); if (!name || name->empty() || !shipType || shipType->empty()) { continue; } ShipLayoutBlueprint bp; bp.name = QString::fromStdString(*name); bp.shipType = *shipType; const toml::array* modArr = (*bpTbl)["modules"].as_array(); if (modArr) { for (std::size_t j = 0; j < modArr->size(); ++j) { const toml::table* modTbl = (*modArr)[j].as_table(); if (!modTbl) { continue; } const std::optional type = (*modTbl)["type"].value(); const std::optional x = (*modTbl)["x"].value(); const std::optional y = (*modTbl)["y"].value(); const std::optional rotStr = (*modTbl)["rotation"].value(); if (!type || !x || !y || !rotStr) { continue; } PlacedModule pm; pm.moduleId = *type; pm.position = QPoint(static_cast(*x), static_cast(*y)); pm.rotation = parseRotation(*rotStr); bp.modules.push_back(std::move(pm)); } } result.push_back(std::move(bp)); } return result; } } // namespace ShipLayoutBlueprintSerializer