use wdl_ast::Diagnostic;
use super::CallContext;
use super::Callback;
use super::Function;
use super::Signature;
use crate::Array;
use crate::Pair;
use crate::Value;
fn as_pairs(context: CallContext<'_>) -> Result<Value, Diagnostic> {
debug_assert_eq!(context.arguments.len(), 1);
let map = context.arguments[0]
.value
.as_map()
.expect("argument should be a map");
let element_ty = context
.return_type
.as_array()
.expect("type should be an array")
.element_type();
let elements = map
.iter()
.map(|(k, v)| Pair::new_unchecked(element_ty.clone(), k.clone().into(), v.clone()).into())
.collect();
Ok(Array::new_unchecked(context.return_type, elements).into())
}
pub const fn descriptor() -> Function {
Function::new(
const {
&[Signature::new(
"(map: Map[K, V]) -> Array[Pair[K, V]] where `K`: any non-optional primitive type",
Callback::Sync(as_pairs),
)]
},
)
}
#[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 as_pairs() {
let env = TestEnv::default();
let value = eval_v1_expr(&env, V1::One, "as_pairs({})").await.unwrap();
assert_eq!(value.unwrap_array().len(), 0);
let value = eval_v1_expr(&env, V1::One, "as_pairs({ 'foo': 'bar', 'bar': 'baz' })")
.await
.unwrap();
let elements: Vec<_> = value
.as_array()
.unwrap()
.as_slice()
.iter()
.map(|v| {
let pair = v.as_pair().unwrap();
(
pair.left().as_string().unwrap().as_str(),
pair.right().as_string().unwrap().as_str(),
)
})
.collect();
assert_eq!(elements, [("foo", "bar"), ("bar", "baz")]);
let value = eval_v1_expr(&env, V1::One, "as_pairs({'a': 1, 'c': 3, 'b': 2})")
.await
.unwrap();
let elements: Vec<_> = value
.as_array()
.unwrap()
.as_slice()
.iter()
.map(|v| {
let pair = v.as_pair().unwrap();
(
pair.left().as_string().unwrap().as_str(),
pair.right().as_integer().unwrap(),
)
})
.collect();
assert_eq!(elements, [("a", 1), ("c", 3), ("b", 2)]);
let value = eval_v1_expr(&env, V1::One, "as_pairs({1: 1, 2: 2, 3: 3})")
.await
.unwrap();
let elements: Vec<_> = value
.as_array()
.unwrap()
.as_slice()
.iter()
.map(|v| {
let pair = v.as_pair().unwrap();
(
pair.left().as_integer().unwrap(),
pair.right().as_integer().unwrap(),
)
})
.collect();
assert_eq!(elements, [(1, 1), (2, 2), (3, 3)]);
}
}