Skip to content

AttributeValue covers four of JSON's six value types #2

Description

@nekoyoubi

AttributeValue currently models String, Number, Bool, and Null. JSON has six value types; arrays and objects are missing, so an attribute value that is an array or an object cannot round-trip.

pub enum AttributeValue {
    String(String),
    Number(f32),
    Bool(bool),
    Null,
}

The decision to go beyond strings was already made when Number and Bool were added, and I think arrays and objects are the natural completion of that set rather than a new direction. JsonML's attribute object is a plain JSON object, and nothing in the format restricts its values to scalars.

This matters in practice for JsonML documents whose nodes are components rather than markup elements, where a node's attributes carry structured configuration. Two examples of the shape:

["Gauge",  { "style": { "fg": "Green", "bold": true } }]
["Layout", { "constraints": ["Length:1", "Min:0", "Length:1"] }]

Neither survives a round-trip today.

Also: Number is f32

JSON numbers are double-precision. Number(f32) silently loses precision for integers above 2^24 and for most decimal fractions:

// 16_777_217.0_f32 == 16_777_216.0_f32

I think this should be f64.

Both changes are breaking

Element and AttributeValue are not #[non_exhaustive], so adding variants breaks any downstream exhaustive match, and the f32 to f64 change is breaking on its own. That puts this at 0.6.0.

If you are open to it, I would suggest adding #[non_exhaustive] to both enums in the same release, so that this is the last time a variant addition is a breaking change.

Offer

I am happy to do the work: the two variants, the f64 change, #[non_exhaustive], serde round-trip tests for nested arrays and objects, and a CHANGELOG.md entry under [Unreleased].

Entirely your call, though. If you would rather keep the value set scalar, say so and I will drop it. I would rather hear no than have you feel obliged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions