use crate::args;
use anyhow::{Context, Error};
use fidl_fuchsia_update_channelcontrol::{ChannelControlMarker, ChannelControlProxy};
use fuchsia_component::client::connect_to_protocol;
pub async fn handle_channel_control_cmd(cmd: args::channel::Command) -> Result<(), Error> {
let channel_control = connect_to_protocol::<ChannelControlMarker>()
.context("Failed to connect to channel control service")?;
handle_channel_control_cmd_impl(cmd, &channel_control).await
}
async fn handle_channel_control_cmd_impl(
cmd: args::channel::Command,
channel_control: &ChannelControlProxy,
) -> Result<(), Error> {
match cmd {
args::channel::Command::Get(_) => {
let channel = channel_control.get_current().await?;
println!("current channel: {channel}");
}
args::channel::Command::Target(_) => {
let channel = channel_control.get_target().await?;
println!("target channel: {channel}");
}
args::channel::Command::Set(args::channel::Set { channel }) => {
channel_control.set_target(&channel).await?;
}
args::channel::Command::List(_) => {
let channels = channel_control.get_target_list().await?;
if channels.is_empty() {
println!("known channels list is empty.");
} else {
println!("known channels:");
for channel in channels {
println!("{channel}");
}
}
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use assert_matches::assert_matches;
use fidl::endpoints::create_proxy_and_stream;
use fidl_fuchsia_update_channelcontrol::ChannelControlRequest;
use fuchsia_async as fasync;
use futures::prelude::*;
async fn perform_channel_control_test<V>(argument: args::channel::Command, verifier: V)
where
V: Fn(ChannelControlRequest),
{
let (proxy, mut stream) = create_proxy_and_stream::<ChannelControlMarker>();
let fut = async move {
assert_matches!(handle_channel_control_cmd_impl(argument, &proxy).await, Ok(()));
};
let stream_fut = async move {
let result = stream.next().await.unwrap();
match result {
Ok(cmd) => verifier(cmd),
err => panic!("Err in request handler: {err:?}"),
}
};
future::join(fut, stream_fut).await;
}
#[fasync::run_singlethreaded(test)]
async fn test_channel_get() {
perform_channel_control_test(args::channel::Command::Get(args::channel::Get {}), |cmd| {
match cmd {
ChannelControlRequest::GetCurrent { responder } => {
responder.send("channel").unwrap();
}
request => panic!("Unexpected request: {request:?}"),
}
})
.await;
}
#[fasync::run_singlethreaded(test)]
async fn test_channel_target() {
perform_channel_control_test(
args::channel::Command::Target(args::channel::Target {}),
|cmd| match cmd {
ChannelControlRequest::GetTarget { responder } => {
responder.send("target-channel").unwrap();
}
request => panic!("Unexpected request: {request:?}"),
},
)
.await;
}
#[fasync::run_singlethreaded(test)]
async fn test_channel_set() {
perform_channel_control_test(
args::channel::Command::Set(args::channel::Set { channel: "new-channel".to_string() }),
|cmd| match cmd {
ChannelControlRequest::SetTarget { channel, responder } => {
assert_eq!(channel, "new-channel");
responder.send().unwrap();
}
request => panic!("Unexpected request: {request:?}"),
},
)
.await;
}
#[fasync::run_singlethreaded(test)]
async fn test_channel_list() {
perform_channel_control_test(args::channel::Command::List(args::channel::List {}), |cmd| {
match cmd {
ChannelControlRequest::GetTargetList { responder } => {
responder
.send(&["some-channel".to_owned(), "other-channel".to_owned()])
.unwrap();
}
request => panic!("Unexpected request: {request:?}"),
}
})
.await;
}
}