// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "Item2JsonSerializer.hpp" #include "visitor/ItemNode.hpp" #include "visitor/DepthFirstItemTree.hpp" #include "ItemDataNames.hpp" #include using namespace gui; void Item2JsonSerializer::handleSibling(gui::ItemNode &node, prototype &doc, int &level) { node.getItem().accept(visitor); doc[level].emplace_back(json11::Json::object{{visitor.moveName(), visitor.moveState()}}); } void Item2JsonSerializer::handleParent(gui::ItemNode &node, prototype &doc, int &level) { auto parentLevel = node.getLevel(); auto children = json11::Json::array{}; while (!doc[level].empty()) { auto &&child = doc[level].front(); children.emplace_back(std::move(child)); doc[level].pop_front(); } doc[level].clear(); level = parentLevel; node.getItem().accept(visitor); auto parent = visitor.moveState(); parent.emplace(magic_enum::enum_name(visitor::Names::Children), std::move(children)); doc[level].emplace_back(json11::Json::object{{visitor.moveName(), std::move(parent)}}); } void Item2JsonSerializer::handleOther(gui::ItemNode &node, prototype &doc, int &level) { level = node.getLevel(); doc[level] = std::list{}; node.getItem().accept(visitor); doc[level].emplace_back(json11::Json::object{{visitor.moveName(), visitor.moveState()}}); } void Item2JsonSerializer::traverse(gui::Item &root) { int level = ItemNode::rootLevel; prototype documentPrototype; DepthFirstItemTree nodes(root, DepthFirstItemTree::TraverseMode::PostOrder); while (nodes.hasNext()) { auto node = nodes.getNext(); if (node.getLevel() == level) { handleSibling(node, documentPrototype, level); } else if (node.getLevel() < level) { handleParent(node, documentPrototype, level); } else { handleOther(node, documentPrototype, level); } } document = json11::Json(std::move(documentPrototype[0].front())); } void Item2JsonSerializer::dump(std::ostream &stream) { stream << document.dump(); } [[nodiscard]] auto Item2JsonSerializer::get() -> json11::Json && { return std::move(document); }