diff --git a/garnet/bin/ui/text/test_suite/src/test_helpers.rs b/garnet/bin/ui/text/test_suite/src/test_helpers.rs
index e3051b8b6c9811d93c87c59066c8b3b3dc7728da..30be6e755577d3002f1be1de14f8d26d49cd5708 100644
--- a/garnet/bin/ui/text/test_suite/src/test_helpers.rs
+++ b/garnet/bin/ui/text/test_suite/src/test_helpers.rs
@@ -271,31 +271,25 @@ mod test {
                 await!(wrapper.simple_insert("meow!")).expect("Should have inserted successfully");
             },
         );
-        if let txt::TextFieldRequest::BeginEdit { revision, .. } = await!(stream.try_next())
+        let (revision, _ch) = await!(stream.try_next())
             .expect("Waiting for message failed")
             .expect("Should have sent message")
-        {
-            assert_eq!(revision, 4);
-        } else {
-            panic!("Expected BeginEdit");
-        }
-        if let txt::TextFieldRequest::Replace { new_text, .. } = await!(stream.try_next())
+            .into_begin_edit()
+            .expect("Expected BeginEdit");
+        assert_eq!(revision, 4);
+
+        let (_range, new_text, _ch) = await!(stream.try_next())
             .expect("Waiting for message failed")
             .expect("Should have sent message")
-        {
-            assert_eq!(new_text, "meow!");
-        } else {
-            panic!("Expected Replace");
-        }
-        if let txt::TextFieldRequest::CommitEdit { .. } = await!(stream.try_next())
+            .into_replace()
+            .expect("Expected Replace");
+        assert_eq!(new_text, "meow!");
+
+        await!(stream.try_next())
             .expect("Waiting for message failed")
             .expect("Should have sent message")
-        {
-            // ok!
-        } else {
-            panic!("Expected CommitEdit");
-        }
-        assert!(true);
+            .into_commit_edit()
+            .expect("Expected CommitEdit");
     }
 
     #[fuchsia_async::run_singlethreaded]
diff --git a/garnet/go/src/fidl/compiler/backend/goldens/doc_comments.test.fidl.json.rs.golden b/garnet/go/src/fidl/compiler/backend/goldens/doc_comments.test.fidl.json.rs.golden
index 1e39f004db6072d25385de246ca9aff86f5a3974..a461129f297b0acf30967351a6877488888e5945 100644
--- a/garnet/go/src/fidl/compiler/backend/goldens/doc_comments.test.fidl.json.rs.golden
+++ b/garnet/go/src/fidl/compiler/backend/goldens/doc_comments.test.fidl.json.rs.golden
@@ -232,6 +232,21 @@ pub enum InterfaceEvent {
 		
 	},}
 
+impl InterfaceEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_on_event(self) -> Option<(
+	)> {
+		if let InterfaceEvent::OnEvent {
+		} = self {
+			Some((
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct InterfaceEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -356,6 +371,21 @@ pub enum InterfaceRequest {
 		control_handle: InterfaceControlHandle,},
 }
 
+impl InterfaceRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method(self) -> Option<(InterfaceControlHandle,
+	)> {
+		if let InterfaceRequest::Method {control_handle,
+		} = self {
+			Some((control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct InterfaceEncoder;
 impl InterfaceEncoder {
 	pub fn encode_method_request<'a>(
diff --git a/garnet/go/src/fidl/compiler/backend/goldens/ordinal_switch.test.fidl.json.rs.golden b/garnet/go/src/fidl/compiler/backend/goldens/ordinal_switch.test.fidl.json.rs.golden
index 4718810722e6748ca766f13c8f75af548be39a20..8d1cc35cfc402286ea4218d6f3bf65901304d281 100644
--- a/garnet/go/src/fidl/compiler/backend/goldens/ordinal_switch.test.fidl.json.rs.golden
+++ b/garnet/go/src/fidl/compiler/backend/goldens/ordinal_switch.test.fidl.json.rs.golden
@@ -192,6 +192,33 @@ pub enum SwitchingOrdinalsEvent {
 		
 	},}
 
+impl SwitchingOrdinalsEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_ordinal_fifteen(self) -> Option<(
+	)> {
+		if let SwitchingOrdinalsEvent::EventOrdinalFifteen {
+		} = self {
+			Some((
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_only_generated_ordinal(self) -> Option<(
+	)> {
+		if let SwitchingOrdinalsEvent::EventOnlyGeneratedOrdinal {
+		} = self {
+			Some((
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct SwitchingOrdinalsEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -330,6 +357,33 @@ pub enum SwitchingOrdinalsRequest {
 		control_handle: SwitchingOrdinalsControlHandle,},
 }
 
+impl SwitchingOrdinalsRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_ordinal_five(self) -> Option<(SwitchingOrdinalsControlHandle,
+	)> {
+		if let SwitchingOrdinalsRequest::OrdinalFive {control_handle,
+		} = self {
+			Some((control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_only_generated_ordinal(self) -> Option<(SwitchingOrdinalsControlHandle,
+	)> {
+		if let SwitchingOrdinalsRequest::OnlyGeneratedOrdinal {control_handle,
+		} = self {
+			Some((control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct SwitchingOrdinalsEncoder;
 impl SwitchingOrdinalsEncoder {
 	pub fn encode_ordinal_five_request<'a>(
diff --git a/garnet/go/src/fidl/compiler/backend/goldens/protocol_request.test.fidl.json.rs.golden b/garnet/go/src/fidl/compiler/backend/goldens/protocol_request.test.fidl.json.rs.golden
index 62178920580f8e0af0d39f759a54bfc9650d2207..e6178ddd95a1829a0461b3d78c4b0c3b9959359c 100644
--- a/garnet/go/src/fidl/compiler/backend/goldens/protocol_request.test.fidl.json.rs.golden
+++ b/garnet/go/src/fidl/compiler/backend/goldens/protocol_request.test.fidl.json.rs.golden
@@ -136,6 +136,9 @@ impl futures::Stream for ChildEventStream {
 pub enum ChildEvent {
 	}
 
+impl ChildEvent {
+}
+
 pub struct ChildEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -234,6 +237,9 @@ impl futures::Stream for ChildRequestStream {
 pub enum ChildRequest {
 }
 
+impl ChildRequest {
+}
+
 pub struct ChildEncoder;
 impl ChildEncoder {}
 
@@ -448,6 +454,9 @@ pub enum ParentEvent {
 	
 	}
 
+impl ParentEvent {
+}
+
 pub struct ParentEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -602,6 +611,69 @@ pub enum ParentRequest {
 		control_handle: ParentControlHandle,},
 }
 
+impl ParentRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_get_child(self) -> Option<(ParentGetChildResponder,
+	)> {
+		if let ParentRequest::GetChild {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_get_child_request(self) -> Option<(ParentGetChildRequestResponder,
+	)> {
+		if let ParentRequest::GetChildRequest {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_take_child(self) -> Option<(
+		fidl::endpoints::ClientEnd<ChildMarker>,
+		ParentControlHandle,
+	)> {
+		if let ParentRequest::TakeChild {
+			c,
+			control_handle,
+		} = self {
+			Some((
+				c,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_take_child_request(self) -> Option<(
+		fidl::endpoints::ServerEnd<ChildMarker>,
+		ParentControlHandle,
+	)> {
+		if let ParentRequest::TakeChildRequest {
+			r,
+			control_handle,
+		} = self {
+			Some((
+				r,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct ParentEncoder;
 impl ParentEncoder {
 	pub fn encode_get_child_request<'a>(
diff --git a/garnet/go/src/fidl/compiler/backend/goldens/protocols.test.fidl.json.rs.golden b/garnet/go/src/fidl/compiler/backend/goldens/protocols.test.fidl.json.rs.golden
index 7dd355accc472a429b685f8860fb9e5b29f633ea..b57533d8f9c0a68222258b9fdcb884d85f665488 100644
--- a/garnet/go/src/fidl/compiler/backend/goldens/protocols.test.fidl.json.rs.golden
+++ b/garnet/go/src/fidl/compiler/backend/goldens/protocols.test.fidl.json.rs.golden
@@ -305,6 +305,39 @@ pub enum WithAndWithoutRequestResponseEvent {
 		
 	},}
 
+impl WithAndWithoutRequestResponseEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_on_empty_response(self) -> Option<(
+	)> {
+		if let WithAndWithoutRequestResponseEvent::OnEmptyResponse {
+		} = self {
+			Some((
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_on_with_response(self) -> Option<(
+		String,
+		
+	)> {
+		if let WithAndWithoutRequestResponseEvent::OnWithResponse {
+			ret,
+			
+		} = self {
+			Some((
+				ret,
+				
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct WithAndWithoutRequestResponseEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -510,6 +543,99 @@ pub enum WithAndWithoutRequestResponseRequest {
 		responder: WithAndWithoutRequestResponseWithRequestWithResponseResponder,},
 }
 
+impl WithAndWithoutRequestResponseRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_no_request_no_response(self) -> Option<(WithAndWithoutRequestResponseControlHandle,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::NoRequestNoResponse {control_handle,
+		} = self {
+			Some((control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_no_request_empty_response(self) -> Option<(WithAndWithoutRequestResponseNoRequestEmptyResponseResponder,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::NoRequestEmptyResponse {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_no_request_with_response(self) -> Option<(WithAndWithoutRequestResponseNoRequestWithResponseResponder,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::NoRequestWithResponse {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_with_request_no_response(self) -> Option<(
+		String,
+		WithAndWithoutRequestResponseControlHandle,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::WithRequestNoResponse {
+			arg,
+			control_handle,
+		} = self {
+			Some((
+				arg,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_with_request_empty_response(self) -> Option<(
+		String,
+		WithAndWithoutRequestResponseWithRequestEmptyResponseResponder,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::WithRequestEmptyResponse {
+			arg,
+			responder,
+		} = self {
+			Some((
+				arg,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_with_request_with_response(self) -> Option<(
+		String,
+		WithAndWithoutRequestResponseWithRequestWithResponseResponder,
+	)> {
+		if let WithAndWithoutRequestResponseRequest::WithRequestWithResponse {
+			arg,
+			responder,
+		} = self {
+			Some((
+				arg,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct WithAndWithoutRequestResponseEncoder;
 impl WithAndWithoutRequestResponseEncoder {
 	pub fn encode_no_request_no_response_request<'a>(
@@ -1183,6 +1309,9 @@ pub enum WithErrorSyntaxEvent {
 	
 	}
 
+impl WithErrorSyntaxEvent {
+}
+
 pub struct WithErrorSyntaxEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -1311,6 +1440,33 @@ pub enum WithErrorSyntaxRequest {
 		responder: WithErrorSyntaxErrorAsEnumResponder,},
 }
 
+impl WithErrorSyntaxRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_error_as_primitive(self) -> Option<(WithErrorSyntaxErrorAsPrimitiveResponder,
+	)> {
+		if let WithErrorSyntaxRequest::ErrorAsPrimitive {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_error_as_enum(self) -> Option<(WithErrorSyntaxErrorAsEnumResponder,
+	)> {
+		if let WithErrorSyntaxRequest::ErrorAsEnum {responder,
+		} = self {
+			Some((responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct WithErrorSyntaxEncoder;
 impl WithErrorSyntaxEncoder {
 	pub fn encode_error_as_primitive_request<'a>(
@@ -1748,6 +1904,33 @@ pub enum OvernetInternalProtocolEvent {
 	
 	}
 
+impl OvernetInternalProtocolEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_a(self) -> Option<(
+		i64,
+		
+		i64,
+		
+	)> {
+		if let OvernetInternalProtocolEvent::EventA {
+			a,
+			
+			b,
+			
+		} = self {
+			Some((
+				a,
+				
+				b,
+				
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct OvernetInternalProtocolEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -1908,6 +2091,75 @@ pub enum OvernetInternalProtocolRequest {
 		responder: OvernetInternalProtocolMutateSocketResponder,},
 }
 
+impl OvernetInternalProtocolRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_a(self) -> Option<(
+		i64,
+		
+		i64,
+		OvernetInternalProtocolControlHandle,
+	)> {
+		if let OvernetInternalProtocolRequest::MethodA {
+			a,
+			
+			b,
+			control_handle,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_b(self) -> Option<(
+		i64,
+		
+		i64,
+		OvernetInternalProtocolMethodBResponder,
+	)> {
+		if let OvernetInternalProtocolRequest::MethodB {
+			a,
+			
+			b,
+			responder,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_mutate_socket(self) -> Option<(
+		zx::Socket,
+		OvernetInternalProtocolMutateSocketResponder,
+	)> {
+		if let OvernetInternalProtocolRequest::MutateSocket {
+			a,
+			responder,
+		} = self {
+			Some((
+				a,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct OvernetInternalProtocolEncoder;
 impl OvernetInternalProtocolEncoder {
 	pub fn encode_method_a_request<'a>(
@@ -2390,6 +2642,33 @@ pub enum SocketControlProtocolEvent {
 	
 	}
 
+impl SocketControlProtocolEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_a(self) -> Option<(
+		i64,
+		
+		i64,
+		
+	)> {
+		if let SocketControlProtocolEvent::EventA {
+			a,
+			
+			b,
+			
+		} = self {
+			Some((
+				a,
+				
+				b,
+				
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct SocketControlProtocolEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -2550,6 +2829,75 @@ pub enum SocketControlProtocolRequest {
 		responder: SocketControlProtocolMutateSocketResponder,},
 }
 
+impl SocketControlProtocolRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_a(self) -> Option<(
+		i64,
+		
+		i64,
+		SocketControlProtocolControlHandle,
+	)> {
+		if let SocketControlProtocolRequest::MethodA {
+			a,
+			
+			b,
+			control_handle,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_b(self) -> Option<(
+		i64,
+		
+		i64,
+		SocketControlProtocolMethodBResponder,
+	)> {
+		if let SocketControlProtocolRequest::MethodB {
+			a,
+			
+			b,
+			responder,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_mutate_socket(self) -> Option<(
+		zx::Socket,
+		SocketControlProtocolMutateSocketResponder,
+	)> {
+		if let SocketControlProtocolRequest::MutateSocket {
+			a,
+			responder,
+		} = self {
+			Some((
+				a,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct SocketControlProtocolEncoder;
 impl SocketControlProtocolEncoder {
 	pub fn encode_method_a_request<'a>(
@@ -3032,6 +3380,33 @@ pub enum ChannelProtocolEvent {
 	
 	}
 
+impl ChannelProtocolEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_a(self) -> Option<(
+		i64,
+		
+		i64,
+		
+	)> {
+		if let ChannelProtocolEvent::EventA {
+			a,
+			
+			b,
+			
+		} = self {
+			Some((
+				a,
+				
+				b,
+				
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct ChannelProtocolEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -3192,6 +3567,75 @@ pub enum ChannelProtocolRequest {
 		responder: ChannelProtocolMutateSocketResponder,},
 }
 
+impl ChannelProtocolRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_a(self) -> Option<(
+		i64,
+		
+		i64,
+		ChannelProtocolControlHandle,
+	)> {
+		if let ChannelProtocolRequest::MethodA {
+			a,
+			
+			b,
+			control_handle,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_b(self) -> Option<(
+		i64,
+		
+		i64,
+		ChannelProtocolMethodBResponder,
+	)> {
+		if let ChannelProtocolRequest::MethodB {
+			a,
+			
+			b,
+			responder,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_mutate_socket(self) -> Option<(
+		zx::Socket,
+		ChannelProtocolMutateSocketResponder,
+	)> {
+		if let ChannelProtocolRequest::MutateSocket {
+			a,
+			responder,
+		} = self {
+			Some((
+				a,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct ChannelProtocolEncoder;
 impl ChannelProtocolEncoder {
 	pub fn encode_method_a_request<'a>(
@@ -3674,6 +4118,33 @@ pub enum KitchenSinkEvent {
 	
 	}
 
+impl KitchenSinkEvent {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_event_a(self) -> Option<(
+		i64,
+		
+		i64,
+		
+	)> {
+		if let KitchenSinkEvent::EventA {
+			a,
+			
+			b,
+			
+		} = self {
+			Some((
+				a,
+				
+				b,
+				
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct KitchenSinkEventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -3834,6 +4305,75 @@ pub enum KitchenSinkRequest {
 		responder: KitchenSinkMutateSocketResponder,},
 }
 
+impl KitchenSinkRequest {
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_a(self) -> Option<(
+		i64,
+		
+		i64,
+		KitchenSinkControlHandle,
+	)> {
+		if let KitchenSinkRequest::MethodA {
+			a,
+			
+			b,
+			control_handle,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				control_handle,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_method_b(self) -> Option<(
+		i64,
+		
+		i64,
+		KitchenSinkMethodBResponder,
+	)> {
+		if let KitchenSinkRequest::MethodB {
+			a,
+			
+			b,
+			responder,
+		} = self {
+			Some((
+				a,
+				
+				b,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_mutate_socket(self) -> Option<(
+		zx::Socket,
+		KitchenSinkMutateSocketResponder,
+	)> {
+		if let KitchenSinkRequest::MutateSocket {
+			a,
+			responder,
+		} = self {
+			Some((
+				a,
+				responder,
+			))
+		} else {
+			None
+		}
+	}
+	
+}
+
 pub struct KitchenSinkEncoder;
 impl KitchenSinkEncoder {
 	pub fn encode_method_a_request<'a>(
diff --git a/garnet/go/src/fidl/compiler/backend/rust/templates/interface.tmpl.go b/garnet/go/src/fidl/compiler/backend/rust/templates/interface.tmpl.go
index 826b3139c0a88abf4b413f95609e4bebcad766e8..68cf1f439ddeafc87136ecd03ddbc724df0582c5 100644
--- a/garnet/go/src/fidl/compiler/backend/rust/templates/interface.tmpl.go
+++ b/garnet/go/src/fidl/compiler/backend/rust/templates/interface.tmpl.go
@@ -282,6 +282,33 @@ pub enum {{ $interface.Name }}Event {
 	{{- end -}}
 }
 
+impl {{ $interface.Name }}Event {
+	{{- range $method := $interface.Methods }}
+	{{- if not $method.HasRequest }}
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_{{ $method.Name }}(self) -> Option<(
+		{{- range $param := $method.Response }}
+		{{ $param.Type }},
+		{{ end }}
+	)> {
+		if let {{ $interface.Name }}Event::{{ $method.CamelName }} {
+			{{- range $param := $method.Response }}
+			{{ $param.Name }},
+			{{ end }}
+		} = self {
+			Some((
+				{{- range $param := $method.Response }}
+				{{ $param.Name }},
+				{{ end }}
+			))
+		} else {
+			None
+		}
+	}
+	{{ end }}
+	{{- end }}
+}
+
 pub struct {{ $interface.Name }}EventSender<'a> {
 	// Some protocols don't define events which would render this channel unused.
 	#[allow(unused)]
@@ -457,6 +484,48 @@ pub enum {{ $interface.Name }}Request {
 	{{- end }}
 }
 
+impl {{ $interface.Name }}Request {
+	{{- range $method := $interface.Methods }}
+	{{- if $method.HasRequest }}
+	#[allow(irrefutable_let_patterns)]
+	pub fn into_{{ $method.Name }}(self) -> Option<(
+		{{- range $param := $method.Request }}
+		{{ $param.Type }},
+		{{ end }}
+		{{- if $method.HasResponse -}}
+		{{ $interface.Name }}{{ $method.CamelName }}Responder,
+		{{- else -}}
+		{{ $interface.Name }}ControlHandle,
+		{{- end }}
+	)> {
+		if let {{ $interface.Name }}Request::{{ $method.CamelName }} {
+			{{- range $param := $method.Request }}
+			{{ $param.Name }},
+			{{ end }}
+			{{- if $method.HasResponse -}}
+			responder,
+			{{- else -}}
+			control_handle,
+			{{- end }}
+		} = self {
+			Some((
+				{{- range $param := $method.Request }}
+				{{ $param.Name }},
+				{{ end }}
+				{{- if $method.HasResponse -}}
+				responder,
+				{{- else -}}
+				control_handle,
+				{{- end }}
+			))
+		} else {
+			None
+		}
+	}
+	{{ end }}
+	{{- end }}
+}
+
 pub struct {{ $interface.Name }}Encoder;
 impl {{ $interface.Name }}Encoder {
 	{{- range $method := $interface.Methods }}