How to serialize one field in 2?

Can I do only serialization from the shelf_life: Limit field

#[derive(Debug)]
pub enum Limit {
    HOURS(i64),
    DAYS(i64),
    WEEKS(i64),
    MONTHS(i64),
    YEARS(i64),
    NOT_LIMITED,
}

into 2 fields shelfLife: i64 and shelfLifeType: String, which will be flattened against the struct.
At the moment I'm using:

...
#[serde(
    rename(deserialize(deserialize = “shelfLifeInDays”, serialize = “shelfLife”),
    deserialize_with = “deserialize_shelf_life”,
    serialize_with = “serialize_shelf_life”,
)]
pub shelf_life: Limit,
...

fn serialize_shelf_life<S>(shelf: &Limit, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let mut map = s.serialize_map(Some(2)).unwrap();
    let (type_, value) = match shelf {
        HOURS(v) => (“HOURS”, v),
        DAYS(v) => (“DAYS”, v),
        WEEKS(v) => (“WEEKS”, v),
        MONTHS(v) => (“MONTHS”, v),
        YEARS(v) => (“YEARS”, v),
        NOT_LIMITED => (“NOT_LIMITED”, &i64::MAX),
    };
    map.serialize_entry(
        “shelfLife”,
        value
    ).unwrap();
    map.serialize_entry(
        “shelfLifeType”,
        type_
    ).unwrap();
    map.end()
}

which, creates the structure:

“shelfLife”: {
    “shelfLife”: 0,
    “shelfLifeType": ”DAYS”
}

and required:

...
“shelfLife”: 0,
“shelfLifeType": ”DAYS”
...

Sounds like you are looking for adjacently tagged enums? Enum representations · Serde. Example.

3 Likes
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = “shelfLifeType”, content = “shelfLife”)]]
pub enum Limit {
    HOURS(i64),
    DAYS(i64),
    WEEKS(i64),
    MONTHS(i64),
    YEARS(i64),
    NOT_LIMITED,
}
...
#[serde(
    rename(deserialize(deserialize = “shelfLifeInDays”),
    deserialize_with = “deserialize_shelf_life”,
)]
pub shelf_life: Limit,
...

I get:

“shelf_life”: {
    “shelfLifeTypse”: “DAYS”,
    “shelfLife": 0
 },

fields are not merged with an external structure.
I know there is flatten, I deserialize certain fields in shelf_life: Limit, but by serializing I need to create 2 fields. flatten will not work, because when deserializing, there is no structure, but when serializing I get structure (as json). If one could do flatten only on serialization would it work? Or does flatten work based on struct?

It's unclear what you are asking. If you are having trouble expressing yourself in English, please seek help from a fluent speaker. And in any case, do provide concrete code and examples of expected input/output. It's nearly impossible to help you based on vague, abstract descriptions.

I'm not sure I understand. flatten works for serializing the adjacently tagged enum as well or have I misunderstood your requirements?

1 Like

In the json I only have the shelfLifeInDays field as here.
That's why I can't use flatten.

So is the goal then to determine the type by the name of the field being of the form "shelfLifeInXXX”? That seems different from what you described before.

I may have forgotten to emphasize the serialization stage. At the deserialization stage I use another method: deserialize_shelf_life. At the serialization stage I have to serialize the field shelf_life: Limit into 2 fields: shelfLife and shelfLifeType

Your thread title explicitly asks how to serialize the enum in a specific way, which has been answered (tag, content and flatten). If you need to deserialize the data in another way, you have multiple options.

  1. Don't derive, but implement Deserialize manually.
  2. Use different data structures for serialization and deserialization that represent the data of the respective APIs and implement appropriate conversion traits between them. *

*) My recommendation

3 Likes

So there is essentially no solution to this problem? I needed to know if adding the flatten_serialize option inflatten would work.

What does deserialize_shelf_life look like? What format are you deserializing from?

Here I changed your code and added deserialize_shelf_life. Which deserializes i64

I agree with Shard, I'd use two different types for serialization and deserialization respectively. There is no version of flatten that'd only do the flattening on serialization but not on deserialization.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.