use ironflow_store::entities::{WorkerCapabilities, normalize_worker_tags, validate_worker_tags};
use crate::error::ApiError;
pub fn parse_worker_capabilities(
workflows: Option<&str>,
tags: Option<&str>,
) -> Result<Option<WorkerCapabilities>, ApiError> {
if workflows.is_none() && tags.is_none() {
return Ok(None);
}
let workflows = workflows.map(|raw| normalize_worker_tags(split_list(raw)));
let tags: Vec<String> = tags.map(split_list).unwrap_or_default();
validate_worker_tags(&tags).map_err(|e| ApiError::BadRequest(e.to_string()))?;
Ok(Some(WorkerCapabilities::new(
workflows,
normalize_worker_tags(tags),
)))
}
fn split_list(raw: &str) -> Vec<String> {
raw.split(',')
.map(str::trim)
.filter(|entry| !entry.is_empty())
.map(str::to_string)
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
fn strings(values: &[&str]) -> Vec<String> {
values.iter().map(|v| (*v).to_string()).collect()
}
#[test]
fn absent_params_mean_a_legacy_worker() {
assert!(parse_worker_capabilities(None, None).unwrap().is_none());
}
#[test]
fn both_params_are_parsed() {
let caps = parse_worker_capabilities(Some("deploy, build"), Some("gpu,region:eu"))
.unwrap()
.unwrap();
assert_eq!(caps.workflows, Some(strings(&["build", "deploy"])));
assert_eq!(caps.tags, strings(&["gpu", "region:eu"]));
}
#[test]
fn tags_without_workflows_accept_any_workflow() {
let caps = parse_worker_capabilities(None, Some("gpu"))
.unwrap()
.unwrap();
assert!(caps.workflows.is_none());
assert_eq!(caps.tags, strings(&["gpu"]));
}
#[test]
fn empty_tags_mean_a_worker_without_tags() {
let caps = parse_worker_capabilities(Some("deploy"), Some(""))
.unwrap()
.unwrap();
assert_eq!(caps.workflows, Some(strings(&["deploy"])));
assert!(caps.tags.is_empty());
}
#[test]
fn empty_workflows_take_no_workflow() {
let caps = parse_worker_capabilities(Some(""), None).unwrap().unwrap();
assert_eq!(caps.workflows, Some(Vec::new()));
assert!(caps.tags.is_empty());
}
#[test]
fn duplicate_tags_are_dropped() {
let caps = parse_worker_capabilities(None, Some("gpu,gpu, gpu,,arm"))
.unwrap()
.unwrap();
assert_eq!(caps.tags, strings(&["arm", "gpu"]));
}
#[test]
fn invalid_tag_is_a_bad_request() {
let err = parse_worker_capabilities(None, Some("gpu,two words")).unwrap_err();
assert!(matches!(err, ApiError::BadRequest(ref msg) if msg.contains("two words")));
}
#[test]
fn too_long_tag_is_a_bad_request() {
let long = "a".repeat(65);
let err = parse_worker_capabilities(None, Some(&long)).unwrap_err();
assert!(matches!(err, ApiError::BadRequest(_)));
}
}