<commit_before>use variables::*;
use variables::LpExpression::*;
use std::rc::Rc;
use operations::LpOperations;
use problem::LpFileFormat;

#[test]
fn expressions_creation() {
    let ref a = LpInteger::new("a")
        .lower_bound(10.0)
        .upper_bound(20.0);
    let ref b = LpInteger::new("b");

    assert_eq!(a + b, AddExpr(Rc::new(ConsInt(a.clone())), Rc::new(ConsInt(b.clone()))));
}

#[test]
fn expressions_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!((a + 2*b + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + 3 * 2 * c).to_lp_file_format(), "a + 2 b + 6 c");
    assert_eq!((a + 2).to_lp_file_format(), "a + 2");
    assert_eq!((2*a + 2*b -4*c).to_lp_file_format(), "2 a + 2 b - 4 c");
    assert_eq!((-2*a).to_lp_file_format(), "-2 a");
}

#[test]
fn constraints_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!((a+b).equal(10).to_lp_file_format(), "a + b = 10");
    assert_eq!((2*a + b).ge(10).to_lp_file_format(), "2 a + b >= 10");
    assert_eq!((2*a + b + 20).ge(c).to_lp_file_format(), "2 a + b - c >= -20");
    assert_eq!((-a).ge(10).to_lp_file_format(), "-a >= 10");
    assert_eq!((2*a - 20 + b).ge(-c).to_lp_file_format(), "2 a + b + c >= 20");
}

#[test]
fn test_readme_example() {
    use problem::{LpObjective, LpProblem};
    use operations::{LpOperations};
    use variables::LpInteger;
    use solvers::{SolverTrait, CbcSolver};

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let mut problem = LpProblem::new("One Problem", LpObjective::Maximize);
    problem += 10.0 * a + 20.0 * b;

    problem += (500*a + 1200*b + 1500*c).le(10000);
    problem += (a).le(b);

    let solver = CbcSolver::new();

    match solver.run(&problem) {
        Ok((status, res)) => {
            println!("Status {:?}", status);
            for (name, value) in res.iter() {
                println!("value of {} = {}", name, value);
            }
        },
        Err(msg) => println!("{}", msg),
    }

    let output1 = "\\ One Problem

Maximize
  10 a + 20 b

Subject To
  c1: 500 a + 1200 b + 1500 c <= 10000
  c2: a - b <= 0

".to_string();
    let output2 = problem.to_lp_file_format();
    let output2 = output2.split("Generals").collect::<Vec<&str>>();
    let output2 = output2[0];
    assert_eq!(output1, output2);
}
<commit_msg>Take the obj name into account in tests<commit_after>use variables::*;
use variables::LpExpression::*;
use std::rc::Rc;
use operations::LpOperations;
use problem::LpFileFormat;

#[test]
fn expressions_creation() {
    let ref a = LpInteger::new("a")
        .lower_bound(10.0)
        .upper_bound(20.0);
    let ref b = LpInteger::new("b");

    assert_eq!(a + b, AddExpr(Rc::new(ConsInt(a.clone())), Rc::new(ConsInt(b.clone()))));
}

#[test]
fn expressions_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!((a + 2*b + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + 3 * 2 * c).to_lp_file_format(), "a + 2 b + 6 c");
    assert_eq!((a + 2).to_lp_file_format(), "a + 2");
    assert_eq!((2*a + 2*b -4*c).to_lp_file_format(), "2 a + 2 b - 4 c");
    assert_eq!((-2*a).to_lp_file_format(), "-2 a");
}

#[test]
fn constraints_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!((a+b).equal(10).to_lp_file_format(), "a + b = 10");
    assert_eq!((2*a + b).ge(10).to_lp_file_format(), "2 a + b >= 10");
    assert_eq!((2*a + b + 20).ge(c).to_lp_file_format(), "2 a + b - c >= -20");
    assert_eq!((-a).ge(10).to_lp_file_format(), "-a >= 10");
    assert_eq!((2*a - 20 + b).ge(-c).to_lp_file_format(), "2 a + b + c >= 20");
}

#[test]
fn test_readme_example() {
    use problem::{LpObjective, LpProblem};
    use operations::{LpOperations};
    use variables::LpInteger;
    use solvers::{SolverTrait, CbcSolver};

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let mut problem = LpProblem::new("One Problem", LpObjective::Maximize);
    problem += 10.0 * a + 20.0 * b;

    problem += (500*a + 1200*b + 1500*c).le(10000);
    problem += (a).le(b);

    let solver = CbcSolver::new();

    match solver.run(&problem) {
        Ok((status, res)) => {
            println!("Status {:?}", status);
            for (name, value) in res.iter() {
                println!("value of {} = {}", name, value);
            }
        },
        Err(msg) => println!("{}", msg),
    }

    let output1 = "\\ One Problem

Maximize
  obj: 10 a + 20 b

Subject To
  c1: 500 a + 1200 b + 1500 c <= 10000
  c2: a - b <= 0

".to_string();
    let output2 = problem.to_lp_file_format();
    let output2 = output2.split("Generals").collect::<Vec<&str>>();
    let output2 = output2[0];
    assert_eq!(output1, output2);
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::rc::Rc;
use data::{Value, List, Scope, RuntimeError};
use builtins::{BuiltinFn, load_builtins};

#[derive(Debug)]
pub struct GlobalScope
{
    dict: HashMap<String, Value>,
}

impl GlobalScope
{
    pub fn new() -> GlobalScope
    {
        GlobalScope{ dict: HashMap::new() }
    }

    pub fn set_number(&mut self, key: &str, val: f64)
    {
        self.set(key, Value::Number(val))
    }

    pub fn set_string(&mut self, key: &str, val: String)
    {
        self.set(key, Value::String(Rc::new(val)))
    }

    pub fn set_builtin<F>(&mut self, key: &'static str, do_eval: bool, val: F)
        where F: Fn(&List, &mut Scope) -> Result<Value, RuntimeError> + 'static
    {
        self.set(key, Value::Function(Rc::new(BuiltinFn{ name: key, do_eval: do_eval, func: Box::new(val) })))
    }

    pub fn load_stdlib(&mut self)
    {
        self.set("nil", Value::Nil);
        self.set("true", Value::Bool(true));
        self.set("false", Value::Bool(false));
        load_builtins(self);
    }
}

impl Scope for GlobalScope
{
    fn get(&self, key: &str) -> Option<Value>
    {
        self.dict.get(key).map(|v| v.clone())
    }

    fn set(&mut self, key: &str, val: Value)
    {
        self.dict.insert(key.to_string(), val);
    }

    fn decl(&mut self, key: &str, val: Value)
    {
        self.set(key, val)
    }
}

pub struct LocalScope<'a>
{
    dict: HashMap<String, Value>,
    parent: &'a mut Scope,
}

impl<'a> LocalScope<'a>
{
    pub fn new(env: &mut Scope) -> LocalScope
    {
        LocalScope{ dict: HashMap::new(), parent: env }
    }
}

impl<'a> Scope for LocalScope<'a>
{
    fn get(&self, key: &str) -> Option<Value>
    {
        match self.dict.get(key) {
            Some(val) => Some(val.clone()),
            None => self.parent.get(key),
        }
    }

    fn set(&mut self, key: &str, val: Value)
    {
        match self.dict.entry(key.to_string()) {
            Entry::Occupied(mut entry) => { entry.insert(val); },
            Entry::Vacant(_) => self.parent.set(key, val),
        }
    }

    fn decl(&mut self, key: &str, val: Value)
    {
        self.dict.insert(key.to_string(), val);
    }
}
<commit_msg>this should be more efficient<commit_after>use std::collections::HashMap;
use std::rc::Rc;
use data::{Value, List, Scope, RuntimeError};
use builtins::{BuiltinFn, load_builtins};

#[derive(Debug)]
pub struct GlobalScope
{
    dict: HashMap<String, Value>,
}

impl GlobalScope
{
    pub fn new() -> GlobalScope
    {
        GlobalScope{ dict: HashMap::new() }
    }

    pub fn set_number(&mut self, key: &str, val: f64)
    {
        self.set(key, Value::Number(val))
    }

    pub fn set_string(&mut self, key: &str, val: String)
    {
        self.set(key, Value::String(Rc::new(val)))
    }

    pub fn set_builtin<F>(&mut self, key: &'static str, do_eval: bool, val: F)
        where F: Fn(&List, &mut Scope) -> Result<Value, RuntimeError> + 'static
    {
        self.set(key, Value::Function(Rc::new(BuiltinFn{ name: key, do_eval: do_eval, func: Box::new(val) })))
    }

    pub fn load_stdlib(&mut self)
    {
        self.set("nil", Value::Nil);
        self.set("true", Value::Bool(true));
        self.set("false", Value::Bool(false));
        load_builtins(self);
    }
}

impl Scope for GlobalScope
{
    fn get(&self, key: &str) -> Option<Value>
    {
        self.dict.get(key).map(|v| v.clone())
    }

    fn set(&mut self, key: &str, val: Value)
    {
        self.dict.insert(key.to_string(), val);
    }

    fn decl(&mut self, key: &str, val: Value)
    {
        self.set(key, val)
    }
}

pub struct LocalScope<'a>
{
    dict: HashMap<String, Value>,
    parent: &'a mut Scope,
}

impl<'a> LocalScope<'a>
{
    pub fn new(env: &mut Scope) -> LocalScope
    {
        LocalScope{ dict: HashMap::new(), parent: env }
    }
}

impl<'a> Scope for LocalScope<'a>
{
    fn get(&self, key: &str) -> Option<Value>
    {
        match self.dict.get(key) {
            Some(val) => Some(val.clone()),
            None => self.parent.get(key),
        }
    }

    fn set(&mut self, key: &str, val: Value)
    {
        if let Some(entry) = self.dict.get_mut(key)
        {
            *entry = val;
        }
        else
        {
            self.parent.set(key, val)
        }
    }

    fn decl(&mut self, key: &str, val: Value)
    {
        self.dict.insert(key.to_string(), val);
    }
}
<|endoftext|>


<commit_before>use url::percent_encoding::{percent_decode, percent_encode_byte};

// 以后应该自己组结构体，Hyper 的 Url new方法都没, md 一个 path 都改不了，只能反复 decode..
pub fn url_for_parent(path: &str) -> String{
    let req_path_dec = percent_decode(path.as_bytes()).decode_utf8().unwrap();
    let cow_str = req_path_dec.as_ref();
    let req_path_components = cow_str
        .split('/')
        .filter(|c| !c.is_empty())
        .collect::<Vec<_>>();
    // if `/` encoding as '%2F', brower will concat origin'path with req_path_parent
    if req_path_components.len() > 1 {
        req_path_components[..req_path_components.len() - 1]
            .iter()
            .flat_map(|c| {
                "/".chars()
                    .chain(c.bytes().flat_map(|cc| percent_encode_byte(cc).chars()))
            })
            .collect::<String>()
    } else {
        "/".to_owned()
    }
}<commit_msg>add '/' for url_for_parent.<commit_after>use url::percent_encoding::{percent_decode, percent_encode_byte};

// 以后应该自己组结构体，Hyper 的 Url new方法都没, md 一个 path 都改不了，只能反复 decode..
pub fn url_for_parent(path: &str) -> String {
    let req_path_dec = percent_decode(path.as_bytes()).decode_utf8().unwrap();
    let cow_str = req_path_dec.as_ref();
    let req_path_components = cow_str
        .split('/')
        .filter(|c| !c.is_empty())
        .collect::<Vec<_>>();
    // if `/` encoding as '%2F', brower will concat origin'path with req_path_parent
    let mut out = if req_path_components.len() > 1 {
        req_path_components[..req_path_components.len() - 1]
            .iter()
            .flat_map(|c| {
                "/".chars()
                    .chain(c.bytes().flat_map(|cc| percent_encode_byte(cc).chars()))
            })
            .collect::<String>()
    } else {
        String::new()
    };
    out.push('/');
    out
}<|endoftext|>


<commit_before>use hyper::header::common::content_type::ContentType;
use hyper::server::request::Request;

use mime::{Mime, TopLevel, SubLevel, Attr, Value};

use super::{MultipartField, MultipartFile};

use std::cmp;

use std::io::{IoError, IoResult, EndOfFile, standard_error, OtherIoError};

fn is_multipart_formdata(req: &Request) -> bool {
    use mime::{Multipart};

    req.headers.get::<ContentType>().map_or(false, |ct| {
        let ContentType(ref mime) = *ct;

        debug!("Content-Type: {}", mime);

        match *mime {
            Mime(TopLevel::Multipart, SubLevel::FormData, _) => true,
            _ => false,
        }
    })
}

fn get_boundary(ct: &ContentType) -> Option<String> {
    let ContentType(ref mime) = *ct;
    let Mime(_, _, ref params) = *mime;

    params.iter().find(|&&(ref name, _)|
        if let Attr::Ext(ref name) = *name {
            name[] == "boundary"
        } else { false }
    ).and_then(|&(_, ref val)|
        if let Value::Ext(ref val) = *val {
            Some(val.clone())
        } else { None }
    )
}

pub struct Multipart<'a> {
    source: BoundaryReader<Request<'a>>,
}

macro_rules! try_find(
    ($haystack:expr, $f:ident, $needle:expr, $err:expr, $line:expr) => (
        try!($haystack.$f($needle).ok_or(line_error($err, $line.clone())))
    )
)

impl<'a> Multipart<'a> {

    /// If the given `Request` is of `Content-Type: multipart/form-data`, return
    /// the wrapped request as `Ok(Multipart)`, otherwise `Err(Request)`.
    pub fn from_request(req: Request<'a>) -> Result<Multipart<'a>, Request<'a>> {
        if !is_multipart_formdata(&req) { return Err(req); }

        debug!("Is multipart!");

        let boundary = if let Some(boundary) = req.headers.get::<ContentType>()
            .and_then(get_boundary) { boundary } else { return Err(req); };

        debug!("Boundary: {}", boundary);

        Ok(Multipart { source: BoundaryReader::from_reader(req, format!("--{}\r\n", boundary)) })
    }

    pub fn read_entry<'a>(&'a mut self) -> IoResult<(String, MultipartField<'a>)> {
        debug!("Read entry!");

        try!(self.source.consume_boundary());
        let (disp_type, field_name, filename) = try!(self.read_content_disposition());

        if &*disp_type != "form-data" {
            return Err(IoError {
                    kind: OtherIoError,
                    desc: "Content-Disposition value was not \"form-data\"",
                    detail: Some(format!("Content-Disposition: {}", disp_type)),
                });
        }

        if let Some(content_type) = try!(self.read_content_type()) {
            let _ = try!(self.source.read_line()); // Consume empty line
            Ok((field_name,
                MultipartField::File(
                    MultipartFile::from_octet(filename, &mut self.source, content_type[])
                )
            ))
        } else {
            // Empty line consumed by read_content_type()
            let text = try!(self.source.read_to_string());
            // The last two characters are "\r\n".
            // We can't do a simple trim because the content might be terminated
            // with line separators we want to preserve.
            Ok((field_name, MultipartField::Text(text[..text.len() - 2].into_string())))
        }
    }

    /// Call `f` for each entry in the multipart request.
    /// This is a substitute for `Multipart` implementing `Iterator`,
    /// since `Iterator::next()` can't use bound lifetimes.
    /// See https://www.reddit.com/r/rust/comments/2lkk4i/concrete_lifetime_vs_bound_lifetime/
    pub fn foreach_entry<F: for<'a> FnMut(String, MultipartField<'a>)>(&mut self, mut f: F) {
        loop {
            debug!("Loop!");

            match self.read_entry() {
                Ok((name, field)) => f(name, field),
                Err(err) => {
                    if err.kind != EndOfFile {
                        error!("Error reading Multipart: {}", err);
                    }

                    break;
                },
            }
        }
    }

    fn read_content_disposition(&mut self) -> IoResult<(String, String, Option<String>)> {
        debug!("Read content disposition!");
        let line = try!(self.source.read_line());

        debug!("Line: {}", line);

        // Find the end of CONT_DISP in the line
        let disp_type = {
            const CONT_DISP: &'static str = "Content-Disposition:";

            let disp_idx = try_find!(line[], find_str, CONT_DISP,
                "Content-Disposition subheader not found!", line) + CONT_DISP.len();

            debug!("Disp idx: {} Line len: {}", disp_idx, line.len());

            let disp_type_end = try_find!(line[disp_idx..], find, ';',
                "Error parsing Content-Disposition value!", line);

            debug!("Disp end: {}", disp_type_end);

            line[disp_idx .. disp_idx + disp_type_end].trim().into_string()
        };

        debug!("Disp-type: {}", disp_type);

        let field_name = {
            const NAME: &'static str = "name=\"";

            let name_idx = try_find!(line[], find_str, NAME,
                "Error parsing field name!", line) + NAME.len();

            debug!("Name idx: {}", name_idx);

            let name_end = try_find!(line[name_idx ..], find, '"',
                "Error parsing field name!", line);

            debug!("Name end: {}", name_end);

            line[name_idx .. name_idx + name_end].into_string() // No trim here since it's in quotes.
        };

        debug!("Field name: {}", field_name);

        let filename = {
            const FILENAME: &'static str = "filename=\"";

            let filename_idx = line[].find_str(FILENAME).map(|idx| idx + FILENAME.len());
            let filename_idxs = with(filename_idx, |&start| line[start ..].find('"'));

            filename_idxs.map(|(start, end)| line[start .. start + end].into_string())
        };

        debug!("Filename: {}", filename);

        Ok((disp_type, field_name, filename))
    }

    fn read_content_type(&mut self) -> IoResult<Option<String>> {
        debug!("Read content type!");
        let line = try!(self.source.read_line());

        const CONTENT_TYPE: &'static str = "Content-Type:";

        let type_idx = (&*line).find_str(CONTENT_TYPE);

        // FIXME Will not properly parse for multiple files!
        // Does not expect boundary=<boundary>
        Ok(type_idx.map(|start| line[start + CONTENT_TYPE.len()..].trim().into_string()))
    }
}

fn with<T, U>(left: Option<T>, right: |&T| -> Option<U>) -> Option<(T, U)> {
    let temp = left.as_ref().and_then(right);
    match (left, temp) {
        (Some(lval), Some(rval)) => Some((lval, rval)),
        _ => None,
    }
}

fn line_error(msg: &'static str, line: String) -> IoError {
    IoError {
        kind: OtherIoError,
        desc: msg,
        detail: Some(line),
    }
}

/* FIXME: Can't have an iterator return a borrowed reference
impl<'a> Iterator<(String, MultipartField<'a>)> for Multipart {
    fn next(&mut self) -> Option<(String, MultipartField<'a>)> {
        match self.read_entry() {
            Ok(ok) => Some(ok),
            Err(err) => {
                if err.kind != EndOfFile {
                    error!("Error reading Multipart: {}", err);
                }

                None
             },
        }
    }
}
*/

/// A `Reader` that will yield bytes until it sees a given sequence.
pub struct BoundaryReader<S> {
    reader: S,
    boundary: Vec<u8>,
    last_search_idx: uint,
    boundary_read: bool,
    buf: Vec<u8>,
    buf_len: uint,
}

fn eof<T>() -> IoResult<T> {
    Err(standard_error(EndOfFile))
}

const BUF_SIZE: uint = 1024 * 64; // 64k buffer

impl<S> BoundaryReader<S> where S: Reader {
    fn from_reader(reader: S, boundary: String) -> BoundaryReader<S> {
        let mut buf = Vec::with_capacity(BUF_SIZE);
        unsafe { buf.set_len(BUF_SIZE); }

        BoundaryReader {
            reader: reader,
            boundary: boundary.into_bytes(),
            last_search_idx: 0,
            boundary_read: false,
            buf: buf,
            buf_len: 0,
        }
    }

    fn read_to_boundary(&mut self) -> IoResult<()> {
         if !self.boundary_read {
            try!(self.true_fill_buf());

            if self.buf_len == 0 { return eof(); }

            let lookahead = self.buf[self.last_search_idx .. self.buf_len];

            let search_idx = lookahead.position_elem(&self.boundary[0])
                .unwrap_or(lookahead.len() - 1);

            debug!("Search idx: {}", search_idx);

            self.boundary_read = lookahead[search_idx..]
                .starts_with(self.boundary[]);

            self.last_search_idx += search_idx;

            if !self.boundary_read {
                self.last_search_idx += 1;
            }

        } else if self.last_search_idx == 0 {
            return Err(standard_error(EndOfFile))
        }

        Ok(())
    }

    /// Read bytes until the reader is full
    fn true_fill_buf(&mut self) -> IoResult<()> {
        let mut bytes_read = 1u;

        while bytes_read != 0 {
            bytes_read = match self.reader.read(self.buf[mut self.buf_len..]) {
                Ok(read) => read,
                Err(err) => if err.kind == EndOfFile { break; } else { return Err(err); },
            };

            self.buf_len += bytes_read;
        }

        Ok(())
    }

    fn _consume(&mut self, amt: uint) {
        use std::ptr::copy_memory;

        assert!(amt <= self.buf_len);

        let src = self.buf[amt..].as_ptr();
        let dest = self.buf[mut].as_mut_ptr();

        unsafe { copy_memory(dest, src, self.buf_len - amt); }

        self.buf_len -= amt;
        self.last_search_idx -= amt;
    }

    fn consume_boundary(&mut self) -> IoResult<()> {
        while !self.boundary_read {
            match self.read_to_boundary() {
                Ok(_) => (),
                Err(e) => if e.kind == EndOfFile {
                    break;
                } else {
                    return Err(e);
                }
            }
        }

        let consume_amt = cmp::min(self.buf_len, self.last_search_idx + self.boundary.len());

        debug!("Consume amt: {} Buf len: {}", consume_amt, self.buf_len);

        self._consume(consume_amt);
        self.last_search_idx = 0;
        self.boundary_read = false;

        Ok(())
    }

    #[allow(unused)]
    fn set_boundary(&mut self, boundary: String) {
        self.boundary = boundary.into_bytes();
    }
}

impl<S> Reader for BoundaryReader<S> where S: Reader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        use std::cmp;
        use std::slice::bytes::copy_memory;

        try!(self.read_to_boundary());

        let trunc_len = cmp::min(buf.len(), self.last_search_idx);
        copy_memory(buf, self.buf[..trunc_len]);

        self._consume(trunc_len);

        Ok(trunc_len)
    }
}

impl<S> Buffer for BoundaryReader<S> where S: Reader {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        try!(self.read_to_boundary());

        let buf = self.buf[..self.last_search_idx];

        Ok(buf)
    }

    fn consume(&mut self, amt: uint) {
        assert!(amt <= self.last_search_idx);
        self._consume(amt);
    }
}

#[test]
fn test_boundary() {
    use std::io::BufReader;

    const BOUNDARY: &'static str = "--boundary\r\n";
    const TEST_VAL: &'static str = "\r
--boundary\r
dashed-value-1\r
--boundary\r
dashed-value-2\r
--boundary\r
";

    let test_reader = BufReader::new(TEST_VAL.as_bytes());
    let mut reader = BoundaryReader::from_reader(test_reader, BOUNDARY.into_string());

    debug!("Read 1");
    let string = reader.read_to_string().unwrap();
    debug!("{}", string);
    assert!(string[].trim().is_empty());

    debug!("Consume 1");
    reader.consume_boundary().unwrap();

    debug!("Read 2");
    assert_eq!(reader.read_to_string().unwrap()[].trim(), "dashed-value-1");

    debug!("Consume 2");
    reader.consume_boundary().unwrap();

    debug!("Read 3");
    assert_eq!(reader.read_to_string().unwrap()[].trim(), "dashed-value-2");

    debug!("Consume 3");
    reader.consume_boundary().unwrap();

}

<commit_msg>More debug removal<commit_after>use hyper::header::common::content_type::ContentType;
use hyper::server::request::Request;

use mime::{Mime, TopLevel, SubLevel, Attr, Value};

use super::{MultipartField, MultipartFile};

use std::cmp;

use std::io::{IoError, IoResult, EndOfFile, standard_error, OtherIoError};

fn is_multipart_formdata(req: &Request) -> bool {
    use mime::{Multipart};

    req.headers.get::<ContentType>().map_or(false, |ct| {
        let ContentType(ref mime) = *ct;

        debug!("Content-Type: {}", mime);

        match *mime {
            Mime(TopLevel::Multipart, SubLevel::FormData, _) => true,
            _ => false,
        }
    })
}

fn get_boundary(ct: &ContentType) -> Option<String> {
    let ContentType(ref mime) = *ct;
    let Mime(_, _, ref params) = *mime;

    params.iter().find(|&&(ref name, _)|
        if let Attr::Ext(ref name) = *name {
            name[] == "boundary"
        } else { false }
    ).and_then(|&(_, ref val)|
        if let Value::Ext(ref val) = *val {
            Some(val.clone())
        } else { None }
    )
}

pub struct Multipart<'a> {
    source: BoundaryReader<Request<'a>>,
}

macro_rules! try_find(
    ($haystack:expr, $f:ident, $needle:expr, $err:expr, $line:expr) => (
        try!($haystack.$f($needle).ok_or(line_error($err, $line.clone())))
    )
)

impl<'a> Multipart<'a> {

    /// If the given `Request` is of `Content-Type: multipart/form-data`, return
    /// the wrapped request as `Ok(Multipart)`, otherwise `Err(Request)`.
    pub fn from_request(req: Request<'a>) -> Result<Multipart<'a>, Request<'a>> {
        if !is_multipart_formdata(&req) { return Err(req); }

        let boundary = if let Some(boundary) = req.headers.get::<ContentType>()
            .and_then(get_boundary) { boundary } else { return Err(req); };

        debug!("Boundary: {}", boundary);

        Ok(Multipart { source: BoundaryReader::from_reader(req, format!("--{}\r\n", boundary)) })
    }

    pub fn read_entry(&'a mut self) -> IoResult<(String, MultipartField<'a>)> {
        try!(self.source.consume_boundary());
        let (disp_type, field_name, filename) = try!(self.read_content_disposition());

        if &*disp_type != "form-data" {
            return Err(IoError {
                    kind: OtherIoError,
                    desc: "Content-Disposition value was not \"form-data\"",
                    detail: Some(format!("Content-Disposition: {}", disp_type)),
                });
        }

        if let Some(content_type) = try!(self.read_content_type()) {
            let _ = try!(self.source.read_line()); // Consume empty line
            Ok((field_name,
                MultipartField::File(
                    MultipartFile::from_octet(filename, &mut self.source, content_type[])
                )
            ))
        } else {
            // Empty line consumed by read_content_type()
            let text = try!(self.source.read_to_string());
            // The last two characters are "\r\n".
            // We can't do a simple trim because the content might be terminated
            // with line separators we want to preserve.
            Ok((field_name, MultipartField::Text(text[..text.len() - 2].into_string())))
        }
    }

    /// Call `f` for each entry in the multipart request.
    /// This is a substitute for `Multipart` implementing `Iterator`,
    /// since `Iterator::next()` can't use bound lifetimes.
    /// See https://www.reddit.com/r/rust/comments/2lkk4i/concrete_lifetime_vs_bound_lifetime/
    pub fn foreach_entry<F: for<'a> FnMut(String, MultipartField<'a>)>(&mut self, mut f: F) {
        loop {
            match self.read_entry() {
                Ok((name, field)) => f(name, field),
                Err(err) => {
                    if err.kind != EndOfFile {
                        error!("Error reading Multipart: {}", err);
                    }

                    break;
                },
            }
        }
    }

    fn read_content_disposition(&mut self) -> IoResult<(String, String, Option<String>)> {
        let line = try!(self.source.read_line());

        // Find the end of CONT_DISP in the line
        let disp_type = {
            const CONT_DISP: &'static str = "Content-Disposition:";

            let disp_idx = try_find!(line[], find_str, CONT_DISP,
                "Content-Disposition subheader not found!", line) + CONT_DISP.len();

            let disp_type_end = try_find!(line[disp_idx..], find, ';',
                "Error parsing Content-Disposition value!", line);

            line[disp_idx .. disp_idx + disp_type_end].trim().into_string()
        };

        let field_name = {
            const NAME: &'static str = "name=\"";

            let name_idx = try_find!(line[], find_str, NAME,
                "Error parsing field name!", line) + NAME.len();

            let name_end = try_find!(line[name_idx ..], find, '"',
                "Error parsing field name!", line);

            line[name_idx .. name_idx + name_end].into_string() // No trim here since it's in quotes.
        };

        let filename = {
            const FILENAME: &'static str = "filename=\"";

            let filename_idx = line[].find_str(FILENAME).map(|idx| idx + FILENAME.len());
            let filename_idxs = with(filename_idx, |&start| line[start ..].find('"'));

            filename_idxs.map(|(start, end)| line[start .. start + end].into_string())
        };

        Ok((disp_type, field_name, filename))
    }

    fn read_content_type(&mut self) -> IoResult<Option<String>> {
        debug!("Read content type!");
        let line = try!(self.source.read_line());

        const CONTENT_TYPE: &'static str = "Content-Type:";

        let type_idx = (&*line).find_str(CONTENT_TYPE);

        // FIXME Will not properly parse for multiple files!
        // Does not expect boundary=<boundary>
        Ok(type_idx.map(|start| line[start + CONTENT_TYPE.len()..].trim().into_string()))
    }
}

fn with<T, U>(left: Option<T>, right: |&T| -> Option<U>) -> Option<(T, U)> {
    let temp = left.as_ref().and_then(right);
    match (left, temp) {
        (Some(lval), Some(rval)) => Some((lval, rval)),
        _ => None,
    }
}

fn line_error(msg: &'static str, line: String) -> IoError {
    IoError {
        kind: OtherIoError,
        desc: msg,
        detail: Some(line),
    }
}

/* FIXME: Can't have an iterator return a borrowed reference
impl<'a> Iterator<(String, MultipartField<'a>)> for Multipart<'a> {
    fn next(&mut self) -> Option<(String, MultipartField<'a>)> {
        match self.read_entry() {
            Ok(ok) => Some(ok),
            Err(err) => {
                if err.kind != EndOfFile {
                    error!("Error reading Multipart: {}", err);
                }

                None
             },
        }
    }
}
*/

/// A `Reader` that will yield bytes until it sees a given sequence.
pub struct BoundaryReader<S> {
    reader: S,
    boundary: Vec<u8>,
    last_search_idx: uint,
    boundary_read: bool,
    buf: Vec<u8>,
    buf_len: uint,
}

fn eof<T>() -> IoResult<T> {
    Err(standard_error(EndOfFile))
}

const BUF_SIZE: uint = 1024 * 64; // 64k buffer

impl<S> BoundaryReader<S> where S: Reader {
    fn from_reader(reader: S, boundary: String) -> BoundaryReader<S> {
        let mut buf = Vec::with_capacity(BUF_SIZE);
        unsafe { buf.set_len(BUF_SIZE); }

        BoundaryReader {
            reader: reader,
            boundary: boundary.into_bytes(),
            last_search_idx: 0,
            boundary_read: false,
            buf: buf,
            buf_len: 0,
        }
    }

    fn read_to_boundary(&mut self) -> IoResult<()> {
         if !self.boundary_read {
            try!(self.true_fill_buf());

            if self.buf_len == 0 { return eof(); }

            let lookahead = self.buf[self.last_search_idx .. self.buf_len];

            let search_idx = lookahead.position_elem(&self.boundary[0])
                .unwrap_or(lookahead.len() - 1);

            debug!("Search idx: {}", search_idx);

            self.boundary_read = lookahead[search_idx..]
                .starts_with(self.boundary[]);

            self.last_search_idx += search_idx;

            if !self.boundary_read {
                self.last_search_idx += 1;
            }

        } else if self.last_search_idx == 0 {
            return Err(standard_error(EndOfFile))
        }

        Ok(())
    }

    /// Read bytes until the reader is full
    fn true_fill_buf(&mut self) -> IoResult<()> {
        let mut bytes_read = 1u;

        while bytes_read != 0 {
            bytes_read = match self.reader.read(self.buf[mut self.buf_len..]) {
                Ok(read) => read,
                Err(err) => if err.kind == EndOfFile { break; } else { return Err(err); },
            };

            self.buf_len += bytes_read;
        }

        Ok(())
    }

    fn _consume(&mut self, amt: uint) {
        use std::ptr::copy_memory;

        assert!(amt <= self.buf_len);

        let src = self.buf[amt..].as_ptr();
        let dest = self.buf[mut].as_mut_ptr();

        unsafe { copy_memory(dest, src, self.buf_len - amt); }

        self.buf_len -= amt;
        self.last_search_idx -= amt;
    }

    fn consume_boundary(&mut self) -> IoResult<()> {
        while !self.boundary_read {
            match self.read_to_boundary() {
                Ok(_) => (),
                Err(e) => if e.kind == EndOfFile {
                    break;
                } else {
                    return Err(e);
                }
            }
        }

        let consume_amt = cmp::min(self.buf_len, self.last_search_idx + self.boundary.len());

        debug!("Consume amt: {} Buf len: {}", consume_amt, self.buf_len);

        self._consume(consume_amt);
        self.last_search_idx = 0;
        self.boundary_read = false;

        Ok(())
    }

    #[allow(unused)]
    fn set_boundary(&mut self, boundary: String) {
        self.boundary = boundary.into_bytes();
    }
}

impl<S> Reader for BoundaryReader<S> where S: Reader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        use std::cmp;
        use std::slice::bytes::copy_memory;

        try!(self.read_to_boundary());

        let trunc_len = cmp::min(buf.len(), self.last_search_idx);
        copy_memory(buf, self.buf[..trunc_len]);

        self._consume(trunc_len);

        Ok(trunc_len)
    }
}

impl<S> Buffer for BoundaryReader<S> where S: Reader {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        try!(self.read_to_boundary());

        let buf = self.buf[..self.last_search_idx];

        Ok(buf)
    }

    fn consume(&mut self, amt: uint) {
        assert!(amt <= self.last_search_idx);
        self._consume(amt);
    }
}

#[test]
fn test_boundary() {
    use std::io::BufReader;

    const BOUNDARY: &'static str = "--boundary\r\n";
    const TEST_VAL: &'static str = "\r
--boundary\r
dashed-value-1\r
--boundary\r
dashed-value-2\r
--boundary\r
";

    let test_reader = BufReader::new(TEST_VAL.as_bytes());
    let mut reader = BoundaryReader::from_reader(test_reader, BOUNDARY.into_string());

    debug!("Read 1");
    let string = reader.read_to_string().unwrap();
    debug!("{}", string);
    assert!(string[].trim().is_empty());

    debug!("Consume 1");
    reader.consume_boundary().unwrap();

    debug!("Read 2");
    assert_eq!(reader.read_to_string().unwrap()[].trim(), "dashed-value-1");

    debug!("Consume 2");
    reader.consume_boundary().unwrap();

    debug!("Read 3");
    assert_eq!(reader.read_to_string().unwrap()[].trim(), "dashed-value-2");

    debug!("Consume 3");
    reader.consume_boundary().unwrap();

}

<|endoftext|>


<commit_before>//! Server implementation.

use std::collections::hashmap::HashSet;
use std::comm::{Receiver, Sender};
use std::rc::{Rc, Weak};
use uuid::Uuid;
use std::io::timer::Timer;
use std::time::duration::Duration;

use addr::Addr;
use broadcast::Broadcast;
use result::{GossipResult, GossipError};

use node::Node;
use health::{Health};
use state::State;

#[deriving(Show, PartialEq)]
pub enum ShutdownReason {
    UserInitiatedShutdown,
    NetworkFailure,
    Failure
}

/// Messages that can be sent and received to and from the server task.
#[deriving(Show, PartialEq)]
pub enum ServerMsg {
    /// Receive a particular broadcast. We will commit it in our log that can persist to disk.
    Message(Broadcast),
    /// A signal to kill the current server. This will send a IAmShuttingDown message as
    /// a gossip message to let the cluster know why it's shutting down.
    Shutdown(ShutdownReason),
    /// Kill a specific node in the cluster. This is a state change rather than a gossip. This will
    /// remove a specific node from the cluster.
    KillNode(Node)
}

pub struct ServerTask {
    /// Part of a channel that the server sends messages to.
    receiver: Receiver<ServerMsg>,
    /// Part of a channel that communicates with the server.
    sender: Sender<ServerMsg>
}

impl ServerTask {
    ///
    /// ```rust
    /// use gossip::{ServerTask};
    ///
    /// let mut task = ServerTask::create("127.0.0.1", 4555);
    /// task.close();
    /// ```
    pub fn create(ip: &str, port: u16) -> ServerTask {
        // Create an intermediate channel.
        let (tx, rx) = channel();
        let (sender, receiver) = channel();
        let addr = ip.to_string();

        spawn(proc() {
            // Create a new server.
            let mut server = Server::new(sender.clone());
            tx.send(server.sender.clone());
            server.listen(addr.as_slice(), port);
        });

        ServerTask {
            receiver: receiver,
            sender: rx.recv()
        }
    }

    pub fn shutdown(&mut self, time: Duration) {
        let mut timer = Timer::new().unwrap();
        timer.sleep(time);
        self.close();
    }

    pub fn close(&mut self) {
        self.sender.send(Shutdown(UserInitiatedShutdown));
    }

    pub fn recv(&mut self) -> ServerMsg {
        self.receiver.recv()
    }
}

/// A server/node/peer is the most atomic unit within a cluster. Each node is equal with it's peers,
/// thus we don't have any leader or election processes. Each server is identified with a unique ID
/// that is randomly generated, along with the appropriate state.
///
/// A server requires a bit of metadata about the cluster, the cluster's state and things like
/// channels. Each server has it's own Receiver to handle incoming messages. A separate Receiver
/// is used for users of this library. We then have a Sender that sends to the server's receiver.
/// This is meant to be copied to the appropriate task.
///
/// Usage:
///
/// ```rust
/// use gossip::{Server, Shutdown};
/// use std::time::duration::Duration;
///
/// let mut task = Server::create("127.0.0.1", 5666);
///
/// // Shutdown in the specified time in seconds.
/// task.shutdown(Duration::seconds(1));
///
/// // Wait for new messages. This will block the main task until the
/// // server has been shutdown.
/// loop {
///     match task.recv() {
///         Shutdown(reason) => break,
///         _ => {}
///     }
/// }
/// ```
pub struct Server {
    /// A unique id for the server. This allows servers to talk about each other in
    /// a consistent manner.
    id: Uuid,
    /// Each server has an Addr instance. Regardless of what type of transport it has.
    addr: Option<Addr>,
    /// The state handles the core Gossip protocol. It's basically a giant state machine
    /// that keeps track of which nodes to communicate with, which nodes are alive/dead/failing,
    /// etc...
    state: State,
    /// We need to know a list of servers in the cluster (excluding itself).
    servers: Vec<Node>,
    receiver: Receiver<ServerMsg>,
    sender: Sender<ServerMsg>,
    /// External sender
    tx: Sender<ServerMsg>
}

impl Server {

    pub fn new(sender: Sender<ServerMsg>) -> Server {
        // Create a default channel for the server itself.
        let (tx, rx) = channel();

        let server = Server {
            id: Uuid::new_v4(),
            addr: None,
            state: State::new(),
            servers: Vec::new(),
            receiver: rx,
            sender: tx,
            tx: sender
        };

        server
    }

    /// Create a brand new server with a bunch of defaults. It won't actually connect to
    /// anything nor do anything. That's up to the transports to initiate the connections
    /// and such.
    ///
    /// 1. Chan<ServerMsg>: Server -> User
    /// 2. Chan<Sender<ServerMsg>>: User -> Server
    ///
    /// 1. We need the user to receive real messages.
    /// 2. We need the user to be able to send real messages back to the server.
    pub fn create(ip: &str, port: u16) -> ServerTask {
        ServerTask::create(ip, port)
    }

    /// Bind the server to the specified address. If there's a transport,
    /// it has the possibility of failing, otherwise, it uses an in-memory
    /// function.
    pub fn listen(&mut self, ip: &str, port: u16) -> GossipResult<()> {
        self.addr = Some(Addr::new(ip, port));

        loop {
            match self.receiver.recv() {
                Shutdown(reason) => {
                    println!("Server is shutting down, reason: {}", reason);
                    self.tx.send(Shutdown(UserInitiatedShutdown));
                    break;
                },
                _ => {}
            }
        }

        Ok(())
    }

    /// Shutdown the current server and disconnect from the cluster. This has to first
    /// communicate with the cluster to properly disconnect it, so it's an asynchronous
    /// operation.
    ///
    /// Note that this method is only called from the server's task, not from the user's
    /// tasks. To do the latter, you'll have to use the Sender that the server passes to
    /// you.
    pub fn close(&mut self) {
        //self.ctx.send(Shutdown(UserInitiatedShutdown));
    }
}

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

    #[test]
    fn default_server() {
        let (tx, rx) = channel();
        let s = Server::new(tx);
        assert!(s.addr.is_none())
    }
}
<commit_msg>Small cleanup<commit_after>//! Server implementation.

use std::collections::hashmap::HashSet;
use std::comm::{Receiver, Sender};
use uuid::Uuid;
use std::io::timer::Timer;
use std::time::duration::Duration;

use addr::Addr;
use broadcast::Broadcast;
use result::{GossipResult, GossipError};

use node::Node;
use health::{Health};
use state::State;

/// Each shutdown command needs to have a reason. Sometimes, we may not know the reason
/// of a particular shutdown (the network may fail, but we don't know if it's them or us, etc...).
/// This also improves error handling and error reporting to where it allows one to report the type
/// of shutdown and when.
#[deriving(Show, PartialEq)]
pub enum ShutdownReason {
    UserInitiatedShutdown,
    NetworkFailure,
    Failure
}

/// All the possible types of messages we can send to most of the channels that communicate with
/// the server. The most common one is the `Message` variant, which initiates/receives a new
/// broadcast/gossip to the appropriate nodes.
#[deriving(Show, PartialEq)]
pub enum ServerMessage {
    /// A broadcast/gossip that can be sent and/or received!
    Message(Broadcast),
    /// A shutdown command to the local node. This is an internal variant and thus isn't used
    /// to kill another member within the cluster. If we have received one of those commands, then
    /// this is emitted internally.
    Shutdown(ShutdownReason),
}

/// Handle the communication and setup of the server. Each server is spawned on
/// a separate task for isolation and independence. Thus, the only communication mechanism
/// is through the use of channels. Instead of requiring the user of the crate to initialize
/// all the local channels and such, this handles it automatically resulting in a super
/// clean API.
pub struct ServerTask {
    /// Part of a channel that the server sends messages to.
    receiver: Receiver<ServerMsg>,
    /// Part of a channel that communicates with the server.
    sender: Sender<ServerMsg>
}

impl ServerTask {
    /// Create a new `ServerTask` that will handle the initialization of
    /// a server in a separate task. This will also handle creating all the required
    /// channels and such.
    ///
    /// ```rust
    /// use gossip::{ServerTask};
    ///
    /// let mut task = ServerTask::create("127.0.0.1", 4555);
    ///
    /// // We need to shutdown the system so that we don't hang in the
    /// // tests.
    /// task.shutdown();
    /// ```
    pub fn create(ip: &str, port: u16) -> ServerTask {
        // Create an intermediate channel to send and receive another Sender
        // that will be used in the `ServerTask`. This channel is only used
        // once and then thrown away.
        let (tx, rx) = channel();

        // Create another channel that will act as the local receiver. The sender
        // will be sent to the server.
        let (sender, receiver) = channel();

        // A slice does not implement `Send` so we have to allocate it first.
        let addr = ip.to_string();

        spawn(proc() {
            // Create a new server sending our `Sender`. This allows the server to send the user
            // messages over the channel.
            let mut server = Server::new(sender.clone());

            // Send back the server's sender portion of the channel. This is how
            // we can further communicate with the server.
            tx.send(server.sender.clone());

            // Start the server. This will run forever until it's killed.
            server.listen(addr.as_slice(), port);
        });

        ServerTask {
            receiver: receiver,
            sender: rx.recv()
        }
    }

    /// Call the shutdown method after a set duration. This uses a
    /// synchronous timer.
    pub fn shutdown_in(&mut self, time: Duration) {
        let mut timer = Timer::new().unwrap();
        timer.sleep(time);
        self.shutdown();
    }

    /// Shutdown the current server now. This may not happen right away,
    /// but as soon as the proper protocol has been followed.
    pub fn shutdown(&mut self) {
        self.sender.send(Shutdown(UserInitiatedShutdown));
    }

    /// A slightly nicer interface for sending messages to the Server. This
    /// allows us to keep the `receiver` and `sender` private.
    pub fn recv(&mut self) -> ServerMsg {
        self.receiver.recv()
    }
}

/// A server/node/peer is the most atomic unit within a cluster. Each node is equal with it's peers,
/// thus we don't have any leader or election processes. Each server is identified with a unique ID
/// that is randomly generated, along with the appropriate state.
///
/// A server requires a bit of metadata about the cluster, the cluster's state and things like
/// channels. Each server has it's own Receiver to handle incoming messages. A separate Receiver
/// is used for users of this library. We then have a Sender that sends to the server's receiver.
/// This is meant to be copied to the appropriate task.
///
/// Usage:
///
/// ```rust
/// use gossip::{Server, Shutdown};
/// use std::time::duration::Duration;
///
/// let mut task = Server::create("127.0.0.1", 5666);
///
/// // Shutdown in the specified time in seconds.
/// task.shutdown_in(Duration::seconds(1));
///
/// // Wait for new messages. This will block the main task until the
/// // server has been shutdown.
/// loop {
///     match task.recv() {
///         Shutdown(reason) => break,
///         _ => {}
///     }
/// }
/// ```
pub struct Server {
    /// A unique id for the server. This allows servers to talk about each other in
    /// a consistent manner.
    id: Uuid,
    /// The server may have an address to bind to. We make it optional to have a cleaner API
    /// to initially create the server, as the address is only needed at the .listen method.
    addr: Option<Addr>,
    /// The state handles the core Gossip protocol. It's basically a giant state machine
    /// that keeps track of which nodes to communicate with, which nodes are alive/dead/failing,
    /// etc...
    state: State,
    /// A collection of servers within the cluster. Note that these aren't allocated/running
    /// servers, so we use another record called `Node` to handle that understanding.
    servers: Vec<Node>,
    /// The internal receiver to handle incoming messages. These can be messages coming from a
    /// transport, or from a user.
    receiver: Receiver<ServerMsg>,
    /// The sender-half of the previous channel. This is copied to the user and transports to send
    /// incoming messages. These aren't always broadcasts! Broadcasts are simply one kind of server
    /// message.
    sender: Sender<ServerMsg>,
    /// This is the user sender so that we can communicate with the end user of this crate. Any
    /// broadcasts that we don't handle will be relayed to the user's sender and they can take
    /// care of it.
    tx: Sender<ServerMsg>
}

impl Server {

    /// Create a standard, default server. This only initializes the server
    /// but does **not** start it! So it doesn't spawn a new thread.
    ///
    /// This function requires a Sender so that the server can relay messages
    /// externally (such as the user of the crate).
    pub fn new(sender: Sender<ServerMsg>) -> Server {
        // Create an internal channel for the server. The sender is often
        // copied around to various components.
        let (tx, rx) = channel();

        Server {
            id: Uuid::new_v4(),
            addr: None,
            state: State::new(),
            servers: Vec::new(),
            receiver: rx,
            sender: tx,
            tx: sender
        }
    }

    /// Create a new `ServerTask` that is responsible for fully initializing and starting
    /// the server component. A `ServerTask` is what the user will interact with as the server
    /// is running within another task, so the communication protocol is through channels
    /// exclusively.
    pub fn create(ip: &str, port: u16) -> ServerTask {
        ServerTask::create(ip, port)
    }

    /// Bind the server to the specified address. If there's a transport,
    /// it has the possibility of failing.
    pub fn listen(&mut self, ip: &str, port: u16) -> GossipResult<()> {
        self.addr = Some(Addr::new(ip, port));

        // FIXME: We'll probably need a select! macro invocation to allow the ability
        // to read from multiple sources.
        loop {
            // Receive the next message from the channel. This can be from any component.
            match self.receiver.recv() {
                // Ok, so we are tasked with shutting down. We'll relay the shutdown
                // message back to the user so they can do some cleanup or other operations.
                //
                // FIXME: We'll need to broadcast to the cluster that this server is shutting down.
                Shutdown(reason) => {
                    self.tx.send(Shutdown(reason));
                    break;
                },
                _ => {}
            }
        }

        Ok(())
    }
}

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

    #[test]
    fn default_server() {
        let (tx, rx) = channel();
        let s = Server::new(tx);
        assert!(s.addr.is_none())
    }
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate string_telephone;
extern crate collections;

use collections::str::{Slice, Owned};
use std::io::net::ip::{Ipv4Addr, SocketAddr};
use piston::{EventIterator, EventSettings, WindowSettings, NoWindow};
use string_telephone::{Server, ConnectionConfig, UserPacket};

struct Player {
    controller: SocketAddr,
    x: uint,
    y: uint
}

fn deserializer(message: &Vec<u8>) -> String {
    match String::from_utf8_lossy(message.as_slice()) {
        Slice(slice) => slice.to_string(),
        Owned(item) => item
    }
}

fn serializer(packet: &String) -> Vec<u8> {
    packet.clone().into_bytes()
}

fn main() {
    let mut window = NoWindow::new(WindowSettings {
        title: "SuperMegaTag".to_string(),
        size: [0u32, 0u32],
        samples: 0,
        fullscreen: false,
        exit_on_esc: true,
    });

    let game_iter_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };

    let settings = ConnectionConfig {
        protocol_id: 88869,
        timeout_period: 10,
        packet_deserializer: deserializer,
        packet_serializer: serializer
    };

    let mut server = match Server::new(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 8869}, settings) {
        Ok(server) => {
            println!("Listening on {}", server.addr);
            server
        },
        Err(e) => fail!("Failed to start listening - {}", e)
    };

    for e in EventIterator::new(&mut window, &game_iter_settings) {
        loop {
            match server.poll() {
                Some((UserPacket(packet), _)) => {
                    //Do something
                },
                Some(_) => (),
                None => break
            }
        };

        let culled = server.cull();
        if culled.len() > 0 {
            println!("{}", culled);
        }
    }
}
<commit_msg>Started working on entities<commit_after>extern crate piston;
extern crate string_telephone;
extern crate collections;

use collections::str::{Slice, Owned};
use std::io::net::ip::{Ipv4Addr, SocketAddr};
use piston::{EventIterator, EventSettings, WindowSettings, NoWindow};
use string_telephone::{Server, ConnectionConfig, UserPacket};
use std::fmt;

struct Player {
    controller: SocketAddr,
    x: i32,
    y: i32,

    keyUp: bool,
    keyDown: bool,
    keyLeft: bool,
    keyRight: bool
}

impl Player {
    pub fn new (controller: SocketAddr, x: i32, y: i32) -> Player {
        Player {
            controller: controller,
            x: x,
            y: y,
            keyUp: false,
            keyDown: false,
            keyLeft: false,
            keyRight: false
        }
    }

    pub fn move(&mut self) {
        if self.keyUp && self.y > 0 {
            self.y -= 1;
        } else if self.keyDown && self.y < 600 {
            self.y += 1;
        }

        if self.keyLeft && self.x > 0 {
            self.x -= 1;
        } else if self.keyRight && self.x < 800{
            self.x += 1;
        }
    }
}

impl fmt::Show for Player {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} at {} {}", self.controller, self.x, self.y)
    }
}

fn deserializer(message: &Vec<u8>) -> String {
    match String::from_utf8_lossy(message.as_slice()) {
        Slice(slice) => slice.to_string(),
        Owned(item) => item
    }
}

fn serializer(packet: &String) -> Vec<u8> {
    packet.clone().into_bytes()
}

fn main() {
    let mut window = NoWindow::new(WindowSettings {
        title: "SuperMegaTag".to_string(),
        size: [0u32, 0u32],
        samples: 0,
        fullscreen: false,
        exit_on_esc: true,
    });

    let game_iter_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };

    let settings = ConnectionConfig {
        protocol_id: 88869,
        timeout_period: 10,
        packet_deserializer: deserializer,
        packet_serializer: serializer
    };

    let mut server = match Server::new(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 8869}, settings) {
        Ok(server) => {
            println!("Listening on {}", server.addr);
            server
        },
        Err(e) => fail!("Failed to start listening - {}", e)
    };

    let mut players:Vec<Player> = vec![
        Player::new(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 8869}, 400, 300)
    ];

    for e in EventIterator::new(&mut window, &game_iter_settings) {
        match e {
            piston::Update(update_args) => {
                loop {
                    match server.poll() {
                        Some((UserPacket(packet), _)) => {
                            //Do something
                        },
                        Some(_) => (),
                        None => break
                    }
                };

                //Update the game world
                for player in players.iter_mut() {
                    player.move()
                }
                println!("{}", players);
                let culled = server.cull();
                if culled.len() > 0 {
                    println!("{}", culled);
                }
            },
            _ => ()
        }
    }
}
<|endoftext|>


<commit_before>extern crate "parser-combinators" as parser_combinators;
use self::parser_combinators::{between, spaces, parser, many, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;
use super::ast::NumNode::*;

pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        unimplemented!()
}

pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        spaces.clone().with(
            sexpr
                .or(parser(name).map(Name))
            ).parse_state(input)
}

#[cfg(test)]
mod tests {
    use ::ast::*;
    use ::ast::ExprNode::*;
    use super::{expr, number};
    use super::parser_combinators::{Parser,parser};

    #[test]
    fn test_basic_ident() {
        assert_eq!(
            parser(expr).parse("ident").unwrap(),
            (Name(NameNode { name: "ident".to_string() }), "")
            );
    }

    #[test]
    fn test_basic_sexpr() {
        assert_eq!(
            parser(expr).parse("(ident arg1 arg2)").unwrap(),
            (SExpr(SExprNode {
                operator: NameNode { name: "ident".to_string() },
                operands: vec![
                    Name(NameNode { name: "arg1".to_string() }),
                    Name(NameNode { name: "arg2".to_string() })
                ]
            }), "")
            );
    }

    #[test]
    fn test_parse_number() {
        assert_eq!(
            parser(number).parse("1234").unwrap(),
            (NumNode::IntConst(IntNode { value: 1234isize }), "")
            );
        assert_eq!(
            parser(number).parse("-1234").unwrap(),
            (NumNode::IntConst(IntNode { value: -1234isize }), "")
            );
        assert_eq!(
            parser(number).parse("1234u").unwrap(),
            (NumNode::UIntConst(UIntNode { value: 1234usize }), "")
            );
        assert_eq!(
            parser(number).parse("1.0").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("1f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
    }

}
<commit_msg>Implemented parser for signed ints<commit_after>extern crate "parser-combinators" as parser_combinators;
use self::parser_combinators::{between, spaces, parser, many, many1, digit, optional, hex_digit, not_followed_by, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;

pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        let signed_int = optional(satisfy(|c| c == '-'))
            .and(many1::<Vec<_>, _>(digit())
                .or(satisfy(|c| c == '0')
                    .with(satisfy(|c| c == 'x' || c == 'X'))
                    .with(many1::<Vec<_>, _>(hex_digit()))
                    )
                )
            .map(|x| {
                let mut s = String::new();
                if let Some(sign) = x.0 { s.push(sign) };
                x.1.iter()
                    .fold(s, |mut s: String, i| { s.push(*i); s })
                    .parse::<isize>()
                    .unwrap()
                });

        signed_int
            .map(|x: isize| NumNode::IntConst(IntNode{value: x}))
            .parse_state(input)
}

pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        spaces.clone().with(
            sexpr
                .or(parser(name).map(Name))
            ).parse_state(input)
}

#[cfg(test)]
mod tests {
    use ::ast::*;
    use ::ast::ExprNode::*;
    use super::{expr, number};
    use super::parser_combinators::{Parser,parser};

    #[test]
    fn test_basic_ident() {
        assert_eq!(
            parser(expr).parse("ident").unwrap(),
            (Name(NameNode { name: "ident".to_string() }), "")
            );
    }

    #[test]
    fn test_basic_sexpr() {
        assert_eq!(
            parser(expr).parse("(ident arg1 arg2)").unwrap(),
            (SExpr(SExprNode {
                operator: NameNode { name: "ident".to_string() },
                operands: vec![
                    Name(NameNode { name: "arg1".to_string() }),
                    Name(NameNode { name: "arg2".to_string() })
                ]
            }), "")
            );
    }

    #[test]
    fn test_parse_number() {
        assert_eq!(
            parser(number).parse("1234").unwrap(),
            (NumNode::IntConst(IntNode { value: 1234isize }), "")
            );
        assert_eq!(
            parser(number).parse("-1234").unwrap(),
            (NumNode::IntConst(IntNode { value: -1234isize }), "")
            );
        assert_eq!(
            parser(number).parse("1234u").unwrap(),
            (NumNode::UIntConst(UIntNode { value: 1234usize }), "")
            );
        assert_eq!(
            parser(number).parse("1.0").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("1f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
        assert_eq!(
            parser(number).parse("22.2222f").unwrap(),
            (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
            );
    }

}
<|endoftext|>


<commit_before>//! This module contains the parallel iterator types for slices
//! (`[T]`). You will rarely need to interact with it directly unless
//! you have need to name one of those types.

use iter::*;
use iter::internal::*;

/// Parallel extensions for slices.
///
/// Implementing this trait is not permitted outside of `rayon`.
pub trait ParallelSlice<T> {
    private_decl!{}

    /// Returns a parallel iterator over all contiguous windows of
    /// length `size`. The windows overlap.
    fn par_windows(&self, size: usize) -> WindowsIter<T> where T: Sync;

    /// Returns a parallel iterator over at most `size` elements of
    /// `self` at a time. The chunks do not overlap.
    fn par_chunks(&self, size: usize) -> ChunksIter<T> where T: Sync;

    /// Returns a parallel iterator over at most `size` elements of
    /// `self` at a time. The chunks are mutable and do not overlap.
    fn par_chunks_mut(&mut self, size: usize) -> ChunksMutIter<T> where T: Send;
}

pub struct SliceIter<'data, T: 'data + Sync> {
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T] {
    type Item = &'data T;
    type Iter = SliceIter<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIter { slice: self }
    }
}

impl<'data, T: Sync + 'data> IntoParallelIterator for &'data Vec<T> {
    type Item = &'data T;
    type Iter = SliceIter<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIter { slice: self }
    }
}

impl<T> ParallelSlice<T> for [T] {
    private_impl!{}

    fn par_windows(&self, window_size: usize) -> WindowsIter<T> where T: Sync {
        WindowsIter {
            window_size: window_size,
            slice: self,
        }
    }

    fn par_chunks(&self, chunk_size: usize) -> ChunksIter<T> where T: Sync {
        ChunksIter {
            chunk_size: chunk_size,
            slice: self,
        }
    }

    fn par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMutIter<T> where T: Send {
        ChunksMutIter {
            chunk_size: chunk_size,
            slice: self,
        }
    }
}

impl<'data, T: Sync + 'data> ParallelIterator for SliceIter<'data, T> {
    type Item = &'data T;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for SliceIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for SliceIter<'data, T> {
    fn len(&mut self) -> usize {
        self.slice.len()
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for SliceIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceProducer { slice: self.slice })
    }
}

pub struct ChunksIter<'data, T: 'data + Sync> {
    chunk_size: usize,
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> ParallelIterator for ChunksIter<'data, T> {
    type Item = &'data [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for ChunksIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for ChunksIter<'data, T> {
    fn len(&mut self) -> usize {
        (self.slice.len() + (self.chunk_size - 1)) / self.chunk_size
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for ChunksIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceChunksProducer {
            chunk_size: self.chunk_size,
            slice: self.slice,
        })
    }
}

pub struct WindowsIter<'data, T: 'data + Sync> {
    window_size: usize,
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> ParallelIterator for WindowsIter<'data, T> {
    type Item = &'data [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for WindowsIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for WindowsIter<'data, T> {
    fn len(&mut self) -> usize {
        assert!(self.window_size >= 1);
        self.slice.len().saturating_sub(self.window_size - 1)
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for WindowsIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceWindowsProducer {
            window_size: self.window_size,
            slice: self.slice,
        })
    }
}

/// ////////////////////////////////////////////////////////////////////////

struct SliceProducer<'data, T: 'data + Sync> {
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceProducer<'data, T> {
    type Item = &'data T;
    type IntoIter = ::std::slice::Iter<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.into_iter()
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let (left, right) = self.slice.split_at(index);
        (SliceProducer { slice: left }, SliceProducer { slice: right })
    }
}

struct SliceChunksProducer<'data, T: 'data + Sync> {
    chunk_size: usize,
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceChunksProducer<'data, T> {
    type Item = &'data [T];
    type IntoIter = ::std::slice::Chunks<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.chunks(self.chunk_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let elem_index = index * self.chunk_size;
        let (left, right) = self.slice.split_at(elem_index);
        (SliceChunksProducer {
             chunk_size: self.chunk_size,
             slice: left,
         },
         SliceChunksProducer {
             chunk_size: self.chunk_size,
             slice: right,
         })
    }
}

struct SliceWindowsProducer<'data, T: 'data + Sync> {
    window_size: usize,
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceWindowsProducer<'data, T> {
    type Item = &'data [T];
    type IntoIter = ::std::slice::Windows<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.windows(self.window_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let left = &self.slice[..index + (self.window_size - 1)];
        let right = &self.slice[index..];
        (SliceWindowsProducer {
             window_size: self.window_size,
             slice: left,
         },
         SliceWindowsProducer {
             window_size: self.window_size,
             slice: right,
         })
    }
}

pub struct SliceIterMut<'data, T: 'data + Send> {
    slice: &'data mut [T],
}

impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut [T] {
    type Item = &'data mut T;
    type Iter = SliceIterMut<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIterMut { slice: self }
    }
}

impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut Vec<T> {
    type Item = &'data mut T;
    type Iter = SliceIterMut<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIterMut { slice: self }
    }
}

impl<'data, T: Send + 'data> ParallelIterator for SliceIterMut<'data, T> {
    type Item = &'data mut T;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Send + 'data> BoundedParallelIterator for SliceIterMut<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Send + 'data> ExactParallelIterator for SliceIterMut<'data, T> {
    fn len(&mut self) -> usize {
        self.slice.len()
    }
}

impl<'data, T: Send + 'data> IndexedParallelIterator for SliceIterMut<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceMutProducer { slice: self.slice })
    }
}

pub struct ChunksMutIter<'data, T: 'data + Send> {
    chunk_size: usize,
    slice: &'data mut [T],
}

impl<'data, T: Send + 'data> ParallelIterator for ChunksMutIter<'data, T> {
    type Item = &'data mut [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Send + 'data> BoundedParallelIterator for ChunksMutIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Send + 'data> ExactParallelIterator for ChunksMutIter<'data, T> {
    fn len(&mut self) -> usize {
        (self.slice.len() + (self.chunk_size - 1)) / self.chunk_size
    }
}

impl<'data, T: Send + 'data> IndexedParallelIterator for ChunksMutIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceChunksMutProducer {
            chunk_size: self.chunk_size,
            slice: self.slice,
        })
    }
}

/// ////////////////////////////////////////////////////////////////////////

struct SliceMutProducer<'data, T: 'data + Send> {
    slice: &'data mut [T],
}

impl<'data, T: 'data + Send> Producer for SliceMutProducer<'data, T> {
    type Item = &'data mut T;
    type IntoIter = ::std::slice::IterMut<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.into_iter()
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let (left, right) = self.slice.split_at_mut(index);
        (SliceMutProducer { slice: left }, SliceMutProducer { slice: right })
    }
}

struct SliceChunksMutProducer<'data, T: 'data + Send> {
    chunk_size: usize,
    slice: &'data mut [T],
}

impl<'data, T: 'data + Send> Producer for SliceChunksMutProducer<'data, T> {
    type Item = &'data mut [T];
    type IntoIter = ::std::slice::ChunksMut<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.chunks_mut(self.chunk_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let elem_index = index * self.chunk_size;
        let (left, right) = self.slice.split_at_mut(elem_index);
        (SliceChunksMutProducer {
             chunk_size: self.chunk_size,
             slice: left,
         },
         SliceChunksMutProducer {
             chunk_size: self.chunk_size,
             slice: right,
         })
    }
}
<commit_msg>Reorganize slice producers next to their iters<commit_after>//! This module contains the parallel iterator types for slices
//! (`[T]`). You will rarely need to interact with it directly unless
//! you have need to name one of those types.

use iter::*;
use iter::internal::*;

/// Parallel extensions for slices.
///
/// Implementing this trait is not permitted outside of `rayon`.
pub trait ParallelSlice<T> {
    private_decl!{}

    /// Returns a parallel iterator over all contiguous windows of
    /// length `size`. The windows overlap.
    fn par_windows(&self, size: usize) -> WindowsIter<T> where T: Sync;

    /// Returns a parallel iterator over at most `size` elements of
    /// `self` at a time. The chunks do not overlap.
    fn par_chunks(&self, size: usize) -> ChunksIter<T> where T: Sync;

    /// Returns a parallel iterator over at most `size` elements of
    /// `self` at a time. The chunks are mutable and do not overlap.
    fn par_chunks_mut(&mut self, size: usize) -> ChunksMutIter<T> where T: Send;
}

impl<T> ParallelSlice<T> for [T] {
    private_impl!{}

    fn par_windows(&self, window_size: usize) -> WindowsIter<T> where T: Sync {
        WindowsIter {
            window_size: window_size,
            slice: self,
        }
    }

    fn par_chunks(&self, chunk_size: usize) -> ChunksIter<T> where T: Sync {
        ChunksIter {
            chunk_size: chunk_size,
            slice: self,
        }
    }

    fn par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMutIter<T> where T: Send {
        ChunksMutIter {
            chunk_size: chunk_size,
            slice: self,
        }
    }
}

impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T] {
    type Item = &'data T;
    type Iter = SliceIter<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIter { slice: self }
    }
}

impl<'data, T: Sync + 'data> IntoParallelIterator for &'data Vec<T> {
    type Item = &'data T;
    type Iter = SliceIter<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIter { slice: self }
    }
}

impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut [T] {
    type Item = &'data mut T;
    type Iter = SliceIterMut<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIterMut { slice: self }
    }
}

impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut Vec<T> {
    type Item = &'data mut T;
    type Iter = SliceIterMut<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        SliceIterMut { slice: self }
    }
}

/// Parallel iterator over immutable items in a slice
pub struct SliceIter<'data, T: 'data + Sync> {
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> ParallelIterator for SliceIter<'data, T> {
    type Item = &'data T;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for SliceIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for SliceIter<'data, T> {
    fn len(&mut self) -> usize {
        self.slice.len()
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for SliceIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceProducer { slice: self.slice })
    }
}

struct SliceProducer<'data, T: 'data + Sync> {
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceProducer<'data, T> {
    type Item = &'data T;
    type IntoIter = ::std::slice::Iter<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.into_iter()
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let (left, right) = self.slice.split_at(index);
        (SliceProducer { slice: left }, SliceProducer { slice: right })
    }
}

/// Parallel iterator over immutable non-overlapping chunks of a slice
pub struct ChunksIter<'data, T: 'data + Sync> {
    chunk_size: usize,
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> ParallelIterator for ChunksIter<'data, T> {
    type Item = &'data [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for ChunksIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for ChunksIter<'data, T> {
    fn len(&mut self) -> usize {
        (self.slice.len() + (self.chunk_size - 1)) / self.chunk_size
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for ChunksIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceChunksProducer {
            chunk_size: self.chunk_size,
            slice: self.slice,
        })
    }
}

struct SliceChunksProducer<'data, T: 'data + Sync> {
    chunk_size: usize,
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceChunksProducer<'data, T> {
    type Item = &'data [T];
    type IntoIter = ::std::slice::Chunks<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.chunks(self.chunk_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let elem_index = index * self.chunk_size;
        let (left, right) = self.slice.split_at(elem_index);
        (SliceChunksProducer {
             chunk_size: self.chunk_size,
             slice: left,
         },
         SliceChunksProducer {
             chunk_size: self.chunk_size,
             slice: right,
         })
    }
}

/// Parallel iterator over immutable overlapping windows of a slice
pub struct WindowsIter<'data, T: 'data + Sync> {
    window_size: usize,
    slice: &'data [T],
}

impl<'data, T: Sync + 'data> ParallelIterator for WindowsIter<'data, T> {
    type Item = &'data [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Sync + 'data> BoundedParallelIterator for WindowsIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Sync + 'data> ExactParallelIterator for WindowsIter<'data, T> {
    fn len(&mut self) -> usize {
        assert!(self.window_size >= 1);
        self.slice.len().saturating_sub(self.window_size - 1)
    }
}

impl<'data, T: Sync + 'data> IndexedParallelIterator for WindowsIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceWindowsProducer {
            window_size: self.window_size,
            slice: self.slice,
        })
    }
}

struct SliceWindowsProducer<'data, T: 'data + Sync> {
    window_size: usize,
    slice: &'data [T],
}

impl<'data, T: 'data + Sync> Producer for SliceWindowsProducer<'data, T> {
    type Item = &'data [T];
    type IntoIter = ::std::slice::Windows<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.windows(self.window_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let left = &self.slice[..index + (self.window_size - 1)];
        let right = &self.slice[index..];
        (SliceWindowsProducer {
             window_size: self.window_size,
             slice: left,
         },
         SliceWindowsProducer {
             window_size: self.window_size,
             slice: right,
         })
    }
}

/// Parallel iterator over mutable items in a slice
pub struct SliceIterMut<'data, T: 'data + Send> {
    slice: &'data mut [T],
}

impl<'data, T: Send + 'data> ParallelIterator for SliceIterMut<'data, T> {
    type Item = &'data mut T;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Send + 'data> BoundedParallelIterator for SliceIterMut<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Send + 'data> ExactParallelIterator for SliceIterMut<'data, T> {
    fn len(&mut self) -> usize {
        self.slice.len()
    }
}

impl<'data, T: Send + 'data> IndexedParallelIterator for SliceIterMut<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceMutProducer { slice: self.slice })
    }
}

struct SliceMutProducer<'data, T: 'data + Send> {
    slice: &'data mut [T],
}

impl<'data, T: 'data + Send> Producer for SliceMutProducer<'data, T> {
    type Item = &'data mut T;
    type IntoIter = ::std::slice::IterMut<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.into_iter()
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let (left, right) = self.slice.split_at_mut(index);
        (SliceMutProducer { slice: left }, SliceMutProducer { slice: right })
    }
}

/// Parallel iterator over mutable non-overlapping chunks of a slice
pub struct ChunksMutIter<'data, T: 'data + Send> {
    chunk_size: usize,
    slice: &'data mut [T],
}

impl<'data, T: Send + 'data> ParallelIterator for ChunksMutIter<'data, T> {
    type Item = &'data mut [T];

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        bridge(self, consumer)
    }

    fn opt_len(&mut self) -> Option<usize> {
        Some(self.len())
    }
}

impl<'data, T: Send + 'data> BoundedParallelIterator for ChunksMutIter<'data, T> {
    fn upper_bound(&mut self) -> usize {
        ExactParallelIterator::len(self)
    }

    fn drive<C>(self, consumer: C) -> C::Result
        where C: Consumer<Self::Item>
    {
        bridge(self, consumer)
    }
}

impl<'data, T: Send + 'data> ExactParallelIterator for ChunksMutIter<'data, T> {
    fn len(&mut self) -> usize {
        (self.slice.len() + (self.chunk_size - 1)) / self.chunk_size
    }
}

impl<'data, T: Send + 'data> IndexedParallelIterator for ChunksMutIter<'data, T> {
    fn with_producer<CB>(self, callback: CB) -> CB::Output
        where CB: ProducerCallback<Self::Item>
    {
        callback.callback(SliceChunksMutProducer {
            chunk_size: self.chunk_size,
            slice: self.slice,
        })
    }
}

struct SliceChunksMutProducer<'data, T: 'data + Send> {
    chunk_size: usize,
    slice: &'data mut [T],
}

impl<'data, T: 'data + Send> Producer for SliceChunksMutProducer<'data, T> {
    type Item = &'data mut [T];
    type IntoIter = ::std::slice::ChunksMut<'data, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.slice.chunks_mut(self.chunk_size)
    }

    fn split_at(self, index: usize) -> (Self, Self) {
        let elem_index = index * self.chunk_size;
        let (left, right) = self.slice.split_at_mut(elem_index);
        (SliceChunksMutProducer {
             chunk_size: self.chunk_size,
             slice: left,
         },
         SliceChunksMutProducer {
             chunk_size: self.chunk_size,
             slice: right,
         })
    }
}
<|endoftext|>