<commit_before>use libc;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;

pub struct PropertyBag<'a>(HashMap<&'a CStr, &'a CStr>);

pub struct OwnedPropertyBag(HashMap<CString, CString>);

pub struct PropertyBagIter<'a>(hash_map::Iter<'a, &'a CStr, &'a CStr>);

pub struct PropertyBagCStrIter<'a>(hash_map::Iter<'a, &'a CStr, &'a CStr>);

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    map.insert(key_str, val_str);
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, v) in &owned.0 {
            map.insert(k.deref(), v.deref());
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, CString>::new();

        for (k, v) in &self.0 {
            map.insert((*k).to_owned(), (*v).to_owned());
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn lookup_cstr(&self, key: &CStr) -> Option<&CStr> {
        self.0.get(key).map(|v| *v)
    }

    pub fn lookup(&self, key: &str) -> Option<&str> {
        let k = CString::new(key).unwrap();
        self.lookup_cstr(&k).map(|v| v.to_str().unwrap())
    }

    pub fn enumerate(&self,
                 enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                 data: *const libc::c_void) {
        for (k, v) in &self.0 {
            enum_fn(k.as_ptr(), v.as_ptr(), data);
        }
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter(self.0.iter())
    }

    pub fn cstr_iter(&self) -> PropertyBagCStrIter {
        PropertyBagCStrIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, v)| (k.to_str().unwrap(), v.to_str().unwrap()))
    }
}

impl<'a> Iterator for PropertyBagCStrIter<'a> {
    type Item = (&'a CStr, &'a CStr);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, v)| (*k, *v))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_size(pbag: *const PropertyBag) -> libc::c_uint {
    unsafe {
        let pbag = &*pbag;

        pbag.len() as libc::c_uint
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_enumerate(pbag: *const PropertyBag,
                                          enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                                          data: *const libc::c_void) {
    unsafe {
        let pbag = &*pbag;

        pbag.enumerate(enum_fn, data);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
                                       raw_key: *const libc::c_char) -> *const libc::c_char {
    unsafe {
        let pbag = &*pbag;
        let key = CStr::from_ptr(raw_key);
        match pbag.lookup_cstr(key) {
            Some(v) => v.as_ptr(),
            None => ptr::null()
        }
    }
}

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

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_lookups_and_iters() {
        let pairs = [
            CString::new("alpha").unwrap(),
            CString::new("1").unwrap(),
            CString::new("beta").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        assert_eq!(pbag.lookup("alpha"), Some("1"));
        assert_eq!(pbag.lookup("beta"), Some("2"));
        assert_eq!(pbag.lookup("gamma"), None);

        let mut had_alpha: bool = false;
        let mut had_beta: bool = false;

        for (k, _) in pbag.iter() {
            if k == "alpha" {
                had_alpha = true;
            } else if k == "beta" {
                had_beta = true;
            }
        }

        assert!(had_alpha);
        assert!(had_beta);
    }
}
<commit_msg>PropertyBag: implement PropertyBagIter in terms of PropertyBagCStrIter<commit_after>use libc;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;

pub struct PropertyBag<'a>(HashMap<&'a CStr, &'a CStr>);

pub struct OwnedPropertyBag(HashMap<CString, CString>);

pub struct PropertyBagIter<'a>(PropertyBagCStrIter<'a>);

pub struct PropertyBagCStrIter<'a>(hash_map::Iter<'a, &'a CStr, &'a CStr>);

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    map.insert(key_str, val_str);
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, v) in &owned.0 {
            map.insert(k.deref(), v.deref());
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, CString>::new();

        for (k, v) in &self.0 {
            map.insert((*k).to_owned(), (*v).to_owned());
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn lookup_cstr(&self, key: &CStr) -> Option<&CStr> {
        self.0.get(key).map(|v| *v)
    }

    pub fn lookup(&self, key: &str) -> Option<&str> {
        let k = CString::new(key).unwrap();
        self.lookup_cstr(&k).map(|v| v.to_str().unwrap())
    }

    pub fn enumerate(&self,
                 enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                 data: *const libc::c_void) {
        for (k, v) in &self.0 {
            enum_fn(k.as_ptr(), v.as_ptr(), data);
        }
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter(self.cstr_iter())
    }

    pub fn cstr_iter(&self) -> PropertyBagCStrIter {
        PropertyBagCStrIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, v)| (k.to_str().unwrap(), v.to_str().unwrap()))
    }
}

impl<'a> Iterator for PropertyBagCStrIter<'a> {
    type Item = (&'a CStr, &'a CStr);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, v)| (*k, *v))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_size(pbag: *const PropertyBag) -> libc::c_uint {
    unsafe {
        let pbag = &*pbag;

        pbag.len() as libc::c_uint
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_enumerate(pbag: *const PropertyBag,
                                          enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
                                          data: *const libc::c_void) {
    unsafe {
        let pbag = &*pbag;

        pbag.enumerate(enum_fn, data);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
                                       raw_key: *const libc::c_char) -> *const libc::c_char {
    unsafe {
        let pbag = &*pbag;
        let key = CStr::from_ptr(raw_key);
        match pbag.lookup_cstr(key) {
            Some(v) => v.as_ptr(),
            None => ptr::null()
        }
    }
}

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

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_lookups_and_iters() {
        let pairs = [
            CString::new("alpha").unwrap(),
            CString::new("1").unwrap(),
            CString::new("beta").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        assert_eq!(pbag.lookup("alpha"), Some("1"));
        assert_eq!(pbag.lookup("beta"), Some("2"));
        assert_eq!(pbag.lookup("gamma"), None);

        let mut had_alpha: bool = false;
        let mut had_beta: bool = false;

        for (k, _) in pbag.iter() {
            if k == "alpha" {
                had_alpha = true;
            } else if k == "beta" {
                had_beta = true;
            }
        }

        assert!(had_alpha);
        assert!(had_beta);
    }
}
<|endoftext|>


<commit_before>#[allow(unknown_lints)]
#[allow(clippy)]
mod grammar;

pub use self::grammar::ProgramParser;<commit_msg>Add a buttload of parser unit tests<commit_after>#[allow(unknown_lints)]
#[allow(clippy)]
mod grammar;

pub use self::grammar::ProgramParser;

#[cfg(test)]
mod test {
    use super::*;
    use ast::{Expr, Operator, Stmt};
    use lexer::Lexer;

    fn parse(input: &str, expected: Vec<Stmt>) {
        let lexer = Lexer::new(input);
        let parser = ProgramParser::new();
        assert_eq!(expected, parser.parse(lexer).unwrap());
    }

    #[test]
    fn literals() {
        parse("nil", vec![Stmt::ExprStmt(Expr::Nil)]);
        parse("true", vec![Stmt::ExprStmt(Expr::BooleanLiteral(true))]);
        parse("false", vec![Stmt::ExprStmt(Expr::BooleanLiteral(false))]);
        parse("123", vec![Stmt::ExprStmt(Expr::NumberLiteral(123.0))]);
        parse("123.45", vec![Stmt::ExprStmt(Expr::NumberLiteral(123.45))]);
        parse(
            "\"string\"",
            vec![Stmt::ExprStmt(Expr::StringLiteral("string".to_string()))],
        );
    }

    #[test]
    fn identifiers() {
        parse(
            "id",
            vec![Stmt::ExprStmt(Expr::Identifier("id".to_string()))],
        );

        parse(
            "_id",
            vec![Stmt::ExprStmt(Expr::Identifier("_id".to_string()))],
        );

        parse(
            "id123",
            vec![Stmt::ExprStmt(Expr::Identifier("id123".to_string()))],
        );
    }

    #[test]
    fn assignment() {
        parse(
            "x = 10",
            vec![
                Stmt::ExprStmt(Expr::Assign(
                    "x".to_string(),
                    Box::new(Expr::NumberLiteral(10.0)),
                )),
            ],
        );

        parse(
            "x = y = 10",
            vec![
                Stmt::ExprStmt(Expr::Assign(
                    "x".to_string(),
                    Box::new(Expr::Assign(
                        "y".to_string(),
                        Box::new(Expr::NumberLiteral(10.0)),
                    )),
                )),
            ],
        );
    }

    #[test]
    fn equality() {
        parse(
            "nil == nil",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Equals,
                    Box::new(Expr::Nil),
                    Box::new(Expr::Nil),
                )),
            ],
        );

        parse(
            "nil != nil",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::NotEquals,
                    Box::new(Expr::Nil),
                    Box::new(Expr::Nil),
                )),
            ],
        );
    }

    #[test]
    fn comparison() {
        parse(
            "10 > 5",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::GreaterThan,
                    Box::new(Expr::NumberLiteral(10.0)),
                    Box::new(Expr::NumberLiteral(5.0)),
                )),
            ],
        );

        parse(
            "10 >= 5",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::GreaterEquals,
                    Box::new(Expr::NumberLiteral(10.0)),
                    Box::new(Expr::NumberLiteral(5.0)),
                )),
            ],
        );

        parse(
            "10 < 5",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::LessThan,
                    Box::new(Expr::NumberLiteral(10.0)),
                    Box::new(Expr::NumberLiteral(5.0)),
                )),
            ],
        );

        parse(
            "10 <= 5",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::LessEquals,
                    Box::new(Expr::NumberLiteral(10.0)),
                    Box::new(Expr::NumberLiteral(5.0)),
                )),
            ],
        );
    }

    #[test]
    fn addition() {
        parse(
            "1 + 1",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Add,
                    Box::new(Expr::NumberLiteral(1.0)),
                    Box::new(Expr::NumberLiteral(1.0)),
                )),
            ],
        );
    }

    #[test]
    fn subtraction() {
        parse(
            "1 - 1",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Subtract,
                    Box::new(Expr::NumberLiteral(1.0)),
                    Box::new(Expr::NumberLiteral(1.0)),
                )),
            ],
        );
    }

    #[test]
    fn multiplication() {
        parse(
            "1 * 1",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Multiply,
                    Box::new(Expr::NumberLiteral(1.0)),
                    Box::new(Expr::NumberLiteral(1.0)),
                )),
            ],
        );
    }

    #[test]
    fn division() {
        parse(
            "1 / 1",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Divide,
                    Box::new(Expr::NumberLiteral(1.0)),
                    Box::new(Expr::NumberLiteral(1.0)),
                )),
            ],
        );
    }

    #[test]
    fn unary() {
        parse(
            "!true",
            vec![
                Stmt::ExprStmt(Expr::UnaryOp(
                    Operator::Not,
                    Box::new(Expr::BooleanLiteral(true)),
                )),
            ],
        );

        parse(
            "-true",
            vec![
                Stmt::ExprStmt(Expr::UnaryOp(
                    Operator::UnaryMinus,
                    Box::new(Expr::BooleanLiteral(true)),
                )),
            ],
        );
    }

    #[test]
    fn precedence() {
        // TODO: Might be worth adding test cases for the other ops
        parse(
            "x = -1 * 2 + 3 > 4 != 5",
            vec![
                Stmt::ExprStmt(Expr::Assign(
                    "x".to_string(),
                    Box::new(Expr::BinaryOp(
                        Operator::NotEquals,
                        Box::new(Expr::BinaryOp(
                            Operator::GreaterThan,
                            Box::new(Expr::BinaryOp(
                                Operator::Add,
                                Box::new(Expr::BinaryOp(
                                    Operator::Multiply,
                                    Box::new(Expr::UnaryOp(
                                        Operator::UnaryMinus,
                                        Box::new(Expr::NumberLiteral(1.0)),
                                    )),
                                    Box::new(Expr::NumberLiteral(2.0)),
                                )),
                                Box::new(Expr::NumberLiteral(3.0)),
                            )),
                            Box::new(Expr::NumberLiteral(4.0)),
                        )),
                        Box::new(Expr::NumberLiteral(5.0)),
                    )),
                )),
            ],
        );
    }

    #[test]
    fn grouping() {
        parse(
            "2 * (1 + 2) * 3",
            vec![
                Stmt::ExprStmt(Expr::BinaryOp(
                    Operator::Multiply,
                    Box::new(Expr::BinaryOp(
                        Operator::Multiply,
                        Box::new(Expr::NumberLiteral(2.0)),
                        Box::new(Expr::BinaryOp(
                            Operator::Add,
                            Box::new(Expr::NumberLiteral(1.0)),
                            Box::new(Expr::NumberLiteral(2.0)),
                        )),
                    )),
                    Box::new(Expr::NumberLiteral(3.0)),
                )),
            ],
        );
    }

    #[test]
    fn declaration() {
        parse(
            "let x = 10",
            vec![
                Stmt::Declaration("x".to_string(), Expr::NumberLiteral(10.0)),
            ],
        );
    }

    #[test]
    fn program() {
        parse(
            "\nx\ny\n\nz\n",
            vec![
                Stmt::ExprStmt(Expr::Identifier("x".to_string())),
                Stmt::ExprStmt(Expr::Identifier("y".to_string())),
                Stmt::ExprStmt(Expr::Identifier("z".to_string())),
            ],
        );
    }
}
<|endoftext|>


<commit_before>use super::mode;
use super::string_utils;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Break(uint, uint),
    Group(Box<Doc>),
    Nest(uint, Box<Doc>),
    Newline,
    Text(String),
}

pub type Doc = DOC;

fn fitting(xs:Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    match xs.as_slice() {
        [] => {
            true
        },
        [(i, mode, ref doc), rest..] => match doc.clone() {
            Nil => {
                fitting(rest.to_vec(), left)
            },
            Append(box x, box y) => {
                let mut ys = [(i, mode, x), (i, mode, y)].to_vec();
                ys.push_all(rest);
                fitting(ys, left)
            },
            Nest(j, box x) => {
                let mut ys = [(i + j, mode, x)].to_vec();
                ys.push_all(rest);
                fitting(ys, left)
            },
            Text(str) => {
                fitting(rest.to_vec(), left - str.len())
            },
            Break(sp, _) => match mode {
                mode::Flat => {
                    fitting(rest.to_vec(), left - sp)
                },
                mode::Break => {
                    true
                },
            },
            Newline => {
                true
            },
            Group(box x) => {
                let mut ys = [(i, mode, x)].to_vec();
                ys.push_all(rest);
                fitting(ys, left)
            },
        }
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0, x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s,
            [(i, mode, ref doc), rest..] => match doc.clone() {
                Nil => {
                    go(w, s, k, rest.to_vec())
                },
                Append(box x, box y) => {
                    let mut zs = [(i, mode, x), (i, mode, y)].to_vec();
                    zs.push_all(rest);
                    go(w, s, k, zs)
                },
                Nest(j, box x) => {
                    let mut zs = [(i + j, mode, x)].to_vec();
                    zs.push_all(rest);
                    go(w, s, k, zs)
                },
                Text(str) => {
                    go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec())
                },
                Newline => {
                    go(w, prepend(s, string_utils::nl_space(i)), i, rest.to_vec())
                },
                Break(sp, off) => {
                    match mode {
                        mode::Flat => {
                            go(w, prepend(s, string_utils::spaces(sp)), k + sp, rest.to_vec())
                        },
                        mode::Break => {
                            go(w, prepend(s, string_utils::nl_space(i + off)), i + off, rest.to_vec())
                        }
                    }
                },
                Group(box x) => {
                    match mode {
                        mode::Flat => {
                            let mut zs = [(i, mode::Flat, x)].to_vec();
                            zs.push_all(rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = [(i, mode::Flat, x.clone())].to_vec();
                            ys.push_all(rest);
                            if fitting(ys.clone(), w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = [(i, mode::Break, x)].to_vec();
                                zs.push_all(rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, [(0, mode::Break, x)].to_vec())
}

impl Doc {

    pub fn nil() -> Doc {
        Nil
    }

    pub fn append(self, e:Doc) -> Doc {
        match self {
            Nil => e,
            x => match e {
                Nil => x,
                y => Append(box x, box y)
            }
        }
    }

    pub fn nest(self, i:uint) -> Doc {
        Nest(i, box self)
    }

    pub fn text<S:Str>(s:S) -> Doc {
        Text(String::from_str(s.as_slice()))
    }

    pub fn brk(space:uint, offset:uint) -> Doc {
        Break(space, offset)
    }

    pub fn newline() -> Doc {
        Newline
    }

    pub fn group(self) -> Doc {
        Group(box self)
    }

    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn as_str<T:ToString>(t:T) -> Doc {
        Doc::text(t.to_string())
    }

    pub fn to_string(self, w:uint) -> String {
        let mut strs = best(w, Vec::new(), self);
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}
<commit_msg>Use vec! notation<commit_after>use super::mode;
use super::string_utils;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Break(uint, uint),
    Group(Box<Doc>),
    Nest(uint, Box<Doc>),
    Newline,
    Text(String),
}

pub type Doc = DOC;

fn fitting(xs:Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    match xs.as_slice() {
        [] => {
            true
        },
        [(i, mode, ref doc), rest..] => match doc.clone() {
            Nil => {
                fitting(rest.to_vec(), left)
            },
            Append(box x, box y) => {
                let mut ys = vec![(i, mode, x), (i, mode, y)];
                ys.push_all(rest);
                fitting(ys, left)
            },
            Nest(j, box x) => {
                let mut ys = vec![(i + j, mode, x)];
                ys.push_all(rest);
                fitting(ys, left)
            },
            Text(str) => {
                fitting(rest.to_vec(), left - str.len())
            },
            Break(sp, _) => match mode {
                mode::Flat => {
                    fitting(rest.to_vec(), left - sp)
                },
                mode::Break => {
                    true
                },
            },
            Newline => {
                true
            },
            Group(box x) => {
                let mut ys = vec![(i, mode, x)];
                ys.push_all(rest);
                fitting(ys, left)
            },
        }
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0, x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s,
            [(i, mode, ref doc), rest..] => match doc.clone() {
                Nil => {
                    go(w, s, k, rest.to_vec())
                },
                Append(box x, box y) => {
                    let mut zs = vec![(i, mode, x), (i, mode, y)];
                    zs.push_all(rest);
                    go(w, s, k, zs)
                },
                Nest(j, box x) => {
                    let mut zs = vec![(i + j, mode, x)];
                    zs.push_all(rest);
                    go(w, s, k, zs)
                },
                Text(str) => {
                    go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec())
                },
                Newline => {
                    go(w, prepend(s, string_utils::nl_space(i)), i, rest.to_vec())
                },
                Break(sp, off) => {
                    match mode {
                        mode::Flat => {
                            go(w, prepend(s, string_utils::spaces(sp)), k + sp, rest.to_vec())
                        },
                        mode::Break => {
                            go(w, prepend(s, string_utils::nl_space(i + off)), i + off, rest.to_vec())
                        }
                    }
                },
                Group(box x) => {
                    match mode {
                        mode::Flat => {
                            let mut zs = vec![(i, mode::Flat, x)];
                            zs.push_all(rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = vec![(i, mode::Flat, x.clone())];
                            ys.push_all(rest);
                            if fitting(ys.clone(), w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = vec![(i, mode::Break, x)];
                                zs.push_all(rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, vec![(0, mode::Break, x)])
}

impl Doc {

    pub fn nil() -> Doc {
        Nil
    }

    pub fn append(self, e:Doc) -> Doc {
        match self {
            Nil => e,
            x => match e {
                Nil => x,
                y => Append(box x, box y)
            }
        }
    }

    pub fn nest(self, i:uint) -> Doc {
        Nest(i, box self)
    }

    pub fn text<S:Str>(s:S) -> Doc {
        Text(String::from_str(s.as_slice()))
    }

    pub fn brk(space:uint, offset:uint) -> Doc {
        Break(space, offset)
    }

    pub fn newline() -> Doc {
        Newline
    }

    pub fn group(self) -> Doc {
        Group(box self)
    }

    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn as_str<T:ToString>(t:T) -> Doc {
        Doc::text(t.to_string())
    }

    pub fn to_string(self, w:uint) -> String {
        let mut strs = best(w, Vec::new(), self);
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone, PartialEq)]
pub struct RetryConf {
    max: u64,
    multiplier: f64,
}

impl Default for RetryConf {
    fn default() -> RetryConf {
        RetryConf {
            max: 10,
            multiplier: 5_f64,
        }
    }
}

impl RetryConf {
    pub fn new() -> RetryConf {
        Default::default()
    }

    pub fn max(mut self, max: u64) -> RetryConf {
        self.max = max;
        self
    }

    pub fn multiplier(mut self, multiplier: f64) -> RetryConf {
        self.multiplier = multiplier;
        self
    }

    pub fn build(self) -> (u64, f64) {
        (self.max, self.multiplier)
    }
}
<commit_msg>retry_conf: Add rustdoc<commit_after>//! Retry sending records configuration.

/// You can calculate retrying interval as the following equation:
///
/// `retry_interval = exp ** (multiplier + retry_counts)`
///
/// see: https://github.com/jimmycuadra/retry/blob/v0.4.0/src/lib.rs#L142-L143
///
/// You can estimate to caluculate concrete values like:
///
/// * retry_counts: 10, e ^ (10 + 10)/1000.0/60.0/60.0 = 0.908060381242253, about 0.9 hour
///
/// * retry_counts: 11, e ^ (5 + 11)/1000.0/60.0/60.0 = 2.4683640334744092, about 2.5 hours
///
/// * retry_counts: 12, e ^ (5 + 12)/1000.0/60.0/60.0 = 6.709709098215361, about 6.7 hours
///
/// where multiplier = 5,
/// e is [exponential function](https://doc.rust-lang.org/std/primitive.f64.html#method.exp).
///
/// ## Default values
///
/// * multiplier: 5_f64
/// * max: 10
#[derive(Debug, Clone, PartialEq)]
pub struct RetryConf {
    max: u64,
    multiplier: f64,
}

impl Default for RetryConf {
    fn default() -> RetryConf {
        RetryConf {
            max: 10,
            multiplier: 5_f64,
        }
    }
}

impl RetryConf {
    pub fn new() -> RetryConf {
        Default::default()
    }

    pub fn max(mut self, max: u64) -> RetryConf {
        self.max = max;
        self
    }

    pub fn multiplier(mut self, multiplier: f64) -> RetryConf {
        self.multiplier = multiplier;
        self
    }

    pub fn build(self) -> (u64, f64) {
        (self.max, self.multiplier)
    }
}
<|endoftext|>


<commit_before>use ppu::{Color, SCREEN_BUFFER_SIZE, SCREEN_HEIGHT, SCREEN_WIDTH};
use screen::Screen;
use sdl2::{Sdl, VideoSubsystem};
use sdl2::render::{Renderer, Texture};
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;

#[allow(dead_code)]
pub struct SDLScreen<'a> {
    video: VideoSubsystem,
    renderer: Renderer<'a>,
    texture: Texture,
}

const SCALE: usize = 3;

impl<'a> SDLScreen<'a> {
    pub fn new(sdl_context: &Sdl) -> SDLScreen<'a> {
        let video_subsystem = sdl_context.video().unwrap();

        let window = video_subsystem.window("Corrosion",
                                            (SCREEN_WIDTH * SCALE) as u32,
                                            (SCREEN_HEIGHT * SCALE) as u32)
                                    .position_centered()
                                    .opengl()
                                    .build()
                                    .unwrap();

        let mut renderer = window.renderer().present_vsync().build().unwrap();
        renderer.set_logical_size(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32).unwrap();

        let texture = renderer.create_texture_streaming(PixelFormatEnum::RGB24,
                                                        SCREEN_WIDTH as u32,
                                                        SCREEN_HEIGHT as u32)
                              .unwrap();
        SDLScreen {
            video: video_subsystem,
            renderer: renderer,
            texture: texture,
        }
    }
}

// Using a hard-coded palette for now. Will add .pal file support later,
// maybe proper NTSC video decoding eventually.
#[cfg_attr(rustfmt, rustfmt_skip)]
static PALETTE: [u8; 192] = [
    84, 84, 84,       0, 30, 116,       8, 16, 144,       48, 0, 136,       68, 0, 100,       92, 0, 48,        84, 4, 0,         60, 24, 0,        32, 42, 0,        8, 58, 0,         0, 64, 0,         0, 60, 0,         0, 50, 60,        0, 0, 0,          0, 0, 0,    0, 0, 0,
    152, 150, 152,    8, 76, 196,       48, 50, 236,      92, 30, 228,      136, 20, 176,     160, 20, 100,     152, 34, 32,      120, 60, 0,       84, 90, 0,        40, 114, 0,       8, 124, 0,        0, 118, 40,       0, 102, 120,      0, 0, 0,          0, 0, 0,    0, 0, 0,
    236, 238, 236,    76, 154, 236,     120, 124, 236,    176, 98, 236,     228, 84, 236,     236, 88, 180,     236, 106, 100,    212, 136, 32,     160, 170, 0,      116, 196, 0,      76, 208, 32,      56, 204, 108,     56, 180, 204,     60, 60, 60,       0, 0, 0,    0, 0, 0,
    236, 238, 236,    168, 204, 236,    188, 188, 236,    212, 178, 236,    236, 174, 236,    236, 174, 212,    236, 180, 176,    228, 196, 144,    204, 210, 120,    180, 222, 120,    168, 226, 144,    152, 226, 180,    160, 214, 228,    160, 162, 160,    0, 0, 0,    0, 0, 0,
];

impl<'a> Screen for SDLScreen<'a> {
    fn draw(&mut self, buf: &[Color; SCREEN_BUFFER_SIZE]) {
        self.texture
            .with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..SCREEN_HEIGHT {
                    for x in 0..SCREEN_HEIGHT {
                        let nes_idx = y * SCREEN_WIDTH + x;
                        let color = buf[nes_idx];
                        let pal_idx = color.bits() as usize * 3;
                        let offset = y * pitch + x * 3;
                        buffer[offset + 0] = PALETTE[pal_idx + 0];
                        buffer[offset + 1] = PALETTE[pal_idx + 1];
                        buffer[offset + 2] = PALETTE[pal_idx + 2];
                    }
                }
            })
            .unwrap();

        self.renderer.copy(&self.texture,
                           None,
                           Some(Rect::new(0, 0, SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)));
        self.renderer.present();
    }
}
<commit_msg>Extracted the copy-to-texture code to a function.<commit_after>use ppu::{Color, SCREEN_BUFFER_SIZE, SCREEN_HEIGHT, SCREEN_WIDTH};
use screen::Screen;
use sdl2::{Sdl, VideoSubsystem};
use sdl2::render::{Renderer, Texture};
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;

#[allow(dead_code)]
pub struct SDLScreen<'a> {
    video: VideoSubsystem,
    renderer: Renderer<'a>,
    texture: Texture,
}

const SCALE: usize = 3;

impl<'a> SDLScreen<'a> {
    pub fn new(sdl_context: &Sdl) -> SDLScreen<'a> {
        let video_subsystem = sdl_context.video().unwrap();

        let window = video_subsystem.window("Corrosion",
                                            (SCREEN_WIDTH * SCALE) as u32,
                                            (SCREEN_HEIGHT * SCALE) as u32)
                                    .position_centered()
                                    .opengl()
                                    .build()
                                    .unwrap();

        let mut renderer = window.renderer().present_vsync().build().unwrap();
        renderer.set_logical_size(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32).unwrap();

        let texture = renderer.create_texture_streaming(PixelFormatEnum::RGB24,
                                                        SCREEN_WIDTH as u32,
                                                        SCREEN_HEIGHT as u32)
                              .unwrap();
        SDLScreen {
            video: video_subsystem,
            renderer: renderer,
            texture: texture,
        }
    }
}

// Using a hard-coded palette for now. Will add .pal file support later,
// maybe proper NTSC video decoding eventually.
#[cfg_attr(rustfmt, rustfmt_skip)]
static PALETTE: [u8; 192] = [
    84, 84, 84,       0, 30, 116,       8, 16, 144,       48, 0, 136,       68, 0, 100,       92, 0, 48,        84, 4, 0,         60, 24, 0,        32, 42, 0,        8, 58, 0,         0, 64, 0,         0, 60, 0,         0, 50, 60,        0, 0, 0,          0, 0, 0,    0, 0, 0,
    152, 150, 152,    8, 76, 196,       48, 50, 236,      92, 30, 228,      136, 20, 176,     160, 20, 100,     152, 34, 32,      120, 60, 0,       84, 90, 0,        40, 114, 0,       8, 124, 0,        0, 118, 40,       0, 102, 120,      0, 0, 0,          0, 0, 0,    0, 0, 0,
    236, 238, 236,    76, 154, 236,     120, 124, 236,    176, 98, 236,     228, 84, 236,     236, 88, 180,     236, 106, 100,    212, 136, 32,     160, 170, 0,      116, 196, 0,      76, 208, 32,      56, 204, 108,     56, 180, 204,     60, 60, 60,       0, 0, 0,    0, 0, 0,
    236, 238, 236,    168, 204, 236,    188, 188, 236,    212, 178, 236,    236, 174, 236,    236, 174, 212,    236, 180, 176,    228, 196, 144,    204, 210, 120,    180, 222, 120,    168, 226, 144,    152, 226, 180,    160, 214, 228,    160, 162, 160,    0, 0, 0,    0, 0, 0,
];

fn copy_to_texture(buf: &[Color; SCREEN_BUFFER_SIZE], buffer: &mut [u8], pitch: usize) {
    for y in 0..SCREEN_HEIGHT {
        for x in 0..SCREEN_HEIGHT {
            let nes_idx = y * SCREEN_WIDTH + x;
            let color = buf[nes_idx];
            let pal_idx = color.bits() as usize * 3;
            let offset = y * pitch + x * 3;
            buffer[offset + 0] = PALETTE[pal_idx + 0];
            buffer[offset + 1] = PALETTE[pal_idx + 1];
            buffer[offset + 2] = PALETTE[pal_idx + 2];
        }
    }
}

impl<'a> Screen for SDLScreen<'a> {
    fn draw(&mut self, buf: &[Color; SCREEN_BUFFER_SIZE]) {
        self.texture
            .with_lock(None, |buffer: &mut [u8], pitch: usize| {
                copy_to_texture(buf, buffer, pitch);
            })
            .unwrap();

        self.renderer.copy(&self.texture,
                           None,
                           Some(Rect::new(0, 0, SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)));
        self.renderer.present();
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature.
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.

extern crate buf_redux;
extern crate httparse;
extern crate safemem;
extern crate twoway;

use std::borrow::Borrow;
use std::io::prelude::*;
use std::path::Path;
use std::io;

use tempdir::TempDir;

use self::boundary::BoundaryReader;

use self::field::PrivReadEntry;

pub use self::field::{MultipartField, MultipartFile, MultipartData, ReadEntry, ReadEntryResult};

use self::save::SaveBuilder;

pub use self::save::{Entries, SaveResult, SavedFile};

use self::save::EntriesSaveResult;

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    );
    ($expr:expr, $before_ret:expr) => (
        match $expr {
            Some(val) => val,
            None => {
                $before_ret;
                return None;
            }
        }
    )
);

macro_rules! try_read_entry {
    ($self_:expr; $try:expr) => (
        match $try {
            Ok(res) => res,
            Err(err) => return ::server::ReadEntryResult::Error($self_, err),
        }
    )
}

mod boundary;
mod field;

#[cfg(feature = "hyper")]
pub mod hyper;

#[cfg(feature = "iron")]
pub mod iron;

#[cfg(feature = "nickel")]
pub mod nickel;

#[cfg(feature = "tiny_http")]
pub mod tiny_http;

pub mod save;

/// The server-side implementation of `multipart/form-data` requests.
///
/// Implements `Borrow<R>` to allow access to the request body, if desired.
pub struct Multipart<R> {
    reader: BoundaryReader<R>,
}

impl Multipart<()> {
    /// If the given `HttpRequest` is a multipart/form-data POST request,
    /// return the request body wrapped in the multipart reader. Otherwise,
    /// returns the original request.
    pub fn from_request<R: HttpRequest>(req: R) -> Result<Multipart<R::Body>, R> {
        //FIXME: move `map` expr to `Some` arm when nonlexical borrow scopes land.
        let boundary = match req.multipart_boundary().map(String::from) {
            Some(boundary) => boundary,
            None => return Err(req),
        };

        Ok(Multipart::with_body(req.body(), boundary))
    }
}

impl<R: Read> Multipart<R> {
    /// Construct a new `Multipart` with the given body reader and boundary.
    pub fn with_body<Bnd: Into<String>>(body: R, boundary: Bnd) -> Self {
        Multipart {
            reader: BoundaryReader::from_reader(body, boundary.into()),
        }
    }

    /// Read the next entry from this multipart request, returning a struct with the field's name and
    /// data. See `MultipartField` for more info.
    ///
    /// ##Warning: Risk of Data Loss
    /// If the previously returned entry had contents of type `MultipartField::File`,
    /// calling this again will discard any unread contents of that entry.
    pub fn read_entry(&mut self) -> io::Result<Option<MultipartField<&mut Self>>> {
        self.read_entry_mut().into_result()
    }

    /// Read the next entry from this multipart request, returning a struct with the field's name and
    /// data. See `MultipartField` for more info.
    pub fn into_entry(self) -> ReadEntryResult<Self> {
        self.read_entry()
    }

    /// Call `f` for each entry in the multipart request.
    ///
    /// This is a substitute for Rust not supporting streaming iterators (where the return value
    /// from `next()` borrows the iterator for a bound lifetime).
    ///
    /// Returns `Ok(())` when all fields have been read, or the first error.
    pub fn foreach_entry<F>(&mut self, mut foreach: F) -> io::Result<()> where F: FnMut(MultipartField<&mut Self>) {
        loop {
            match self.read_entry() {
                Ok(Some(field)) => foreach(field),
                Ok(None) => return Ok(()),
                Err(err) => return Err(err),
            }
        }
    }

    /// Get a builder type for saving the files in this request to the filesystem.
    ///
    /// See [`SaveBuilder`](save/struct.SaveBuilder.html) for more information.
    pub fn save(&mut self) -> SaveBuilder<&mut Self> {
        SaveBuilder::new(self)
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under the OS temporary directory.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().temp()` instead")]
    pub fn save_all(&mut self) -> EntriesSaveResult<&mut Self> {
        self.save().temp()
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under `dir`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().with_temp_dir()` instead")]
    pub fn save_all_under<P: AsRef<Path>>(&mut self, dir: P) -> EntriesSaveResult<&mut Self> {
        match TempDir::new_in(dir, "multipart") {
            Ok(temp_dir) => self.save().with_temp_dir(temp_dir),
            Err(err) => return SaveResult::Error(err),
        }
    }

    /// Read the request fully, parsing all fields and saving all fields in a new temporary
    /// directory under the OS temporary directory.
    ///
    /// Files larger than `limit` will be truncated to `limit`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().size_limit(limit)` instead")]
    pub fn save_all_limited(&mut self, limit: u64) -> EntriesSaveResult<&mut Self> {
        self.save().size_limit(limit).temp()
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under `dir`.
    ///
    /// Files larger than `limit` will be truncated to `limit`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().size_limit(limit).with_temp_dir()` instead")]
    pub fn save_all_under_limited<P: AsRef<Path>>(&mut self, dir: P, limit: u64) -> EntriesSaveResult<&mut Self> {
        match TempDir::new_in(dir, "multipart") {
            Ok(temp_dir) => self.save().size_limit(limit).with_temp_dir(temp_dir),
            Err(err) => return SaveResult::Error(err),
        }
    }
}

impl<R> Borrow<R> for Multipart<R> {
    fn borrow(&self) -> &R {
        self.reader.borrow()
    }
}

impl<R: Read> PrivReadEntry for Multipart<R> {
    type Source = BoundaryReader<R>;

    fn source(&mut self) -> &mut BoundaryReader<R> {
        &mut self.reader
    }

    /// Consume the next boundary.
    /// Returns `true` if the last boundary was read, `false` otherwise.
    fn consume_boundary(&mut self) -> io::Result<bool> {
        debug!("Consume boundary!");
        self.reader.consume_boundary()
    }
}

/// A server-side HTTP request that may or may not be multipart.
///
/// May be implemented by mutable references if providing the request or body by-value is
/// undesirable.
pub trait HttpRequest {
    /// The body of this request.
    type Body: Read;
    /// Get the boundary string of this request if it is a POST request
    /// with the `Content-Type` header set to `multipart/form-data`.
    ///
    /// The boundary string should be supplied as an extra value of the `Content-Type` header, e.g.
    /// `Content-Type: multipart/form-data; boundary={boundary}`.
    fn multipart_boundary(&self) -> Option<&str>;

    /// Return the request body for reading.
    fn body(self) -> Self::Body;
}
<commit_msg>Log the boundary in server<commit_after>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature.
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.

extern crate buf_redux;
extern crate httparse;
extern crate safemem;
extern crate twoway;

use std::borrow::Borrow;
use std::io::prelude::*;
use std::path::Path;
use std::io;

use tempdir::TempDir;

use self::boundary::BoundaryReader;

use self::field::PrivReadEntry;

pub use self::field::{MultipartField, MultipartFile, MultipartData, ReadEntry, ReadEntryResult};

use self::save::SaveBuilder;

pub use self::save::{Entries, SaveResult, SavedFile};

use self::save::EntriesSaveResult;

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    );
    ($expr:expr, $before_ret:expr) => (
        match $expr {
            Some(val) => val,
            None => {
                $before_ret;
                return None;
            }
        }
    )
);

macro_rules! try_read_entry {
    ($self_:expr; $try:expr) => (
        match $try {
            Ok(res) => res,
            Err(err) => return ::server::ReadEntryResult::Error($self_, err),
        }
    )
}

mod boundary;
mod field;

#[cfg(feature = "hyper")]
pub mod hyper;

#[cfg(feature = "iron")]
pub mod iron;

#[cfg(feature = "nickel")]
pub mod nickel;

#[cfg(feature = "tiny_http")]
pub mod tiny_http;

pub mod save;

/// The server-side implementation of `multipart/form-data` requests.
///
/// Implements `Borrow<R>` to allow access to the request body, if desired.
pub struct Multipart<R> {
    reader: BoundaryReader<R>,
}

impl Multipart<()> {
    /// If the given `HttpRequest` is a multipart/form-data POST request,
    /// return the request body wrapped in the multipart reader. Otherwise,
    /// returns the original request.
    pub fn from_request<R: HttpRequest>(req: R) -> Result<Multipart<R::Body>, R> {
        //FIXME: move `map` expr to `Some` arm when nonlexical borrow scopes land.
        let boundary = match req.multipart_boundary().map(String::from) {
            Some(boundary) => boundary,
            None => return Err(req),
        };

        Ok(Multipart::with_body(req.body(), boundary))
    }
}

impl<R: Read> Multipart<R> {
    /// Construct a new `Multipart` with the given body reader and boundary.
    pub fn with_body<Bnd: Into<String>>(body: R, boundary: Bnd) -> Self {
        let boundary = boundary.into();

        info!("Multipart::with_boundary(_, {:?}", boundary);

        Multipart {
            reader: BoundaryReader::from_reader(body, boundary),
        }
    }

    /// Read the next entry from this multipart request, returning a struct with the field's name and
    /// data. See `MultipartField` for more info.
    ///
    /// ##Warning: Risk of Data Loss
    /// If the previously returned entry had contents of type `MultipartField::File`,
    /// calling this again will discard any unread contents of that entry.
    pub fn read_entry(&mut self) -> io::Result<Option<MultipartField<&mut Self>>> {
        self.read_entry_mut().into_result()
    }

    /// Read the next entry from this multipart request, returning a struct with the field's name and
    /// data. See `MultipartField` for more info.
    pub fn into_entry(self) -> ReadEntryResult<Self> {
        self.read_entry()
    }

    /// Call `f` for each entry in the multipart request.
    ///
    /// This is a substitute for Rust not supporting streaming iterators (where the return value
    /// from `next()` borrows the iterator for a bound lifetime).
    ///
    /// Returns `Ok(())` when all fields have been read, or the first error.
    pub fn foreach_entry<F>(&mut self, mut foreach: F) -> io::Result<()> where F: FnMut(MultipartField<&mut Self>) {
        loop {
            match self.read_entry() {
                Ok(Some(field)) => foreach(field),
                Ok(None) => return Ok(()),
                Err(err) => return Err(err),
            }
        }
    }

    /// Get a builder type for saving the files in this request to the filesystem.
    ///
    /// See [`SaveBuilder`](save/struct.SaveBuilder.html) for more information.
    pub fn save(&mut self) -> SaveBuilder<&mut Self> {
        SaveBuilder::new(self)
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under the OS temporary directory.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().temp()` instead")]
    pub fn save_all(&mut self) -> EntriesSaveResult<&mut Self> {
        self.save().temp()
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under `dir`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().with_temp_dir()` instead")]
    pub fn save_all_under<P: AsRef<Path>>(&mut self, dir: P) -> EntriesSaveResult<&mut Self> {
        match TempDir::new_in(dir, "multipart") {
            Ok(temp_dir) => self.save().with_temp_dir(temp_dir),
            Err(err) => return SaveResult::Error(err),
        }
    }

    /// Read the request fully, parsing all fields and saving all fields in a new temporary
    /// directory under the OS temporary directory.
    ///
    /// Files larger than `limit` will be truncated to `limit`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().size_limit(limit)` instead")]
    pub fn save_all_limited(&mut self, limit: u64) -> EntriesSaveResult<&mut Self> {
        self.save().size_limit(limit).temp()
    }

    /// Read the request fully, parsing all fields and saving all files in a new temporary
    /// directory under `dir`.
    ///
    /// Files larger than `limit` will be truncated to `limit`.
    ///
    /// If there is an error in reading the request, returns the partial result along with the
    /// error. See [`SaveResult`](save/enum.SaveResult.html) for more information.
    #[deprecated(since = "0.10.0", note = "use `.save().size_limit(limit).with_temp_dir()` instead")]
    pub fn save_all_under_limited<P: AsRef<Path>>(&mut self, dir: P, limit: u64) -> EntriesSaveResult<&mut Self> {
        match TempDir::new_in(dir, "multipart") {
            Ok(temp_dir) => self.save().size_limit(limit).with_temp_dir(temp_dir),
            Err(err) => return SaveResult::Error(err),
        }
    }
}

impl<R> Borrow<R> for Multipart<R> {
    fn borrow(&self) -> &R {
        self.reader.borrow()
    }
}

impl<R: Read> PrivReadEntry for Multipart<R> {
    type Source = BoundaryReader<R>;

    fn source(&mut self) -> &mut BoundaryReader<R> {
        &mut self.reader
    }

    /// Consume the next boundary.
    /// Returns `true` if the last boundary was read, `false` otherwise.
    fn consume_boundary(&mut self) -> io::Result<bool> {
        debug!("Consume boundary!");
        self.reader.consume_boundary()
    }
}

/// A server-side HTTP request that may or may not be multipart.
///
/// May be implemented by mutable references if providing the request or body by-value is
/// undesirable.
pub trait HttpRequest {
    /// The body of this request.
    type Body: Read;
    /// Get the boundary string of this request if it is a POST request
    /// with the `Content-Type` header set to `multipart/form-data`.
    ///
    /// The boundary string should be supplied as an extra value of the `Content-Type` header, e.g.
    /// `Content-Type: multipart/form-data; boundary={boundary}`.
    fn multipart_boundary(&self) -> Option<&str>;

    /// Return the request body for reading.
    fn body(self) -> Self::Body;
}
<|endoftext|>


<commit_before>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is a form of gradient noise, similar to Perlin or simplex noise,
//! but using a simplectic honeycomb. The 2D case is functionally identical
//! to simplex noise. The 3D case is a tetrahedral-octohedral honeycomb and
//! the 4D case is a 5-cell honeycomb. See the Wikipedia article on
//! simplectic honeycombs for more info:
//! http://en.wikipedia.org/wiki/Simplectic_honeycomb
//!
//! The virtue of this noise, over the alternatives, is it's algorithmic
//! cleanliness. In any dimension, it can be seen as a series of layers of
//! the noise function from the lower dimension. So for any given point,
//! one can calculate the lower dimensional noise twice, one for the layer
//! below and one for the layer above, to get the relevant set of gradient
//! points. Thus, 3D noise can be composed out of two iterations of 2D
//! noise, and 4D noise can be composed out of two iterations of 3D noise,
//! or four iterations of 2D noise.

use std::num::{cast, Float};

use {gradient, math, Seed};

struct SimplecticPoint2<T: Float> {
    x_cell: i64,
    y_cell: i64,
    x_offset: T,
    y_offset: T,
}

impl<T: Float> SimplecticPoint2<T> {
    fn to_simplectic_point3(&self, z_cell: i64, z_offset: T) -> SimplecticPoint3<T> {
        SimplecticPoint3 {
            x_cell: self.x_cell,
            y_cell: self.y_cell,
            z_cell: z_cell,
            x_offset: self.x_offset,
            y_offset: self.y_offset,
            z_offset: z_offset,
        }
    }
}

struct SimplecticPoint3<T: Float> {
    x_cell: i64,
    y_cell: i64,
    z_cell: i64,
    x_offset: T,
    y_offset: T,
    z_offset: T,
}

impl<T: Float> SimplecticPoint3<T> {
    fn to_simplectic_point4(&self, w_cell: i64, w_offset: T) -> SimplecticPoint4<T> {
        SimplecticPoint4 {
            x_cell: self.x_cell,
            y_cell: self.y_cell,
            z_cell: self.z_cell,
            w_cell: w_cell,
            x_offset: self.x_offset,
            y_offset: self.y_offset,
            z_offset: self.z_offset,
            w_offset: w_offset,
        }
    }
}

struct SimplecticPoint4<T: Float> {
    x_cell: i64,
    y_cell: i64,
    z_cell: i64,
    w_cell: i64,
    x_offset: T,
    y_offset: T,
    z_offset: T,
    w_offset: T,
}

const SKEW_CONSTANT: f64 = 0.36602540378; // 0.5*(sqrt(3.0)-1.0)
const UNSKEW_CONSTANT: f64 = 0.2113248654; // (3.0-sqrt(3.0))/6.0

const SIMPLEX_SIZE: f64 = 0.70710678119;
const INV_SIMPLEX_SIZE: f64 = 1.41421356235; // 1 / SIMPLEX_SIZE
const LAYER_OFFSET_X: f64 = 0.45534180126; // (2.0-3.0*UNSKEW_CONSTANT)/3.0
const LAYER_OFFSET_Y: f64 = 0.12200846793; // (1.0-3.0*UNSKEW_CONSTANT)/3.0
const LAYER_OFFSET_Z: f64 = 0.35355339059; // (1.0-3.0*UNSKEW_CONSTANT)/3.0

const NORM_CONSTANT_2D: f64 = 8.0;
const NORM_CONSTANT_3D: f64 = 9.0;
const NORM_CONSTANT_4D: f64 = 10.0;

#[inline(always)]
fn simplectic2_points<T: Float>(point: &::Point2<T>) -> [SimplecticPoint2<T>, ..3] {
    let zero: T = math::cast(0u);
    let one: T = math::cast(1u);
    let two: T = math::cast(2u);
    let skew_constant  = math::cast(SKEW_CONSTANT);
    let unskew_constant  = math::cast(UNSKEW_CONSTANT);

    // Skew the input coordinates into the grid to figure out which grid cell we're in
    let skew_offset = (point[0] + point[1]) * skew_constant;
    let x_cell = (point[0] + skew_offset).floor();
    let y_cell = (point[1] + skew_offset).floor();

    // Unskew the floored coordinates to find the real coordinates of the cell's origin
    let unskew_offset = (x_cell + y_cell) * unskew_constant;
    let x_origin = x_cell - unskew_offset;
    let y_origin = y_cell - unskew_offset;

    // Compute the delta from the first point, which is the cell origin
    let dx0 = point[0] - x_origin;
    let dy0 = point[1] - y_origin;

    // Compute the delta from the second point, which depends on which simplex we're in
    let (x1_offset, y1_offset) = if dx0 > dy0 { (one, zero) } else { (zero, one) };
    let dx1 = dx0 - x1_offset + unskew_constant;
    let dy1 = dy0 - y1_offset + unskew_constant;

    // Compute the delta from the third point
    let dx2 = dx0 - one + two * unskew_constant;
    let dy2 = dy0 - one + two * unskew_constant;

    [
        SimplecticPoint2 {
            x_cell: math::cast(x_cell),
            y_cell: math::cast(y_cell),
            x_offset: dx0,
            y_offset: dy0,
        },
        SimplecticPoint2 {
            x_cell: math::cast(x_cell + x1_offset),
            y_cell: math::cast(y_cell + y1_offset),
            x_offset: dx1,
            y_offset: dy1,
        },
        SimplecticPoint2 {
            x_cell: 1i64 + math::cast(x_cell),
            y_cell: 1i64 + math::cast(y_cell),
            x_offset: dx2,
            y_offset: dy2,
        },
    ]
}

#[inline(always)]
fn simplectic3_points<T: Float>(point: &::Point3<T>) -> [SimplecticPoint3<T>, ..6] {
    let layer_offset_x = math::cast(LAYER_OFFSET_X);
    let layer_offset_y = math::cast(LAYER_OFFSET_Y);
    let layer_scale = math::cast(SIMPLEX_SIZE);
    let inv_layer_scale = math::cast(INV_SIMPLEX_SIZE);

    let layer = (point[2] * inv_layer_scale).floor();
    let layer_int: i64 = math::cast(layer);

    let (layer1_point, layer2_point) = if layer_int % 2 == 0 {
        ([point[0], point[1]], [point[0] + layer_offset_x, point[1] + layer_offset_y])
    } else {
        ([point[0] + layer_offset_x, point[1] + layer_offset_y], [point[0], point[1]])
    };

    let [p1, p2, p3] = simplectic2_points(&layer1_point);
    let [p4, p5, p6] = simplectic2_points(&layer2_point);

    let z_offset = point[2] - layer * layer_scale;
    [
        p1.to_simplectic_point3(layer_int, z_offset),
        p2.to_simplectic_point3(layer_int, z_offset),
        p3.to_simplectic_point3(layer_int, z_offset),
        p4.to_simplectic_point3(layer_int + 1, z_offset - layer_scale),
        p5.to_simplectic_point3(layer_int + 1, z_offset - layer_scale),
        p6.to_simplectic_point3(layer_int + 1, z_offset - layer_scale),
    ]
}

#[inline(always)]
fn simplectic4_points<T: Float>(point: &::Point4<T>) -> [SimplecticPoint4<T>, ..12] {
    let layer_offset_x = math::cast(LAYER_OFFSET_X);
    let layer_offset_y = math::cast(LAYER_OFFSET_Y);
    let layer_offset_z = math::cast(LAYER_OFFSET_Z);
    let layer_scale = math::cast(SIMPLEX_SIZE);
    let inv_layer_scale = math::cast(INV_SIMPLEX_SIZE);

    let layer = (point[3] * inv_layer_scale).floor();
    let layer_int: i64 = math::cast(layer);

    let (layer1_point, layer2_point) = if layer_int % 2 == 0 {
        ([point[0], point[1], point[2]], [point[0] + layer_offset_x, point[1] + layer_offset_y, point[2] + layer_offset_z])
    } else {
        ([point[0] + layer_offset_x, point[1] + layer_offset_y, point[2] + layer_offset_z], [point[0], point[1], point[2]])
    };

    let [p1, p2, p3, p4, p5, p6] = simplectic3_points(&layer1_point);
    let [p7, p8, p9, p10, p11, p12] = simplectic3_points(&layer2_point);

    let w_offset = point[3] - layer * layer_scale;
    [
        p1.to_simplectic_point4(layer_int, w_offset),
        p2.to_simplectic_point4(layer_int, w_offset),
        p3.to_simplectic_point4(layer_int, w_offset),
        p4.to_simplectic_point4(layer_int, w_offset),
        p5.to_simplectic_point4(layer_int, w_offset),
        p6.to_simplectic_point4(layer_int, w_offset),
        p7.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
        p8.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
        p9.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
        p10.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
        p11.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
        p12.to_simplectic_point4(layer_int + 1, w_offset - layer_scale),
    ]
}

pub fn simplectic2<T: Float>(seed: &Seed, point: &::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint2<T>) -> T {
        let attn = math::cast::<_, T>(SIMPLEX_SIZE) - p.x_offset * p.x_offset
                                                    - p.y_offset * p.y_offset;
        if attn > Float::zero() {
            let [gx, gy] = gradient::get2(seed.get2(p.x_cell, p.y_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3] = simplectic2_points(point);

    (gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3)) * math::cast(NORM_CONSTANT_2D)
}

pub fn simplectic3<T: Float>(seed: &Seed, point: &::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint3<T>) -> T {
        let attn = math::cast::<_, T>(SIMPLEX_SIZE) - p.x_offset * p.x_offset
                                                    - p.y_offset * p.y_offset
                                                    - p.z_offset * p.z_offset;
        if attn > Float::zero() {
            let [gx, gy, gz] = gradient::get3(seed.get3(p.x_cell, p.y_cell, p.z_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy + p.z_offset * gz)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3, p4, p5, p6] = simplectic3_points(point);

    (
        gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3) + gradient(seed, &p4) + gradient(seed, &p5) + gradient(seed, &p6)
    ) * math::cast(NORM_CONSTANT_3D)
}

pub fn simplectic4<T: Float>(seed: &Seed, point: &::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint4<T>) -> T {
        let attn = math::cast::<_, T>(SIMPLEX_SIZE) - p.x_offset * p.x_offset
                                                    - p.y_offset * p.y_offset
                                                    - p.z_offset * p.z_offset
                                                    - p.w_offset * p.w_offset;
        if attn > Float::zero() {
            let [gx, gy, gz, gw] = gradient::get4(seed.get4(p.x_cell, p.y_cell, p.z_cell, p.w_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy + p.z_offset * gz + p.w_offset * gw)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12] = simplectic4_points(point);

    (
        gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3) + gradient(seed, &p4) + gradient(seed, &p5) + gradient(seed, &p6) +
        gradient(seed, &p7) + gradient(seed, &p8) + gradient(seed, &p9) + gradient(seed, &p10) + gradient(seed, &p11) + gradient(seed, &p12)
    ) * math::cast(NORM_CONSTANT_4D)
}
<commit_msg>Use functions instead of constants<commit_after>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is a form of gradient noise, similar to Perlin or simplex noise,
//! but using a simplectic honeycomb. The 2D case is functionally identical
//! to simplex noise. The 3D case is a tetrahedral-octohedral honeycomb and
//! the 4D case is a 5-cell honeycomb. See the Wikipedia article on
//! simplectic honeycombs for more info:
//! http://en.wikipedia.org/wiki/Simplectic_honeycomb
//!
//! The virtue of this noise, over the alternatives, is it's algorithmic
//! cleanliness. In any dimension, it can be seen as a series of layers of
//! the noise function from the lower dimension. So for any given point,
//! one can calculate the lower dimensional noise twice, one for the layer
//! below and one for the layer above, to get the relevant set of gradient
//! points. Thus, 3D noise can be composed out of two iterations of 2D
//! noise, and 4D noise can be composed out of two iterations of 3D noise,
//! or four iterations of 2D noise.

use std::num::{cast, Float};

use {gradient, math, Seed};

struct SimplecticPoint2<T: Float> {
    x_cell: i64,
    y_cell: i64,
    x_offset: T,
    y_offset: T,
}

impl<T: Float> SimplecticPoint2<T> {
    fn to_simplectic_point3(&self, z_cell: i64, z_offset: T) -> SimplecticPoint3<T> {
        SimplecticPoint3 {
            x_cell: self.x_cell,
            y_cell: self.y_cell,
            z_cell: z_cell,
            x_offset: self.x_offset,
            y_offset: self.y_offset,
            z_offset: z_offset,
        }
    }
}

struct SimplecticPoint3<T: Float> {
    x_cell: i64,
    y_cell: i64,
    z_cell: i64,
    x_offset: T,
    y_offset: T,
    z_offset: T,
}

impl<T: Float> SimplecticPoint3<T> {
    fn to_simplectic_point4(&self, w_cell: i64, w_offset: T) -> SimplecticPoint4<T> {
        SimplecticPoint4 {
            x_cell: self.x_cell,
            y_cell: self.y_cell,
            z_cell: self.z_cell,
            w_cell: w_cell,
            x_offset: self.x_offset,
            y_offset: self.y_offset,
            z_offset: self.z_offset,
            w_offset: w_offset,
        }
    }
}

struct SimplecticPoint4<T: Float> {
    x_cell: i64,
    y_cell: i64,
    z_cell: i64,
    w_cell: i64,
    x_offset: T,
    y_offset: T,
    z_offset: T,
    w_offset: T,
}

fn skew_constant<T: Float>() -> T { math::cast(0.36602540378_f64) } // 0.5 * (sqrt(3.0) - 1.0)
fn unskew_constant<T: Float>() -> T { math::cast(0.2113248654_f64) } // (3.0 - sqrt(3.0)) / 6.0

fn simplex_size<T: Float>() -> T { math::cast(0.70710678119_f64) }
fn inv_simplex_size<T: Float>() -> T { math::cast(1.41421356235_f64) } // 1 / simplex_size()
fn layer_offset_x<T: Float>() -> T { math::cast(0.45534180126_f64) } // (2.0 - 3.0 * unskew_constant()) / 3.0
fn layer_offset_y<T: Float>() -> T { math::cast(0.12200846793_f64) } // (1.0 - 3.0 * unskew_constant()) / 3.0
fn layer_offset_z<T: Float>() -> T { math::cast(0.35355339059_f64) } // (1.0 - 3.0 * unskew_constant()) / 3.0

fn norm2_constant<T: Float>() -> T { math::cast(8.0_f64) }
fn norm3_constant<T: Float>() -> T { math::cast(9.0_f64) }
fn norm4_constant<T: Float>() -> T { math::cast(10.0_f64) }

#[inline(always)]
fn simplectic2_points<T: Float>(point: &::Point2<T>) -> [SimplecticPoint2<T>, ..3] {
    let zero: T = math::cast(0u);
    let one: T = math::cast(1u);
    let two: T = math::cast(2u);

    // Skew the input coordinates into the grid to figure out which grid cell we're in
    let skew_offset = (point[0] + point[1]) * skew_constant();
    let x_cell = (point[0] + skew_offset).floor();
    let y_cell = (point[1] + skew_offset).floor();

    // Unskew the floored coordinates to find the real coordinates of the cell's origin
    let unskew_offset = (x_cell + y_cell) * unskew_constant();
    let x_origin = x_cell - unskew_offset;
    let y_origin = y_cell - unskew_offset;

    // Compute the delta from the first point, which is the cell origin
    let dx0 = point[0] - x_origin;
    let dy0 = point[1] - y_origin;

    // Compute the delta from the second point, which depends on which simplex we're in
    let (x1_offset, y1_offset) = if dx0 > dy0 { (one, zero) } else { (zero, one) };
    let dx1 = dx0 - x1_offset + unskew_constant();
    let dy1 = dy0 - y1_offset + unskew_constant();

    // Compute the delta from the third point
    let dx2 = dx0 - one + two * unskew_constant();
    let dy2 = dy0 - one + two * unskew_constant();

    [
        SimplecticPoint2 {
            x_cell: math::cast(x_cell),
            y_cell: math::cast(y_cell),
            x_offset: dx0,
            y_offset: dy0,
        },
        SimplecticPoint2 {
            x_cell: math::cast(x_cell + x1_offset),
            y_cell: math::cast(y_cell + y1_offset),
            x_offset: dx1,
            y_offset: dy1,
        },
        SimplecticPoint2 {
            x_cell: 1i64 + math::cast(x_cell),
            y_cell: 1i64 + math::cast(y_cell),
            x_offset: dx2,
            y_offset: dy2,
        },
    ]
}

#[inline(always)]
fn simplectic3_points<T: Float>(point: &::Point3<T>) -> [SimplecticPoint3<T>, ..6] {
    let layer = (point[2] * inv_simplex_size()).floor();
    let layer_int: i64 = math::cast(layer);

    let (layer1_point, layer2_point) = if layer_int % 2 == 0 {
        ([point[0], point[1]], [point[0] + layer_offset_x(), point[1] + layer_offset_y()])
    } else {
        ([point[0] + layer_offset_x(), point[1] + layer_offset_y()], [point[0], point[1]])
    };

    let [p1, p2, p3] = simplectic2_points(&layer1_point);
    let [p4, p5, p6] = simplectic2_points(&layer2_point);

    let z_offset = point[2] - layer * simplex_size();
    [
        p1.to_simplectic_point3(layer_int, z_offset),
        p2.to_simplectic_point3(layer_int, z_offset),
        p3.to_simplectic_point3(layer_int, z_offset),
        p4.to_simplectic_point3(layer_int + 1, z_offset - simplex_size()),
        p5.to_simplectic_point3(layer_int + 1, z_offset - simplex_size()),
        p6.to_simplectic_point3(layer_int + 1, z_offset - simplex_size()),
    ]
}

#[inline(always)]
fn simplectic4_points<T: Float>(point: &::Point4<T>) -> [SimplecticPoint4<T>, ..12] {
    let layer = (point[3] * inv_simplex_size()).floor();
    let layer_int: i64 = math::cast(layer);

    let (layer1_point, layer2_point) = if layer_int % 2 == 0 {
        ([point[0], point[1], point[2]], [point[0] + layer_offset_x(), point[1] + layer_offset_y(), point[2] + layer_offset_z()])
    } else {
        ([point[0] + layer_offset_x(), point[1] + layer_offset_y(), point[2] + layer_offset_z()], [point[0], point[1], point[2]])
    };

    let [p1, p2, p3, p4, p5, p6] = simplectic3_points(&layer1_point);
    let [p7, p8, p9, p10, p11, p12] = simplectic3_points(&layer2_point);

    let w_offset = point[3] - layer * simplex_size();
    [
        p1.to_simplectic_point4(layer_int, w_offset),
        p2.to_simplectic_point4(layer_int, w_offset),
        p3.to_simplectic_point4(layer_int, w_offset),
        p4.to_simplectic_point4(layer_int, w_offset),
        p5.to_simplectic_point4(layer_int, w_offset),
        p6.to_simplectic_point4(layer_int, w_offset),
        p7.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
        p8.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
        p9.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
        p10.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
        p11.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
        p12.to_simplectic_point4(layer_int + 1, w_offset - simplex_size()),
    ]
}

pub fn simplectic2<T: Float>(seed: &Seed, point: &::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint2<T>) -> T {
        let attn = simplex_size::<T>() - p.x_offset * p.x_offset
                                       - p.y_offset * p.y_offset;
        if attn > Float::zero() {
            let [gx, gy] = gradient::get2(seed.get2(p.x_cell, p.y_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3] = simplectic2_points(point);

    (gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3)) * norm2_constant()
}

pub fn simplectic3<T: Float>(seed: &Seed, point: &::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint3<T>) -> T {
        let attn = simplex_size::<T>() - p.x_offset * p.x_offset
                                       - p.y_offset * p.y_offset
                                       - p.z_offset * p.z_offset;
        if attn > Float::zero() {
            let [gx, gy, gz] = gradient::get3(seed.get3(p.x_cell, p.y_cell, p.z_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy + p.z_offset * gz)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3, p4, p5, p6] = simplectic3_points(point);

    (
        gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3) + gradient(seed, &p4) + gradient(seed, &p5) + gradient(seed, &p6)
    ) * norm3_constant()
}

pub fn simplectic4<T: Float>(seed: &Seed, point: &::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, p: &SimplecticPoint4<T>) -> T {
        let attn = simplex_size::<T>() - p.x_offset * p.x_offset
                                       - p.y_offset * p.y_offset
                                       - p.z_offset * p.z_offset
                                       - p.w_offset * p.w_offset;
        if attn > Float::zero() {
            let [gx, gy, gz, gw] = gradient::get4(seed.get4(p.x_cell, p.y_cell, p.z_cell, p.w_cell));
            let attn2 = attn * attn;
            attn2 * attn2 * (p.x_offset * gx + p.y_offset * gy + p.z_offset * gz + p.w_offset * gw)
        } else {
            Float::zero()
        }
    }

    let [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12] = simplectic4_points(point);

    (
        gradient(seed, &p1) + gradient(seed, &p2) + gradient(seed, &p3) + gradient(seed, &p4) + gradient(seed, &p5) + gradient(seed, &p6) +
        gradient(seed, &p7) + gradient(seed, &p8) + gradient(seed, &p9) + gradient(seed, &p10) + gradient(seed, &p11) + gradient(seed, &p12)
    ) * norm4_constant()
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fs;
use std::io::prelude::*;
use std::path::Path;

#[derive(Clone)]
#[derive(Debug)]
pub enum CellState
{
	Dead,
	Alive
}

pub struct Simulator {
	iteration_num: u32,
	height: usize,
	width: usize,
	output_dir: String,
	starting_states: Vec<Vec<CellState>>,
	current_iteration: u32,
}

impl<'a> Simulator {
	pub fn new(iteration_num: u32, output_dir: String,
		starting_states: Vec<Vec<CellState>>) -> Simulator {
		// Check input data
		if starting_states.len() < 1 {
			panic!("not enough rows");
		}
		let row_length = starting_states[0].len();
		for row in &starting_states {
			if row.len() != row_length {
				panic!("row lengths do not match");
			}
		}
		// Check input directory
		if !fs::metadata(&output_dir).is_ok() {
			match fs::create_dir_all(&output_dir) {
				Ok(_) => {},
				Err(e) => {
					panic!("output directory did not exist and cannot be created: {}",
						e.description());
				}
			}
		}
		// Assign struct
		Simulator {
			iteration_num: iteration_num,
			height: starting_states.len(),
			width: starting_states[0].len(),
			output_dir: output_dir,
			starting_states: starting_states,
			current_iteration: 0,
		}
	}

	pub fn run_simulation(&mut self) {
		// Set up first cells
		let mut current_states = self.create_initial_states();
		loop {
			// Create new states
			let mut new_states = Vec::new();
			for x in 0..self.height {
				let mut new_row = Vec::new();
				for y in 0..self.width {
					let cell = current_states[x][y].clone();
					let new_cell = cell.iterate(&current_states);
					new_row.push(new_cell);
				}
				new_states.push(new_row);
			}
			// Set current states
			current_states = new_states;
			// Output
			{
				let current_states = &current_states;
				self.output(current_states);
			}
			// Increment iteration
			self.current_iteration += 1;
			if self.current_iteration == self.iteration_num {
				break;
			}
		}
	}

	fn create_initial_states(&mut self) -> Vec<Vec<Cell>> {
		let mut states = Vec::new();
		for x in 0..self.starting_states.len() {
			let mut row = Vec::new();
			for y in 0..self.starting_states[x].len() {
				row.push(Cell {
					state: self.starting_states[x][y].clone(),
					row: x,
					col: y,
				});
			}
			states.push(row);
		}
		return states;
	}

	fn output(&mut self, current_states: &Vec<Vec<Cell>>) {
		let path = Path::new(&self.output_dir);
		let path = path.join(format!("{}.csv", self.current_iteration));
		let mut file = match fs::File::create(&path) {
			Err(why) => panic!("couldn't create {}: {}",
								path.display(), why.description()),
			Ok(file) => file,
		};
		for row in current_states {
			let mut row_str: String = row.iter().map(|c| match c.state {
				CellState::Dead => "0",
				CellState::Alive => "1",
			}).collect::<Vec<&str>>().join(",");
			row_str.push('\n');
			match file.write_all(row_str.as_bytes()) {
				Err(why) => {
					panic!("couldn't write to {}: {}", path.display(),
						   why.description())
				},
				Ok(_) => {},
			}
		}
	}
}

#[derive(Clone)]
struct Cell {
	state: CellState,
	row: usize,
	col: usize,
}

impl Cell {
	fn iterate(self, prev_state: &Vec<Vec<Cell>>) -> Cell {
		let alive_neighbours = self.count_alive_neighbours(prev_state);
		return Cell {
			state: self.conways_rules(alive_neighbours),
			row: self.row,
			col: self.col,
		};
	}

	fn count_alive_neighbours(&self, prev_state: &Vec<Vec<Cell>>) -> usize {
		let mut alive_neighbours: usize = 0;
		for x in 0..3 {
			for y in 0..3 {
				if (self.row > 0) &&  (self.row + x < prev_state.len()) &&
					(self.col > 0) && (self.col + y < prev_state[0].len()) {
					let n_x: usize = self.row + x - 1;
					let n_y: usize = self.col + y - 1;
					alive_neighbours = match prev_state[n_x][n_y].state {
						CellState::Alive => alive_neighbours + 1,
						CellState::Dead => alive_neighbours
					}
				}
			}
		}
		return alive_neighbours;
	}

	fn conways_rules(&self, alive_neighbours: usize) -> CellState {
		match self.state {
			CellState::Alive => {
				if alive_neighbours < 2 || alive_neighbours > 3 {
					CellState::Dead
				} else {
				    CellState::Alive
				}
			},
			CellState::Dead => {
				if alive_neighbours == 3 {
					CellState::Alive
				} else {
				    CellState::Dead
				}
			}
		}
	}
}<commit_msg>Fixed Conways Game of Life rules (alive neighbours counting was incorrect)<commit_after>use std::error::Error;
use std::fs;
use std::io::prelude::*;
use std::path::Path;

#[derive(Clone)]
#[derive(Debug)]
pub enum CellState
{
	Dead,
	Alive
}

pub struct Simulator {
	iteration_num: u32,
	height: usize,
	width: usize,
	output_dir: String,
	starting_states: Vec<Vec<CellState>>,
	current_iteration: u32,
}

impl<'a> Simulator {
	pub fn new(iteration_num: u32, output_dir: String,
		starting_states: Vec<Vec<CellState>>) -> Simulator {
		// Check input data
		if starting_states.len() < 1 {
			panic!("not enough rows");
		}
		let row_length = starting_states[0].len();
		for row in &starting_states {
			if row.len() != row_length {
				panic!("row lengths do not match");
			}
		}
		// Check input directory
		if !fs::metadata(&output_dir).is_ok() {
			match fs::create_dir_all(&output_dir) {
				Ok(_) => {},
				Err(e) => {
					panic!("output directory did not exist and cannot be created: {}",
						e.description());
				}
			}
		}
		// Assign struct
		Simulator {
			iteration_num: iteration_num,
			height: starting_states.len(),
			width: starting_states[0].len(),
			output_dir: output_dir,
			starting_states: starting_states,
			current_iteration: 0,
		}
	}

	pub fn run_simulation(&mut self) {
		// Set up first cells
		let mut current_states = self.create_initial_states();
		loop {
			// Create new states
			let mut new_states = Vec::new();
			for x in 0..self.height {
				let mut new_row = Vec::new();
				for y in 0..self.width {
					let cell = current_states[x][y].clone();
					let new_cell = cell.iterate(&current_states);
					new_row.push(new_cell);
				}
				new_states.push(new_row);
			}
			// Set current states
			current_states = new_states;
			// Output
			{
				let current_states = &current_states;
				self.output(current_states);
			}
			// Increment iteration
			self.current_iteration += 1;
			if self.current_iteration == self.iteration_num {
				break;
			}
		}
	}

	fn create_initial_states(&mut self) -> Vec<Vec<Cell>> {
		let mut states = Vec::new();
		for x in 0..self.starting_states.len() {
			let mut row = Vec::new();
			for y in 0..self.starting_states[x].len() {
				row.push(Cell {
					state: self.starting_states[x][y].clone(),
					row: x,
					col: y,
				});
			}
			states.push(row);
		}
		return states;
	}

	fn output(&mut self, current_states: &Vec<Vec<Cell>>) {
		let path = Path::new(&self.output_dir);
		let path = path.join(format!("{}.csv", self.current_iteration));
		let mut file = match fs::File::create(&path) {
			Err(why) => panic!("couldn't create {}: {}",
								path.display(), why.description()),
			Ok(file) => file,
		};
		for row in current_states {
			let mut row_str: String = row.iter().map(|c| match c.state {
				CellState::Dead => "0",
				CellState::Alive => "1",
			}).collect::<Vec<&str>>().join(",");
			row_str.push('\n');
			match file.write_all(row_str.as_bytes()) {
				Err(why) => {
					panic!("couldn't write to {}: {}", path.display(),
						   why.description())
				},
				Ok(_) => {},
			}
		}
	}
}

#[derive(Clone)]
struct Cell {
	state: CellState,
	row: usize,
	col: usize,
}

impl Cell {
	fn iterate(self, prev_state: &Vec<Vec<Cell>>) -> Cell {
		let alive_neighbours = self.count_alive_neighbours(prev_state);
		return Cell {
			state: self.conways_rules(alive_neighbours),
			row: self.row,
			col: self.col,
		};
	}

	fn count_alive_neighbours(&self, prev_state: &Vec<Vec<Cell>>) -> usize {
		let mut alive_neighbours: usize = 0;
		for x in 0..3 {
			for y in 0..3 {
				if (x != 1 || y != 1) &&
					((((self.row > 0) && ((self.row + 1) < prev_state.len())) ||
					(((self.row == 0) && (x > 0)) || ((self.row + 1) == prev_state.len() && (x < 2)))) &&
					(((self.col > 0) && (self.col + 1 < prev_state[0].len())) ||
					(((self.col == 0) && (y > 0)) || (((self.col + 1) == prev_state[0].len()) && (y < 2))))) {
					let n_x: usize = self.row + x - 1;
					let n_y: usize = self.col + y - 1;
					alive_neighbours = match prev_state[n_x][n_y].state {
						CellState::Alive => alive_neighbours + 1,
						CellState::Dead => alive_neighbours
					}
				}
			}
		}
		return alive_neighbours;
	}

	fn conways_rules(&self, alive_neighbours: usize) -> CellState {
		match self.state {
			CellState::Alive => {
				if alive_neighbours < 2 || alive_neighbours > 3 {
					CellState::Dead
				} else {
				    CellState::Alive
				}
			},
			CellState::Dead => {
				if alive_neighbours == 3 {
					CellState::Alive
				} else {
				    CellState::Dead
				}
			}
		}
	}
}<|endoftext|>


<commit_before>/// Internal event used to stop the `Simulation`. The `halt` event queue will always be created.
pub struct Halt;

/// The core wiring for entity component systems built on `trex`. This macro takes a set of
/// `Component`s, events, and `System`s, and creates a `Simulation` type that manages them.
/// See the library documentation for an example of how this macro is used.
#[macro_export]
macro_rules! simulation {
    {
        components: {
            $( $C:ident : $F:ident ),*
        },

        events: {
            $( $queue:ident : $E:ident ),*
        },

        systems: {
            $( $system:ident : $S:ident ),*
        }
    } => {
        $(
            component! {
                $C : $F
            }
        )*

        pub struct Events {
            pub halt: $crate::EventQueue<$crate::Halt>,

            $(
                pub $queue: $crate::EventQueue<$E>,
            )*
        }

        impl Events {
            fn new() -> Events {
                Events {
                    halt: $crate::EventQueue::new(),

                    $(
                        $queue: $crate::EventQueue::new(),
                    )*
                }
            }
        }

        pub struct Simulation {
            pub world: World,
            pub events: Events,
            received_halt: bool,

            $(
                pub $system : $S
            ),*
        }

        impl Simulation {
            pub fn new() -> Simulation {
                Simulation {
                    world: {
                        let mut world = World::new();
                        $(
                            world.register_component::<$C>();
                        )+
                        world
                    },
                    events: Events::new(),
                    received_halt: false,
                    $(
                        $system: $S::new()
                    ),*
                }
            }

            pub fn setup<F>(&mut self, setup_fn: F) where F: FnOnce(&mut World, &mut Events) {
                setup_fn(&mut self.world, &mut self.events);
            }

            pub fn update(&mut self, dt: f32) {
                $(
                    self.$system.update(&mut self.world, &mut self.events, dt);
                )*

                $(
                    self.events.$queue.flush();
                )*

                if let Some(_) = self.events.halt.receive().next() {
                    self.received_halt = true;
                }
                self.events.halt.flush();
            }

            pub fn received_halt(&self) -> bool {
                self.received_halt
            }
        }
    }
}
<commit_msg>Add :: namespace to World in simulation macro<commit_after>/// Internal event used to stop the `Simulation`. The `halt` event queue will always be created.
pub struct Halt;

/// The core wiring for entity component systems built on `trex`. This macro takes a set of
/// `Component`s, events, and `System`s, and creates a `Simulation` type that manages them.
/// See the library documentation for an example of how this macro is used.
#[macro_export]
macro_rules! simulation {
    {
        components: {
            $( $C:ident : $F:ident ),*
        },

        events: {
            $( $queue:ident : $E:ident ),*
        },

        systems: {
            $( $system:ident : $S:ident ),*
        }
    } => {
        $(
            component! {
                $C : $F
            }
        )*

        pub struct Events {
            pub halt: $crate::EventQueue<$crate::Halt>,

            $(
                pub $queue: $crate::EventQueue<$E>,
            )*
        }

        impl Events {
            fn new() -> Events {
                Events {
                    halt: $crate::EventQueue::new(),

                    $(
                        $queue: $crate::EventQueue::new(),
                    )*
                }
            }
        }

        pub struct Simulation {
            pub world: $crate::World,
            pub events: Events,
            received_halt: bool,

            $(
                pub $system : $S
            ),*
        }

        impl Simulation {
            pub fn new() -> Simulation {
                Simulation {
                    world: {
                        let mut world = $crate::World::new();
                        $(
                            world.register_component::<$C>();
                        )+
                        world
                    },
                    events: Events::new(),
                    received_halt: false,
                    $(
                        $system: $S::new()
                    ),*
                }
            }

            pub fn setup<F>(&mut self, setup_fn: F) where F: FnOnce(&mut $crate::World, &mut Events) {
                setup_fn(&mut self.world, &mut self.events);
            }

            pub fn update(&mut self, dt: f32) {
                $(
                    self.$system.update(&mut self.world, &mut self.events, dt);
                )*

                $(
                    self.events.$queue.flush();
                )*

                if let Some(_) = self.events.halt.receive().next() {
                    self.received_halt = true;
                }
                self.events.halt.flush();
            }

            pub fn received_halt(&self) -> bool {
                self.received_halt
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

#[macro_use] extern crate diesel;
extern crate dotenv;

pub mod schema;
pub mod models;

use diesel::prelude::*;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;

// extern crate diesel_demo;
//  use self::diesel_demo::*;
use self::models::*;
use self::diesel::prelude::*;

pub fn establish_connection() -> PgConnection {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}

extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;

use rocket_contrib::{Json, Value};

mod hero;
use hero::{Hero};

#[post("/", data="<hero>")]
fn create (hero: Json<Hero>) -> Json<Hero> {
    hero
}

#[get("/")]
fn read() -> Json<Value> {
    Json(json!([
        "hero 1",
        "hero 2"
    ]))
}

#[put("/<id>", data="<hero>")]
fn update (id: i32, hero: Json<Hero>) -> Json<Hero> {
    hero
}

#[delete("/<id>")]
fn delete(id: i32) -> Json<Value>{
    Json(json!({"status": "ok"}))
}

fn main() {
    rocket::ignite().mount("/hero", routes![create, update, delete])
        .mount("/heroes", routes![read]).launch();
    use diesel_demo::schema::posts::dsl::*;
    // let connection = establish_connection();
    // let results = posts.filter(published.eq(true)).limit(5).load::<Post>(&connection).expect("Error loading posts");

    /*
    println!("Displaying {} posts",results.len());
    for post in results {
        println!("{}", post.title);
        println!("---------------\n")
        println!("{}", post.body);
    }
    */
}

<commit_msg>Uncommented code to permit import library<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

#[macro_use] extern crate diesel;
extern crate dotenv;

pub mod schema;
pub mod models;

use diesel::prelude::*;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;

extern crate hello_rocket;
use self::hello_rocket::*;
use self::models::*;
use self::diesel::prelude::*;

pub fn establish_connection() -> PgConnection {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}

extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;

use rocket_contrib::{Json, Value};

mod hero;
use hero::{Hero};

#[post("/", data="<hero>")]
fn create (hero: Json<Hero>) -> Json<Hero> {
    hero
}

#[get("/")]
fn read() -> Json<Value> {
    Json(json!([
        "hero 1",
        "hero 2"
    ]))
}

#[put("/<id>", data="<hero>")]
fn update (id: i32, hero: Json<Hero>) -> Json<Hero> {
    hero
}

#[delete("/<id>")]
fn delete(id: i32) -> Json<Value>{
    Json(json!({"status": "ok"}))
}

fn main() {
    rocket::ignite().mount("/hero", routes![create, update, delete])
        .mount("/heroes", routes![read]).launch();
    use diesel_demo::schema::posts::dsl::*;
    let connection = establish_connection();
    let results = posts.filter(published.eq(true)).limit(5).load::<Post>(&connection).expect("Error loading posts");

    println!("Displaying {} posts",results.len());
    for post in results {
        println!("{}", post.title);
        println!("---------------\n");
        println!("{}", post.body);
    }
}

<|endoftext|>