#![allow(unsafe_code)]
use lean_rs_sys::object::{lean_is_scalar, lean_obj_tag, lean_unbox};
use lean_rs_sys::scalar::{lean_uint64_to_nat, lean_usize_to_nat};
use crate::abi::traits::conversion_error;
use crate::error::{LeanError, LeanResult};
use crate::runtime::LeanRuntime;
use crate::runtime::obj::Obj;
#[must_use]
pub fn from_u64(runtime: &LeanRuntime, n: u64) -> Obj<'_> {
unsafe { Obj::from_owned_raw(runtime, lean_uint64_to_nat(n)) }
}
#[must_use]
pub fn from_usize(runtime: &LeanRuntime, n: usize) -> Obj<'_> {
unsafe { Obj::from_owned_raw(runtime, lean_usize_to_nat(n)) }
}
#[allow(
clippy::needless_pass_by_value,
reason = "Obj is consumed by Drop on return; that releases the refcount"
)]
pub fn try_to_u64(obj: Obj<'_>) -> LeanResult<u64> {
let ptr = obj.as_raw_borrowed();
if unsafe { lean_is_scalar(ptr) } {
let raw = unsafe { lean_unbox(ptr) };
Ok(raw as u64)
} else {
let found_tag = unsafe { lean_obj_tag(ptr) };
Err(bignum_nat(found_tag))
}
}
#[allow(
clippy::needless_pass_by_value,
reason = "Obj is consumed by Drop on return; that releases the refcount"
)]
pub fn try_to_usize(obj: Obj<'_>) -> LeanResult<usize> {
let ptr = obj.as_raw_borrowed();
if unsafe { lean_is_scalar(ptr) } {
Ok(unsafe { lean_unbox(ptr) })
} else {
let found_tag = unsafe { lean_obj_tag(ptr) };
Err(bignum_nat(found_tag))
}
}
fn bignum_nat(found_tag: u32) -> LeanError {
conversion_error(format!(
"expected Lean Nat (scalar-fitting), found object with tag {found_tag}"
))
}