1 #pragma once
2 
3 #include <mbgl/style/filter.hpp>
4 #include <mbgl/style/property_value.hpp>
5 #include <mbgl/style/data_driven_property_value.hpp>
6 #include <mbgl/util/enum.hpp>
7 #include <mbgl/util/color.hpp>
8 #include <mbgl/util/feature.hpp>
9 #include <mbgl/util/ignore.hpp>
10 #include <mbgl/util/rapidjson.hpp>
11 
12 #include <array>
13 #include <vector>
14 #include <unordered_map>
15 
16 namespace mbgl {
17 namespace style {
18 namespace conversion {
19 
20 template <class Writer>
stringify(Writer & writer,NullValue)21 void stringify(Writer& writer, NullValue) {
22     writer.Null();
23 }
24 
25 template <class Writer>
stringify(Writer & writer,bool v)26 void stringify(Writer& writer, bool v) {
27     writer.Bool(v);
28 }
29 
30 template <class Writer>
stringify(Writer & writer,uint64_t v)31 void stringify(Writer& writer, uint64_t v) {
32     writer.Uint64(v);
33 }
34 
35 template <class Writer>
stringify(Writer & writer,int64_t v)36 void stringify(Writer& writer, int64_t v) {
37     writer.Int64(v);
38 }
39 
40 template <class Writer>
stringify(Writer & writer,double v)41 void stringify(Writer& writer, double v) {
42     writer.Double(v);
43 }
44 
45 template <class Writer>
stringify(Writer & writer,const std::string & v)46 void stringify(Writer& writer, const std::string& v) {
47     writer.String(v);
48 }
49 
50 template <class Writer, class T, class Enable = std::enable_if_t<std::is_enum<T>::value>>
stringify(Writer & writer,const T & v)51 void stringify(Writer& writer, const T& v) {
52     writer.String(Enum<T>::toString(v));
53 }
54 
55 template <class Writer>
stringify(Writer & writer,const Color & v)56 void stringify(Writer& writer, const Color& v) {
57     writer.String(v.stringify());
58 }
59 
60 template <class Writer>
stringify(Writer & writer,const std::array<float,2> & v)61 void stringify(Writer& writer, const std::array<float, 2>& v) {
62     writer.StartArray();
63     writer.Double(v[0]);
64     writer.Double(v[1]);
65     writer.EndArray();
66 }
67 
68 template <class Writer>
stringify(Writer & writer,const std::array<float,4> & v)69 void stringify(Writer& writer, const std::array<float, 4>& v) {
70     writer.StartArray();
71     writer.Double(v[0]);
72     writer.Double(v[1]);
73     writer.Double(v[2]);
74     writer.Double(v[3]);
75     writer.EndArray();
76 }
77 
78 template <class Writer>
79 void stringify(Writer&, const Value&);
80 
81 template <class Writer, class T>
stringify(Writer & writer,const std::vector<T> & v)82 void stringify(Writer& writer, const std::vector<T>& v) {
83     writer.StartArray();
84     for (const auto& e : v) {
85         stringify(writer, e);
86     }
87     writer.EndArray();
88 }
89 
90 template <class Writer, class T>
stringify(Writer & writer,const std::unordered_map<std::string,T> & m)91 void stringify(Writer& writer, const std::unordered_map<std::string, T>& m) {
92     writer.StartObject();
93     for (const auto& p : m) {
94         writer.Key(p.first.data(), static_cast<unsigned>(p.first.size()));
95         stringify(writer, p.second);
96     }
97     writer.EndObject();
98 }
99 
100 template <class Writer>
stringify(Writer & writer,const Value & v)101 void stringify(Writer& writer, const Value& v) {
102     Value::visit(v, [&] (const auto& v_) { stringify(writer, v_); });
103 }
104 
105 template <class Writer>
stringify(Writer & writer,FeatureType type)106 void stringify(Writer& writer, FeatureType type) {
107     switch (type) {
108     case FeatureType::Unknown:
109         writer.String("Unknown");
110         break;
111     case FeatureType::Point:
112         writer.String("Point");
113         break;
114     case FeatureType::LineString:
115         writer.String("LineString");
116         break;
117     case FeatureType::Polygon:
118         writer.String("Polygon");
119         break;
120     }
121 }
122 
123 template <class Writer>
stringify(Writer & writer,const FeatureIdentifier & id)124 void stringify(Writer& writer, const FeatureIdentifier& id) {
125     FeatureIdentifier::visit(id, [&] (const auto& id_) { stringify(writer, id_); });
126 }
127 
128 template <class Writer>
stringify(Writer & writer,const Filter & filter)129 void stringify(Writer& writer, const Filter& filter) {
130     if (!filter.expression) writer.Null();
131     else stringify(writer, (*filter.expression)->serialize());
132 }
133 
134 template <class Writer>
stringify(Writer & writer,const Undefined &)135 void stringify(Writer& writer, const Undefined&) {
136     assert(false); // Should be omitted entirely instead.
137     writer.Null();
138 }
139 
140 template <class Writer, class T>
stringify(Writer & writer,const PropertyExpression<T> & fn)141 void stringify(Writer& writer, const PropertyExpression<T>& fn) {
142     stringify(writer, fn.getExpression().serialize());
143 }
144 
145 template <class Writer, class T>
stringify(Writer & writer,const PropertyValue<T> & v)146 void stringify(Writer& writer, const PropertyValue<T>& v) {
147     v.evaluate([&] (const auto& v_) { stringify(writer, v_); });
148 }
149 
150 template <class Property, class Writer, class T>
stringify(Writer & writer,const PropertyValue<T> & value)151 void stringify(Writer& writer, const PropertyValue<T>& value) {
152     if (!value.isUndefined()) {
153         writer.Key(Property::key);
154         stringify(writer, value);
155     }
156 }
157 
158 template <class Writer, class T>
stringify(Writer & writer,const DataDrivenPropertyValue<T> & v)159 void stringify(Writer& writer, const DataDrivenPropertyValue<T>& v) {
160     v.evaluate([&] (const auto& v_) { stringify(writer, v_); });
161 }
162 
163 template <class Property, class Writer, class T>
stringify(Writer & writer,const DataDrivenPropertyValue<T> & value)164 void stringify(Writer& writer, const DataDrivenPropertyValue<T>& value) {
165     if (!value.isUndefined()) {
166         writer.Key(Property::key);
167         stringify(writer, value);
168     }
169 }
170 
171 } // namespace conversion
172 } // namespace style
173 } // namespace mbgl
174