use non_empty_vec::NonEmpty;
use serde::Deserialize;
use serde_with::{formats::PreferOne, serde_as, OneOrMany};
use tokio::sync::mpsc;
use crate::comms::Terminated;
use crate::manager::{Component, WaitPoint};
use crate::{comms::Link, manager::TargetCommand};
#[serde_as]
#[derive(Debug, Deserialize)]
pub struct Target {
#[allow(dead_code)]
#[serde(alias = "source")]
#[serde_as(deserialize_as = "OneOrMany<_, PreferOne>")]
sources: Vec<Link>,
}
impl Target {
pub async fn run(
mut self,
_: Component,
mut cmd_rx: mpsc::Receiver<TargetCommand>,
waitpoint: WaitPoint,
) -> Result<(), Terminated> {
for source in &mut self.sources {
source.suspend().await;
}
waitpoint.running().await;
while let Some(cmd) = cmd_rx.recv().await {
match cmd {
TargetCommand::Reconfigure { new_config } => {
if let crate::targets::Target::Null(Target {
sources: new_sources,
..
}) = new_config
{
self.sources = new_sources;
for source in &mut self.sources {
source.suspend().await;
}
}
}
TargetCommand::ReportLinks { report } => {
if let Ok(non_empty) =
NonEmpty::try_from(self.sources.clone())
{
report.set_sources(&non_empty);
}
}
TargetCommand::Terminate => {
break;
}
}
}
Err(Terminated)
}
}