#include #include 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 checkSubtype(const Type& expected, const Type& t) { if (t.is()) return {}; optional result = expected.match( [&] (const Array& expectedArray) -> optional { if (!t.is()) { return {errorMessage(expected, t)}; } const auto& actualArray = t.get(); if (!actualArray.N || *actualArray.N != 0 || actualArray.itemType != type::Value) { 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 { if (t.is()) return {}; const Type members[] = { Null, Boolean, Number, String, Object, Color, Formatted, Array(Value) }; for (const auto& member : members) { const auto err = checkSubtype(member, t); if (!err) { return {}; } } return { errorMessage(expected, t) }; }, [&] (const auto&) -> optional { if (expected != t) { return { errorMessage(expected, t) }; } return {}; } ); return result; } } // namespace type } // namespace expression } // namespace style } // namespace mbgl