Skip to content

Commit

Permalink
More narration in the docs, less in the code
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Aug 6, 2024
1 parent dfca577 commit 60a47ea
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
39 changes: 33 additions & 6 deletions immer/extra/persist/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------
Expand Down
21 changes: 11 additions & 10 deletions test/extra/persist/test_for_docs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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
Expand All @@ -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},
Expand All @@ -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<document>(str, policy);
REQUIRE(value == loaded_value);
// include:intro/end-with-persist
}
}

0 comments on commit 60a47ea

Please sign in to comment.