Files
el/_archive/rust-bootstrap/engrams/el-stdlib/src/result.rs
T

66 lines
2.8 KiB
Rust

//! 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());
}
}