Paul
Paul

Reputation: 21

Is there a way to group fields of a struct when serializing with Serde, like the inverse of the "flatten" attribute?

Serde has a flatten attribute which flattens one level of the data structure. I want the inverse: a way to group attributes.

I have the struct

struct Foo {
    owner: Owner,
    alpha: Server,
    beta: Server,
}

and I want the servers to be serialized in a nested fashion, such:

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates
[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

by default Serde would produce:

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates

[alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[beta]
ip = "10.0.0.2"
dc = "eqdc10"

Which I don't want. Is there a way to get the first YAML output without refactoring my struct?

Upvotes: 2

Views: 815

Answers (1)

Emerson Harkin
Emerson Harkin

Reputation: 917

If you can't refactor Foo for some reason, maybe you could create a new struct that captures the nested structure and use the Serde from and into attributes to serialize Foo through it.

Example

#[derive(Clone)]
#[serde(from = "IntermediateFoo", into = "IntermediateFoo")]
pub struct Foo {
    owner: Owner,
    alpha: Server,
    beta: Server,
}

impl From<Foo> for IntermediateFoo {
    /* ... */
}

impl From<IntermediateFoo> for Foo {
    /* ... */
}

#[derive(Serialize, Deserialize)]
struct IntermediateFoo {
    owner: Owner,
    servers: IntermediateServers,
}

#[derive(Serialize, Deserialize)]
struct IntermediateServers {
    alpha: Server,
    beta: Server,
}

Upvotes: 1

Related Questions