Skip to main content

Module serde_finite

Module serde_finite 

Source
Expand description

Structural non-finite-float guard for anything that implements Serialize.

§Why this exists

serde_json renders f64::NAN and ±f64::INFINITY as the JSON literal null — JSON has no encoding for them and serde_json’s serializer takes the lossy branch silently. A persisted model carrying one non-finite scalar therefore writes without complaint and only fails on the way back in, as

invalid type: null, expected f64

— an error that names neither the field nor the fit that produced it, and that surfaces arbitrarily far from the computation at fault (#2601).

§Why it is structural rather than a field list

The pre-existing guards (ensure_finite_scalar, validate_all_finite, and the hand-maintained FittedModel::validate_numeric_finiteness) each name one field. A hand-maintained enumeration over a struct with hundreds of optional numeric fields cannot stay complete: every new field is opted OUT by default, so the guard silently stops covering the payload as the payload grows. That is exactly how #2601’s null reached a saved model.

ensure_serialized_floats_are_finite instead walks the value through serde’s own data model — the same traversal the JSON writer performs — so every float that would be written is checked, by construction, with no per-field opt-in. It tracks the struct-field / map-key / sequence-index path as it descends, so the error names the offending scalar the way the scalar-at-a-time guards do:

payload.fit_result.blocks[3].edf must be finite, got NaN

The walk allocates nothing per scalar; only the current path (bounded by the nesting depth) and the borrowed field names are held.

Structs§

NonFiniteFloat
A non-finite float found at path while walking a serializable value.

Functions§

ensure_serialized_floats_are_finite
Walk value through serde’s data model and fail on the FIRST non-finite f32/f64 that a serializer would emit, reporting its path.