<commit_before>use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry::*;

use util::*;

/// Information about the position of a single term within a document
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable)]
pub struct Position {
    /// Pair of byte indexes into the document at the beginning (inclusive) and end (exclusive) of
    /// the term.
    pub offsets: (usize, usize),
    /// The token position of the term, i.e., the number of tokens that occur before it in the doc.
    /// For example, for the sentence "I have to go to the store",
    /// the term "to" has positions [2, 4].
    pub position: usize,
}

impl Position {
    /// Creates a new Position struct with the given offsets and position.
    pub fn new(offsets: (usize, usize), position: usize) -> Position {
        Position {
            offsets: offsets,
            position: position,
        }
    }
}

impl Merge for Position {
    fn merge(self,
             Position { offsets: (begin2, end2), position: position2 }: Position)
             -> Option<Position> {
        let Position{offsets: (begin1, end1), position: position1} = self;
        assert!(begin2 >= begin1);
        if position1 == position2 && end1 >= begin2 {
            Some(Position {
                offsets: if end1 < end2 {
                    (begin1, end2)
                } else {
                    (begin1, end1)
                },
                position: position1,
            })
        } else {
            None
        }
    }
}

/// Each document is assigned a unique string id.
pub type DocId = String;

/// A Postings map (doc id => positions) for a single term.
/// Records which Documents contain the term, and at which locations in the documents.
pub type PostingsMap = BTreeMap<DocId, Vec<Position>>;

/// An extension trait for iterables over PostingsMaps
/// that enables the computation of the union of Postingsmaps
pub trait PostingsMerge {
    /// Computes the map containing the union of the maps in self
    fn merge_postings(self) -> PostingsMap;
}

impl<'a, Iter> PostingsMerge for Iter
    where Iter: IntoIterator,
          Iter::Item: Borrow<PostingsMap> {
    fn merge_postings(self) -> PostingsMap {
        let mut map = PostingsMap::new();
        for tree in self {
            for (doc_id, positions) in tree.borrow() {
                match map.entry(doc_id.clone()) {
                    Vacant(entry) => {
                        entry.insert(positions.clone());
                    }
                    Occupied(mut entry) =>
                        entry.get_mut().merge_coalesce(positions.iter().cloned()),
                }
            }
        }
        map
    }
}

/// An extension trait for slices of PostingsMaps,
/// that enables the computation of the intersection
/// of PostingsMaps
pub trait PostingsIntersect {
    /// Computes the map containing the intersection of the the maps in self
    fn intersect_postings(self) -> PostingsMap;
}

impl<'a> PostingsIntersect for &'a [PostingsMap] {
    fn intersect_postings(self) -> PostingsMap {
        match self {
            [] => PostingsMap::new(),
            [ref posting] => posting.clone(),
            [ref posting0, rest..] => {
                self.intersection()
                    .map(|doc_id| {
                        let mut positions = posting0[doc_id].clone();
                        for posting in rest {
                            positions.merge_coalesce(posting[doc_id].iter().cloned());
                        }
                        (doc_id.clone(), positions)
                    })
                    .collect()
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::iter;
    use super::super::Position;
    use super::PostingsMerge;

    #[test]
    fn test_merge() {
        let postings = [iter::once(("1".into(),
                                    vec![Position::new((0, 1), 0), Position::new((2, 3), 1)]))
                            .collect(),
                        iter::once(("1".into(),
                                    vec![Position::new((4, 5), 2), Position::new((6, 7), 3)]))
                            .collect()];
        assert_eq!(postings.iter().merge_postings(),
                   iter::once(("1".into(),
                               vec![Position::new((0, 1), 0),
                                    Position::new((2, 3), 1),
                                    Position::new((4, 5), 2),
                                    Position::new((6, 7), 3)]))
                       .collect());
    }
}
<commit_msg>Re-use (usize, usize)'s Merge impl in the impl of Merge for Position<commit_after>use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry::*;

use util::*;

/// Information about the position of a single term within a document
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable)]
pub struct Position {
    /// Pair of byte indexes into the document at the beginning (inclusive) and end (exclusive) of
    /// the term.
    pub offsets: (usize, usize),
    /// The token position of the term, i.e., the number of tokens that occur before it in the doc.
    /// For example, for the sentence "I have to go to the store",
    /// the term "to" has positions [2, 4].
    pub position: usize,
}

impl Position {
    /// Creates a new Position struct with the given offsets and position.
    pub fn new(offsets: (usize, usize), position: usize) -> Position {
        Position {
            offsets: offsets,
            position: position,
        }
    }
}

impl Merge for Position {
    fn merge(self, other: Position) -> Option<Position> {
        if self.position == other.position {
            self.offsets.merge(other.offsets).map(|offsets| Position::new(offsets, self.position))
        } else {
            None
        }
    }
}

/// Each document is assigned a unique string id.
pub type DocId = String;

/// A Postings map (doc id => positions) for a single term.
/// Records which Documents contain the term, and at which locations in the documents.
pub type PostingsMap = BTreeMap<DocId, Vec<Position>>;

/// An extension trait for iterables over PostingsMaps
/// that enables the computation of the union of Postingsmaps
pub trait PostingsMerge {
    /// Computes the map containing the union of the maps in self
    fn merge_postings(self) -> PostingsMap;
}

impl<'a, Iter> PostingsMerge for Iter
    where Iter: IntoIterator,
          Iter::Item: Borrow<PostingsMap> {
    fn merge_postings(self) -> PostingsMap {
        let mut map = PostingsMap::new();
        for tree in self {
            for (doc_id, positions) in tree.borrow() {
                match map.entry(doc_id.clone()) {
                    Vacant(entry) => {
                        entry.insert(positions.clone());
                    }
                    Occupied(mut entry) =>
                        entry.get_mut().merge_coalesce(positions.iter().cloned()),
                }
            }
        }
        map
    }
}

/// An extension trait for slices of PostingsMaps,
/// that enables the computation of the intersection
/// of PostingsMaps
pub trait PostingsIntersect {
    /// Computes the map containing the intersection of the the maps in self
    fn intersect_postings(self) -> PostingsMap;
}

impl<'a> PostingsIntersect for &'a [PostingsMap] {
    fn intersect_postings(self) -> PostingsMap {
        match self {
            [] => PostingsMap::new(),
            [ref posting] => posting.clone(),
            [ref posting0, rest..] => {
                self.intersection()
                    .map(|doc_id| {
                        let mut positions = posting0[doc_id].clone();
                        for posting in rest {
                            positions.merge_coalesce(posting[doc_id].iter().cloned());
                        }
                        (doc_id.clone(), positions)
                    })
                    .collect()
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::iter;
    use super::super::Position;
    use super::PostingsMerge;

    #[test]
    fn test_merge() {
        let postings = [iter::once(("1".into(),
                                    vec![Position::new((0, 1), 0), Position::new((2, 3), 1)]))
                            .collect(),
                        iter::once(("1".into(),
                                    vec![Position::new((4, 5), 2), Position::new((6, 7), 3)]))
                            .collect()];
        assert_eq!(postings.iter().merge_postings(),
                   iter::once(("1".into(),
                               vec![Position::new((0, 1), 0),
                                    Position::new((2, 3), 1),
                                    Position::new((4, 5), 2),
                                    Position::new((6, 7), 3)]))
                       .collect());
    }
}
<|endoftext|>


<commit_before>#![feature(never_type)]

use std::{future::Future, pin::Pin, task::Poll};
use std::task::{Wake, Waker, Context};
use std::sync::Arc;

// See if we can run a basic `async fn`
pub async fn foo(x: &u32, y: u32) -> u32 {
    let y = &y;
    let z = 9;
    let z = &z;
    let y = async { *y + *z }.await;
    let a = 10;
    let a = &a;
    *x + y + *a
}

async fn add(x: u32, y: u32) -> u32 {
    let a = async { x + y };
    a.await
}

async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 {
    let x = (add(a, b).await, add(c, d).await);
    x.0 + x.1
}

enum Never {}
fn never() -> Never {
    panic!()
}

async fn includes_never(crash: bool, x: u32) -> u32 {
    let mut result = async { x * x }.await;
    if !crash {
        return result;
    }
    #[allow(unused)]
    let bad = never();
    result *= async { x + x }.await;
    drop(bad);
    result
}

async fn partial_init(x: u32) -> u32 {
    #[allow(unreachable_code)]
    let _x: (String, !) = (String::new(), return async { x + x }.await);
}

fn run_fut(mut fut: impl Future<Output=u32>, output: u32) {
    struct MyWaker;
    impl Wake for MyWaker {
        fn wake(self: Arc<Self>) {
            unimplemented!()
        }
    }

    let waker = Waker::from(Arc::new(MyWaker));
    let mut context = Context::from_waker(&waker);
    assert_eq!(unsafe { Pin::new_unchecked(&mut fut) }.poll(&mut context), Poll::Ready(output));
}

fn main() {
    let x = 5;
    run_fut(foo(&x, 7), 31);

    run_fut(build_aggregate(1, 2, 3, 4), 10);

    run_fut(includes_never(false, 4), 16);

    run_fut(partial_init(4), 8);
}
<commit_msg>async-fn test: make run_fut more general and entirely safe<commit_after>#![feature(never_type)]

use std::future::Future;

// See if we can run a basic `async fn`
pub async fn foo(x: &u32, y: u32) -> u32 {
    let y = &y;
    let z = 9;
    let z = &z;
    let y = async { *y + *z }.await;
    let a = 10;
    let a = &a;
    *x + y + *a
}

async fn add(x: u32, y: u32) -> u32 {
    let a = async { x + y };
    a.await
}

async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 {
    let x = (add(a, b).await, add(c, d).await);
    x.0 + x.1
}

enum Never {}
fn never() -> Never {
    panic!()
}

async fn includes_never(crash: bool, x: u32) -> u32 {
    let mut result = async { x * x }.await;
    if !crash {
        return result;
    }
    #[allow(unused)]
    let bad = never();
    result *= async { x + x }.await;
    drop(bad);
    result
}

async fn partial_init(x: u32) -> u32 {
    #[allow(unreachable_code)]
    let _x: (String, !) = (String::new(), return async { x + x }.await);
}

fn run_fut<T>(fut: impl Future<Output = T>) -> T {
    use std::sync::Arc;
    use std::task::{Context, Poll, Wake, Waker};

    struct MyWaker;
    impl Wake for MyWaker {
        fn wake(self: Arc<Self>) {
            unimplemented!()
        }
    }

    let waker = Waker::from(Arc::new(MyWaker));
    let mut context = Context::from_waker(&waker);

    let mut pinned = Box::pin(fut);
    loop {
        match pinned.as_mut().poll(&mut context) {
            Poll::Pending => continue,
            Poll::Ready(v) => return v,
        }
    }
}

fn main() {
    let x = 5;
    assert_eq!(run_fut(foo(&x, 7)), 31);
    assert_eq!(run_fut(build_aggregate(1, 2, 3, 4)), 10);
    assert_eq!(run_fut(includes_never(false, 4)), 16);
    assert_eq!(run_fut(partial_init(4)), 8);
}
<|endoftext|>


<commit_before>
extern crate regex;
use mysql::conn::pool::{MyPool,MyPooledConn};
use mysql::conn::Stmt;
use mysql::error::MyError;

use std::process::{Command, Stdio, Child};
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::io;
use lib::config::ConfigGen;
use std::convert::Into;

macro_rules! regex(
    ($s:expr) => (regex::Regex::new($s).unwrap());
);

#[derive(Clone)]
pub struct DownloadDB {
    pub url: String,
    pub quality: i16,
    pub playlist: bool,
    pub compress: bool,
    pub audioquality: i16,
    pub qid: i64,
    pub folder: String, // download folder, changes for playlists
    pub pool: MyPool,
}

pub struct Downloader<'a> {
    ddb: DownloadDB,
    defaults: &'a ConfigGen,
    // pool: MyPool,
}

#[derive(Debug)]
pub enum DownloadError{
    DownloadError(String),
    ReadError,
    DMCAError,
    InternalError(String),
    DBError(String),
}

impl From<MyError> for DownloadError {
    fn from(err: MyError) -> DownloadError {
        DownloadError::DBError(err.description().into())
    }
}

impl From<io::Error> for DownloadError {
    fn from(err: io::Error) -> DownloadError {
        DownloadError::InternalError(err.description().into())
    }
}

impl<'a> Downloader<'a>{
    pub fn new(ddb: DownloadDB, defaults: &'a ConfigGen) -> Downloader<'a>{
        Downloader {ddb: ddb, defaults: defaults}
    }

    ///Regex matching: [download]  13.4% of 275.27MiB at 525.36KiB/s ETA 07:52
    ///
    ///Downloads a video, updates the DB
    ///TODO: get the sql statements out of the class
    ///TODO: wrap errors
    ///Doesn't care about DMCAs, will emit errors on them
    ///download_audio: ignore quality & download config set audio for split containers
    pub fn download_video(&self, file_path: &str, download_audio: bool) -> Result<bool,DownloadError> {
        println!("{:?}", self.ddb.url);
        let curr_quality = if download_audio {
            &self.ddb.audioquality
        }else{
            &self.ddb.quality
        };
        println!("quality: {}",curr_quality);
        let process = try!(self.run_download_process(file_path,curr_quality));
        let stdout = BufReader::new(process.stdout.unwrap());

        let mut conn = self.ddb.pool.get_conn().unwrap();
        let mut statement = self.prepare_progress_updater(&mut conn);
        let re = regex!(r"\d+\.\d");

        for line in stdout.lines(){
            match line{
                Err(why) => panic!("couldn't read cmd stdout: {}", Error::description(&why)),
                Ok(text) => {
                        println!("Out: {}",text);
                        match re.find(&text) {
                            Some(s) => { println!("Match at {}", s.0);
                                        println!("{}", &text[s.0..s.1]); // ONLY with ASCII chars makeable!
                                        self.update_progress(&mut statement, &text[s.0..s.1].to_string());
                                    },
                            None => println!("Detected no % match."),
                        }
                    },
            }
        }

        Ok(true)
    }

    ///Trys to get the original name of a file, while checking for availability
    ///
    pub fn get_file_name(&self) -> Result<String,DownloadError> {
        let process = try!(self.run_filename_process());
        let mut stdout_buffer = BufReader::new(process.stdout.unwrap());
        let mut stderr_buffer = BufReader::new(process.stderr.unwrap());

        let mut stdout: String = String::new();
        try!(stdout_buffer.read_to_string(&mut stdout));
        let mut stderr: String = String::new();
        try!(stderr_buffer.read_to_string(&mut stderr));
        println!("stderr: {:?}", stderr);
        println!("stdout: {:?}", stdout);
        if stderr.is_empty() == true {
            stdout.trim();
            println!("get_file_name: {:?}", stdout);
            Ok(stdout.trim().to_string())
        }else{
            if stderr.contains("not available in your country") {
                return Err(DownloadError::DMCAError);
            }else{
                return Err(DownloadError::DownloadError(stderr));
            }
        }
    }

    fn run_download_process(&self, file_path: &str, quality: &i16) -> Result<Child,DownloadError> {
        match Command::new("youtube-dl")
                                    .arg("--newline")
                                    .arg("-r")
                                    .arg(format!("{}M",self.defaults.download_mbps))
                                    .arg("-f")
                                    .arg(quality.to_string())
                                    .arg("-o")
                                    .arg(file_path)
                                    .arg(&self.ddb.url)
                                    .arg("2>&1")
                                    .stdin(Stdio::null())
                                    .stdout(Stdio::piped())
                                    .spawn() {
            Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
            Ok(process) => Ok(process),
        }
    }

    fn run_filename_process(&self) -> Result<Child,DownloadError> {
        match Command::new("youtube-dl")
                                    .arg("--get-filename")
                                    .arg(&self.ddb.url)
                                    .stdin(Stdio::null())
                                    .stdout(Stdio::piped())
                                    .stderr(Stdio::piped())
                                    .spawn() {
            Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
            Ok(process) => Ok(process),
        }
    }

    // MyPooledConn does only live when MyOpts is alive -> lifetime needs to be declared
    fn prepare_progress_updater(&'a self,conn: &'a mut MyPooledConn) -> Stmt<'a> { // no livetime needed: struct livetime used
        conn.prepare("UPDATE querydetails SET progress = ? WHERE qid = ?").unwrap()
    }

    ///updater called from the stdout progress
    fn update_progress(&self,stmt: &mut Stmt, progress: &String){
        stmt.execute(&[progress,&self.ddb.qid]);
    }

    ///This function does a 3rd party binding
    ///due to the country restrictions, in case it's needed
    ///Because hyper doesn't support timeout settings atm, we're calling an external
    ///lib
    ///The returned value contains the original video name, the lib downloads & saved
    ///the file at the given folder to the given name
    pub fn lib_request_video(&self) -> Result<String,DownloadError> {
        let process = try!(self.lib_request_video_cmd());

        let mut stdout_buffer = BufReader::new(process.stdout.unwrap());
        let mut stderr_buffer = BufReader::new(process.stderr.unwrap());

        let mut stdout: String = String::new();
        try!(stdout_buffer.read_to_string(&mut stdout));
        let mut stderr: String = String::new();
        try!(stderr_buffer.read_to_string(&mut stderr));
        println!("stdout: {:?}", stdout);
        if stderr.contains("error") {
            println!("stderr: {:?}", stderr);
            return Err(DownloadError::InternalError(stderr));
        }
        stdout.trim();
        println!("get_file_name: {:?}", stdout);
        Ok(stdout)
    }

    ///Generate the lib-cmd `request [..]?v=asdf -folder /downloads -a -name testfile`
    fn lib_request_video_cmd(&self) -> Result<Child,DownloadError> {
        println!("{:?}", format!("{} {}/offliberty.jar",self.defaults.jar_cmd,self.defaults.jar_folder));
        match Command::new(format!("{} {}/offliberty.jar",self.defaults.jar_cmd,self.defaults.jar_folder))
                                        .arg("request")
                                        .arg(&self.ddb.url)
                                        .arg("-folder")
                                        .arg(&self.ddb.folder)
                                        .arg(self.gen_request_str())
                                        .arg("-name")
                                        .arg(self.ddb.qid.to_string()) //eq. format! https://botbot.me/mozilla/rust/msg/37524131/
                                        .stdin(Stdio::null())
                                        .stdout(Stdio::piped())
                                        .stderr(Stdio::piped())
                                        .spawn() {
                Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
                Ok(process) => Ok(process),
            }
    }

    ///Generate -a or -v, based on if an audio or video quality is requested
    fn gen_request_str(&self) -> &'a str{
        if self.is_audio() {
            "-a"
        } else {
            "-v"
        }
    }

    ///Check if the quality is 141, standing for audio or not
    pub fn is_audio(&self) -> bool {
        match self.ddb.quality {
            k if(k == self.ddb.audioquality ) => true,
            _ => false,
        }
    }
}<commit_msg>*bugfix<commit_after>
extern crate regex;
use mysql::conn::pool::{MyPool,MyPooledConn};
use mysql::conn::Stmt;
use mysql::error::MyError;

use std::process::{Command, Stdio, Child};
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::io;
use lib::config::ConfigGen;
use std::convert::Into;

macro_rules! regex(
    ($s:expr) => (regex::Regex::new($s).unwrap());
);

#[derive(Clone)]
pub struct DownloadDB {
    pub url: String,
    pub quality: i16,
    pub playlist: bool,
    pub compress: bool,
    pub audioquality: i16,
    pub qid: i64,
    pub folder: String, // download folder, changes for playlists
    pub pool: MyPool,
}

pub struct Downloader<'a> {
    ddb: DownloadDB,
    defaults: &'a ConfigGen,
    // pool: MyPool,
}

#[derive(Debug)]
pub enum DownloadError{
    DownloadError(String),
    ReadError,
    DMCAError,
    InternalError(String),
    DBError(String),
}

impl From<MyError> for DownloadError {
    fn from(err: MyError) -> DownloadError {
        DownloadError::DBError(err.description().into())
    }
}

impl From<io::Error> for DownloadError {
    fn from(err: io::Error) -> DownloadError {
        DownloadError::InternalError(err.description().into())
    }
}

impl<'a> Downloader<'a>{
    pub fn new(ddb: DownloadDB, defaults: &'a ConfigGen) -> Downloader<'a>{
        Downloader {ddb: ddb, defaults: defaults}
    }

    ///Regex matching: [download]  13.4% of 275.27MiB at 525.36KiB/s ETA 07:52
    ///
    ///Downloads a video, updates the DB
    ///TODO: get the sql statements out of the class
    ///TODO: wrap errors
    ///Doesn't care about DMCAs, will emit errors on them
    ///download_audio: ignore quality & download config set audio for split containers
    pub fn download_video(&self, file_path: &str, download_audio: bool) -> Result<bool,DownloadError> {
        println!("{:?}", self.ddb.url);
        let curr_quality = if download_audio {
            &self.ddb.audioquality
        }else{
            &self.ddb.quality
        };
        println!("quality: {}",curr_quality);
        let process = try!(self.run_download_process(file_path,curr_quality));
        let stdout = BufReader::new(process.stdout.unwrap());

        let mut conn = self.ddb.pool.get_conn().unwrap();
        let mut statement = self.prepare_progress_updater(&mut conn);
        let re = regex!(r"\d+\.\d");

        for line in stdout.lines(){
            match line{
                Err(why) => panic!("couldn't read cmd stdout: {}", Error::description(&why)),
                Ok(text) => {
                        println!("Out: {}",text);
                        match re.find(&text) {
                            Some(s) => { println!("Match at {}", s.0);
                                        println!("{}", &text[s.0..s.1]); // ONLY with ASCII chars makeable!
                                        self.update_progress(&mut statement, &text[s.0..s.1].to_string());
                                    },
                            None => println!("Detected no % match."),
                        }
                    },
            }
        }

        Ok(true)
    }

    ///Trys to get the original name of a file, while checking for availability
    ///
    pub fn get_file_name(&self) -> Result<String,DownloadError> {
        let process = try!(self.run_filename_process());
        let mut stdout_buffer = BufReader::new(process.stdout.unwrap());
        let mut stderr_buffer = BufReader::new(process.stderr.unwrap());

        let mut stdout: String = String::new();
        try!(stdout_buffer.read_to_string(&mut stdout));
        let mut stderr: String = String::new();
        try!(stderr_buffer.read_to_string(&mut stderr));
        println!("stderr: {:?}", stderr);
        println!("stdout: {:?}", stdout);
        if stderr.is_empty() == true {
            stdout.trim();
            println!("get_file_name: {:?}", stdout);
            Ok(stdout.trim().to_string())
        }else{
            if stderr.contains("not available in your country") {
                return Err(DownloadError::DMCAError);
            }else{
                return Err(DownloadError::DownloadError(stderr));
            }
        }
    }

    fn run_download_process(&self, file_path: &str, quality: &i16) -> Result<Child,DownloadError> {
        match Command::new("youtube-dl")
                                    .arg("--newline")
                                    .arg("-r")
                                    .arg(format!("{}M",self.defaults.download_mbps))
                                    .arg("-f")
                                    .arg(quality.to_string())
                                    .arg("-o")
                                    .arg(file_path)
                                    .arg(&self.ddb.url)
                                    .stdin(Stdio::null())
                                    .stdout(Stdio::piped())
                                    .spawn() {
            Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
            Ok(process) => Ok(process),
        }
    }

    fn run_filename_process(&self) -> Result<Child,DownloadError> {
        match Command::new("youtube-dl")
                                    .arg("--get-filename")
                                    .arg(&self.ddb.url)
                                    .stdin(Stdio::null())
                                    .stdout(Stdio::piped())
                                    .stderr(Stdio::piped())
                                    .spawn() {
            Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
            Ok(process) => Ok(process),
        }
    }

    // MyPooledConn does only live when MyOpts is alive -> lifetime needs to be declared
    fn prepare_progress_updater(&'a self,conn: &'a mut MyPooledConn) -> Stmt<'a> { // no livetime needed: struct livetime used
        conn.prepare("UPDATE querydetails SET progress = ? WHERE qid = ?").unwrap()
    }

    ///updater called from the stdout progress
    fn update_progress(&self,stmt: &mut Stmt, progress: &String){
        stmt.execute(&[progress,&self.ddb.qid]);
    }

    ///This function does a 3rd party binding
    ///due to the country restrictions, in case it's needed
    ///Because hyper doesn't support timeout settings atm, we're calling an external
    ///lib
    ///The returned value contains the original video name, the lib downloads & saved
    ///the file at the given folder to the given name
    pub fn lib_request_video(&self) -> Result<String,DownloadError> {
        let process = try!(self.lib_request_video_cmd());

        let mut stdout_buffer = BufReader::new(process.stdout.unwrap());
        let mut stderr_buffer = BufReader::new(process.stderr.unwrap());

        let mut stdout: String = String::new();
        try!(stdout_buffer.read_to_string(&mut stdout));
        let mut stderr: String = String::new();
        try!(stderr_buffer.read_to_string(&mut stderr));
        println!("stdout: {:?}", stdout);
        if stderr.contains("error") {
            println!("stderr: {:?}", stderr);
            return Err(DownloadError::InternalError(stderr));
        }
        stdout.trim();
        println!("get_file_name: {:?}", stdout);
        Ok(stdout)
    }

    ///Generate the lib-cmd `request [..]?v=asdf -folder /downloads -a -name testfile`
    fn lib_request_video_cmd(&self) -> Result<Child,DownloadError> {
        println!("{:?}", format!("{} {}/offliberty.jar",self.defaults.jar_cmd,self.defaults.jar_folder));
        match Command::new(format!("{} {}/offliberty.jar",self.defaults.jar_cmd,self.defaults.jar_folder))
                                        .arg("request")
                                        .arg(&self.ddb.url)
                                        .arg("-folder")
                                        .arg(&self.ddb.folder)
                                        .arg(self.gen_request_str())
                                        .arg("-name")
                                        .arg(self.ddb.qid.to_string()) //eq. format! https://botbot.me/mozilla/rust/msg/37524131/
                                        .stdin(Stdio::null())
                                        .stdout(Stdio::piped())
                                        .stderr(Stdio::piped())
                                        .spawn() {
                Err(why) => Err(DownloadError::InternalError(Error::description(&why).into())),
                Ok(process) => Ok(process),
            }
    }

    ///Generate -a or -v, based on if an audio or video quality is requested
    fn gen_request_str(&self) -> &'a str{
        if self.is_audio() {
            "-a"
        } else {
            "-v"
        }
    }

    ///Check if the quality is 141, standing for audio or not
    pub fn is_audio(&self) -> bool {
        match self.ddb.quality {
            k if(k == self.ddb.audioquality ) => true,
            _ => false,
        }
    }
}

#[test]
fn conversion(){

}<|endoftext|>


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

//! A pointer type for heap allocation.
//!
//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
//! drop their contents when they go out of scope.
//!
//! Boxes are useful in two situations: recursive data structures, and
//! occasionally when returning data. [The Pointer chapter of the
//! Book](../../../book/pointers.html#best-practices-1) explains these cases in
//! detail.
//!
//! # Examples
//!
//! Creating a box:
//!
//! ```
//! let x = Box::new(5);
//! ```
//!
//! Creating a recursive data structure:
//!
//! ```
//! #[derive(Debug)]
//! enum List<T> {
//!     Cons(T, Box<List<T>>),
//!     Nil,
//! }
//!
//! fn main() {
//!     let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
//!     println!("{:?}", list);
//! }
//! ```
//!
//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.

#![stable(feature = "rust1", since = "1.0.0")]

use core::prelude::*;

use core::any::Any;
use core::cmp::Ordering;
use core::default::Default;
use core::fmt;
use core::hash::{self, Hash};
use core::mem;
use core::ops::{Deref, DerefMut};
use core::ptr::{Unique};
use core::raw::{TraitObject};

/// A value that represents the heap. This is the default place that the `box`
/// keyword allocates into when no place is supplied.
///
/// The following two examples are equivalent:
///
/// ```
/// # #![feature(alloc)]
/// #![feature(box_syntax)]
/// use std::boxed::HEAP;
///
/// fn main() {
///     let foo = box(HEAP) 5;
///     let foo = box 5;
/// }
/// ```
#[lang = "exchange_heap"]
#[unstable(feature = "alloc",
           reason = "may be renamed; uncertain about custom allocator design")]
pub static HEAP: () = ();

/// A pointer type for heap allocation.
///
/// See the [module-level documentation](../../std/boxed/index.html) for more.
#[lang = "owned_box"]
#[stable(feature = "rust1", since = "1.0.0")]
#[fundamental]
pub struct Box<T>(Unique<T>);

impl<T> Box<T> {
    /// Allocates memory on the heap and then moves `x` into it.
    ///
    /// # Examples
    ///
    /// ```
    /// let x = Box::new(5);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline(always)]
    pub fn new(x: T) -> Box<T> {
        box x
    }
}

impl<T : ?Sized> Box<T> {
    /// Constructs a box from the raw pointer.
    ///
    /// After this function call, pointer is owned by resulting box.
    /// In particular, it means that `Box` destructor calls destructor
    /// of `T` and releases memory. Since the way `Box` allocates and
    /// releases memory is unspecified, the only valid pointer to pass
    /// to this function is the one taken from another `Box` with
    /// `boxed::into_raw` function.
    ///
    /// Function is unsafe, because improper use of this function may
    /// lead to memory problems like double-free, for example if the
    /// function is called twice on the same raw pointer.
    #[unstable(feature = "alloc",
               reason = "may be renamed or moved out of Box scope")]
    #[inline]
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        mem::transmute(raw)
    }
}

/// Consumes the `Box`, returning the wrapped raw pointer.
///
/// After call to this function, caller is responsible for the memory
/// previously managed by `Box`, in particular caller should properly
/// destroy `T` and release memory. The proper way to do it is to
/// convert pointer back to `Box` with `Box::from_raw` function, because
/// `Box` does not specify, how memory is allocated.
///
/// Function is unsafe, because result of this function is no longer
/// automatically managed that may lead to memory or other resource
/// leak.
///
/// # Examples
/// ```
/// # #![feature(alloc)]
/// use std::boxed;
///
/// let seventeen = Box::new(17u32);
/// let raw = unsafe { boxed::into_raw(seventeen) };
/// let boxed_again = unsafe { Box::from_raw(raw) };
/// ```
#[unstable(feature = "alloc",
           reason = "may be renamed")]
#[inline]
pub unsafe fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
    mem::transmute(b)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Box<T> {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Box<T> { box Default::default() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Box<[T]> {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> Clone for Box<T> {
    /// Returns a new box with a `clone()` of this box's contents.
    ///
    /// # Examples
    ///
    /// ```
    /// let x = Box::new(5);
    /// let y = x.clone();
    /// ```
    #[inline]
    fn clone(&self) -> Box<T> { box {(**self).clone()} }

    /// Copies `source`'s contents into `self` without creating a new allocation.
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(alloc, core)]
    /// let x = Box::new(5);
    /// let mut y = Box::new(10);
    ///
    /// y.clone_from(&x);
    ///
    /// assert_eq!(*y, 5);
    /// ```
    #[inline]
    fn clone_from(&mut self, source: &Box<T>) {
        (**self).clone_from(&(**source));
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
    #[inline]
    fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
    #[inline]
    fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
    #[inline]
    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
    #[inline]
    fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
    #[inline]
    fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
    #[inline]
    fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
    #[inline]
    fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord> Ord for Box<T> {
    #[inline]
    fn cmp(&self, other: &Box<T>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Eq> Eq for Box<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Hash> Hash for Box<T> {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        (**self).hash(state);
    }
}

impl Box<Any> {
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = into_raw(self);
                let to: TraitObject =
                    mem::transmute::<*mut Any, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Box<Any+Send> {
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
        <Box<Any>>::downcast(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Pointer for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // It's not possible to extract the inner Uniq directly from the Box,
        // instead we cast it to a *const which aliases the Unique
        let ptr: *const T = &**self;
        fmt::Pointer::fmt(&ptr, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for Box<T> {
    fn deref_mut(&mut self) -> &mut T { &mut **self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator + ?Sized> Iterator for Box<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> { (**self).next() }
    fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
    fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}

/// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a
/// `Box<FnOnce()>` in a data structure, you should use
/// `Box<FnBox()>`. The two traits behave essentially the same, except
/// that a `FnBox` closure can only be called if it is boxed. (Note
/// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
/// closures become directly usable.)
///
/// ### Example
///
/// Here is a snippet of code which creates a hashmap full of boxed
/// once closures and then removes them one by one, calling each
/// closure as it is removed. Note that the type of the closures
/// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
/// -> i32>`.
///
/// ```
/// #![feature(core)]
///
/// use std::boxed::FnBox;
/// use std::collections::HashMap;
///
/// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
///     let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
///     map.insert(1, Box::new(|| 22));
///     map.insert(2, Box::new(|| 44));
///     map
/// }
///
/// fn main() {
///     let mut map = make_map();
///     for i in &[1, 2] {
///         let f = map.remove(&i).unwrap();
///         assert_eq!(f(), i * 22);
///     }
/// }
/// ```
#[rustc_paren_sugar]
#[unstable(feature = "core", reason = "Newly introduced")]
pub trait FnBox<A> {
    type Output;

    fn call_box(self: Box<Self>, args: A) -> Self::Output;
}

impl<A,F> FnBox<A> for F
    where F: FnOnce<A>
{
    type Output = F::Output;

    fn call_box(self: Box<F>, args: A) -> F::Output {
        self.call_once(args)
    }
}

impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+'a> {
    type Output = R;

    extern "rust-call" fn call_once(self, args: A) -> R {
        self.call_box(args)
    }
}

impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
    type Output = R;

    extern "rust-call" fn call_once(self, args: A) -> R {
        self.call_box(args)
    }
}
<commit_msg>Clean up Box documentation.<commit_after>// Copyright 2012-2015 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.

//! A pointer type for heap allocation.
//!
//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in
//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of
//! scope.
//!
//! # Examples
//!
//! Creating a box:
//!
//! ```
//! let x = Box::new(5);
//! ```
//!
//! Creating a recursive data structure:
//!
//! ```
//! #[derive(Debug)]
//! enum List<T> {
//!     Cons(T, Box<List<T>>),
//!     Nil,
//! }
//!
//! fn main() {
//!     let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
//!     println!("{:?}", list);
//! }
//! ```
//!
//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.
//!
//! Recursive structures must be boxed, because if the definition of `Cons` looked like this:
//!
//! ```rust,ignore
//! Cons(T, List<T>),
//! ```
//!
//! It wouldn't work. This is because the size of a `List` depends on how many elements are in the
//! list, and so we don't know how much memory to allocate for a `Cons`. By introducing a `Box`,
//! which has a defined size, we know how big `Cons` needs to be.

#![stable(feature = "rust1", since = "1.0.0")]

use core::prelude::*;

use core::any::Any;
use core::cmp::Ordering;
use core::default::Default;
use core::fmt;
use core::hash::{self, Hash};
use core::mem;
use core::ops::{Deref, DerefMut};
use core::ptr::{Unique};
use core::raw::{TraitObject};

/// A value that represents the heap. This is the default place that the `box`
/// keyword allocates into when no place is supplied.
///
/// The following two examples are equivalent:
///
/// ```
/// # #![feature(alloc)]
/// #![feature(box_syntax)]
/// use std::boxed::HEAP;
///
/// fn main() {
///     let foo = box(HEAP) 5;
///     let foo = box 5;
/// }
/// ```
#[lang = "exchange_heap"]
#[unstable(feature = "alloc",
           reason = "may be renamed; uncertain about custom allocator design")]
pub static HEAP: () = ();

/// A pointer type for heap allocation.
///
/// See the [module-level documentation](../../std/boxed/index.html) for more.
#[lang = "owned_box"]
#[stable(feature = "rust1", since = "1.0.0")]
#[fundamental]
pub struct Box<T>(Unique<T>);

impl<T> Box<T> {
    /// Allocates memory on the heap and then moves `x` into it.
    ///
    /// # Examples
    ///
    /// ```
    /// let x = Box::new(5);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline(always)]
    pub fn new(x: T) -> Box<T> {
        box x
    }
}

impl<T : ?Sized> Box<T> {
    /// Constructs a box from the raw pointer.
    ///
    /// After this function call, pointer is owned by resulting box.
    /// In particular, it means that `Box` destructor calls destructor
    /// of `T` and releases memory. Since the way `Box` allocates and
    /// releases memory is unspecified, the only valid pointer to pass
    /// to this function is the one taken from another `Box` with
    /// `boxed::into_raw` function.
    ///
    /// Function is unsafe, because improper use of this function may
    /// lead to memory problems like double-free, for example if the
    /// function is called twice on the same raw pointer.
    #[unstable(feature = "alloc",
               reason = "may be renamed or moved out of Box scope")]
    #[inline]
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        mem::transmute(raw)
    }
}

/// Consumes the `Box`, returning the wrapped raw pointer.
///
/// After call to this function, caller is responsible for the memory
/// previously managed by `Box`, in particular caller should properly
/// destroy `T` and release memory. The proper way to do it is to
/// convert pointer back to `Box` with `Box::from_raw` function, because
/// `Box` does not specify, how memory is allocated.
///
/// Function is unsafe, because result of this function is no longer
/// automatically managed that may lead to memory or other resource
/// leak.
///
/// # Examples
/// ```
/// # #![feature(alloc)]
/// use std::boxed;
///
/// let seventeen = Box::new(17u32);
/// let raw = unsafe { boxed::into_raw(seventeen) };
/// let boxed_again = unsafe { Box::from_raw(raw) };
/// ```
#[unstable(feature = "alloc",
           reason = "may be renamed")]
#[inline]
pub unsafe fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
    mem::transmute(b)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Box<T> {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Box<T> { box Default::default() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Box<[T]> {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> Clone for Box<T> {
    /// Returns a new box with a `clone()` of this box's contents.
    ///
    /// # Examples
    ///
    /// ```
    /// let x = Box::new(5);
    /// let y = x.clone();
    /// ```
    #[inline]
    fn clone(&self) -> Box<T> { box {(**self).clone()} }

    /// Copies `source`'s contents into `self` without creating a new allocation.
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(alloc, core)]
    /// let x = Box::new(5);
    /// let mut y = Box::new(10);
    ///
    /// y.clone_from(&x);
    ///
    /// assert_eq!(*y, 5);
    /// ```
    #[inline]
    fn clone_from(&mut self, source: &Box<T>) {
        (**self).clone_from(&(**source));
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
    #[inline]
    fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
    #[inline]
    fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
    #[inline]
    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
    #[inline]
    fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
    #[inline]
    fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
    #[inline]
    fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
    #[inline]
    fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord> Ord for Box<T> {
    #[inline]
    fn cmp(&self, other: &Box<T>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Eq> Eq for Box<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Hash> Hash for Box<T> {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        (**self).hash(state);
    }
}

impl Box<Any> {
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = into_raw(self);
                let to: TraitObject =
                    mem::transmute::<*mut Any, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Box<Any+Send> {
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
        <Box<Any>>::downcast(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Pointer for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // It's not possible to extract the inner Uniq directly from the Box,
        // instead we cast it to a *const which aliases the Unique
        let ptr: *const T = &**self;
        fmt::Pointer::fmt(&ptr, f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for Box<T> {
    fn deref_mut(&mut self) -> &mut T { &mut **self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator + ?Sized> Iterator for Box<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> { (**self).next() }
    fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
    fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}

/// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a
/// `Box<FnOnce()>` in a data structure, you should use
/// `Box<FnBox()>`. The two traits behave essentially the same, except
/// that a `FnBox` closure can only be called if it is boxed. (Note
/// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
/// closures become directly usable.)
///
/// ### Example
///
/// Here is a snippet of code which creates a hashmap full of boxed
/// once closures and then removes them one by one, calling each
/// closure as it is removed. Note that the type of the closures
/// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
/// -> i32>`.
///
/// ```
/// #![feature(core)]
///
/// use std::boxed::FnBox;
/// use std::collections::HashMap;
///
/// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
///     let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
///     map.insert(1, Box::new(|| 22));
///     map.insert(2, Box::new(|| 44));
///     map
/// }
///
/// fn main() {
///     let mut map = make_map();
///     for i in &[1, 2] {
///         let f = map.remove(&i).unwrap();
///         assert_eq!(f(), i * 22);
///     }
/// }
/// ```
#[rustc_paren_sugar]
#[unstable(feature = "core", reason = "Newly introduced")]
pub trait FnBox<A> {
    type Output;

    fn call_box(self: Box<Self>, args: A) -> Self::Output;
}

impl<A,F> FnBox<A> for F
    where F: FnOnce<A>
{
    type Output = F::Output;

    fn call_box(self: Box<F>, args: A) -> F::Output {
        self.call_once(args)
    }
}

impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+'a> {
    type Output = R;

    extern "rust-call" fn call_once(self, args: A) -> R {
        self.call_box(args)
    }
}

impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
    type Output = R;

    extern "rust-call" fn call_once(self, args: A) -> R {
        self.call_box(args)
    }
}
<|endoftext|>


<commit_before>use super::game;
use super::cards;
use super::pos;

#[derive(PartialEq)]
pub enum Target {
    Contract80,
    Contract90,
    Contract100,
    Contract110,
    Contract120,
    Contract130,
    Contract140,
    Contract150,
    Contract160,
    ContractCapot,
}

impl Target {
    pub fn score(&self) -> i32 {
        match *self {
            Target::Contract80 => 80,
            Target::Contract90 => 90,
            Target::Contract100 => 100,
            Target::Contract110 => 110,
            Target::Contract120 => 120,
            Target::Contract130 => 130,
            Target::Contract140 => 140,
            Target::Contract150 => 150,
            Target::Contract160 => 160,
            Target::ContractCapot => 250,
        }
    }

    pub fn victory(&self, score: i32, capot: bool) -> bool {
        match *self {
            Target::Contract80 => score >= 80,
            Target::Contract90 => score >= 90,
            Target::Contract100 => score >= 100,
            Target::Contract110 => score >= 110,
            Target::Contract120 => score >= 120,
            Target::Contract130 => score >= 130,
            Target::Contract140 => score >= 140,
            Target::Contract150 => score >= 150,
            Target::Contract160 => score >= 160,
            Target::ContractCapot => capot,
        }
    }
}

pub struct Contract {
    pub trump: cards::Suit,
    pub author: pos::PlayerPos,
    pub target: Target,
    pub coinche_level: i32,
}

pub struct Auction {
    history: Vec<Contract>,
    pass_count: usize,
    first: pos::PlayerPos,
    stopped: bool,
    players: [cards::Hand; 4],
}

pub fn new_auction(first: pos::PlayerPos) -> Auction {
    Auction {
        history: Vec::new(),
        pass_count: 0,
        stopped: false,
        first: first,
        players: super::deal_hands(),
    }
}

impl Auction {

    fn can_bid(&self, contract: &Contract) -> Result<(),String> {
        if self.stopped {
            return Err("auction is closed".to_string());
        }

        if contract.coinche_level != 0 {
            return Err("cannot bid pre-coinched contract".to_string());
        }

        if !self.history.is_empty() {
            if contract.author != self.current_contract().expect("no contract found").author.next_n(self.pass_count + 1) {
                return Err("wrong player order".to_string());
            }
            if contract.target.score() <= self.history[self.history.len()-1].target.score() {
                return Err("must bid higher than current contract".to_string());
            }
        } else {
            if contract.author != self.first.next_n(self.pass_count) {
                return Err(format!("wrong player order: expected {}", self.first.next_n(self.pass_count).0));
            }
        }

        Ok(())
    }

    // Bid a new, higher contract.
    pub fn bid(&mut self, contract: Contract) -> Result<bool,String> {
        match self.can_bid(&contract) {
            Err(msg) => return Err(msg),
            Ok(_) => (),
        }

        self.stopped = contract.target == Target::ContractCapot;

        self.history.push(contract);
        self.pass_count = 0;

        // Only stops the bids if the guy asked for a capot
        Ok(self.stopped)
    }

    pub fn current_contract(&self) -> Option<&Contract> {
        if self.history.is_empty() {
            None
        } else {
            Some(&self.history[self.history.len() - 1])
        }
    }

    pub fn hands(&self) -> &[cards::Hand; 4] {
        &self.players
    }

    pub fn pass(&mut self) -> bool {
        self.pass_count += 1;

        // After 3 passes, we're back to the contract author, and we can start.
        let pass_limit = if !self.history.is_empty() {
            3
        } else {
            4
        };

        self.stopped = self.pass_count == pass_limit;

        self.stopped
    }

    pub fn coinche(&mut self) -> Result<bool,String> {
        if self.history.is_empty() {
            Err("no contract to coinche".to_string())
        } else {
            self.stopped = true;
            let i = self.history.len() - 1;
            if self.history[i].coinche_level > 1 {
                Err("constract is already sur-coinched".to_string())
            } else {
                self.history[i].coinche_level += 1;
                // Stop if we are already sur-coinching
                Ok(self.history[i].coinche_level == 2)
            }
        }
    }

    // Moves the auction to kill it
    pub fn complete(mut self) -> Result<game::GameState,String> {
        if !self.stopped {
            Err("auction is still running".to_string())
        } else if self.history.is_empty() {
            Err("no contract to start the game with".to_string())
        } else {
            Ok(game::new_game(self.first, self.players, self.history.pop().expect("contract history empty")))
        }
    }
}

#[test]
fn test_auction() {
    let mut auction = new_auction(pos::PlayerPos(0));

    assert!(!auction.stopped);

    // First three people pass.
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(!auction.pass());

    // Someone bids.
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(3),
        trump: cards::HEART,
        target: Target::Contract80,
        coinche_level: 0,
    }), Ok(false));
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(0),
        trump: cards::CLUB,
        target: Target::Contract80,
        coinche_level: 0,
    }).ok(), None);
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::CLUB,
        target: Target::Contract100,
        coinche_level: 0,
    }).ok(), None);
    assert!(!auction.pass());
    // Partner surbids
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::HEART,
        target: Target::Contract100,
        coinche_level: 0,
    }), Ok(false));
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(auction.pass());

    assert!(auction.stopped);

    match auction.complete() {
        Err(_) => assert!(false),
        _=> {},
    }
}
<commit_msg>Add enum error to bidding<commit_after>use super::game;
use super::cards;
use super::pos;

#[derive(PartialEq)]
pub enum Target {
    Contract80,
    Contract90,
    Contract100,
    Contract110,
    Contract120,
    Contract130,
    Contract140,
    Contract150,
    Contract160,
    ContractCapot,
}

impl Target {
    pub fn score(&self) -> i32 {
        match *self {
            Target::Contract80 => 80,
            Target::Contract90 => 90,
            Target::Contract100 => 100,
            Target::Contract110 => 110,
            Target::Contract120 => 120,
            Target::Contract130 => 130,
            Target::Contract140 => 140,
            Target::Contract150 => 150,
            Target::Contract160 => 160,
            Target::ContractCapot => 250,
        }
    }

    pub fn victory(&self, score: i32, capot: bool) -> bool {
        match *self {
            Target::Contract80 => score >= 80,
            Target::Contract90 => score >= 90,
            Target::Contract100 => score >= 100,
            Target::Contract110 => score >= 110,
            Target::Contract120 => score >= 120,
            Target::Contract130 => score >= 130,
            Target::Contract140 => score >= 140,
            Target::Contract150 => score >= 150,
            Target::Contract160 => score >= 160,
            Target::ContractCapot => capot,
        }
    }
}

pub struct Contract {
    pub trump: cards::Suit,
    pub author: pos::PlayerPos,
    pub target: Target,
    pub coinche_level: i32,
}

#[derive(PartialEq,Clone,Copy,Debug)]
pub enum AuctionState {
    Bidding,
    Coinching,
    Over,
}

pub struct Auction {
    history: Vec<Contract>,
    pass_count: usize,
    first: pos::PlayerPos,
    state: AuctionState,
    players: [cards::Hand; 4],
}

pub fn new_auction(first: pos::PlayerPos) -> Auction {
    Auction {
        history: Vec::new(),
        pass_count: 0,
        state: AuctionState::Bidding,
        first: first,
        players: super::deal_hands(),
    }
}

#[derive(PartialEq,Debug)]
pub enum BidError {
    AuctionClosed,
    PreCoinchedContract,
    TurnError,
    NonRaisedTarget,
}

impl Auction {

    fn can_bid(&self, contract: &Contract) -> Result<(),BidError> {
        if self.state != AuctionState::Bidding {
            return Err(BidError::AuctionClosed);
        }

        if contract.coinche_level != 0 {
            return Err(BidError::PreCoinchedContract);
        }

        if !self.history.is_empty() {
            if contract.author != self.current_contract().expect("no contract found").author.next_n(self.pass_count + 1) {
                return Err(BidError::TurnError);
            }
            if contract.target.score() <= self.history[self.history.len()-1].target.score() {
                return Err(BidError::NonRaisedTarget);
            }
        } else {
            if contract.author != self.first.next_n(self.pass_count) {
                return Err(BidError::TurnError);
            }
        }

        Ok(())
    }

    // Bid a new, higher contract.
    pub fn bid(&mut self, contract: Contract) -> Result<AuctionState,BidError> {
        match self.can_bid(&contract) {
            Err(err) => return Err(err),
            Ok(_) => (),
        }

        if contract.target == Target::ContractCapot {
            self.state = AuctionState::Coinching;
        }

        self.history.push(contract);
        self.pass_count = 0;

        // Only stops the bids if the guy asked for a capot
        Ok(self.state)
    }

    pub fn current_contract(&self) -> Option<&Contract> {
        if self.history.is_empty() {
            None
        } else {
            Some(&self.history[self.history.len() - 1])
        }
    }

    pub fn hands(&self) -> &[cards::Hand; 4] {
        &self.players
    }

    pub fn pass(&mut self) -> AuctionState {
        self.pass_count += 1;

        // After 3 passes, we're back to the contract author, and we can start.
        let pass_limit = if !self.history.is_empty() {
            3
        } else {
            4
        };

        if self.pass_count == pass_limit {
            self.state = AuctionState::Over;
        }

        self.state
    }

    pub fn coinche(&mut self) -> Result<AuctionState,String> {
        if self.history.is_empty() {
            Err("no contract to coinche".to_string())
        } else {
            let i = self.history.len() - 1;
            if self.history[i].coinche_level > 1 {
                Err("constract is already sur-coinched".to_string())
            } else {
                self.history[i].coinche_level += 1;
                // Stop if we are already sur-coinching
                self.state = if self.history[i].coinche_level == 2 {
                    AuctionState::Over
                } else {
                    AuctionState::Coinching
                };

                Ok(self.state)
            }
        }
    }

    // Moves the auction to kill it
    pub fn complete(mut self) -> Result<game::GameState,String> {
        if self.state != AuctionState::Over {
            Err("auction is still running".to_string())
        } else if self.history.is_empty() {
            Err("no contract to start the game with".to_string())
        } else {
            Ok(game::new_game(self.first, self.players, self.history.pop().expect("contract history empty")))
        }
    }
}

#[test]
fn test_auction() {
    let mut auction = new_auction(pos::PlayerPos(0));

    assert!(auction.state == AuctionState::Bidding);

    // First three people pass.
    assert_eq!(auction.pass(), AuctionState::Bidding);
    assert_eq!(auction.pass(), AuctionState::Bidding);
    assert_eq!(auction.pass(), AuctionState::Bidding);

    // Someone bids.
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(3),
        trump: cards::HEART,
        target: Target::Contract80,
        coinche_level: 0,
    }), Ok(AuctionState::Bidding));
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(0),
        trump: cards::CLUB,
        target: Target::Contract80,
        coinche_level: 0,
    }).err(), Some(BidError::NonRaisedTarget));
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::CLUB,
        target: Target::Contract100,
        coinche_level: 0,
    }).err(), Some(BidError::TurnError));
    assert_eq!(auction.pass(), AuctionState::Bidding);
    // Partner surbids
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::HEART,
        target: Target::Contract100,
        coinche_level: 0,
    }), Ok(AuctionState::Bidding));
    assert_eq!(auction.pass(), AuctionState::Bidding);
    assert_eq!(auction.pass(), AuctionState::Bidding);
    assert_eq!(auction.pass(), AuctionState::Over);

    assert!(auction.state == AuctionState::Over);

    match auction.complete() {
        Err(_) => assert!(false),
        _=> {},
    }
}
<|endoftext|>


<commit_before>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! A type that represents one of two alternatives

use cmp::Eq;
use result::Result;

/// The either type
enum Either<T, U> {
    Left(T),
    Right(U)
}

fn either<T, U, V>(f_left: fn((&T)) -> V,
                   f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
    /*!
     * Applies a function based on the given either value
     *
     * If `value` is left(T) then `f_left` is applied to its contents, if
     * `value` is right(U) then `f_right` is applied to its contents, and the
     * result is returned.
     */

    match *value {
      Left(ref l) => f_left(l),
      Right(ref r) => f_right(r)
    }
}

fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
    //! Extracts from a vector of either all the left values

    do vec::build_sized(eithers.len()) |push| {
        for vec::each(eithers) |elt| {
            match *elt {
                Left(ref l) => { push(*l); }
                _ => { /* fallthrough */ }
            }
        }
    }
}

fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
    //! Extracts from a vector of either all the right values

    do vec::build_sized(eithers.len()) |push| {
        for vec::each(eithers) |elt| {
            match *elt {
                Right(ref r) => { push(*r); }
                _ => { /* fallthrough */ }
            }
        }
    }
}

fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
    -> {lefts: ~[T], rights: ~[U]} {
    /*!
     * Extracts from a vector of either all the left values and right values
     *
     * Returns a structure containing a vector of left values and a vector of
     * right values.
     */

    let mut lefts: ~[T] = ~[];
    let mut rights: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match *elt {
          Left(l) => lefts.push(l),
          Right(r) => rights.push(r)
        }
    }
    return {lefts: move lefts, rights: move rights};
}

pure fn flip<T: Copy, U: Copy>(eith: &Either<T, U>) -> Either<U, T> {
    //! Flips between left and right of a given either

    match *eith {
      Right(r) => Left(r),
      Left(l) => Right(l)
    }
}

pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>) -> Result<U, T> {
    /*!
     * Converts either::t to a result::t
     *
     * Converts an `either` type to a `result` type, making the "right" choice
     * an ok result, and the "left" choice a fail
     */

    match *eith {
      Right(r) => result::Ok(r),
      Left(l) => result::Err(l)
    }
}

pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a left

    match *eith { Left(_) => true, _ => false }
}

pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a right

    match *eith { Right(_) => true, _ => false }
}

pure fn unwrap_left<T,U>(+eith: Either<T,U>) -> T {
    //! Retrieves the value in the left branch. Fails if the either is Right.

    match move eith {
        Left(move x) => move x, Right(_) => fail ~"either::unwrap_left Right"
    }
}

pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
    //! Retrieves the value in the right branch. Fails if the either is Left.

    match move eith {
        Right(move x) => move x, Left(_) => fail ~"either::unwrap_right Left"
    }
}

impl<T:Eq,U:Eq> Either<T,U> : Eq {
    pure fn eq(other: &Either<T,U>) -> bool {
        match self {
            Left(a) => {
                match (*other) {
                    Left(ref b) => a.eq(b),
                    Right(_) => false
                }
            }
            Right(a) => {
                match (*other) {
                    Left(_) => false,
                    Right(ref b) => a.eq(b)
                }
            }
        }
    }
    pure fn ne(other: &Either<T,U>) -> bool { !self.eq(other) }
}

#[test]
fn test_either_left() {
    let val = Left(10);
    fn f_left(x: &int) -> bool { *x == 10 }
    fn f_right(_x: &uint) -> bool { false }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_either_right() {
    let val = Right(10u);
    fn f_left(_x: &int) -> bool { false }
    fn f_right(x: &uint) -> bool { *x == 10u }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_lefts() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = lefts(input);
    assert (result == ~[10, 12, 14]);
}

#[test]
fn test_lefts_none() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_lefts_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = rights(input);
    assert (result == ~[11, 13]);
}

#[test]
fn test_rights_none() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_partition() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = partition(input);
    assert (result.lefts[0] == 10);
    assert (result.lefts[1] == 12);
    assert (result.lefts[2] == 14);
    assert (result.rights[0] == 11);
    assert (result.rights[1] == 13);
}

#[test]
fn test_partition_no_lefts() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 2u);
}

#[test]
fn test_partition_no_rights() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 2u);
    assert (vec::len(result.rights) == 0u);
}

#[test]
fn test_partition_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 0u);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<commit_msg>Fix patterns in either<commit_after>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! A type that represents one of two alternatives

use cmp::Eq;
use result::Result;

/// The either type
enum Either<T, U> {
    Left(T),
    Right(U)
}

fn either<T, U, V>(f_left: fn((&T)) -> V,
                   f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
    /*!
     * Applies a function based on the given either value
     *
     * If `value` is left(T) then `f_left` is applied to its contents, if
     * `value` is right(U) then `f_right` is applied to its contents, and the
     * result is returned.
     */

    match *value {
      Left(ref l) => f_left(l),
      Right(ref r) => f_right(r)
    }
}

fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
    //! Extracts from a vector of either all the left values

    do vec::build_sized(eithers.len()) |push| {
        for vec::each(eithers) |elt| {
            match *elt {
                Left(ref l) => { push(*l); }
                _ => { /* fallthrough */ }
            }
        }
    }
}

fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
    //! Extracts from a vector of either all the right values

    do vec::build_sized(eithers.len()) |push| {
        for vec::each(eithers) |elt| {
            match *elt {
                Right(ref r) => { push(*r); }
                _ => { /* fallthrough */ }
            }
        }
    }
}

fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
    -> {lefts: ~[T], rights: ~[U]} {
    /*!
     * Extracts from a vector of either all the left values and right values
     *
     * Returns a structure containing a vector of left values and a vector of
     * right values.
     */

    let mut lefts: ~[T] = ~[];
    let mut rights: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match *elt {
          Left(copy l) => lefts.push(l),
          Right(copy r) => rights.push(r)
        }
    }
    return {lefts: move lefts, rights: move rights};
}

pure fn flip<T: Copy, U: Copy>(eith: &Either<T, U>) -> Either<U, T> {
    //! Flips between left and right of a given either

    match *eith {
      Right(copy r) => Left(r),
      Left(copy l) => Right(l)
    }
}

pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>) -> Result<U, T> {
    /*!
     * Converts either::t to a result::t
     *
     * Converts an `either` type to a `result` type, making the "right" choice
     * an ok result, and the "left" choice a fail
     */

    match *eith {
      Right(copy r) => result::Ok(r),
      Left(copy l) => result::Err(l)
    }
}

pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a left

    match *eith { Left(_) => true, _ => false }
}

pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a right

    match *eith { Right(_) => true, _ => false }
}

pure fn unwrap_left<T,U>(+eith: Either<T,U>) -> T {
    //! Retrieves the value in the left branch. Fails if the either is Right.

    match move eith {
        Left(move x) => move x, Right(_) => fail ~"either::unwrap_left Right"
    }
}

pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
    //! Retrieves the value in the right branch. Fails if the either is Left.

    match move eith {
        Right(move x) => move x, Left(_) => fail ~"either::unwrap_right Left"
    }
}

impl<T:Eq,U:Eq> Either<T,U> : Eq {
    pure fn eq(other: &Either<T,U>) -> bool {
        match self {
            Left(ref a) => {
                match (*other) {
                    Left(ref b) => (*a).eq(b),
                    Right(_) => false
                }
            }
            Right(ref a) => {
                match (*other) {
                    Left(_) => false,
                    Right(ref b) => (*a).eq(b)
                }
            }
        }
    }
    pure fn ne(other: &Either<T,U>) -> bool { !self.eq(other) }
}

#[test]
fn test_either_left() {
    let val = Left(10);
    fn f_left(x: &int) -> bool { *x == 10 }
    fn f_right(_x: &uint) -> bool { false }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_either_right() {
    let val = Right(10u);
    fn f_left(_x: &int) -> bool { false }
    fn f_right(x: &uint) -> bool { *x == 10u }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_lefts() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = lefts(input);
    assert (result == ~[10, 12, 14]);
}

#[test]
fn test_lefts_none() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_lefts_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = rights(input);
    assert (result == ~[11, 13]);
}

#[test]
fn test_rights_none() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_partition() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = partition(input);
    assert (result.lefts[0] == 10);
    assert (result.lefts[1] == 12);
    assert (result.lefts[2] == 14);
    assert (result.rights[0] == 11);
    assert (result.rights[1] == 13);
}

#[test]
fn test_partition_no_lefts() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 2u);
}

#[test]
fn test_partition_no_rights() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 2u);
    assert (vec::len(result.rights) == 0u);
}

#[test]
fn test_partition_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 0u);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<|endoftext|>


<commit_before>#[macro_escape];

macro_rules! lua_struct(
    ($name:ident {
        $( $field:ident: $ty:ty ),+
    }) => {
        mod $name
        {
            use lua::state::State;
            use lua::traits::{FromLua, ToLua};

            #[deriving(Clone, Eq)]
            pub struct $name
            {
                $( $field: $ty, )+
            }

            impl FromLua for $name
            {
                fn from_lua(state: &State, idx: int) -> Option<$name>
                {
                    let s = $name {
                        $(
                        $field: {
                            state.get_field(idx, stringify!($field));
                            let r = match FromLua::from_lua(state, idx) {
                                Some(r) => r,
                                None => {
                                    return None;
                                }
                            };
                            state.pop(1);

                            r
                        },
                        )+
                    };

                    Some(s)
                }
            }

            impl ToLua for $name
            {
                fn to_lua(&self, state: &State)
                {
                    state.new_table();

                    $(
                    state.push_str(stringify!($field));
                    self.$field.to_lua(state);
                    state.raw_set(-3);
                    )+
                }
            }
        }
    }
)

macro_rules! lua_fn_export(
    // Function with no args and no return value
    ($proxy_name:ident: $name:ident()) => {
        fn $proxy_name(_: &lua::Lua) -> int
        {
            $name();
            0
        }
    };

    // Function with no args but return value
    ($proxy_name:ident: $name:ident() -> $rty:ty) => {
        fn $proxy_name(l: &lua::Lua) -> int
        {
            let ret = $name();

            l.push(ret);
            1
        }
    };

    // Function with args and no return value
    ($proxy_name:ident: $name:ident($($arg:ident: $ty:ty),+)) => {
        fn $proxy_name(l: &lua::Lua) -> int
        {
            let mut _i = 1;
            $(
                let $arg: $ty = match l.get(_i) {
                    Some(v) => v,
                    None => fail!("Bad argument: {}", _i),
                };
                _i += 1;
            )+

            $name($($arg),*);
            0
        }
    };

    // Function with args and return value
    ($proxy_name:ident: $name:ident($($arg:ident: $ty:ty),+) -> $rty:ty) => {
        fn $proxy_name(l: &lua::Lua) -> int
        {
            let mut _i = 1;
            $(
                let $arg: $ty = match l.get(_i) {
                    Some(v) => v,
                    None => fail!("Bad argument: {}", _i),
                };
                _i += 1;
            )+

            let ret = $name($($arg),*);

            l.push(ret);
            1
        }
    };
)

macro_rules! lua_fn_import(
    // Function with no args and no return value
    ($name:ident()) => {
        fn $name(l: &lua::Lua)
        {
            l.state.get_global(stringify!($name));

            l.state.pcall(0, 0, 0);
        }
    };

    // Function with no args but return value
    ($name:ident() -> $rty:ty) => {
        fn $name(l: &lua::Lua) -> $rty
        {
            l.state.get_global(stringify!($name));

            l.state.pcall(0, 1, 0);

            match l.pop()
            {
                Some(ret) => ret,
                None => fail!("Bad return value!"),
            }
        }
    };

    // Function with args and no return value
    ($name:ident($($arg:ident: $ty:ty),+)) => {
        fn $name(l: &lua::Lua, $($arg: $ty),+)
        {
            l.state.get_global(stringify!($name));

            let mut _len = 0;

            $(
                l.push($arg);
                _len += 1;
            )+

            l.state.pcall(_len, 0, 0);
        }
    };

    // Function with args and return value
    ($name:ident($($arg:ident: $ty:ty),+) -> $rty:ty) => {
        fn $name(l: &lua::Lua, $($arg: $ty),+) -> $rty
        {
            l.state.get_global(stringify!($name));

            let mut _len = 0;

            $(
                l.push($arg);
                _len += 1;
            )+

            l.state.pcall(_len, 1, 0);

            match l.pop()
            {
                Some(ret) => ret,
                None => fail!("Bad return value!"),
            }
        }
    };

    // Closure with no args and no return value
    ($lua:ident: $name:ident ||) => {
        || {
            lua_fn_import!($name())

            $name(&$lua)
        }
    };

    // Closure with no args but return value
    ($lua:ident: $name: ident || -> $rty:ty) => {
        || {
            lua_fn_import!($name() -> $rty)

            $name(&$lua)
        }
    };

    ($lua:ident: $name:ident | |) => {
        || {
            lua_fn_import!($lua: $name ||)
        }
    };

    // Closure with no args but return value
    ($lua:ident: $name: ident | | -> $rty:ty) => {
        || {
            lua_fn_import!($lua: $name || -> $rty)
        }
    };

    // Closure with args and no return value
    ($lua:ident: $name: ident | $($arg:ident: $ty:ty),+ |) => {
        |$($arg),+| {
            lua_fn_import!($name($($arg: $ty),+))

            $name(&$lua, $($arg),+)
        }
    };

    // Closure with args and return value
    ($lua:ident: $name: ident | $($arg:ident: $ty:ty),+ | -> $rty:ty) => {
        |$($arg),+| {
            lua_fn_import!($name($($arg: $ty),+) -> $rty)

            $name(&$lua, $($arg),+)
        }
    };
)
<commit_msg>Need rewriting for macros.<commit_after>
// TODO: Rewrite this.
<|endoftext|>