summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsheem Mamoowala <asheem.mamoowala@mapbox.com>2018-06-29 12:56:44 -0700
committerAsheem Mamoowala <asheem.mamoowala@mapbox.com>2018-07-10 11:16:12 -0700
commit3353c6c8b8fcd666b469ba266edc3dcb5d93ddf3 (patch)
treea94544db9c1cf20669d80aafa5a3aa1287935f36
parent124faee638f82a7e30dbb9584bbfb65cf48be871 (diff)
downloadqtlocation-mapboxgl-3353c6c8b8fcd666b469ba266edc3dcb5d93ddf3.tar.gz
Keep original input for filters using legacy syntax.
-rw-r--r--include/mbgl/style/filter.hpp20
-rw-r--r--src/mbgl/style/conversion/filter.cpp21
-rw-r--r--test/style/filter.test.cpp55
3 files changed, 92 insertions, 4 deletions
diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp
index ce4015bb69..c9dc9fb1ec 100644
--- a/include/mbgl/style/filter.hpp
+++ b/include/mbgl/style/filter.hpp
@@ -11,14 +11,18 @@
namespace mbgl {
namespace style {
-
+
class Filter {
public:
optional<std::shared_ptr<const expression::Expression>> expression;
-
+private:
+ optional<mbgl::Value> legacyFilter;
+public:
Filter() : expression() {}
- Filter(expression::ParseResult _expression) : expression(std::move(*_expression)) {
+ Filter(expression::ParseResult _expression, optional<mbgl::Value> _filter = {})
+ : expression(std::move(*_expression)),
+ legacyFilter(std::move(_filter)){
assert(!expression || *expression != nullptr);
}
@@ -35,6 +39,16 @@ public:
friend bool operator!=(const Filter& lhs, const Filter& rhs) {
return !(lhs == rhs);
}
+
+ mbgl::Value serialize() const {
+ if (legacyFilter) {
+ return *legacyFilter;
+ }
+ else if (expression) {
+ return (**expression).serialize();
+ }
+ return NullValue();
+ }
};
} // namespace style
diff --git a/src/mbgl/style/conversion/filter.cpp b/src/mbgl/style/conversion/filter.cpp
index cd588345ef..b690c96388 100644
--- a/src/mbgl/style/conversion/filter.cpp
+++ b/src/mbgl/style/conversion/filter.cpp
@@ -14,6 +14,7 @@ using namespace mbgl::style::expression;
static bool isExpression(const Convertible& filter);
ParseResult convertLegacyFilter(const Convertible& values, Error& error);
+optional<mbgl::Value> serializeLegacyFilter(const Convertible& values);
optional<Filter> Converter<Filter>::operator()(const Convertible& value, Error& error) const {
if (isExpression(value)) {
@@ -31,7 +32,7 @@ optional<Filter> Converter<Filter>::operator()(const Convertible& value, Error&
assert(error.message.size() > 0);
return {};
}
- return Filter(optional<std::unique_ptr<Expression>>(std::move(*expression)));
+ return Filter(optional<std::unique_ptr<Expression>>(std::move(*expression)), serializeLegacyFilter(value));
}
}
@@ -218,6 +219,24 @@ ParseResult convertLegacyFilter(const Convertible& values, Error& error) {
}
}
+optional<mbgl::Value> serializeLegacyFilter(const Convertible& values) {
+ if (isUndefined(values)) {
+ return {};
+ } else if (isArray(values)) {
+ std::vector<mbgl::Value> result;
+ for (std::size_t i = 0; i < arrayLength(values); i++) {
+ auto arrayValue = serializeLegacyFilter(arrayMember(values, i));
+ if (arrayValue) {
+ result.push_back(*arrayValue);
+ } else {
+ result.push_back(NullValue());
+ }
+ }
+ return (mbgl::Value)result;
+ }
+ return toValue(values);
+}
+
} // namespace conversion
} // namespace style
} // namespace mbgl
diff --git a/test/style/filter.test.cpp b/test/style/filter.test.cpp
index bac3801223..e04a569203 100644
--- a/test/style/filter.test.cpp
+++ b/test/style/filter.test.cpp
@@ -11,6 +11,10 @@
#include <mbgl/style/filter.hpp>
#include <mbgl/style/conversion/json.hpp>
#include <mbgl/style/conversion/filter.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+#include <rapidjson/writer.h>
+#include <rapidjson/stringbuffer.h>
using namespace mbgl;
using namespace mbgl::style;
@@ -39,6 +43,42 @@ void invalidFilter(const char * json) {
EXPECT_NE(error.message, "");
}
+void writeJSON(rapidjson::Writer<rapidjson::StringBuffer>& writer, const Value& value) {
+ value.match(
+ [&] (const NullValue&) { writer.Null(); },
+ [&] (bool b) { writer.Bool(b); },
+ [&] (uint64_t t) { writer.Uint64(t); },
+ [&] (int64_t t) { writer.Int64(t); },
+ [&] (double f) {
+ // make sure integer values are stringified without trailing ".0".
+ f == std::floor(f) ? writer.Int(f) : writer.Double(f);
+ },
+ [&] (const std::string& s) { writer.String(s); },
+ [&] (const std::vector<Value>& arr) {
+ writer.StartArray();
+ for(const auto& item : arr) {
+ writeJSON(writer, item);
+ }
+ writer.EndArray();
+ },
+ [](const auto&) {
+ });
+}
+
+std::string stringifyFilter(const char * json) {
+ conversion::Error error;
+ optional<Filter> filter = conversion::convertJSON<Filter>(json, error);
+ EXPECT_TRUE(bool(filter));
+ EXPECT_EQ(error.message, "");
+
+ auto value = filter->serialize();
+
+ rapidjson::StringBuffer s;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(s);
+ writeJSON(writer, value);
+ return s.GetString();
+}
+
TEST(Filter, EqualsNull) {
auto f = R"(["==", "foo", null])";
ASSERT_TRUE(filter(f, {{ "foo", mapbox::geometry::null_value }}));
@@ -181,6 +221,21 @@ TEST(Filter, LegacyProperty) {
ASSERT_FALSE(filter("[\"==\", \"two\", 4]", {{"two", std::string("2")}}));
}
+TEST(Filter, Serialize) {
+ std::string json = R"(["any",["==","foo",0],["==","foo",1]])";
+ EXPECT_EQ(stringifyFilter(json.c_str()), std::string(json));
+
+ json = R"(["<=","two",2])";
+ EXPECT_EQ(stringifyFilter(json.c_str()), std::string(json));
+
+ //Constant folding for Expression filters
+ json = R"(["==",["+",1,1],2])";
+ EXPECT_EQ(stringifyFilter(json.c_str()), std::string("true"));
+
+ json = R"(["all",["==",["get","foo"],0],["==",["get","foo"],1]])";
+ EXPECT_EQ(stringifyFilter(json.c_str()), std::string(json));
+}
+
TEST(Filter, ExpressionLegacyMix) {
conversion::Error error;
optional<Filter> filter = conversion::convertJSON<Filter>(R"(["any", ["all", ["==", ["geometry-type"], "LineString"]], ["==", "x", 1]])", error);