use crate::sys;
pub struct Root(pub ocaml_boxroot_sys::BoxRoot);
impl PartialEq for Root {
fn eq(&self, other: &Self) -> bool {
ocaml_boxroot_sys::boxroot_get_ref(self.0) == ocaml_boxroot_sys::boxroot_get_ref(other.0)
}
}
impl PartialOrd for Root {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
ocaml_boxroot_sys::boxroot_get_ref(self.0)
.partial_cmp(&ocaml_boxroot_sys::boxroot_get_ref(other.0))
}
}
impl core::fmt::Debug for Root {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
ocaml_boxroot_sys::boxroot_get_ref(self.0).fmt(f)
}
}
impl Eq for Root {}
fn boxroot_raise_error() -> ! {
use ocaml_boxroot_sys::Status;
let status = unsafe { ocaml_boxroot_sys::boxroot_status() };
let error_message = match status {
Status::ToreDown => "boxroot_teardown has previously been called",
Status::Invalid => "With systhreads, boxroot_setup must be called after caml_thread_initialize but before any thread is created",
Status::Running | Status::NotSetup => {
#[cfg(not(feature = "no-std"))]
{
use std::io::{Error, ErrorKind};
match Error::last_os_error().kind() {
ErrorKind::PermissionDenied => {
"You tried calling boxroot_create or boxroot_modify without holding the domain lock"
}
ErrorKind::OutOfMemory => {
"Allocation failure of the backing store"
}
_ => "Unknown Error::last_os_error().kind()",
}
}
#[cfg(feature = "no-std")]
{
"Unknown error (details unavailable in no-std environment)"
}
}
_ => "Unknown ocaml_boxroot_sys::Status",
};
panic!("Boxroot error: {error_message}");
}
impl Root {
pub unsafe fn new(v: sys::Value) -> Root {
match ocaml_boxroot_sys::boxroot_create(v) {
Some(root) => Root(root),
None => boxroot_raise_error(),
}
}
pub unsafe fn get(&self) -> sys::Value {
ocaml_boxroot_sys::boxroot_get(self.0)
}
pub unsafe fn modify(&mut self, v: sys::Value) {
if !ocaml_boxroot_sys::boxroot_modify(&mut self.0, v) {
panic!("boxroot_modify failed")
}
}
}
impl Clone for Root {
fn clone(&self) -> Root {
unsafe { Root::new(self.get()) }
}
}
impl Drop for Root {
fn drop(&mut self) {
unsafe { ocaml_boxroot_sys::boxroot_delete(self.0) }
}
}