diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2018-03-01 16:02:56 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2018-03-01 17:02:26 -0800 |
commit | 54f3dc961e3a9e668312d7210706cddcf19676f7 (patch) | |
tree | 2606d627a67594a7146aa45e428052c596c99235 | |
parent | 15ba70b5ff018ec2285e0459bf557d1f61240c41 (diff) | |
download | qtlocation-mapboxgl-54f3dc961e3a9e668312d7210706cddcf19676f7.tar.gz |
Relax type checking for "length"
-rw-r--r-- | cmake/core-files.cmake | 2 | ||||
-rw-r--r-- | include/mbgl/style/expression/length.hpp | 32 | ||||
-rw-r--r-- | src/mbgl/style/expression/compound_expression.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/style/expression/length.cpp | 66 | ||||
-rw-r--r-- | src/mbgl/style/expression/parsing_context.cpp | 2 |
5 files changed, 102 insertions, 7 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index f24482e301..a915ffed69 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -456,6 +456,7 @@ set(MBGL_CORE_FILES include/mbgl/style/expression/interpolate.hpp include/mbgl/style/expression/is_constant.hpp include/mbgl/style/expression/is_expression.hpp + include/mbgl/style/expression/length.hpp include/mbgl/style/expression/let.hpp include/mbgl/style/expression/literal.hpp include/mbgl/style/expression/match.hpp @@ -478,6 +479,7 @@ set(MBGL_CORE_FILES src/mbgl/style/expression/interpolate.cpp src/mbgl/style/expression/is_constant.cpp src/mbgl/style/expression/is_expression.cpp + src/mbgl/style/expression/length.cpp src/mbgl/style/expression/let.cpp src/mbgl/style/expression/literal.cpp src/mbgl/style/expression/match.cpp diff --git a/include/mbgl/style/expression/length.hpp b/include/mbgl/style/expression/length.hpp new file mode 100644 index 0000000000..1d754f1932 --- /dev/null +++ b/include/mbgl/style/expression/length.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include <mbgl/style/expression/expression.hpp> +#include <mbgl/style/conversion.hpp> +#include <mbgl/style/expression/parsing_context.hpp> + +#include <memory> +#include <vector> + +namespace mbgl { +namespace style { +namespace expression { + +class Length : public Expression { +public: + Length(std::unique_ptr<Expression> input); + + static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx); + + EvaluationResult evaluate(const EvaluationContext& params) const override; + void eachChild(const std::function<void(const Expression&)>& visit) const override; + bool operator==(const Expression& e) const override; + std::vector<optional<Value>> possibleOutputs() const override; + std::string getOperator() const override { return "length"; } + +private: + std::unique_ptr<Expression> input; +}; + +} // namespace expression +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 86d968c521..b1c2d74a9f 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -271,13 +271,6 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali return object.at(key); }); - define("length", [](const std::vector<Value>& arr) -> Result<double> { - return arr.size(); - }); - define("length", [] (const std::string s) -> Result<double> { - return s.size(); - }); - define("properties", [](const EvaluationContext& params) -> Result<std::unordered_map<std::string, Value>> { if (!params.feature) { return EvaluationError { diff --git a/src/mbgl/style/expression/length.cpp b/src/mbgl/style/expression/length.cpp new file mode 100644 index 0000000000..258353ae4e --- /dev/null +++ b/src/mbgl/style/expression/length.cpp @@ -0,0 +1,66 @@ +#include <mbgl/style/expression/length.hpp> +#include <mbgl/util/string.hpp> + +namespace mbgl { +namespace style { +namespace expression { + +Length::Length(std::unique_ptr<Expression> input_) + : Expression(type::Number), + input(std::move(input_)) { +} + +EvaluationResult Length::evaluate(const EvaluationContext& params) const { + const EvaluationResult value = input->evaluate(params); + if (!value) return value; + return value->match( + [] (const std::string& s) { + return EvaluationResult { double(s.size()) }; + }, + [] (const std::vector<Value>& v) { + return EvaluationResult { double(v.size()) }; + }, + [&] (const auto&) -> EvaluationResult { + return EvaluationError { "Expected value to be of type string or array, but found " + toString(typeOf(*value)) + " instead." }; + }); +} + +void Length::eachChild(const std::function<void(const Expression&)>& visit) const { + visit(*input); +} + +bool Length::operator==(const Expression& e) const { + if (auto eq = dynamic_cast<const Length*>(&e)) { + return *eq->input == *input; + } + return false; +} + +std::vector<optional<Value>> Length::possibleOutputs() const { + return { nullopt }; +} + +using namespace mbgl::style::conversion; +ParseResult Length::parse(const Convertible& value, ParsingContext& ctx) { + std::size_t length = arrayLength(value); + + if (length != 2) { + ctx.error("Expected one argument, but found " + util::toString(length) + " instead."); + return ParseResult(); + } + + ParseResult input = ctx.parse(arrayMember(value, 1), 1); + if (!input) return ParseResult(); + + type::Type type = (*input)->getType(); + if (!type.is<type::Array>() && !type.is<type::StringType>() && !type.is<type::ValueType>()) { + ctx.error("Expected argument of type string or array, but found " + toString(type) + " instead."); + return ParseResult(); + } + + return ParseResult(std::make_unique<Length>(std::move(*input))); +} + +} // namespace expression +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp index 880772d926..364c3f740a 100644 --- a/src/mbgl/style/expression/parsing_context.cpp +++ b/src/mbgl/style/expression/parsing_context.cpp @@ -15,6 +15,7 @@ #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/equals.hpp> #include <mbgl/style/expression/interpolate.hpp> +#include <mbgl/style/expression/length.hpp> #include <mbgl/style/expression/let.hpp> #include <mbgl/style/expression/literal.hpp> #include <mbgl/style/expression/match.hpp> @@ -89,6 +90,7 @@ const ExpressionRegistry& getExpressionRegistry() { {"case", Case::parse}, {"coalesce", Coalesce::parse}, {"interpolate", parseInterpolate}, + {"length", Length::parse}, {"let", Let::parse}, {"literal", Literal::parse}, {"match", parseMatch}, |