title: Can Serde deserialize JSON to one of a set of types depending on the value of a field?
body: <p>I have a group of different messages that come in as JSON and can be distinguished based on a single field, but then each variant has a different collection of secondary fields:</p>
  
  <pre><code>#[derive(Debug, Serialize, Deserialize)]
  struct MessageOne {
      ///op will always be "one"
      op: String,
      x: f64,
      y: f64,
  }
  
  #[derive(Debug, Serialize, Deserialize)]
  struct MessageTwo {
      ///op will always be "two"
      op: String,
      a: f64,
      b: i64,
  }
  </code></pre>
  
  <p>The different message types are routed to different processing functions (e.g. <code>process_message_one</code>, <code>process_message_two</code>, etc). Is there an elegant or idiomatic way to automatically select the correct message sub-type? Currently I've defined a generic message:</p>
  
  <pre><code>#[derive(Debug, Serialize, Deserialize)]
  struct MessageGeneric {
      op: String,
  }
  </code></pre>
  
  <p>then parse the incoming JSON into the <code>MessageGeneric</code>, read the <code>op</code> field and then deserialize again, matching on <code>op</code> to select the correct message type. Full example:</p>
  
  <pre><code>#![allow(unused)]
  
  extern crate serde; // 1.0.78
  extern crate serde_json; // 1.0.27
  
  #[macro_use]
  extern crate serde_derive;
  
  use std::collections::HashMap;
  
  #[derive(Debug, Serialize, Deserialize)]
  struct MessageGeneric {
      op: String,
  }
  
  #[derive(Debug, Serialize, Deserialize)]
  struct MessageOne {
      ///op will always be "one"
      op: String,
      x: f64,
      y: f64,
  }
  
  #[derive(Debug, Serialize, Deserialize)]
  struct MessageTwo {
      ///op will always be "two"
      op: String,
      a: f64,
      b: f64,
  }
  
  fn process_message_one(m: &amp;MessageOne) {
      println!("Processing a MessageOne: {:?}", m);
  }
  
  fn process_message_two(m: &amp;MessageTwo) {
      println!("Processing a MessageTwo: {:?}", m);
  }
  
  
  
  fn main() {
      let data = r#"{
          "op": "one",
          "x": 1.0,
          "y": 2.0
      }"#;
  
      let z: MessageGeneric = serde_json::from_str(data).unwrap();
  
      match z.op.as_ref() {
          "one" =&gt; {
              let zp: MessageOne = serde_json::from_str(data).unwrap();
              process_message_one(&amp;zp);
          },
          "two" =&gt; {
              let zp: MessageTwo = serde_json::from_str(data).unwrap();
              process_message_two(&amp;zp);
          },
          _ =&gt; println!("Unknown Message Type")
  
      }
  
  }
  </code></pre>
  
  <p>I've seen <a href="https://serde.rs/enum-representations.html" rel="noreferrer">Serde's enum representations</a> but it was unclear to me if/how that would be applied in this case. The messages coming in are defined by an external API, so I can't control their content beyond knowing what the variants are.</p>