2

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Paul
  • 21
  • 1

1 Answers1

1

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,
}
Emerson Harkin
  • 889
  • 5
  • 13
  • Don't implement `Into` directly. [When should I implement std::convert::From vs std::convert::Into?](https://stackoverflow.com/q/29812530/155423) – Shepmaster Aug 05 '20 at 15:41
  • Thanks @Shepmaster, I didn't know manual `impl Into` was discouraged. Edited accordingly. – Emerson Harkin Aug 06 '20 at 13:28