json.cpp 2.91 KB
Newer Older
Shucai Xiao's avatar
Shucai Xiao committed
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <migraphx/serialize.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/literal.hpp>
#include <nlohmann/json.hpp>
#include <migraphx/json.hpp>

namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {

using json = nlohmann::json;

void value_to_json(const value& val, json& j);
migraphx::value value_from_json(const json& j);

} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx

namespace nlohmann {
template <>
struct adl_serializer<migraphx::value>
{
    static void to_json(json& j, const migraphx::value& val) { migraphx::value_to_json(val, j); }

    static void from_json(const json& j, migraphx::value& val)
    {
        val = migraphx::value_from_json(j);
    }
};
} // namespace nlohmann

namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {

using json = nlohmann::json;

template <class T>
void value_to_json(const T& x, json& j)
{
    j = x;
}

void value_to_json(const std::vector<value>& x, json& j)
{
    for(auto& v : x)
    {
        if(v.get_key().empty())
        {
            j.push_back(v);
        }
        else
        {
            j[v.get_key()] = v.without_key();
        }
    }
}

void value_to_json(std::nullptr_t&, json& j) { j = {}; }

void value_to_json(const value& val, json& j)
{
    if(val.is_array())
    {
        j = json::array();
    }

    if(val.is_object())
    {
        j = json::object();
    }

    val.visit([&](auto v) { value_to_json(v, j); });
}

migraphx::value value_from_json(const json& j)
{
    migraphx::value val;
    json::value_t type = j.type();
    switch(type)
    {
    case json::value_t::null: val = nullptr; break;

    case json::value_t::boolean: val = j.get<bool>(); break;

    case json::value_t::number_float: val = j.get<double>(); break;

    case json::value_t::number_integer: val = j.get<int64_t>(); break;

    case json::value_t::number_unsigned: val = j.get<uint64_t>(); break;

    case json::value_t::string: val = j.get<std::string>(); break;

    case json::value_t::array:
        val = migraphx::value::array{};
        std::transform(j.begin(), j.end(), std::back_inserter(val), [&](const json& jj) {
            return jj.get<value>();
        });
        break;

    case json::value_t::object:
        val = migraphx::value::object{};
        for(const auto& item : j.items())
        {
            const auto& key = item.key();
            const json& jv  = item.value();
            val[key]        = jv.get<value>();
        }
        break;

    case json::value_t::binary: MIGRAPHX_THROW("Convert JSON to Value: binary type not supported!");
    case json::value_t::discarded:
        MIGRAPHX_THROW("Convert JSON to Value: discarded type not supported!");
    }

    return val;
}

std::string to_json_string(const value& val)
{
    json j = val;
    return j.dump();
}

migraphx::value from_json_string(const std::string& str)
{
    json j = json::parse(str);
    return j.get<value>();
}

} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx