use rite_model::{ArtifactId, ArtifactRef, RoleId, StepId, StepInputs};
use crate::runner::ActionError;
#[derive(Debug, Clone)]
pub struct StepInfo {
pub id: StepId,
pub role: Option<RoleId>,
pub backend: Option<String>,
pub produces: Option<ArtifactId>,
pub typed_inputs: Option<StepInputs>,
}
impl StepInfo {
pub fn new(
id: StepId,
role: Option<RoleId>,
backend: Option<String>,
produces: Option<ArtifactId>,
typed_inputs: Option<StepInputs>,
) -> Self {
Self {
id,
role,
backend,
produces,
typed_inputs,
}
}
pub fn id_str(&self) -> &str {
self.id.as_str()
}
pub fn role_str(&self) -> Option<&str> {
self.role.as_ref().map(rite_model::RoleId::as_str)
}
#[must_use]
pub fn named_input(&self, key: &str) -> Option<&ArtifactRef> {
self.typed_inputs.as_ref().and_then(|i| i.get(key))
}
pub fn required_named_input(
&self,
key: &str,
action: &'static str,
) -> Result<&ArtifactRef, ActionError> {
self.named_input(key)
.ok_or_else(|| ActionError::Failed(format!("{action}: missing required input '{key}'")))
}
pub fn required_named_inputs(
&self,
key: &str,
action: &'static str,
) -> Result<&[ArtifactRef], ActionError> {
self.typed_inputs
.as_ref()
.and_then(|i| i.get_many(key))
.ok_or_else(|| {
ActionError::Failed(format!("{action}: missing required list input '{key}'"))
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use rite_model::ArtifactRef;
#[test]
fn step_info_exposes_its_id_role_and_backend() {
let typed_inputs = Some(StepInputs::Single(ArtifactRef::Produced {
id: ArtifactId::new("foo"),
property: None,
}));
let info = StepInfo::new(
StepId::new("test_step"),
Some(RoleId::new("operator")),
Some("software".to_string()),
Some(ArtifactId::new("output")),
typed_inputs,
);
assert_eq!(info.id_str(), "test_step");
assert_eq!(info.role_str(), Some("operator"));
assert_eq!(info.backend, Some("software".to_string()));
assert!(info.produces.is_some());
assert!(info.typed_inputs.is_some());
}
}