AK: Add a fallible try_resolve() function to JsonPath

The existing version simply crashed if the expected layout wasn't in
line with reality.
This commit is contained in:
Ali Mohammad Pur
2024-04-26 10:39:03 +02:00
committed by Ali Mohammad Pur
parent 4d1319e798
commit 9a80f2f9ff
2 changed files with 20 additions and 6 deletions

View File

@@ -13,17 +13,30 @@ namespace AK {
JsonPathElement JsonPathElement::any_array_element { Kind::AnyIndex };
JsonPathElement JsonPathElement::any_object_element { Kind::AnyKey };
JsonValue JsonPath::resolve(JsonValue const& top_root) const
ErrorOr<JsonValue> JsonPath::try_resolve(JsonValue const& top_root) const
{
auto root = top_root;
for (auto const& element : *this) {
switch (element.kind()) {
case JsonPathElement::Kind::Key:
root = JsonValue { root.as_object().get(element.key()).value() };
case JsonPathElement::Kind::Key: {
if (!root.is_object())
return Error::from_string_literal("Element is not an object");
auto& object = root.as_object();
auto entry = object.get(element.key());
if (!entry.has_value())
return Error::from_string_literal("Element not found");
root = JsonValue { entry.value() };
break;
case JsonPathElement::Kind::Index:
root = JsonValue { root.as_array().at(element.index()) };
}
case JsonPathElement::Kind::Index: {
if (!root.is_array())
return Error::from_string_literal("Element is not an array");
auto& array = root.as_array();
if (element.index() >= array.size())
return Error::from_string_literal("Element not found");
root = JsonValue { array.at(element.index()) };
break;
}
default:
VERIFY_NOT_REACHED();
}

View File

@@ -89,7 +89,8 @@ private:
class JsonPath : public Vector<JsonPathElement> {
public:
JsonValue resolve(JsonValue const&) const;
JsonValue resolve(JsonValue const& root) const { return MUST(try_resolve(root)); }
ErrorOr<JsonValue> try_resolve(JsonValue const&) const;
ByteString to_byte_string() const;
};