How to set a datatype, which is the union of several types?

I'm new to rust, and I have a problem while I use serde_json to parser json files.

For example, If I want to define a datatype named Domain, which is possible to be a String or Null. In python I can define its type as Union[str, None], but how do I do in rust?

I have found blew codes in Google search:

enum Domain{
String(String),
Null,
}

But it is not OK when I applied it on my serde_json codes: I need to parser the json code which the key domain maybe a string or null, and above definition will triggle blew error:

Err(Error("unknown variant `hotel`, expected `String` or `Null`", line: 1, column: 24))

Is there some solution for me? Thanks.

AFAIK, serde_json has special handling of Rust’s built-in enum type to signal “some value of type T or null”, which is called Option<T>.

Try if using Option<String> instead of Domain works as expected.

If not, you’ll want to give us more detail, e.g. some code together with some concrete json input that results in the error message you got, so we can help you fix the problem.

3 Likes

Thank you very much, it works well.

Another related intersting problem is in some items some "key"s were lost. That is another problem driving me to think out a "Union type". For example, there are two similar data sturcture when I try to parse a json Value, like:

#[derive(Debug, Serialize, Deserialize)]
struct ItemBySystem{
    speaker: String,
    text:String,
    dialogue_act:Vec<Act>,
    active_domain:Domain,
    belief:Belief,
    booked_domains:Vec<Domain>,
    delexicalised_text:String,
    database:Database,
}

#[derive(Debug, Serialize, Deserialize)]
struct ItemByUser{
    speaker: String,
    text:String,
    dialogue_act:Vec<Act>,
}

And all keys in ItemByUser are owned by ItemBySystem. I found a solution by discriminating if a value have the key only owned by ItemBySystem:

if let Some(field)=&item.get("belief"){
...
}

Some other elegant solutions maybe? :rofl:

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.