memory: move long code blocks in callbacks into separate functions

It is a bit cleaner to have separate functions rather than keep codes in
the callback, as callback normally have deeper indent.

The main reason is that this helps code review of later changes that
make Expand at MemoryCollection efficient.

Tested:
1. Tested on my mock environment,
```
URI: /redfish/v1/Systems/system/Memory/dimm0
{
    "@odata.id": "/redfish/v1/Systems/system/Memory/dimm0",
    "@odata.type": "#Memory.v1_11_0.Memory",
    "AllowedSpeedsMHz": [],
    "BaseModuleType": "RDIMM",
    "BusWidthBits": 0,
    "CapacityMiB": 1024,
    "DataWidthBits": 0,
    "ErrorCorrection": "NoECC",
    "FirmwareRevision": "0",
    "Id": "dimm0",
    "Name": "DIMM Slot",
    "OperatingSpeedMhz": 0,
    "RankCount": 0,
    "Status": {
        "Health": "OK",
        "HealthRollup": "OK",
        "State": "Enabled"
    }
}
```
2. No new Redfish Validator failures on MemoryCollection on real
hardware.

Signed-off-by: Nan Zhou <nanzhoumails@gmail.com>
Change-Id: I7693388049aeffa6ebd285b958e5ca6622e5d3b6
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index 6e4ab67..f84a17a 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -426,6 +426,264 @@
     }
 }
 
+inline void
+    assembleDimmProperties(std::string_view dimmId,
+                           const std::shared_ptr<bmcweb::AsyncResp>& aResp,
+                           const dbus::utility::DBusPropertiesMap& properties)
+{
+    aResp->res.jsonValue["Id"] = dimmId;
+    aResp->res.jsonValue["Name"] = "DIMM Slot";
+    aResp->res.jsonValue["Status"]["State"] = "Enabled";
+    aResp->res.jsonValue["Status"]["Health"] = "OK";
+
+    for (const auto& property : properties)
+    {
+        if (property.first == "MemoryDataWidth")
+        {
+            const uint16_t* value = std::get_if<uint16_t>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["DataWidthBits"] = *value;
+        }
+        else if (property.first == "MemorySizeInKB")
+        {
+            const size_t* memorySize = std::get_if<size_t>(&property.second);
+            if (memorySize == nullptr)
+            {
+                // Important property not in desired type
+                messages::internalError(aResp->res);
+                return;
+            }
+            aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
+        }
+        else if (property.first == "PartNumber")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["PartNumber"] = *value;
+        }
+        else if (property.first == "SerialNumber")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["SerialNumber"] = *value;
+        }
+        else if (property.first == "Manufacturer")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["Manufacturer"] = *value;
+        }
+        else if (property.first == "RevisionCode")
+        {
+            const uint16_t* value = std::get_if<uint16_t>(&property.second);
+
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode";
+                return;
+            }
+            aResp->res.jsonValue["FirmwareRevision"] = std::to_string(*value);
+        }
+        else if (property.first == "Present")
+        {
+            const bool* value = std::get_if<bool>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence";
+                return;
+            }
+            if (!*value)
+            {
+                aResp->res.jsonValue["Status"]["State"] = "Absent";
+            }
+        }
+        else if (property.first == "MemoryTotalWidth")
+        {
+            const uint16_t* value = std::get_if<uint16_t>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["BusWidthBits"] = *value;
+        }
+        else if (property.first == "ECC")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
+                return;
+            }
+            constexpr const std::array<const char*, 4> values{
+                "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
+
+            for (const char* v : values)
+            {
+                if (boost::ends_with(*value, v))
+                {
+                    aResp->res.jsonValue["ErrorCorrection"] = v;
+                    break;
+                }
+            }
+        }
+        else if (property.first == "FormFactor")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
+                return;
+            }
+            constexpr const std::array<const char*, 11> values{
+                "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
+                "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
+                "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
+
+            for (const char* v : values)
+            {
+                if (boost::ends_with(*value, v))
+                {
+                    aResp->res.jsonValue["BaseModuleType"] = v;
+                    break;
+                }
+            }
+        }
+        else if (property.first == "AllowedSpeedsMT")
+        {
+            const std::vector<uint16_t>* value =
+                std::get_if<std::vector<uint16_t>>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            nlohmann::json& jValue = aResp->res.jsonValue["AllowedSpeedsMHz"];
+            jValue = nlohmann::json::array();
+            for (uint16_t subVal : *value)
+            {
+                jValue.push_back(subVal);
+            }
+        }
+        else if (property.first == "MemoryAttributes")
+        {
+            const uint8_t* value = std::get_if<uint8_t>(&property.second);
+
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                BMCWEB_LOG_DEBUG
+                    << "Invalid property type for MemoryAttributes";
+                return;
+            }
+            aResp->res.jsonValue["RankCount"] = static_cast<uint64_t>(*value);
+        }
+        else if (property.first == "MemoryConfiguredSpeedInMhz")
+        {
+            const uint16_t* value = std::get_if<uint16_t>(&property.second);
+            if (value == nullptr)
+            {
+                continue;
+            }
+            aResp->res.jsonValue["OperatingSpeedMhz"] = *value;
+        }
+        else if (property.first == "MemoryType")
+        {
+            const auto* value = std::get_if<std::string>(&property.second);
+            if (value != nullptr)
+            {
+                std::string memoryDeviceType =
+                    translateMemoryTypeToRedfish(*value);
+                // Values like "Unknown" or "Other" will return empty
+                // so just leave off
+                if (!memoryDeviceType.empty())
+                {
+                    aResp->res.jsonValue["MemoryDeviceType"] = memoryDeviceType;
+                }
+                if (value->find("DDR") != std::string::npos)
+                {
+                    aResp->res.jsonValue["MemoryType"] = "DRAM";
+                }
+                else if (boost::ends_with(*value, "Logical"))
+                {
+                    aResp->res.jsonValue["MemoryType"] = "IntelOptane";
+                }
+            }
+        }
+        // memory location interface
+        else if (property.first == "Channel" ||
+                 property.first == "MemoryController" ||
+                 property.first == "Slot" || property.first == "Socket")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                return;
+            }
+            aResp->res.jsonValue["MemoryLocation"][property.first] = *value;
+        }
+        else if (property.first == "SparePartNumber")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                return;
+            }
+            aResp->res.jsonValue["SparePartNumber"] = *value;
+        }
+        else if (property.first == "Model")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                return;
+            }
+            aResp->res.jsonValue["Model"] = *value;
+        }
+        else if (property.first == "LocationCode")
+        {
+            const std::string* value =
+                std::get_if<std::string>(&property.second);
+            if (value == nullptr)
+            {
+                messages::internalError(aResp->res);
+                return;
+            }
+            aResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+                *value;
+        }
+        else
+        {
+            getPersistentMemoryProperties(aResp, property);
+        }
+    }
+}
+
 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
                                  const std::string& dimmId,
                                  const std::string& service,
@@ -446,275 +704,7 @@
                 messages::internalError(aResp->res);
                 return;
             }
-            aResp->res.jsonValue["Id"] = dimmId;
-            aResp->res.jsonValue["Name"] = "DIMM Slot";
-            aResp->res.jsonValue["Status"]["State"] = "Enabled";
-            aResp->res.jsonValue["Status"]["Health"] = "OK";
-
-            for (const auto& property : properties)
-            {
-                if (property.first == "MemoryDataWidth")
-                {
-                    const uint16_t* value =
-                        std::get_if<uint16_t>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["DataWidthBits"] = *value;
-                }
-                else if (property.first == "MemorySizeInKB")
-                {
-                    const size_t* memorySize =
-                        std::get_if<size_t>(&property.second);
-                    if (memorySize == nullptr)
-                    {
-                        // Important property not in desired type
-                        messages::internalError(aResp->res);
-                        return;
-                    }
-                    aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
-                }
-                else if (property.first == "PartNumber")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["PartNumber"] = *value;
-                }
-                else if (property.first == "SerialNumber")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["SerialNumber"] = *value;
-                }
-                else if (property.first == "Manufacturer")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["Manufacturer"] = *value;
-                }
-                else if (property.first == "RevisionCode")
-                {
-                    const uint16_t* value =
-                        std::get_if<uint16_t>(&property.second);
-
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        BMCWEB_LOG_DEBUG
-                            << "Invalid property type for RevisionCode";
-                        return;
-                    }
-                    aResp->res.jsonValue["FirmwareRevision"] =
-                        std::to_string(*value);
-                }
-                else if (property.first == "Present")
-                {
-                    const bool* value = std::get_if<bool>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        BMCWEB_LOG_DEBUG
-                            << "Invalid property type for Dimm Presence";
-                        return;
-                    }
-                    if (!*value)
-                    {
-                        aResp->res.jsonValue["Status"]["State"] = "Absent";
-                    }
-                }
-                else if (property.first == "MemoryTotalWidth")
-                {
-                    const uint16_t* value =
-                        std::get_if<uint16_t>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["BusWidthBits"] = *value;
-                }
-                else if (property.first == "ECC")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
-                        return;
-                    }
-                    constexpr const std::array<const char*, 4> values{
-                        "NoECC", "SingleBitECC", "MultiBitECC",
-                        "AddressParity"};
-
-                    for (const char* v : values)
-                    {
-                        if (boost::ends_with(*value, v))
-                        {
-                            aResp->res.jsonValue["ErrorCorrection"] = v;
-                            break;
-                        }
-                    }
-                }
-                else if (property.first == "FormFactor")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        BMCWEB_LOG_DEBUG
-                            << "Invalid property type for FormFactor";
-                        return;
-                    }
-                    constexpr const std::array<const char*, 11> values{
-                        "RDIMM",        "UDIMM",        "SO_DIMM",
-                        "LRDIMM",       "Mini_RDIMM",   "Mini_UDIMM",
-                        "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
-                        "SO_DIMM_32b",  "Die"};
-
-                    for (const char* v : values)
-                    {
-                        if (boost::ends_with(*value, v))
-                        {
-                            aResp->res.jsonValue["BaseModuleType"] = v;
-                            break;
-                        }
-                    }
-                }
-                else if (property.first == "AllowedSpeedsMT")
-                {
-                    const std::vector<uint16_t>* value =
-                        std::get_if<std::vector<uint16_t>>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    nlohmann::json& jValue =
-                        aResp->res.jsonValue["AllowedSpeedsMHz"];
-                    jValue = nlohmann::json::array();
-                    for (uint16_t subVal : *value)
-                    {
-                        jValue.push_back(subVal);
-                    }
-                }
-                else if (property.first == "MemoryAttributes")
-                {
-                    const uint8_t* value =
-                        std::get_if<uint8_t>(&property.second);
-
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        BMCWEB_LOG_DEBUG
-                            << "Invalid property type for MemoryAttributes";
-                        return;
-                    }
-                    aResp->res.jsonValue["RankCount"] =
-                        static_cast<uint64_t>(*value);
-                }
-                else if (property.first == "MemoryConfiguredSpeedInMhz")
-                {
-                    const uint16_t* value =
-                        std::get_if<uint16_t>(&property.second);
-                    if (value == nullptr)
-                    {
-                        continue;
-                    }
-                    aResp->res.jsonValue["OperatingSpeedMhz"] = *value;
-                }
-                else if (property.first == "MemoryType")
-                {
-                    const auto* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value != nullptr)
-                    {
-                        std::string memoryDeviceType =
-                            translateMemoryTypeToRedfish(*value);
-                        // Values like "Unknown" or "Other" will return empty
-                        // so just leave off
-                        if (!memoryDeviceType.empty())
-                        {
-                            aResp->res.jsonValue["MemoryDeviceType"] =
-                                memoryDeviceType;
-                        }
-                        if (value->find("DDR") != std::string::npos)
-                        {
-                            aResp->res.jsonValue["MemoryType"] = "DRAM";
-                        }
-                        else if (boost::ends_with(*value, "Logical"))
-                        {
-                            aResp->res.jsonValue["MemoryType"] = "IntelOptane";
-                        }
-                    }
-                }
-                // memory location interface
-                else if (property.first == "Channel" ||
-                         property.first == "MemoryController" ||
-                         property.first == "Slot" || property.first == "Socket")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        return;
-                    }
-                    aResp->res.jsonValue["MemoryLocation"][property.first] =
-                        *value;
-                }
-                else if (property.first == "SparePartNumber")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        return;
-                    }
-                    aResp->res.jsonValue["SparePartNumber"] = *value;
-                }
-                else if (property.first == "Model")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        return;
-                    }
-                    aResp->res.jsonValue["Model"] = *value;
-                }
-                else if (property.first == "LocationCode")
-                {
-                    const std::string* value =
-                        std::get_if<std::string>(&property.second);
-                    if (value == nullptr)
-                    {
-                        messages::internalError(aResp->res);
-                        return;
-                    }
-                    aResp->res
-                        .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
-                        *value;
-                }
-                else
-                {
-                    getPersistentMemoryProperties(aResp, property);
-                }
-            }
+            assembleDimmProperties(dimmId, aResp, properties);
         },
         service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
 }