AK: Add equals method to JsonValue to semantically compare two values.

This patchsets adds the semantic check of two values. One first approach
was to compare the (generated) json strings of the two values. This works
out in the most cases, but not with numbers, where "1.0" and "1" in JSON
format are semantically the same. Therefore, this patch adds deep (recursive)
check of two JsonValues.
This commit is contained in:
Emanuel Sprung 2020-03-31 20:44:34 +02:00 committed by Andreas Kling
parent c27e8a258a
commit b995a499d3
2 changed files with 42 additions and 0 deletions

View file

@ -89,6 +89,46 @@ JsonValue& JsonValue::operator=(JsonValue&& other)
return *this;
}
bool JsonValue::equals(const JsonValue& other) const
{
if (is_null() && other.is_null())
return true;
if (is_bool() && other.is_bool() && as_bool() == other.as_bool())
return true;
if (is_string() && other.is_string() && as_string() == other.as_string())
return true;
#if !defined(KERNEL) && !defined(BOOTSTRAPPER)
if (is_number() && other.is_number() && to_number<double>() == other.to_number<double>()) {
return true;
}
#else
if (is_number() && other.is_number() && to_number<i64>() == other.to_number<i64>()) {
return true;
}
#endif
if (is_array() && other.is_array() && as_array().size() == other.as_array().size()) {
bool result = true;
for (int i = 0; i < as_array().size(); ++i) {
result &= as_array().at(i).equals(other.as_array().at(i));
}
return result;
}
if (is_object() && other.is_object() && as_object().size() == other.as_object().size()) {
bool result = true;
as_object().for_each_member([&](auto& key, auto& value) {
result &= value.equals(other.as_object().get(key));
});
return result;
}
return false;
}
JsonValue::JsonValue(i32 value)
: m_type(Type::Int32)
{

View file

@ -238,6 +238,8 @@ public:
return default_value;
}
bool equals(const JsonValue& other) const;
private:
void clear();
void copy_from(const JsonValue&);