use std::borrow::{Borrow, BorrowMut};
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;
use libc::{c_char, c_void, free};
use error::ProxyResolutionError;
use ffi::MallocCString;
pub struct Proxies {
data: *mut MallocCString,
len: usize,
}
impl Proxies {
pub(crate) fn new(data: *mut *mut c_char) -> Result<Proxies, ProxyResolutionError> {
if data.is_null() {
Err(ProxyResolutionError)
} else {
let mut len = 0;
unsafe {
let mut data_ptr = data;
while !(*data_ptr).is_null() {
len += 1;
data_ptr = data_ptr.offset(1);
}
}
Ok(Proxies {
data: data as *mut MallocCString,
len,
})
}
}
pub fn as_slice(&self) -> &[MallocCString] {
unsafe { slice::from_raw_parts(self.data, self.len) }
}
pub fn as_mut_slice(&mut self) -> &mut [MallocCString] {
unsafe { slice::from_raw_parts_mut(self.data, self.len) }
}
}
impl AsRef<[MallocCString]> for Proxies {
fn as_ref(&self) -> &[MallocCString] {
self.as_slice()
}
}
impl AsMut<[MallocCString]> for Proxies {
fn as_mut(&mut self) -> &mut [MallocCString] {
self.as_mut_slice()
}
}
impl Borrow<[MallocCString]> for Proxies {
fn borrow(&self) -> &[MallocCString] {
self.as_slice()
}
}
impl BorrowMut<[MallocCString]> for Proxies {
fn borrow_mut(&mut self) -> &mut [MallocCString] {
self.as_mut_slice()
}
}
impl Deref for Proxies {
type Target = [MallocCString];
fn deref(&self) -> &[MallocCString] {
self.as_slice()
}
}
impl DerefMut for Proxies {
fn deref_mut(&mut self) -> &mut [MallocCString] {
self.as_mut_slice()
}
}
impl Drop for Proxies {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(self.as_mut_slice());
free(self.data as *mut c_void)
}
}
}
impl<'a> IntoIterator for &'a Proxies {
type Item = &'a MallocCString;
type IntoIter = slice::Iter<'a, MallocCString>;
#[allow(clippy::into_iter_on_ref)]
fn into_iter(self) -> Self::IntoIter {
self.as_slice().into_iter()
}
}
impl<'a> IntoIterator for &'a mut Proxies {
type Item = &'a mut MallocCString;
type IntoIter = slice::IterMut<'a, MallocCString>;
#[allow(clippy::into_iter_on_ref)]
fn into_iter(self) -> Self::IntoIter {
self.as_mut_slice().into_iter()
}
}