serde-yaml
serde-yaml copied to clipboard
Support for serializing flow sequences
It would be amazing to be able to serialize flow sequences, especially for Vec
Would a PR for this be welcome, and any ideas on how to signal that via the API?
yes, that would be nice to have in serde-yaml! In Python's PyYAML there's a default_flow_style option which controls whether to output dicts/sequences always in block (False) or flow (True) style, or, most usefully, if set to None value, it outputs flow style only for the collections that consists only of scalars, e.g.:
contours:
- - x: 222.0
y: -227.0
typ: Line
- x: 329.0
y: -227.0
typ: Line
- x: 329.0
y: 757.0
typ: Line
- x: 222.0
y: 757.0
typ: Line
... would be serialized like this with default_flow_style=None in PyYAML:
contours:
- - {typ: Line, x: 222.0, y: -227.0}
- {typ: Line, x: 329.0, y: -227.0}
- {typ: Line, x: 329.0, y: 757.0}
- {typ: Line, x: 222.0, y: 757.0}
Is there interest in adding support for something like this in serde_yaml?
Yes please! Here's some output I generated today... not ideal.
- - - - -150
- -150
- - -150
- -150
- - -150
- -150
- - -150
- -150
- - -150
- -150
- - -150
- -150
- - -150
- -150
- - -150
- -150
Similar case here, where this:
Vec2: !vec2
- 1.2
- 5.1
Vec3: !vec3
- 1.2
- 5.1
- 1.9
Vec4: !vec4
- 4.9
- 1.1
- 2.3
- 3.5
Color: !color
- 0.7
- 0.8
- 0.9
- 1.0
Has been more nicely represented by other tools as this:
Vec2: !vec2 [1.2. 5.1]
Vec3: !vec3 [1.2, 5.1, 1.9]
Vec4: !vec4 [4.9, 1.1, 2.3, 3.5]
Color: !color [0.7, 0.8, 0.9, 1.0]
So I've been investigating making a PR for this, but TBH I'm having a pretty hard time figuring out a way to implement. Presumably we don't want flow-only: that's basically JSON. Nor would we want the flow style to automatically be used under a certain number of elements, as depending on the content of the elements this may or may not produce desirable output (e.g. an array of three gigantic maps should probably not use the flow style).
The only way that would seems reasonable would be to factor both length and content (e.g. I've seen conditions used in other projects like, "If there are less than 10 children and none of them are an array or map, use flow style"). But I am not sure this is at all possible the way Serde and serde-yaml are set up, as it would require you to look ahead to whether the children of a sequence or map will themselves have children while initiating the sequence or map.
Take the following idea with a gain of salt.. I haven't done Rust and serde work for a few months:
- Add a
FlowWrappertype that can wrap anotherSerializetype. - Mark fields that should be flow as
#[serde(into = "FlowWrapper<MyField>")] - The YAML serlializer specializes on
FlowWrapperto serialize in flow style (not sure if this is even possible).
Side note: For my use case listed above I ended up writing my own little function to emit YAML (ie, not using serde at all). It was simple and provided exactly what I wanted.
i would also like to see this being implemented and being able to manually specify which type should be used
example:
#[derive(Debug, Serialize, Deserialize)]
struct Test {
pub list: Vec<Testy>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum Testy {
String(String),
#[serde(serialize_with = "serde_yaml::IntoFlow")] // maybe even something more convenient?
Tuple(String, bool),
}
and produce the following:
list:
- Test
- [Test, true]
instead of
list:
- Test
- - Test
- true