pub mod error;
pub mod fd;
pub mod net;
pub mod time;
use nss_sys::nspr as ffi;
use std::marker::PhantomData;
use std::sync::{Once, ONCE_INIT};
use GenStatus;
pub use self::fd::File;
pub fn init() {
static PR_INIT_ONCE: Once = ONCE_INIT;
PR_INIT_ONCE.call_once(|| {
unsafe {
ffi::PR_Init(ffi::PR_SYSTEM_THREAD, ffi::PR_PRIORITY_NORMAL, 0);
}
});
}
impl From<ffi::PRStatus> for GenStatus<()> {
fn from(status: ffi::PRStatus) -> Self {
match status {
ffi::PR_SUCCESS => GenStatus::Success(()),
ffi::PR_FAILURE => GenStatus::ErrorFromC,
}
}
}
impl From<i32> for GenStatus<usize> {
fn from(rv: i32) -> Self {
if rv >= 0 {
GenStatus::Success(rv as usize)
} else {
GenStatus::ErrorFromC
}
}
}
pub fn bool_from_nspr(b: ffi::PRBool) -> bool {
match b {
ffi::PR_FALSE => false,
ffi::PR_TRUE => true,
_ => unreachable!(),
}
}
pub fn bool_to_nspr(b: bool) -> ffi::PRBool {
if b {
ffi::PR_TRUE
} else {
ffi::PR_FALSE
}
}
pub type ListNode = *mut ffi::PRCList;
pub trait Listable {
unsafe fn from_list_node(node: ListNode) -> Self;
}
#[derive(Clone, Debug)]
pub struct ListIterator<'l, L: Listable + 'l> {
next: ListNode,
end: ListNode,
phantom: PhantomData<&'l [L]>,
}
impl<'l, L: Listable + 'l> ListIterator<'l, L> {
pub unsafe fn new(list: ListNode) -> Self {
ListIterator {
next: (*list).next,
end: list,
phantom: PhantomData,
}
}
}
impl<'l, L: Listable + 'l> Iterator for ListIterator<'l, L> {
type Item = L;
fn next(&mut self) -> Option<L> {
if self.next == self.end {
None
} else {
unsafe {
let next = self.next;
self.next = (*next).next;
Some(Listable::from_list_node(next))
}
}
}
}
impl<'l, L: Listable + 'l> DoubleEndedIterator for ListIterator<'l, L> {
fn next_back(&mut self) -> Option<L> {
if self.next == self.end {
None
} else {
unsafe {
let prev = (*self.end).prev;
self.end = prev;
Some(Listable::from_list_node(prev))
}
}
}
}