powerline 0.1.0

Work-in-progress: Power-line communication library
Documentation
extern crate std;

use crate::*;
use core::{marker::PhantomData, ptr::null_mut};
use libc::ifaddrs;
use libc::{freeifaddrs, getifaddrs};
use std::io::{Error, Result};

pub trait UnixInterface: EtherInterface + Sized {
    fn new(addr: &ifaddrs) -> Option<Self>;
}

pub struct UnixInterfaceIter<T: UnixInterface> {
    first: *mut ifaddrs,
    next: *const ifaddrs,
    phantom: PhantomData<T>,
}
impl<T: UnixInterface> UnixInterfaceIter<T> {
    pub(crate) fn new() -> Result<UnixInterfaceIter<T>> {
        unsafe {
            let mut first: *mut ifaddrs = null_mut();
            if getifaddrs(&mut first) == -1 {
                return Err(Error::last_os_error());
            }
            Ok(UnixInterfaceIter {
                first,
                next: first,
                phantom: PhantomData,
            })
        }
    }
}
impl<T: UnixInterface> Iterator for UnixInterfaceIter<T> {
    type Item = T;
    fn next(&mut self) -> Option<T> {
        unsafe {
            while let Some(ifaddr) = self.next.as_ref() {
                self.next = ifaddr.ifa_next;
                if let Some(interface) = T::new(ifaddr) {
                    return Some(interface);
                }
            }
            None
        }
    }
}
impl<T: UnixInterface> Drop for UnixInterfaceIter<T> {
    fn drop(&mut self) {
        unsafe { freeifaddrs(self.first) };
    }
}