<commit_before>use coordinates::{CoordinateSystem, Point};
use std::ops::{Index, IndexMut};
use std::ops::{Add, Sub, Mul, Div, Deref, DerefMut};
use typenum::uint::Unsigned;
use typenum::Pow;
use generic_array::{GenericArray, ArrayLength};
use super::{CovariantIndex, ContravariantIndex, Variance, IndexType};

/// This is a struct that represents a generic tensor
pub struct Tensor<T: CoordinateSystem, U: Variance>
    where T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    p: Point<T>,
    x: GenericArray<f64, <T::Dimension as Pow<U::Rank>>::Output>
}

impl<T, U> Clone for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn clone(&self) -> Tensor<T, U> {
        Tensor {
            p: self.p.clone(),
            x: self.x.clone()
        }
    }
}

impl<T, U> Copy for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as ArrayLength<f64>>::ArrayType: Copy,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>,
          <<T::Dimension as Pow<U::Rank>>::Output as ArrayLength<f64>>::ArrayType: Copy
{}

impl<T, U> Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    /// Returns the point at which the tensor is defined.
    pub fn get_point(&self) -> &Point<T> {
        &self.p
    }

    /// Converts a set of tensor indices passed as a slice into a single index for the internal array.
    /// The length of the slice (the number of indices) has to be compatible with the rank of the tensor.
    pub fn get_coord(i: &[usize]) -> usize {
        assert_eq!(i.len(), U::rank());
        let dim = T::dimension();
        let index = i.into_iter().fold(0, |res, idx| {
            assert!(*idx < dim);
            res * dim + idx
        });
        index
    }

    /// Returns the variance of the tensor, that is, the list of the index types.
    /// A vector would return vec![Contravariant], a metric tensor: vec![Covariant, Covariant].
    pub fn get_variance() -> Vec<IndexType> {
        U::variance()
    }

    /// Returns the rank of the tensor
    pub fn get_rank() -> usize {
        U::rank()
    }

    /// Returns the number of coordinates of the tensor
    pub fn get_num_coords() -> usize {
        <T::Dimension as Pow<U::Rank>>::Output::to_usize()
    }

    pub fn new(point: Point<T>) -> Tensor<T, U> {
        Tensor {
            p: point,
            x: GenericArray::new()
        }
    }
}

impl<'a, T, U> Index<&'a [usize]> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = f64;

    fn index(&self, idx: &'a [usize]) -> &f64 {
        &self.x[Self::get_coord(idx)]
    }
}

impl<'a, T, U> IndexMut<&'a [usize]> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn index_mut(&mut self, idx: &'a [usize]) -> &mut f64 {
        &mut self.x[Self::get_coord(idx)]
    }
}

impl<'a, T, U> Index<usize> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = f64;

    fn index(&self, idx: usize) -> &f64 {
        &self.x[idx]
    }
}

impl<'a, T, U> IndexMut<usize> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn index_mut(&mut self, idx: usize) -> &mut f64 {
        &mut self.x[idx]
    }
}

pub type Scalar<T> = Tensor<T, ()>;
pub type Vector<T> = Tensor<T, ContravariantIndex>;
pub type Covector<T> = Tensor<T, CovariantIndex>;
pub type Matrix<T> = Tensor<T, (ContravariantIndex, CovariantIndex)>;

impl<T: CoordinateSystem> Deref for Scalar<T> {
    type Target = f64;

    fn deref(&self) -> &f64 {
        &self.x[0]
    }
}

impl<T: CoordinateSystem> DerefMut for Scalar<T> {
    fn deref_mut(&mut self) -> &mut f64 {
        &mut self.x[0]
    }
}

// Arithmetic operations

impl<T, U> Add<Tensor<T, U>> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn add(mut self, rhs: Tensor<T, U>) -> Tensor<T, U> {
        assert!(self.p == rhs.p);
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] + rhs[i];
        }
        self
    }
}

impl<T, U> Sub<Tensor<T, U>> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn sub(mut self, rhs: Tensor<T, U>) -> Tensor<T, U> {
        assert!(self.p == rhs.p);
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] - rhs[i];
        }
        self
    }
}

impl<T, U> Mul<f64> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn mul(mut self, rhs: f64) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] * rhs;
        }
        self
    }
}

impl<T, U> Mul<Tensor<T, U>> for f64
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn mul(self, mut rhs: Tensor<T, U>) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            rhs[i] = rhs[i] * self;
        }
        rhs
    }
}

impl<T, U> Div<f64> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn div(mut self, rhs: f64) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] / rhs;
        }
        self
    }
}
<commit_msg>Added coordinate iteration for tensors<commit_after>use coordinates::{CoordinateSystem, Point};
use std::ops::{Index, IndexMut};
use std::ops::{Add, Sub, Mul, Div, Deref, DerefMut};
use typenum::uint::Unsigned;
use typenum::Pow;
use generic_array::{GenericArray, ArrayLength};
use super::{CovariantIndex, ContravariantIndex, Variance, IndexType};

/// This is a struct that represents a generic tensor
pub struct Tensor<T: CoordinateSystem, U: Variance>
    where T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    p: Point<T>,
    x: GenericArray<f64, <T::Dimension as Pow<U::Rank>>::Output>
}

impl<T, U> Clone for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn clone(&self) -> Tensor<T, U> {
        Tensor {
            p: self.p.clone(),
            x: self.x.clone()
        }
    }
}

impl<T, U> Copy for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as ArrayLength<f64>>::ArrayType: Copy,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>,
          <<T::Dimension as Pow<U::Rank>>::Output as ArrayLength<f64>>::ArrayType: Copy
{}

pub struct CoordIterator<U>
    where U: Variance,
          U::Rank: ArrayLength<usize>
{
    started: bool,
    dimension: usize,
    cur_coord: GenericArray<usize, U::Rank>
}

impl<U> CoordIterator<U>
    where U: Variance,
          U::Rank: ArrayLength<usize>
{
    pub fn new(dimension: usize) -> CoordIterator<U> {
        CoordIterator {
            started: false,
            dimension: dimension,
            cur_coord: GenericArray::new()
        }
    }
}

impl<U> Iterator for CoordIterator<U>
    where U: Variance,
          U::Rank: ArrayLength<usize>
{
    type Item = GenericArray<usize, U::Rank>;

    fn next(&mut self) -> Option<Self::Item> {
        if !self.started {
            self.started = true;
            return Some(self.cur_coord.clone())
        }

        let mut i = self.cur_coord.len() - 1;
        loop {
            self.cur_coord[i] += 1;
            if self.cur_coord[i] < self.dimension {
                break;
            }
            self.cur_coord[i] = 0;
            if i == 0 {
                return None;
            }
            i -= 1;
        }

        Some(self.cur_coord.clone())
    }
}

impl<T, U> Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    /// Returns the point at which the tensor is defined.
    pub fn get_point(&self) -> &Point<T> {
        &self.p
    }

    /// Converts a set of tensor indices passed as a slice into a single index for the internal array.
    /// The length of the slice (the number of indices) has to be compatible with the rank of the tensor.
    pub fn get_coord(i: &[usize]) -> usize {
        assert_eq!(i.len(), U::rank());
        let dim = T::dimension();
        let index = i.into_iter().fold(0, |res, idx| {
            assert!(*idx < dim);
            res * dim + idx
        });
        index
    }

    /// Returns the variance of the tensor, that is, the list of the index types.
    /// A vector would return vec![Contravariant], a metric tensor: vec![Covariant, Covariant].
    pub fn get_variance() -> Vec<IndexType> {
        U::variance()
    }

    /// Returns the rank of the tensor
    pub fn get_rank() -> usize {
        U::rank()
    }

    /// Returns the number of coordinates of the tensor
    pub fn get_num_coords() -> usize {
        <T::Dimension as Pow<U::Rank>>::Output::to_usize()
    }

    pub fn new(point: Point<T>) -> Tensor<T, U> {
        Tensor {
            p: point,
            x: GenericArray::new()
        }
    }
}

impl<T, U> Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          U::Rank: ArrayLength<usize>,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    pub fn iter_coords(&self) -> CoordIterator<U> {
        CoordIterator::new(T::dimension())
    }
}

impl<'a, T, U> Index<&'a [usize]> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = f64;

    fn index(&self, idx: &'a [usize]) -> &f64 {
        &self.x[Self::get_coord(idx)]
    }
}

impl<'a, T, U> IndexMut<&'a [usize]> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn index_mut(&mut self, idx: &'a [usize]) -> &mut f64 {
        &mut self.x[Self::get_coord(idx)]
    }
}

impl<'a, T, U> Index<usize> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = f64;

    fn index(&self, idx: usize) -> &f64 {
        &self.x[idx]
    }
}

impl<'a, T, U> IndexMut<usize> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    fn index_mut(&mut self, idx: usize) -> &mut f64 {
        &mut self.x[idx]
    }
}

pub type Scalar<T> = Tensor<T, ()>;
pub type Vector<T> = Tensor<T, ContravariantIndex>;
pub type Covector<T> = Tensor<T, CovariantIndex>;
pub type Matrix<T> = Tensor<T, (ContravariantIndex, CovariantIndex)>;

impl<T: CoordinateSystem> Deref for Scalar<T> {
    type Target = f64;

    fn deref(&self) -> &f64 {
        &self.x[0]
    }
}

impl<T: CoordinateSystem> DerefMut for Scalar<T> {
    fn deref_mut(&mut self) -> &mut f64 {
        &mut self.x[0]
    }
}

// Arithmetic operations

impl<T, U> Add<Tensor<T, U>> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn add(mut self, rhs: Tensor<T, U>) -> Tensor<T, U> {
        assert!(self.p == rhs.p);
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] + rhs[i];
        }
        self
    }
}

impl<T, U> Sub<Tensor<T, U>> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn sub(mut self, rhs: Tensor<T, U>) -> Tensor<T, U> {
        assert!(self.p == rhs.p);
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] - rhs[i];
        }
        self
    }
}

impl<T, U> Mul<f64> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn mul(mut self, rhs: f64) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] * rhs;
        }
        self
    }
}

impl<T, U> Mul<Tensor<T, U>> for f64
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn mul(self, mut rhs: Tensor<T, U>) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            rhs[i] = rhs[i] * self;
        }
        rhs
    }
}

impl<T, U> Div<f64> for Tensor<T, U>
    where T: CoordinateSystem,
          U: Variance,
          T::Dimension: Pow<U::Rank>,
          <T::Dimension as Pow<U::Rank>>::Output: ArrayLength<f64>
{
    type Output = Tensor<T, U>;

    fn div(mut self, rhs: f64) -> Tensor<T, U> {
        for i in 0..(Tensor::<T, U>::get_num_coords()) {
            self[i] = self[i] / rhs;
        }
        self
    }
}
<|endoftext|>


<commit_before>
//! **mprovision** is a tool that helps iOS developers to manage mobileprovision
//! files. Main purpose of this crate is to contain functions and types
//! for **mprovision**.

#[cfg(test)]
#[macro_use(expect)]
extern crate expectest;
#[cfg(test)]
extern crate tempdir;
extern crate plist;
extern crate chrono;

use std::fs::{self, DirEntry, File};
use std::path::{Path, PathBuf};
use std::env;
use std::io::{self, Read};
use plist::PlistEvent::*;

pub use error::Error;
pub use profile::Profile;

mod error;
mod profile;

/// A Result type for this crate.
pub type Result<T> = std::result::Result<T, Error>;

/// Returns an iterator over the `*.mobileprovision` entries within a given
/// directory.
///
/// # Errors
/// This function will return an error in the following cases:
///
/// - the user lacks the requisite permissions
/// - there is no entry in the filesystem at the provided path
/// - the provided path is not a directory
pub fn files<P>(path: P) -> Result<Box<Iterator<Item = DirEntry>>>
    where P: AsRef<Path>
{
    let entries = try!(fs::read_dir(&path));
    let filtered = entries.filter_map(|entry| entry.ok())
                          .filter_map(|entry| {
                              if let Some(ext) = entry.path().extension() {
                                  if ext == "mobileprovision" {
                                      return Some(entry);
                                  }
                              }
                              None
                          });
    Ok(Box::new(filtered))
}

/// Returns the path to the directory that contains installed mobile
/// provisioning profiles.
///
/// Should return `~/Library/MobileDevice/Provisioning Profiles` directory.
///
/// # Errors
/// This function will return an error if 'HOME' environment variable is not set
/// or equal to the empty string.
pub fn directory() -> Result<PathBuf> {
    env::home_dir()
        .map(|path| path.join("Library/MobileDevice/Provisioning Profiles"))
        .ok_or(Error::Io(io::Error::new(io::ErrorKind::NotFound, "")))
}

pub fn search<P>(path: Option<P>, s: &str) -> Result<Vec<Result<Profile>>>
    where P: AsRef<Path>
{
    if let Some(path) = path {
        search_dir(path, s)
    } else {
        let path = try!(directory());
        search_dir(path, s)
    }
}

pub fn search_dir<P>(path: P, s: &str) -> Result<Vec<Result<Profile>>>
    where P: AsRef<Path>
{
    let files = try!(files(&path));
    let mut buf = Vec::with_capacity(100 * 1024);
    let results: Vec<_> = files.map(|entry| profile_from_file(entry.path(), &mut buf))
                               .filter(|result| {
                                   if let &Ok(ref profile) = result {
                                       profile.contains(s)
                                   } else {
                                       true
                                   }
                               })
                               .collect();
    Ok(results)
}

/// Returns instance of the `Profile` parsed from a file.
pub fn profile_from_file<P>(path: P, buf: &mut Vec<u8>) -> Result<Profile>
    where P: AsRef<Path>
{
    let mut file = try!(File::open(path.as_ref()));
    buf.clear();
    try!(file.read_to_end(buf));
    profile_from_data(buf).map(|mut p| {
        p.path = path.as_ref().to_owned();
        p
    }).ok_or(Error::Own("Couldn't parse file.".into()))
}

/// Returns instance of the `Profile` parsed from a `data`.
pub fn profile_from_data(data: &[u8]) -> Option<Profile> {
    if let Some(data) = find_plist(data) {
        let mut profile = Profile::empty();
        let mut iter = plist::StreamingParser::new(io::Cursor::new(data)).into_iter();
        while let Some(item) = iter.next() {
            if let Ok(StringValue(key)) = item {
                if key == "UUID" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.uuid = value;
                    }
                }
                if key == "Name" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.name = value;
                    }
                }
                if key == "application-identifier" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.app_identifier = value;
                    }
                }
                if key == "CreationDate" {
                    if let Some(Ok(DateValue(value))) = iter.next() {
                        profile.creation_date = value;
                    }
                }
                if key == "ExpirationDate" {
                    if let Some(Ok(DateValue(value))) = iter.next() {
                        profile.expiration_date = value;
                    }
                }
            }
        }
        Some(profile)
    } else {
        None
    }
}

/// Returns an index where the `needle` starts in the `data`.
fn find(data: &[u8], needle: &[u8]) -> Option<usize> {
    let needle_len = needle.len();
    for (i, _) in data.iter().enumerate() {
        if i + needle_len > data.len() {
            return None;
        }
        if &data[i..i + needle_len] == needle {
            return Some(i);
        }
    }
    None
}

/// Returns a plist content in a `data`.
fn find_plist(data: &[u8]) -> Option<&[u8]> {
    let prefix = b"<?xml version=";
    let suffix = b"</plist>";

    let start_i = find(data, prefix);
    let end_i = find(data, suffix).map(|i| i + suffix.len());

    if let (Some(start_i), Some(end_i)) = (start_i, end_i) {
        if end_i < data.len() {
            return Some(&data[start_i..end_i]);
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use expectest::prelude::*;
    use tempdir::TempDir;
    use std::fs::File;
    use super::files;

    #[test]
    fn filter_mobileprovision_files() {
        let temp_dir = TempDir::new("test").unwrap();
        let result = files(temp_dir.path()).map(|iter| iter.count());
        expect!(result).to(be_ok().value(0));

        File::create(temp_dir.path().join("1.mobileprovision")).unwrap();
        File::create(temp_dir.path().join("2.mobileprovision")).unwrap();
        File::create(temp_dir.path().join("3.txt")).unwrap();
        let result = files(temp_dir.path()).map(|iter| iter.count());
        expect!(result).to(be_ok().value(2));
    }
}
<commit_msg>Read data in local buffer.<commit_after>
//! **mprovision** is a tool that helps iOS developers to manage mobileprovision
//! files. Main purpose of this crate is to contain functions and types
//! for **mprovision**.

#[cfg(test)]
#[macro_use(expect)]
extern crate expectest;
#[cfg(test)]
extern crate tempdir;
extern crate plist;
extern crate chrono;

use std::fs::{self, DirEntry, File};
use std::path::{Path, PathBuf};
use std::env;
use std::io::{self, Read};
use plist::PlistEvent::*;

pub use error::Error;
pub use profile::Profile;

mod error;
mod profile;

/// A Result type for this crate.
pub type Result<T> = std::result::Result<T, Error>;

/// Returns an iterator over the `*.mobileprovision` entries within a given
/// directory.
///
/// # Errors
/// This function will return an error in the following cases:
///
/// - the user lacks the requisite permissions
/// - there is no entry in the filesystem at the provided path
/// - the provided path is not a directory
pub fn files<P>(path: P) -> Result<Box<Iterator<Item = DirEntry>>>
    where P: AsRef<Path>
{
    let entries = try!(fs::read_dir(&path));
    let filtered = entries.filter_map(|entry| entry.ok())
                          .filter_map(|entry| {
                              if let Some(ext) = entry.path().extension() {
                                  if ext == "mobileprovision" {
                                      return Some(entry);
                                  }
                              }
                              None
                          });
    Ok(Box::new(filtered))
}

/// Returns the path to the directory that contains installed mobile
/// provisioning profiles.
///
/// Should return `~/Library/MobileDevice/Provisioning Profiles` directory.
///
/// # Errors
/// This function will return an error if 'HOME' environment variable is not set
/// or equal to the empty string.
pub fn directory() -> Result<PathBuf> {
    env::home_dir()
        .map(|path| path.join("Library/MobileDevice/Provisioning Profiles"))
        .ok_or(Error::Io(io::Error::new(io::ErrorKind::NotFound, "")))
}

pub fn search<P>(path: Option<P>, s: &str) -> Result<Vec<Result<Profile>>>
    where P: AsRef<Path>
{
    if let Some(path) = path {
        search_dir(path, s)
    } else {
        let path = try!(directory());
        search_dir(path, s)
    }
}

pub fn search_dir<P>(path: P, s: &str) -> Result<Vec<Result<Profile>>>
    where P: AsRef<Path>
{
    let files = try!(files(&path));
    let results: Vec<_> = files.map(|entry| profile_from_file(entry.path()))
                               .filter(|result| {
                                   if let &Ok(ref profile) = result {
                                       profile.contains(s)
                                   } else {
                                       true
                                   }
                               })
                               .collect();
    Ok(results)
}

/// Returns instance of the `Profile` parsed from a file.
pub fn profile_from_file<P>(path: P) -> Result<Profile>
    where P: AsRef<Path>
{
    let mut file = try!(File::open(path.as_ref()));
    let mut buf = Vec::new();
    try!(file.read_to_end(&mut buf));
    profile_from_data(&buf).map(|mut p| {
        p.path = path.as_ref().to_owned();
        p
    }).ok_or(Error::Own("Couldn't parse file.".into()))
}

/// Returns instance of the `Profile` parsed from a `data`.
pub fn profile_from_data(data: &[u8]) -> Option<Profile> {
    if let Some(data) = find_plist(data) {
        let mut profile = Profile::empty();
        let mut iter = plist::StreamingParser::new(io::Cursor::new(data)).into_iter();
        while let Some(item) = iter.next() {
            if let Ok(StringValue(key)) = item {
                if key == "UUID" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.uuid = value;
                    }
                }
                if key == "Name" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.name = value;
                    }
                }
                if key == "application-identifier" {
                    if let Some(Ok(StringValue(value))) = iter.next() {
                        profile.app_identifier = value;
                    }
                }
                if key == "CreationDate" {
                    if let Some(Ok(DateValue(value))) = iter.next() {
                        profile.creation_date = value;
                    }
                }
                if key == "ExpirationDate" {
                    if let Some(Ok(DateValue(value))) = iter.next() {
                        profile.expiration_date = value;
                    }
                }
            }
        }
        Some(profile)
    } else {
        None
    }
}

/// Returns an index where the `needle` starts in the `data`.
fn find(data: &[u8], needle: &[u8]) -> Option<usize> {
    let needle_len = needle.len();
    for (i, _) in data.iter().enumerate() {
        if i + needle_len > data.len() {
            return None;
        }
        if &data[i..i + needle_len] == needle {
            return Some(i);
        }
    }
    None
}

/// Returns a plist content in a `data`.
fn find_plist(data: &[u8]) -> Option<&[u8]> {
    let prefix = b"<?xml version=";
    let suffix = b"</plist>";

    let start_i = find(data, prefix);
    let end_i = find(data, suffix).map(|i| i + suffix.len());

    if let (Some(start_i), Some(end_i)) = (start_i, end_i) {
        if end_i < data.len() {
            return Some(&data[start_i..end_i]);
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use expectest::prelude::*;
    use tempdir::TempDir;
    use std::fs::File;
    use super::files;

    #[test]
    fn filter_mobileprovision_files() {
        let temp_dir = TempDir::new("test").unwrap();
        let result = files(temp_dir.path()).map(|iter| iter.count());
        expect!(result).to(be_ok().value(0));

        File::create(temp_dir.path().join("1.mobileprovision")).unwrap();
        File::create(temp_dir.path().join("2.mobileprovision")).unwrap();
        File::create(temp_dir.path().join("3.txt")).unwrap();
        let result = files(temp_dir.path()).map(|iter| iter.count());
        expect!(result).to(be_ok().value(2));
    }
}
<|endoftext|>


<commit_before>use std::slice::Iter;

use Tree;
use Node;
use NodeId;
use tree::IteratorNew;

pub struct Ancestors<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Ancestors<'a, T>> for Ancestors<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Ancestors<'a, T> {
        Ancestors {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for Ancestors<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(current_id) = self.node_id.clone() {

            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {

                let parent = self.tree.get_unsafe(&parent_id);

                self.node_id = Some(parent_id.clone());

                return Some(parent);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

pub struct AncestorIds<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, AncestorIds<'a, T>> for AncestorIds<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> AncestorIds<'a, T> {
        AncestorIds {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for AncestorIds<'a, T> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        if let Some(current_id) = self.node_id.clone() {
            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {
                self.node_id = Some(parent_id.clone());
                return Some(parent_id);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

pub struct Children<'a, T: 'a> {
    tree: &'a Tree<T>,
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Children<'a, T>> for Children<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Children<'a, T> {
        Children {
            tree: tree,
            child_ids: tree.get_unsafe(&node_id).children().as_slice().iter()
        }
    }
}

impl<'a, T> Iterator for Children<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(ref next_child_id) = self.child_ids.next() {
            return Some(self.tree.get_unsafe(next_child_id));
        }
        None
    }
}

pub struct ChildrenIds<'a> {
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, ChildrenIds<'a>> for ChildrenIds<'a> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> ChildrenIds<'a> {
        ChildrenIds {
            child_ids: tree.get_unsafe(&node_id).children().as_slice().iter()
        }
    }
}

impl<'a> Iterator for ChildrenIds<'a> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        self.child_ids.next()
    }
}

#[cfg(test)]
mod tests {

    use Tree;
    use Node;
    use InsertBehavior::*;

    #[test]
    fn test_ancestors() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestors = tree.ancestors(&root_id).unwrap();
        assert_eq!(ancestors.count(), 0);

        let data = [0];
        for (index, node) in tree.ancestors(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_2).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_3).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }
    }

    #[test]
    fn test_ancestor_ids() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestor_ids = tree.ancestor_ids(&root_id).unwrap();
        assert_eq!(ancestor_ids.count(), 0);

        let data = [0];
        for (index, node_id) in tree.ancestor_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_2).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_3).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }
    }

    #[test]
    fn test_children() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node) in tree.children(&root_id).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node) in tree.children(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let children = tree.children(&node_2).unwrap();
        assert_eq!(children.count(), 0);

        let children = tree.children(&node_3).unwrap();
        assert_eq!(children.count(), 0);
    }

    #[test]
    fn test_children_ids() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node_id) in tree.children_ids(&root_id).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node_id) in tree.children_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let children_ids = tree.children_ids(&node_2).unwrap();
        assert_eq!(children_ids.count(), 0);

        let children_ids = tree.children_ids(&node_3).unwrap();
        assert_eq!(children_ids.count(), 0);
    }
}
<commit_msg>run cargo fmt<commit_after>use std::slice::Iter;

use Tree;
use Node;
use NodeId;
use tree::IteratorNew;

pub struct Ancestors<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Ancestors<'a, T>> for Ancestors<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Ancestors<'a, T> {
        Ancestors {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for Ancestors<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(current_id) = self.node_id.clone() {

            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {

                let parent = self.tree.get_unsafe(&parent_id);

                self.node_id = Some(parent_id.clone());

                return Some(parent);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

pub struct AncestorIds<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, AncestorIds<'a, T>> for AncestorIds<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> AncestorIds<'a, T> {
        AncestorIds {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for AncestorIds<'a, T> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        if let Some(current_id) = self.node_id.clone() {
            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {
                self.node_id = Some(parent_id.clone());
                return Some(parent_id);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

pub struct Children<'a, T: 'a> {
    tree: &'a Tree<T>,
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Children<'a, T>> for Children<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Children<'a, T> {
        Children {
            tree: tree,
            child_ids: tree.get_unsafe(&node_id).children().as_slice().iter(),
        }
    }
}

impl<'a, T> Iterator for Children<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(ref next_child_id) = self.child_ids.next() {
            return Some(self.tree.get_unsafe(next_child_id));
        }
        None
    }
}

pub struct ChildrenIds<'a> {
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, ChildrenIds<'a>> for ChildrenIds<'a> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> ChildrenIds<'a> {
        ChildrenIds { child_ids: tree.get_unsafe(&node_id).children().as_slice().iter() }
    }
}

impl<'a> Iterator for ChildrenIds<'a> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        self.child_ids.next()
    }
}

#[cfg(test)]
mod tests {

    use Tree;
    use Node;
    use InsertBehavior::*;

    #[test]
    fn test_ancestors() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestors = tree.ancestors(&root_id).unwrap();
        assert_eq!(ancestors.count(), 0);

        let data = [0];
        for (index, node) in tree.ancestors(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_2).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_3).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }
    }

    #[test]
    fn test_ancestor_ids() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestor_ids = tree.ancestor_ids(&root_id).unwrap();
        assert_eq!(ancestor_ids.count(), 0);

        let data = [0];
        for (index, node_id) in tree.ancestor_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_2).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_3).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }
    }

    #[test]
    fn test_children() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node) in tree.children(&root_id).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node) in tree.children(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let children = tree.children(&node_2).unwrap();
        assert_eq!(children.count(), 0);

        let children = tree.children(&node_3).unwrap();
        assert_eq!(children.count(), 0);
    }

    #[test]
    fn test_children_ids() {

        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node_id) in tree.children_ids(&root_id).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node_id) in tree.children_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let children_ids = tree.children_ids(&node_2).unwrap();
        assert_eq!(children_ids.count(), 0);

        let children_ids = tree.children_ids(&node_3).unwrap();
        assert_eq!(children_ids.count(), 0);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;

extern crate rex;

mod util;

use std::path::Path;

use rex::frontend::{Event, KeyPress};

use util::mock_filesystem::MockFilesystem;

// Little helper function till Iterator.eq stabalizes
fn iter_eq<I, J>(one: I, other: J) -> bool where
    I: IntoIterator,
    J: IntoIterator,
    I::Item: PartialEq<J::Item>,
{
    let mut one = one.into_iter();
    let mut other = other.into_iter();

    loop {
        match (one.next(), other.next()) {
            (None, None) => return true,
            (None, _) | (_, None) => return false,
            (Some(x), Some(y)) => if x != y { return false },
        }
    }
}

#[test]
fn test_basic_open() {
    // Create a vec with a marker in the end
    let mut v = vec![0; 1000];
    let len = v.len();
    v[len-1] = 0xAA;

    let (mut edit, mut frontend) = util::simple_init_empty();
    let pedit = &mut edit;

    MockFilesystem::put("test_basic_open", v);

    // Open file with the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('o')]);
    frontend.run_str(pedit, "test_basic_open");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Find the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('f')]);
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('h')]);
    frontend.run_str(pedit, "AA");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // And make sure it is in the right place
    assert_eq!(pedit.get_position(), (len-1) as isize);

    // Make sure the opened file name is correct
    let name = Path::new("test_basic_open");
    assert_eq!(name, pedit.get_file_path().unwrap());
}

#[test]
fn test_basic_save() {
    // Create a view over a generic vector
    let v = util::generate_vec(1000);
    let (mut edit, mut frontend) = util::simple_init_with_vec(v.clone());
    let pedit = &mut edit;

    // Save it to a file
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('s')]);
    frontend.run_str(pedit, "test_basic_save");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Make sure they are equal
    assert!(iter_eq(v.iter(), MockFilesystem::get_inner("test_basic_save").iter()));
}
<commit_msg>Change order of tests<commit_after>#[macro_use]
extern crate lazy_static;

extern crate rex;

mod util;

use std::path::Path;

use rex::frontend::{Event, KeyPress};

use util::mock_filesystem::MockFilesystem;

// Little helper function till Iterator.eq stabalizes
fn iter_eq<I, J>(one: I, other: J) -> bool where
    I: IntoIterator,
    J: IntoIterator,
    I::Item: PartialEq<J::Item>,
{
    let mut one = one.into_iter();
    let mut other = other.into_iter();

    loop {
        match (one.next(), other.next()) {
            (None, None) => return true,
            (None, _) | (_, None) => return false,
            (Some(x), Some(y)) => if x != y { return false },
        }
    }
}

#[test]
fn test_basic_open() {
    // Create a vec with a marker in the end
    let mut v = vec![0; 1000];
    let len = v.len();
    v[len-1] = 0xAA;

    let (mut edit, mut frontend) = util::simple_init_empty();
    let pedit = &mut edit;

    MockFilesystem::put("test_basic_open", v);

    // Open file with the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('o')]);
    frontend.run_str(pedit, "test_basic_open");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Find the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('f')]);
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('h')]);
    frontend.run_str(pedit, "AA");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Make sure the opened file name is correct
    let name = Path::new("test_basic_open");
    assert_eq!(name, pedit.get_file_path().unwrap());

    // And make sure it is in the right place
    assert_eq!(pedit.get_position(), (len-1) as isize);
}

#[test]
fn test_basic_save() {
    // Create a view over a generic vector
    let v = util::generate_vec(1000);
    let (mut edit, mut frontend) = util::simple_init_with_vec(v.clone());
    let pedit = &mut edit;

    // Save it to a file
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('s')]);
    frontend.run_str(pedit, "test_basic_save");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Make sure they are equal
    assert!(iter_eq(v.iter(), MockFilesystem::get_inner("test_basic_save").iter()));
}
<|endoftext|>


<commit_before>/*!
 * Communication between tasks
 *
 * Communication between tasks is facilitated by ports (in the receiving
 * task), and channels (in the sending task). Any number of channels may
 * feed into a single port.  Ports and channels may only transmit values
 * of unique types; that is, values that are statically guaranteed to be
 * accessed by a single 'owner' at a time.  Unique types include scalars,
 * vectors, strings, and records, tags, tuples and unique boxes (`~T`)
 * thereof. Most notably, shared boxes (`@T`) may not be transmitted
 * across channels.
 *
 * # Example
 *
 * ~~~
 * let po = comm::port();
 * let ch = comm::chan(po);
 *
 * do task::spawn {
 *     comm::send(ch, "Hello, World");
 * }
 *
 * io::println(comm::recv(p));
 * ~~~
 */

import either::either;
import libc::size_t;

export port;
export chan;
export send;
export recv;
export peek;
export recv_chan;
export select2;
export methods;
export listen;

/**
 * A communication endpoint that can receive messages
 *
 * Each port has a unique per-task identity and may not be replicated or
 * transmitted. If a port value is copied, both copies refer to the same
 * port.  Ports may be associated with multiple `chan`s.
 */
enum port<T: send> {
    port_t(@port_ptr<T>)
}

// It's critical that this only have one variant, so it has a record
// layout, and will work in the rust_task structure in task.rs.
/**
 * A communication endpoint that can send messages
 *
 * Each channel is bound to a port when the channel is constructed, so
 * the destination port for a channel must exist before the channel
 * itself.  Channels are weak: a channel does not keep the port it is
 * bound to alive. If a channel attempts to send data to a dead port that
 * data will be silently dropped.  Channels may be duplicated and
 * themselves transmitted over other channels.
 */
enum chan<T: send> {
    chan_t(port_id)
}

/// Constructs a port
fn port<T: send>() -> port<T> {
    port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
}

impl methods<T: send> for port<T> {

    fn chan() -> chan<T> { chan(self) }
    fn send(+v: T) { self.chan().send(v) }
    fn recv() -> T { recv(self) }
    fn peek() -> bool { peek(self) }

}

impl methods<T: send> for chan<T> {

    fn chan() -> chan<T> { self }
    fn send(+v: T) { send(self, v) }
    fn recv() -> T { recv_chan(self) }
    fn peek() -> bool { peek_chan(self) }

}

/// Open a new receiving channel for the duration of a function
fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
    let po = port();
    f(po.chan())
}

class port_ptr<T:send> {
  let po: *rust_port;
  new(po: *rust_port) { self.po = po; }
  drop unsafe {
      do task::unkillable {
        // Once the port is detached it's guaranteed not to receive further
        // messages
        let yield = 0u;
        let yieldp = ptr::addr_of(yield);
        rustrt::rust_port_begin_detach(self.po, yieldp);
        if yield != 0u {
            // Need to wait for the port to be detached
            task::yield();
        }
        rustrt::rust_port_end_detach(self.po);

        // Drain the port so that all the still-enqueued items get dropped
        while rustrt::rust_port_size(self.po) > 0u as size_t {
            recv_::<T>(self.po);
        }
        rustrt::del_port(self.po);
    }
  }
}

/**
 * Internal function for converting from a channel to a port
 *
 * # Failure
 *
 * Fails if the port is detached or dead. Fails if the port
 * is owned by a different task.
 */
fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {

    class portref {
       let p: *rust_port;
       new(p: *rust_port) { self.p = p; }
       drop {
         if !ptr::is_null(self.p) {
           rustrt::rust_port_drop(self.p);
         }
       }
    }

    let p = portref(rustrt::rust_port_take(*ch));

    if ptr::is_null(p.p) {
        fail ~"unable to locate port for channel"
    } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
        fail ~"unable to access unowned port"
    }

    f(p.p)
}

/**
 * Constructs a channel. The channel is bound to the port used to
 * construct it.
 */
fn chan<T: send>(p: port<T>) -> chan<T> {
    chan_t(rustrt::get_port_id((**p).po))
}

/**
 * Sends data over a channel. The sent data is moved into the channel,
 * whereupon the caller loses access to it.
 */
fn send<T: send>(ch: chan<T>, -data: T) {
    let chan_t(p) = ch;
    let data_ptr = ptr::addr_of(data) as *();
    let res = rustrt::rust_port_id_send(p, data_ptr);
    if res != 0u unsafe {
        // Data sent successfully
        unsafe::forget(data);
    }
    task::yield();
}

/**
 * Receive from a port.  If no data is available on the port then the
 * task will block until data becomes available.
 */
fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }

/// Returns true if there are messages available
fn peek<T: send>(p: port<T>) -> bool { peek_((**p).po) }

#[doc(hidden)]
fn recv_chan<T: send>(ch: comm::chan<T>) -> T {
    as_raw_port(ch, |x|recv_(x))
}

fn peek_chan<T: send>(ch: comm::chan<T>) -> bool {
    as_raw_port(ch, |x|peek_(x))
}

/// Receive on a raw port pointer
fn recv_<T: send>(p: *rust_port) -> T {
    let yield = 0u;
    let yieldp = ptr::addr_of(yield);
    let mut res;
    res = rusti::init::<T>();
    rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);

    if yield != 0u {
        // Data isn't available yet, so res has not been initialized.
        task::yield();
    } else {
        // In the absence of compiler-generated preemption points
        // this is a good place to yield
        task::yield();
    }
    ret res;
}

fn peek_(p: *rust_port) -> bool {
    rustrt::rust_port_size(p) != 0u as libc::size_t
}

/// Receive on one of two ports
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
    -> either<A, B> {
    let ports = ~[(**p_a).po, (**p_b).po];
    let n_ports = 2 as libc::size_t;
    let yield = 0u, yieldp = ptr::addr_of(yield);

    let mut resport: *rust_port;
    resport = rusti::init::<*rust_port>();
    do vec::as_buf(ports) |ports| {
        rustrt::rust_port_select(ptr::addr_of(resport), ports, n_ports,
                                 yieldp);
    }

    if yield != 0u {
        // Wait for data
        task::yield();
    } else {
        // As in recv, this is a good place to yield anyway until
        // the compiler generates yield calls
        task::yield();
    }

    // Now we know the port we're supposed to receive from
    assert resport != ptr::null();

    if resport == (**p_a).po {
        either::left(recv(p_a))
    } else if resport == (**p_b).po {
        either::right(recv(p_b))
    } else {
        fail ~"unexpected result from rust_port_select";
    }
}

/* Implementation details */

enum rust_port {}

type port_id = int;

#[abi = "cdecl"]
extern mod rustrt {
    fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t;

    fn new_port(unit_sz: libc::size_t) -> *rust_port;
    fn del_port(po: *rust_port);
    fn rust_port_begin_detach(po: *rust_port,
                              yield: *libc::uintptr_t);
    fn rust_port_end_detach(po: *rust_port);
    fn get_port_id(po: *rust_port) -> port_id;
    fn rust_port_size(po: *rust_port) -> libc::size_t;
    fn port_recv(dptr: *uint, po: *rust_port,
                 yield: *libc::uintptr_t);
    fn rust_port_select(dptr: **rust_port, ports: **rust_port,
                        n_ports: libc::size_t,
                        yield: *libc::uintptr_t);
    fn rust_port_take(port_id: port_id) -> *rust_port;
    fn rust_port_drop(p: *rust_port);
    fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
    fn get_task_id() -> libc::uintptr_t;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn init<T>() -> T;
}

/* Tests */

#[test]
fn create_port_and_chan() { let p = port::<int>(); chan(p); }

#[test]
fn send_int() {
    let p = port::<int>();
    let c = chan(p);
    send(c, 22);
}

#[test]
fn send_recv_fn() {
    let p = port::<int>();
    let c = chan::<int>(p);
    send(c, 42);
    assert (recv(p) == 42);
}

#[test]
fn send_recv_fn_infer() {
    let p = port();
    let c = chan(p);
    send(c, 42);
    assert (recv(p) == 42);
}

#[test]
fn chan_chan_infer() {
    let p = port(), p2 = port::<int>();
    let c = chan(p);
    send(c, chan(p2));
    recv(p);
}

#[test]
fn chan_chan() {
    let p = port::<chan<int>>(), p2 = port::<int>();
    let c = chan(p);
    send(c, chan(p2));
    recv(p);
}

#[test]
fn test_peek() {
    let po = port();
    let ch = chan(po);
    assert !peek(po);
    send(ch, ());
    assert peek(po);
    recv(po);
    assert !peek(po);
}

#[test]
fn test_select2_available() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    send(ch_a, ~"a");

    assert select2(po_a, po_b) == either::left(~"a");

    send(ch_b, ~"b");

    assert select2(po_a, po_b) == either::right(~"b");
}

#[test]
fn test_select2_rendezvous() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    for iter::repeat(10u) {
        do task::spawn {
            for iter::repeat(10u) { task::yield() }
            send(ch_a, ~"a");
        };

        assert select2(po_a, po_b) == either::left(~"a");

        do task::spawn {
            for iter::repeat(10u) { task::yield() }
            send(ch_b, ~"b");
        };

        assert select2(po_a, po_b) == either::right(~"b");
    }
}

#[test]
fn test_select2_stress() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    let msgs = 100u;
    let times = 4u;

    for iter::repeat(times) {
        do task::spawn {
            for iter::repeat(msgs) {
                send(ch_a, ~"a")
            }
        };
        do task::spawn {
            for iter::repeat(msgs) {
                send(ch_b, ~"b")
            }
        };
    }

    let mut as = 0;
    let mut bs = 0;
    for iter::repeat(msgs * times * 2u) {
        alt check select2(po_a, po_b) {
          either::left(~"a") { as += 1 }
          either::right(~"b") { bs += 1 }
        }
    }

    assert as == 400;
    assert bs == 400;
}

#[test]
fn test_recv_chan() {
    let po = port();
    let ch = chan(po);
    send(ch, ~"flower");
    assert recv_chan(ch) == ~"flower";
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_recv_chan_dead() {
    let ch = chan(port());
    send(ch, ~"flower");
    recv_chan(ch);
}

#[test]
#[ignore(cfg(windows))]
fn test_recv_chan_wrong_task() {
    let po = port();
    let ch = chan(po);
    send(ch, ~"flower");
    assert result::is_err(task::try(||
        recv_chan(ch)
    ))
}

#[test]
fn test_port_send() {
    let po = port();
    po.send(());
    po.recv();
}

#[test]
fn test_chan_peek() {
    let po = port();
    let ch = po.chan();
    ch.send(());
    assert ch.peek();
}

#[test]
fn test_listen() {
    do listen |parent| {
        do task::spawn {
            parent.send(~"oatmeal-salad");
        }
        assert parent.recv() == ~"oatmeal-salad";
    }
}

#[test]
#[ignore(cfg(windows))]
fn test_port_detach_fail() {
    for iter::repeat(100u) {
        do task::spawn_unlinked {
            let po = port();
            let ch = po.chan();

            do task::spawn {
                fail;
            }

            do task::spawn {
                ch.send(());
            }
        }
    }
}
<commit_msg>call task::yield in comm::peek<commit_after>/*!
 * Communication between tasks
 *
 * Communication between tasks is facilitated by ports (in the receiving
 * task), and channels (in the sending task). Any number of channels may
 * feed into a single port.  Ports and channels may only transmit values
 * of unique types; that is, values that are statically guaranteed to be
 * accessed by a single 'owner' at a time.  Unique types include scalars,
 * vectors, strings, and records, tags, tuples and unique boxes (`~T`)
 * thereof. Most notably, shared boxes (`@T`) may not be transmitted
 * across channels.
 *
 * # Example
 *
 * ~~~
 * let po = comm::port();
 * let ch = comm::chan(po);
 *
 * do task::spawn {
 *     comm::send(ch, "Hello, World");
 * }
 *
 * io::println(comm::recv(p));
 * ~~~
 */

import either::either;
import libc::size_t;

export port;
export chan;
export send;
export recv;
export peek;
export recv_chan;
export select2;
export methods;
export listen;

/**
 * A communication endpoint that can receive messages
 *
 * Each port has a unique per-task identity and may not be replicated or
 * transmitted. If a port value is copied, both copies refer to the same
 * port.  Ports may be associated with multiple `chan`s.
 */
enum port<T: send> {
    port_t(@port_ptr<T>)
}

// It's critical that this only have one variant, so it has a record
// layout, and will work in the rust_task structure in task.rs.
/**
 * A communication endpoint that can send messages
 *
 * Each channel is bound to a port when the channel is constructed, so
 * the destination port for a channel must exist before the channel
 * itself.  Channels are weak: a channel does not keep the port it is
 * bound to alive. If a channel attempts to send data to a dead port that
 * data will be silently dropped.  Channels may be duplicated and
 * themselves transmitted over other channels.
 */
enum chan<T: send> {
    chan_t(port_id)
}

/// Constructs a port
fn port<T: send>() -> port<T> {
    port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
}

impl methods<T: send> for port<T> {

    fn chan() -> chan<T> { chan(self) }
    fn send(+v: T) { self.chan().send(v) }
    fn recv() -> T { recv(self) }
    fn peek() -> bool { peek(self) }

}

impl methods<T: send> for chan<T> {

    fn chan() -> chan<T> { self }
    fn send(+v: T) { send(self, v) }
    fn recv() -> T { recv_chan(self) }
    fn peek() -> bool { peek_chan(self) }

}

/// Open a new receiving channel for the duration of a function
fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
    let po = port();
    f(po.chan())
}

class port_ptr<T:send> {
  let po: *rust_port;
  new(po: *rust_port) { self.po = po; }
  drop unsafe {
      do task::unkillable {
        // Once the port is detached it's guaranteed not to receive further
        // messages
        let yield = 0u;
        let yieldp = ptr::addr_of(yield);
        rustrt::rust_port_begin_detach(self.po, yieldp);
        if yield != 0u {
            // Need to wait for the port to be detached
            task::yield();
        }
        rustrt::rust_port_end_detach(self.po);

        // Drain the port so that all the still-enqueued items get dropped
        while rustrt::rust_port_size(self.po) > 0u as size_t {
            recv_::<T>(self.po);
        }
        rustrt::del_port(self.po);
    }
  }
}

/**
 * Internal function for converting from a channel to a port
 *
 * # Failure
 *
 * Fails if the port is detached or dead. Fails if the port
 * is owned by a different task.
 */
fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {

    class portref {
       let p: *rust_port;
       new(p: *rust_port) { self.p = p; }
       drop {
         if !ptr::is_null(self.p) {
           rustrt::rust_port_drop(self.p);
         }
       }
    }

    let p = portref(rustrt::rust_port_take(*ch));

    if ptr::is_null(p.p) {
        fail ~"unable to locate port for channel"
    } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
        fail ~"unable to access unowned port"
    }

    f(p.p)
}

/**
 * Constructs a channel. The channel is bound to the port used to
 * construct it.
 */
fn chan<T: send>(p: port<T>) -> chan<T> {
    chan_t(rustrt::get_port_id((**p).po))
}

/**
 * Sends data over a channel. The sent data is moved into the channel,
 * whereupon the caller loses access to it.
 */
fn send<T: send>(ch: chan<T>, -data: T) {
    let chan_t(p) = ch;
    let data_ptr = ptr::addr_of(data) as *();
    let res = rustrt::rust_port_id_send(p, data_ptr);
    if res != 0u unsafe {
        // Data sent successfully
        unsafe::forget(data);
    }
    task::yield();
}

/**
 * Receive from a port.  If no data is available on the port then the
 * task will block until data becomes available.
 */
fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }

/// Returns true if there are messages available
fn peek<T: send>(p: port<T>) -> bool { peek_((**p).po) }

#[doc(hidden)]
fn recv_chan<T: send>(ch: comm::chan<T>) -> T {
    as_raw_port(ch, |x|recv_(x))
}

fn peek_chan<T: send>(ch: comm::chan<T>) -> bool {
    as_raw_port(ch, |x|peek_(x))
}

/// Receive on a raw port pointer
fn recv_<T: send>(p: *rust_port) -> T {
    let yield = 0u;
    let yieldp = ptr::addr_of(yield);
    let mut res;
    res = rusti::init::<T>();
    rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);

    if yield != 0u {
        // Data isn't available yet, so res has not been initialized.
        task::yield();
    } else {
        // In the absence of compiler-generated preemption points
        // this is a good place to yield
        task::yield();
    }
    ret res;
}

fn peek_(p: *rust_port) -> bool {
    // Yield here before we check to see if someone sent us a message
    // FIXME #524, if the compilergenerates yields, we don't need this
    task::yield();
    rustrt::rust_port_size(p) != 0u as libc::size_t
}

/// Receive on one of two ports
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
    -> either<A, B> {
    let ports = ~[(**p_a).po, (**p_b).po];
    let n_ports = 2 as libc::size_t;
    let yield = 0u, yieldp = ptr::addr_of(yield);

    let mut resport: *rust_port;
    resport = rusti::init::<*rust_port>();
    do vec::as_buf(ports) |ports| {
        rustrt::rust_port_select(ptr::addr_of(resport), ports, n_ports,
                                 yieldp);
    }

    if yield != 0u {
        // Wait for data
        task::yield();
    } else {
        // As in recv, this is a good place to yield anyway until
        // the compiler generates yield calls
        task::yield();
    }

    // Now we know the port we're supposed to receive from
    assert resport != ptr::null();

    if resport == (**p_a).po {
        either::left(recv(p_a))
    } else if resport == (**p_b).po {
        either::right(recv(p_b))
    } else {
        fail ~"unexpected result from rust_port_select";
    }
}

/* Implementation details */

enum rust_port {}

type port_id = int;

#[abi = "cdecl"]
extern mod rustrt {
    fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t;

    fn new_port(unit_sz: libc::size_t) -> *rust_port;
    fn del_port(po: *rust_port);
    fn rust_port_begin_detach(po: *rust_port,
                              yield: *libc::uintptr_t);
    fn rust_port_end_detach(po: *rust_port);
    fn get_port_id(po: *rust_port) -> port_id;
    fn rust_port_size(po: *rust_port) -> libc::size_t;
    fn port_recv(dptr: *uint, po: *rust_port,
                 yield: *libc::uintptr_t);
    fn rust_port_select(dptr: **rust_port, ports: **rust_port,
                        n_ports: libc::size_t,
                        yield: *libc::uintptr_t);
    fn rust_port_take(port_id: port_id) -> *rust_port;
    fn rust_port_drop(p: *rust_port);
    fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
    fn get_task_id() -> libc::uintptr_t;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn init<T>() -> T;
}

/* Tests */

#[test]
fn create_port_and_chan() { let p = port::<int>(); chan(p); }

#[test]
fn send_int() {
    let p = port::<int>();
    let c = chan(p);
    send(c, 22);
}

#[test]
fn send_recv_fn() {
    let p = port::<int>();
    let c = chan::<int>(p);
    send(c, 42);
    assert (recv(p) == 42);
}

#[test]
fn send_recv_fn_infer() {
    let p = port();
    let c = chan(p);
    send(c, 42);
    assert (recv(p) == 42);
}

#[test]
fn chan_chan_infer() {
    let p = port(), p2 = port::<int>();
    let c = chan(p);
    send(c, chan(p2));
    recv(p);
}

#[test]
fn chan_chan() {
    let p = port::<chan<int>>(), p2 = port::<int>();
    let c = chan(p);
    send(c, chan(p2));
    recv(p);
}

#[test]
fn test_peek() {
    let po = port();
    let ch = chan(po);
    assert !peek(po);
    send(ch, ());
    assert peek(po);
    recv(po);
    assert !peek(po);
}

#[test]
fn test_select2_available() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    send(ch_a, ~"a");

    assert select2(po_a, po_b) == either::left(~"a");

    send(ch_b, ~"b");

    assert select2(po_a, po_b) == either::right(~"b");
}

#[test]
fn test_select2_rendezvous() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    for iter::repeat(10u) {
        do task::spawn {
            for iter::repeat(10u) { task::yield() }
            send(ch_a, ~"a");
        };

        assert select2(po_a, po_b) == either::left(~"a");

        do task::spawn {
            for iter::repeat(10u) { task::yield() }
            send(ch_b, ~"b");
        };

        assert select2(po_a, po_b) == either::right(~"b");
    }
}

#[test]
fn test_select2_stress() {
    let po_a = port();
    let po_b = port();
    let ch_a = chan(po_a);
    let ch_b = chan(po_b);

    let msgs = 100u;
    let times = 4u;

    for iter::repeat(times) {
        do task::spawn {
            for iter::repeat(msgs) {
                send(ch_a, ~"a")
            }
        };
        do task::spawn {
            for iter::repeat(msgs) {
                send(ch_b, ~"b")
            }
        };
    }

    let mut as = 0;
    let mut bs = 0;
    for iter::repeat(msgs * times * 2u) {
        alt check select2(po_a, po_b) {
          either::left(~"a") { as += 1 }
          either::right(~"b") { bs += 1 }
        }
    }

    assert as == 400;
    assert bs == 400;
}

#[test]
fn test_recv_chan() {
    let po = port();
    let ch = chan(po);
    send(ch, ~"flower");
    assert recv_chan(ch) == ~"flower";
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_recv_chan_dead() {
    let ch = chan(port());
    send(ch, ~"flower");
    recv_chan(ch);
}

#[test]
#[ignore(cfg(windows))]
fn test_recv_chan_wrong_task() {
    let po = port();
    let ch = chan(po);
    send(ch, ~"flower");
    assert result::is_err(task::try(||
        recv_chan(ch)
    ))
}

#[test]
fn test_port_send() {
    let po = port();
    po.send(());
    po.recv();
}

#[test]
fn test_chan_peek() {
    let po = port();
    let ch = po.chan();
    ch.send(());
    assert ch.peek();
}

#[test]
fn test_listen() {
    do listen |parent| {
        do task::spawn {
            parent.send(~"oatmeal-salad");
        }
        assert parent.recv() == ~"oatmeal-salad";
    }
}

#[test]
#[ignore(cfg(windows))]
fn test_port_detach_fail() {
    for iter::repeat(100u) {
        do task::spawn_unlinked {
            let po = port();
            let ch = po.chan();

            do task::spawn {
                fail;
            }

            do task::spawn {
                ch.send(());
            }
        }
    }
}
<|endoftext|>


<commit_before>use bindings::*;
use compile::Compile;
use function::ABI;
use libc::c_uint;
use std::kinds::marker::{
    ContravariantLifetime,
    Managed
};
use std::str::raw::from_c_str;
use std::c_str::ToCStr;
use util::NativeRef;
/// The types that a value can be
bitflags!(
    flags TypeKind: i32 {
        static Invalid      = -1,
        static Void         = 0,
        static SByte        = 1,
        static UByte        = 2,
        static Short        = 3,
        static UShort       = 4,
        static Int          = 5,
        static UInt         = 6,
        static NInt         = 7,
        static NUInt        = 8,
        static Long         = 9,
        static ULong        = 10,
        static Float32      = 11,
        static Float64      = 12,
        static NFloat       = 13,
        static MaxPrimitive = 13,
        static Struct       = 14,
        static Union        = 15,
        static Signature    = 16,
        static Pointer      = 17,
        static FirstTagged  = 32,
        static SysBool      = 10009,
        static SysChar      = 10010
    }
)
/// A single field of a struct
pub struct Field<'a> {
    /// The index of the field
    pub index: c_uint,
    _type: jit_type_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> Field<'a> {
    #[inline]
    /// Get the field's name or none if it lacks one
    pub fn get_name(&self) -> Option<String> {
        unsafe {
            let c_name = jit_type_get_name(self._type, self.index);
            if c_name.is_null() {
                None
            } else {
                Some(from_c_str(c_name))
            }
        }
    }
    #[inline]
    /// Get the type of the field
    pub fn get_type(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_get_field(self._type, self.index))
        }
    }
    #[inline]
    /// Get the offset of the field
    pub fn get_offset(&self) -> uint {
        unsafe {
            jit_type_get_offset(self._type, self.index) as uint
        }
    }
}
/// A type field iterator
pub struct Fields<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Fields<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Fields<'a> {
        unsafe {
            Fields {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_fields(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Field<'a>> for Fields<'a> {
    fn next(&mut self) -> Option<Field<'a>> {
        let index = self.index;
        self.index += 1;
        if index < self.length {
            Some(Field {
                _type: self._type.clone(),
                index: index,
                marker: ContravariantLifetime::<'a>
            })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
    #[inline]
    fn count(&mut self) -> uint {
        let count = self.length - self.index;
        self.index = self.length;
        count as uint
    }
    #[inline]
    fn nth(&mut self, n:uint) -> Option<Field<'a>> {
        self.index += n as u32;
        self.next()
    }
}
pub struct Params<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Params<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Params<'a> {
        unsafe {
            Params {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_params(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Type> for Params<'a> {
    fn next(&mut self) -> Option<Type> {
        let index = self.index;
        self.index += 1;
        if index < self.length {
            Some(unsafe {
                NativeRef::from_ptr(jit_type_get_param(self._type, index))
            })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
    #[inline]
    fn count(&mut self) -> uint {
        let count = self.length - self.index;
        self.index = self.length;
        count as uint
    }
    #[inline]
    fn nth(&mut self, n:uint) -> Option<Type> {
        self.index += n as u32;
        self.next()
    }
}
/**
 * An object that represents a native system type.
 *
 * Each `Type` represents a basic system type,
 * be it a primitive, a struct, a union, a pointer, or a function signature.
 * The library uses this information to lay out values in memory.
*/
#[deriving(PartialEq)]
pub struct Type {
    _type: jit_type_t,
    marker: Managed
}
impl NativeRef for Type {
    #[inline]
    unsafe fn as_ptr(&self) -> jit_type_t {
        self._type
    }
    #[inline]
    unsafe fn from_ptr(ptr:jit_type_t) -> Type {
        Type {
            _type: ptr,
            marker: Managed
        }
    }
}
impl Clone for Type {
    #[inline]
    /// Make a copy of the type descriptor by increasing its reference count.
    fn clone(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_copy(self.as_ptr()))
        }
    }
}
#[unsafe_destructor]
impl Drop for Type {
    #[inline]
    /**
     * Free a type descriptor by decreasing its reference count.
     *
     * This function is save to use on pre-defined types, which
     * are never actually freed.
     */
    fn drop(&mut self) {
        unsafe {
            jit_type_free(self.as_ptr());
        }
    }
}
impl Type {
    /// Create a type descriptor for a function signature.
    pub fn create_signature(abi: ABI, return_type: Type, params: &mut [Type]) -> Type {
        unsafe {
            let mut native_params:Vec<jit_type_t> = params.iter().map(|param| param.as_ptr()).collect();
            let signature = jit_type_create_signature(abi as jit_abi_t, return_type.as_ptr(), native_params.as_mut_ptr(), params.len() as c_uint, 1);
            NativeRef::from_ptr(signature)
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a structure.
    pub fn create_struct(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            NativeRef::from_ptr(jit_type_create_struct(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a union.
    pub fn create_union(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            NativeRef::from_ptr(jit_type_create_union(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a pointer to another type.
    pub fn create_pointer(pointee: Type) -> Type {
        unsafe {
            let ptr = jit_type_create_pointer(pointee.as_ptr(), 1);
            NativeRef::from_ptr(ptr)
        }
    }
    #[inline]
    /// Get the size of this type in bytes.
    pub fn get_size(&self) -> uint {
        unsafe {
            jit_type_get_size(self.as_ptr()) as uint
        }
    }
    /**
     * Get a value that indicates the kind of this type. This allows
     * callers to quickly classify a type to determine how it should
     * be handled further.
     */
    #[inline]
    pub fn get_kind(&self) -> TypeKind {
        unsafe {
            TypeKind::from_bits(jit_type_get_kind(self.as_ptr())).unwrap()
        }
    }
    #[inline]
    /// Get the type that is referred to by this pointer type.
    pub fn get_ref(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_get_ref(self.as_ptr()))
        }
    }
    /// Set the field or parameter names of this type.
    pub fn set_names<T:ToCStr>(&self, names:&[T]) -> bool {
        unsafe {
            let native_names : Vec<*i8> = names.iter().map(|name| name.to_c_str().unwrap()).collect();
            jit_type_set_names(self.as_ptr(), native_names.as_ptr() as *mut *mut i8, names.len() as u32) != 0
        }
    }
    #[inline]
    /// Iterator over the type's fields
    pub fn iter_fields<'a>(&'a self) -> Fields<'a> {
        Fields::new(self.clone())
    }
    #[inline]
    /// Iterator over the function signature's parameters
    pub fn iter_params<'a>(&'a self) -> Params<'a> {
        Params::new(self.clone())
    }
    #[inline]
    /// Find the field/parameter index for a particular name.
    pub fn find_name<T:ToCStr>(&self, name:T) -> uint {
        name.with_c_str(|c_name| unsafe {
            jit_type_find_name(self.as_ptr(), c_name) as uint
        })
    }
}
#[inline]
/// Get the Rust type given as a type descriptor
pub fn get<T:Compile>() -> Type {
    Compile::jit_type(None::<T>)
}<commit_msg>Use `#[inline(always)]` for one-liners<commit_after>use bindings::*;
use compile::Compile;
use function::ABI;
use libc::c_uint;
use std::kinds::marker::{
    ContravariantLifetime,
    Managed
};
use std::str::raw::from_c_str;
use std::c_str::ToCStr;
use util::NativeRef;
/// The types that a value can be
bitflags!(
    flags TypeKind: i32 {
        static Invalid      = -1,
        static Void         = 0,
        static SByte        = 1,
        static UByte        = 2,
        static Short        = 3,
        static UShort       = 4,
        static Int          = 5,
        static UInt         = 6,
        static NInt         = 7,
        static NUInt        = 8,
        static Long         = 9,
        static ULong        = 10,
        static Float32      = 11,
        static Float64      = 12,
        static NFloat       = 13,
        static MaxPrimitive = 13,
        static Struct       = 14,
        static Union        = 15,
        static Signature    = 16,
        static Pointer      = 17,
        static FirstTagged  = 32,
        static SysBool      = 10009,
        static SysChar      = 10010
    }
)
/// A single field of a struct
pub struct Field<'a> {
    /// The index of the field
    pub index: c_uint,
    _type: jit_type_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> Field<'a> {
    #[inline]
    /// Get the field's name or none if it lacks one
    pub fn get_name(&self) -> Option<String> {
        unsafe {
            let c_name = jit_type_get_name(self._type, self.index);
            if c_name.is_null() {
                None
            } else {
                Some(from_c_str(c_name))
            }
        }
    }
    #[inline]
    /// Get the type of the field
    pub fn get_type(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_get_field(self._type, self.index))
        }
    }
    #[inline]
    /// Get the offset of the field
    pub fn get_offset(&self) -> uint {
        unsafe {
            jit_type_get_offset(self._type, self.index) as uint
        }
    }
}
/// A type field iterator
pub struct Fields<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Fields<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Fields<'a> {
        unsafe {
            Fields {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_fields(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Field<'a>> for Fields<'a> {
    fn next(&mut self) -> Option<Field<'a>> {
        let index = self.index;
        self.index += 1;
        if index < self.length {
            Some(Field {
                _type: self._type.clone(),
                index: index,
                marker: ContravariantLifetime::<'a>
            })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
    #[inline]
    fn count(&mut self) -> uint {
        let count = self.length - self.index;
        self.index = self.length;
        count as uint
    }
    #[inline]
    fn nth(&mut self, n:uint) -> Option<Field<'a>> {
        self.index += n as u32;
        self.next()
    }
}
pub struct Params<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Params<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Params<'a> {
        unsafe {
            Params {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_params(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Type> for Params<'a> {
    fn next(&mut self) -> Option<Type> {
        let index = self.index;
        self.index += 1;
        if index < self.length {
            Some(unsafe {
                NativeRef::from_ptr(jit_type_get_param(self._type, index))
            })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
    #[inline]
    fn count(&mut self) -> uint {
        let count = self.length - self.index;
        self.index = self.length;
        count as uint
    }
    #[inline]
    fn nth(&mut self, n:uint) -> Option<Type> {
        self.index += n as u32;
        self.next()
    }
}
/**
 * An object that represents a native system type.
 *
 * Each `Type` represents a basic system type,
 * be it a primitive, a struct, a union, a pointer, or a function signature.
 * The library uses this information to lay out values in memory.
*/
#[deriving(PartialEq)]
pub struct Type {
    _type: jit_type_t,
    marker: Managed
}
impl NativeRef for Type {
    #[inline]
    unsafe fn as_ptr(&self) -> jit_type_t {
        self._type
    }
    #[inline]
    unsafe fn from_ptr(ptr:jit_type_t) -> Type {
        Type {
            _type: ptr,
            marker: Managed
        }
    }
}
impl Clone for Type {
    #[inline]
    /// Make a copy of the type descriptor by increasing its reference count.
    fn clone(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_copy(self.as_ptr()))
        }
    }
}
#[unsafe_destructor]
impl Drop for Type {
    #[inline]
    /**
     * Free a type descriptor by decreasing its reference count.
     *
     * This function is save to use on pre-defined types, which
     * are never actually freed.
     */
    fn drop(&mut self) {
        unsafe {
            jit_type_free(self.as_ptr());
        }
    }
}
impl Type {
    /// Create a type descriptor for a function signature.
    pub fn create_signature(abi: ABI, return_type: Type, params: &mut [Type]) -> Type {
        unsafe {
            let mut native_params:Vec<jit_type_t> = params.iter().map(|param| param.as_ptr()).collect();
            let signature = jit_type_create_signature(abi as jit_abi_t, return_type.as_ptr(), native_params.as_mut_ptr(), params.len() as c_uint, 1);
            NativeRef::from_ptr(signature)
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a structure.
    pub fn create_struct(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            NativeRef::from_ptr(jit_type_create_struct(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a union.
    pub fn create_union(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            NativeRef::from_ptr(jit_type_create_union(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a pointer to another type.
    pub fn create_pointer(pointee: Type) -> Type {
        unsafe {
            let ptr = jit_type_create_pointer(pointee.as_ptr(), 1);
            NativeRef::from_ptr(ptr)
        }
    }
    #[inline]
    /// Get the size of this type in bytes.
    pub fn get_size(&self) -> uint {
        unsafe {
            jit_type_get_size(self.as_ptr()) as uint
        }
    }
    #[inline]
    /**
     * Get a value that indicates the kind of this type. This allows
     * callers to quickly classify a type to determine how it should
     * be handled further.
     */
    pub fn get_kind(&self) -> TypeKind {
        unsafe {
            TypeKind::from_bits(jit_type_get_kind(self.as_ptr())).unwrap()
        }
    }
    #[inline]
    /// Get the type that is referred to by this pointer type.
    pub fn get_ref(&self) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_get_ref(self.as_ptr()))
        }
    }
    /// Set the field or parameter names of this type.
    pub fn set_names<T:ToCStr>(&self, names:&[T]) -> bool {
        unsafe {
            let native_names : Vec<*i8> = names.iter().map(|name| name.to_c_str().unwrap()).collect();
            jit_type_set_names(self.as_ptr(), native_names.as_ptr() as *mut *mut i8, names.len() as u32) != 0
        }
    }
    #[inline(always)]
    /// Iterator over the type's fields
    pub fn iter_fields<'a>(&'a self) -> Fields<'a> {
        Fields::new(self.clone())
    }
    #[inline(always)]
    /// Iterator over the function signature's parameters
    pub fn iter_params<'a>(&'a self) -> Params<'a> {
        Params::new(self.clone())
    }
    #[inline]
    /// Find the field/parameter index for a particular name.
    pub fn find_name<T:ToCStr>(&self, name:T) -> uint {
        name.with_c_str(|c_name| unsafe {
            jit_type_find_name(self.as_ptr(), c_name) as uint
        })
    }
}
#[inline(always)]
/// Get the Rust type given as a type descriptor
pub fn get<T:Compile>() -> Type {
    Compile::jit_type(None::<T>)
}<|endoftext|>