[wlan] Support `match` expressions in write_frame!

Supports match expressions in the write_frame! macro.
The expected return type is of: Option<&ValueType>

`match` expressions are supported for optional and
required IEs.

Bug: 43987
Test: Included
Change-Id: Ia921b5678db1c8a8df0ef0b547c290d13403c643
diff --git a/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs b/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
index 4b23894..2c0cc52 100644
--- a/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
+++ b/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
@@ -7,7 +7,7 @@
     quote::quote,
     syn::{
         parse::{Parse, ParseStream},
-        Error, Expr, ExprIf, Ident, Result, Token,
+        Error, Expr, Ident, Result, Token,
     },
 };
 
@@ -61,7 +61,6 @@
     ($name:expr, $optional:expr, $expr:expr) => {
         match $expr {
             Expr::If(if_expr) => {
-                let if_expr: &ExprIf = if_expr;
                 if if_expr.else_branch.is_some() {
                     if $optional {
                         quote!(let $name: Option<_> = #if_expr;)
@@ -219,7 +218,9 @@
             Ie::DsssParamSet => {
                 apply_on!(dsss, &self.value, ie::write_dsss_param_set(&mut w, &dsss)?)
             }
-            Ie::Wpa1 => apply_on!(wpa1, &self.value, ie::write_wpa1_ie(&mut w, &wpa1)?),
+            Ie::Wpa1 => {
+                apply_on!(wpa1, self.optional, &self.value, ie::write_wpa1_ie(&mut w, &wpa1)?)
+            }
         })
     }
 
@@ -261,6 +262,7 @@
             | Expr::Tuple(_)
             | Expr::Unary(_)
             | Expr::Index(_)
+            | Expr::Match(_)
             | Expr::Path(_) => (),
             other => {
                 return Err(Error::new(
diff --git a/src/connectivity/wlan/lib/frame_writer/src/lib.rs b/src/connectivity/wlan/lib/frame_writer/src/lib.rs
index b283f80..48f56db 100644
--- a/src/connectivity/wlan/lib/frame_writer/src/lib.rs
+++ b/src/connectivity/wlan/lib/frame_writer/src/lib.rs
@@ -271,7 +271,7 @@
                 0xdd, 0x16, // Vendor IE header
                 0x00, 0x50, 0xf2, // MSFT OUI
                 0x01, 0x01, 0x00, // WPA IE header
-                0x00, 0x50, 0xf2, 0x02, // multicast cipher: AKM
+                0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
                 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
                 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
             ][..],
@@ -280,6 +280,122 @@
     }
 
     #[test]
+    fn write_match_optional_positive() {
+        let wpa_ie = wpa::WpaIe {
+            multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+            unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+            akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+        };
+
+        let buffer_provider = BufferProvider;
+        let (buf, bytes_written) = write_frame!(buffer_provider, {
+            ies: {
+                wpa1?: match 2u8 {
+                    1 => None,
+                    2 => Some(&wpa_ie),
+                    _ => None,
+                },
+            }
+        })
+        .expect("frame construction failed");
+        assert_eq!(bytes_written, 24);
+        assert_eq!(
+            &[
+                0xdd, 0x16, // Vendor IE header
+                0x00, 0x50, 0xf2, // MSFT OUI
+                0x01, 0x01, 0x00, // WPA IE header
+                0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+            ][..],
+            &buf[..]
+        );
+    }
+
+    #[test]
+    fn write_match_optional_negative() {
+        let wpa_ie = wpa::WpaIe {
+            multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+            unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+            akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+        };
+
+        let buffer_provider = BufferProvider;
+        let (buf, bytes_written) = write_frame!(buffer_provider, {
+            ies: {
+                wpa1?: match 1u8 {
+                    1 => None,
+                    2 => Some(&wpa_ie),
+                    _ => None,
+                },
+            }
+        })
+        .expect("frame construction failed");
+        assert_eq!(bytes_written, 0);
+        assert!(buf.is_empty());
+    }
+
+    #[test]
+    fn write_match_required() {
+        let wpa_ie_first = wpa::WpaIe {
+            multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+            unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+            akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+        };
+        let wpa_ie_second = wpa::WpaIe {
+            multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: CCMP_128 },
+            unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: CCMP_128 }],
+            akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+        };
+
+        let buffer_provider = BufferProvider;
+        let (buf, bytes_written) = write_frame!(buffer_provider, {
+            ies: {
+                wpa1: match 1u8 {
+                    1 => &wpa_ie_first,
+                    _ => &wpa_ie_second,
+                },
+            }
+        })
+        .expect("frame construction failed");
+        assert_eq!(bytes_written, 24);
+        assert_eq!(
+            &[
+                0xdd, 0x16, // Vendor IE header
+                0x00, 0x50, 0xf2, // MSFT OUI
+                0x01, 0x01, 0x00, // WPA IE header
+                0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+            ][..],
+            &buf[..]
+        );
+
+        let buffer_provider = BufferProvider;
+        let (buf, bytes_written) = write_frame!(buffer_provider, {
+            ies: {
+                wpa1: match 2u8 {
+                    1 => &wpa_ie_first,
+                    _ => &wpa_ie_second,
+                },
+            }
+        })
+        .expect("frame construction failed");
+        assert_eq!(bytes_written, 24);
+        assert_eq!(
+            &[
+                0xdd, 0x16, // Vendor IE header
+                0x00, 0x50, 0xf2, // MSFT OUI
+                0x01, 0x01, 0x00, // WPA IE header
+                0x00, 0x50, 0xf2, 0x04, // multicast cipher: CCMP_128
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x04, // 1 unicast cipher: CCMP_128
+                0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+            ][..],
+            &buf[..]
+        );
+    }
+
+    #[test]
     fn write_ht_caps() {
         let buffer_provider = BufferProvider;
         let (buf, bytes_written) = write_frame!(buffer_provider, {