<commit_before>pub use self::os::{
    Semaphore,
    SemaphoreGuard,
};

#[cfg(not(target_os = "macos"))]
mod os {
    use std::cell::UnsafeCell;
    use std::mem;
    use std::io;
    use libc::{
        c_int,
        c_uint,
    };

    #[cfg(target_pointer_width = "64")]
    const SIZEOF_SEM_T: usize = 32;
    #[cfg(not(target_pointer_width = "64"))]
    const SIZEOF_SEM_T: usize = 16;

    extern {
        fn sem_init(sem: *mut sem_t, pshared: c_int, value: c_uint) -> c_int;
        fn sem_post(sem: *mut sem_t) -> c_int;
        fn sem_wait(sem: *mut sem_t) -> c_int;
        fn sem_destroy(sem: *mut sem_t) -> c_int;
    }

    #[repr(C)]
    #[derive(Debug)]
    struct sem_t {
        __opaque: [u8; SIZEOF_SEM_T],
    }

    pub struct Semaphore {
        inner: UnsafeCell<sem_t>,
    }

    pub struct SemaphoreGuard<'a> {
        sem: &'a Semaphore,
    }

    impl Semaphore {
        pub fn new(value: u32) -> Semaphore {
            let mut sem: sem_t = unsafe {
                mem::uninitialized()
            };
            let res = unsafe {
                sem_init(&mut sem, 0, value as c_uint)
            };
            debug_assert_eq!(res, 0);

            Semaphore {
                inner: UnsafeCell::new(sem),
            }
        }

        pub fn wait(&self) {
            loop {
                let res = unsafe {
                    sem_wait(self.inner.get())
                };
                if res == -1 {
                    match io::Error::last_os_error() {
                        ref e if e.kind() == io::ErrorKind::Interrupted => continue,
                        other => panic!("{}", other),
                    }
                } else {
                    break;
                }
            }
        }

        pub fn post(&self) {
            let res = unsafe {
                sem_post(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }

        pub fn access(&self) -> SemaphoreGuard {
            self.wait();
            SemaphoreGuard { sem: self }
        }
    }

    unsafe impl Send for Semaphore {}
    unsafe impl Sync for Semaphore {}

    impl Drop for Semaphore {
        fn drop(&mut self) {
            let res = unsafe {
                sem_destroy(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }
    }

    impl<'a> Drop for SemaphoreGuard<'a> {
        fn drop(&mut self) {
            self.sem.post();
        }
    }
}

#[cfg(target_os = "macos")]
mod os {
    use std::ffi::CString;
    use rand::{
        thread_rng,
        Rng,
    };
    use libc::{
        c_int,
        c_uint,
        c_char,
        mode_t,
        O_CREAT,
        O_EXCL,
        S_IRWXU,
    };

    const SIZEOF_SEM_T: usize = 4;
    const SEM_NAME_MAX: usize = 28; // No definitive value for this on OS X. Erring on the side of caution.
    const SEM_FAILED: *mut sem_t = 0 as *mut sem_t;

    extern {
        fn sem_open(name: *const c_char, oflag: c_int, mode: mode_t, value: c_uint) -> *mut sem_t;
        fn sem_post(sem: *mut sem_t) -> c_int;
        fn sem_wait(sem: *mut sem_t) -> c_int;
        fn sem_close(sem: *mut sem_t) -> c_int;
        fn sem_unlink(sem: *const c_char) -> c_int;
    }

    #[repr(C)]
    #[derive(Debug)]
    pub struct sem_t {
        __opaque: c_int,
    }

    pub struct Semaphore {
        inner: UnsafeCell<*mut sem_t>,
        name: CString,
    }

    impl Semaphore {
        pub fn new(value: u32) -> Semaphore {
            let name: String = thread_rng().gen_ascii_chars().take(SEM_NAME_MAX).collect();
            let c_name = CString::new(name).unwrap(); // Rng does not emit 0 bytes.

            let sem: *mut sem_t = unsafe {
                sem_open(c_name.as_ptr(), O_CREAT | O_EXCL, S_IRWXU, value as c_uint)
            };
            debug_assert!(sem != SEM_FAILED);

            Semaphore {
                inner: UnsafeCell::new(sem),
                name: c_name,
            }
        }

        pub fn wait(&self) {
            loop {
                let res = unsafe {
                    sem_wait(self.inner.get())
                };
                if res == -1 {
                    match io::Error::last_os_error() {
                        ref e if e.kind() == io::ErrorKind::Interrupted => continue,
                        other => panic!("{}", other),
                    }
                } else {
                    break;
                }
            }
        }

        pub fn post(&self) {
            let res = unsafe {
                sem_post(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }

        pub fn access(&self) -> SemaphoreGuard {
            self.wait();
            SemaphoreGuard { sem: self }
        }
    }

    impl Drop for Semaphore {
        fn drop(&mut self) {
            let res = unsafe {
                sem_close(self.inner.get())
            };
            debug_assert_eq!(res, 0);
            let res = unsafe {
                sem_unlink(self.name.as_ptr())
            };
            debug_assert_eq!(res, 0);
        }
    }

    impl<'a> Drop for SemaphoreGuard<'a> {
        fn drop(&mut self) {
            self.sem.post();
        }
    }
}
<commit_msg>fix mistakes. (can't test macos code as quickly/easily)<commit_after>pub use self::os::{
    Semaphore,
    SemaphoreGuard,
};

#[cfg(not(target_os = "macos"))]
mod os {
    use std::cell::UnsafeCell;
    use std::mem;
    use std::io;
    use libc::{
        c_int,
        c_uint,
    };

    #[cfg(target_pointer_width = "64")]
    const SIZEOF_SEM_T: usize = 32;
    #[cfg(not(target_pointer_width = "64"))]
    const SIZEOF_SEM_T: usize = 16;

    extern {
        fn sem_init(sem: *mut sem_t, pshared: c_int, value: c_uint) -> c_int;
        fn sem_post(sem: *mut sem_t) -> c_int;
        fn sem_wait(sem: *mut sem_t) -> c_int;
        fn sem_destroy(sem: *mut sem_t) -> c_int;
    }

    #[repr(C)]
    #[derive(Debug)]
    struct sem_t {
        __opaque: [u8; SIZEOF_SEM_T],
    }

    pub struct Semaphore {
        inner: UnsafeCell<sem_t>,
    }

    pub struct SemaphoreGuard<'a> {
        sem: &'a Semaphore,
    }

    impl Semaphore {
        pub fn new(value: u32) -> Semaphore {
            let mut sem: sem_t = unsafe {
                mem::uninitialized()
            };
            let res = unsafe {
                sem_init(&mut sem, 0, value as c_uint)
            };
            debug_assert_eq!(res, 0);

            Semaphore {
                inner: UnsafeCell::new(sem),
            }
        }

        pub fn wait(&self) {
            loop {
                let res = unsafe {
                    sem_wait(self.inner.get())
                };
                if res == -1 {
                    match io::Error::last_os_error() {
                        ref e if e.kind() == io::ErrorKind::Interrupted => continue,
                        other => panic!("{}", other),
                    }
                } else {
                    break;
                }
            }
        }

        pub fn post(&self) {
            let res = unsafe {
                sem_post(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }

        pub fn access(&self) -> SemaphoreGuard {
            self.wait();
            SemaphoreGuard { sem: self }
        }
    }

    unsafe impl Send for Semaphore {}
    unsafe impl Sync for Semaphore {}

    impl Drop for Semaphore {
        fn drop(&mut self) {
            let res = unsafe {
                sem_destroy(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }
    }

    impl<'a> Drop for SemaphoreGuard<'a> {
        fn drop(&mut self) {
            self.sem.post();
        }
    }
}

#[cfg(target_os = "macos")]
mod os {
    use std::ffi::CString;
    use rand::{
        thread_rng,
        Rng,
    };
    use libc::{
        c_int,
        c_uint,
        c_char,
        mode_t,
        O_CREAT,
        O_EXCL,
        S_IRWXU,
    };

    const SIZEOF_SEM_T: usize = 4;
    const SEM_NAME_MAX: usize = 28; // No definitive value for this on OS X. Erring on the side of caution.
    const SEM_FAILED: *mut sem_t = 0 as *mut sem_t;

    extern {
        fn sem_open(name: *const c_char, oflag: c_int, mode: mode_t, value: c_uint) -> *mut sem_t;
        fn sem_post(sem: *mut sem_t) -> c_int;
        fn sem_wait(sem: *mut sem_t) -> c_int;
        fn sem_close(sem: *mut sem_t) -> c_int;
        fn sem_unlink(sem: *const c_char) -> c_int;
    }

    #[repr(C)]
    #[derive(Debug)]
    pub struct sem_t {
        __opaque: c_int,
    }

    pub struct Semaphore {
        inner: UnsafeCell<*mut sem_t>,
        name: CString,
    }

    pub struct SemaphoreGuard<'a> {
        sem: &'a Semaphore,
    }

    impl Semaphore {
        pub fn new(value: u32) -> Semaphore {
            let name: String = thread_rng().gen_ascii_chars().take(SEM_NAME_MAX).collect();
            let c_name = CString::new(name).unwrap(); // Rng does not emit 0 bytes.

            let sem: *mut sem_t = unsafe {
                sem_open(c_name.as_ptr(), O_CREAT | O_EXCL, S_IRWXU, value as c_uint)
            };
            debug_assert!(sem != SEM_FAILED);

            Semaphore {
                inner: UnsafeCell::new(sem),
                name: c_name,
            }
        }

        pub fn wait(&self) {
            loop {
                let res = unsafe {
                    sem_wait(self.inner.get())
                };
                if res == -1 {
                    match io::Error::last_os_error() {
                        ref e if e.kind() == io::ErrorKind::Interrupted => continue,
                        other => panic!("{}", other),
                    }
                } else {
                    break;
                }
            }
        }

        pub fn post(&self) {
            let res = unsafe {
                sem_post(self.inner.get())
            };
            debug_assert_eq!(res, 0);
        }

        pub fn access(&self) -> SemaphoreGuard {
            self.wait();
            SemaphoreGuard { sem: self }
        }
    }

    impl Drop for Semaphore {
        fn drop(&mut self) {
            let res = unsafe {
                sem_close(self.inner.get())
            };
            debug_assert_eq!(res, 0);
            let res = unsafe {
                sem_unlink(self.name.as_ptr())
            };
            debug_assert_eq!(res, 0);
        }
    }

    impl<'a> Drop for SemaphoreGuard<'a> {
        fn drop(&mut self) {
            self.sem.post();
        }
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::old_io::{stdio, File, Open, ReadWrite, Command};
use std::old_io::process::StdioContainer;
use std::os::unix::prelude::AsRawFd;

pub struct TTY {
    file: File,
    dimensions: (usize, usize),
    original_state: String
}

pub trait IO {
    fn write(&mut self, line: &str);
    fn read(&mut self) -> Option<String>;
    fn last(&self) -> &str;
    fn lines(&self) -> Vec<String>;
    fn dimensions(&self) -> (usize, usize);
}

impl IO for TTY {
    fn write(&mut self, line: &str) {
        let it = format!("{}\n", line);
        self.file.write_str(it.as_slice());
    }

    fn read(&mut self) -> Option<String> {
        let res = match self.file.read_byte() {
            Ok(c) => {
                let character = c as char;
                Some(character.to_string())
            },
            Err(_) => None,
        };
        res
    }

    fn last(&self) -> &str {
        "fail"
    }

    fn lines(&self) -> Vec<String> {
        let mut lines: Vec<String> = Vec::new();
        lines.push("fail".to_string());
        lines
    }

    fn dimensions(&self) -> (usize, usize) {
        self.dimensions
    }
}

impl TTY {
    pub fn new() -> TTY {
        let path = Path::new("/dev/tty");
        let file = File::open_mode(&path, Open, ReadWrite).unwrap();
        let dimension = TTY::get_window_size();

        TTY::no_echo_no_escaping(&file);

        TTY {
            original_state: TTY::previous_state(&file),
            dimensions: dimension,
            file: file,
        }
    }

    pub fn reset(&self) {
        TTY::stty(&self.file, &[self.original_state.as_slice()]);
    }

    fn get_window_size() -> (usize, usize) {
        let (w,h) = stdio::stdout_raw().winsize().unwrap();
        (w as usize, h as usize)
    }

    fn stty(file: &File, args: &[&str]) -> Option<String> {
        let container = StdioContainer::InheritFd(file.as_raw_fd());
        let output = Command::new("stty").args(args).stdin(container).output().unwrap();
        String::from_utf8(output.output).ok()
    }

    fn no_echo_no_escaping(file: &File) {
        TTY::stty(file, &["-echo", "-icanon"]);
    }

    fn previous_state(file: &File) -> String {
        TTY::stty(file, &["-g"]).unwrap_or("".to_string())
    }
}

#[cfg(test)]

#[test]
fn can_create_a_tty() {
    let mut tty = TTY::new();
    tty.write("##### a string        \n");
    //tty.read();
}
<commit_msg>Save the tty original state before changing it<commit_after>extern crate libc;

use std::old_io::{stdio, File, Open, ReadWrite, Command};
use std::old_io::process::StdioContainer;
use std::os::unix::prelude::AsRawFd;

pub struct TTY {
    file: File,
    dimensions: (usize, usize),
    original_state: String
}

pub trait IO {
    fn write(&mut self, line: &str);
    fn read(&mut self) -> Option<String>;
    fn last(&self) -> &str;
    fn lines(&self) -> Vec<String>;
    fn dimensions(&self) -> (usize, usize);
}

impl IO for TTY {
    fn write(&mut self, line: &str) {
        let it = format!("{}\n", line);
        self.file.write_str(it.as_slice());
    }

    fn read(&mut self) -> Option<String> {
        let res = match self.file.read_byte() {
            Ok(c) => {
                let character = c as char;
                Some(character.to_string())
            },
            Err(_) => None,
        };
        res
    }

    fn last(&self) -> &str {
        "fail"
    }

    fn lines(&self) -> Vec<String> {
        let mut lines: Vec<String> = Vec::new();
        lines.push("fail".to_string());
        lines
    }

    fn dimensions(&self) -> (usize, usize) {
        self.dimensions
    }
}

impl TTY {
    pub fn new() -> TTY {
        let path = Path::new("/dev/tty");
        let file = File::open_mode(&path, Open, ReadWrite).unwrap();
        let dimension = TTY::get_window_size();
        let orig_state = TTY::previous_state(&file);

        TTY::no_echo_no_escaping(&file);

        TTY {
            original_state: orig_state,
            dimensions: dimension,
            file: file,
        }
    }

    pub fn reset(&self) {
        TTY::stty(&self.file, &[self.original_state.as_slice()]);
    }

    fn get_window_size() -> (usize, usize) {
        let (w,h) = stdio::stdout_raw().winsize().unwrap();
        (w as usize, h as usize)
    }

    fn stty(file: &File, args: &[&str]) -> Option<String> {
        let container = StdioContainer::InheritFd(file.as_raw_fd());
        let output = Command::new("stty").args(args).stdin(container).output().unwrap();
        String::from_utf8(output.output).ok()
    }

    fn no_echo_no_escaping(file: &File) {
        TTY::stty(file, &["-echo", "-icanon"]);
    }

    fn previous_state(file: &File) -> String {
        TTY::stty(file, &["-g"]).unwrap_or("".to_string())
    }
}

#[cfg(test)]

#[test]
fn can_create_a_tty() {
    let mut tty = TTY::new();
    tty.write("##### a string        \n");
    //tty.read();
}
<|endoftext|>


<commit_before>//! Variable length records are used to store additional metadata not defined in the header.
//!
//! Variable length records (VLRs) can be "regular" or "extended". "Regular" vlrs are stored right
//! after the header, before the point records. "Extended" vlrs (EVLRs) are stored at the end of
//! the file, after the point records.
//!
//! Vlrs contain arbitrary data:
//!
//! ```
//! use las::Vlr;
//! let vlr = Vlr {
//!     user_id: "gadomski".to_string(),
//!     record_id: 42,
//!     description: "Some really important data".to_string(),
//!     data: vec![1, 2, 3],
//!     is_extended: false,
//! };
//! ```
//!
//! Use the `is_extended` flag to indicate that this vlr should be stored as an extended variable
//! length record. Note that a header may choose to ignore this flag if the version doesn't support
//! evlrs and the evlr can be safely converted to a vlr.
//!
//! ```
//! use las::{Vlr, Header};
//! let mut header = Header::default();
//! header.version = (1, 4).into();
//!
//! let evlr = Vlr { is_extended: true, ..Default::default() };
//! header.push_vlr(evlr);
//! assert_eq!(1, header.evlrs().count());
//!
//! header.version = (1, 2).into(); // las 1.2 doesn't support evlrs
//! assert_eq!(0, header.evlrs().count());
//! assert_eq!(1, header.vlrs().count());
//! ```

use {Result, raw};

const HEADER_SIZE: usize = 54;

quick_error! {
    /// Vlr-specific errors.
    #[derive(Debug, Clone, Copy)]
    pub enum Error {
        /// The vlr data is too long.
        TooLong(len: usize) {
            description("The vlr is too long")
            display("the vlr is too long: {}", len)
        }
    }
}

/// A variable length record.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Vlr {
    /// The user that created this record.
    ///
    /// This value is often an official, "registered" user_id, such as "LASF_Spec" or
    /// "LASF_Projection".
    pub user_id: String,

    /// This value specifies the type of record, and depends on the user id.
    pub record_id: u16,

    /// Textual description of these data.
    pub description: String,

    /// The data themselves.
    pub data: Vec<u8>,

    /// Should this vlr be written "extended", i.e. at the end of the file.
    ///
    /// Note that not all las versions support extended vlrs, and extra-long vlrs might be written
    /// as extended even if this flag is not set.
    pub is_extended: bool,
}

impl Vlr {
    /// Creates a vlr from a raw vlr.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::{Vlr, raw};
    /// let raw_vlr = raw::Vlr::default();
    /// let vlr = Vlr::new(raw_vlr).unwrap();
    /// ```
    pub fn new(raw_vlr: raw::Vlr) -> Result<Vlr> {
        use utils::AsLasStr;
        Ok(Vlr {
            user_id: raw_vlr.user_id.as_ref().as_las_str()?.to_string(),
            record_id: raw_vlr.record_id,
            description: raw_vlr.description.as_ref().as_las_str()?.to_string(),
            is_extended: raw_vlr.is_extended(),
            data: raw_vlr.data,
        })
    }

    /// Converts this vlr to a raw vlr.
    ///
    /// The second argument works like this:
    ///
    /// - If `Some(false)`, create a normal vlr.
    /// - If `Some(true)`, create an extended vlr.
    /// - If `None`, fall back to the default as defined by the `extended` flag on this vlr.
    ///
    /// Note that you can just pass `true` or `false` and it will be converted to the option type.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::Vlr;
    /// let raw_vlr =  Vlr::default().into_raw(false).unwrap();
    /// let raw_evlr =  Vlr::default().into_raw(true).unwrap();
    /// let raw_vlr2 =  Vlr::default().into_raw(None).unwrap();
    /// ```
    pub fn into_raw<T>(self, force_extended: T) -> Result<raw::Vlr>
    where
        T: Into<Option<bool>>,
    {
        use utils::FromLasStr;

        let extended = force_extended.into().unwrap_or(self.is_extended);
        let mut user_id = [0; 16];
        user_id.as_mut().from_las_str(&self.user_id)?;
        let mut description = [0; 32];
        description.as_mut().from_las_str(&self.description)?;
        Ok(raw::Vlr {
            reserved: 0,
            user_id: user_id,
            record_id: self.record_id,
            record_length_after_header: self.record_length_after_header(extended)?,
            description: description,
            data: self.data,
        })
    }

    /// Returns the total length of this vlr, header and data.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::Vlr;
    /// let vlr = Vlr::default();
    /// assert_eq!(54, vlr.len());
    /// ```
    pub fn len(&self) -> usize {
        self.data.len() + HEADER_SIZE
    }

    /// Returns true if this vlr is extended.
    ///
    /// True either if the flag is set, or the data is too long for a normal vlr.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::u16;
    /// use las::Vlr;
    /// let mut vlr = Vlr::default();
    /// assert!(!vlr.is_extended());
    /// vlr.is_extended = true;
    /// assert!(vlr.is_extended());
    ///
    /// vlr.is_extended = false;
    /// vlr.data = vec![0; u16::MAX as usize + 1];
    /// assert!(vlr.is_extended());
    /// ```
    pub fn is_extended(&self) -> bool {
        use std::u16;
        self.is_extended || self.data.len() > u16::MAX as usize
    }

    fn record_length_after_header(&self, extended: bool) -> Result<raw::vlr::RecordLength> {
        if extended {
            Ok(raw::vlr::RecordLength::Evlr(self.data.len() as u64))
        } else {
            use std::u16;
            if self.data.len() > u16::MAX as usize {
                Err(Error::TooLong(self.data.len()).into())
            } else {
                Ok(raw::vlr::RecordLength::Vlr(self.data.len() as u16))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn len() {
        let data = vec![0; 1];
        let vlr = Vlr {
            data: data,
            ..Default::default()
        };
        assert_eq!(55, vlr.len());
    }

    #[test]
    fn too_long() {
        use std::u16;
        let data = vec![0; u16::MAX as usize + 1];
        let vlr = Vlr {
            data: data,
            ..Default::default()
        };
        assert!(vlr.into_raw(false).is_err());
    }
}
<commit_msg>Add is_empty to vlr<commit_after>//! Variable length records are used to store additional metadata not defined in the header.
//!
//! Variable length records (VLRs) can be "regular" or "extended". "Regular" vlrs are stored right
//! after the header, before the point records. "Extended" vlrs (EVLRs) are stored at the end of
//! the file, after the point records.
//!
//! Vlrs contain arbitrary data:
//!
//! ```
//! use las::Vlr;
//! let vlr = Vlr {
//!     user_id: "gadomski".to_string(),
//!     record_id: 42,
//!     description: "Some really important data".to_string(),
//!     data: vec![1, 2, 3],
//!     is_extended: false,
//! };
//! ```
//!
//! Use the `is_extended` flag to indicate that this vlr should be stored as an extended variable
//! length record. Note that a header may choose to ignore this flag if the version doesn't support
//! evlrs and the evlr can be safely converted to a vlr.
//!
//! ```
//! use las::{Vlr, Header};
//! let mut header = Header::default();
//! header.version = (1, 4).into();
//!
//! let evlr = Vlr { is_extended: true, ..Default::default() };
//! header.push_vlr(evlr);
//! assert_eq!(1, header.evlrs().count());
//!
//! header.version = (1, 2).into(); // las 1.2 doesn't support evlrs
//! assert_eq!(0, header.evlrs().count());
//! assert_eq!(1, header.vlrs().count());
//! ```

use {Result, raw};

const HEADER_SIZE: usize = 54;

quick_error! {
    /// Vlr-specific errors.
    #[derive(Debug, Clone, Copy)]
    pub enum Error {
        /// The vlr data is too long.
        TooLong(len: usize) {
            description("The vlr is too long")
            display("the vlr is too long: {}", len)
        }
    }
}

/// A variable length record.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Vlr {
    /// The user that created this record.
    ///
    /// This value is often an official, "registered" user_id, such as "LASF_Spec" or
    /// "LASF_Projection".
    pub user_id: String,

    /// This value specifies the type of record, and depends on the user id.
    pub record_id: u16,

    /// Textual description of these data.
    pub description: String,

    /// The data themselves.
    pub data: Vec<u8>,

    /// Should this vlr be written "extended", i.e. at the end of the file.
    ///
    /// Note that not all las versions support extended vlrs, and extra-long vlrs might be written
    /// as extended even if this flag is not set.
    pub is_extended: bool,
}

impl Vlr {
    /// Creates a vlr from a raw vlr.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::{Vlr, raw};
    /// let raw_vlr = raw::Vlr::default();
    /// let vlr = Vlr::new(raw_vlr).unwrap();
    /// ```
    pub fn new(raw_vlr: raw::Vlr) -> Result<Vlr> {
        use utils::AsLasStr;
        Ok(Vlr {
            user_id: raw_vlr.user_id.as_ref().as_las_str()?.to_string(),
            record_id: raw_vlr.record_id,
            description: raw_vlr.description.as_ref().as_las_str()?.to_string(),
            is_extended: raw_vlr.is_extended(),
            data: raw_vlr.data,
        })
    }

    /// Converts this vlr to a raw vlr.
    ///
    /// The second argument works like this:
    ///
    /// - If `Some(false)`, create a normal vlr.
    /// - If `Some(true)`, create an extended vlr.
    /// - If `None`, fall back to the default as defined by the `extended` flag on this vlr.
    ///
    /// Note that you can just pass `true` or `false` and it will be converted to the option type.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::Vlr;
    /// let raw_vlr =  Vlr::default().into_raw(false).unwrap();
    /// let raw_evlr =  Vlr::default().into_raw(true).unwrap();
    /// let raw_vlr2 =  Vlr::default().into_raw(None).unwrap();
    /// ```
    pub fn into_raw<T>(self, force_extended: T) -> Result<raw::Vlr>
    where
        T: Into<Option<bool>>,
    {
        use utils::FromLasStr;

        let extended = force_extended.into().unwrap_or(self.is_extended);
        let mut user_id = [0; 16];
        user_id.as_mut().from_las_str(&self.user_id)?;
        let mut description = [0; 32];
        description.as_mut().from_las_str(&self.description)?;
        Ok(raw::Vlr {
            reserved: 0,
            user_id: user_id,
            record_id: self.record_id,
            record_length_after_header: self.record_length_after_header(extended)?,
            description: description,
            data: self.data,
        })
    }

    /// Returns the total length of this vlr, header and data.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::Vlr;
    /// let vlr = Vlr::default();
    /// assert_eq!(54, vlr.len());
    /// ```
    pub fn len(&self) -> usize {
        self.data.len() + HEADER_SIZE
    }

    /// Returns true if the data of this vlr are empty.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::Vlr;
    /// let mut vlr = Vlr::default();
    /// assert!(vlr.is_empty());
    /// vlr.data = vec![42];
    /// assert!(!vlr.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Returns true if this vlr is extended.
    ///
    /// True either if the flag is set, or the data is too long for a normal vlr.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::u16;
    /// use las::Vlr;
    /// let mut vlr = Vlr::default();
    /// assert!(!vlr.is_extended());
    /// vlr.is_extended = true;
    /// assert!(vlr.is_extended());
    ///
    /// vlr.is_extended = false;
    /// vlr.data = vec![0; u16::MAX as usize + 1];
    /// assert!(vlr.is_extended());
    /// ```
    pub fn is_extended(&self) -> bool {
        use std::u16;
        self.is_extended || self.data.len() > u16::MAX as usize
    }

    fn record_length_after_header(&self, extended: bool) -> Result<raw::vlr::RecordLength> {
        if extended {
            Ok(raw::vlr::RecordLength::Evlr(self.data.len() as u64))
        } else {
            use std::u16;
            if self.data.len() > u16::MAX as usize {
                Err(Error::TooLong(self.data.len()).into())
            } else {
                Ok(raw::vlr::RecordLength::Vlr(self.data.len() as u16))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn len() {
        let data = vec![0; 1];
        let vlr = Vlr {
            data: data,
            ..Default::default()
        };
        assert_eq!(55, vlr.len());
    }

    #[test]
    fn too_long() {
        use std::u16;
        let data = vec![0; u16::MAX as usize + 1];
        let vlr = Vlr {
            data: data,
            ..Default::default()
        };
        assert!(vlr.into_raw(false).is_err());
    }
}
<|endoftext|>


<commit_before>
use iron::{Iron, IronResult, Listening, status};
use iron::error::HttpResult;
use iron::response::Response;
use iron::request::Request;
use iron::middleware::Handler;
use iron::mime::Mime;

use sysinfo::{System, SystemExt};
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use std::time::{Duration, SystemTime};
use SysinfoExt;
use serde_json;

const INDEX_HTML: &'static str = include_str!("index.html");
const REFRESH_DELAY: u64 = 60 * 10; // 10 minutes

struct SysinfoIronHandler(Arc<DataHandler>);

struct DataHandler {
    system: RwLock<System>,
    last_connection: Mutex<SystemTime>,
    json_output: RwLock<String>,
}

impl DataHandler {
    fn can_update_system_info(&self) -> bool {
        SystemTime::now().duration_since(*self.last_connection.lock().unwrap())
                         .unwrap()
                         .as_secs() < REFRESH_DELAY
    }

    fn update_last_connection(&self) {
        *self.last_connection.lock().unwrap() = SystemTime::now();
    }
}

impl Handler for SysinfoIronHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        match req.url.path().last() {
            Some(path) => {
                if *path == "" {
                    Ok(Response::with((status::Ok,
                                       "text/html".parse::<Mime>().unwrap(),
                                       INDEX_HTML)))
                } else {
                    self.0.update_last_connection();
                    Ok(Response::with((status::Ok,
                                       "application/json".parse::<Mime>().unwrap(),
                                       self.0.json_output.read().unwrap().clone())))
                }
            },
            None => Ok(Response::with((status::NotFound, "Not found")))
        }
    }
}

pub fn start_web_server(sock_addr: Option<String>) -> HttpResult<Listening> {
    let data_handler = Arc::new(DataHandler {
        system: RwLock::new(System::new()),
        last_connection: Mutex::new(SystemTime::now()),
        json_output: RwLock::new(String::from("[]")),
    });
    let data_handler_clone = data_handler.clone();
    thread::spawn(move || {
        loop {
            if data_handler_clone.can_update_system_info() {
                {
                    let mut system = data_handler_clone.system.write().unwrap();
                    system.refresh_all();
                    let sysinfo = SysinfoExt::new(&system);
                    let mut json_output = data_handler_clone.json_output.write().unwrap();
                    json_output.clear();
                    use std::fmt::Write;
                    json_output.write_str(&serde_json::to_string(&sysinfo)
                                          .unwrap_or(String::from("[]"))).unwrap();
                }
                thread::sleep(Duration::new(5, 0));
            } else {
                // If we don't need to refresh the system information, we can sleep a lot less.
                thread::sleep(Duration::from_millis(500));
            }
        }
    });
    let mut iron = Iron::new(SysinfoIronHandler(data_handler));
    iron.threads = 4;
    iron.http(sock_addr.unwrap_or("localhost:3000".to_owned()))
}
<commit_msg>Refresh system twice after wake up<commit_after>
use iron::{Iron, IronResult, Listening, status};
use iron::error::HttpResult;
use iron::response::Response;
use iron::request::Request;
use iron::middleware::Handler;
use iron::mime::Mime;

use sysinfo::{System, SystemExt};
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use std::time::{Duration, SystemTime};
use SysinfoExt;
use serde_json;

const INDEX_HTML: &'static str = include_str!("index.html");
const REFRESH_DELAY: u64 = 60 * 10; // 10 minutes

struct SysinfoIronHandler(Arc<DataHandler>);

struct DataHandler {
    system: RwLock<System>,
    last_connection: Mutex<SystemTime>,
    json_output: RwLock<String>,
}

impl DataHandler {
    fn can_update_system_info(&self) -> bool {
        SystemTime::now().duration_since(*self.last_connection.lock().unwrap())
                         .unwrap()
                         .as_secs() < REFRESH_DELAY
    }

    fn update_last_connection(&self) {
        *self.last_connection.lock().unwrap() = SystemTime::now();
    }
}

impl Handler for SysinfoIronHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        match req.url.path().last() {
            Some(path) => {
                if *path == "" {
                    Ok(Response::with((status::Ok,
                                       "text/html".parse::<Mime>().unwrap(),
                                       INDEX_HTML)))
                } else {
                    self.0.update_last_connection();
                    Ok(Response::with((status::Ok,
                                       "application/json".parse::<Mime>().unwrap(),
                                       self.0.json_output.read().unwrap().clone())))
                }
            },
            None => Ok(Response::with((status::NotFound, "Not found")))
        }
    }
}

pub fn start_web_server(sock_addr: Option<String>) -> HttpResult<Listening> {
    let data_handler = Arc::new(DataHandler {
        system: RwLock::new(System::new()),
        last_connection: Mutex::new(SystemTime::now()),
        json_output: RwLock::new(String::from("[]")),
    });
    let data_handler_clone = data_handler.clone();
    thread::spawn(move || {
        let mut sleeping = false;
        loop {
            if data_handler_clone.can_update_system_info() {
                {
                    let mut system = data_handler_clone.system.write().unwrap();
                    system.refresh_all();
                    // refresh it twice to provide accurate information after wake up
                    if sleeping {
                        system.refresh_all();
                        sleeping = false;
                    }
                    let sysinfo = SysinfoExt::new(&system);
                    let mut json_output = data_handler_clone.json_output.write().unwrap();
                    json_output.clear();
                    use std::fmt::Write;
                    json_output.write_str(&serde_json::to_string(&sysinfo)
                                          .unwrap_or(String::from("[]"))).unwrap();
                }
                thread::sleep(Duration::new(5, 0));
            } else {
                // If we don't need to refresh the system information, we can sleep a lot less.
                thread::sleep(Duration::from_millis(500));
                sleeping = true;
            }
        }
    });
    let mut iron = Iron::new(SysinfoIronHandler(data_handler));
    iron.threads = 4;
    iron.http(sock_addr.unwrap_or("localhost:3000".to_owned()))
}
<|endoftext|>


<commit_before>// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use fmt;
use marker;
use usize;

use super::{FusedIterator, TrustedLen};

/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat`] function. See its documentation for more.
///
/// [`repeat`]: fn.repeat.html
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
    element: A
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> { Some(self.element.clone()) }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
/// over and over and 🔁.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`take`], in order to make them finite.
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with`] function.
///
/// [`repeat_with`]: fn.repeat_with.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`take`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
    Repeat{element: elt}
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`repeat_with`] function.
/// See its documentation for more.
///
/// [`repeat_with`]: fn.repeat_with.html
#[derive(Copy, Clone, Debug)]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub struct RepeatWith<F> {
    repeater: F
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> { Some((self.repeater)()) }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> DoubleEndedIterator for RepeatWith<F> {
    #[inline]
    fn next_back(&mut self) -> Option<A> { self.next() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}

/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
/// The `repeat_with()` function calls the repeater over and over and over and
/// over and over and 🔁.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`take`], in order to make them finite.
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need implements `Clone`, and
/// it is OK to keep the source element in memory, you should instead use
/// the [`repeat`] function.
///
/// [`repeat`]: fn.repeat.html
///
/// An iterator produced by `repeat_with()` is a `DoubleEndedIterator`.
/// It is important to not that reversing `repeat_with(f)` will produce
/// the exact same sequence as the non-reversed iterator. In other words,
/// `repeat_with(f).rev().collect::<Vec<_>>()` is equivalent to
/// `repeat_with(f).collect::<Vec<_>>()`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // let's assume we have some value of a type that is not `Clone`
/// // or which don't want to have in memory just yet because it is expensive:
/// #[derive(PartialEq, Debug)]
/// struct Expensive;
///
/// // a particular value forever:
/// let mut things = iter::repeat_with(|| Expensive);
///
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// ```
///
/// Using mutation and going finite:
///
/// ```rust
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // From the zeroth to the third power of two:
/// let mut curr = 1;
/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
///                     .take(4);
///
/// assert_eq!(Some(1), pow2.next());
/// assert_eq!(Some(2), pow2.next());
/// assert_eq!(Some(4), pow2.next());
/// assert_eq!(Some(8), pow2.next());
///
/// // ... and now we're done
/// assert_eq!(None, pow2.next());
/// ```
#[inline]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
    RepeatWith { repeater }
}

/// An iterator that yields nothing.
///
/// This `struct` is created by the [`empty`] function. See its documentation for more.
///
/// [`empty`]: fn.empty.html
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);

#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<T> fmt::Debug for Empty<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Empty")
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Iterator for Empty<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        None
    }

    fn size_hint(&self) -> (usize, Option<usize>){
        (0, Some(0))
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> DoubleEndedIterator for Empty<T> {
    fn next_back(&mut self) -> Option<T> {
        None
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> ExactSizeIterator for Empty<T> {
    fn len(&self) -> usize {
        0
    }
}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Empty<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Empty<T> {}

// not #[derive] because that adds a Clone bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Clone for Empty<T> {
    fn clone(&self) -> Empty<T> {
        Empty(marker::PhantomData)
    }
}

// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Default for Empty<T> {
    fn default() -> Empty<T> {
        Empty(marker::PhantomData)
    }
}

/// Creates an iterator that yields nothing.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // this could have been an iterator over i32, but alas, it's just not.
/// let mut nope = iter::empty::<i32>();
///
/// assert_eq!(None, nope.next());
/// ```
#[stable(feature = "iter_empty", since = "1.2.0")]
pub fn empty<T>() -> Empty<T> {
    Empty(marker::PhantomData)
}

/// An iterator that yields an element exactly once.
///
/// This `struct` is created by the [`once`] function. See its documentation for more.
///
/// [`once`]: fn.once.html
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
    inner: ::option::IntoIter<T>
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> Iterator for Once<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.inner.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> DoubleEndedIterator for Once<T> {
    fn next_back(&mut self) -> Option<T> {
        self.inner.next_back()
    }
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> ExactSizeIterator for Once<T> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Once<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Once<T> {}

/// Creates an iterator that yields an element exactly once.
///
/// This is commonly used to adapt a single value into a [`chain`] of other
/// kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// [`chain`]: trait.Iterator.html#method.chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once(1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once(PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
///     println!("{:?}", f);
/// }
/// ```
#[stable(feature = "iter_once", since = "1.2.0")]
pub fn once<T>(value: T) -> Once<T> {
    Once { inner: Some(value).into_iter() }
}
<commit_msg>Rollup merge of #48282 - Centril:spelling-fix/iter-repeat-with, r=kennytm<commit_after>// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use fmt;
use marker;
use usize;

use super::{FusedIterator, TrustedLen};

/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat`] function. See its documentation for more.
///
/// [`repeat`]: fn.repeat.html
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
    element: A
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> { Some(self.element.clone()) }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
/// over and over and 🔁.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`take`], in order to make them finite.
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with`] function.
///
/// [`repeat_with`]: fn.repeat_with.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`take`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
    Repeat{element: elt}
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`repeat_with`] function.
/// See its documentation for more.
///
/// [`repeat_with`]: fn.repeat_with.html
#[derive(Copy, Clone, Debug)]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub struct RepeatWith<F> {
    repeater: F
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> { Some((self.repeater)()) }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> DoubleEndedIterator for RepeatWith<F> {
    #[inline]
    fn next_back(&mut self) -> Option<A> { self.next() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}

/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
/// The `repeat_with()` function calls the repeater over and over and over and
/// over and over and 🔁.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`take`], in order to make them finite.
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need implements `Clone`, and
/// it is OK to keep the source element in memory, you should instead use
/// the [`repeat`] function.
///
/// [`repeat`]: fn.repeat.html
///
/// An iterator produced by `repeat_with()` is a `DoubleEndedIterator`.
/// It is important to note that reversing `repeat_with(f)` will produce
/// the exact same sequence as the non-reversed iterator. In other words,
/// `repeat_with(f).rev().collect::<Vec<_>>()` is equivalent to
/// `repeat_with(f).collect::<Vec<_>>()`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // let's assume we have some value of a type that is not `Clone`
/// // or which don't want to have in memory just yet because it is expensive:
/// #[derive(PartialEq, Debug)]
/// struct Expensive;
///
/// // a particular value forever:
/// let mut things = iter::repeat_with(|| Expensive);
///
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// ```
///
/// Using mutation and going finite:
///
/// ```rust
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // From the zeroth to the third power of two:
/// let mut curr = 1;
/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
///                     .take(4);
///
/// assert_eq!(Some(1), pow2.next());
/// assert_eq!(Some(2), pow2.next());
/// assert_eq!(Some(4), pow2.next());
/// assert_eq!(Some(8), pow2.next());
///
/// // ... and now we're done
/// assert_eq!(None, pow2.next());
/// ```
#[inline]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
    RepeatWith { repeater }
}

/// An iterator that yields nothing.
///
/// This `struct` is created by the [`empty`] function. See its documentation for more.
///
/// [`empty`]: fn.empty.html
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);

#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<T> fmt::Debug for Empty<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Empty")
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Iterator for Empty<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        None
    }

    fn size_hint(&self) -> (usize, Option<usize>){
        (0, Some(0))
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> DoubleEndedIterator for Empty<T> {
    fn next_back(&mut self) -> Option<T> {
        None
    }
}

#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> ExactSizeIterator for Empty<T> {
    fn len(&self) -> usize {
        0
    }
}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Empty<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Empty<T> {}

// not #[derive] because that adds a Clone bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Clone for Empty<T> {
    fn clone(&self) -> Empty<T> {
        Empty(marker::PhantomData)
    }
}

// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Default for Empty<T> {
    fn default() -> Empty<T> {
        Empty(marker::PhantomData)
    }
}

/// Creates an iterator that yields nothing.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // this could have been an iterator over i32, but alas, it's just not.
/// let mut nope = iter::empty::<i32>();
///
/// assert_eq!(None, nope.next());
/// ```
#[stable(feature = "iter_empty", since = "1.2.0")]
pub fn empty<T>() -> Empty<T> {
    Empty(marker::PhantomData)
}

/// An iterator that yields an element exactly once.
///
/// This `struct` is created by the [`once`] function. See its documentation for more.
///
/// [`once`]: fn.once.html
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
    inner: ::option::IntoIter<T>
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> Iterator for Once<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.inner.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> DoubleEndedIterator for Once<T> {
    fn next_back(&mut self) -> Option<T> {
        self.inner.next_back()
    }
}

#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> ExactSizeIterator for Once<T> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Once<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Once<T> {}

/// Creates an iterator that yields an element exactly once.
///
/// This is commonly used to adapt a single value into a [`chain`] of other
/// kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// [`chain`]: trait.Iterator.html#method.chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once(1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once(PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
///     println!("{:?}", f);
/// }
/// ```
#[stable(feature = "iter_once", since = "1.2.0")]
pub fn once<T>(value: T) -> Once<T> {
    Once { inner: Some(value).into_iter() }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_upper_case_globals)]

use llvm;
use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind};
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};

use context::CrateContext;

use syntax::ast;
use rustc::ty::layout;

use std::ffi::CString;
use std::fmt;
use std::mem;
use std::ptr;

use libc::c_uint;

#[derive(Clone, Copy, PartialEq)]
#[repr(C)]
pub struct Type {
    rf: TypeRef
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&llvm::build_string(|s| unsafe {
            llvm::LLVMRustWriteTypeToString(self.to_ref(), s);
        }).expect("non-UTF8 type description from LLVM"))
    }
}

macro_rules! ty {
    ($e:expr) => ( Type::from_ref(unsafe { $e }))
}

/// Wrapper for LLVM TypeRef
impl Type {
    #[inline(always)]
    pub fn from_ref(r: TypeRef) -> Type {
        Type {
            rf: r
        }
    }

    #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
    pub fn to_ref(&self) -> TypeRef {
        self.rf
    }

    pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
        unsafe { mem::transmute(slice) }
    }

    pub fn void(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMVoidTypeInContext(ccx.llcx()))
    }

    pub fn nil(ccx: &CrateContext) -> Type {
        Type::empty_struct(ccx)
    }

    pub fn metadata(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMRustMetadataTypeInContext(ccx.llcx()))
    }

    pub fn i1(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt1TypeInContext(ccx.llcx()))
    }

    pub fn i8(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
    }

    pub fn i8_llcx(llcx: ContextRef) -> Type {
        ty!(llvm::LLVMInt8TypeInContext(llcx))
    }

    pub fn i16(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
    }

    pub fn i32(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt32TypeInContext(ccx.llcx()))
    }

    pub fn i64(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt64TypeInContext(ccx.llcx()))
    }

    pub fn i128(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), 128))
    }

    // Creates an integer type with the given number of bits, e.g. i24
    pub fn ix(ccx: &CrateContext, num_bits: u64) -> Type {
        ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), num_bits as c_uint))
    }

    pub fn f32(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMFloatTypeInContext(ccx.llcx()))
    }

    pub fn f64(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMDoubleTypeInContext(ccx.llcx()))
    }

    pub fn bool(ccx: &CrateContext) -> Type {
        Type::i8(ccx)
    }

    pub fn char(ccx: &CrateContext) -> Type {
        Type::i32(ccx)
    }

    pub fn i8p(ccx: &CrateContext) -> Type {
        Type::i8(ccx).ptr_to()
    }

    pub fn i8p_llcx(llcx: ContextRef) -> Type {
        Type::i8_llcx(llcx).ptr_to()
    }

    pub fn isize(ccx: &CrateContext) -> Type {
        match &ccx.tcx().sess.target.target.target_pointer_width[..] {
            "16" => Type::i16(ccx),
            "32" => Type::i32(ccx),
            "64" => Type::i64(ccx),
            tws => bug!("Unsupported target word size for int: {}", tws),
        }
    }

    pub fn int_from_ty(ccx: &CrateContext, t: ast::IntTy) -> Type {
        match t {
            ast::IntTy::Is => ccx.isize_ty(),
            ast::IntTy::I8 => Type::i8(ccx),
            ast::IntTy::I16 => Type::i16(ccx),
            ast::IntTy::I32 => Type::i32(ccx),
            ast::IntTy::I64 => Type::i64(ccx),
            ast::IntTy::I128 => Type::i128(ccx),
        }
    }

    pub fn uint_from_ty(ccx: &CrateContext, t: ast::UintTy) -> Type {
        match t {
            ast::UintTy::Us => ccx.isize_ty(),
            ast::UintTy::U8 => Type::i8(ccx),
            ast::UintTy::U16 => Type::i16(ccx),
            ast::UintTy::U32 => Type::i32(ccx),
            ast::UintTy::U64 => Type::i64(ccx),
            ast::UintTy::U128 => Type::i128(ccx),
        }
    }

    pub fn float_from_ty(ccx: &CrateContext, t: ast::FloatTy) -> Type {
        match t {
            ast::FloatTy::F32 => Type::f32(ccx),
            ast::FloatTy::F64 => Type::f64(ccx),
        }
    }

    pub fn func(args: &[Type], ret: &Type) -> Type {
        let slice: &[TypeRef] = Type::to_ref_slice(args);
        ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
                                   args.len() as c_uint, False))
    }

    pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
        let slice: &[TypeRef] = Type::to_ref_slice(args);
        ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
                                   args.len() as c_uint, True))
    }

    pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
        let els: &[TypeRef] = Type::to_ref_slice(els);
        ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(),
                                          els.len() as c_uint,
                                          packed as Bool))
    }

    pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
        let name = CString::new(name).unwrap();
        ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
    }

    pub fn empty_struct(ccx: &CrateContext) -> Type {
        Type::struct_(ccx, &[], false)
    }

    pub fn array(ty: &Type, len: u64) -> Type {
        ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
    }

    pub fn vector(ty: &Type, len: u64) -> Type {
        ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint))
    }

    pub fn vec(ccx: &CrateContext, ty: &Type) -> Type {
        Type::struct_(ccx,
            &[Type::array(ty, 0), Type::isize(ccx)],
        false)
    }

    pub fn opaque_vec(ccx: &CrateContext) -> Type {
        Type::vec(ccx, &Type::i8(ccx))
    }

    pub fn vtable_ptr(ccx: &CrateContext) -> Type {
        Type::func(&[Type::i8p(ccx)], &Type::void(ccx)).ptr_to().ptr_to()
    }

    pub fn kind(&self) -> TypeKind {
        unsafe {
            llvm::LLVMRustGetTypeKind(self.to_ref())
        }
    }

    pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
        let slice: &[TypeRef] = Type::to_ref_slice(els);
        unsafe {
            llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(),
                                    els.len() as c_uint, packed as Bool)
        }
    }

    pub fn ptr_to(&self) -> Type {
        ty!(llvm::LLVMPointerType(self.to_ref(), 0))
    }

    pub fn element_type(&self) -> Type {
        unsafe {
            Type::from_ref(llvm::LLVMGetElementType(self.to_ref()))
        }
    }

    /// Return the number of elements in `self` if it is a LLVM vector type.
    pub fn vector_length(&self) -> usize {
        unsafe {
            llvm::LLVMGetVectorSize(self.to_ref()) as usize
        }
    }

    pub fn field_types(&self) -> Vec<Type> {
        unsafe {
            let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as usize;
            if n_elts == 0 {
                return Vec::new();
            }
            let mut elts = vec![Type { rf: ptr::null_mut() }; n_elts];
            llvm::LLVMGetStructElementTypes(self.to_ref(),
                                            elts.as_mut_ptr() as *mut TypeRef);
            elts
        }
    }

    pub fn func_params(&self) -> Vec<Type> {
        unsafe {
            let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
            let mut args = vec![Type { rf: ptr::null_mut() }; n_args];
            llvm::LLVMGetParamTypes(self.to_ref(),
                                    args.as_mut_ptr() as *mut TypeRef);
            args
        }
    }

    pub fn float_width(&self) -> usize {
        match self.kind() {
            Float => 32,
            Double => 64,
            X86_FP80 => 80,
            FP128 | PPC_FP128 => 128,
            _ => bug!("llvm_float_width called on a non-float type")
        }
    }

    /// Retrieve the bit width of the integer type `self`.
    pub fn int_width(&self) -> u64 {
        unsafe {
            llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64
        }
    }

    pub fn from_integer(cx: &CrateContext, i: layout::Integer) -> Type {
        use rustc::ty::layout::Integer::*;
        match i {
            I1 => Type::i1(cx),
            I8 => Type::i8(cx),
            I16 => Type::i16(cx),
            I32 => Type::i32(cx),
            I64 => Type::i64(cx),
            I128 => Type::i128(cx),
        }
    }
}
<commit_msg>rustc: Add Type::c_int()<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_upper_case_globals)]

use llvm;
use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind};
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};

use context::CrateContext;

use syntax::ast;
use rustc::ty::layout;

use std::ffi::CString;
use std::fmt;
use std::mem;
use std::ptr;

use libc::c_uint;

#[derive(Clone, Copy, PartialEq)]
#[repr(C)]
pub struct Type {
    rf: TypeRef
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&llvm::build_string(|s| unsafe {
            llvm::LLVMRustWriteTypeToString(self.to_ref(), s);
        }).expect("non-UTF8 type description from LLVM"))
    }
}

macro_rules! ty {
    ($e:expr) => ( Type::from_ref(unsafe { $e }))
}

/// Wrapper for LLVM TypeRef
impl Type {
    #[inline(always)]
    pub fn from_ref(r: TypeRef) -> Type {
        Type {
            rf: r
        }
    }

    #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
    pub fn to_ref(&self) -> TypeRef {
        self.rf
    }

    pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
        unsafe { mem::transmute(slice) }
    }

    pub fn void(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMVoidTypeInContext(ccx.llcx()))
    }

    pub fn nil(ccx: &CrateContext) -> Type {
        Type::empty_struct(ccx)
    }

    pub fn metadata(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMRustMetadataTypeInContext(ccx.llcx()))
    }

    pub fn i1(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt1TypeInContext(ccx.llcx()))
    }

    pub fn i8(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
    }

    pub fn i8_llcx(llcx: ContextRef) -> Type {
        ty!(llvm::LLVMInt8TypeInContext(llcx))
    }

    pub fn i16(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
    }

    pub fn i32(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt32TypeInContext(ccx.llcx()))
    }

    pub fn i64(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMInt64TypeInContext(ccx.llcx()))
    }

    pub fn i128(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), 128))
    }

    // Creates an integer type with the given number of bits, e.g. i24
    pub fn ix(ccx: &CrateContext, num_bits: u64) -> Type {
        ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), num_bits as c_uint))
    }

    pub fn f32(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMFloatTypeInContext(ccx.llcx()))
    }

    pub fn f64(ccx: &CrateContext) -> Type {
        ty!(llvm::LLVMDoubleTypeInContext(ccx.llcx()))
    }

    pub fn bool(ccx: &CrateContext) -> Type {
        Type::i8(ccx)
    }

    pub fn char(ccx: &CrateContext) -> Type {
        Type::i32(ccx)
    }

    pub fn i8p(ccx: &CrateContext) -> Type {
        Type::i8(ccx).ptr_to()
    }

    pub fn i8p_llcx(llcx: ContextRef) -> Type {
        Type::i8_llcx(llcx).ptr_to()
    }

    pub fn isize(ccx: &CrateContext) -> Type {
        match &ccx.tcx().sess.target.target.target_pointer_width[..] {
            "16" => Type::i16(ccx),
            "32" => Type::i32(ccx),
            "64" => Type::i64(ccx),
            tws => bug!("Unsupported target word size for int: {}", tws),
        }
    }

    pub fn c_int(ccx: &CrateContext) -> Type {
        Type::i32(ccx)
    }

    pub fn int_from_ty(ccx: &CrateContext, t: ast::IntTy) -> Type {
        match t {
            ast::IntTy::Is => ccx.isize_ty(),
            ast::IntTy::I8 => Type::i8(ccx),
            ast::IntTy::I16 => Type::i16(ccx),
            ast::IntTy::I32 => Type::i32(ccx),
            ast::IntTy::I64 => Type::i64(ccx),
            ast::IntTy::I128 => Type::i128(ccx),
        }
    }

    pub fn uint_from_ty(ccx: &CrateContext, t: ast::UintTy) -> Type {
        match t {
            ast::UintTy::Us => ccx.isize_ty(),
            ast::UintTy::U8 => Type::i8(ccx),
            ast::UintTy::U16 => Type::i16(ccx),
            ast::UintTy::U32 => Type::i32(ccx),
            ast::UintTy::U64 => Type::i64(ccx),
            ast::UintTy::U128 => Type::i128(ccx),
        }
    }

    pub fn float_from_ty(ccx: &CrateContext, t: ast::FloatTy) -> Type {
        match t {
            ast::FloatTy::F32 => Type::f32(ccx),
            ast::FloatTy::F64 => Type::f64(ccx),
        }
    }

    pub fn func(args: &[Type], ret: &Type) -> Type {
        let slice: &[TypeRef] = Type::to_ref_slice(args);
        ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
                                   args.len() as c_uint, False))
    }

    pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
        let slice: &[TypeRef] = Type::to_ref_slice(args);
        ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
                                   args.len() as c_uint, True))
    }

    pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
        let els: &[TypeRef] = Type::to_ref_slice(els);
        ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(),
                                          els.len() as c_uint,
                                          packed as Bool))
    }

    pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
        let name = CString::new(name).unwrap();
        ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
    }

    pub fn empty_struct(ccx: &CrateContext) -> Type {
        Type::struct_(ccx, &[], false)
    }

    pub fn array(ty: &Type, len: u64) -> Type {
        ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
    }

    pub fn vector(ty: &Type, len: u64) -> Type {
        ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint))
    }

    pub fn vec(ccx: &CrateContext, ty: &Type) -> Type {
        Type::struct_(ccx,
            &[Type::array(ty, 0), Type::isize(ccx)],
        false)
    }

    pub fn opaque_vec(ccx: &CrateContext) -> Type {
        Type::vec(ccx, &Type::i8(ccx))
    }

    pub fn vtable_ptr(ccx: &CrateContext) -> Type {
        Type::func(&[Type::i8p(ccx)], &Type::void(ccx)).ptr_to().ptr_to()
    }

    pub fn kind(&self) -> TypeKind {
        unsafe {
            llvm::LLVMRustGetTypeKind(self.to_ref())
        }
    }

    pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
        let slice: &[TypeRef] = Type::to_ref_slice(els);
        unsafe {
            llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(),
                                    els.len() as c_uint, packed as Bool)
        }
    }

    pub fn ptr_to(&self) -> Type {
        ty!(llvm::LLVMPointerType(self.to_ref(), 0))
    }

    pub fn element_type(&self) -> Type {
        unsafe {
            Type::from_ref(llvm::LLVMGetElementType(self.to_ref()))
        }
    }

    /// Return the number of elements in `self` if it is a LLVM vector type.
    pub fn vector_length(&self) -> usize {
        unsafe {
            llvm::LLVMGetVectorSize(self.to_ref()) as usize
        }
    }

    pub fn field_types(&self) -> Vec<Type> {
        unsafe {
            let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as usize;
            if n_elts == 0 {
                return Vec::new();
            }
            let mut elts = vec![Type { rf: ptr::null_mut() }; n_elts];
            llvm::LLVMGetStructElementTypes(self.to_ref(),
                                            elts.as_mut_ptr() as *mut TypeRef);
            elts
        }
    }

    pub fn func_params(&self) -> Vec<Type> {
        unsafe {
            let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
            let mut args = vec![Type { rf: ptr::null_mut() }; n_args];
            llvm::LLVMGetParamTypes(self.to_ref(),
                                    args.as_mut_ptr() as *mut TypeRef);
            args
        }
    }

    pub fn float_width(&self) -> usize {
        match self.kind() {
            Float => 32,
            Double => 64,
            X86_FP80 => 80,
            FP128 | PPC_FP128 => 128,
            _ => bug!("llvm_float_width called on a non-float type")
        }
    }

    /// Retrieve the bit width of the integer type `self`.
    pub fn int_width(&self) -> u64 {
        unsafe {
            llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64
        }
    }

    pub fn from_integer(cx: &CrateContext, i: layout::Integer) -> Type {
        use rustc::ty::layout::Integer::*;
        match i {
            I1 => Type::i1(cx),
            I8 => Type::i8(cx),
            I16 => Type::i16(cx),
            I32 => Type::i32(cx),
            I64 => Type::i64(cx),
            I128 => Type::i128(cx),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate base64;
extern crate clap;
extern crate habitat_common as common;
extern crate habitat_core as hcore;
extern crate habitat_pkg_export_docker as export_docker;
extern crate handlebars;
extern crate serde;
#[macro_use]
extern crate serde_json;

extern crate failure;
#[macro_use]
extern crate failure_derive;

use std::fs::File;
use std::io;
use std::io::prelude::*;

use common::ui::{Status, UIWriter, UI};

pub mod cli;
pub mod env;
pub mod error;
pub mod hb;
pub mod manifest;
pub mod manifestjson;
pub mod service_bind;
pub mod storage;
pub mod topology;

use export_docker::Result;

pub use cli::Cli;
pub use error::Error;
pub use manifest::Manifest;
pub use manifestjson::ManifestJson;

// Synced with the version of the Habitat operator.
pub const VERSION: &'static str = "0.1.0";

/// Convenient do-it-all function. You give it the CLI arguments from the user and it generates the
/// Kubernetes manifest. If user passed an `--output` argument with a value that is not "`-`", the
/// manifest is written to the provided file; otherwise, it is written to the standard output.
pub fn export_for_cli_matches(ui: &mut UI, matches: &clap::ArgMatches) -> Result<()> {
    let image = if !matches.is_present("NO_DOCKER_IMAGE") {
        export_docker::export_for_cli_matches(ui, &matches)?
    } else {
        ui.status(
            Status::Custom('☛', String::from("Skipping")),
            "Docker image generation",
        )?;
        None
    };
    let mut manifest = Manifest::new_from_cli_matches(ui, &matches, image)?;

    let mut write: Box<Write> = match matches.value_of("OUTPUT") {
        Some(o) if o != "-" => {
            ui.status(Status::Creating, format!("Kubernetes manifest file {}", o))?;
            let file = Box::new(File::create(o)?);
            ui.status(Status::Created, format!("Kubernetes manifest file {}", o))?;

            file
        }
        _ => {
            let stdout = Box::new(io::stdout());
            ui.status(
                Status::Custom('→', String::from("Writing")),
                "Kubernetes manifest to stdout",
            )?;

            stdout
        }
    };
    manifest.generate(&mut write)
}
<commit_msg>pkg-export-k8s: Expose PersistentStorage and QuoteHelper<commit_after>// Copyright (c) 2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate base64;
extern crate clap;
extern crate habitat_common as common;
extern crate habitat_core as hcore;
extern crate habitat_pkg_export_docker as export_docker;
extern crate handlebars;
extern crate serde;
#[macro_use]
extern crate serde_json;

extern crate failure;
#[macro_use]
extern crate failure_derive;

use std::fs::File;
use std::io;
use std::io::prelude::*;

use common::ui::{Status, UIWriter, UI};

pub mod cli;
pub mod env;
pub mod error;
pub mod hb;
pub mod manifest;
pub mod manifestjson;
pub mod service_bind;
pub mod storage;
pub mod topology;

use export_docker::Result;

pub use cli::Cli;
pub use error::Error;
pub use hb::QuoteHelper;
pub use manifest::Manifest;
pub use manifestjson::ManifestJson;
pub use storage::PersistentStorage;

// Synced with the version of the Habitat operator.
pub const VERSION: &'static str = "0.1.0";

/// Convenient do-it-all function. You give it the CLI arguments from the user and it generates the
/// Kubernetes manifest. If user passed an `--output` argument with a value that is not "`-`", the
/// manifest is written to the provided file; otherwise, it is written to the standard output.
pub fn export_for_cli_matches(ui: &mut UI, matches: &clap::ArgMatches) -> Result<()> {
    let image = if !matches.is_present("NO_DOCKER_IMAGE") {
        export_docker::export_for_cli_matches(ui, &matches)?
    } else {
        ui.status(
            Status::Custom('☛', String::from("Skipping")),
            "Docker image generation",
        )?;
        None
    };
    let mut manifest = Manifest::new_from_cli_matches(ui, &matches, image)?;

    let mut write: Box<Write> = match matches.value_of("OUTPUT") {
        Some(o) if o != "-" => {
            ui.status(Status::Creating, format!("Kubernetes manifest file {}", o))?;
            let file = Box::new(File::create(o)?);
            ui.status(Status::Created, format!("Kubernetes manifest file {}", o))?;

            file
        }
        _ => {
            let stdout = Box::new(io::stdout());
            ui.status(
                Status::Custom('→', String::from("Writing")),
                "Kubernetes manifest to stdout",
            )?;

            stdout
        }
    };
    manifest.generate(&mut write)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding;
use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding::HTMLDetailsElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::AttributeMutation;
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use script_thread::Runnable;
use std::cell::Cell;
use string_cache::Atom;
use task_source::TaskSource;
use task_source::dom_manipulation::DOMManipulationTask;

#[dom_struct]
pub struct HTMLDetailsElement {
    htmlelement: HTMLElement,
    toggle_counter: Cell<u32>
}

impl HTMLDetailsElement {
    fn new_inherited(localName: Atom,
                     prefix: Option<DOMString>,
                     document: &Document) -> HTMLDetailsElement {
        HTMLDetailsElement {
            htmlelement:
                HTMLElement::new_inherited(localName, prefix, document),
            toggle_counter: Cell::new(0)
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: Atom,
               prefix: Option<DOMString>,
               document: &Document) -> Root<HTMLDetailsElement> {
        let element = HTMLDetailsElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLDetailsElementBinding::Wrap)
    }

    pub fn check_toggle_count(&self, number: u32) -> bool {
        number == self.toggle_counter.get()
    }
}

impl HTMLDetailsElementMethods for HTMLDetailsElement {
    // https://html.spec.whatwg.org/multipage/#dom-details-open
    make_bool_getter!(Open, "open");

    // https://html.spec.whatwg.org/multipage/#dom-details-open
    make_bool_setter!(SetOpen, "open");
}

impl VirtualMethods for HTMLDetailsElement {
    fn super_type(&self) -> Option<&VirtualMethods> {
        Some(self.upcast::<HTMLElement>() as &VirtualMethods)
    }

    fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
        self.super_type().unwrap().attribute_mutated(attr, mutation);

        if attr.local_name() == &atom!("open") {
            let counter = self.toggle_counter.get() + 1;
            self.toggle_counter.set(counter);

            let window = window_from_node(self);
            let window = window.r();
            let task_source = window.dom_manipulation_task_source();
            let details = Trusted::new(self);
            let runnable = box DetailsNotificationRunnable {
                element: details,
                toggle_number: counter
            };
            let _ = task_source.queue(DOMManipulationTask::Runnable(runnable));
        }
    }
}

pub struct DetailsNotificationRunnable {
    element: Trusted<HTMLDetailsElement>,
    toggle_number: u32
}

impl Runnable for DetailsNotificationRunnable {
    fn handler(self: Box<DetailsNotificationRunnable>) {
        let target = self.element.root();
        if target.check_toggle_count(self.toggle_number) {
            target.upcast::<EventTarget>().fire_simple_event("toggle");
        }
    }
}
<commit_msg>Add name method for Runnable trait into DetailsNotificationRunnable<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding;
use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding::HTMLDetailsElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::AttributeMutation;
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use script_thread::Runnable;
use std::cell::Cell;
use string_cache::Atom;
use task_source::TaskSource;
use task_source::dom_manipulation::DOMManipulationTask;

#[dom_struct]
pub struct HTMLDetailsElement {
    htmlelement: HTMLElement,
    toggle_counter: Cell<u32>
}

impl HTMLDetailsElement {
    fn new_inherited(localName: Atom,
                     prefix: Option<DOMString>,
                     document: &Document) -> HTMLDetailsElement {
        HTMLDetailsElement {
            htmlelement:
                HTMLElement::new_inherited(localName, prefix, document),
            toggle_counter: Cell::new(0)
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: Atom,
               prefix: Option<DOMString>,
               document: &Document) -> Root<HTMLDetailsElement> {
        let element = HTMLDetailsElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLDetailsElementBinding::Wrap)
    }

    pub fn check_toggle_count(&self, number: u32) -> bool {
        number == self.toggle_counter.get()
    }
}

impl HTMLDetailsElementMethods for HTMLDetailsElement {
    // https://html.spec.whatwg.org/multipage/#dom-details-open
    make_bool_getter!(Open, "open");

    // https://html.spec.whatwg.org/multipage/#dom-details-open
    make_bool_setter!(SetOpen, "open");
}

impl VirtualMethods for HTMLDetailsElement {
    fn super_type(&self) -> Option<&VirtualMethods> {
        Some(self.upcast::<HTMLElement>() as &VirtualMethods)
    }

    fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
        self.super_type().unwrap().attribute_mutated(attr, mutation);

        if attr.local_name() == &atom!("open") {
            let counter = self.toggle_counter.get() + 1;
            self.toggle_counter.set(counter);

            let window = window_from_node(self);
            let window = window.r();
            let task_source = window.dom_manipulation_task_source();
            let details = Trusted::new(self);
            let runnable = box DetailsNotificationRunnable {
                element: details,
                toggle_number: counter
            };
            let _ = task_source.queue(DOMManipulationTask::Runnable(runnable));
        }
    }
}

pub struct DetailsNotificationRunnable {
    element: Trusted<HTMLDetailsElement>,
    toggle_number: u32
}

impl Runnable for DetailsNotificationRunnable {
    fn name(&self) -> &'static str { "DetailsNotificationRunnable" }

    fn handler(self: Box<DetailsNotificationRunnable>) {
        let target = self.element.root();
        if target.check_toggle_count(self.toggle_number) {
            target.upcast::<EventTarget>().fire_simple_event("toggle");
        }
    }
}
<|endoftext|>