summaryrefslogtreecommitdiff
path: root/src/mbgl/style/conversion/stringify.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/conversion/stringify.hpp')
-rw-r--r--src/mbgl/style/conversion/stringify.hpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/src/mbgl/style/conversion/stringify.hpp b/src/mbgl/style/conversion/stringify.hpp
new file mode 100644
index 0000000000..d06b2f2814
--- /dev/null
+++ b/src/mbgl/style/conversion/stringify.hpp
@@ -0,0 +1,256 @@
+#pragma once
+
+#include <mbgl/style/filter.hpp>
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/util/enum.hpp>
+#include <mbgl/util/color.hpp>
+#include <mbgl/util/feature.hpp>
+#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+#include <array>
+#include <vector>
+#include <unordered_map>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+template <class Writer>
+void stringify(Writer& writer, NullValue) {
+ writer.Null();
+}
+
+template <class Writer>
+void stringify(Writer& writer, bool v) {
+ writer.Bool(v);
+}
+
+template <class Writer>
+void stringify(Writer& writer, uint64_t v) {
+ writer.Uint64(v);
+}
+
+template <class Writer>
+void stringify(Writer& writer, int64_t v) {
+ writer.Int64(v);
+}
+
+template <class Writer>
+void stringify(Writer& writer, double v) {
+ writer.Double(v);
+}
+
+template <class Writer>
+void stringify(Writer& writer, const std::string& v) {
+ writer.String(v);
+}
+
+template <class Writer, class T, class Enable = std::enable_if_t<std::is_enum<T>::value>>
+void stringify(Writer& writer, const T& v) {
+ writer.String(Enum<T>::toString(v));
+}
+
+template <class Writer>
+void stringify(Writer& writer, const Color& v) {
+ writer.String(v.stringify());
+}
+
+template <class Writer>
+void stringify(Writer& writer, const std::array<float, 2>& v) {
+ writer.StartArray();
+ writer.Double(v[0]);
+ writer.Double(v[1]);
+ writer.EndArray();
+}
+
+template <class Writer>
+void stringify(Writer& writer, const std::array<float, 4>& v) {
+ writer.StartArray();
+ writer.Double(v[0]);
+ writer.Double(v[1]);
+ writer.Double(v[2]);
+ writer.Double(v[3]);
+ writer.EndArray();
+}
+
+template <class Writer>
+void stringify(Writer&, const Value&);
+
+template <class Writer, class T>
+void stringify(Writer& writer, const std::vector<T>& v) {
+ writer.StartArray();
+ for (const auto& e : v) {
+ stringify(writer, e);
+ }
+ writer.EndArray();
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const std::unordered_map<std::string, T>& m) {
+ writer.StartObject();
+ for (const auto& p : m) {
+ writer.Key(p.first.data(), static_cast<unsigned>(p.first.size()));
+ stringify(writer, p.second);
+ }
+ writer.EndObject();
+}
+
+template <class Writer>
+void stringify(Writer& writer, const Value& v) {
+ Value::visit(v, [&] (const auto& v_) { stringify(writer, v_); });
+}
+
+template <class Writer>
+class StringifyFilter {
+public:
+ Writer& writer;
+
+ void operator()(const NullFilter&) {
+ writer.Null();
+ }
+
+ void operator()(const EqualsFilter& f) {
+ stringifyBinaryFilter(f, "==");
+ }
+
+ void operator()(const NotEqualsFilter& f) {
+ stringifyBinaryFilter(f, "!=");
+ }
+
+ void operator()(const LessThanFilter& f) {
+ stringifyBinaryFilter(f, "<");
+ }
+
+ void operator()(const LessThanEqualsFilter& f) {
+ stringifyBinaryFilter(f, "<=");
+ }
+
+ void operator()(const GreaterThanFilter& f) {
+ stringifyBinaryFilter(f, ">");
+ }
+
+ void operator()(const GreaterThanEqualsFilter& f) {
+ stringifyBinaryFilter(f, ">=");
+ }
+
+ void operator()(const InFilter& f) {
+ stringifySetFilter(f, "in");
+ }
+
+ void operator()(const NotInFilter& f) {
+ stringifySetFilter(f, "!in");
+ }
+
+ void operator()(const AllFilter& f) {
+ stringifyCompoundFilter(f, "all");
+ }
+
+ void operator()(const AnyFilter& f) {
+ stringifyCompoundFilter(f, "any");
+ }
+
+ void operator()(const NoneFilter& f) {
+ stringifyCompoundFilter(f, "none");
+ }
+
+ void operator()(const HasFilter& f) {
+ stringifyUnaryFilter(f, "has");
+ }
+
+ void operator()(const NotHasFilter& f) {
+ stringifyUnaryFilter(f, "!has");
+ }
+
+private:
+ template <class F>
+ void stringifyBinaryFilter(const F& f, const char * op) {
+ writer.StartArray();
+ writer.String(op);
+ writer.String(f.key);
+ stringify(writer, f.value);
+ writer.EndArray();
+ }
+
+ template <class F>
+ void stringifySetFilter(const F& f, const char * op) {
+ writer.StartArray();
+ writer.String(op);
+ writer.String(f.key);
+ for (const auto& value : f.values) {
+ stringify(writer, value);
+ }
+ writer.EndArray();
+ }
+
+ template <class F>
+ void stringifyCompoundFilter(const F& f, const char * op) {
+ writer.StartArray();
+ writer.String(op);
+ for (const auto& filter : f.filters) {
+ Filter::visit(filter, *this);
+ }
+ writer.EndArray();
+ }
+
+ template <class F>
+ void stringifyUnaryFilter(const F& f, const char * op) {
+ writer.StartArray();
+ writer.String(op);
+ writer.String(f.key);
+ writer.EndArray();
+ }
+};
+
+template <class Writer>
+void stringify(Writer& writer, const Filter& f) {
+ Filter::visit(f, StringifyFilter<Writer> { writer });
+}
+
+template <class Writer>
+void stringify(Writer& writer, const Undefined&) {
+ assert(false); // Should be omitted entirely instead.
+ writer.Null();
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const Function<T>& f) {
+ writer.StartObject();
+ writer.Key("base");
+ writer.Double(f.getBase());
+ writer.Key("stops");
+ writer.StartArray();
+ for (const auto& stop : f.getStops()) {
+ writer.StartArray();
+ writer.Double(stop.first);
+ stringify(writer, stop.second);
+ writer.EndArray();
+ }
+ writer.EndArray();
+ writer.EndObject();
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const PropertyValue<T>& v) {
+ v.evaluate([&] (const auto& v_) { stringify(writer, v_); });
+}
+
+template <class Property, class Writer, class T>
+void stringify(Writer& writer, const PropertyValue<T>& value) {
+ if (value) {
+ writer.Key(Property::key);
+ stringify(writer, value);
+ }
+}
+
+template <class Writer, class... Ps>
+void stringify(Writer& writer, const LayoutProperties<Ps...>& ps) {
+ writer.StartObject();
+ util::ignore({ (stringify<Ps>(writer, ps.unevaluated.template get<Ps>()), 0)... });
+ writer.EndObject();
+}
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl