#include "state.h" #include "spdlog/spdlog.h" #include #include #include using namespace state; using namespace nlohmann; AppState::AppState(std::string filename) : m_saveFilename(filename) { std::ifstream f(filename); if (f.fail()) { spdlog::info("no state file"); return; } json state = json::parse(f); if (state.type() != json::value_t::object) { throw InvalidSavedStateException("JSON root must be an object"); } if (state.contains("vk")) { json vkState = state["vk"]; if (vkState.type() == json::value_t::object) { if (vkState.contains("last_post_id")) { json lastPostId = vkState["last_post_id"]; if (lastPostId.type() == json::value_t::number_integer || lastPostId.type() == json::value_t::number_unsigned) { vkLastPostId = lastPostId; } else { throw InvalidSavedStateException("key vk.last_post_id must be an integer"); } } } else { throw InvalidSavedStateException("key vk must be an object"); } } if (state.contains("tg")) { json tgState = state["tg"]; if (tgState.type() == json::value_t::object) { if (tgState.contains("last_post_id")) { json lastPostId = tgState["last_post_id"]; if (lastPostId.type() == json::value_t::number_integer || lastPostId.type() == json::value_t::number_unsigned) { tgLastPostId = lastPostId; } else { throw InvalidSavedStateException("key tg.last_post_id must be an integer"); } } } else { throw InvalidSavedStateException("key tg must be an object"); } } } void AppState::save() { if (m_saveFilename.empty()) return; spdlog::info("saving state"); json state = {{"vk", {{"last_post_id", vkLastPostId}}}, {"tg", {{"last_post_id", tgLastPostId}}}}; std::ofstream f(m_saveFilename.c_str()); if (f.fail()) { spdlog::error("failed to open state file '{}'", m_saveFilename); return; } f << state << std::endl; } std::string AppState::to_string() { return std::format("AppState {{ tgLastPostId: {}, vkLastPostId: {} }}", tgLastPostId, vkLastPostId); }