Remove nlohmann brace initialization

There's a few last places (outside of tests) where we still use
nlohmann brace initialization.  Per the transforms we've been doing,
move these to constructing the objects explicitly, using operator[],
nlohmann::object_t and nlohmann::array_t.  Theses were found by manual
inspection grepping for all uses of nlohmann::json.

This is done to reduce binary size and reduce the number of intermediate
objects being constructed.  This commit saves a trivial amount of size
(~4KB, Half a percent of total) and in addition but makes our
construction consistent.

Tested:
Redfish service validator passes.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I7478479a9fdc41b254eef325002d413c1fb411a0
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 5d8bb15..91bd024 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -182,10 +182,18 @@
     {
         BMCWEB_LOG_DEBUG << "Pushing the data groupName="
                          << obj.second.groupName << "\n";
-        roleMapArray.push_back(
-            {nlohmann::json::array({"RemoteGroup", obj.second.groupName}),
-             nlohmann::json::array(
-                 {"LocalRole", getRoleIdFromPrivilege(obj.second.privilege)})});
+
+        nlohmann::json::array_t remoteGroupArray;
+        nlohmann::json::object_t remoteGroup;
+        remoteGroup["RemoteGroup"] = obj.second.groupName;
+        remoteGroupArray.emplace_back(std::move(remoteGroup));
+        roleMapArray.emplace_back(std::move(remoteGroupArray));
+
+        nlohmann::json::array_t localRoleArray;
+        nlohmann::json::object_t localRole;
+        localRole["LocalRole"] = getRoleIdFromPrivilege(obj.second.privilege);
+        localRoleArray.emplace_back(std::move(localRole));
+        roleMapArray.emplace_back(std::move(localRoleArray));
     }
 }
 
@@ -1733,7 +1741,8 @@
         asyncResp->res.jsonValue["Name"] = "User Account";
         asyncResp->res.jsonValue["Description"] = "User Account";
         asyncResp->res.jsonValue["Password"] = nullptr;
-        asyncResp->res.jsonValue["AccountTypes"] = {"Redfish"};
+        asyncResp->res.jsonValue["AccountTypes"] =
+            nlohmann::json::array_t({"Redfish"});
 
         for (const auto& interface : userIt->second)
         {
diff --git a/redfish-core/lib/certificate_service.hpp b/redfish-core/lib/certificate_service.hpp
index ebd9436..d3aedd0 100644
--- a/redfish-core/lib/certificate_service.hpp
+++ b/redfish-core/lib/certificate_service.hpp
@@ -78,15 +78,16 @@
             asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
                 "/redfish/v1/CertificateService/CertificateLocations";
         }
-        asyncResp->res
-            .jsonValue["Actions"]["#CertificateService.ReplaceCertificate"] = {
-            {"target",
-             "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate"},
-            {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
-        asyncResp->res
-            .jsonValue["Actions"]["#CertificateService.GenerateCSR"] = {
-            {"target",
-             "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR"}};
+        nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
+        nlohmann::json& replace =
+            actions["#CertificateService.ReplaceCertificate"];
+        replace["target"] =
+            "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
+        nlohmann::json::array_t allowed;
+        allowed.push_back("PEM");
+        replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
+        actions["#CertificateService.GenerateCSR"]["target"] =
+            "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
         });
 } // requestRoutesCertificateService
 
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 9fb125d..3530d79 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -1660,9 +1660,9 @@
         jsonResponse["FQDN"] = fqdn;
     }
 
-    jsonResponse["VLANs"] = {
-        {"@odata.id",
-         "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId + "/VLANs"}};
+    jsonResponse["VLANs"]["@odata.id"] =
+        crow::utility::urlFromPieces("redfish", "v1", "Managers", "bmc",
+                                     "EthernetInterfaces", ifaceId, "VLANs");
 
     jsonResponse["NameServers"] = ethData.nameServers;
     jsonResponse["StaticNameServers"] = ethData.staticNameServers;
@@ -1673,7 +1673,6 @@
     ipv4StaticArray = nlohmann::json::array();
     for (const auto& ipv4Config : ipv4Data)
     {
-
         std::string gatewayStr = ipv4Config.gateway;
         if (gatewayStr.empty())
         {
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 9c5b378..d473c8e 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -83,13 +83,16 @@
         asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
         asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
 
-        nlohmann::json supportedSSEFilters = {
-            {"EventFormatType", true},        {"MessageId", true},
-            {"MetricReportDefinition", true}, {"RegistryPrefix", true},
-            {"OriginResource", false},        {"ResourceType", false}};
+        nlohmann::json::object_t supportedSSEFilters;
+        supportedSSEFilters["EventFormatType"] = true;
+        supportedSSEFilters["MessageId"] = true;
+        supportedSSEFilters["MetricReportDefinition"] = true;
+        supportedSSEFilters["RegistryPrefix"] = true;
+        supportedSSEFilters["OriginResource"] = false;
+        supportedSSEFilters["ResourceType"] = false;
 
         asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
-            supportedSSEFilters;
+            std::move(supportedSSEFilters);
         });
 
     BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index b75dec1..78bf626 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -137,11 +137,12 @@
         }
 
         // Object present so system support limited ComputerSystem Action
-        aResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
-            {"target",
-             "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset"},
-            {"@Redfish.ActionInfo",
-             "/redfish/v1/Systems/hypervisor/ResetActionInfo"}};
+        nlohmann::json& reset =
+            aResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"];
+        reset["target"] =
+            "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset";
+        reset["@Redfish.ActionInfo"] =
+            "/redfish/v1/Systems/hypervisor/ResetActionInfo";
         },
         "xyz.openbmc_project.ObjectMapper",
         "/xyz/openbmc_project/object_mapper",
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index faa295a..1b52d00 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -972,9 +972,12 @@
                 {
                     nlohmann::json& logServiceArrayLocal =
                         asyncResp->res.jsonValue["Members"];
-                    logServiceArrayLocal.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/Systems/system/LogServices/PostCodes"}});
+                    nlohmann::json::object_t member;
+                    member["@odata.id"] =
+                        "/redfish/v1/Systems/system/LogServices/PostCodes";
+
+                    logServiceArrayLocal.push_back(std::move(member));
+
                     asyncResp->res.jsonValue["Members@odata.count"] =
                         logServiceArrayLocal.size();
                     return;
@@ -2013,8 +2016,9 @@
     logServiceArray = nlohmann::json::array();
 
 #ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL
-    logServiceArray.push_back(
-        {{"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Journal"}});
+    nlohmann::json::object_t journal;
+    journal["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/Journal";
+    logServiceArray.push_back(std::move(journal));
 #endif
 
     asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
@@ -2041,15 +2045,17 @@
         {
             if (path == "/xyz/openbmc_project/dump/bmc")
             {
-                logServiceArrayLocal.push_back(
-                    {{"@odata.id",
-                      "/redfish/v1/Managers/bmc/LogServices/Dump"}});
+                nlohmann::json::object_t member;
+                member["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/Dump";
+                logServiceArrayLocal.push_back(std::move(member));
             }
             else if (path == "/xyz/openbmc_project/dump/faultlog")
             {
-                logServiceArrayLocal.push_back(
-                    {{"@odata.id",
-                      "/redfish/v1/Managers/bmc/LogServices/FaultLog"}});
+                nlohmann::json::object_t member;
+                member["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/FaultLog";
+                logServiceArrayLocal.push_back(std::move(member));
             }
         }
 
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index a52b7b5..1955de1 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -400,8 +400,8 @@
                         chassis = "#IllegalValue";
                     }
                     nlohmann::json& zone = zones[name];
-                    zone["Chassis"] = {
-                        {"@odata.id", "/redfish/v1/Chassis/" + chassis}};
+                    zone["Chassis"]["@odata.id"] =
+                        "/redfish/v1/Chassis/" + chassis;
                     zone["@odata.id"] =
                         "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/FanZones/" +
                         name;
@@ -2000,7 +2000,8 @@
             asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
         resetToDefaults["target"] =
             "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults";
-        resetToDefaults["ResetType@Redfish.AllowableValues"] = {"ResetAll"};
+        resetToDefaults["ResetType@Redfish.AllowableValues"] =
+            nlohmann::json::array_t({"ResetAll"});
 
         std::pair<std::string, std::string> redfishDateTimeOffset =
             redfish::time_utils::getDateTimeOffsetNow();
@@ -2015,15 +2016,15 @@
         // Fill in SerialConsole info
         asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
-        asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] = {
-            "IPMI", "SSH"};
+        asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] =
+            nlohmann::json::array_t({"IPMI", "SSH"});
 #ifdef BMCWEB_ENABLE_KVM
         // Fill in GraphicalConsole info
         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
             4;
-        asyncResp->res
-            .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = {"KVMIP"};
+        asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
+            nlohmann::json::array_t({"KVMIP"});
 #endif // BMCWEB_ENABLE_KVM
 
         asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] = 1;
diff --git a/redfish-core/lib/message_registries.hpp b/redfish-core/lib/message_registries.hpp
index 09d32b7..9d6f109 100644
--- a/redfish-core/lib/message_registries.hpp
+++ b/redfish-core/lib/message_registries.hpp
@@ -25,6 +25,8 @@
 #include <query.hpp>
 #include <registries/privilege_registry.hpp>
 
+#include <array>
+
 namespace redfish
 {
 
@@ -46,11 +48,16 @@
     asyncResp->res.jsonValue["Description"] =
         "Collection of MessageRegistryFiles";
     asyncResp->res.jsonValue["Members@odata.count"] = 4;
-    asyncResp->res.jsonValue["Members"] = {
-        {{"@odata.id", "/redfish/v1/Registries/Base"}},
-        {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
-        {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
-        {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}};
+
+    nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+    for (const char* memberName :
+         std::to_array({"Base", "TaskEvent", "ResourceEvent", "OpenBMC"}))
+    {
+        nlohmann::json::object_t member;
+        member["@odata.id"] = crow::utility::urlFromPieces(
+            "redfish", "v1", "Registries", memberName);
+        members.emplace_back(std::move(member));
+    }
 }
 
 inline void requestRoutesMessageRegistryFileCollection(App& app)
@@ -113,18 +120,22 @@
         dmtf + registry + " Message Registry File Location";
     asyncResp->res.jsonValue["Id"] = header->registryPrefix;
     asyncResp->res.jsonValue["Registry"] = header->id;
-    asyncResp->res.jsonValue["Languages"] = {"en"};
-    asyncResp->res.jsonValue["Languages@odata.count"] = 1;
-    asyncResp->res.jsonValue["Location"] = {
-        {{"Language", "en"},
-         {"Uri", "/redfish/v1/Registries/" + registry + "/" + registry}}};
-
-    asyncResp->res.jsonValue["Location@odata.count"] = 1;
+    nlohmann::json::array_t languages;
+    languages.push_back("en");
+    asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
+    asyncResp->res.jsonValue["Languages"] = std::move(languages);
+    nlohmann::json::array_t locationMembers;
+    nlohmann::json::object_t location;
+    location["Language"] = "en";
+    location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
 
     if (url != nullptr)
     {
-        asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url;
+        location["PublicationUri"] = url;
     }
+    locationMembers.emplace_back(std::move(location));
+    asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
+    asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
 }
 
 inline void requestRoutesMessageRegistryFile(App& app)
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
index 18830f1..6b79c51 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -29,12 +29,13 @@
 
     for (const auto& [id, metadata, sensorValue, timestamp] : readings)
     {
-        metricValues.push_back({
-            {"MetricId", id},
-            {"MetricProperty", metadata},
-            {"MetricValue", std::to_string(sensorValue)},
-            {"Timestamp", redfish::time_utils::getDateTimeUintMs(timestamp)},
-        });
+        nlohmann::json::object_t metricReport;
+        metricReport["MetricId"] = id;
+        metricReport["MetricProperty"] = metadata;
+        metricReport["MetricValue"] = std::to_string(sensorValue);
+        metricReport["Timestamp"] =
+            redfish::time_utils::getDateTimeUintMs(timestamp);
+        metricValues.push_back(std::move(metricReport));
     }
 
     return metricValues;
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index 37e9031..e15e920 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -87,10 +87,10 @@
         for (const auto& [sensorPath, operationType, metricId, metadata] :
              *readingParameters)
         {
-            metrics.push_back({
-                {"MetricId", metricId},
-                {"MetricProperties", {metadata}},
-            });
+            nlohmann::json::object_t metric;
+            metric["MetricId"] = metricId;
+            metric["MetricProperties"] = nlohmann::json::array_t({metadata});
+            metrics.push_back(std::move(metric));
         }
     }
 
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 24e6d41..975e90b 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -881,7 +881,7 @@
 
         aResp->res.jsonValue["Boot"]
                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
-            {"Legacy", "UEFI"};
+            nlohmann::json::array_t({"Legacy", "UEFI"});
 
         auto rfType = dbusToRfBootType(bootType);
         if (rfType.empty())
@@ -2939,8 +2939,8 @@
         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
             4;
-        asyncResp->res
-            .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = {"KVMIP"};
+        asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
+            nlohmann::json::array_t({"KVMIP"});
 
 #endif // BMCWEB_ENABLE_KVM
         constexpr const std::array<const char*, 4> inventoryForSystems = {
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index b40d522..fe3b990 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -448,9 +448,10 @@
             {
                 continue; // shouldn't be possible
             }
-            members.emplace_back(
-                nlohmann::json{{"@odata.id", "/redfish/v1/TaskService/Tasks/" +
-                                                 std::to_string(task->index)}});
+            nlohmann::json::object_t member;
+            member["@odata.id"] =
+                "redfish/v1/TaskService/Tasks/" + std::to_string(task->index);
+            members.emplace_back(std::move(member));
         }
         });
 }
diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp
index 5e2f050..811d355 100644
--- a/redfish-core/lib/trigger.hpp
+++ b/redfish-core/lib/trigger.hpp
@@ -100,13 +100,12 @@
         {
             return std::nullopt;
         }
-
-        triggers.push_back({
-            {"Name", name},
-            {"Severity", severity},
-            {"DwellTime", *duration},
-            {"Value", value},
-        });
+        nlohmann::json::object_t trigger;
+        trigger["Name"] = name;
+        trigger["Severity"] = severity;
+        trigger["DwellTime"] = *duration;
+        trigger["Value"] = value;
+        triggers.push_back(std::move(trigger));
     }
 
     return {std::move(triggers)};
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index 15dcdb9..af38163 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -155,7 +155,7 @@
     item["Name"] = "Virtual Removable Media";
     item["Id"] = resName;
     item["WriteProtected"] = true;
-    item["MediaTypes"] = {"CD", "USBStick"};
+    item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
     item["TransferMethod"] = "Stream";
     item["Oem"]["OpenBMC"]["@odata.type"] =
         "#OemVirtualMedia.v1_0_0.VirtualMedia";