Expand description
Manual Serialize / Deserialize for the outer DataContract enum.
§Critical-4: platform-version coupling (pinned by tests below)
Both impls call PlatformVersion::get_version_or_current_or_latest(None),
making serialization output depend on a process-global thread-local-ish
state — same DataContract value, different bytes if the active platform
version changes. This is by design: DataContract is a versioned enum
routed through DataContractInSerializationFormat, and the format depends
on the current platform.
§Validation policy: validate by default
The Deserialize impl runs full schema validation — it decodes the
wire form into DataContractInSerializationFormat, then converts it to a
DataContract with full_validation = true. So
serde_json::from_value::<DataContract>(...) / from_str reject a
structurally-decodable but schema-invalid contract: a DataContract you
can hold is a valid one.
To reconstruct already-trusted data without re-validating it (e.g.
storage reads, round-trips of a known-good value), use the explicit
no-validation path
DataContractJsonConversionMethodsV0::from_json(value, false, pv) /
DataContractValueConversionMethodsV0::from_value(value, false, pv) — those
call try_from_platform_versioned directly and skip schema validation.
Why this is KEEP-AS-EXCEPTION: the manual impls also inject the active
PlatformVersion (via get_version_or_current_or_latest), coupling the
output to process-global state. This is by design — DataContract is a
versioned enum routed through DataContractInSerializationFormat, and the
format depends on the current platform. The stateless alternative is the
bincode storage path (serialize_to_bytes_with_platform_version).
The data_contract_serde_pins_critical_4 test module below pins this
behavior (validate-by-default + explicit false opt-out) so future
refactors can’t silently change it.