#include #include #include #include namespace mbgl { namespace style { namespace expression { Length::Length(std::unique_ptr input_) : Expression(Kind::Length, type::Number, depsOf(input_)), input(std::move(input_)) {} EvaluationResult Length::evaluate(const EvaluationContext& params) const { EvaluationResult value = input->evaluate(params); if (!value) return value; return value->match( [](const std::string& s) { return EvaluationResult{static_cast(unicodeLengthOnValidatedUtf8(s))}; }, [](const std::vector& v) { return EvaluationResult{static_cast(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& visit) const { visit(*input); } bool Length::operator==(const Expression& e) const noexcept { if (e.getKind() == Kind::Length) { auto eq = static_cast(&e); return *eq->input == *input; } return false; } std::vector> Length::possibleOutputs() const { return {std::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.is() && !type.is()) { ctx.error("Expected argument of type string or array, but found " + toString(type) + " instead."); return ParseResult(); } return ParseResult(std::make_unique(std::move(*input))); } } // namespace expression } // namespace style } // namespace mbgl