Simplify the types by using a nested record for publish.qos

The presence of a message_id field in a publish frame depends on the
value of qos. Pairing the qos level and message_id in a record
simplifies the types.

There are also a few frames for which the qos is fixed at 1 (e.g.,
subscribe) -- I've removed the field from the frame record and
hard-wired it in the parsing and serialising.