summaryrefslogtreecommitdiff
path: root/src/mbgl/style/expression/check_subtype.cpp
blob: 04a1643f0ca3cf1efd0a8435831451f9f61df6c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <string>
#include <mbgl/style/expression/check_subtype.hpp>

namespace mbgl {
namespace style {
namespace expression {
namespace type {

std::string errorMessage(const Type& expected, const Type& t) {
    return {"Expected " + toString(expected) + " but found " + toString(t) + " instead."};
}

optional<std::string> checkSubtype(const Type& expected, const Type& t) {
    if (t.is<ErrorType>()) return {};
    
    optional<std::string> result = expected.match(
        [&] (const Array& expectedArray) -> optional<std::string> {
            if (!t.is<Array>()) { return {errorMessage(expected, t)}; }
            const auto& actualArray = t.get<Array>();
            const auto err = checkSubtype(expectedArray.itemType, actualArray.itemType);
            if (err) return { errorMessage(expected, t) };
            if (expectedArray.N && expectedArray.N != actualArray.N) return { errorMessage(expected, t) };
            return {};
        },
        [&] (const ValueType&) -> optional<std::string> {
            if (t.is<ValueType>()) return {};
            
            const Type members[] = {
                Null,
                Boolean,
                Number,
                String,
                Object,
                Color,
                Array(Value)
            };
            
            for (const auto& member : members) {
                const auto err = checkSubtype(member, t);
                if (!err) {
                    return {};
                }
            }
            return { errorMessage(expected, t) };
        },
        [&] (const auto&) -> optional<std::string> {
            if (expected != t) {
                return { errorMessage(expected, t) };
            }
            return {};
        }
    );
    
    return result;
}

} // namespace type
} // namespace expression
} // namespace style
} // namespace mbgl