Skip to main content

lean_rs_sys/
io.rs

1//! `IO`-result helpers — mirrors `lean.h:2893–2907`.
2//!
3//! `IO α` results from compiled Lean are encoded as constructors with tag 0
4//! (`ok`) or tag 1 (`error`). The single object payload sits in constructor
5//! slot 0; reading it requires the `ctor` accessors implemented against
6//! `LeanCtorObjectRepr`.
7
8#![allow(clippy::inline_always)]
9
10use crate::repr::LeanCtorObjectRepr;
11use crate::types::{b_lean_obj_arg, b_lean_obj_res, lean_obj_arg, lean_obj_res, lean_object};
12
13unsafe extern "C" {
14    /// Signal that runtime initialization is complete; subsequent allocations
15    /// should not flag objects as persistent (`lean.h:2907`).
16    pub fn lean_io_mark_end_initialization();
17}
18
19#[inline(always)]
20unsafe fn ctor_get0(r: b_lean_obj_arg) -> *mut lean_object {
21    // SAFETY: caller asserts `r` is an IO-result constructor whose first
22    // object slot holds the payload.
23    unsafe {
24        let ctor = r.cast::<LeanCtorObjectRepr>();
25        *(*ctor).objs.as_ptr()
26    }
27}
28
29/// True if `r` is an `IO.ok` result (`lean.h:2893`).
30///
31/// # Safety
32///
33/// `r` must be a borrowed Lean `IO α` result.
34#[inline(always)]
35pub unsafe fn lean_io_result_is_ok(r: b_lean_obj_arg) -> bool {
36    // SAFETY: precondition above; tag read is layout-pinned.
37    unsafe { crate::object::lean_ptr_tag(r) == 0 }
38}
39
40/// True if `r` is an `IO.error` result (`lean.h:2894`).
41///
42/// # Safety
43///
44/// Same as [`lean_io_result_is_ok`].
45#[inline(always)]
46pub unsafe fn lean_io_result_is_error(r: b_lean_obj_arg) -> bool {
47    // SAFETY: precondition above.
48    unsafe { crate::object::lean_ptr_tag(r) == 1 }
49}
50
51/// Borrow the value out of an `IO.ok` result (`lean.h:2895`).
52///
53/// # Safety
54///
55/// `r` must be a borrowed Lean `IO α` result tagged `ok`. The returned
56/// pointer aliases storage owned by `r`; the caller must not free `r` while
57/// the borrow is live.
58#[inline(always)]
59pub unsafe fn lean_io_result_get_value(r: b_lean_obj_arg) -> b_lean_obj_res {
60    // SAFETY: precondition above.
61    unsafe { ctor_get0(r) }
62}
63
64/// Borrow the error out of an `IO.error` result (`lean.h:2896`).
65///
66/// # Safety
67///
68/// `r` must be a borrowed Lean `IO α` result tagged `error`.
69#[inline(always)]
70pub unsafe fn lean_io_result_get_error(r: b_lean_obj_arg) -> b_lean_obj_res {
71    // SAFETY: precondition above.
72    unsafe { ctor_get0(r) }
73}
74
75/// Take ownership of the value out of an `IO.ok` result (`lean.h:2898–2903`).
76///
77/// # Safety
78///
79/// `r` must be a Lean `IO α` result tagged `ok` and owned by the caller.
80/// This function bumps the value's refcount and decrements `r`'s; after the
81/// call `r` is no longer valid.
82#[inline(always)]
83pub unsafe fn lean_io_result_take_value(r: lean_obj_arg) -> lean_obj_res {
84    // SAFETY: precondition above; calls into refcount helpers with the same
85    // invariants.
86    unsafe {
87        let v = ctor_get0(r);
88        crate::refcount::lean_inc(v);
89        crate::refcount::lean_dec(r);
90        v
91    }
92}