ChaiScript
json_wrap.hpp
1 #ifndef CHAISCRIPT_SIMPLEJSON_WRAP_HPP
2 #define CHAISCRIPT_SIMPLEJSON_WRAP_HPP
3 
4 #include "json.hpp"
5 
6 namespace chaiscript {
7  class json_wrap {
8  public:
9  static Module &library(Module &m) {
10  m.add(chaiscript::fun([](const std::string &t_str) { return from_json(t_str); }), "from_json");
11  m.add(chaiscript::fun(&json_wrap::to_json), "to_json");
12 
13  return m;
14  }
15 
16  private:
17  static Boxed_Value from_json(const json::JSON &t_json) {
18  switch (t_json.JSONType()) {
19  case json::JSON::Class::Null:
20  return Boxed_Value();
21  case json::JSON::Class::Object: {
22  std::map<std::string, Boxed_Value> m;
23 
24  for (const auto &p : t_json.object_range()) {
25  m.insert(std::make_pair(p.first, from_json(p.second)));
26  }
27 
28  return Boxed_Value(m);
29  }
30  case json::JSON::Class::Array: {
31  std::vector<Boxed_Value> vec;
32 
33  for (const auto &p : t_json.array_range()) {
34  vec.emplace_back(from_json(p));
35  }
36 
37  return Boxed_Value(vec);
38  }
39  case json::JSON::Class::String:
40  return Boxed_Value(t_json.to_string());
41  case json::JSON::Class::Floating:
42  return Boxed_Value(t_json.to_float());
43  case json::JSON::Class::Integral:
44  return Boxed_Value(t_json.to_int());
45  case json::JSON::Class::Boolean:
46  return Boxed_Value(t_json.to_bool());
47  }
48 
49  throw std::runtime_error("Unknown JSON type");
50  }
51 
52  static Boxed_Value from_json(const std::string &t_json) {
53  try {
54  return from_json(json::JSON::Load(t_json));
55  } catch (const std::out_of_range &) {
56  throw std::runtime_error("Unparsed JSON input");
57  }
58  }
59 
60  static std::string to_json(const Boxed_Value &t_bv) { return to_json_object(t_bv).dump(); }
61 
62  static json::JSON to_json_object(const Boxed_Value &t_bv) {
63  try {
64  const std::map<std::string, Boxed_Value> m = chaiscript::boxed_cast<const std::map<std::string, Boxed_Value> &>(t_bv);
65 
66  json::JSON obj(json::JSON::Class::Object);
67  for (const auto &o : m) {
68  obj[o.first] = to_json_object(o.second);
69  }
70  return obj;
71  } catch (const chaiscript::exception::bad_boxed_cast &) {
72  // not a map
73  }
74 
75  try {
76  const std::vector<Boxed_Value> v = chaiscript::boxed_cast<const std::vector<Boxed_Value> &>(t_bv);
77 
78  json::JSON obj(json::JSON::Class::Array);
79  for (size_t i = 0; i < v.size(); ++i) {
80  obj[i] = to_json_object(v[i]);
81  }
82  return obj;
83  } catch (const chaiscript::exception::bad_boxed_cast &) {
84  // not a vector
85  }
86 
87  try {
88  Boxed_Number bn(t_bv);
89  if (Boxed_Number::is_floating_point(t_bv)) {
90  return json::JSON(bn.get_as<double>());
91  } else {
92  return json::JSON(bn.get_as<std::int64_t>());
93  }
95  // not a number
96  }
97 
98  try {
99  return json::JSON(boxed_cast<bool>(t_bv));
100  } catch (const chaiscript::exception::bad_boxed_cast &) {
101  // not a bool
102  }
103 
104  try {
105  return json::JSON(boxed_cast<std::string>(t_bv));
106  } catch (const chaiscript::exception::bad_boxed_cast &) {
107  // not a string
108  }
109 
110  try {
112 
113  json::JSON obj(json::JSON::Class::Object);
114  for (const auto &attr : o.get_attrs()) {
115  obj[attr.first] = to_json_object(attr.second);
116  }
117  return obj;
118  } catch (const chaiscript::exception::bad_boxed_cast &) {
119  // not a dynamic object
120  }
121 
122  if (t_bv.is_null())
123  return json::JSON(); // a null value
124 
125  throw std::runtime_error("Unknown object type to convert to JSON");
126  }
127  };
128 
129 } // namespace chaiscript
130 
131 #endif
Holds a collection of ChaiScript settings which can be applied to the ChaiScript runtime.
Definition: dispatchkit.hpp:128
decltype(auto) boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions=nullptr)
Function for extracting a value stored in a Boxed_Value object.
Definition: boxed_cast.hpp:71
Definition: json_wrap.hpp:7
Namespace chaiscript contains every API call that the average user will be concerned with...
A wrapper for holding any valid C++ type.
Definition: boxed_value.hpp:24
Thrown in the event that a Boxed_Value cannot be cast to the desired type.
Definition: bad_boxed_cast.hpp:31
Definition: json.hpp:30
Definition: dynamic_object.hpp:38
Thrown in the event that an Any cannot be cast to the desired type.
Definition: any.hpp:20
Proxy_Function fun(T &&t)
Creates a new Proxy_Function object from a free function, member function or data member...
Definition: register_function.hpp:81
Represents any numeric type, generically. Used internally for generic operations between POD values...
Definition: boxed_number.hpp:60