use core::marker::PhantomData;
use crate::types::sealed::Sealed;
use crate::types::{CallEnv, Env, FreeTerm, Invariant, RawTerm, Term};
#[derive(Clone, Copy)]
pub struct Pid<'id> {
raw_term: RawTerm,
_id: Invariant<'id>,
}
impl<'id> Pid<'id> {
#[crate::raw]
pub(crate) fn from_raw(raw_term: RawTerm) -> Self {
Self { raw_term, _id: PhantomData }
}
pub fn to_local(self, env: impl Env<'id>) -> Option<LocalPid> {
let mut out = enif_ffi::Pid { pid: 0 };
(unsafe { enif_ffi::get_local_pid(env.raw_env(), self.raw_term, &mut out) } != 0)
.then_some(LocalPid { pid: out })
}
pub fn is_pid(env: impl Env<'id>, term: impl Term<'id>) -> bool {
unsafe { enif_ffi::is_pid(env.raw_env(), term.raw_term()) != 0 }
}
}
#[derive(Clone, Copy)]
pub struct LocalPid {
pub(crate) pid: enif_ffi::Pid,
}
impl LocalPid {
pub fn self_(env: CallEnv<'_>) -> LocalPid {
let mut out = enif_ffi::Pid { pid: 0 };
let ok = unsafe { !enif_ffi::self_(env.raw_env(), &mut out).is_null() };
assert!(ok, "enif_self returned NULL on a CallEnv");
LocalPid { pid: out }
}
pub fn whereis<'id>(env: impl Env<'id>, name: impl Term<'id>) -> Option<LocalPid> {
let mut out = enif_ffi::Pid { pid: 0 };
(unsafe { enif_ffi::whereis_pid(env.raw_env(), name.raw_term(), &mut out) } != 0)
.then_some(LocalPid { pid: out })
}
pub fn is_alive<'id>(self, env: impl Env<'id>) -> bool {
unsafe { enif_ffi::is_process_alive(env.raw_env(), &self.pid) != 0 }
}
}
impl PartialEq for Pid<'_> {
fn eq(&self, other: &Self) -> bool {
unsafe { enif_ffi::is_identical(self.raw_term, other.raw_term) != 0 }
}
}
impl Eq for Pid<'_> {}
impl PartialOrd for Pid<'_> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Pid<'_> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
unsafe { enif_ffi::compare(self.raw_term, other.raw_term) }.cmp(&0)
}
}
impl std::fmt::Debug for Pid<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Pid")
}
}
impl PartialEq for LocalPid {
fn eq(&self, other: &Self) -> bool {
unsafe { enif_ffi::is_identical(self.pid.pid, other.pid.pid) != 0 }
}
}
impl Eq for LocalPid {}
impl PartialOrd for LocalPid {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for LocalPid {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
unsafe { enif_ffi::compare(self.pid.pid, other.pid.pid) }.cmp(&0)
}
}
impl std::fmt::Debug for LocalPid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "LocalPid")
}
}
impl<'id> Sealed for Pid<'id> {}
impl<'id> Term<'id> for Pid<'id> {
fn raw_term(self) -> RawTerm {
self.raw_term
}
}
impl Sealed for LocalPid {}
impl<'id> Term<'id> for LocalPid {
fn raw_term(self) -> RawTerm {
self.pid.pid
}
}
impl FreeTerm for LocalPid {}