<commit_before><commit_msg>Add simple UtpStream test using only the public API.<commit_after>#![feature(macro_rules)]

extern crate utp;

use std::io::test::next_test_ip4;
use utp::UtpStream;

macro_rules! iotry(
    ($e:expr) => (match $e { Ok(e) => e, Err(e) => panic!("{}", e) })
)

#[test]
fn test_stream_open_and_close() {
    let server_addr = next_test_ip4();
    let mut server = iotry!(UtpStream::bind(server_addr));

    spawn(proc() {
        let mut client = iotry!(UtpStream::connect(server_addr));
        iotry!(client.close());
        drop(client);
    });

    iotry!(server.read_to_end());
    iotry!(server.close());
}
<|endoftext|>


<commit_before><commit_msg>Represent SMTP reply codes by u16<commit_after><|endoftext|>


<commit_before>use std::io;
use std::io::fs::mkdir_recursive;

use csv;
use csv::index::Indexed;
use docopt;

use CliResult;
use config::{Config, Delimiter};
use util;

docopt!(Args deriving Clone, "
Splits the given CSV data into chunks.

The files are written to the directory given with the name '{start}.csv',
where {start} is the index of the first record of the chunk (starting at 0).

Usage:
    xsv split [options] <outdir> [<input>]

split options:
    -s, --size <arg>       The number of records to write into each chunk.
                           [default: 500]
    -j, --jobs <arg>       The number of spliting jobs to run in parallel.
                           This only works when the given CSV data has
                           an index already created. Note that a file handle
                           is opened for each job.
                           [default: 12]

Common options:
    -h, --help             Display this message
    -o, --output <file>    Write output to <file> instead of stdout.
    -n, --no-headers       When set, the first row will NOT be interpreted
                           as column names. Note that this has no effect when
                           concatenating columns.
    -d, --delimiter <arg>  The field delimiter for reading CSV data.
                           Must be a single character. [default: ,]
", arg_input: Option<String>, arg_outdir: String, flag_output: Option<String>,
   flag_delimiter: Delimiter, flag_size: u64, flag_jobs: uint)

pub fn run(argv: &[&str]) -> CliResult<()> {
    let args: Args = try!(util::get_args(argv));
    try!(io| mkdir_recursive(&Path::new(args.arg_outdir[]),
                             io::AllPermissions));

    match try!(args.rconfig().indexed()) {
        Some(idx) => args.parallel_split(idx),
        None => args.sequential_split(),
    }
}

impl Args {
    fn sequential_split(&self) -> CliResult<()> {
        let rconfig = self.rconfig();
        let mut rdr = try!(io| rconfig.reader());
        let headers = try!(csv| rdr.byte_headers());

        let mut wtr = try!(self.new_writer(headers[], 0));
        for (i, row) in rdr.byte_records().enumerate() {
            if i > 0 && i as u64 % self.flag_size == 0 {
                try!(csv| wtr.flush());
                wtr = try!(self.new_writer(headers[], i as u64));
            }
            let row = try!(csv| row);
            try!(csv| wtr.write_bytes(row.into_iter()));
        }
        try!(csv| wtr.flush());
        Ok(())
    }

    fn parallel_split(&self, idx: Indexed<io::File, io::File>)
                     -> CliResult<()> {
        use std::sync::TaskPool;

        let nchunks = util::num_of_chunks(idx.count(), self.flag_size);
        let mut pool = TaskPool::new(self.flag_jobs, || { proc(i) i });
        for i in range(0, nchunks) {
            let args = self.clone();
            pool.execute(proc(_) {
                let conf = args.rconfig();
                let mut idx = conf.indexed().unwrap().unwrap();
                let headers = idx.csv().byte_headers().unwrap();
                let mut wtr = args.new_writer(headers[], i * args.flag_size)
                                  .unwrap();

                idx.seek(i * args.flag_size).unwrap();
                let writenum = args.flag_size as uint;
                for row in idx.csv().byte_records().take(writenum) {
                    let row = row.unwrap();
                    wtr.write_bytes(row.into_iter()).unwrap();
                }
                wtr.flush().unwrap();
            });
        }
        Ok(())
    }

    fn new_writer(&self, headers: &[csv::ByteString], start: u64)
                 -> CliResult<csv::Writer<Box<io::Writer+'static>>> {
        let dir = Path::new(self.arg_outdir.clone());
        let path = dir.join(format!("{}.csv", start));
        let spath = Some(path.display().to_string());
        let mut wtr = try!(io| Config::new(spath).writer());
        if !self.flag_no_headers {
            try!(csv| wtr.write_bytes(headers.iter().map(|f| f[])));
        }
        Ok(wtr)
    }

    fn rconfig(&self) -> Config {
        Config::new(self.arg_input.clone())
               .delimiter(self.flag_delimiter)
               .no_headers(self.flag_no_headers)
    }
}
<commit_msg>Update name change for latest Rust.<commit_after>use std::io;
use std::io::fs::mkdir_recursive;

use csv;
use csv::index::Indexed;
use docopt;

use CliResult;
use config::{Config, Delimiter};
use util;

docopt!(Args deriving Clone, "
Splits the given CSV data into chunks.

The files are written to the directory given with the name '{start}.csv',
where {start} is the index of the first record of the chunk (starting at 0).

Usage:
    xsv split [options] <outdir> [<input>]

split options:
    -s, --size <arg>       The number of records to write into each chunk.
                           [default: 500]
    -j, --jobs <arg>       The number of spliting jobs to run in parallel.
                           This only works when the given CSV data has
                           an index already created. Note that a file handle
                           is opened for each job.
                           [default: 12]

Common options:
    -h, --help             Display this message
    -o, --output <file>    Write output to <file> instead of stdout.
    -n, --no-headers       When set, the first row will NOT be interpreted
                           as column names. Note that this has no effect when
                           concatenating columns.
    -d, --delimiter <arg>  The field delimiter for reading CSV data.
                           Must be a single character. [default: ,]
", arg_input: Option<String>, arg_outdir: String, flag_output: Option<String>,
   flag_delimiter: Delimiter, flag_size: u64, flag_jobs: uint)

pub fn run(argv: &[&str]) -> CliResult<()> {
    let args: Args = try!(util::get_args(argv));
    try!(io| mkdir_recursive(&Path::new(args.arg_outdir[]),
                             io::ALL_PERMISSIONS));

    match try!(args.rconfig().indexed()) {
        Some(idx) => args.parallel_split(idx),
        None => args.sequential_split(),
    }
}

impl Args {
    fn sequential_split(&self) -> CliResult<()> {
        let rconfig = self.rconfig();
        let mut rdr = try!(io| rconfig.reader());
        let headers = try!(csv| rdr.byte_headers());

        let mut wtr = try!(self.new_writer(headers[], 0));
        for (i, row) in rdr.byte_records().enumerate() {
            if i > 0 && i as u64 % self.flag_size == 0 {
                try!(csv| wtr.flush());
                wtr = try!(self.new_writer(headers[], i as u64));
            }
            let row = try!(csv| row);
            try!(csv| wtr.write_bytes(row.into_iter()));
        }
        try!(csv| wtr.flush());
        Ok(())
    }

    fn parallel_split(&self, idx: Indexed<io::File, io::File>)
                     -> CliResult<()> {
        use std::sync::TaskPool;

        let nchunks = util::num_of_chunks(idx.count(), self.flag_size);
        let mut pool = TaskPool::new(self.flag_jobs, || { proc(i) i });
        for i in range(0, nchunks) {
            let args = self.clone();
            pool.execute(proc(_) {
                let conf = args.rconfig();
                let mut idx = conf.indexed().unwrap().unwrap();
                let headers = idx.csv().byte_headers().unwrap();
                let mut wtr = args.new_writer(headers[], i * args.flag_size)
                                  .unwrap();

                idx.seek(i * args.flag_size).unwrap();
                let writenum = args.flag_size as uint;
                for row in idx.csv().byte_records().take(writenum) {
                    let row = row.unwrap();
                    wtr.write_bytes(row.into_iter()).unwrap();
                }
                wtr.flush().unwrap();
            });
        }
        Ok(())
    }

    fn new_writer(&self, headers: &[csv::ByteString], start: u64)
                 -> CliResult<csv::Writer<Box<io::Writer+'static>>> {
        let dir = Path::new(self.arg_outdir.clone());
        let path = dir.join(format!("{}.csv", start));
        let spath = Some(path.display().to_string());
        let mut wtr = try!(io| Config::new(spath).writer());
        if !self.flag_no_headers {
            try!(csv| wtr.write_bytes(headers.iter().map(|f| f[])));
        }
        Ok(wtr)
    }

    fn rconfig(&self) -> Config {
        Config::new(self.arg_input.clone())
               .delimiter(self.flag_delimiter)
               .no_headers(self.flag_no_headers)
    }
}
<|endoftext|>


<commit_before><commit_msg>Create ex4.rs<commit_after>// Make me compile!

fn something() -> Result<i32, std::num::ParseIntError> {
    let x:i32 = "3".parse();
    Ok(x * 4)
}

fn main() {
    match something() {
        Ok(..) => println!("You win!"),
        Err(e) => println!("Oh no something went wrong: {}", e),
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(feature = "unstable")]
use itertools::{ZipTrusted};

use itertools::ZipSlices;

use std::iter::repeat;
use std::cmp;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in xs.iter().zip(&ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipSlices::new(&xs, &ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_checked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let xs = &xs[..];
        let ys = &ys[..];
        let len = cmp::min(xs.len(), ys.len());

        for i in 0..len {
            let x = xs[i];
            let y = ys[i];
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    b.iter(|| {
        let iter = test::black_box(data.iter());
        for (_key, group) in &iter.group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<commit_msg>bench: Update group_by_lazy benches for better black boxing<commit_after>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(feature = "unstable")]
use itertools::{ZipTrusted};

use itertools::ZipSlices;

use std::iter::repeat;
use std::cmp;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in xs.iter().zip(&ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipSlices::new(&xs, &ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_checked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let xs = &xs[..];
        let ys = &ys[..];
        let len = cmp::min(xs.len(), ys.len());

        for i in 0..len {
            let x = xs[i];
            let y = ys[i];
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<|endoftext|>


<commit_before>extern crate std;
use core::prelude::*;
use self::std::io::Error as IoError;
use stack;
use valgrind;

#[cfg(unix)]
#[path = "os/unix.rs"] mod sys;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Stack {
  ptr: *mut u8,
  len: usize,
  valgrind_id: valgrind::stack_id_t
}

pub struct StackSource;

impl stack::StackSource for StackSource {
  type Output = Stack;
  fn get_stack(size: usize) -> Stack {
    Stack::new(size)
  }
}

impl stack::Stack for Stack {
  fn top(&mut self) -> *mut u8 {
    unsafe {
      self.ptr.offset(self.len as isize)
    }
  }

  fn limit(&self) -> *const u8 {
    unsafe {
      self.ptr.offset(sys::page_size() as isize)
    }
  }
}

impl Stack {
  fn new(size: usize) -> Stack {
    let page_size = sys::page_size();

    // round the page size up,
    // using the fact that it is a power of two
    let len = (size + page_size - 1) & !(page_size - 1);

    let stack = unsafe {
      let ptr = match sys::map_stack(size) {
        None => {
          panic!("mmap for stack of size {} failed: {:?}",
                 len, IoError::last_os_error())
        }
        Some(ptr) => ptr
      };

      let valgrind_id =
        valgrind::stack_register(ptr as *const _,
                                 ptr.offset(len as isize) as *const _);

      Stack { ptr: ptr as *mut u8, len: len, valgrind_id: valgrind_id }
    };

    unsafe {
      if !sys::protect_stack(stack.ptr) {
        panic!("mprotect for guard page of stack {:p} failed: {:?}",
               stack.ptr, IoError::last_os_error());
      }
    }

    stack
  }
}

impl Drop for Stack {
  fn drop(&mut self) {
    unsafe {
      valgrind::stack_deregister(self.valgrind_id);
      if !sys::unmap_stack(self.ptr, self.len) {
        panic!("munmap for stack {:p} of size {} failed: {:?}",
               self.ptr, self.len, IoError::last_os_error())
      }
    }
  }
}
<commit_msg>use Display for displaying IoErrors<commit_after>extern crate std;
use core::prelude::*;
use self::std::io::Error as IoError;
use stack;
use valgrind;

#[cfg(unix)]
#[path = "os/unix.rs"] mod sys;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Stack {
  ptr: *mut u8,
  len: usize,
  valgrind_id: valgrind::stack_id_t
}

pub struct StackSource;

impl stack::StackSource for StackSource {
  type Output = Stack;
  fn get_stack(size: usize) -> Stack {
    Stack::new(size)
  }
}

impl stack::Stack for Stack {
  fn top(&mut self) -> *mut u8 {
    unsafe {
      self.ptr.offset(self.len as isize)
    }
  }

  fn limit(&self) -> *const u8 {
    unsafe {
      self.ptr.offset(sys::page_size() as isize)
    }
  }
}

impl Stack {
  fn new(size: usize) -> Stack {
    let page_size = sys::page_size();

    // round the page size up,
    // using the fact that it is a power of two
    let len = (size + page_size - 1) & !(page_size - 1);

    let stack = unsafe {
      let ptr = match sys::map_stack(size) {
        None => {
          panic!("mmap for stack of size {} failed: {}",
                 len, IoError::last_os_error())
        }
        Some(ptr) => ptr
      };

      let valgrind_id =
        valgrind::stack_register(ptr as *const _,
                                 ptr.offset(len as isize) as *const _);

      Stack { ptr: ptr as *mut u8, len: len, valgrind_id: valgrind_id }
    };

    unsafe {
      if !sys::protect_stack(stack.ptr) {
        panic!("mprotect for guard page of stack {:p} failed: {}",
               stack.ptr, IoError::last_os_error());
      }
    }

    stack
  }
}

impl Drop for Stack {
  fn drop(&mut self) {
    unsafe {
      valgrind::stack_deregister(self.valgrind_id);
      if !sys::unmap_stack(self.ptr, self.len) {
        panic!("munmap for stack {:p} of size {} failed: {}",
               self.ptr, self.len, IoError::last_os_error())
      }
    }
  }
}
<|endoftext|>


<commit_before>// Copyright 2016 The Gfx-rs Developers.
//
// 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.

#[macro_use]
extern crate log;
extern crate shared_library;
extern crate gfx_core;
extern crate vk_sys as vk;

use std::{fmt, iter, mem, ptr};
use std::cell::RefCell;
use std::sync::Arc;
use std::ffi::CStr;
use shared_library::dynamic_library::DynamicLibrary;

pub use self::command::{GraphicsQueue, Buffer as CommandBuffer};
pub use self::factory::Factory;

mod command;
pub mod data;
mod factory;
mod native;

struct PhysicalDeviceInfo {
    device: vk::PhysicalDevice,
    _properties: vk::PhysicalDeviceProperties,
    queue_families: Vec<vk::QueueFamilyProperties>,
    memory: vk::PhysicalDeviceMemoryProperties,
    _features: vk::PhysicalDeviceFeatures,
}

impl PhysicalDeviceInfo {
    pub fn new(dev: vk::PhysicalDevice, vk: &vk::InstancePointers) -> PhysicalDeviceInfo {
        PhysicalDeviceInfo {
            device: dev,
            _properties: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceProperties(dev, &mut out);
                out
            },
            queue_families: unsafe {
                let mut num = 4;
                let mut families = Vec::with_capacity(num as usize);
                vk.GetPhysicalDeviceQueueFamilyProperties(dev, &mut num, families.as_mut_ptr());
                families.set_len(num as usize);
                families
            },
            memory: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceMemoryProperties(dev, &mut out);
                out
            },
            _features: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceFeatures(dev, &mut out);
                out
            },
        }
    }
}

pub struct Share {
    _dynamic_lib: DynamicLibrary,
    _library: vk::Static,
    instance: vk::Instance,
    inst_pointers: vk::InstancePointers,
    device: vk::Device,
    dev_pointers: vk::DevicePointers,
    handles: RefCell<gfx_core::handle::Manager<Resources>>,
}

pub type SharePointer = Arc<Share>;

impl Share {
    pub fn get_instance(&self) -> (vk::Instance, &vk::InstancePointers) {
        (self.instance, &self.inst_pointers)
    }
    pub fn get_device(&self) -> (vk::Device, &vk::DevicePointers) {
        (self.device, &self.dev_pointers)
    }
}

const SURFACE_EXTENSIONS: &'static [&'static str] = &[
    // Platform-specific WSI extensions
    "VK_KHR_xlib_surface",
    "VK_KHR_xcb_surface",
    "VK_KHR_wayland_surface",
    "VK_KHR_mir_surface",
    "VK_KHR_android_surface",
    "VK_KHR_win32_surface",
];

pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str],
              dev_extensions: &[&str]) -> (command::GraphicsQueue, factory::Factory, SharePointer) {
    use std::ffi::CString;
    use std::path::Path;

    let dynamic_lib = DynamicLibrary::open(Some(
            if cfg!(target_os = "windows") {
                Path::new("vulkan-1.dll")
            } else {
                Path::new("libvulkan.so.1")
            }
        )).expect("Unable to open vulkan shared library");
    let lib = vk::Static::load(|name| unsafe {
        let name = name.to_str().unwrap();
        dynamic_lib.symbol(name).unwrap()
    });
    let entry_points = vk::EntryPoints::load(|name| unsafe {
        mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr()))
    });

    let app_info = vk::ApplicationInfo {
        sType: vk::STRUCTURE_TYPE_APPLICATION_INFO,
        pNext: ptr::null(),
        pApplicationName: app_name.as_ptr() as *const _,
        applicationVersion: app_version,
        pEngineName: "gfx-rs".as_ptr() as *const _,
        engineVersion: 0x1000, //TODO
        apiVersion: 0x400000, //TODO
    };

    let instance_extensions = {
        let mut num = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, ptr::null_mut())
        });
        let mut out = Vec::with_capacity(num as usize);
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, out.as_mut_ptr())
        });
        unsafe { out.set_len(num as usize); }
        out
    };

    // Check our surface extensions against the available extensions
    let surface_extensions = SURFACE_EXTENSIONS.iter().filter(|ext| {
        for inst_ext in instance_extensions.iter() {
            unsafe {
                if CStr::from_ptr(inst_ext.extensionName.as_ptr()) == CStr::from_ptr(ext.as_ptr() as *const i8) {
                    return true;
                }
            }
        }
        false
    }).map(|s| *s).collect::<Vec<_>>();

    let instance = {
        let cstrings = layers.iter().chain(extensions.iter())
                                    .chain(surface_extensions.iter())
                         .map(|&s| CString::new(s).unwrap())
                         .collect::<Vec<_>>();
        let str_pointers = cstrings.iter()
                                   .map(|s| s.as_ptr())
                                   .collect::<Vec<_>>();

        let create_info = vk::InstanceCreateInfo {
            sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            pApplicationInfo: &app_info,
            enabledLayerCount: layers.len() as u32,
            ppEnabledLayerNames: str_pointers.as_ptr(),
            enabledExtensionCount: (extensions.len() + surface_extensions.len()) as u32,
            ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(),
        };
        let mut out = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.CreateInstance(&create_info, ptr::null(), &mut out)
        });
        out
    };

    let inst_pointers = vk::InstancePointers::load(|name| unsafe {
        mem::transmute(lib.GetInstanceProcAddr(instance, name.as_ptr()))
    });

    let mut physical_devices: [vk::PhysicalDevice; 4] = unsafe { mem::zeroed() };
    let mut num = physical_devices.len() as u32;
    assert_eq!(vk::SUCCESS, unsafe {
        inst_pointers.EnumeratePhysicalDevices(instance, &mut num, physical_devices.as_mut_ptr())
    });
    let devices = physical_devices[..num as usize].iter()
        .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers))
        .collect::<Vec<_>>();

    let (dev, (qf_id, _))  = devices.iter()
        .flat_map(|d| iter::repeat(d).zip(d.queue_families.iter().enumerate()))
        .find(|&(_, (_, qf))| qf.queueFlags & vk::QUEUE_GRAPHICS_BIT != 0)
        .unwrap();
    info!("Chosen physical device {:?} with queue family {}", dev.device, qf_id);

    let mvid_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize)
                            .position(|mt| mt.propertyFlags & vk::MEMORY_PROPERTY_DEVICE_LOCAL_BIT != 0)
                            .unwrap() as u32;
    let msys_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize)
                            .position(|mt| mt.propertyFlags & vk::MEMORY_PROPERTY_HOST_COHERENT_BIT != 0)
                            .unwrap() as u32;

    let device = {
        let cstrings = dev_extensions.iter()
                                     .map(|&s| CString::new(s).unwrap())
                                     .collect::<Vec<_>>();
        let str_pointers = cstrings.iter().map(|s| s.as_ptr())
                                   .collect::<Vec<_>>();

        let queue_info = vk::DeviceQueueCreateInfo {
            sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            queueFamilyIndex: qf_id as u32,
            queueCount: 1,
            pQueuePriorities: &1.0,
        };
        let features = unsafe{ mem::zeroed() };

        let dev_info = vk::DeviceCreateInfo {
            sType: vk::STRUCTURE_TYPE_DEVICE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            queueCreateInfoCount: 1,
            pQueueCreateInfos: &queue_info,
            enabledLayerCount: 0,
            ppEnabledLayerNames: ptr::null(),
            enabledExtensionCount: str_pointers.len() as u32,
            ppEnabledExtensionNames: str_pointers.as_ptr(),
            pEnabledFeatures: &features,
        };
        let mut out = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            inst_pointers.CreateDevice(dev.device, &dev_info, ptr::null(), &mut out)
        });
        out
    };

    let dev_pointers = vk::DevicePointers::load(|name| unsafe {
        inst_pointers.GetDeviceProcAddr(device, name.as_ptr()) as *const _
    });
    let queue = unsafe {
        let mut out = mem::zeroed();
        dev_pointers.GetDeviceQueue(device, qf_id as u32, 0, &mut out);
        out
    };

    let share = Arc::new(Share {
        _dynamic_lib: dynamic_lib,
        _library: lib,
        instance: instance,
        inst_pointers: inst_pointers,
        device: device,
        dev_pointers: dev_pointers,
        handles: RefCell::new(gfx_core::handle::Manager::new()),
    });
    let gfx_device = command::GraphicsQueue::new(share.clone(), queue, qf_id as u32);
    let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32, mvid_id, msys_id);

    (gfx_device, gfx_factory, share)
}

#[derive(Clone, PartialEq, Eq)]
pub struct Error(pub vk::Result);

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(match self.0 {
            vk::SUCCESS => "success",
            vk::NOT_READY => "not ready",
            vk::TIMEOUT => "timeout",
            vk::EVENT_SET => "event_set",
            vk::EVENT_RESET => "event_reset",
            vk::INCOMPLETE => "incomplete",
            vk::ERROR_OUT_OF_HOST_MEMORY => "out of host memory",
            vk::ERROR_OUT_OF_DEVICE_MEMORY => "out of device memory",
            vk::ERROR_INITIALIZATION_FAILED => "initialization failed",
            vk::ERROR_DEVICE_LOST => "device lost",
            vk::ERROR_MEMORY_MAP_FAILED => "memory map failed",
            vk::ERROR_LAYER_NOT_PRESENT => "layer not present",
            vk::ERROR_EXTENSION_NOT_PRESENT => "extension not present",
            vk::ERROR_FEATURE_NOT_PRESENT => "feature not present",
            vk::ERROR_INCOMPATIBLE_DRIVER => "incompatible driver",
            vk::ERROR_TOO_MANY_OBJECTS => "too many objects",
            vk::ERROR_FORMAT_NOT_SUPPORTED => "format not supported",
            vk::ERROR_SURFACE_LOST_KHR => "surface lost (KHR)",
            vk::ERROR_NATIVE_WINDOW_IN_USE_KHR => "native window in use (KHR)",
            vk::SUBOPTIMAL_KHR => "suboptimal (KHR)",
            vk::ERROR_OUT_OF_DATE_KHR => "out of date (KHR)",
            vk::ERROR_INCOMPATIBLE_DISPLAY_KHR => "incompatible display (KHR)",
            vk::ERROR_VALIDATION_FAILED_EXT => "validation failed (EXT)",
            _ => "unknown",
        })
    }
}

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Resources {}

impl gfx_core::Resources for Resources {
    type Buffer               = native::Buffer;
    type Shader               = vk::ShaderModule;
    type Program              = native::Program;
    type PipelineStateObject  = native::Pipeline;
    type Texture              = native::Texture;
    type ShaderResourceView   = native::TextureView; //TODO: buffer view
    type UnorderedAccessView  = ();
    type RenderTargetView     = native::TextureView;
    type DepthStencilView     = native::TextureView;
    type Sampler              = vk::Sampler;
    type Fence                = vk::Fence;
}
<commit_msg>Vulkan: Fix heap selection for host map-able memory<commit_after>// Copyright 2016 The Gfx-rs Developers.
//
// 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.

#[macro_use]
extern crate log;
extern crate shared_library;
extern crate gfx_core;
extern crate vk_sys as vk;

use std::{fmt, iter, mem, ptr};
use std::cell::RefCell;
use std::sync::Arc;
use std::ffi::CStr;
use shared_library::dynamic_library::DynamicLibrary;

pub use self::command::{GraphicsQueue, Buffer as CommandBuffer};
pub use self::factory::Factory;

mod command;
pub mod data;
mod factory;
mod native;

struct PhysicalDeviceInfo {
    device: vk::PhysicalDevice,
    _properties: vk::PhysicalDeviceProperties,
    queue_families: Vec<vk::QueueFamilyProperties>,
    memory: vk::PhysicalDeviceMemoryProperties,
    _features: vk::PhysicalDeviceFeatures,
}

impl PhysicalDeviceInfo {
    pub fn new(dev: vk::PhysicalDevice, vk: &vk::InstancePointers) -> PhysicalDeviceInfo {
        PhysicalDeviceInfo {
            device: dev,
            _properties: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceProperties(dev, &mut out);
                out
            },
            queue_families: unsafe {
                let mut num = 4;
                let mut families = Vec::with_capacity(num as usize);
                vk.GetPhysicalDeviceQueueFamilyProperties(dev, &mut num, families.as_mut_ptr());
                families.set_len(num as usize);
                families
            },
            memory: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceMemoryProperties(dev, &mut out);
                out
            },
            _features: unsafe {
                let mut out = mem::zeroed();
                vk.GetPhysicalDeviceFeatures(dev, &mut out);
                out
            },
        }
    }
}

pub struct Share {
    _dynamic_lib: DynamicLibrary,
    _library: vk::Static,
    instance: vk::Instance,
    inst_pointers: vk::InstancePointers,
    device: vk::Device,
    dev_pointers: vk::DevicePointers,
    handles: RefCell<gfx_core::handle::Manager<Resources>>,
}

pub type SharePointer = Arc<Share>;

impl Share {
    pub fn get_instance(&self) -> (vk::Instance, &vk::InstancePointers) {
        (self.instance, &self.inst_pointers)
    }
    pub fn get_device(&self) -> (vk::Device, &vk::DevicePointers) {
        (self.device, &self.dev_pointers)
    }
}

const SURFACE_EXTENSIONS: &'static [&'static str] = &[
    // Platform-specific WSI extensions
    "VK_KHR_xlib_surface",
    "VK_KHR_xcb_surface",
    "VK_KHR_wayland_surface",
    "VK_KHR_mir_surface",
    "VK_KHR_android_surface",
    "VK_KHR_win32_surface",
];

pub fn create(app_name: &str, app_version: u32, layers: &[&str], extensions: &[&str],
              dev_extensions: &[&str]) -> (command::GraphicsQueue, factory::Factory, SharePointer) {
    use std::ffi::CString;
    use std::path::Path;

    let dynamic_lib = DynamicLibrary::open(Some(
            if cfg!(target_os = "windows") {
                Path::new("vulkan-1.dll")
            } else {
                Path::new("libvulkan.so.1")
            }
        )).expect("Unable to open vulkan shared library");
    let lib = vk::Static::load(|name| unsafe {
        let name = name.to_str().unwrap();
        dynamic_lib.symbol(name).unwrap()
    });
    let entry_points = vk::EntryPoints::load(|name| unsafe {
        mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr()))
    });

    let app_info = vk::ApplicationInfo {
        sType: vk::STRUCTURE_TYPE_APPLICATION_INFO,
        pNext: ptr::null(),
        pApplicationName: app_name.as_ptr() as *const _,
        applicationVersion: app_version,
        pEngineName: "gfx-rs".as_ptr() as *const _,
        engineVersion: 0x1000, //TODO
        apiVersion: 0x400000, //TODO
    };

    let instance_extensions = {
        let mut num = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, ptr::null_mut())
        });
        let mut out = Vec::with_capacity(num as usize);
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, out.as_mut_ptr())
        });
        unsafe { out.set_len(num as usize); }
        out
    };

    // Check our surface extensions against the available extensions
    let surface_extensions = SURFACE_EXTENSIONS.iter().filter(|ext| {
        for inst_ext in instance_extensions.iter() {
            unsafe {
                if CStr::from_ptr(inst_ext.extensionName.as_ptr()) == CStr::from_ptr(ext.as_ptr() as *const i8) {
                    return true;
                }
            }
        }
        false
    }).map(|s| *s).collect::<Vec<_>>();

    let instance = {
        let cstrings = layers.iter().chain(extensions.iter())
                                    .chain(surface_extensions.iter())
                         .map(|&s| CString::new(s).unwrap())
                         .collect::<Vec<_>>();
        let str_pointers = cstrings.iter()
                                   .map(|s| s.as_ptr())
                                   .collect::<Vec<_>>();

        let create_info = vk::InstanceCreateInfo {
            sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            pApplicationInfo: &app_info,
            enabledLayerCount: layers.len() as u32,
            ppEnabledLayerNames: str_pointers.as_ptr(),
            enabledExtensionCount: (extensions.len() + surface_extensions.len()) as u32,
            ppEnabledExtensionNames: str_pointers[layers.len()..].as_ptr(),
        };
        let mut out = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            entry_points.CreateInstance(&create_info, ptr::null(), &mut out)
        });
        out
    };

    let inst_pointers = vk::InstancePointers::load(|name| unsafe {
        mem::transmute(lib.GetInstanceProcAddr(instance, name.as_ptr()))
    });

    let mut physical_devices: [vk::PhysicalDevice; 4] = unsafe { mem::zeroed() };
    let mut num = physical_devices.len() as u32;
    assert_eq!(vk::SUCCESS, unsafe {
        inst_pointers.EnumeratePhysicalDevices(instance, &mut num, physical_devices.as_mut_ptr())
    });
    let devices = physical_devices[..num as usize].iter()
        .map(|dev| PhysicalDeviceInfo::new(*dev, &inst_pointers))
        .collect::<Vec<_>>();

    let (dev, (qf_id, _))  = devices.iter()
        .flat_map(|d| iter::repeat(d).zip(d.queue_families.iter().enumerate()))
        .find(|&(_, (_, qf))| qf.queueFlags & vk::QUEUE_GRAPHICS_BIT != 0)
        .unwrap();
    info!("Chosen physical device {:?} with queue family {}", dev.device, qf_id);

    let mvid_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize)
                            .position(|mt| (mt.propertyFlags & vk::MEMORY_PROPERTY_DEVICE_LOCAL_BIT != 0)
                                        && (mt.propertyFlags & vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT != 0))
                            .unwrap() as u32;
    let msys_id = dev.memory.memoryTypes.iter().take(dev.memory.memoryTypeCount as usize)
                            .position(|mt| mt.propertyFlags & vk::MEMORY_PROPERTY_HOST_COHERENT_BIT != 0)
                            .unwrap() as u32;

    let device = {
        let cstrings = dev_extensions.iter()
                                     .map(|&s| CString::new(s).unwrap())
                                     .collect::<Vec<_>>();
        let str_pointers = cstrings.iter().map(|s| s.as_ptr())
                                   .collect::<Vec<_>>();

        let queue_info = vk::DeviceQueueCreateInfo {
            sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            queueFamilyIndex: qf_id as u32,
            queueCount: 1,
            pQueuePriorities: &1.0,
        };
        let features = unsafe{ mem::zeroed() };

        let dev_info = vk::DeviceCreateInfo {
            sType: vk::STRUCTURE_TYPE_DEVICE_CREATE_INFO,
            pNext: ptr::null(),
            flags: 0,
            queueCreateInfoCount: 1,
            pQueueCreateInfos: &queue_info,
            enabledLayerCount: 0,
            ppEnabledLayerNames: ptr::null(),
            enabledExtensionCount: str_pointers.len() as u32,
            ppEnabledExtensionNames: str_pointers.as_ptr(),
            pEnabledFeatures: &features,
        };
        let mut out = 0;
        assert_eq!(vk::SUCCESS, unsafe {
            inst_pointers.CreateDevice(dev.device, &dev_info, ptr::null(), &mut out)
        });
        out
    };

    let dev_pointers = vk::DevicePointers::load(|name| unsafe {
        inst_pointers.GetDeviceProcAddr(device, name.as_ptr()) as *const _
    });
    let queue = unsafe {
        let mut out = mem::zeroed();
        dev_pointers.GetDeviceQueue(device, qf_id as u32, 0, &mut out);
        out
    };

    let share = Arc::new(Share {
        _dynamic_lib: dynamic_lib,
        _library: lib,
        instance: instance,
        inst_pointers: inst_pointers,
        device: device,
        dev_pointers: dev_pointers,
        handles: RefCell::new(gfx_core::handle::Manager::new()),
    });
    let gfx_device = command::GraphicsQueue::new(share.clone(), queue, qf_id as u32);
    let gfx_factory = factory::Factory::new(share.clone(), qf_id as u32, mvid_id, msys_id);

    (gfx_device, gfx_factory, share)
}

#[derive(Clone, PartialEq, Eq)]
pub struct Error(pub vk::Result);

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(match self.0 {
            vk::SUCCESS => "success",
            vk::NOT_READY => "not ready",
            vk::TIMEOUT => "timeout",
            vk::EVENT_SET => "event_set",
            vk::EVENT_RESET => "event_reset",
            vk::INCOMPLETE => "incomplete",
            vk::ERROR_OUT_OF_HOST_MEMORY => "out of host memory",
            vk::ERROR_OUT_OF_DEVICE_MEMORY => "out of device memory",
            vk::ERROR_INITIALIZATION_FAILED => "initialization failed",
            vk::ERROR_DEVICE_LOST => "device lost",
            vk::ERROR_MEMORY_MAP_FAILED => "memory map failed",
            vk::ERROR_LAYER_NOT_PRESENT => "layer not present",
            vk::ERROR_EXTENSION_NOT_PRESENT => "extension not present",
            vk::ERROR_FEATURE_NOT_PRESENT => "feature not present",
            vk::ERROR_INCOMPATIBLE_DRIVER => "incompatible driver",
            vk::ERROR_TOO_MANY_OBJECTS => "too many objects",
            vk::ERROR_FORMAT_NOT_SUPPORTED => "format not supported",
            vk::ERROR_SURFACE_LOST_KHR => "surface lost (KHR)",
            vk::ERROR_NATIVE_WINDOW_IN_USE_KHR => "native window in use (KHR)",
            vk::SUBOPTIMAL_KHR => "suboptimal (KHR)",
            vk::ERROR_OUT_OF_DATE_KHR => "out of date (KHR)",
            vk::ERROR_INCOMPATIBLE_DISPLAY_KHR => "incompatible display (KHR)",
            vk::ERROR_VALIDATION_FAILED_EXT => "validation failed (EXT)",
            _ => "unknown",
        })
    }
}

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Resources {}

impl gfx_core::Resources for Resources {
    type Buffer               = native::Buffer;
    type Shader               = vk::ShaderModule;
    type Program              = native::Program;
    type PipelineStateObject  = native::Pipeline;
    type Texture              = native::Texture;
    type ShaderResourceView   = native::TextureView; //TODO: buffer view
    type UnorderedAccessView  = ();
    type RenderTargetView     = native::TextureView;
    type DepthStencilView     = native::TextureView;
    type Sampler              = vk::Sampler;
    type Fence                = vk::Fence;
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{Read, Write};

use system::scheme::{Packet, Scheme};

extern crate system;

struct ExampleScheme;

impl Scheme for ExampleScheme {

}

fn main() {
   //In order to handle example:, we create :example
   let mut scheme = File::create(":example").unwrap();
   loop {
       let mut packet = Packet::default();
       if scheme.read(&mut packet).unwrap() == 0 {
           panic!("Unexpected EOF");
       }

       println!("Received: {:?}", packet);

       packet.a = 0;
       scheme.write(&packet).unwrap();
   }
}
<commit_msg>WIP: Implement tests for syscalls in example scheme<commit_after>use std::fs::File;
use std::io::{Read, Write};

use system::error::{Error, Result, ENOENT, EBADF};
use system::scheme::{Packet, Scheme};

extern crate system;

struct ExampleScheme;

impl Scheme for ExampleScheme {
    fn open(&mut self, path: &str, flags: usize, mode: usize) -> Result {
        println!("open {:X} = {}, {:X}, {:X}", path.as_ptr() as usize, path, flags, mode);
        Ok(0)
    }

    #[allow(unused_variables)]
    fn unlink(&mut self, path: &str) -> Result {
        println!("unlink {}", path);
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn mkdir(&mut self, path: &str, mode: usize) -> Result {
        println!("mkdir {}, {:X}", path, mode);
        Err(Error::new(ENOENT))
    }

    /* Resource operations */

    #[allow(unused_variables)]
    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result {
        println!("read {}, {:X}, {}", id, buf.as_mut_ptr() as usize, buf.len());
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn write(&mut self, id: usize, buf: &[u8]) -> Result {
        println!("write {}, {:X}, {}", id, buf.as_ptr() as usize, buf.len());
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result {
        println!("seek {}, {}, {}", id, pos, whence);
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn sync(&mut self, id: usize) -> Result {
        println!("sync {}", id);
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn truncate(&mut self, id: usize, len: usize) -> Result {
        println!("truncate {}, {}", id, len);
        Err(Error::new(EBADF))
    }
}

fn main() {
   //In order to handle example:, we create :example
   let mut scheme = ExampleScheme;
   let mut socket = File::create(":example").unwrap();
   loop {
       let mut packet = Packet::default();
       if socket.read(&mut packet).unwrap() == 0 {
           panic!("Unexpected EOF");
       }
       println!("Recv {:?}", packet);

       scheme.handle(&mut packet);

       socket.write(&packet).unwrap();
       println!("Sent {:?}", packet);
   }
}
<|endoftext|>


<commit_before>/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagutil::debug_result::*;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
pub struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// Get a link Url object from a `FileLockEntry`, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.get_header()
            .read("imag.content.uri")
            .ok()
            .and_then(|opt| match opt {
                Some(Value::String(s)) => Url::parse(&s[..]).ok(),
                _ => None
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .get_header()
            .read("imag.content.uri");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(Some)
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

/// Check whether the StoreId starts with `/link/external/`
pub fn is_external_link_storeid(id: &StoreId) -> bool {
    debug!("Checking whether this is a link/external/*: '{:?}'", id);
    id.local().starts_with("link/external")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|vect| {
                debug!("Getting external links");
                vect.into_iter()
                    .filter(is_external_link_storeid)
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => get_external_link_from_file(&f),
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.as_str()[..]);
                s.result_str()
            };
            let file_id = try!(
                ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
                    .map_err_into(LEK::StoreWriteError)
                    .map_dbg_err(|_| {
                        format!("Failed to build StoreId for this hash '{:?}'", hash)
                    })
                );

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let mut file = try!(store
                .retrieve(file_id.clone())
                .map_err_into(LEK::StoreWriteError)
                .map_dbg_err(|_| {
                    format!("Failed to create or retrieve an file for this link '{:?}'", link)
                }));

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.into_string());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.as_str() != link.as_str())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

<commit_msg>Fix: We save the url at imag.content.url, not imag.content.uri<commit_after>/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagutil::debug_result::*;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
pub struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// Get a link Url object from a `FileLockEntry`, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.get_header()
            .read("imag.content.url")
            .ok()
            .and_then(|opt| match opt {
                Some(Value::String(s)) => Url::parse(&s[..]).ok(),
                _ => None
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .get_header()
            .read("imag.content.url");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(Some)
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

/// Check whether the StoreId starts with `/link/external/`
pub fn is_external_link_storeid(id: &StoreId) -> bool {
    debug!("Checking whether this is a link/external/*: '{:?}'", id);
    id.local().starts_with("link/external")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|vect| {
                debug!("Getting external links");
                vect.into_iter()
                    .filter(is_external_link_storeid)
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => get_external_link_from_file(&f),
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.as_str()[..]);
                s.result_str()
            };
            let file_id = try!(
                ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
                    .map_err_into(LEK::StoreWriteError)
                    .map_dbg_err(|_| {
                        format!("Failed to build StoreId for this hash '{:?}'", hash)
                    })
                );

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let mut file = try!(store
                .retrieve(file_id.clone())
                .map_err_into(LEK::StoreWriteError)
                .map_dbg_err(|_| {
                    format!("Failed to create or retrieve an file for this link '{:?}'", link)
                }));

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.into_string());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.as_str() != link.as_str())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

<|endoftext|>


<commit_before><commit_msg>adding default method to traits<commit_after><|endoftext|>


<commit_before><commit_msg>Add Artist struct<commit_after>use std::collections::BTreeMap;
use rustc_serialize::json::{ToJson, Json};
use postgres;
use uuid::Uuid;
use std::fmt;
use chrono::{NaiveDateTime, UTC, DateTime};

use soundcloud;
use spotify;
use error::Error;
use super::{conn, Model};
use model::provider::Provider;

static PROPS: [&'static str; 9]  = ["id",
                                    "provider",
                                    "identifier",
                                    "url",
                                    "name",
                                    "thumbnail_url",
                                    "artwork_url",
                                    "created_at",
                                    "updated_at"];

#[derive(Debug, Clone)]
pub struct Artist {
    pub id:            Uuid,
    pub provider:      Provider,
    pub identifier:    String,
    pub url:           String,
    pub name:          String,
    pub thumbnail_url: Option<String>,
    pub artwork_url:   Option<String>,
    pub created_at:    NaiveDateTime,
    pub updated_at:    NaiveDateTime,
}

impl ToJson for Artist {
    fn to_json(&self) -> Json {
        let created_at   = DateTime::<UTC>::from_utc(self.created_at  , UTC);
        let updated_at   = DateTime::<UTC>::from_utc(self.updated_at  , UTC);
        let mut d = BTreeMap::new();
        d.insert("id".to_string()           , self.id.to_string().to_json());
        d.insert("provider".to_string()     , self.provider.to_json());
        d.insert("identifier".to_string()   , self.identifier.to_json());
        d.insert("url".to_string()          , self.url.to_json());
        d.insert("name".to_string()         , self.name.to_json());
        d.insert("thumbnail_url".to_string(), self.thumbnail_url.to_json());
        d.insert("artwork_url".to_string()  , self.artwork_url.to_json());
        d.insert("created_at".to_string()   , created_at.to_rfc3339().to_json());
        d.insert("updated_at".to_string()   , updated_at.to_rfc3339().to_json());
        Json::Object(d)
    }
}

impl fmt::Display for Artist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{}", self.provider, self.identifier)
    }
}

impl Model for Artist {
    fn table_name() -> String { "artists".to_string() }
    fn props_str(prefix: &str) -> String {
        PROPS
            .iter()
            .map(|&p| format!("{}{}", prefix, p))
            .collect::<Vec<String>>().join(",")
    }
    fn rows_to_items(rows: postgres::rows::Rows) -> Vec<Artist> {
        let mut artists = Vec::new();
        for row in rows.iter() {
            let artist = Artist {
                id:            row.get(0),
                provider:      Provider::new(row.get(1)),
                identifier:    row.get(2),
                url:           row.get(3),
                name:          row.get(4),
                thumbnail_url: row.get(5),
                artwork_url:   row.get(6),
                created_at:    row.get(7),
                updated_at:    row.get(8),
            };
            artists.push(artist)
        }
        artists
    }

    fn create(&self) -> Result<Artist, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare("INSERT INTO artists (provider, identifier, url, name)
                                 VALUES ($1, $2, $3, $4) RETURNING id"));
        let rows = try!(stmt.query(&[&self.provider.to_string(), &self.identifier, &self.url, &self.name]));
        let mut artist = self.clone();
        for row in rows.iter() {
            artist.id = row.get(0);
        }
        Ok(artist)
    }

    fn save(&mut self) -> Result<(), Error> {
        self.updated_at = UTC::now().naive_utc();
        let conn = conn().unwrap();
        let stmt = conn.prepare("UPDATE artists SET
                                 provider      = $2,
                                 identifier    = $3,
                                 url           = $4,
                                 name          = $5,
                                 thumbnail_url = $6,
                                 artwork_url   = $7,
                                 created_at    = $8,
                                 updated_at    = $9
                                 WHERE id = $1").unwrap();
        let result = stmt.query(&[&self.id,
                                  &self.provider.to_string(),
                                  &self.identifier,
                                  &self.url,
                                  &self.name,
                                  &self.thumbnail_url,
                                  &self.artwork_url,
                                  &self.created_at,
                                  &self.updated_at,
        ]);
        match result {
            Ok(_)  => Ok(()),
            Err(_) => Err(Error::Unexpected),
        }
    }
}

impl Artist {
    fn new(provider: Provider, identifier: String) -> Artist {
        Artist {
            id:            Uuid::new_v4(),
            provider:      provider,
            identifier:    identifier,
            url:           "".to_string(),
            name:          "".to_string(),
            thumbnail_url: None,
            artwork_url:   None,
            created_at:    UTC::now().naive_utc(),
            updated_at:    UTC::now().naive_utc(),
        }
    }
    fn find_by(provider: &Provider, identifier: &str) -> Result<Artist, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare(
            &format!("SELECT {} FROM {}
                     WHERE provider = $1 AND identifier = $2
                     ORDER BY updated_at DESC",
                     Artist::props_str(""), Artist::table_name())).unwrap();
        let rows = stmt.query(&[&(*provider).to_string(), &identifier]).unwrap();
        let items = Artist::rows_to_items(rows);
        if items.len() > 0 {
            return Ok(items[0].clone());
        }
        return Err(Error::NotFound)
    }
    pub fn find_or_create(provider: Provider, identifier: String) -> Result<Artist, Error> {
        return match Artist::find_by(&provider, &identifier) {
            Ok(item) => Ok(item),
            Err(_)   => Artist::new(provider, identifier).create()
        }
    }
    pub fn from_yt_channel(channel_id: &str, channel_title: &str) -> Artist {
        let mut artist = Artist::new(Provider::YouTube, channel_id.to_string());
        artist.name = channel_title.to_string();
        artist.clone()
    }
    pub fn from_sp_artist(artist: &spotify::Artist) -> Artist {
        Artist::new(Provider::Spotify, (*artist).id.to_string())
            .update_with_sp_artist(artist)
            .clone()
    }

    pub fn from_sc_user(playlist: &soundcloud::User) -> Artist {
        Artist::new(Provider::SoundCloud, (*playlist).id.to_string())
            .update_with_sc_user(playlist)
            .clone()
    }

    pub fn from_am_artist(artist: &str) -> Artist {
        let mut artist = Artist::new(Provider::AppleMusic, artist.to_string());
        artist.name = artist.to_string();
        artist.clone()
    }

    pub fn update_with_sp_artist(&mut self, artist: &spotify::Artist) -> &mut Artist {
        self.provider       = Provider::Spotify;
        self.identifier     = artist.id.to_string();
        self.url            = artist.uri.clone();
        self.name           = artist.name.clone();
        if let Some(ref images) = artist.images {
            if images.len() > 0 {
                self.artwork_url   = Some(images[0].url.clone());
                self.thumbnail_url = Some(images[0].url.clone());
            }
            if images.len() > 1 {
                self.thumbnail_url = Some(images[1].url.clone());
            }
        }
        self
    }

    pub fn update_with_sc_user(&mut self, user: &soundcloud::User) -> &mut Artist {
        self.provider      = Provider::SoundCloud;
        self.identifier    = user.id.to_string();
        self.url           = user.permalink.to_string();
        self.name          = user.username.to_string();
        self.thumbnail_url = Some(user.avatar_url.clone());
        self.artwork_url   = Some(user.avatar_url.clone());
        self
    }
}

#[cfg(test)]
mod test {
    use model::Model;
    use super::Artist;
    use Provider;
    #[test]
    fn test_new() {
        let artist = Artist::new(Provider::Spotify,
                               "4tZwfgrHOc3mvqYlEYSvVi".to_string());
        assert_eq!(artist.provider, Provider::Spotify);
        assert_eq!(&artist.identifier, "4tZwfgrHOc3mvqYlEYSvVi");
    }
    #[test]
    fn test_find_of_create() {
        let identifier = "4tZwfgrHOc3mvqYlEYSvVi".to_string();
        let result     = Artist::find_or_create(Provider::Spotify, identifier);
        assert!(result.is_ok());
    }
    #[test]
    fn test_save() {
        let id = "test_save";
        let mut artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        artist.name   = "name".to_string();
        let result    = artist.save();
        assert!(result.is_ok());
        let artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        assert_eq!(&artist.name, "name");
    }
}
<|endoftext|>


<commit_before><commit_msg>Add missing mod.rs<commit_after>//! Structures responsible for rendering elements other than kiss3d's meshes.

pub use self::point_renderer::PointRenderer;
pub use self::line_renderer::LineRenderer;
pub use self::renderer::Renderer;

pub mod line_renderer;
pub mod point_renderer;
mod renderer;<|endoftext|>


<commit_before>//! A set of macros for easily working with internals.

macro_rules! request {
    ($route:expr, $method:ident($body:expr), $url:expr, $($rest:tt)*) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(&format!(api!($url), $($rest)*))
            .body(&$body))?
    }};
    ($route:expr, $method:ident($body:expr), $url:expr) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(api!($url))
            .body(&$body))?
    }};
    ($route:expr, $method:ident, $url:expr, $($rest:tt)*) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(&format!(api!($url), $($rest)*)))?
    }};
    ($route:expr, $method:ident, $url:expr) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(api!($url)))?
    }};
}

macro_rules! cdn {
    ($e:expr) => {
        concat!("https://cdn.discordapp.com", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(cdn!($e), $($rest)*)
    };
}

macro_rules! base {
    ($e:expr) => {
        concat!("https://discordapp.com", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(base!($e), $($rest)*)
    };
}

macro_rules! api {
    ($e:expr) => {
        concat!("https://discordapp.com/api/v6", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(api!($e), $($rest)*)
    };
}

macro_rules! status {
    ($e:expr) => {
        concat!("https://status.discordapp.com/api/v2", $e)
    }
}

// Enable/disable check for cache
#[cfg(feature="cache")]
macro_rules! feature_cache {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="cache"))]
macro_rules! feature_cache {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

// Enable/disable check for framework
#[cfg(feature="framework")]
macro_rules! feature_framework {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="framework"))]
macro_rules! feature_framework {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

// Enable/disable check for voice
#[cfg(feature="voice")]
macro_rules! feature_voice {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="voice"))]
macro_rules! feature_voice {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

#[macro_export]
macro_rules! enum_number {
    (#[$attr_:meta] $name:ident { $(#[$attr:meta] $variant:ident = $value:expr, )* }) => {
        #[$attr_]
        #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
        pub enum $name {
            $(
                #[$attr]
                $variant = $value,
            )*
        }

        impl ::serde::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
                where S: ::serde::Serializer
            {
                // Serialize the enum as a u64.
                serializer.serialize_u64(*self as u64)
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $name {
            fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
                where D: ::serde::Deserializer<'de>
            {
                struct Visitor;

                impl<'de> ::serde::de::Visitor<'de> for Visitor {
                    type Value = $name;

                    fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                        formatter.write_str("positive integer")
                    }

                    fn visit_u64<E>(self, value: u64) -> ::std::result::Result<$name, E>
                        where E: ::serde::de::Error
                    {
                        // Rust does not come with a simple way of converting a
                        // number to an enum, so use a big `match`.
                        match value {
                            $( $value => Ok($name::$variant), )*
                            _ => Err(E::custom(
                                format!("unknown {} value: {}",
                                stringify!($name), value))),
                        }
                    }
                }

                // Deserialize the enum from a u64.
                deserializer.deserialize_u64(Visitor)
            }
        }
    }
}
<commit_msg>Fix internal enum being exported<commit_after>//! A set of macros for easily working with internals.

macro_rules! request {
    ($route:expr, $method:ident($body:expr), $url:expr, $($rest:tt)*) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(&format!(api!($url), $($rest)*))
            .body(&$body))?
    }};
    ($route:expr, $method:ident($body:expr), $url:expr) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(api!($url))
            .body(&$body))?
    }};
    ($route:expr, $method:ident, $url:expr, $($rest:tt)*) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(&format!(api!($url), $($rest)*)))?
    }};
    ($route:expr, $method:ident, $url:expr) => {{
        let client = HyperClient::new();
        request($route, || client
            .$method(api!($url)))?
    }};
}

macro_rules! cdn {
    ($e:expr) => {
        concat!("https://cdn.discordapp.com", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(cdn!($e), $($rest)*)
    };
}

macro_rules! base {
    ($e:expr) => {
        concat!("https://discordapp.com", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(base!($e), $($rest)*)
    };
}

macro_rules! api {
    ($e:expr) => {
        concat!("https://discordapp.com/api/v6", $e)
    };
    ($e:expr, $($rest:tt)*) => {
        format!(api!($e), $($rest)*)
    };
}

macro_rules! status {
    ($e:expr) => {
        concat!("https://status.discordapp.com/api/v2", $e)
    }
}

// Enable/disable check for cache
#[cfg(feature="cache")]
macro_rules! feature_cache {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="cache"))]
macro_rules! feature_cache {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

// Enable/disable check for framework
#[cfg(feature="framework")]
macro_rules! feature_framework {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="framework"))]
macro_rules! feature_framework {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

// Enable/disable check for voice
#[cfg(feature="voice")]
macro_rules! feature_voice {
    ($enabled:block else $disabled:block) => {
        {
            $enabled
        }
    }
}

#[cfg(not(feature="voice"))]
macro_rules! feature_voice {
    ($enabled:block else $disabled:block) => {
        {
            $disabled
        }
    }
}

macro_rules! enum_number {
    (#[$attr_:meta] $name:ident { $(#[$attr:meta] $variant:ident = $value:expr, )* }) => {
        #[$attr_]
        #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
        pub enum $name {
            $(
                #[$attr]
                $variant = $value,
            )*
        }

        impl ::serde::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
                where S: ::serde::Serializer
            {
                // Serialize the enum as a u64.
                serializer.serialize_u64(*self as u64)
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $name {
            fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
                where D: ::serde::Deserializer<'de>
            {
                struct Visitor;

                impl<'de> ::serde::de::Visitor<'de> for Visitor {
                    type Value = $name;

                    fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                        formatter.write_str("positive integer")
                    }

                    fn visit_u64<E>(self, value: u64) -> ::std::result::Result<$name, E>
                        where E: ::serde::de::Error
                    {
                        // Rust does not come with a simple way of converting a
                        // number to an enum, so use a big `match`.
                        match value {
                            $( $value => Ok($name::$variant), )*
                            _ => Err(E::custom(
                                format!("unknown {} value: {}",
                                stringify!($name), value))),
                        }
                    }
                }

                // Deserialize the enum from a u64.
                deserializer.deserialize_u64(Visitor)
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add main function file of assembling.<commit_after><|endoftext|>


<commit_before>// Copyright 2017 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.

// Test that `for` loops don't introduce artificial
// constraints on the type of the binding (`i`).
// Subtle changes in the desugaring can cause the
// type of elements in the vector to (incorrectly)
// fallback to `!` or `()`.

fn main() {
    for i in Vec::new() { } //~ ERROR type annotations needed
}
<commit_msg>remove trailing whitespace<commit_after>// Copyright 2017 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.

// Test that `for` loops don't introduce artificial
// constraints on the type of the binding (`i`).
// Subtle changes in the desugaring can cause the
// type of elements in the vector to (incorrectly)
// fallback to `!` or `()`.

fn main() {
    for i in Vec::new() { } //~ ERROR type annotations needed
}
<|endoftext|>


<commit_before><commit_msg>WIP: client<commit_after><|endoftext|>


<commit_before><commit_msg>Improved formatting.<commit_after><|endoftext|>


<commit_before><commit_msg>Forgot to add scheduler module<commit_after>extern crate getopts;
/// All projects involve building a thread pool. This is the task equivalent for the threadpool in NetBricks/ZCSI/E2D2.
/// Anything that implements Runnable can be polled by the scheduler. This thing can be a `Batch` (e.g., `SendBatch`) or
/// something else (e.g., the `GroupBy` operator). Eventually this trait will have more stuff.
pub trait Executable {
    fn execute(&mut self);
}
<|endoftext|>


<commit_before><commit_msg>Add HasIpAddr collector<commit_after><|endoftext|>