Spaces:
Running
Running
| --- include/nanobind_json/nanobind_json.hpp | |
| +++ include/nanobind_json/nanobind_json.hpp | |
| #include "nlohmann/json.hpp" | |
| -#include "nanobind/nanobind.hpp" | |
| +#include <nanobind/nanobind.h> | |
| +#include <nanobind/stl/string.h> | |
| namespace nb = nanobind; | |
| namespace nl = nlohmann; | |
| namespace pyjson | |
| { | |
| + | |
| inline nb::object from_json(const nl::json& j) | |
| { | |
| if (j.is_null()) | |
| } | |
| else if (j.is_string()) | |
| { | |
| - return nb::str(j.get<std::string>()); | |
| + return nb::str(j.get<std::string>().c_str()); | |
| } | |
| else if (j.is_array()) | |
| { | |
| nb::dict obj; | |
| for (nl::json::const_iterator it = j.cbegin(); it != j.cend(); ++it) | |
| { | |
| - obj[nb::str(it.key())] = from_json(it.value()); | |
| + obj[nb::str(it.key().c_str())] = from_json(it.value()); | |
| } | |
| return std::move(obj); | |
| } | |
| } | |
| if (nb::isinstance<nb::bool_>(obj)) | |
| { | |
| - return obj.cast<bool>(); | |
| + return nb::cast<bool>(obj); | |
| } | |
| if (nb::isinstance<nb::int_>(obj)) | |
| { | |
| - return obj.cast<long>(); | |
| + return nb::cast<long>(obj); | |
| } | |
| if (nb::isinstance<nb::float_>(obj)) | |
| { | |
| - return obj.cast<double>(); | |
| + return nb::cast<double>(obj); | |
| } | |
| if (nb::isinstance<nb::bytes>(obj)) | |
| { | |
| - nb::module base64 = nb::module::import("base64"); | |
| - return base64.attr("b64encode")(obj).attr("decode")("utf-8").cast<std::string>(); | |
| + nb::module_ base64 = nb::module_::import_("base64"); | |
| + return nb::cast<std::string>(base64.attr("b64encode")(obj).attr("decode")("utf-8")); | |
| } | |
| if (nb::isinstance<nb::str>(obj)) | |
| { | |
| - return obj.cast<std::string>(); | |
| + return nb::cast<std::string>(obj); | |
| } | |
| if (nb::isinstance<nb::tuple>(obj) || nb::isinstance<nb::list>(obj)) | |
| { | |
| auto out = nl::json::object(); | |
| for (const nb::handle key : obj) | |
| { | |
| - out[nb::str(key).cast<std::string>()] = to_json(obj[key]); | |
| + out[nb::cast<std::string>(nb::str(key))] = to_json(obj[key]); | |
| } | |
| return out; | |
| } | |
| - throw std::runtime_error("to_json not implemented for this type of object: " + nb::repr(obj).cast<std::string>()); | |
| + throw std::runtime_error("to_json not implemented for this type of object: " + nb::cast<std::string>(nb::repr(obj))); | |
| } | |
| } | |
| j = pyjson::to_json(obj); \ | |
| } \ | |
| \ | |
| - inline static T from_json(const json& j) \ | |
| + inline static nb::object from_json(const json& j) \ | |
| { \ | |
| return pyjson::from_json(j); \ | |
| } \ | |
| MAKE_NLJSON_SERIALIZER_DESERIALIZER(nb::dict); | |
| MAKE_NLJSON_SERIALIZER_ONLY(nb::handle); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::item_accessor); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::list_accessor); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::tuple_accessor); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::sequence_accessor); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::str_attr_accessor); | |
| - MAKE_NLJSON_SERIALIZER_ONLY(nb::detail::obj_attr_accessor); | |
| #undef MAKE_NLJSON_SERIALIZER | |
| #undef MAKE_NLJSON_SERIALIZER_ONLY | |
| { | |
| namespace detail | |
| { | |
| - template <> struct type_caster<nl::json> | |
| - { | |
| - public: | |
| - NANOBIND_TYPE_CASTER(nl::json, _("json")); | |
| + | |
| + template <> struct type_caster<nl::json> { | |
| + using Value = nl::json; | |
| - bool load(handle src, bool) | |
| - { | |
| - try { | |
| - value = pyjson::to_json(src); | |
| - return true; | |
| - } | |
| - catch (...) | |
| - { | |
| - return false; | |
| - } | |
| - } | |
| + template <typename T> using Cast = Value; | |
| + | |
| + // Value name for docstring generation | |
| + static constexpr auto Name = const_name("Json"); | |
| - static handle cast(nl::json src, return_value_policy /* policy */, handle /* parent */) | |
| + /// Python -> C++ caster, populates `caster1` and `caster2` upon success | |
| + bool from_python(handle src, uint8_t flags, | |
| + cleanup_list *cleanup) noexcept { | |
| + try { | |
| + value = pyjson::to_json(src); | |
| + return true; | |
| + } | |
| + catch (...) | |
| { | |
| - object obj = pyjson::from_json(src); | |
| - return obj.release(); | |
| + return false; | |
| } | |
| - }; | |
| + } | |
| + | |
| + template <typename T> | |
| + static handle from_cpp(T *value, rv_policy policy, cleanup_list *cleanup) { | |
| + if (!value) | |
| + return none().release(); | |
| + return from_cpp(*value, policy, cleanup); | |
| + } | |
| + | |
| + template<typename T> | |
| + static handle from_cpp(T &&value, rv_policy policy, | |
| + cleanup_list *cleanup) noexcept { | |
| + object obj = pyjson::from_json(value); | |
| + return obj.release(); | |
| + } | |
| + | |
| + template <typename T> | |
| + bool can_cast() const noexcept { | |
| + return true; | |
| + } | |
| + | |
| + /// Return the constructed tuple by copying from the sub-casters | |
| + explicit operator Value() { | |
| + return value; | |
| + } | |
| + | |
| + Value value; | |
| + }; | |
| } | |
| } | |