diff --git a/immer/extra/persist/README.rst b/immer/extra/persist/README.rst index 4824f3ec..b9266440 100644 --- a/immer/extra/persist/README.rst +++ b/immer/extra/persist/README.rst @@ -40,20 +40,47 @@ For this example, we'll use a `document` type that contains two immer vectors. :start-after: intro/start-types :end-before: intro/end-types -**Without immer-persist** +Let's say we have two vectors ``v1`` and ``v2``, where ``v2`` is derived from ``v1`` so that it shares data with it: .. literalinclude:: ../test/extra/persist/test_for_docs.cpp :language: c++ - :start-after: intro/start-no-persist - :end-before: intro/end-no-persist + :start-after: intro/start-prepare-value + :end-before: intro/end-prepare-value -**With immer-persist** +We can serialize the document using ``cereal`` with this: .. literalinclude:: ../test/extra/persist/test_for_docs.cpp :language: c++ - :start-after: intro/start-with-persist - :end-before: intro/end-with-persist + :start-after: intro/start-serialize-with-cereal + :end-before: intro/end-serialize-with-cereal +Generating a JSON like this one: + +.. code-block:: c++ + + {"value0": {"ints": [1, 2, 3], "ints2": [1, 2, 3, 4, 5, 6]}} + +As you can see, ``ints`` and ``ints2`` contain the full linearization of each vector. +The structural sharing between these two data structures is not represented in its +serialized form. However, with ``immer-persist`` we can serialize it with: + +.. literalinclude:: ../test/extra/persist/test_for_docs.cpp + :language: c++ + :start-after: intro/start-serialize-with-persist + :end-before: intro/end-serialize-with-persist + +Which generates some JSON like this: + +.. literalinclude:: ../test/extra/persist/test_for_docs.cpp + :language: c++ + :start-after: include:intro/start-persist-json + :end-before: include:intro/end-persist-json + +As you can see, the value is serialized with every ``immer`` container replaced by an identifier. +This identifier is a key into a pool, which is serialized just after. + +- XXX: what's a pool? +- XXX: to_json_with_pool uses cereal API Overview ------------ diff --git a/test/extra/persist/test_for_docs.cpp b/test/extra/persist/test_for_docs.cpp index 118f1a3c..1db39533 100644 --- a/test/extra/persist/test_for_docs.cpp +++ b/test/extra/persist/test_for_docs.cpp @@ -42,27 +42,26 @@ using json_t = nlohmann::json; TEST_CASE("Docs save with immer-persist", "[docs]") { - // include:intro/start-no-persist - const auto v1 = vector_one{1, 2, 3}; - const auto v2 = v1.push_back(4).push_back(5).push_back(6); - // Vector v2 uses structural sharing to reuse the nodes that store the - // values of v1. + // include:intro/start-prepare-value + const auto v1 = vector_one{1, 2, 3}; + const auto v2 = v1.push_back(4).push_back(5).push_back(6); const auto value = document{v1, v2}; + // include:intro/end-prepare-value SECTION("Without immer-persist") { - // Vectors are serialized directly as lists. Notably, as independent - // lists. const auto expected_json = json_t::parse(R"( {"value0": {"ints": [1, 2, 3], "ints2": [1, 2, 3, 4, 5, 6]}} )"); const auto str = [&] { + // include:intro/start-serialize-with-cereal auto os = std::ostringstream{}; { auto ar = cereal::JSONOutputArchive{os}; ar(value); } return os.str(); + // include:intro/end-serialize-with-cereal }(); REQUIRE(json_t::parse(str) == expected_json); @@ -76,18 +75,18 @@ TEST_CASE("Docs save with immer-persist", "[docs]") REQUIRE(value == loaded_value); } - // include:intro/end-no-persist SECTION("With immer-persist") { - // include:intro/start-with-persist // Immer-persist uses policies to control certain aspects of // serialization: // - types of pools that should be used // - names of those pools + // include:intro/start-serialize-with-persist const auto policy = immer::persist::hana_struct_auto_member_name_policy(document{}); const auto str = immer::persist::to_json_with_pool(value, policy); + // include:intro/end-serialize-with-persist // The resulting JSON looks much more complicated for this little // example but the more structural sharing is used inside the serialized @@ -108,6 +107,8 @@ TEST_CASE("Docs save with immer-persist", "[docs]") // structure and to refer to the vector with just one integer: // `{"ints": 0, "ints2": 1}`: 0 and 1 refer to the indices of this // array. + + // include:intro/start-persist-json const auto expected_json = json_t::parse(R"( { "value0": {"ints": 0, "ints2": 1}, @@ -130,11 +131,11 @@ TEST_CASE("Docs save with immer-persist", "[docs]") } } )"); + // include:intro/end-persist-json REQUIRE(json_t::parse(str) == expected_json); const auto loaded_value = immer::persist::from_json_with_pool(str, policy); REQUIRE(value == loaded_value); - // include:intro/end-with-persist } }