diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp index ef94ad9cbdf..8b2c5c7e988 100644 --- a/include/mbgl/style/expression/expression.hpp +++ b/include/mbgl/style/expression/expression.hpp @@ -66,7 +66,13 @@ class Result : private variant { } }; -using EvaluationResult = Result; +struct EvaluationResult : public Result { + using Result::Result; + + EvaluationResult(const std::array& arr) : + Result(std::vector(arr.begin(), arr.end())) + {} +}; struct CompileError { std::string message; @@ -80,6 +86,7 @@ class TypedExpression { virtual bool isFeatureConstant() const { return true; } virtual bool isZoomConstant() const { return true; } + virtual EvaluationResult evaluate(const EvaluationParameters& params) const = 0; /* diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 99f0270c1d2..189cb0f6a11 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -119,6 +119,47 @@ std::unordered_map CompoundExpressi define("boolean", assertion), define("array", assertion>), // TODO: [array, type, value], [array, type, length, value] + define("to_string", [](const Value& v) -> Result { return stringify(v); }), + define("to_number", [](const Value& v) -> Result { + optional result = v.match( + [](const float f) -> optional { return f; }, + [](const std::string& s) -> optional { + try { + return std::stof(s); + } catch(std::exception) { + return optional(); + } + }, + [](const auto&) { return optional(); } + ); + if (!result) { + return EvaluationError { + "Could not convert " + stringify(v) + " to number." + }; + } + return *result; + }), + define("to_boolean", [](const Value& v) -> Result { + return v.match( + [&] (float f) { return (bool)f; }, + [&] (const std::string& s) { return s.length() > 0; }, + [&] (bool b) { return b; }, + [&] (const NullValue&) { return false; }, + [&] (const auto&) { return true; } + ); + }), + define("to_rgba", [](const mbgl::Color& color) -> Result> { + return std::array {{ color.r, color.g, color.b, color.a }}; + }), + + define("parse_color", [](const std::string& colorString) -> Result { + const auto& result = mbgl::Color::parse(colorString); + if (result) return *result; + return EvaluationError { + "Could not parse color from value '" + colorString + "'" + }; + }), + std::pair("get", defineGet()), define("+", [](const Varargs& args) -> Result {