use std::fmt::Write;
use wdl_analysis::types::PrimitiveType;
use wdl_ast::Diagnostic;
use super::CallContext;
use super::Callback;
use super::Function;
use super::Signature;
use crate::PrimitiveValue;
use crate::Value;
fn sep(context: CallContext<'_>) -> Result<Value, Diagnostic> {
debug_assert_eq!(context.arguments.len(), 2);
debug_assert!(context.return_type_eq(PrimitiveType::String));
let sep = context
.coerce_argument(0, PrimitiveType::String)
.unwrap_string();
let array = context.arguments[1]
.value
.as_array()
.expect("value should be an array");
let s = array
.as_slice()
.iter()
.enumerate()
.fold(String::new(), |mut s, (i, v)| {
if i > 0 {
s.push_str(&sep);
}
match v {
Value::None(_) => {}
Value::Primitive(v) => write!(&mut s, "{v}", v = v.raw(Some(context.inner())))
.expect("failed to write to a string"),
_ => panic!("expected an array of primitive values"),
}
s
});
Ok(PrimitiveValue::new_string(s).into())
}
pub const fn descriptor() -> Function {
Function::new(
const {
&[Signature::new(
"(separator: String, array: Array[P]) -> String where `P`: any primitive type",
Callback::Sync(sep),
)]
},
)
}
#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use wdl_ast::version::V1;
use crate::v1::test::TestEnv;
use crate::v1::test::eval_v1_expr;
#[tokio::test]
async fn sep() {
let env = TestEnv::default();
let value = eval_v1_expr(
&env,
V1::One,
"sep(' ', prefix('-i ', ['file_1', 'file_2']))",
)
.await
.unwrap();
assert_eq!(value.unwrap_string().as_str(), "-i file_1 -i file_2");
let value = eval_v1_expr(&env, V1::One, "sep('', ['a', 'b', 'c'])")
.await
.unwrap();
assert_eq!(value.unwrap_string().as_str(), "abc");
let value = eval_v1_expr(&env, V1::One, "sep(' ', ['a', 'b', 'c'])")
.await
.unwrap();
assert_eq!(value.unwrap_string().as_str(), "a b c");
let value = eval_v1_expr(&env, V1::One, "sep(' ', ['a', None, 'c'])")
.await
.unwrap();
assert_eq!(value.unwrap_string().as_str(), "a c");
let value = eval_v1_expr(&env, V1::One, "sep(',', [1])").await.unwrap();
assert_eq!(value.unwrap_string().as_str(), "1");
let value = eval_v1_expr(&env, V1::One, "sep(',', [])").await.unwrap();
assert_eq!(value.unwrap_string().as_str(), "");
}
}