diff options
Diffstat (limited to 'src/mbgl/style/expression/assertion.cpp')
-rw-r--r-- | src/mbgl/style/expression/assertion.cpp | 79 |
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 |