serialization: adapt to filesystem API changes

The behavior of std::filesystem::path::append changed on its journey
from experimental:: to std::
Add a testcase and adapt to the behavior change.

Fixes: e6b21c74581c30ea635aabbbc08d0a56f8e27063
Change-Id: I4bdb43ea9b85933ec12ae0f4b609ec3a33d77d01
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/serialize.hpp b/serialize.hpp
index 4028899..82bd4bb 100644
--- a/serialize.hpp
+++ b/serialize.hpp
@@ -16,6 +16,18 @@
 
 namespace fs = std::filesystem;
 
+namespace detail
+{
+inline fs::path getStoragePath(const std::string& path,
+                               const std::string& iface)
+{
+    auto p = fs::path(PIM_PERSIST_PATH);
+    p /= fs::path(path).relative_path();
+    p /= fs::path(iface).relative_path();
+    return p;
+}
+} // namespace detail
+
 struct SerialOps
 {
     /** @brief Serialize inventory item path
@@ -26,10 +38,8 @@
      */
     static void serialize(const std::string& path, const std::string& iface)
     {
-        fs::path p(PIM_PERSIST_PATH);
-        p /= path;
-        fs::create_directories(p);
-        p /= iface;
+        auto p = detail::getStoragePath(path, iface);
+        fs::create_directories(p.parent_path());
         std::ofstream os(p, std::ios::binary);
     }
 
@@ -43,10 +53,8 @@
     static void serialize(const std::string& path, const std::string& iface,
                           const T& object)
     {
-        fs::path p(PIM_PERSIST_PATH);
-        p /= path;
-        fs::create_directories(p);
-        p /= iface;
+        auto p = detail::getStoragePath(path, iface);
+        fs::create_directories(p.parent_path());
         std::ofstream os(p, std::ios::binary);
         cereal::JSONOutputArchive oarchive(os);
         oarchive(object);