structio 0.3.0
Internally tagged enums: the variant name goes inside the payload's object, the convention most JSON APIs use.
[dependencies]
structio = "0.3"Added
-
Internal tagging, a second convention for
tagged_enum!, asked for with a tag clause:tagged_enum!(Shape as tag "kind" { .. }). The variant name goes inside the payload's object as a member rather than wrapping it, giving{"kind":"Circle","radius":1}where the clause-free form writes{"Circle":{"radius":1}}. This is what most JSON APIs use, and the only form here that a C++ Glazestd::variantcan be made to agree with, external tagging having nowhere to put the payload's own keys. The clause works onjson_tagged_enum!andbeve_tagged_enum!too.The tag has to be the object's first member, and a document that puts it elsewhere is the new
ErrorCode::ExpectedTag, reported against the offending key. Reading is one pass with no lookahead, so a tag arriving after the members it gives meaning to could only be used by holding the object or walking it twice. Writing always emits the tag first, so this crate's own output round-trips unconditionally, as does any producer that emits its tag first - the conventional ordering. The refusal is loud and positioned rather than a misparse.A payload must be an object (a compile error naming
WriteObjectotherwise), since its members share the object with the tag. Everything else carries over: renaming, case rules, generics, borrowed payloads, reading into an existing value, and the policies. The result is an ordinary object, so pointers, validation and transcoding walk it with no knowledge of enums at all. See docs/enums.md. -
A tag that is also a field of a variant's payload is a compile error. The two share one object, so it would write the name twice; structio reads that back and a last-wins parser does not, keeping the field and losing the variant. The comparison is of wire names, so a collision that only appears after a case rule is caught too.
cargo checkrefuses a declaration with no generics; a generic one is refused when the crate is built, a generic payload having no keys until it is instantiated. -
Parser::read_object_restandParser::finish_internally_tagged, theirReadercounterparts, andWriter::write_internally_taggedin both formats, for hand-written impls of the two newReadInternallyTaggedtraits. A variant carrying nothing writes through the existingwrite_tagged, the bytes being the same object of one member.
Nothing existing changed shape: an externally tagged declaration reads and writes exactly the bytes it did in 0.2.2. The minor bump is for the added ErrorCode variant.