finish engram-lang: protocols, decorators, imports, Result, closures, stdlib, integration tests
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
//! Result<T, E> operations: map, map_err, unwrap_or, unwrap_or_else, and_then, ok.
|
||||
|
||||
use el_types::{Type, TypeEnv};
|
||||
use super::fn_type;
|
||||
|
||||
pub fn register(env: &mut TypeEnv) {
|
||||
// result_unwrap_or(Result<T, E>, T) -> T
|
||||
let result_unk = Type::Result {
|
||||
ok: Box::new(Type::Unknown),
|
||||
err: Box::new(Type::Unknown),
|
||||
};
|
||||
env.register_fn("result_unwrap_or", fn_type(vec![result_unk.clone(), Type::Unknown], Type::Unknown));
|
||||
env.register_fn("result_unwrap_or_else", fn_type(
|
||||
vec![result_unk.clone(), Type::Fn { params: vec![Type::Unknown], return_type: Box::new(Type::Unknown) }],
|
||||
Type::Unknown,
|
||||
));
|
||||
// result_ok(Result<T, E>) -> T?
|
||||
env.register_fn("result_ok", fn_type(vec![result_unk.clone()], Type::Optional(Box::new(Type::Unknown))));
|
||||
// result_err(Result<T, E>) -> E?
|
||||
env.register_fn("result_err", fn_type(vec![result_unk.clone()], Type::Optional(Box::new(Type::Unknown))));
|
||||
// result_is_ok(Result<T, E>) -> Bool
|
||||
env.register_fn("result_is_ok", fn_type(vec![result_unk.clone()], Type::Bool));
|
||||
// result_is_err(Result<T, E>) -> Bool
|
||||
env.register_fn("result_is_err", fn_type(vec![result_unk.clone()], Type::Bool));
|
||||
// result_map(Result<T, E>, fn(T) -> U) -> Result<U, E>
|
||||
let mapper = Type::Fn { params: vec![Type::Unknown], return_type: Box::new(Type::Unknown) };
|
||||
env.register_fn("result_map", fn_type(vec![result_unk.clone(), mapper.clone()], result_unk.clone()));
|
||||
// result_and_then(Result<T, E>, fn(T) -> Result<U, E>) -> Result<U, E>
|
||||
let chain_fn = Type::Fn { params: vec![Type::Unknown], return_type: Box::new(result_unk.clone()) };
|
||||
env.register_fn("result_and_then", fn_type(vec![result_unk.clone(), chain_fn], result_unk.clone()));
|
||||
// result_ok_val(T) -> Result<T, E> — wrap a value in Ok
|
||||
env.register_fn("ok", fn_type(vec![Type::Unknown], result_unk.clone()));
|
||||
// result_err_val(E) -> Result<T, E> — wrap an error in Err
|
||||
env.register_fn("err", fn_type(vec![Type::Unknown], result_unk));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn env() -> TypeEnv {
|
||||
let mut e = TypeEnv::with_builtins();
|
||||
register(&mut e);
|
||||
e
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_result_unwrap_or_registered() {
|
||||
assert!(env().lookup_fn("result_unwrap_or").is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_result_ok_returns_optional() {
|
||||
let e = env();
|
||||
let ty = e.lookup_fn("result_ok").unwrap();
|
||||
assert!(matches!(ty, Type::Fn { return_type, .. } if matches!(return_type.as_ref(), Type::Optional(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ok_and_err_registered() {
|
||||
let e = env();
|
||||
assert!(e.lookup_fn("ok").is_some());
|
||||
assert!(e.lookup_fn("err").is_some());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user