use crate::run;
use anyhow::{bail, Result};
use netidx::publisher::Value;
const SIMPLE_TYPECHECK: &str = r#"
{
"foo" + 1
}
"#;
run!(simple_typecheck, SIMPLE_TYPECHECK, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const FUNCTION_TYPES: &str = r#"
{
let f = |x: Number, y: Number| -> string "x is [x] and y is [y]";
f("foo", 3)
}
"#;
run!(function_types, FUNCTION_TYPES, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const PARTIAL_FUNCTION_TYPES: &str = r#"
{
let f = |x: Number, y| "x is [x] and y is [y]";
f("foo", 3)
}
"#;
run!(partial_function_types, PARTIAL_FUNCTION_TYPES, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const FUNCTION_RTYPE: &str = r#"
{
let f = |x, y| -> Number "x is [x] and y is [y]";
f("foo", 3)
}
"#;
run!(function_rtype, FUNCTION_RTYPE, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const INFERRED_RTYPE: &str = r#"
{
let f = |x, y| "x is [x] and y is [y]";
let v = f("foo", 3);
let g = |x| x + 1;
g(v)
}
"#;
run!(inferred_rtype, INFERRED_RTYPE, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const LAMBDA_CONSTRAINT: &str = r#"
{
let f = |f: fn(string, string) -> string, a| f("foo", a);
f(|x, y: Number| "[x] and [y]", "foo")
}
"#;
run!(lambda_constraint, LAMBDA_CONSTRAINT, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const EXPLICIT_TYPE_VARS0: &str = r#"
{
let f = 'a: Number |x: 'a, y: 'a| -> 'a x + y;
f("foo", "bar")
}
"#;
run!(explicit_type_vars0, EXPLICIT_TYPE_VARS0, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const EXPLICIT_TYPE_VARS1: &str = r#"
{
let f = 'a: Number |x: 'a, y: 'a| -> 'a x + y;
f(u32:1, i64:2)
}
"#;
run!(explicit_type_vars1, EXPLICIT_TYPE_VARS1, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const EXPLICIT_TYPE_VARS2: &str = r#"
{
let f = 'a: Number |x: 'a, y: 'a| -> 'a x + y;
select f(1, 1) {
i64 as t => t
}
}
"#;
run!(explicit_type_vars2, EXPLICIT_TYPE_VARS2, |v: Result<&Value>| match v {
Ok(Value::I64(2)) => true,
_ => false,
});
const EXPLICIT_TYPE_VARS3: &str = r#"
{
let f = 'a: Number, 'b: Number |x: 'a, y: 'b| -> ['a, 'b] x + y;
select f(u32:1, u64:1) {
[u32, u64] as t => t
}
}
"#;
run!(explicit_type_vars3, EXPLICIT_TYPE_VARS3, |v: Result<&Value>| match v {
Ok(Value::U32(2) | Value::U64(2)) => true,
_ => false,
});
const TYPED_ARRAYS0: &str = r#"
{
let f = |x: Array<'a>, y: Array<'a>| -> Array<Array<'a>> [x, y];
f([1, 2, 3], [1, 2, 3])
}
"#;
run!(typed_arrays0, TYPED_ARRAYS0, |v: Result<&Value>| match v {
Ok(Value::Array(a)) => match &**a {
[Value::Array(a0), Value::Array(a1)] => match (&**a0, &**a1) {
(
[Value::I64(1), Value::I64(2), Value::I64(3)],
[Value::I64(1), Value::I64(2), Value::I64(3)],
) => true,
_ => false,
},
_ => false,
},
_ => false,
});
const TYPED_ARRAYS1: &str = r#"
{
let f = |x: Array<'a>, y: Array<'a>| -> Array<Array<'a>> [x, y];
f([1, 2, 3], [u32:1, 2, 3])
}
"#;
run!(typed_arrays1, TYPED_ARRAYS1, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const RECTYPES0: &str = r#"
{
type List = [
`Cons(Any, List),
`Nil
];
let l: List = `Cons(42, `Cons(3, `Nil));
l
}
"#;
run!(rectypes0, RECTYPES0, |v: Result<&Value>| match v {
Ok(Value::Array(a)) => match &a[..] {
[Value::String(s), Value::I64(42), Value::Array(a)] if &**s == "Cons" =>
match &a[..] {
[Value::String(s0), Value::I64(3), Value::String(s1)]
if &**s0 == "Cons" && s1 == "Nil" =>
true,
_ => false,
},
_ => false,
},
_ => false,
});
const RECTYPES1: &str = r#"
{
type List<'a> = [
`Cons('a, List<'a>),
`Nil
];
let l: List<Any> = `Cons(42, `Cons(3, `Nil));
l
}
"#;
run!(rectypes1, RECTYPES1, |v: Result<&Value>| match v {
Ok(Value::Array(a)) => match &a[..] {
[Value::String(s), Value::I64(42), Value::Array(a)] if &**s == "Cons" =>
match &a[..] {
[Value::String(s0), Value::I64(3), Value::String(s1)]
if &**s0 == "Cons" && s1 == "Nil" =>
true,
_ => false,
},
_ => false,
},
_ => false,
});
const RECTYPES2: &str = r#"
{
type List<'a> = [
`Cons('a, List<'a>),
`Nil
];
let l: List<string> = `Cons(42, `Cons(3, `Nil));
l
}
"#;
run!(rectypes2, RECTYPES2, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const TYPEDEF_TVAR_ERR: &str = r#"
{
type T<'a, 'b> = { foo: 'a, bar: 'b, baz: 'c };
0
}
"#;
run!(typedef_tvar_err, TYPEDEF_TVAR_ERR, |v: Result<&Value>| match v {
Err(_) => true,
_ => false,
});
const TYPEDEF_TVAR_OK: &str = r#"
{
type T<'a, 'b> = { foo: 'a, bar: 'b, f: fn('a, 'b, 'c) -> 'a };
0
}
"#;
run!(typedef_tvar_ok, TYPEDEF_TVAR_OK, |v: Result<&Value>| match v {
Ok(Value::I64(0)) => true,
_ => false,
});