14 constexpr static std::string_view NODES_KEY =
"nodes";
15 constexpr static std::string_view EDGES_KEY =
"edges";
16 constexpr static std::string_view NODE_ID_KEY =
"id";
17 constexpr static std::string_view NODE_DATA_KEY =
"data";
18 using N =
typename BaseContainer::node_type;
20 std::filesystem::path filePath;
25 std::ifstream file(filePath);
26 if(not file.is_open() || std::filesystem::is_empty(filePath)){
32 if(not j.contains(NODES_KEY) or not j.contains(EDGES_KEY)){
33 throw std::runtime_error(
"Invalid JSON format: missing nodes or edges key");
35 std::unordered_map<size_t,N> idToNodeMap;
36 for(
const auto & jsonNode: j[NODES_KEY]){
37 if(not jsonNode.contains(NODE_ID_KEY) or not jsonNode.contains(NODE_DATA_KEY)){
38 throw std::runtime_error(
"Invalid JSON format: node missing id or data key");
40 size_t nodeID = jsonNode[NODE_ID_KEY].get<
size_t>();
41 N node = fromJson(jsonNode[NODE_DATA_KEY]);
43 idToNodeMap.emplace(nodeID, node);
45 for(
const auto & jsonEdge: j[EDGES_KEY]){
46 if(not jsonEdge.contains(
"from") or not jsonEdge.contains(
"to")){
47 throw std::runtime_error(
"Invalid JSON format: edge missing from or to key");
49 size_t fromID = jsonEdge[
"from"].get<
size_t>();
50 size_t toID = jsonEdge[
"to"].get<
size_t>();
51 if(not idToNodeMap.contains(fromID) or not idToNodeMap.contains(toID)){
52 throw std::runtime_error(
"Invalid JSON format: edge references unknown node id");
54 this->
addAdjacency(idToNodeMap.at(fromID), idToNodeMap.at(toID));
58 void save()
const noexcept {
60 j[NODES_KEY] = nlohmann::json::array();
62 std::unordered_map<N,size_t,typename BaseContainer::hash_function,typename BaseContainer::equality_predicate> nodeToIDMap;
63 for(
const auto & node: this->
nodes()){
64 nlohmann::json jsonNode;
66 nodeToIDMap[node] = nodeID;
67 jsonNode[NODE_ID_KEY] = nodeID;
68 jsonNode[NODE_DATA_KEY] = toJson(node);
69 j[NODES_KEY].push_back(jsonNode);
71 j[EDGES_KEY] = nlohmann::json::array();
74 edge[
"from"] = nodeToIDMap.at(from);
75 edge[
"to"] = nodeToIDMap.at(to);
76 j[EDGES_KEY].push_back(edge);
78 std::ofstream file(filePath);
89 if(not this->filePath.has_extension() or this->filePath.extension() !=
".json"){
90 throw std::invalid_argument(
"File path must have .json extension");
JSONFileAdjacency(BaseContainer &&baseContainer, const std::filesystem::path &filePath, util::UnaryFunction< N, nlohmann::json > auto toJson, util::UnaryFunction< nlohmann::json, N > auto fromJson)
Definition JSONFileAdjacency.hpp:87