1use crate::args;
6use anyhow::{Context, Error};
7use fidl_fuchsia_update_channelcontrol::{ChannelControlMarker, ChannelControlProxy};
8use fuchsia_component::client::connect_to_protocol;
9
10pub async fn handle_channel_control_cmd(cmd: args::channel::Command) -> Result<(), Error> {
11 let channel_control = connect_to_protocol::<ChannelControlMarker>()
12 .context("Failed to connect to channel control service")?;
13 handle_channel_control_cmd_impl(cmd, &channel_control).await
14}
15
16async fn handle_channel_control_cmd_impl(
17 cmd: args::channel::Command,
18 channel_control: &ChannelControlProxy,
19) -> Result<(), Error> {
20 match cmd {
21 args::channel::Command::Get(_) => {
22 let channel = channel_control.get_current().await?;
23 println!("current channel: {channel}");
24 }
25 args::channel::Command::Target(_) => {
26 let channel = channel_control.get_target().await?;
27 println!("target channel: {channel}");
28 }
29 args::channel::Command::Set(args::channel::Set { channel }) => {
30 channel_control.set_target(&channel).await?;
31 }
32 args::channel::Command::List(_) => {
33 let channels = channel_control.get_target_list().await?;
34 if channels.is_empty() {
35 println!("known channels list is empty.");
36 } else {
37 println!("known channels:");
38 for channel in channels {
39 println!("{channel}");
40 }
41 }
42 }
43 }
44 Ok(())
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use assert_matches::assert_matches;
51 use fidl::endpoints::create_proxy_and_stream;
52 use fidl_fuchsia_update_channelcontrol::ChannelControlRequest;
53 use fuchsia_async as fasync;
54 use futures::prelude::*;
55
56 async fn perform_channel_control_test<V>(argument: args::channel::Command, verifier: V)
57 where
58 V: Fn(ChannelControlRequest),
59 {
60 let (proxy, mut stream) = create_proxy_and_stream::<ChannelControlMarker>();
61 let fut = async move {
62 assert_matches!(handle_channel_control_cmd_impl(argument, &proxy).await, Ok(()));
63 };
64 let stream_fut = async move {
65 let result = stream.next().await.unwrap();
66 match result {
67 Ok(cmd) => verifier(cmd),
68 err => panic!("Err in request handler: {err:?}"),
69 }
70 };
71 future::join(fut, stream_fut).await;
72 }
73
74 #[fasync::run_singlethreaded(test)]
75 async fn test_channel_get() {
76 perform_channel_control_test(args::channel::Command::Get(args::channel::Get {}), |cmd| {
77 match cmd {
78 ChannelControlRequest::GetCurrent { responder } => {
79 responder.send("channel").unwrap();
80 }
81 request => panic!("Unexpected request: {request:?}"),
82 }
83 })
84 .await;
85 }
86
87 #[fasync::run_singlethreaded(test)]
88 async fn test_channel_target() {
89 perform_channel_control_test(
90 args::channel::Command::Target(args::channel::Target {}),
91 |cmd| match cmd {
92 ChannelControlRequest::GetTarget { responder } => {
93 responder.send("target-channel").unwrap();
94 }
95 request => panic!("Unexpected request: {request:?}"),
96 },
97 )
98 .await;
99 }
100
101 #[fasync::run_singlethreaded(test)]
102 async fn test_channel_set() {
103 perform_channel_control_test(
104 args::channel::Command::Set(args::channel::Set { channel: "new-channel".to_string() }),
105 |cmd| match cmd {
106 ChannelControlRequest::SetTarget { channel, responder } => {
107 assert_eq!(channel, "new-channel");
108 responder.send().unwrap();
109 }
110 request => panic!("Unexpected request: {request:?}"),
111 },
112 )
113 .await;
114 }
115
116 #[fasync::run_singlethreaded(test)]
117 async fn test_channel_list() {
118 perform_channel_control_test(args::channel::Command::List(args::channel::List {}), |cmd| {
119 match cmd {
120 ChannelControlRequest::GetTargetList { responder } => {
121 responder
122 .send(&["some-channel".to_owned(), "other-channel".to_owned()])
123 .unwrap();
124 }
125 request => panic!("Unexpected request: {request:?}"),
126 }
127 })
128 .await;
129 }
130}