use bon::Builder;
use nonempty::NonEmpty;
use tes::v1::types::task::Executor;
use tes::v1::types::task::Input as TesInput;
use tes::v1::types::task::Output as TesOutput;
use tes::v1::types::task::Resources as TesResources;
pub mod execution;
pub mod input;
pub mod output;
pub mod resources;
pub use execution::Execution;
pub use input::Input;
pub use output::Output;
pub use resources::Resources;
#[derive(Builder, Clone, Debug)]
#[builder(builder_type = Builder)]
pub struct Task {
#[builder(into)]
pub(crate) name: Option<String>,
#[builder(into)]
pub(crate) description: Option<String>,
#[builder(into, default)]
pub(crate) inputs: Vec<Input>,
#[builder(into, default)]
pub(crate) outputs: Vec<Output>,
#[builder(into)]
pub(crate) resources: Option<Resources>,
#[builder(into)]
pub(crate) executions: NonEmpty<Execution>,
#[builder(into, default)]
pub(crate) volumes: Vec<String>,
}
impl Task {
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
pub fn override_name(&mut self, name: String) {
self.name = Some(name)
}
pub fn description(&self) -> Option<&str> {
self.description.as_deref()
}
pub fn inputs(&self) -> impl Iterator<Item = &Input> {
self.inputs.iter()
}
pub fn add_input(&mut self, input: impl Into<Input>) {
self.inputs.push(input.into());
}
pub fn outputs(&self) -> impl Iterator<Item = &Output> {
self.outputs.iter()
}
pub fn add_output(&mut self, output: impl Into<Output>) {
self.outputs.push(output.into());
}
pub fn resources(&self) -> Option<&Resources> {
self.resources.as_ref()
}
pub fn executions(&self) -> impl Iterator<Item = &Execution> {
self.executions.iter()
}
pub fn add_execution(&mut self, execution: impl Into<Execution>) {
self.executions.push(execution.into());
}
pub fn shared_volumes(&self) -> impl Iterator<Item = &str> {
self.volumes.iter().map(|v| v.as_str())
}
}
impl TryFrom<Task> for tes::v1::types::requests::Task {
type Error = anyhow::Error;
fn try_from(task: Task) -> Result<Self, Self::Error> {
let Task {
name,
description,
inputs,
outputs,
resources,
executions,
volumes,
} = task;
let inputs = inputs
.into_iter()
.map(TesInput::try_from)
.collect::<anyhow::Result<Vec<_>>>()?;
let inputs = if inputs.is_empty() {
None
} else {
Some(inputs)
};
let outputs = outputs
.into_iter()
.map(|output| TesOutput::from(output.clone()))
.collect::<Vec<TesOutput>>();
let outputs = if outputs.is_empty() {
None
} else {
Some(outputs)
};
let executors = executions.map(Executor::from).into_iter().collect();
let resources = resources.map(TesResources::from);
if !volumes.is_empty() {
todo!("volumes are not yet supported within Crankshaft");
}
Ok(Self {
name,
description,
inputs,
outputs,
executors,
resources,
..Default::default()
})
}
}