1 #include <string>
2 #include <mbgl/style/expression/check_subtype.hpp>
3 
4 namespace mbgl {
5 namespace style {
6 namespace expression {
7 namespace type {
8 
errorMessage(const Type & expected,const Type & t)9 std::string errorMessage(const Type& expected, const Type& t) {
10     return {"Expected " + toString(expected) + " but found " + toString(t) + " instead."};
11 }
12 
checkSubtype(const Type & expected,const Type & t)13 optional<std::string> checkSubtype(const Type& expected, const Type& t) {
14     if (t.is<ErrorType>()) return {};
15 
16     optional<std::string> result = expected.match(
17         [&] (const Array& expectedArray) -> optional<std::string> {
18             if (!t.is<Array>()) { return {errorMessage(expected, t)}; }
19             const auto& actualArray = t.get<Array>();
20             const auto err = checkSubtype(expectedArray.itemType, actualArray.itemType);
21             if (err) return { errorMessage(expected, t) };
22             if (expectedArray.N && expectedArray.N != actualArray.N) return { errorMessage(expected, t) };
23             return {};
24         },
25         [&] (const ValueType&) -> optional<std::string> {
26             if (t.is<ValueType>()) return {};
27 
28             const Type members[] = {
29                 Null,
30                 Boolean,
31                 Number,
32                 String,
33                 Object,
34                 Color,
35                 Array(Value)
36             };
37 
38             for (const auto& member : members) {
39                 const auto err = checkSubtype(member, t);
40                 if (!err) {
41                     return {};
42                 }
43             }
44             return { errorMessage(expected, t) };
45         },
46         [&] (const auto&) -> optional<std::string> {
47             if (expected != t) {
48                 return { errorMessage(expected, t) };
49             }
50             return {};
51         }
52     );
53 
54     return result;
55 }
56 
57 } // namespace type
58 } // namespace expression
59 } // namespace style
60 } // namespace mbgl
61