fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError>Expand description
Refuse a message whose discriminator disagrees with the fields beside it.
Two draft-19 messages carry a field that says which of the following fields
are on the wire: FETCH’s Fetch Type, and REQUEST_ERROR’s Error Code, whose
REDIRECT value (0x34) is what puts the Redirect structure on the wire. This
codec holds the alternatives in an enum and an Option, so a value can say
one thing in its discriminator and another in its body, and the two sides of
the codec resolve that differently — the encoder writes whatever the body
holds, and the decoder reads whatever the discriminator announces.
The result is a message that does not survive its own round trip:
- A FETCH whose type says Standalone and whose body is a joining pair encodes to a joining request id and a joining start where a Track Namespace and a Track Name belong, and comes back as a Standalone fetch of a track named after two integers — or, more often, as an error, which at least is honest. The two joining types share one body shape, so the check is between Standalone and everything else rather than one arm per type.
- A REQUEST_ERROR with code REDIRECT and no Redirect body encodes to a message that ends where the decoder expects a Connect URI length, so the peer reads the redirect out of whatever follows or runs off the end. The mirror case is quieter and no better: a Redirect body under any other error code is written out and then skipped by a decoder that was never told to look for it, so the sender believes it redirected a peer that never saw a redirect.
Refusing at the encoder keeps the two readings from ever diverging on the wire.