title: Check Some, None in multiple nested enums at once
body: <p>I am looking for a way to use a functional event-type mechanism in my project. Nothing is in production yet, so this can even be rewritten from scratch:</p>
  <p>I want to look for 2 things:</p>
  <ul>
  <li>Presence of value (<code>Option&lt;T&gt;</code>)</li>
  <li>Functional treatment of different types, for determinism</li>
  </ul>
  <p>I've done the latter, but I have some issues with the first one:
  For requests that look like this:</p>
  <pre><code>POST http://127.0.0.1:8000/publish_event HTTP/1.1
  content-type: application/json
  
  {
      &quot;source_id&quot;: &quot;user:asdf&quot;,
      &quot;key&quot;: &quot;temperature&quot;,
      &quot;value&quot;: 25
  }
  </code></pre>
  <p>I've set up the following structs and enums:</p>
  <pre class="lang-rs prettyprint-override"><code>    use std::option::{Option};
      use serde::{Deserialize};
      
      #[derive(Deserialize, Debug)]
      pub struct EventPayload&lt;T&gt;{
          pub key: String,
          pub tag: Option&lt;String&gt;,
          pub value: Option&lt;T&gt;
      }
      
      #[derive(Deserialize, Debug)]
      #[serde(untagged)]
      pub enum EventValue {
          String(EventPayload&lt;String&gt;),
          Float(EventPayload&lt;f32&gt;),
          Int(EventPayload&lt;i32&gt;),
          Bool(EventPayload&lt;bool&gt;)
      }
      
      #[derive(Deserialize, Debug)]
      pub struct PublishSingleValueEventRequest {
          pub source_id: String,
          #[serde(flatten)]
          pub manifest: EventValue
      }
  </code></pre>
  <p>And then, I am using rocket for a simple endpoint. This is where problems appear:</p>
  <pre class="lang-rs prettyprint-override"><code>#[macro_use] extern crate rocket;
  use rocket::serde::json::Json;
  use rocket::http::Status;
  
  #[post(&quot;/publish_event&quot;, format=&quot;application/json&quot;, data=&quot;&lt;request&gt;&quot;)]
  pub fn publish_event(request: Json&lt;PublishSingleValueEventRequest&gt;) -&gt; Status {
      let event = request.0;
      
      /* This region does not compile
      let evt_val: Option = match event.manifest {
          EventValue::String(x) =&gt; x.value,
          EventValue::Float(x) =&gt; x.value,
          EventValue::Int(x) =&gt; x.value,
          EventValue::Bool(x) =&gt; x.value
      };
  
      match evt_val {
          Some(x) =&gt; println!(&quot;Event value: {:?}&quot;, x),
          None =&gt; println!(&quot;No event value provided&quot;)
      }
      */
  
  
      println!(&quot;{:?}&quot;, event.manifest);
      match event.manifest {
          EventValue::String(x) =&gt; {
              println!(&quot;String payload: {:?}&quot;, x.value);
          }
  
          EventValue::Float(x) =&gt; {
              println!(&quot;Float payload: {:?}&quot;, x.value);
          }
  
          EventValue::Int(x) =&gt; {
              println!(&quot;Int payload: {:?}&quot;, x.value);
          }
          
          EventValue::Bool(x) =&gt; {
              println!(&quot;Bool payload: {:?}&quot;, x.value);
          }
      }
  
      Status::Accepted
  }
  
  #[launch]
  fn rocket() -&gt; _ {
      rocket::build().mount(&quot;/&quot;, routes![publish_event])
  }
  </code></pre>
  <p>I would also like this to be more like</p>
  <pre class="lang-rs prettyprint-override"><code>match event.manifest.value {
      Some(x) =&gt; ...,
      None =&gt; ...
  }
  </code></pre>
  <p>...instead of manually unwrapping the <code>.value</code> <code>Option&lt;&gt;</code> fields.</p>