From 8d3b268ccae7287b63421a6a5cffd92f085b4b8e Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 21 Dec 2022 12:19:23 +0000 Subject: [PATCH] AK: Add JsonObject::get...() methods that return Optional `get()` is intended as a replacement for `get_deprecated()` and `get_ptr ()`. The former returns the same value for "key not found" and "key found and contains `null`" which is ambiguous. The latter returns a raw pointer which is spooky. Returning `Optional` covers all the previous uses for these. The `get_foo()` methods are helpers to make user code less verbose. Most of the time, we only want a specific type of value: if we want a number and get a string, we respond the same as if the value was not there at all. These make that easier to express. This also adjusts the `has_i32()` method and friends to examine the value instead of just looking at the underlying type. --- AK/JsonObject.cpp | 173 ++++++++++++++++++++++++++++++++++++++++------ AK/JsonObject.h | 38 ++++++++++ 2 files changed, 189 insertions(+), 22 deletions(-) diff --git a/AK/JsonObject.cpp b/AK/JsonObject.cpp index e55c2eea0d..51fe34a7ea 100644 --- a/AK/JsonObject.cpp +++ b/AK/JsonObject.cpp @@ -67,6 +67,111 @@ JsonValue const* JsonObject::get_ptr(StringView key) const return &(*it).value; } +Optional JsonObject::get(StringView key) const +{ + auto it = m_members.find(key); + if (it == m_members.end()) + return {}; + return it->value; +} + +Optional JsonObject::get_i8(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_u8(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_i16(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_u16(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_i32(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_u32(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_i64(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_u64(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_addr(StringView key) const +{ + return get_integer(key); +} + +Optional JsonObject::get_bool(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_bool()) + return maybe_value->as_bool(); + return {}; +} + +#if !defined(KERNEL) +Optional JsonObject::get_deprecated_string(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_string()) + return maybe_value->as_string(); + return {}; +} +#endif + +Optional JsonObject::get_object(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_object()) + return maybe_value->as_object(); + return {}; +} + +Optional JsonObject::get_array(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_array()) + return maybe_value->as_array(); + return {}; +} + +#if !defined(KERNEL) +Optional JsonObject::get_double(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_double()) + return maybe_value->as_double(); + return {}; +} + +Optional JsonObject::get_float(StringView key) const +{ + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_double()) + return static_cast(maybe_value->as_double()); + return {}; +} +#endif + bool JsonObject::has(StringView key) const { return m_members.contains(key); @@ -74,69 +179,93 @@ bool JsonObject::has(StringView key) const bool JsonObject::has_null(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_null(); + auto value = get(key); + return value.has_value() && value->is_null(); } bool JsonObject::has_bool(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_bool(); + auto value = get(key); + return value.has_value() && value->is_bool(); } bool JsonObject::has_string(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_string(); + auto value = get(key); + return value.has_value() && value->is_string(); +} + +bool JsonObject::has_i8(StringView key) const +{ + auto value = get(key); + return value.has_value() && value->is_integer(); +} + +bool JsonObject::has_u8(StringView key) const +{ + auto value = get(key); + return value.has_value() && value->is_integer(); +} + +bool JsonObject::has_i16(StringView key) const +{ + auto value = get(key); + return value.has_value() && value->is_integer(); +} + +bool JsonObject::has_u16(StringView key) const +{ + auto value = get(key); + return value.has_value() && value->is_integer(); } bool JsonObject::has_i32(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_i32(); + auto value = get(key); + return value.has_value() && value->is_integer(); } bool JsonObject::has_u32(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_u32(); + auto value = get(key); + return value.has_value() && value->is_integer(); } bool JsonObject::has_i64(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_i64(); + auto value = get(key); + return value.has_value() && value->is_integer(); } bool JsonObject::has_u64(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_u64(); + auto value = get(key); + return value.has_value() && value->is_integer(); } bool JsonObject::has_number(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_number(); + auto value = get(key); + return value.has_value() && value->is_number(); } bool JsonObject::has_array(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_array(); + auto value = get(key); + return value.has_value() && value->is_array(); } bool JsonObject::has_object(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_object(); + auto value = get(key); + return value.has_value() && value->is_object(); } #ifndef KERNEL bool JsonObject::has_double(StringView key) const { - auto const* value = get_ptr(key); - return value && value->is_double(); + auto value = get(key); + return value.has_value() && value->is_double(); } #endif diff --git a/AK/JsonObject.h b/AK/JsonObject.h index 7622a7b783..5e1e8e9376 100644 --- a/AK/JsonObject.h +++ b/AK/JsonObject.h @@ -44,6 +44,10 @@ public: [[nodiscard]] bool has_null(StringView key) const; [[nodiscard]] bool has_bool(StringView key) const; [[nodiscard]] bool has_string(StringView key) const; + [[nodiscard]] bool has_i8(StringView key) const; + [[nodiscard]] bool has_u8(StringView key) const; + [[nodiscard]] bool has_i16(StringView key) const; + [[nodiscard]] bool has_u16(StringView key) const; [[nodiscard]] bool has_i32(StringView key) const; [[nodiscard]] bool has_u32(StringView key) const; [[nodiscard]] bool has_i64(StringView key) const; @@ -55,6 +59,40 @@ public: [[nodiscard]] bool has_double(StringView key) const; #endif + Optional get(StringView key) const; + + template + Optional get_integer(StringView key) const + { + auto maybe_value = get(key); + if (maybe_value.has_value() && maybe_value->is_integer()) + return maybe_value->as_integer(); + return {}; + } + + Optional get_i8(StringView key) const; + Optional get_u8(StringView key) const; + Optional get_i16(StringView key) const; + Optional get_u16(StringView key) const; + Optional get_i32(StringView key) const; + Optional get_u32(StringView key) const; + Optional get_i64(StringView key) const; + Optional get_u64(StringView key) const; + Optional get_addr(StringView key) const; + Optional get_bool(StringView key) const; + +#if !defined(KERNEL) + Optional get_deprecated_string(StringView key) const; +#endif + + Optional get_object(StringView key) const; + Optional get_array(StringView key) const; + +#if !defined(KERNEL) + Optional get_double(StringView key) const; + Optional get_float(StringView key) const; +#endif + void set(DeprecatedString const& key, JsonValue value); template