diff options
Diffstat (limited to 'src/mbgl/style/expression/at.cpp')
-rw-r--r-- | src/mbgl/style/expression/at.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/mbgl/style/expression/at.cpp b/src/mbgl/style/expression/at.cpp new file mode 100644 index 0000000000..e447d33bc7 --- /dev/null +++ b/src/mbgl/style/expression/at.cpp @@ -0,0 +1,64 @@ +#include <mbgl/style/expression/at.hpp> +#include <mbgl/util/string.hpp> + + +namespace mbgl { +namespace style { +namespace expression { + +EvaluationResult At::evaluate(const EvaluationContext& params) const { + const EvaluationResult evaluatedIndex = index->evaluate(params); + const EvaluationResult evaluatedInput = input->evaluate(params); + if (!evaluatedIndex) { + return evaluatedIndex.error(); + } + if (!evaluatedInput) { + return evaluatedInput.error(); + } + + const auto i = evaluatedIndex->get<double>(); + const auto inputArray = evaluatedInput->get<std::vector<Value>>(); + + if (i < 0 || i >= inputArray.size()) { + return EvaluationError { + "Array index out of bounds: " + stringify(i) + + " > " + util::toString(inputArray.size()) + "." + }; + } + if (i != std::floor(i)) { + return EvaluationError { + "Array index must be an integer, but found " + stringify(i) + " instead." + }; + } + return inputArray[static_cast<std::size_t>(i)]; +} + +void At::eachChild(const std::function<void(const Expression&)>& visit) const { + visit(*index); + visit(*input); +} + +using namespace mbgl::style::conversion; +ParseResult At::parse(const Convertible& value, ParsingContext& ctx) { + assert(isArray(value)); + + std::size_t length = arrayLength(value); + if (length != 3) { + ctx.error("Expected 2 arguments, but found " + util::toString(length - 1) + " instead."); + return ParseResult(); + } + + ParseResult index = ctx.parse(arrayMember(value, 1), 1, {type::Number}); + + type::Type inputType = type::Array(ctx.getExpected() ? *ctx.getExpected() : type::Value); + ParseResult input = ctx.parse(arrayMember(value, 2), 2, {inputType}); + + if (!index || !input) return ParseResult(); + + return ParseResult(std::make_unique<At>(std::move(*index), std::move(*input))); + +} + +} // namespace expression +} // namespace style +} // namespace mbgl |