serde icon indicating copy to clipboard operation
serde copied to clipboard

Support adjacently tagged enum but with content name equals to tag

Open WiSaGaN opened this issue 1 year ago • 4 comments

I have:

{"type":"function","function":{"name":"foo","parameters":"bar"}}
{"type":"search","search":{"keyword":"foo"}}

I want them to be deserialized into

#[derive(Deserialize, Serialize)]                                            
#[serde(tag = "type", content = tag)] // Not supported now
#[serde(rename_all = "snake_case")]
enum Tool {
    Function(Function),
    Search(Search),
}
#[derive(Deserialize, Serialize)]
struct Function {
    name: String,
    parameters: String,
}
#[derive(Deserialize, Serialize)]
struct Search {
    keyword: String,
}

And also these structs serialized into those.

Motivated by OpenAI API: https://platform.openai.com/docs/api-reference/chat/create functions

Currently we can get around using below

#[derive(Deserialize, Serialize)]
#[serde(tag = "type")]
enum Tool {
    Function {
        function: Function,
    },
    Search {
        search: Search,
    },
}

But would be much cleaner and avoid inconsistent data if we have native support.

WiSaGaN avatar Jan 19 '24 04:01 WiSaGaN

I would also like to see this feature. This structure is used in glTF, notably by cameras:

{
    "name": "Finite perspective camera",
    "type": "perspective",
    "perspective": {
        "aspectRatio": 1.5,
        "yfov": 0.660593,
        "zfar": 100,
        "znear": 0.01
    }
}

alteous avatar Feb 03 '24 16:02 alteous

From your example it seems like the type field can be skipped for deserialization and then just use the default externally tagged enum representation?

andrewtoth avatar Feb 05 '24 05:02 andrewtoth

From your example it seems like the type field can be skipped for deserialization and then just use the default externally tagged enum representation?

Yes, it would work in that case for deserialization, but would be trickier for serialization.

WiSaGaN avatar Feb 05 '24 08:02 WiSaGaN