1 #pragma once
2 
3 #include <mbgl/style/property_value.hpp>
4 #include <mbgl/style/conversion.hpp>
5 #include <mbgl/style/conversion/constant.hpp>
6 #include <mbgl/style/conversion/function.hpp>
7 #include <mbgl/style/expression/value.hpp>
8 #include <mbgl/style/expression/is_constant.hpp>
9 #include <mbgl/style/expression/is_expression.hpp>
10 #include <mbgl/style/expression/parsing_context.hpp>
11 #include <mbgl/style/expression/literal.hpp>
12 
13 namespace mbgl {
14 namespace style {
15 namespace conversion {
16 
17 template <class T>
18 struct Converter<PropertyValue<T>> {
operator ()mbgl::style::conversion::Converter19     optional<PropertyValue<T>> operator()(const Convertible& value, Error& error, bool convertTokens = false) const {
20         using namespace mbgl::style::expression;
21 
22         // Only icon-image and text-field support tokens, and they are both data-driven.
23         assert(!convertTokens);
24         (void)convertTokens;
25 
26         if (isUndefined(value)) {
27             return PropertyValue<T>();
28         }
29 
30         optional<PropertyExpression<T>> expression;
31 
32         if (isExpression(value)) {
33             ParsingContext ctx(valueTypeToExpressionType<T>());
34             ParseResult parsed = ctx.parseLayerPropertyExpression(value);
35             if (!parsed) {
36                 error = { ctx.getCombinedErrors() };
37                 return {};
38             }
39             expression = PropertyExpression<T>(std::move(*parsed));
40         } else if (isObject(value)) {
41             expression = convertFunctionToExpression<T>(value, error, false);
42         } else {
43             optional<T> constant = convert<T>(value, error);
44             if (!constant) {
45                 return {};
46             }
47             return { *constant };
48         }
49 
50         if (!expression) {
51             return {};
52         } else if (!(*expression).isFeatureConstant()) {
53             error = { "data expressions not supported" };
54             return {};
55         } else if (!(*expression).isZoomConstant()) {
56             return { std::move(*expression) };
57         } else if ((*expression).getExpression().getKind() == Kind::Literal) {
58             optional<T> constant = fromExpressionValue<T>(
59                 static_cast<const Literal&>((*expression).getExpression()).getValue());
60             if (!constant) {
61                 return {};
62             }
63             return PropertyValue<T>(*constant);
64         } else {
65             assert(false);
66             error = { "expected a literal expression" };
67             return {};
68         }
69     }
70 };
71 
72 } // namespace conversion
73 } // namespace style
74 } // namespace mbgl
75