summaryrefslogtreecommitdiff
path: root/src/mbgl/style/expression/assertion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/expression/assertion.cpp')
-rw-r--r--src/mbgl/style/expression/assertion.cpp79
1 files changed, 73 insertions, 6 deletions
diff --git a/src/mbgl/style/expression/assertion.cpp b/src/mbgl/style/expression/assertion.cpp
index 7e93003ac3..8e5a8b555d 100644
--- a/src/mbgl/style/expression/assertion.cpp
+++ b/src/mbgl/style/expression/assertion.cpp
@@ -30,22 +30,64 @@ ParseResult Assertion::parse(const Convertible& value, ParsingContext& ctx) {
return ParseResult();
}
- auto it = types.find(*toString(arrayMember(value, 0)));
- assert(it != types.end());
-
+ std::size_t i = 1;
+ type::Type type;
+
+ std::string name = *toString(arrayMember(value, 0));
+ if (name == "array") {
+ optional<type::Type> itemType;
+ if (length > 2) {
+ optional<std::string> itemTypeName = toString(arrayMember(value, 1));
+ auto it = itemTypeName ? types.find(*itemTypeName) : types.end();
+ if (it == types.end() || it->second == type::Object) {
+ ctx.error(
+ R"(The item type argument of "array" must be one of string, number, boolean)",
+ 1
+ );
+ return ParseResult();
+ }
+ itemType = it->second;
+ i++;
+ } else {
+ itemType = {type::Value};
+ }
+
+ optional<std::size_t> N;
+ if (length > 3) {
+ auto m = arrayMember(value, 2);
+ optional<float> n = toNumber(m);
+ if (!isUndefined(m) &&
+ (!n || *n < 0 || *n != std::floor(*n))) {
+ ctx.error(
+ R"(The length argument to "array" must be a positive integer literal.)",
+ 2
+ );
+ return ParseResult();
+ }
+ if (n) {
+ N = optional<std::size_t>(*n);
+ }
+ i++;
+ }
+
+ type = type::Array(*itemType, N);
+ } else {
+ type = types.at(name);
+ }
+
std::vector<std::unique_ptr<Expression>> parsed;
parsed.reserve(length - 1);
- for (std::size_t i = 1; i < length; i++) {
+ for (; i < length; i++) {
ParseResult input = ctx.parse(arrayMember(value, i), i, {type::Value});
if (!input) return ParseResult();
parsed.push_back(std::move(*input));
}
- return ParseResult(std::make_unique<Assertion>(it->second, std::move(parsed)));
+ return ParseResult(std::make_unique<Assertion>(type, std::move(parsed)));
}
std::string Assertion::getOperator() const {
- return type::toString(getType());
+ return getType().is<type::Array>() ? "array" : type::toString(getType());
}
EvaluationResult Assertion::evaluate(const EvaluationContext& params) const {
@@ -90,6 +132,31 @@ std::vector<optional<Value>> Assertion::possibleOutputs() const {
return result;
}
+mbgl::Value Assertion::serialize() const {
+ std::vector<mbgl::Value> serialized;
+ serialized.emplace_back(getOperator());
+
+ if (getType().is<type::Array>()) {
+ const auto array = getType().get<type::Array>();
+ if (array.itemType.is<type::StringType>()
+ || array.itemType.is<type::NumberType>()
+ || array.itemType.is<type::BooleanType>()) {
+ serialized.emplace_back(type::toString(array.itemType));
+ if (array.N) {
+ serialized.emplace_back(uint64_t(*array.N));
+ } else if (inputs.size() > 1) {
+ serialized.emplace_back(mbgl::NullValue());
+ }
+ }
+ }
+
+ for (const auto& input : inputs) {
+ serialized.emplace_back(input->serialize());
+ }
+
+ return serialized;
+}
+
} // namespace expression
} // namespace style
} // namespace mbgl