summaryrefslogtreecommitdiffhomepage
path: root/serialize/json-helper.cpp
blob: 315dec2d3d74fa6f230a8c121afd58ad4a1352f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "json-helper.hpp"
#include "compat/exception.hpp"
#include "compat/strerror.hpp"
#include <concepts>
#include <fstream>
#include <Corrade/Containers/StringView.h>

namespace floormat {

namespace {

template<std::derived_from<std::basic_ios<char>> T, std::ios_base::openmode mode>
T open_stream(StringView filename)
{
    T s;
    errno = 0;
    s.open(filename.data(), mode);
    if (!s.good())
    {
        const auto mode_str = (mode & std::ios_base::out) == std::ios_base::out ? "writing"_s : "reading"_s;
        char errbuf[128];
        fm_throw("can't open file '{}' for {}: {}"_cf, filename, mode_str, get_error_string(errbuf));
    }
    return s;
}

} // namespace

auto json_helper::from_json_(StringView filename) noexcept(false) -> json
{
    json j;
    auto s = open_stream<std::ifstream, std::ios_base::in>(filename);
    s >> j;
    if (s.bad() || !s.eof() && s.fail())
    {
        char errbuf[128];
        fm_throw("input/output error while {} '{}': {}"_cf, filename, "reading"_s, get_error_string(errbuf));
    }
    return j;
}

void json_helper::to_json_(const json& j, StringView filename) noexcept(false)
{
    auto s = open_stream<std::ofstream, std::ios_base::out>(filename);
    s << j.dump(2, ' ') << "\n";
    s.flush();
    if (!s.good())
    {
        char errbuf[128];
        fm_throw("input/output error while {} '{}': {}"_cf, filename, "writing"_s, get_error_string(errbuf));
    }
}

} // namespace floormat