瀏覽代碼

AK: Make JSON parser return ErrorOr<JsonValue> (instead of Optional)

Also add slightly richer parse errors now that we can include a string
literal with returned errors.

This will allow us to use TRY() when working with JSON data.
Andreas Kling 3 年之前
父節點
當前提交
587f9af960
共有 54 個文件被更改,包括 173 次插入229 次删除
  1. 46 55
      AK/JsonParser.cpp
  2. 11 11
      AK/JsonParser.h
  3. 1 1
      AK/JsonValue.cpp
  4. 1 1
      AK/JsonValue.h
  5. 3 4
      Meta/Lagom/TestJson.cpp
  6. 18 27
      Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp
  7. 4 6
      Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp
  8. 2 3
      Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h
  9. 3 4
      Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
  10. 3 4
      Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp
  11. 4 5
      Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_ValueID_cpp.cpp
  12. 3 4
      Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_ValueID_h.cpp
  13. 3 3
      Tests/AK/TestJSON.cpp
  14. 1 1
      Userland/Applets/Network/main.cpp
  15. 4 6
      Userland/Applets/ResourceGraph/main.cpp
  16. 2 3
      Userland/Applications/KeyboardSettings/main.cpp
  17. 1 1
      Userland/Applications/PixelPaint/ProjectLoader.cpp
  18. 2 3
      Userland/Applications/SpaceAnalyzer/main.cpp
  19. 1 1
      Userland/Applications/Spreadsheet/ImportDialog.cpp
  20. 1 1
      Userland/Applications/Spreadsheet/Spreadsheet.cpp
  21. 2 3
      Userland/Applications/SystemMonitor/MemoryStatsWidget.cpp
  22. 1 1
      Userland/DevTools/Profiler/Profile.cpp
  23. 1 1
      Userland/Libraries/LibCore/EventLoop.cpp
  24. 1 1
      Userland/Libraries/LibCore/ProcessStatisticsReader.cpp
  25. 2 2
      Userland/Libraries/LibCoredump/Reader.cpp
  26. 2 3
      Userland/Libraries/LibDebug/DebugSession.cpp
  27. 2 3
      Userland/Libraries/LibDesktop/Launcher.cpp
  28. 2 2
      Userland/Libraries/LibGUI/CommonLocationsProvider.cpp
  29. 1 1
      Userland/Libraries/LibGUI/GMLParser.cpp
  30. 3 4
      Userland/Libraries/LibGUI/JsonArrayModel.cpp
  31. 1 1
      Userland/Libraries/LibJS/Runtime/JSONObject.cpp
  32. 1 1
      Userland/Libraries/LibKeyboard/CharacterMapFile.cpp
  33. 2 2
      Userland/Libraries/LibSymbolication/Symbolication.cpp
  34. 1 1
      Userland/Libraries/LibTest/JavaScriptTestRunner.h
  35. 2 5
      Userland/Libraries/LibWeb/DOMTreeModel.h
  36. 2 5
      Userland/Libraries/LibWeb/StylePropertiesModel.h
  37. 1 1
      Userland/Services/DHCPClient/DHCPv4Client.cpp
  38. 2 3
      Userland/Services/LookupServer/MulticastDNS.cpp
  39. 2 3
      Userland/Utilities/arp.cpp
  40. 2 3
      Userland/Utilities/df.cpp
  41. 3 3
      Userland/Utilities/fortune.cpp
  42. 1 1
      Userland/Utilities/gron.cpp
  43. 2 3
      Userland/Utilities/ifconfig.cpp
  44. 1 1
      Userland/Utilities/jp.cpp
  45. 1 1
      Userland/Utilities/js.cpp
  46. 2 3
      Userland/Utilities/lsirq.cpp
  47. 2 7
      Userland/Utilities/lsof.cpp
  48. 2 3
      Userland/Utilities/lspci.cpp
  49. 2 3
      Userland/Utilities/lsusb.cpp
  50. 2 3
      Userland/Utilities/mount.cpp
  51. 4 6
      Userland/Utilities/netstat.cpp
  52. 2 3
      Userland/Utilities/pmap.cpp
  53. 1 1
      Userland/Utilities/utmpupdate.cpp
  54. 1 1
      Userland/Utilities/w.cpp

+ 46 - 55
AK/JsonParser.cpp

@@ -16,10 +16,10 @@ constexpr bool is_space(int ch)
     return ch == '\t' || ch == '\n' || ch == '\r' || ch == ' ';
 }
 
-String JsonParser::consume_and_unescape_string()
+ErrorOr<String> JsonParser::consume_and_unescape_string()
 {
     if (!consume_specific('"'))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected '\"'"sv);
     StringBuilder final_sb;
 
     for (;;) {
@@ -32,7 +32,7 @@ String JsonParser::consume_and_unescape_string()
             if (ch == '"' || ch == '\\')
                 break;
             if (is_ascii_c0_control(ch))
-                return {};
+                return Error::from_string_literal("JsonParser: Error while parsing string"sv);
             ++peek_index;
         }
 
@@ -101,97 +101,90 @@ String JsonParser::consume_and_unescape_string()
         if (next_is('u')) {
             ignore();
             if (tell_remaining() < 4)
-                return {};
+                return Error::from_string_literal("JsonParser: EOF while parsing Unicode escape"sv);
 
             auto code_point = AK::StringUtils::convert_to_uint_from_hex(consume(4));
             if (code_point.has_value()) {
                 final_sb.append_code_point(code_point.value());
                 continue;
-            } else {
-                return {};
             }
+            return Error::from_string_literal("JsonParser: Error while parsing Unicode escape"sv);
         }
 
-        return {};
+        return Error::from_string_literal("JsonParser: Error while parsing string"sv);
     }
     if (!consume_specific('"'))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected '\"'"sv);
 
     return final_sb.to_string();
 }
 
-Optional<JsonValue> JsonParser::parse_object()
+ErrorOr<JsonValue> JsonParser::parse_object()
 {
     JsonObject object;
     if (!consume_specific('{'))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected '{'"sv);
     for (;;) {
         ignore_while(is_space);
         if (peek() == '}')
             break;
         ignore_while(is_space);
-        auto name = consume_and_unescape_string();
+        auto name = TRY(consume_and_unescape_string());
         if (name.is_null())
-            return {};
+            return Error::from_string_literal("JsonParser: Expected object property name"sv);
         ignore_while(is_space);
         if (!consume_specific(':'))
-            return {};
+            return Error::from_string_literal("JsonParser: Expected ':'"sv);
         ignore_while(is_space);
-        auto value = parse_helper();
-        if (!value.has_value())
-            return {};
-        object.set(name, value.release_value());
+        auto value = TRY(parse_helper());
+        object.set(name, move(value));
         ignore_while(is_space);
         if (peek() == '}')
             break;
         if (!consume_specific(','))
-            return {};
+            return Error::from_string_literal("JsonParser: Expected ','"sv);
         ignore_while(is_space);
         if (peek() == '}')
-            return {};
+            return Error::from_string_literal("JsonParser: Unexpected '}'"sv);
     }
     if (!consume_specific('}'))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected '}'"sv);
     return JsonValue { move(object) };
 }
 
-Optional<JsonValue> JsonParser::parse_array()
+ErrorOr<JsonValue> JsonParser::parse_array()
 {
     JsonArray array;
     if (!consume_specific('['))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected '['"sv);
     for (;;) {
         ignore_while(is_space);
         if (peek() == ']')
             break;
-        auto element = parse_helper();
-        if (!element.has_value())
-            return {};
-        array.append(element.release_value());
+        auto element = TRY(parse_helper());
+        array.append(move(element));
         ignore_while(is_space);
         if (peek() == ']')
             break;
         if (!consume_specific(','))
-            return {};
+            return Error::from_string_literal("JsonParser: Expected ','"sv);
         ignore_while(is_space);
         if (peek() == ']')
-            return {};
+            return Error::from_string_literal("JsonParser: Unexpected ']'"sv);
     }
     ignore_while(is_space);
     if (!consume_specific(']'))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected ']'"sv);
     return JsonValue { move(array) };
 }
 
-Optional<JsonValue> JsonParser::parse_string()
+ErrorOr<JsonValue> JsonParser::parse_string()
 {
-    auto result = consume_and_unescape_string();
-    if (result.is_null())
-        return {};
-    return JsonValue(result);
+    auto string = TRY(consume_and_unescape_string());
+    return JsonValue(move(string));
 }
 
-Optional<JsonValue> JsonParser::parse_number()
+ErrorOr<JsonValue> JsonParser::parse_number()
 {
     JsonValue value;
     Vector<char, 128> number_buffer;
@@ -202,7 +195,7 @@ Optional<JsonValue> JsonParser::parse_number()
         char ch = peek();
         if (ch == '.') {
             if (is_double)
-                return {};
+                return Error::from_string_literal("JsonParser: Multiple '.' in number"sv);
 
             is_double = true;
             ++m_index;
@@ -211,18 +204,18 @@ Optional<JsonValue> JsonParser::parse_number()
         if (ch == '-' || (ch >= '0' && ch <= '9')) {
             if (is_double) {
                 if (ch == '-')
-                    return {};
+                    return Error::from_string_literal("JsonParser: Error while parsing number"sv);
 
                 fraction_buffer.append(ch);
             } else {
                 if (number_buffer.size() > 0) {
                     if (number_buffer.at(0) == '0')
-                        return {};
+                        return Error::from_string_literal("JsonParser: Error while parsing number"sv);
                 }
 
                 if (number_buffer.size() > 1) {
                     if (number_buffer.at(0) == '-' && number_buffer.at(1) == '0')
-                        return {};
+                        return Error::from_string_literal("JsonParser: Error while parsing number"sv);
                 }
 
                 number_buffer.append(ch);
@@ -245,14 +238,14 @@ Optional<JsonValue> JsonParser::parse_number()
         } else {
             auto number = number_string.to_int();
             if (!number.has_value())
-                return {};
+                return Error::from_string_literal("JsonParser: Error while parsing number"sv);
             whole = number.value();
         }
 
         StringView fraction_string(fraction_buffer.data(), fraction_buffer.size());
         auto fraction_string_uint = fraction_string.to_uint();
         if (!fraction_string_uint.has_value())
-            return {};
+            return Error::from_string_literal("JsonParser: Error while parsing number"sv);
         int fraction = fraction_string_uint.value();
         fraction *= (whole < 0) ? -1 : 1;
 
@@ -273,7 +266,7 @@ Optional<JsonValue> JsonParser::parse_number()
         } else {
             auto number = number_string.to_int<i64>();
             if (!number.has_value())
-                return {};
+                return Error::from_string_literal("JsonParser: Error while parsing number"sv);
             if (number.value() <= NumericLimits<i32>::max()) {
                 value = JsonValue((i32)number.value());
             } else {
@@ -287,28 +280,28 @@ Optional<JsonValue> JsonParser::parse_number()
     return value;
 }
 
-Optional<JsonValue> JsonParser::parse_true()
+ErrorOr<JsonValue> JsonParser::parse_true()
 {
     if (!consume_specific("true"))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected 'true'"sv);
     return JsonValue(true);
 }
 
-Optional<JsonValue> JsonParser::parse_false()
+ErrorOr<JsonValue> JsonParser::parse_false()
 {
     if (!consume_specific("false"))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected 'false'"sv);
     return JsonValue(false);
 }
 
-Optional<JsonValue> JsonParser::parse_null()
+ErrorOr<JsonValue> JsonParser::parse_null()
 {
     if (!consume_specific("null"))
-        return {};
+        return Error::from_string_literal("JsonParser: Expected 'null'"sv);
     return JsonValue(JsonValue::Type::Null);
 }
 
-Optional<JsonValue> JsonParser::parse_helper()
+ErrorOr<JsonValue> JsonParser::parse_helper()
 {
     ignore_while(is_space);
     auto type_hint = peek();
@@ -339,17 +332,15 @@ Optional<JsonValue> JsonParser::parse_helper()
         return parse_null();
     }
 
-    return {};
+    return Error::from_string_literal("JsonParser: Unexpected character"sv);
 }
 
-Optional<JsonValue> JsonParser::parse()
+ErrorOr<JsonValue> JsonParser::parse()
 {
-    auto result = parse_helper();
-    if (!result.has_value())
-        return {};
+    auto result = TRY(parse_helper());
     ignore_while(is_space);
     if (!is_eof())
-        return {};
+        return Error::from_string_literal("JsonParser: Didn't consume all input"sv);
     return result;
 }
 

+ 11 - 11
AK/JsonParser.h

@@ -18,19 +18,19 @@ public:
     {
     }
 
-    Optional<JsonValue> parse();
+    ErrorOr<JsonValue> parse();
 
 private:
-    Optional<JsonValue> parse_helper();
-
-    String consume_and_unescape_string();
-    Optional<JsonValue> parse_array();
-    Optional<JsonValue> parse_object();
-    Optional<JsonValue> parse_number();
-    Optional<JsonValue> parse_string();
-    Optional<JsonValue> parse_false();
-    Optional<JsonValue> parse_true();
-    Optional<JsonValue> parse_null();
+    ErrorOr<JsonValue> parse_helper();
+
+    ErrorOr<String> consume_and_unescape_string();
+    ErrorOr<JsonValue> parse_array();
+    ErrorOr<JsonValue> parse_object();
+    ErrorOr<JsonValue> parse_number();
+    ErrorOr<JsonValue> parse_string();
+    ErrorOr<JsonValue> parse_false();
+    ErrorOr<JsonValue> parse_true();
+    ErrorOr<JsonValue> parse_null();
 
     String m_last_string_starting_with_character[256];
 };

+ 1 - 1
AK/JsonValue.cpp

@@ -228,7 +228,7 @@ void JsonValue::clear()
 }
 
 #ifndef KERNEL
-Optional<JsonValue> JsonValue::from_string(StringView input)
+ErrorOr<JsonValue> JsonValue::from_string(StringView input)
 {
     return JsonParser(input).parse();
 }

+ 1 - 1
AK/JsonValue.h

@@ -30,7 +30,7 @@ public:
         Object,
     };
 
-    static Optional<JsonValue> from_string(StringView);
+    static ErrorOr<JsonValue> from_string(StringView);
 
     explicit JsonValue(Type = Type::Null);
     ~JsonValue() { clear(); }

+ 3 - 4
Meta/Lagom/TestJson.cpp

@@ -10,9 +10,8 @@
 
 int main(int, char**)
 {
-    auto value = JsonValue::from_string("{\"property\": \"value\"}");
-    VERIFY(value.has_value());
-    printf("parsed: _%s_\n", value.value().to_string().characters());
-    printf("object.property = '%s'\n", value.value().as_object().get("property").to_string().characters());
+    auto value = JsonValue::from_string("{\"property\": \"value\"}").release_value_but_fixme_should_propagate_errors();
+    printf("parsed: _%s_\n", value.to_string().characters());
+    printf("object.property = '%s'\n", value.as_object().get("property").to_string().characters());
     return 0;
 }

+ 18 - 27
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp

@@ -96,10 +96,9 @@ static void parse_core_aliases(String core_supplemental_path, UnicodeLocaleData&
     auto core_aliases_file_or_error = Core::File::open(core_aliases_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!core_aliases_file_or_error.is_error());
 
-    auto core_aliases = JsonParser(core_aliases_file_or_error.value()->read_all()).parse();
-    VERIFY(core_aliases.has_value());
+    auto core_aliases = JsonValue::from_string(core_aliases_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& supplemental_object = core_aliases->as_object().get("supplemental"sv);
+    auto const& supplemental_object = core_aliases.as_object().get("supplemental"sv);
     auto const& metadata_object = supplemental_object.as_object().get("metadata"sv);
     auto const& alias_object = metadata_object.as_object().get("alias"sv);
 
@@ -137,10 +136,9 @@ static void parse_likely_subtags(String core_supplemental_path, UnicodeLocaleDat
     auto likely_subtags_file_or_error = Core::File::open(likely_subtags_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!likely_subtags_file_or_error.is_error());
 
-    auto likely_subtags = JsonParser(likely_subtags_file_or_error.value()->read_all()).parse();
-    VERIFY(likely_subtags.has_value());
+    auto likely_subtags = JsonValue::from_string(likely_subtags_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& supplemental_object = likely_subtags->as_object().get("supplemental"sv);
+    auto const& supplemental_object = likely_subtags.as_object().get("supplemental"sv);
     auto const& likely_subtags_object = supplemental_object.as_object().get("likelySubtags"sv);
 
     likely_subtags_object.as_object().for_each_member([&](auto const& key, JsonValue const& value) {
@@ -163,10 +161,9 @@ static void parse_identity(String locale_path, UnicodeLocaleData& locale_data, L
     auto languages_file_or_error = Core::File::open(languages_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!languages_file_or_error.is_error());
 
-    auto languages = JsonParser(languages_file_or_error.value()->read_all()).parse();
-    VERIFY(languages.has_value());
+    auto languages = JsonValue::from_string(languages_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = languages->as_object().get("main"sv);
+    auto const& main_object = languages.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(languages_path.parent().basename());
     auto const& identity_object = locale_object.as_object().get("identity"sv);
     auto const& language_string = identity_object.as_object().get("language"sv);
@@ -199,10 +196,9 @@ static void parse_locale_languages(String locale_path, UnicodeLocaleData& locale
     auto languages_file_or_error = Core::File::open(languages_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!languages_file_or_error.is_error());
 
-    auto languages = JsonParser(languages_file_or_error.value()->read_all()).parse();
-    VERIFY(languages.has_value());
+    auto languages = JsonValue::from_string(languages_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = languages->as_object().get("main"sv);
+    auto const& main_object = languages.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(languages_path.parent().basename());
     auto const& locale_display_names_object = locale_object.as_object().get("localeDisplayNames"sv);
     auto const& languages_object = locale_display_names_object.as_object().get("languages"sv);
@@ -225,10 +221,9 @@ static void parse_locale_territories(String locale_path, UnicodeLocaleData& loca
     auto territories_file_or_error = Core::File::open(territories_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!territories_file_or_error.is_error());
 
-    auto territories = JsonParser(territories_file_or_error.value()->read_all()).parse();
-    VERIFY(territories.has_value());
+    auto territories = JsonValue::from_string(territories_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = territories->as_object().get("main"sv);
+    auto const& main_object = territories.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(territories_path.parent().basename());
     auto const& locale_display_names_object = locale_object.as_object().get("localeDisplayNames"sv);
     auto const& territories_object = locale_display_names_object.as_object().get("territories"sv);
@@ -251,10 +246,9 @@ static void parse_locale_scripts(String locale_path, UnicodeLocaleData& locale_d
     auto scripts_file_or_error = Core::File::open(scripts_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!scripts_file_or_error.is_error());
 
-    auto scripts = JsonParser(scripts_file_or_error.value()->read_all()).parse();
-    VERIFY(scripts.has_value());
+    auto scripts = JsonValue::from_string(scripts_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = scripts->as_object().get("main"sv);
+    auto const& main_object = scripts.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(scripts_path.parent().basename());
     auto const& locale_display_names_object = locale_object.as_object().get("localeDisplayNames"sv);
     auto const& scripts_object = locale_display_names_object.as_object().get("scripts"sv);
@@ -277,10 +271,9 @@ static void parse_locale_list_patterns(String misc_path, UnicodeLocaleData& loca
     auto list_patterns_file_or_error = Core::File::open(list_patterns_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!list_patterns_file_or_error.is_error());
 
-    auto list_patterns = JsonParser(list_patterns_file_or_error.value()->read_all()).parse();
-    VERIFY(list_patterns.has_value());
+    auto list_patterns = JsonValue::from_string(list_patterns_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = list_patterns->as_object().get("main"sv);
+    auto const& main_object = list_patterns.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(list_patterns_path.parent().basename());
     auto const& list_patterns_object = locale_object.as_object().get("listPatterns"sv);
 
@@ -329,10 +322,9 @@ static void parse_locale_currencies(String numbers_path, UnicodeLocaleData& loca
     auto currencies_file_or_error = Core::File::open(currencies_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!currencies_file_or_error.is_error());
 
-    auto currencies = JsonParser(currencies_file_or_error.value()->read_all()).parse();
-    VERIFY(currencies.has_value());
+    auto currencies = JsonValue::from_string(currencies_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = currencies->as_object().get("main"sv);
+    auto const& main_object = currencies.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(currencies_path.parent().basename());
     auto const& locale_numbers_object = locale_object.as_object().get("numbers"sv);
     auto const& currencies_object = locale_numbers_object.as_object().get("currencies"sv);
@@ -364,10 +356,9 @@ static void parse_numeric_keywords(String locale_numbers_path, UnicodeLocaleData
     auto numbers_file_or_error = Core::File::open(numbers_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!numbers_file_or_error.is_error());
 
-    auto numbers = JsonParser(numbers_file_or_error.value()->read_all()).parse();
-    VERIFY(numbers.has_value());
+    auto numbers = JsonValue::from_string(numbers_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = numbers->as_object().get("main"sv);
+    auto const& main_object = numbers.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(numbers_path.parent().basename());
     auto const& locale_numbers_object = locale_object.as_object().get("numbers"sv);
     auto const& default_numbering_system_object = locale_numbers_object.as_object().get("defaultNumberingSystem"sv);

+ 4 - 6
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp

@@ -240,10 +240,9 @@ static void parse_number_systems(String locale_numbers_path, UnicodeLocaleData&
     auto numbers_file_or_error = Core::File::open(numbers_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!numbers_file_or_error.is_error());
 
-    auto numbers = JsonParser(numbers_file_or_error.value()->read_all()).parse();
-    VERIFY(numbers.has_value());
+    auto numbers = JsonValue::from_string(numbers_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = numbers->as_object().get("main"sv);
+    auto const& main_object = numbers.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(numbers_path.parent().basename());
     auto const& locale_numbers_object = locale_object.as_object().get("numbers"sv);
 
@@ -360,10 +359,9 @@ static void parse_units(String locale_units_path, UnicodeLocaleData& locale_data
     auto units_file_or_error = Core::File::open(units_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!units_file_or_error.is_error());
 
-    auto units = JsonParser(units_file_or_error.value()->read_all()).parse();
-    VERIFY(units.has_value());
+    auto units = JsonValue::from_string(units_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& main_object = units->as_object().get("main"sv);
+    auto const& main_object = units.as_object().get("main"sv);
     auto const& locale_object = main_object.as_object().get(units_path.parent().basename());
     auto const& locale_units_object = locale_object.as_object().get("units"sv);
     auto const& long_object = locale_units_object.as_object().get("long"sv);

+ 2 - 3
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h

@@ -161,10 +161,9 @@ void parse_default_content_locales(String core_path, LocaleDataType& locale_data
     auto default_content_file_or_error = Core::File::open(default_content_path.string(), Core::OpenMode::ReadOnly);
     VERIFY(!default_content_file_or_error.is_error());
 
-    auto default_content = JsonParser(default_content_file_or_error.value()->read_all()).parse();
-    VERIFY(default_content.has_value());
+    auto default_content = JsonValue::from_string(default_content_file_or_error.value()->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    auto const& default_content_array = default_content->as_object().get("defaultContent"sv);
+    auto const& default_content_array = default_content.as_object().get("defaultContent"sv);
 
     default_content_array.as_array().for_each([&](JsonValue const& value) {
         auto locale = value.as_string();

+ 3 - 4
Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp

@@ -58,11 +58,10 @@ int main(int argc, char** argv)
     if (!file->open(Core::OpenMode::ReadOnly))
         return 1;
 
-    auto json = JsonValue::from_string(file->read_all());
-    VERIFY(json.has_value());
-    VERIFY(json.value().is_object());
+    auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
+    VERIFY(json.is_object());
 
-    auto& properties = json.value().as_object();
+    auto& properties = json.as_object();
 
     StringBuilder builder;
     SourceGenerator generator { builder };

+ 3 - 4
Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp

@@ -36,9 +36,8 @@ int main(int argc, char** argv)
     if (!file->open(Core::OpenMode::ReadOnly))
         return 1;
 
-    auto json = JsonValue::from_string(file->read_all());
-    VERIFY(json.has_value());
-    VERIFY(json.value().is_object());
+    auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
+    VERIFY(json.is_object());
 
     StringBuilder builder;
     SourceGenerator generator { builder };
@@ -60,7 +59,7 @@ enum class PropertyID {
     Vector<String> shorthand_property_ids;
     Vector<String> longhand_property_ids;
 
-    json.value().as_object().for_each_member([&](auto& name, auto& value) {
+    json.as_object().for_each_member([&](auto& name, auto& value) {
         VERIFY(value.is_object());
         if (value.as_object().has("longhands"))
             shorthand_property_ids.append(name);

+ 4 - 5
Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_ValueID_cpp.cpp

@@ -36,9 +36,8 @@ int main(int argc, char** argv)
     if (!file->open(Core::OpenMode::ReadOnly))
         return 1;
 
-    auto json = JsonValue::from_string(file->read_all());
-    VERIFY(json.has_value());
-    VERIFY(json.value().is_array());
+    auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
+    VERIFY(json.is_array());
 
     StringBuilder builder;
     SourceGenerator generator { builder };
@@ -53,7 +52,7 @@ ValueID value_id_from_string(StringView string)
 {
 )~~~");
 
-    json.value().as_array().for_each([&](auto& name) {
+    json.as_array().for_each([&](auto& name) {
         auto member_generator = generator.fork();
         member_generator.set("name", name.to_string());
         member_generator.set("name:titlecase", title_casify(name.to_string()));
@@ -71,7 +70,7 @@ const char* string_from_value_id(ValueID value_id) {
     switch (value_id) {
 )~~~");
 
-    json.value().as_array().for_each([&](auto& name) {
+    json.as_array().for_each([&](auto& name) {
         auto member_generator = generator.fork();
         member_generator.set("name", name.to_string());
         member_generator.set("name:titlecase", title_casify(name.to_string()));

+ 3 - 4
Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_ValueID_h.cpp

@@ -36,9 +36,8 @@ int main(int argc, char** argv)
     if (!file->open(Core::OpenMode::ReadOnly))
         return 1;
 
-    auto json = JsonValue::from_string(file->read_all());
-    VERIFY(json.has_value());
-    VERIFY(json.value().is_array());
+    auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
+    VERIFY(json.is_array());
 
     StringBuilder builder;
     SourceGenerator generator { builder };
@@ -54,7 +53,7 @@ enum class ValueID {
     Invalid,
 )~~~");
 
-    json.value().as_array().for_each([&](auto& name) {
+    json.as_array().for_each([&](auto& name) {
         auto member_generator = generator.fork();
         member_generator.set("name:titlecase", title_casify(name.to_string()));
 

+ 3 - 3
Tests/AK/TestJSON.cpp

@@ -86,7 +86,7 @@ FIXME: Parse JSON from a Utf8View
 TEST_CASE(json_utf8_multibyte)
 {
     auto json_or_error = JsonValue::from_string("\"š\"");
-    EXPECT_EQ(json_or_error.has_value(), true);
+    EXPECT_EQ(json_or_error.is_error(), false);
     
     auto& json = json_or_error.value();
     EXPECT_EQ(json.type(), JsonValue::Type::String);
@@ -119,6 +119,6 @@ TEST_CASE(json_u64_roundtrip)
     auto big_value = 0xffffffffffffffffull;
     auto json = JsonValue(big_value).to_string();
     auto value = JsonValue::from_string(json);
-    EXPECT_EQ_FORCE(value.has_value(), true);
-    EXPECT_EQ(value->as_u64(), big_value);
+    EXPECT_EQ_FORCE(value.is_error(), false);
+    EXPECT_EQ(value.value().as_u64(), big_value);
 }

+ 1 - 1
Userland/Applets/Network/main.cpp

@@ -115,7 +115,7 @@ private:
         auto file_contents = file->read_all();
         auto json = JsonValue::from_string(file_contents);
 
-        if (!json.has_value())
+        if (json.is_error())
             return adapter_info.to_string();
 
         int connected_adapters = 0;

+ 4 - 6
Userland/Applets/ResourceGraph/main.cpp

@@ -135,9 +135,8 @@ private:
         }
 
         auto file_contents = m_proc_stat->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
-        auto& obj = json.value().as_object();
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+        auto const& obj = json.as_object();
         total = obj.get("total_time").to_u64();
         idle = obj.get("idle_time").to_u64();
         return true;
@@ -157,9 +156,8 @@ private:
         }
 
         auto file_contents = m_proc_mem->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
-        auto& obj = json.value().as_object();
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+        auto const& obj = json.as_object();
         unsigned kmalloc_allocated = obj.get("kmalloc_allocated").to_u32();
         unsigned kmalloc_available = obj.get("kmalloc_available").to_u32();
         auto user_physical_allocated = obj.get("user_physical_allocated").to_u64();

+ 2 - 3
Userland/Applications/KeyboardSettings/main.cpp

@@ -67,9 +67,8 @@ int main(int argc, char** argv)
     if (!proc_keymap->open(Core::OpenMode::ReadOnly))
         VERIFY_NOT_REACHED();
 
-    auto json = JsonValue::from_string(proc_keymap->read_all());
-    VERIFY(json.has_value());
-    JsonObject keymap_object = json.value().as_object();
+    auto json = JsonValue::from_string(proc_keymap->read_all()).release_value_but_fixme_should_propagate_errors();
+    auto const& keymap_object = json.as_object();
     VERIFY(keymap_object.has("keymap"));
     String current_keymap = keymap_object.get("keymap").to_string();
     dbgln("KeyboardSettings thinks the current keymap is: {}", current_keymap);

+ 1 - 1
Userland/Applications/PixelPaint/ProjectLoader.cpp

@@ -26,7 +26,7 @@ ErrorOr<void> ProjectLoader::try_load_from_fd_and_close(int fd, StringView path)
     auto contents = file->read_all();
 
     auto json_or_error = JsonValue::from_string(contents);
-    if (!json_or_error.has_value()) {
+    if (json_or_error.is_error()) {
         m_is_raw_image = true;
 
         auto mapped_file = TRY(MappedFile::map_from_fd_and_close(fd, path));

+ 2 - 3
Userland/Applications/SpaceAnalyzer/main.cpp

@@ -84,10 +84,9 @@ static void fill_mounts(Vector<MountInfo>& output)
     }
 
     auto content = file->read_all();
-    auto json = JsonValue::from_string(content);
-    VERIFY(json.has_value());
+    auto json = JsonValue::from_string(content).release_value_but_fixme_should_propagate_errors();
 
-    json.value().as_array().for_each([&output](auto& value) {
+    json.as_array().for_each([&output](auto& value) {
         auto& filesystem_object = value.as_object();
         MountInfo mount_info;
         mount_info.mount_point = filesystem_object.get("mount_point").to_string();

+ 1 - 1
Userland/Applications/Spreadsheet/ImportDialog.cpp

@@ -209,7 +209,7 @@ Result<NonnullRefPtrVector<Sheet>, String> ImportDialog::make_and_run_for(String
 
     auto import_worksheet = [&]() -> Result<NonnullRefPtrVector<Sheet>, String> {
         auto json_value_option = JsonParser(file.read_all()).parse();
-        if (!json_value_option.has_value()) {
+        if (json_value_option.is_error()) {
             StringBuilder sb;
             sb.append("Failed to parse ");
             sb.append(file.filename());

+ 1 - 1
Userland/Applications/Spreadsheet/Spreadsheet.cpp

@@ -667,7 +667,7 @@ JsonObject Sheet::gather_documentation() const
         JsonParser parser(doc.to_string_without_side_effects());
         auto doc_object = parser.parse();
 
-        if (doc_object.has_value())
+        if (!doc_object.is_error())
             object.set(it.key.to_display_string(), doc_object.value());
         else
             dbgln("Sheet::gather_documentation(): Failed to parse the documentation for '{}'!", it.key.to_display_string());

+ 2 - 3
Userland/Applications/SystemMonitor/MemoryStatsWidget.cpp

@@ -84,9 +84,8 @@ void MemoryStatsWidget::refresh()
         VERIFY_NOT_REACHED();
 
     auto file_contents = proc_memstat->read_all();
-    auto json_result = JsonValue::from_string(file_contents);
-    VERIFY(json_result.has_value());
-    auto json = json_result.value().as_object();
+    auto json_result = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+    auto const& json = json_result.as_object();
 
     [[maybe_unused]] u32 kmalloc_eternal_allocated = json.get("kmalloc_eternal_allocated").to_u32();
     u32 kmalloc_allocated = json.get("kmalloc_allocated").to_u32();

+ 1 - 1
Userland/DevTools/Profiler/Profile.cpp

@@ -220,7 +220,7 @@ ErrorOr<NonnullOwnPtr<Profile>> Profile::load_from_perfcore_file(StringView path
     auto file = TRY(Core::File::open(path, Core::OpenMode::ReadOnly));
 
     auto json = JsonValue::from_string(file->read_all());
-    if (!json.has_value() || !json.value().is_object())
+    if (json.is_error() || !json.value().is_object())
         return Error::from_string_literal("Invalid perfcore format (not a JSON object)"sv);
 
     auto& object = json.value().as_object();

+ 1 - 1
Userland/Libraries/LibCore/EventLoop.cpp

@@ -144,7 +144,7 @@ private:
             auto request = m_socket->read(length);
 
             auto request_json = JsonValue::from_string(request);
-            if (!request_json.has_value() || !request_json.value().is_object()) {
+            if (request_json.is_error() || !request_json.value().is_object()) {
                 dbgln("RPC client sent invalid request");
                 shutdown();
                 return;

+ 1 - 1
Userland/Libraries/LibCore/ProcessStatisticsReader.cpp

@@ -35,7 +35,7 @@ Optional<AllProcessesStatistics> ProcessStatisticsReader::get_all(RefPtr<Core::F
 
     auto file_contents = proc_all_file->read_all();
     auto json = JsonValue::from_string(file_contents);
-    if (!json.has_value())
+    if (json.is_error())
         return {};
 
     auto& json_obj = json.value().as_object();

+ 2 - 2
Userland/Libraries/LibCoredump/Reader.cpp

@@ -149,7 +149,7 @@ const JsonObject Reader::process_info() const
     if (!process_info_notes_entry)
         return {};
     auto process_info_json_value = JsonValue::from_string(process_info_notes_entry->json_data);
-    if (!process_info_json_value.has_value())
+    if (process_info_json_value.is_error())
         return {};
     if (!process_info_json_value.value().is_object())
         return {};
@@ -247,7 +247,7 @@ HashMap<String, String> Reader::metadata() const
     if (!metadata_notes_entry)
         return {};
     auto metadata_json_value = JsonValue::from_string(metadata_notes_entry->json_data);
-    if (!metadata_json_value.has_value())
+    if (metadata_json_value.is_error())
         return {};
     if (!metadata_json_value.value().is_object())
         return {};

+ 2 - 3
Userland/Libraries/LibDebug/DebugSession.cpp

@@ -405,10 +405,9 @@ void DebugSession::update_loaded_libs()
     VERIFY(rc);
 
     auto file_contents = file->read_all();
-    auto json = JsonValue::from_string(file_contents);
-    VERIFY(json.has_value());
+    auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
-    auto vm_entries = json.value().as_array();
+    auto const& vm_entries = json.as_array();
     Regex<PosixExtended> segment_name_re("(.+): ");
 
     auto get_path_to_object = [&segment_name_re](String const& vm_name) -> Optional<String> {

+ 2 - 3
Userland/Libraries/LibDesktop/Launcher.cpp

@@ -17,9 +17,8 @@ namespace Desktop {
 auto Launcher::Details::from_details_str(const String& details_str) -> NonnullRefPtr<Details>
 {
     auto details = adopt_ref(*new Details);
-    auto json = JsonValue::from_string(details_str);
-    VERIFY(json.has_value());
-    auto obj = json.value().as_object();
+    auto json = JsonValue::from_string(details_str).release_value_but_fixme_should_propagate_errors();
+    auto const& obj = json.as_object();
     details->executable = obj.get("executable").to_string();
     details->name = obj.get("name").to_string();
     if (auto type_value = obj.get_ptr("type")) {

+ 2 - 2
Userland/Libraries/LibGUI/CommonLocationsProvider.cpp

@@ -45,7 +45,7 @@ void CommonLocationsProvider::load_from_json(const String& json_path)
     }
 
     auto json = JsonValue::from_string(file->read_all());
-    if (!json.has_value()) {
+    if (json.is_error()) {
         dbgln("Common locations file {} is not a valid JSON file.", file->filename());
         return;
     }
@@ -55,7 +55,7 @@ void CommonLocationsProvider::load_from_json(const String& json_path)
     }
 
     s_common_locations.clear();
-    auto contents = json.value().as_array();
+    auto const& contents = json.value().as_array();
     for (size_t i = 0; i < contents.size(); ++i) {
         auto entry_value = contents.at(i);
         if (!entry_value.is_object())

+ 1 - 1
Userland/Libraries/LibGUI/GMLParser.cpp

@@ -94,7 +94,7 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
             } else if (peek() == GMLToken::Type::JsonValue) {
                 auto value_string = tokens.dequeue();
                 auto parsed_value = JsonValue::from_string(value_string.m_view);
-                if (!parsed_value.has_value()) {
+                if (parsed_value.is_error()) {
                     dbgln("Expected property to be JSON value");
                     return {};
                 }

+ 3 - 4
Userland/Libraries/LibGUI/JsonArrayModel.cpp

@@ -20,11 +20,10 @@ void JsonArrayModel::invalidate()
         return;
     }
 
-    auto json = JsonValue::from_string(file->read_all());
+    auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
 
-    VERIFY(json.has_value());
-    VERIFY(json.value().is_array());
-    m_array = json.value().as_array();
+    VERIFY(json.is_array());
+    m_array = json.as_array();
 
     did_update();
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/JSONObject.cpp

@@ -352,7 +352,7 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
     auto reviver = vm.argument(1);
 
     auto json = JsonValue::from_string(string);
-    if (!json.has_value())
+    if (json.is_error())
         return vm.throw_completion<SyntaxError>(global_object, ErrorType::JsonMalformed);
     Value unfiltered = parse_json_value(global_object, json.value());
     if (reviver.is_function()) {

+ 1 - 1
Userland/Libraries/LibKeyboard/CharacterMapFile.cpp

@@ -31,7 +31,7 @@ Optional<CharacterMapData> CharacterMapFile::load_from_file(const String& filena
 
     auto file_contents = file->read_all();
     auto json_result = JsonValue::from_string(file_contents);
-    if (!json_result.has_value()) {
+    if (json_result.is_error()) {
         dbgln("Failed to load character map from file {}", path);
         return {};
     }

+ 2 - 2
Userland/Libraries/LibSymbolication/Symbolication.cpp

@@ -158,7 +158,7 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid, IncludeSourcePosition in
         }
 
         auto json = JsonValue::from_string(file_or_error.value()->read_all());
-        if (!json.has_value() || !json.value().is_array()) {
+        if (json.is_error() || !json.value().is_array()) {
             warnln("Invalid contents in {}", stack_path);
             return {};
         }
@@ -178,7 +178,7 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid, IncludeSourcePosition in
         }
 
         auto json = JsonValue::from_string(file_or_error.value()->read_all());
-        if (!json.has_value() || !json.value().is_array()) {
+        if (json.is_error() || !json.value().is_array()) {
             warnln("Invalid contents in {}", vm_path);
             return {};
         }

+ 1 - 1
Userland/Libraries/LibTest/JavaScriptTestRunner.h

@@ -241,7 +241,7 @@ inline Optional<JsonValue> get_test_results(JS::Interpreter& interpreter)
     auto json_string = TRY_OR_DISCARD(JS::JSONObject::stringify_impl(interpreter.global_object(), results, JS::js_undefined(), JS::js_undefined()));
 
     auto json = JsonValue::from_string(json_string);
-    if (!json.has_value())
+    if (json.is_error())
         return {};
 
     return json.value();

+ 2 - 5
Userland/Libraries/LibWeb/DOMTreeModel.h

@@ -18,11 +18,8 @@ class DOMTreeModel final : public GUI::Model {
 public:
     static NonnullRefPtr<DOMTreeModel> create(StringView dom_tree, GUI::TreeView& tree_view)
     {
-        auto json_or_error = JsonValue::from_string(dom_tree);
-        if (!json_or_error.has_value())
-            VERIFY_NOT_REACHED();
-
-        return adopt_ref(*new DOMTreeModel(json_or_error.value().as_object(), tree_view));
+        auto json_or_error = JsonValue::from_string(dom_tree).release_value_but_fixme_should_propagate_errors();
+        return adopt_ref(*new DOMTreeModel(json_or_error.as_object(), tree_view));
     }
 
     virtual ~DOMTreeModel() override;

+ 2 - 5
Userland/Libraries/LibWeb/StylePropertiesModel.h

@@ -23,11 +23,8 @@ public:
 
     static NonnullRefPtr<StylePropertiesModel> create(StringView properties)
     {
-        auto json_or_error = JsonValue::from_string(properties);
-        if (!json_or_error.has_value())
-            VERIFY_NOT_REACHED();
-
-        return adopt_ref(*new StylePropertiesModel(json_or_error.value().as_object()));
+        auto json_or_error = JsonValue::from_string(properties).release_value_but_fixme_should_propagate_errors();
+        return adopt_ref(*new StylePropertiesModel(json_or_error.as_object()));
     }
 
     virtual ~StylePropertiesModel() override;

+ 1 - 1
Userland/Services/DHCPClient/DHCPv4Client.cpp

@@ -169,7 +169,7 @@ ErrorOr<DHCPv4Client::Interfaces> DHCPv4Client::get_discoverable_interfaces()
     auto file_contents = file->read_all();
     auto json = JsonValue::from_string(file_contents);
 
-    if (!json.has_value() || !json.value().is_array()) {
+    if (json.is_error() || !json.value().is_array()) {
         dbgln("Error: No network adapters available");
         return Error::from_string_literal("No network adapters available"sv);
     }

+ 2 - 3
Userland/Services/LookupServer/MulticastDNS.cpp

@@ -121,12 +121,11 @@ Vector<IPv4Address> MulticastDNS::local_addresses() const
     }
 
     auto file_contents = file->read_all();
-    auto json = JsonValue::from_string(file_contents);
-    VERIFY(json.has_value());
+    auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
     Vector<IPv4Address> addresses;
 
-    json.value().as_array().for_each([&addresses](auto& value) {
+    json.as_array().for_each([&addresses](auto& value) {
         auto if_object = value.as_object();
         auto address = if_object.get("ipv4_address").to_string();
         auto ipv4_address = IPv4Address::from_string(address);

+ 2 - 3
Userland/Utilities/arp.cpp

@@ -100,10 +100,9 @@ int main(int argc, char** argv)
         }
 
         auto file_contents = file->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
-        Vector<JsonValue> sorted_regions = json.value().as_array().values();
+        Vector<JsonValue> sorted_regions = json.as_array().values();
         quick_sort(sorted_regions, [](auto& a, auto& b) {
             return a.as_object().get("ip_address").to_string() < b.as_object().get("ip_address").to_string();
         });

+ 2 - 3
Userland/Utilities/df.cpp

@@ -47,9 +47,8 @@ int main(int argc, char** argv)
     }
 
     auto file_contents = file->read_all();
-    auto json_result = JsonValue::from_string(file_contents);
-    VERIFY(json_result.has_value());
-    auto json = json_result.value().as_array();
+    auto json_result = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+    auto const& json = json_result.as_array();
     json.for_each([](auto& value) {
         auto& fs_object = value.as_object();
         auto fs = fs_object.get("class_name").to_string();

+ 3 - 3
Userland/Utilities/fortune.cpp

@@ -100,16 +100,16 @@ int main(int argc, char** argv)
 
     auto file_contents = file->read_all();
     auto json = JsonValue::from_string(file_contents);
-    if (!json.has_value()) {
+    if (json.is_error()) {
         warnln("Couldn't parse {} as JSON", path);
         return 1;
     }
-    if (!json->is_array()) {
+    if (!json.value().is_array()) {
         warnln("{} does not contain an array of quotes", path);
         return 1;
     }
 
-    const auto quotes = parse_all(json->as_array());
+    const auto quotes = parse_all(json.value().as_array());
     if (quotes.is_empty()) {
         warnln("{} does not contain any valid quotes", path);
         return 1;

+ 1 - 1
Userland/Utilities/gron.cpp

@@ -69,7 +69,7 @@ int main(int argc, char** argv)
     auto file_contents = file->read_all();
     auto json = JsonValue::from_string(file_contents);
 
-    if (!json.has_value()) {
+    if (json.is_error()) {
         if (path) {
             warnln("Failed to parse '{}' as JSON", path);
         } else {

+ 2 - 3
Userland/Utilities/ifconfig.cpp

@@ -45,9 +45,8 @@ int main(int argc, char** argv)
         }
 
         auto file_contents = file->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
-        json.value().as_array().for_each([](auto& value) {
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+        json.as_array().for_each([](auto& value) {
             auto& if_object = value.as_object();
 
             auto name = if_object.get("name").to_string();

+ 1 - 1
Userland/Utilities/jp.cpp

@@ -53,7 +53,7 @@ int main(int argc, char** argv)
 
     auto file_contents = file->read_all();
     auto json = JsonValue::from_string(file_contents);
-    if (!json.has_value()) {
+    if (json.is_error()) {
         warnln("Couldn't parse {} as JSON", path);
         return 1;
     }

+ 1 - 1
Userland/Utilities/js.cpp

@@ -918,7 +918,7 @@ static JS::ThrowCompletionOr<JS::Value> load_json_impl(JS::VM& vm, JS::GlobalObj
         return vm.throw_completion<JS::Error>(global_object, String::formatted("Failed to open '{}': {}", filename, file->error_string()));
     auto file_contents = file->read_all();
     auto json = JsonValue::from_string(file_contents);
-    if (!json.has_value())
+    if (json.is_error())
         return vm.throw_completion<JS::SyntaxError>(global_object, JS::ErrorType::JsonMalformed);
     return JS::JSONObject::parse_json_value(global_object, json.value());
 }

+ 2 - 3
Userland/Utilities/lsirq.cpp

@@ -39,9 +39,8 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
 
     outln("      CPU0");
     auto file_contents = proc_interrupts->read_all();
-    auto json = JsonValue::from_string(file_contents);
-    VERIFY(json.has_value());
-    json.value().as_array().for_each([](auto& value) {
+    auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+    json.as_array().for_each([](auto& value) {
         auto& handler = value.as_object();
         auto purpose = handler.get("purpose").to_string();
         auto interrupt = handler.get("interrupt_line").to_string();

+ 2 - 7
Userland/Utilities/lsof.cpp

@@ -70,15 +70,10 @@ static Vector<OpenFile> get_open_files_by_pid(pid_t pid)
     }
     auto data = file.value()->read_all();
 
-    JsonParser parser(data);
-    auto result = parser.parse();
-
-    if (!result.has_value()) {
-        VERIFY_NOT_REACHED();
-    }
+    auto json = JsonValue::from_string(data).release_value_but_fixme_should_propagate_errors();
 
     Vector<OpenFile> files;
-    result.value().as_array().for_each([pid, &files](const JsonValue& object) {
+    json.as_array().for_each([pid, &files](const JsonValue& object) {
         OpenFile open_file;
         open_file.pid = pid;
         open_file.fd = object.as_object().get("fd").to_int();

+ 2 - 3
Userland/Utilities/lspci.cpp

@@ -66,9 +66,8 @@ int main(int argc, char** argv)
     }
 
     auto file_contents = proc_pci->read_all();
-    auto json = JsonValue::from_string(file_contents);
-    VERIFY(json.has_value());
-    json.value().as_array().for_each([db, format](auto& value) {
+    auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
+    json.as_array().for_each([db, format](auto& value) {
         auto& dev = value.as_object();
         auto domain = dev.get("domain").to_u32();
         auto bus = dev.get("bus").to_u32();

+ 2 - 3
Userland/Utilities/lsusb.cpp

@@ -59,10 +59,9 @@ int main(int argc, char** argv)
         }
 
         auto contents = proc_usb_device->read_all();
-        auto json = JsonValue::from_string(contents);
-        VERIFY(json.has_value());
+        auto json = JsonValue::from_string(contents).release_value_but_fixme_should_propagate_errors();
 
-        json.value().as_array().for_each([usb_db](auto& value) {
+        json.as_array().for_each([usb_db](auto& value) {
             auto& device_descriptor = value.as_object();
 
             auto device_address = device_descriptor.get("device_address").to_u32();

+ 2 - 3
Userland/Utilities/mount.cpp

@@ -124,10 +124,9 @@ static bool print_mounts()
     }
 
     auto content = df->read_all();
-    auto json = JsonValue::from_string(content);
-    VERIFY(json.has_value());
+    auto json = JsonValue::from_string(content).release_value_but_fixme_should_propagate_errors();
 
-    json.value().as_array().for_each([](auto& value) {
+    json.as_array().for_each([](auto& value) {
         auto& fs_object = value.as_object();
         auto class_name = fs_object.get("class_name").to_string();
         auto mount_point = fs_object.get("mount_point").to_string();

+ 4 - 6
Userland/Utilities/netstat.cpp

@@ -156,10 +156,9 @@ int main(int argc, char** argv)
         }
 
         auto file_contents = file->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
-        Vector<JsonValue> sorted_regions = json.value().as_array().values();
+        Vector<JsonValue> sorted_regions = json.as_array().values();
         quick_sort(sorted_regions, [](auto& a, auto& b) {
             return a.as_object().get("local_port").to_u32() < b.as_object().get("local_port").to_u32();
         });
@@ -210,10 +209,9 @@ int main(int argc, char** argv)
         }
 
         auto file_contents = file->read_all();
-        auto json = JsonValue::from_string(file_contents);
-        VERIFY(json.has_value());
+        auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
-        Vector<JsonValue> sorted_regions = json.value().as_array().values();
+        Vector<JsonValue> sorted_regions = json.as_array().values();
         quick_sort(sorted_regions, [](auto& a, auto& b) {
             return a.as_object().get("local_port").to_u32() < b.as_object().get("local_port").to_u32();
         });

+ 2 - 3
Userland/Utilities/pmap.cpp

@@ -56,10 +56,9 @@ int main(int argc, char** argv)
     }
 
     auto file_contents = file->read_all();
-    auto json = JsonValue::from_string(file_contents);
-    VERIFY(json.has_value());
+    auto json = JsonValue::from_string(file_contents).release_value_but_fixme_should_propagate_errors();
 
-    Vector<JsonValue> sorted_regions = json.value().as_array().values();
+    Vector<JsonValue> sorted_regions = json.as_array().values();
     quick_sort(sorted_regions, [](auto& a, auto& b) {
         return a.as_object().get("address").to_addr() < b.as_object().get("address").to_addr();
     });

+ 1 - 1
Userland/Utilities/utmpupdate.cpp

@@ -63,7 +63,7 @@ int main(int argc, char** argv)
     JsonObject json;
 
     if (!file_contents.is_empty()) {
-        if (!previous_json.has_value() || !previous_json.value().is_object()) {
+        if (previous_json.is_error() || !previous_json.value().is_object()) {
             dbgln("Error: Could not parse JSON");
         } else {
             json = previous_json.value().as_object();

+ 1 - 1
Userland/Utilities/w.cpp

@@ -50,7 +50,7 @@ int main()
     }
     auto& file = *file_or_error.value();
     auto json = JsonValue::from_string(file.read_all());
-    if (!json.has_value() || !json.value().is_object()) {
+    if (json.is_error() || !json.value().is_object()) {
         warnln("Error: Could not parse /var/run/utmp");
         return 1;
     }