#pragma once #include "value.hpp" #include #include #include #include #include #include namespace mbgl { namespace style { namespace conversion { template <> class ConversionTraits { public: static bool isUndefined(const mbgl::android::Value& value) { return value.isNull(); } static bool isArray(const mbgl::android::Value& value) { return value.isArray(); } static bool isObject(const mbgl::android::Value& value) { return value.isObject(); } static std::size_t arrayLength(const mbgl::android::Value& value) { return value.getLength(); ; } static mbgl::android::Value arrayMember(const mbgl::android::Value& value, std::size_t i) { return value.get(i); } static std::optional objectMember(const mbgl::android::Value& value, const char* key) { mbgl::android::Value member = value.get(key); if (!member.isNull()) { return member; } else { return {}; } } template static std::optional eachMember(const mbgl::android::Value& value, Fn&& fn) { assert(value.isObject()); mbgl::android::Value keys = value.keyArray(); std::size_t length = arrayLength(keys); for (std::size_t i = 0; i < length; ++i) { const auto k = keys.get(i).toString(); auto v = value.get(k.c_str()); std::optional result = fn(k, std::move(v)); if (result) { return result; } } return {}; } static std::optional toBool(const mbgl::android::Value& value) { if (value.isBool()) { return value.toBool(); } else { return {}; } } static std::optional toNumber(const mbgl::android::Value& value) { if (value.isNumber()) { auto num = value.toFloat(); return num; } else { return {}; } } static std::optional toDouble(const mbgl::android::Value& value) { if (value.isNumber()) { return value.toDouble(); } else { return {}; } } static std::optional toString(const mbgl::android::Value& value) { if (value.isString()) { return value.toString(); } else { return {}; } } static std::optional toValue(const mbgl::android::Value& value) { if (value.isNull()) { return {}; } else if (value.isBool()) { return {value.toBool()}; } else if (value.isString()) { return {value.toString()}; } else if (value.isNumber()) { return {value.toDouble()}; } else { return {}; } } static std::optional toGeoJSON(const mbgl::android::Value& value, Error& error) { if (value.isNull()) { error = {"no json data found"}; return {}; } if (value.isString()) { return parseGeoJSON(value.toString(), error); } if (value.isObject()) { mbgl::android::Value keys = value.keyArray(); std::size_t length = arrayLength(keys); for (std::size_t i = 0; i < length; ++i) { if (keys.get(i).toString() == "json") { auto v = value.get("json"); if (v.isString()) { return parseGeoJSON(v.toString(), error); } else { break; } } } } error = {"no json data found"}; return {}; } }; template std::optional convert(mbgl::android::Value&& value, Error& error, Args&&... args) { return convert(Convertible(std::move(value)), error, std::forward(args)...); } } // namespace conversion } // namespace style } // namespace mbgl