#pragma once
#include <panda/string.h>
#include <xs/dict.h>
#include <xs/export.h>
#include <dict.hpp> //rapidjson conflicts with perl macroses
using namespace xs;
using panda::string;
namespace json_tree {
Sv dict2sv(const Dict* dict) {
if (dict == nullptr) return Sv::undef;
return std::visit(overloaded{
[](const Dict::ObjectMap& m) -> Sv {
auto ret = Hash::create(m.size());
for (const auto& r : m) ret[r.first.c_str()] = dict2sv(&r.second);
return Ref::create(ret);
},
[](const Dict::ObjectArr& a) -> Sv {
auto ret = Array::create(a.size());
for (const auto& r : a) ret.push(dict2sv(&r));
return Ref::create(ret);
},
[](panda::string s) -> Sv {
return Simple(s.c_str());
},
[](Undef) -> Sv {
return Sv::undef;
},
[](auto v) -> Sv {
return Simple(v);
},
},
dict->value);
}
Sv dict2sv_slice(const Dict* dict, panda::string field) {
if (dict == nullptr) return Sv::undef;
return std::visit(overloaded{
[&](const Dict::ObjectMap& m) -> Sv {
if (m.find(field) == m.end()) return Sv::undef;
return dict2sv(&m.at(field));
},
[&](const Dict::ObjectArr& a) -> Sv {
uint64_t i;
auto [p, ec] = std::from_chars(field.data(), field.data() + field.size(), i);
if (ec != std::errc() || i >= a.size()) return nullptr;
return dict2sv(&a[i]);
},
[](auto) -> Sv {
return Sv::undef;
},
},
dict->value);
}
struct StringArgsRange {
SV** args;
size_t _size;
size_t size() const { return _size; }
panda::string operator[](size_t i) const { return xs::in<panda::string>(args[i]); }
};
} // namespace json_tree