1- //! Deserialization of a `Value<T>` type which tracks where it was deserialized
2- //! from.
1+ //! Deserialization of a [`Value<T>`] type which tracks where it was deserialized from.
2+ //!
3+ //! ## Rationale for `Value<T>`
34//!
45//! Often Cargo wants to report semantic error information or other sorts of
56//! error information about configuration keys but it also may wish to indicate
67//! as an error context where the key was defined as well (to help user
78//! debugging). The `Value<T>` type here can be used to deserialize a `T` value
89//! from configuration, but also record where it was deserialized from when it
910//! was read.
11+ //!
12+ //! ## How `Value<T>` deserialization works
13+ //!
14+ //! Deserializing `Value<T>` is pretty special, and serde doesn't have built-in
15+ //! support for this operation. To implement this we extend serde's "data model"
16+ //! a bit. We configure deserialization of `Value<T>` to basically only work with
17+ //! our one deserializer using configuration.
18+ //!
19+ //! We define that `Value<T>` deserialization asks the deserializer for a very
20+ //! special [struct name](NAME) and [struct field names](FIELDS). In doing so,
21+ //! the deserializer will recognize this and synthesize a magical value for the
22+ //! `definition` field when we deserialize it. This protocol is how we're able
23+ //! to have a channel of information flowing from the configuration deserializer
24+ //! into the deserialization implementation here.
25+ //!
26+ //! You'll want to also check out the implementation of `ValueDeserializer` in
27+ //! the [`de`] module. Also note that the names below are intended to be invalid
28+ //! Rust identifiers to avoid conflicts with other valid structures.
29+ //!
30+ //! Finally the `definition` field is transmitted as a tuple of i32/string,
31+ //! which is effectively a tagged union of [`Definition`] itself. You should
32+ //! update both places here and in the impl of [`serde::de::MapAccess`] for
33+ //! `ValueDeserializer` when adding or modifying enum variants of [`Definition`].
34+ //!
35+ //! [`de`]: crate::util::context::de
1036
1137use crate :: util:: context:: GlobalContext ;
1238use serde:: de;
@@ -29,24 +55,6 @@ pub struct Value<T> {
2955
3056pub type OptValue < T > = Option < Value < T > > ;
3157
32- // Deserializing `Value<T>` is pretty special, and serde doesn't have built-in
33- // support for this operation. To implement this we extend serde's "data model"
34- // a bit. We configure deserialization of `Value<T>` to basically only work with
35- // our one deserializer using configuration.
36- //
37- // We define that `Value<T>` deserialization asks the deserializer for a very
38- // special struct name and struct field names. In doing so the deserializer will
39- // recognize this and synthesize a magical value for the `definition` field when
40- // we deserialize it. This protocol is how we're able to have a channel of
41- // information flowing from the configuration deserializer into the
42- // deserialization implementation here.
43- //
44- // You'll want to also check out the implementation of `ValueDeserializer` in
45- // `de.rs`. Also note that the names below are intended to be invalid Rust
46- // identifiers to avoid how they might conflict with other valid structures.
47- // Finally the `definition` field is transmitted as a tuple of i32/string, which
48- // is effectively a tagged union of `Definition` itself.
49-
5058pub ( crate ) const VALUE_FIELD : & str = "$__cargo_private_value" ;
5159pub ( crate ) const DEFINITION_FIELD : & str = "$__cargo_private_definition" ;
5260pub ( crate ) const NAME : & str = "$__cargo_private_Value" ;
0 commit comments