title: serde json deserialize different objects in array
body: <p>Building off of <a href="https://stackoverflow.com/questions/56582722/serde-json-deserialize-any-number">my question</a> earlier, I now need to deserialize an array of different objects. There's an <a href="https://stackoverflow.com/questions/55387434/deserialize-json-array-of-different-types">existing question</a> for exactly this situation, but it's not for serde.</p>
  
  <pre><code>use serde::{Deserialize, Deserializer};
  use serde_json;
  
  #[derive(Debug)]
  struct Duration {
      secs: u64,
      nanos: u32,
  }
  
  #[derive(Deserialize)]
  struct Raw&lt;'a&gt; {
      #[serde(borrow)]
      secs: StrOrNum&lt;'a&gt;,
  }
  
  #[derive(Deserialize)]
  #[serde(untagged)]
  enum StrOrNum&lt;'a&gt; {
      Str(&amp;'a str),
      Num(u64),
      Decimal(f64),
  }
  
  #[derive(Debug, Deserialize)]
  struct DailyTask {
      name: String,
      duration: Duration,
  }
  
  #[derive(Debug, Deserialize)]
  struct WeeklyTask {
      name: String,
      duration: Duration,
      priority: u8,
  }
  
  #[derive(Debug, Deserialize)]
  #[serde(untagged)]
  enum Task {
      Daily(DailyTask),
      Weekly(WeeklyTask),
  }
  
  #[derive(Debug, Deserialize)]
  struct Tasks {
      tasks: Vec&lt;Box&lt;Task&gt;&gt;,
  }
  
  impl&lt;'de&gt; Deserialize&lt;'de&gt; for Duration {
      fn deserialize&lt;D&gt;(deserializer: D) -&gt; Result&lt;Self, D::Error&gt;
      where
          D: Deserializer&lt;'de&gt;,
      {
          let raw = Raw::deserialize(deserializer)?;
  
          match raw.secs {
              StrOrNum::Str(s) =&gt; {
                  if s.parse::&lt;f64&gt;().is_ok() {
                      let mut p = s.splitn(2, ".").fuse();
                      let secs = p.next().map_or(0, |s| s.parse().unwrap_or(0));
                      let frac = p.next().map_or(0, |s| s.parse().unwrap_or(0));
                      let nanos = frac.to_string().len() as u32;
                      let secs = secs * 10_u64.pow(nanos) + frac;
                      Ok(Duration { secs, nanos })
                  } else {
                      Err(serde::de::Error::custom(format!("Not a valid decimal: \"{}\"", s)))
                  }
              }
              StrOrNum::Num(secs) =&gt; Ok(Duration { secs, nanos: 0 }),
              StrOrNum::Decimal(secs) =&gt; {
                  Ok(Duration { secs: secs as u64, nanos: 0 })
              },
          }
      }
  }
  
  fn main() {
      let json_raw = r#"{
          "tasks": [
              {
                  "name": "go to sleep",
                  "duration": 1234
              },
              {
                  "name": "go to work",
                  "duration": "98.7"
              },
              {
                  "name": "do that important thing",
                  "duration": 56.78,
                  "priority": 10
              }
          ]
      }"#;
      let j: Tasks = serde_json::from_str(&amp;json_raw).unwrap();
      println!("{:?}", j);
  }
  </code></pre>
  
  <p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a71f95b9fa6a0a593f66b84eaaf2f303" rel="nofollow noreferrer">playground</a></p>
  
  <p>I'm not sure what I'm getting wrong. Is there a simple solution for this too, or do I need to implement a custom <code>Deserialize</code> for <code>enum Task</code> somehow?</p>