Skip to content

Commit 504a0a5

Browse files
committed
docs(gctx): explain Value deserialization step-by-step
1 parent 8aabb1b commit 504a0a5

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

src/cargo/util/context/value.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,34 @@
1616
//!
1717
//! ## How `Value<T>` deserialization works
1818
//!
19-
//! You'll want to also check out the implementation of `ValueDeserializer` in
20-
//! the [`de`] module. Also note that the names below are intended to be invalid
21-
//! Rust identifiers to avoid conflicts with other valid structures.
19+
//! The deserialization process works through a custom protocol:
2220
//!
23-
//! Finally the `definition` field is transmitted as a tuple of i32/string,
24-
//! which is effectively a tagged union of [`Definition`] itself. You should
25-
//! update both places here and in the impl of [`serde::de::MapAccess`] for
26-
//! `ValueDeserializer` when adding or modifying enum variants of [`Definition`].
21+
//! 1. When serde discovers it needs to deserialize a `Value<T>`, it calls
22+
//! `Value<T>::deserialize`.
23+
//!
24+
//! 2. `Value<T>::deserialize` calls `deserializer.deserialize_struct()` with
25+
//! special identifiers: a [struct name](NAME) and [field names](FIELDS).
26+
//!
27+
//! 3. When the deserializer recognizes these magic identifiers, it constructs
28+
//! `ValueDeserializer` (from the [`de`] module) to provide both the value
29+
//! and the definition.
30+
//!
31+
//! 4. `ValueDeserializer` provides data back to `ValueVisitor` through the
32+
//! serde `MapAccess` interface, presenting the actual deserialized value
33+
//! and the definition context as two fields:
34+
//!
35+
//! * For the value field, the original deserializer performs whatever
36+
//! deserialization it needs to deserialize the actual value.
37+
//! * For the definition field, it is transmitted as a `(u32, String)` tuple,
38+
//! which acts as a tagged union of [`Definition`] variants.
39+
//!
40+
//! 5. `ValueVisitor` constructs the complete `Value<T>` from both pieces and
41+
//! returns it back through the deserializer chain to complete the original
42+
//! `Value<T>::deserialize` call.
43+
//!
44+
//! **Note**: When modifying [`Definition`] variants, update both the
45+
//! `Definition::deserialize` implementation here and the
46+
//! `MapAccess::next_value_seed` implementation in `ValueDeserializer`.
2747
//!
2848
//! [`de`]: crate::util::context::de
2949
@@ -48,6 +68,8 @@ pub struct Value<T> {
4868

4969
pub type OptValue<T> = Option<Value<T>>;
5070

71+
// The names below are intended to be invalid Rust identifiers
72+
// to avoid conflicts with other valid structures.
5173
pub(crate) const VALUE_FIELD: &str = "$__cargo_private_value";
5274
pub(crate) const DEFINITION_FIELD: &str = "$__cargo_private_definition";
5375
pub(crate) const NAME: &str = "$__cargo_private_Value";

0 commit comments

Comments
 (0)