From b995a499d3ba75b0c3efb53abc429f1dfd4da06f Mon Sep 17 00:00:00 2001 From: Emanuel Sprung Date: Tue, 31 Mar 2020 20:44:34 +0200 Subject: [PATCH] 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. --- AK/JsonValue.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ AK/JsonValue.h | 2 ++ 2 files changed, 42 insertions(+) diff --git a/AK/JsonValue.cpp b/AK/JsonValue.cpp index c78c05c8d9d..88b57c98793 100644 --- a/AK/JsonValue.cpp +++ b/AK/JsonValue.cpp @@ -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() == other.to_number()) { + return true; + } +#else + if (is_number() && other.is_number() && to_number() == other.to_number()) { + 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) { diff --git a/AK/JsonValue.h b/AK/JsonValue.h index c0780e331c7..681f1fdcc63 100644 --- a/AK/JsonValue.h +++ b/AK/JsonValue.h @@ -238,6 +238,8 @@ public: return default_value; } + bool equals(const JsonValue& other) const; + private: void clear(); void copy_from(const JsonValue&);