<commit_before>// ordered container
// Normally, user will only care about the first several options. So we only keep several of them
// in order. Other items are kept unordered and are sorted on demand.

use std::cell::{Ref, RefCell};
use std::cmp::Ordering;

pub type CompareFunction<T> = Box<dyn Fn(&T, &T) -> Ordering + Send + Sync>;

const ORDERED_SIZE: usize = 300;
const MAX_MOVEMENT: usize = 100;

pub struct OrderedVec<T: Send> {
    // sorted vectors for merge, reverse ordered, last one is the smallest one
    sub_vectors: RefCell<Vec<Vec<T>>>,
    // globally sorted items, the first one is the smallest one.
    sorted: RefCell<Vec<T>>,
    compare: CompareFunction<T>,
    tac: bool,
    nosort: bool,
}

impl<T: Send> OrderedVec<T> {
    pub fn new(compare: CompareFunction<T>) -> Self {
        OrderedVec {
            sub_vectors: RefCell::new(Vec::new()),
            sorted: RefCell::new(Vec::with_capacity(ORDERED_SIZE)),
            compare,
            tac: false,
            nosort: false,
        }
    }

    pub fn tac(&mut self, tac: bool) -> &mut Self {
        self.tac = tac;
        self
    }

    pub fn nosort(&mut self, nosort: bool) -> &mut Self {
        self.nosort = nosort;
        self
    }

    pub fn append_ordered(&mut self, mut items: Vec<T>) {
        if self.nosort {
            self.sorted.borrow_mut().append(&mut items);
            return;
        }

        self.sort_vector(&mut items, false);
        let mut sorted = self.sorted.borrow_mut();

        let mut items_smaller = Vec::new();
        if !sorted.is_empty() {
            // move the ones <= sorted to sorted
            while items_smaller.len() < MAX_MOVEMENT
                && !items.is_empty()
                && self.compare_item(items.last().unwrap(), sorted.last().unwrap()) == Ordering::Less
            {
                items_smaller.push(items.pop().unwrap());
            }
        }

        if !items.is_empty() {
            self.sub_vectors.borrow_mut().push(items);
        }

        let too_many_moved = items_smaller.len() >= ORDERED_SIZE;
        trace!("append_ordered: num_moved: {}", items_smaller.len());

        sorted.append(&mut items_smaller);
        if too_many_moved {
            // means the current sorted vector contains item that's large
            // so we'll move the sorted vector to partially sorted candidates.
            self.sort_vector(&mut sorted, false);
            self.sub_vectors.borrow_mut().push(self.sorted.replace(Vec::new()));
        } else {
            self.sort_vector(&mut sorted, true);
        }
    }

    fn sort_vector(&self, vec: &mut Vec<T>, asc: bool) {
        let asc = asc ^ self.tac;
        if asc {
            vec.sort_by(self.compare.as_ref());
        } else {
            vec.sort_by(|a, b| (self.compare)(b, a));
        }
    }

    #[inline]
    fn compare_item(&self, a: &T, b: &T) -> Ordering {
        if !self.tac {
            (self.compare)(a, b)
        } else {
            (self.compare)(b, a)
        }
    }

    fn merge_till(&self, index: usize) {
        let mut sorted = self.sorted.borrow_mut();
        let mut vectors = self.sub_vectors.borrow_mut();

        if index >= sorted.len() {
            trace!("merge_till: index: {}, num_sorted: {}", index, sorted.len());
        }

        while index >= sorted.len() {
            let o_min_index = vectors
                .iter()
                .map(|v| v.last())
                .enumerate()
                .filter(|(_idx, item)| item.is_some())
                .min_by(|(_, a), (_, b)| self.compare_item(a.unwrap(), b.unwrap()))
                .map(|(idx, _)| idx);
            if o_min_index.is_none() {
                break;
            }

            let min_index = o_min_index.unwrap();
            let min_item = vectors[min_index].pop();
            if min_item.is_none() {
                break;
            }

            if vectors[min_index].is_empty() {
                vectors.remove(min_index);
            }

            sorted.push(min_item.unwrap());
        }
    }

    pub fn get(&self, index: usize) -> Option<Ref<T>> {
        self.merge_till(index);
        if self.len() <= index {
            None
        } else {
            let index = if self.tac && self.nosort {
                self.len() - index - 1
            } else {
                index
            };
            Some(Ref::map(self.sorted.borrow(), |list| &list[index]))
        }
    }

    pub fn len(&self) -> usize {
        let sorted_len = self.sorted.borrow().len();
        let unsorted_len: usize = self.sub_vectors.borrow().iter().map(|v| v.len()).sum();
        sorted_len + unsorted_len
    }

    pub fn clear(&mut self) {
        self.sub_vectors.borrow_mut().clear();
        self.sorted.borrow_mut().clear();
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn iter(&self) -> impl Iterator<Item = Ref<T>> {
        self.merge_till(self.len());
        OrderedVecIter {
            ordered_vec: self,
            index: 0,
        }
    }
}

struct OrderedVecIter<'a, T: Send> {
    ordered_vec: &'a OrderedVec<T>,
    index: usize,
}

impl<'a, T: Send> Iterator for OrderedVecIter<'a, T> {
    type Item = Ref<'a, T>;

    fn next(&mut self) -> Option<Self::Item> {
        let ret = self.ordered_vec.get(self.index);
        self.index += 1;
        ret
    }
}

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

    #[test]
    fn test() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.append_ordered(a);
        assert_eq!(*ordered_vec.get(0).unwrap(), 1);

        ordered_vec.append_ordered(b);
        assert_eq!(*ordered_vec.get(1).unwrap(), 3);
        assert_eq!(*ordered_vec.get(2).unwrap(), 4);
        assert_eq!(*ordered_vec.get(3).unwrap(), 5);

        ordered_vec.append_ordered(c);

        for (idx, item) in ordered_vec.iter().enumerate() {
            assert_eq!(idx + 1, *item)
        }
    }

    #[test]
    fn test_tac() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.tac(true);

        ordered_vec.append_ordered(a);
        assert_eq!(*ordered_vec.get(0).unwrap(), 7);

        ordered_vec.append_ordered(b);
        assert_eq!(*ordered_vec.get(1).unwrap(), 8);
        assert_eq!(*ordered_vec.get(2).unwrap(), 7);
        assert_eq!(*ordered_vec.get(3).unwrap(), 5);

        ordered_vec.append_ordered(c);
        for (idx, item) in ordered_vec.iter().enumerate() {
            assert_eq!(10 - idx, *item)
        }
    }

    #[test]
    fn test_nosort() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let d = vec![1, 3, 5, 7, 4, 8, 9, 2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.nosort(true);
        ordered_vec.append_ordered(a);
        ordered_vec.append_ordered(b);
        ordered_vec.append_ordered(c);
        for (a, b) in ordered_vec.iter().zip(d.iter()) {
            assert_eq!(*a, *b);
        }
    }

    #[test]
    fn test_nosort_and_tac() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let d = vec![10, 6, 2, 9, 8, 4, 7, 5, 3, 1];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.nosort(true).tac(true);
        ordered_vec.append_ordered(a);
        ordered_vec.append_ordered(b);
        ordered_vec.append_ordered(c);
        for (a, b) in ordered_vec.iter().zip(d.iter()) {
            assert_eq!(*a, *b);
        }
    }
}
<commit_msg>fix: orderedvec won't preserve insertion order<commit_after>// ordered container
// Normally, user will only care about the first several options. So we only keep several of them
// in order. Other items are kept unordered and are sorted on demand.

use std::cell::{Ref, RefCell};
use std::cmp::Ordering;

pub type CompareFunction<T> = Box<dyn Fn(&T, &T) -> Ordering + Send + Sync>;

const ORDERED_SIZE: usize = 300;
const MAX_MOVEMENT: usize = 100;

pub struct OrderedVec<T: Send> {
    // sorted vectors for merge, reverse ordered, last one is the smallest one
    sub_vectors: RefCell<Vec<Vec<T>>>,
    // globally sorted items, the first one is the smallest one.
    sorted: RefCell<Vec<T>>,
    compare: CompareFunction<T>,
    tac: bool,
    nosort: bool,
}

impl<T: Send> OrderedVec<T> {
    pub fn new(compare: CompareFunction<T>) -> Self {
        OrderedVec {
            sub_vectors: RefCell::new(Vec::new()),
            sorted: RefCell::new(Vec::with_capacity(ORDERED_SIZE)),
            compare,
            tac: false,
            nosort: false,
        }
    }

    pub fn tac(&mut self, tac: bool) -> &mut Self {
        self.tac = tac;
        self
    }

    pub fn nosort(&mut self, nosort: bool) -> &mut Self {
        self.nosort = nosort;
        self
    }

    pub fn append_ordered(&mut self, mut items: Vec<T>) {
        if self.nosort {
            self.sorted.borrow_mut().append(&mut items);
            return;
        }

        self.sort_vector(&mut items, false);
        let mut sorted = self.sorted.borrow_mut();

        let mut items_smaller = Vec::new();
        if !sorted.is_empty() {
            // move the ones <= sorted to sorted
            while items_smaller.len() < MAX_MOVEMENT
                && !items.is_empty()
                && self.compare_item(items.last().unwrap(), sorted.last().unwrap()) == Ordering::Less
            {
                items_smaller.push(items.pop().unwrap());
            }
        }

        if !items.is_empty() {
            self.sub_vectors.borrow_mut().push(items);
        }

        let too_many_moved = items_smaller.len() >= ORDERED_SIZE;
        trace!("append_ordered: num_moved: {}", items_smaller.len());

        sorted.append(&mut items_smaller);
        if too_many_moved {
            // means the current sorted vector contains item that's large
            // so we'll move the sorted vector to partially sorted candidates.
            self.sort_vector(&mut sorted, false);
            self.sub_vectors.borrow_mut().push(self.sorted.replace(Vec::new()));
        } else {
            self.sort_vector(&mut sorted, true);
        }
    }

    fn sort_vector(&self, vec: &mut Vec<T>, asc: bool) {
        let asc = asc ^ self.tac;
        vec.sort_by(self.compare.as_ref());
        if !asc {
            vec.reverse();
        }
    }

    #[inline]
    fn compare_item(&self, a: &T, b: &T) -> Ordering {
        if !self.tac {
            (self.compare)(a, b)
        } else {
            (self.compare)(b, a)
        }
    }

    fn merge_till(&self, index: usize) {
        let mut sorted = self.sorted.borrow_mut();
        let mut vectors = self.sub_vectors.borrow_mut();

        if index >= sorted.len() {
            trace!("merge_till: index: {}, num_sorted: {}", index, sorted.len());
        }

        while index >= sorted.len() {
            let o_min_index = vectors
                .iter()
                .map(|v| v.last())
                .enumerate()
                .filter(|(_idx, item)| item.is_some())
                .min_by(|(_, a), (_, b)| self.compare_item(a.unwrap(), b.unwrap()))
                .map(|(idx, _)| idx);
            if o_min_index.is_none() {
                break;
            }

            let min_index = o_min_index.unwrap();
            let min_item = vectors[min_index].pop();
            if min_item.is_none() {
                break;
            }

            if vectors[min_index].is_empty() {
                vectors.remove(min_index);
            }

            sorted.push(min_item.unwrap());
        }
    }

    pub fn get(&self, index: usize) -> Option<Ref<T>> {
        self.merge_till(index);
        if self.len() <= index {
            None
        } else {
            let index = if self.tac && self.nosort {
                self.len() - index - 1
            } else {
                index
            };
            Some(Ref::map(self.sorted.borrow(), |list| &list[index]))
        }
    }

    pub fn len(&self) -> usize {
        let sorted_len = self.sorted.borrow().len();
        let unsorted_len: usize = self.sub_vectors.borrow().iter().map(|v| v.len()).sum();
        sorted_len + unsorted_len
    }

    pub fn clear(&mut self) {
        self.sub_vectors.borrow_mut().clear();
        self.sorted.borrow_mut().clear();
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn iter(&self) -> impl Iterator<Item = Ref<T>> {
        self.merge_till(self.len());
        OrderedVecIter {
            ordered_vec: self,
            index: 0,
        }
    }
}

struct OrderedVecIter<'a, T: Send> {
    ordered_vec: &'a OrderedVec<T>,
    index: usize,
}

impl<'a, T: Send> Iterator for OrderedVecIter<'a, T> {
    type Item = Ref<'a, T>;

    fn next(&mut self) -> Option<Self::Item> {
        let ret = self.ordered_vec.get(self.index);
        self.index += 1;
        ret
    }
}

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

    #[test]
    fn test() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.append_ordered(a);
        assert_eq!(*ordered_vec.get(0).unwrap(), 1);

        ordered_vec.append_ordered(b);
        assert_eq!(*ordered_vec.get(1).unwrap(), 3);
        assert_eq!(*ordered_vec.get(2).unwrap(), 4);
        assert_eq!(*ordered_vec.get(3).unwrap(), 5);

        ordered_vec.append_ordered(c);

        for (idx, item) in ordered_vec.iter().enumerate() {
            assert_eq!(idx + 1, *item)
        }
    }

    #[test]
    fn test_tac() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.tac(true);

        ordered_vec.append_ordered(a);
        assert_eq!(*ordered_vec.get(0).unwrap(), 7);

        ordered_vec.append_ordered(b);
        assert_eq!(*ordered_vec.get(1).unwrap(), 8);
        assert_eq!(*ordered_vec.get(2).unwrap(), 7);
        assert_eq!(*ordered_vec.get(3).unwrap(), 5);

        ordered_vec.append_ordered(c);
        for (idx, item) in ordered_vec.iter().enumerate() {
            assert_eq!(10 - idx, *item)
        }
    }

    #[test]
    fn test_nosort() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let d = vec![1, 3, 5, 7, 4, 8, 9, 2, 6, 10];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.nosort(true);
        ordered_vec.append_ordered(a);
        ordered_vec.append_ordered(b);
        ordered_vec.append_ordered(c);
        for (a, b) in ordered_vec.iter().zip(d.iter()) {
            assert_eq!(*a, *b);
        }
    }

    #[test]
    fn test_nosort_and_tac() {
        let a = vec![1, 3, 5, 7];
        let b = vec![4, 8, 9];
        let c = vec![2, 6, 10];
        let d = vec![10, 6, 2, 9, 8, 4, 7, 5, 3, 1];
        let mut ordered_vec = OrderedVec::new(Box::new(usize::cmp));
        ordered_vec.nosort(true).tac(true);
        ordered_vec.append_ordered(a);
        ordered_vec.append_ordered(b);
        ordered_vec.append_ordered(c);
        for (a, b) in ordered_vec.iter().zip(d.iter()) {
            assert_eq!(*a, *b);
        }
    }

    #[test]
    fn test_equals() {
        let a = vec![1, 2, 3, 4];
        let b = vec![5, 6, 7, 8];
        let target = vec![1, 2, 3, 4, 5, 6, 7, 8];
        let mut ordered_vec = OrderedVec::new(Box::new(|_a, _b| Ordering::Equal));
        ordered_vec.append_ordered(a);
        ordered_vec.append_ordered(b);
        for (a, b) in ordered_vec.iter().zip(target.iter()) {
            assert_eq!(*a, *b);
        }
    }
}
<|endoftext|>


<commit_before>use mysql::from_row;
use mysql::error::Error::MySqlError;
use serde_json::Value;
use chrono::NaiveDateTime;

use common::utils::*;
use common::lazy_static::SQL_POOL;

pub fn create_comment_vote(data: &Value) -> Option<u64> {

    Some(1)
}

pub fn update_comment_vote(data: &Value) -> Option<u64> {

    Some(1)
}<commit_msg>修改comment_vote<commit_after>use mysql::from_row;
use mysql::error::Error::MySqlError;
use serde_json::Value;
use chrono::NaiveDateTime;

use common::utils::*;
use common::lazy_static::SQL_POOL;

pub fn is_voted(user_id: &str, comment_id: &str) -> bool {

    let mut result = SQL_POOL.prep_exec(r#"
                        SELECT count(id) FROM comment_vote
                        WHERE
                        user_id = ? AND comment_id = ?
                        "#, (user_id, comment_id)).unwrap();

    let row_wrapper = result.next();

    if row_wrapper.is_none() {
        return false;
    }

    let row = row_wrapper.unwrap().unwrap();
    let (count, ) = from_row::<(u8, )>(row);

    if count == 0 {
        false
    } else {
        true
    }
}

pub fn create_comment_vote(user_id: &str, comment_id: &str, state: &str) -> Option<u8> {

    let create_time = gen_datetime().to_string();
    let mut stmt = SQL_POOL.prepare(r#"
                        INSERT INTO comment_vote
                        (user_id, comment_id, state, create_time, update_time)
                        VALUES
                        (?, ?, ?, ?)
                        "#).unwrap();

    let result = stmt.execute((user_id, comment_id, state, &*create_time, &*create_time));

    if let Err(MySqlError(ref err)) = result {
        println!("{:?}", err.message);
        return None;
    }

    Some(1)
}

pub fn update_comment_vote(user_id: &str, comment_id: &str, state: &str) -> Option<u8> {

    let update_time = gen_datetime().to_string();
    let mut stmt = SQL_POOL.prepare(r#"
                        UPDATE comment_vote SET
                        user_id = ?,
                        comment_id = ?,
                        state = ?,
                        update_time = ?
                        "#).unwrap();

    let result = stmt.execute((user_id, comment_id, state, &*update_time));

    if let Err(MySqlError(ref err)) = result {
        println!("{:?}", err.message);
        return None;
    }

    Some(1)
}

pub fn delete_comment_vote(user_id: &str, comment_id: &str) -> Option<u8> {

    let mut stmt = SQL_POOL.prepare(r#"
                        DELETE FROM comment_vote
                        WHERE
                        user_id = ? AND comment_id = ?
                        "#).unwrap();

    let result = stmt.execute((user_id, comment_id));

    if let Err(MySqlError(ref err)) = result {
        println!("{:?}", err.message);
        return None;
    }

    Some(1)
}<|endoftext|>


<commit_before>pub mod ast;

use std::iter::Peekable;
use std::marker::Sized;
use std::fmt;

use super::lexer::Token::{self, IdentT, LeftParenthesis, RightParenthesis, Comma, Semicolon, NumberT, StringT};
use self::ast::Node::{self, Delete, From, Where, Id, NumberC, StringC, Insert, Table, Values, Column, TableColumn, Create};
use self::ast::Type;
use self::ast::Condition::{Eq};

pub trait Parser {
    fn parse(self) -> Result<Node, String>;
}

impl Parser for Vec<Token> {
    fn parse(self) -> Result<Node, String> {
        let mut iter = self.into_iter().peekable();
        match iter.next() {
            Some(IdentT(statement)) => {
                match statement.as_str() {
                    "create" => Ok(Create(Box::new(try!(parse_create(&mut iter.by_ref()))))),
                    "delete" => Ok(Delete(Box::new(try!(parse_from(&mut iter.by_ref()))), Box::new(try!(parse_where(&mut iter.by_ref()))))),
                    "insert" => Ok(Insert(Box::new(try!(parse_table(&mut iter.by_ref()))), Box::new(Values(parse_values(&mut iter.by_ref()))))),
                    _ => Err("undefined query type".to_owned()),
                }
            }
            _ => Err("".to_owned()),
        }
    }
}

fn parse_create<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'TABLE' keyword
    let table_name = match tokens.next() {
        Some(IdentT(name)) => name,
        Some(token) => return Err(format_unexpected_token("table name", Some(&token))),
        _ => return Err("".to_owned()),
    };
    Ok(Table(table_name, try!(parse_table_columns(&mut tokens.by_ref()))))
}

fn parse_table_columns<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Vec<Node>, String> {
    match tokens.next() {
        Some(LeftParenthesis) => { } //skip '('
        token => return Err(format_unexpected_token(LeftParenthesis, token.as_ref())),
    }

    let mut columns = vec![];

    loop {
        let col_name = match tokens.next() {
            Some(IdentT(name)) => name,
            _ => return Err("".to_owned()),
        };
        let col_type = match tokens.next() {
            Some(IdentT(_)) => Type::Int,
            _ => return Err("".to_owned()),
        };

        columns.push(TableColumn(col_name, col_type, None));

        match tokens.next() {
            Some(Comma) => { }, //skip ','
            Some(RightParenthesis) => break,
            Some(IdentT(id)) => return Err(format_unexpected_token(Comma, Some(&IdentT(id)))),
            Some(token) => return Err(format_unexpected_token(RightParenthesis, Some(&token))),
            None => return Err("parsing error missing ','".to_owned()),
        }
    }

//    tokens.next(); //skip ')'
    match tokens.peek() {
        Some(&Semicolon) => { tokens.next(); } // skip ';'
        _ => return Err(format_unexpected_token(Semicolon, None)),
    }

    Ok(columns)
}

fn format_unexpected_token<D: fmt::Display + Sized>(expected: D, found: Option<&Token>) -> String {
    match found {
        Some(ref token) => format!("error: expected <{}> found <{}>", expected, token),
        None => format!("error: expected <{}>", expected)
    }
}

fn parse_from<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'FROM' keyword
    match tokens.next() {
        Some(IdentT(table_name)) => Ok(From(table_name)),
        _ => Err("".to_owned()),
    }
}

fn parse_where<I: Iterator<Item = Token>>(tokens: &mut I) -> Result<Node, String> {
    tokens.next(); //skip 'WHERE' keyword
    match tokens.next() {
        Some(_) => Ok(Where(Some(Eq(Box::new(Id("col".to_owned())), Box::new(NumberC("5".to_owned())))))),
        _ => Ok(Where(None)),
    }
}

fn parse_table<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'INTO' keyword
    tokens.next(); //skip table name
    Ok(Table("table_name".to_owned(), parse_columns(&mut tokens.by_ref())))
}

fn parse_columns<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Vec<Node> {
    match tokens.peek() {
        Some(&LeftParenthesis) => { tokens.next(); }, //skip '('
        _ => return vec![],
    }
    println!("columns exist");
    let mut columns = vec![];
    loop {
        match tokens.next() {
            Some(Comma) => {},
            Some(IdentT(col)) => { columns.push(Column(col)); },
            _ => break,
        }
    }
    columns
}

fn parse_values<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Vec<Node> {
    tokens.next(); //skip 'VALUES' keyword
    //    println!("left tokens - {:?}", tokens);
    tokens.next(); //skip '('
    let mut values = vec![];
    loop {
        match tokens.next() {
            Some(NumberT(val)) => values.push(NumberC(val)),
            Some(StringT(val)) => values.push(StringC(val)),
            Some(Comma) => {},
            _ => break,
        }
    }

    tokens.next(); // skip ';'
    values
}
<commit_msg>implement trait Parser for all who implement IntoIterator<Token><commit_after>pub mod ast;

use std::iter::Peekable;
use std::marker::Sized;
use std::fmt;

use super::lexer::Token::{self, IdentT, LeftParenthesis, RightParenthesis, Comma, Semicolon, NumberT, StringT};
use self::ast::Node::{self, Delete, From, Where, Id, NumberC, StringC, Insert, Table, Values, Column, TableColumn, Create};
use self::ast::Type;
use self::ast::Condition::{Eq};

pub trait Parser {
    fn parse(self) -> Result<Node, String>;
}

impl <T: IntoIterator<Item = Token>> Parser for T {
    fn parse(self) -> Result<Node, String> {
        let mut iter = self.into_iter().peekable();
        match iter.next() {
            Some(IdentT(statement)) => {
                match statement.as_str() {
                    "create" => Ok(Create(Box::new(try!(parse_create(&mut iter.by_ref()))))),
                    "delete" => Ok(Delete(Box::new(try!(parse_from(&mut iter.by_ref()))), Box::new(try!(parse_where(&mut iter.by_ref()))))),
                    "insert" => Ok(Insert(Box::new(try!(parse_table(&mut iter.by_ref()))), Box::new(Values(parse_values(&mut iter.by_ref()))))),
                    _ => Err("undefined query type".to_owned()),
                }
            }
            _ => Err("".to_owned()),
        }
    }
}

fn parse_create<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'TABLE' keyword
    let table_name = match tokens.next() {
        Some(IdentT(name)) => name,
        Some(token) => return Err(format_unexpected_token("table name", Some(&token))),
        _ => return Err("".to_owned()),
    };
    Ok(Table(table_name, try!(parse_table_columns(&mut tokens.by_ref()))))
}

fn parse_table_columns<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Vec<Node>, String> {
    match tokens.next() {
        Some(LeftParenthesis) => { } //skip '('
        token => return Err(format_unexpected_token(LeftParenthesis, token.as_ref())),
    }

    let mut columns = vec![];

    loop {
        let col_name = match tokens.next() {
            Some(IdentT(name)) => name,
            _ => return Err("".to_owned()),
        };
        let col_type = match tokens.next() {
            Some(IdentT(_)) => Type::Int,
            _ => return Err("".to_owned()),
        };

        columns.push(TableColumn(col_name, col_type, None));

        match tokens.next() {
            Some(Comma) => { }, //skip ','
            Some(RightParenthesis) => break,
            Some(IdentT(id)) => return Err(format_unexpected_token(Comma, Some(&IdentT(id)))),
            Some(token) => return Err(format_unexpected_token(RightParenthesis, Some(&token))),
            None => return Err("parsing error missing ','".to_owned()),
        }
    }

//    tokens.next(); //skip ')'
    match tokens.peek() {
        Some(&Semicolon) => { tokens.next(); } // skip ';'
        _ => return Err(format_unexpected_token(Semicolon, None)),
    }

    Ok(columns)
}

fn format_unexpected_token<D: fmt::Display + Sized>(expected: D, found: Option<&Token>) -> String {
    match found {
        Some(ref token) => format!("error: expected <{}> found <{}>", expected, token),
        None => format!("error: expected <{}>", expected)
    }
}

fn parse_from<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'FROM' keyword
    match tokens.next() {
        Some(IdentT(table_name)) => Ok(From(table_name)),
        _ => Err("".to_owned()),
    }
}

fn parse_where<I: Iterator<Item = Token>>(tokens: &mut I) -> Result<Node, String> {
    tokens.next(); //skip 'WHERE' keyword
    match tokens.next() {
        Some(_) => Ok(Where(Some(Eq(Box::new(Id("col".to_owned())), Box::new(NumberC("5".to_owned())))))),
        _ => Ok(Where(None)),
    }
}

fn parse_table<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Result<Node, String> {
    tokens.next(); //skip 'INTO' keyword
    tokens.next(); //skip table name
    Ok(Table("table_name".to_owned(), parse_columns(&mut tokens.by_ref())))
}

fn parse_columns<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Vec<Node> {
    match tokens.peek() {
        Some(&LeftParenthesis) => { tokens.next(); }, //skip '('
        _ => return vec![],
    }
    println!("columns exist");
    let mut columns = vec![];
    loop {
        match tokens.next() {
            Some(Comma) => {},
            Some(IdentT(col)) => { columns.push(Column(col)); },
            _ => break,
        }
    }
    columns
}

fn parse_values<I: Iterator<Item = Token>>(tokens: &mut Peekable<I>) -> Vec<Node> {
    tokens.next(); //skip 'VALUES' keyword
    //    println!("left tokens - {:?}", tokens);
    tokens.next(); //skip '('
    let mut values = vec![];
    loop {
        match tokens.next() {
            Some(NumberT(val)) => values.push(NumberC(val)),
            Some(StringT(val)) => values.push(StringC(val)),
            Some(Comma) => {},
            _ => break,
        }
    }

    tokens.next(); // skip ';'
    values
}
<|endoftext|>


<commit_before>//! Insertion sort algorithm.
//!
//! The `insertion_sort` module contains the simple sorting algorithm "Insertion Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Insertion_sort

use std::fmt::Debug;

/// Simple sort: insertion sort.
///
/// # Details
///
/// Insertion sort is one of the simplest sorting algorithm. Every elements of the list to sort
/// are picked one at a time and inserted into a the sorted list at the right location.
///
/// This function takes an immutable reference vector of any type and returns a vector of `usize`
/// of the same length containing the indices of the initial vector sorted.
///
/// # Scaling
///
/// In the best case scenario, the list is already sorted and the work is simply to append the
/// element at the end of the list, hence a O(N) scaling.
///
/// In the worst case scenario, the list is in reverse order. Hence, every element is compared to
/// all previous elements already sorted until this new one gets inserted at the beginning of the
/// sorted list, thus making this case O(N^2).
///
/// Insertion sort is still useful as its simplicity (and thus small overhead) makes it ideal for
/// small vectors.
///
/// # Notes
///
/// The implementation is 'unstable' as it does not preserve the relative order of items with
/// equal values. It could be made stable though if required.
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// assert_eq!(vec![3, 1, 2, 0], sorting::simplesorts::insertion::sort(&data));
/// ```
///
pub fn sort<T: Debug + PartialOrd>(input: &Vec<T>) -> Vec<usize> {
    let n = input.len();

    let mut output_index: Vec<usize> = Vec::with_capacity(n);

    if !input.is_empty() {

        // Place the first element's index (0) as the first element of the output_index vector.
        output_index.push(0);

        // Loop over input vector, skipping the first element as it's already inserted as the first
        // element of output_index.
        for (i_start_at_0,elem) in input.iter().skip(1).enumerate() {
            let i = i_start_at_0 + 1;
            println!("  i={:?} Finding where to put element {:?} (i={:?}) in output_index: {:?}", i, elem, i, output_index);

            // Verify next element if it is smaller
            // If next element is larger than the last stored index, just place that element at
            // the end.
            if *elem >= input[*output_index.last().unwrap()] {
                // Next element "elem" is already larger than the previous stored index.
                // Just use its index.
                output_index.push(i);

                println!("    1. Pushing element '{:?}' at the end.", elem);
            } else {
                println!("    2. elem ?< input[output_index[0]]");
                println!("           {:?} ?< {:?}", elem, input[output_index[0]]);
                // The next element of the input vector is smaller than the last stored on.
                // Let's find where it should go by looping back on the stored indices.
                // NOTE: we must use a loop on indices as to prevent problems with the borrow-checker.
                if *elem < input[output_index[0]] {
                    println!("        2a. Yes: --> putting i in front");
                    output_index.insert(0, i);
                } else {
                    println!("        2b. No: --> Looping back");
                    for j in (0..i).rev() {
                        println!("            j={:?}   elem={:?}   input[output_index[j]]={:?}", j, elem, input[output_index[j]]);
                        if *elem > input[output_index[j]] {
                            output_index.insert(j+1, i);
                            break;
                        }
                    }
                }
                println!("        3. output_index: {:?}", output_index);
            }

            print!("           output: [");
            for j in output_index.iter() {
                    print!("{:?}, ", input[*j]);
            }
            println!("]");
        }
    }

    println!("");
    println!("END: input:        {:?}", input);
    println!("END: output_index: {:?}", output_index);
    print!("END: output:       [");
    for j in output_index.iter() {
            print!("{:?}, ", input[*j]);
    }
    println!("]");

    assert_eq!(output_index.len(), n);

    return output_index;
}
<commit_msg>Cleanups and comments<commit_after>//! Insertion sort algorithm.
//!
//! The `insertion_sort` module contains the simple sorting algorithm "Insertion Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Insertion_sort

use std::fmt::Debug;

/// Simple sort: insertion sort.
///
/// # Details
///
/// Insertion sort is one of the simplest sorting algorithm. Every elements of the list to sort
/// are picked one at a time and inserted into a the sorted list at the right location.
///
/// This function takes an immutable reference vector of any type and returns a vector of `usize`
/// of the same length containing the indices of the initial vector sorted.
///
/// # Scaling
///
/// In the best case scenario, the list is already sorted and the work is simply to append the
/// element at the end of the list, hence a O(N) scaling.
///
/// In the worst case scenario, the list is in reverse order. Hence, every element is compared to
/// all previous elements already sorted until this new one gets inserted at the beginning of the
/// sorted list, thus making this case O(N^2).
///
/// Insertion sort is still useful as its simplicity (and thus small overhead) makes it ideal for
/// small vectors.
///
/// # Notes
///
/// The implementation is 'unstable' as it does not preserve the relative order of items with
/// equal values. It could be made stable though if required.
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// assert_eq!(vec![3, 1, 2, 0], sorting::simplesorts::insertion::sort(&data));
/// ```
///
pub fn sort<T: Debug + PartialOrd>(input: &Vec<T>) -> Vec<usize> {
    let n = input.len();

    // Declare the vector of indices to return. Reserve memory for "n" element so it
    // is the same size as the vector to sort.
    let mut output_index: Vec<usize> = Vec::with_capacity(n);

    if !input.is_empty() {

        // Place the first element's index (0) as the first element of the output_index vector.
        output_index.push(0);

        // Loop over input vector, skipping the first element as it's already inserted as the first
        // element of output_index.
        for (i_start_at_0,elem) in input.iter().skip(1).enumerate() {
            // enumerate() returns the current index of iteration, not the index of the
            // vector iterated upon. This means it will start at 0, even though we wanted to skip
            // the first element using skip(1). Let's get the value we wanted: 'i', the loop index
            // of the input array.
            let i = i_start_at_0 + 1;

            // Compare the element of the loop 'elem' with the last element stored in the index
            // vector 'output_index'.
            if *elem >= input[*output_index.last().unwrap()] {
                // If the element of the loop is larger or equal to the last sorted element, simply
                // append its index to the sorted index list.
                output_index.push(i);
            } else {
                println!("    2. elem ?< input[output_index[0]]");
                println!("           {:?} ?< {:?}", elem, input[output_index[0]]);
                // The next element of the input vector is smaller than the last stored on.
                // Let's find where it should go by looping back on the stored indices.
                // NOTE: we must use a loop on indices as to prevent problems with the borrow-checker.
                if *elem < input[output_index[0]] {
                    println!("        2a. Yes: --> putting i in front");
                    output_index.insert(0, i);
                } else {
                    println!("        2b. No: --> Looping back");
                    for j in (0..i).rev() {
                        println!("            j={:?}   elem={:?}   input[output_index[j]]={:?}", j, elem, input[output_index[j]]);
                        if *elem > input[output_index[j]] {
                            output_index.insert(j+1, i);
                            break;
                        }
                    }
                }
            }

            print!("           output: [");
            for j in output_index.iter() {
                    print!("{:?}, ", input[*j]);
            }
            println!("]");
        }
    }

    println!("");
    println!("END: input:        {:?}", input);
    println!("END: output_index: {:?}", output_index);
    print!("END: output:       [");
    for j in output_index.iter() {
            print!("{:?}, ", input[*j]);
    }
    println!("]");

    assert_eq!(output_index.len(), n);

    return output_index;
}
<|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 = 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>(mut v: Vec<A>, x:A) -> Vec<A> {
    v.insert(0, x);
    v
}

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()
    }
}
<commit_msg>First pass at using a DList<commit_after>use super::mode;
use super::string_utils;
use std::collections::DList;
use std::collections::Deque;

#[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:DList<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    let mut tail = xs.clone();
    match tail.pop_front() {
        None => {
            true
        },
        Some((i, mode, ref doc)) => match doc.clone() {
            Nil => {
                fitting(tail, left)
            },
            Append(box x, box y) => {
                let mut prefix = DList::new();
                prefix.push((i, mode, x));
                prefix.push((i, mode, y));
                tail.prepend(prefix);
                fitting(tail, left)
            },
            Nest(j, box x) => {
                let mut prefix = DList::new();
                prefix.push((i + j, mode, x));
                tail.prepend(prefix);
                fitting(tail, left)
            },
            Text(str) => {
                fitting(tail, left - str.len())
            },
            Break(sp, _) => match mode {
                mode::Flat => {
                    fitting(tail, left - sp)
                },
                mode::Break => {
                    true
                },
            },
            Newline => {
                true
            },
            Group(box x) => {
                let mut prefix = DList::new();
                prefix.push((i, mode, x));
                tail.prepend(prefix);
                fitting(tail, left)
            },
        }
    }
}

fn best(w:uint, s:DList<String>, x:Doc) -> DList<String> {
    let mut result = s.clone();

    fn go(w:uint, s:&mut DList<String>, k:uint, xs:&mut DList<(uint,mode::Mode,Doc)>) {
        match xs.pop_front() {
            None => { },
            Some((i, mode, ref doc)) => match doc.clone() {
                Nil => {
                    go(w, s, k, xs)
                },
                Append(box x, box y) => {
                    let mut prefix = DList::new();
                    prefix.push((i, mode, x));
                    prefix.push((i, mode, y));
                    xs.prepend(prefix);
                    go(w, s, k, xs)
                },
                Nest(j, box x) => {
                    let mut prefix = DList::new();
                    prefix.push((i + j, mode, x));
                    xs.prepend(prefix);
                    go(w, s, k, xs)
                },
                Text(ref str) => {
                    let mut prefix = DList::new();
                    prefix.push(str.clone());
                    s.prepend(prefix);
                    go(w, s, k + str.len(), xs)
                },
                Newline => {
                    let mut prefix = DList::new();
                    prefix.push(string_utils::nl_space(i));
                    s.prepend(prefix);
                    go(w, s, i, xs)
                },
                Break(sp, off) => match mode {
                    mode::Flat => {
                        let mut prefix = DList::new();
                        prefix.push(string_utils::spaces(sp));
                        s.prepend(prefix);
                        go(w, s, k + sp, xs)
                    },
                    mode::Break => {
                        let mut prefix = DList::new();
                        prefix.push(string_utils::nl_space(i + off));
                        s.prepend(prefix);
                        go(w, s, i + off, xs)
                    }
                },
                Group(ref x) => match mode {
                    mode::Flat => {
                        let mut prefix = DList::new();
                        prefix.push((i, mode::Flat, *x.clone()));
                        xs.prepend(prefix);
                        go(w, s, k, xs)
                    },
                    mode::Break => {
                        let mut ys = xs.clone();
                        let mut flat_prefix = DList::new();
                        flat_prefix.push((i, mode::Flat, *x.clone()));
                        ys.prepend(flat_prefix);
                        if fitting(ys, w - k) {
                            let mut prefix = DList::new();
                            prefix.push((i, mode::Flat, *x.clone()));
                            xs.prepend(prefix);
                            go(w, s, k, xs)
                        } else {
                            let mut prefix = DList::new();
                            prefix.push((i, mode::Break, *x.clone()));
                            xs.prepend(prefix);
                            go(w, s, k, xs)
                        }
                    }
                }
            }
        }
    }

    let mut start = DList::new();
    start.push((0, mode::Break, x));

    go(w, &mut result, 0, &mut start);
    result
}

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 strs = best(w, DList::new(), self);

        let mut result = String::new();
        for str in strs.iter().rev() {
            result.push_str(str.as_slice());
        }
        result
    }
}
<|endoftext|>


<commit_before>use ll::stylesheet::css_fixed;
use types::CssQName;
use core::libc::c_void;
use lwcstr_from_rust_str = wapcaplet::from_rust_string;

pub fn css_fixed_to_float(f: css_fixed) -> float {
    const before: i32 = 10;
    f as float * 1.0f / ((1i32 << before) as float)
}

pub fn float_to_css_fixed(f: float) -> css_fixed {
    const before: i32 = 10;
    (f * ((1 << before) as float)) as css_fixed
}

pub fn rust_str_to_net_qname(s: &str) -> CssQName {
    CssQName {
        ns: None,
        name: lwcstr_from_rust_str(s)
    }
}

pub fn net_qname_to_rust_str(qname: &CssQName) -> ~str {
    qname.name.to_str()
}

// FIXME: These methods should be unsafe
pub trait VoidPtrLike {
    static fn from_void_ptr(*c_void) -> self;
    fn to_void_ptr(&self) -> *c_void;
}
<commit_msg>Remove a copy<commit_after>use ll::stylesheet::css_fixed;
use types::CssQName;
use core::libc::c_void;
use lwcstr_from_rust_str = wapcaplet::from_rust_string;

pub fn css_fixed_to_float(f: css_fixed) -> float {
    const before: i32 = 10;
    f as float * 1.0f / ((1i32 << before) as float)
}

pub fn float_to_css_fixed(f: float) -> css_fixed {
    const before: i32 = 10;
    (f * ((1 << before) as float)) as css_fixed
}

pub fn rust_str_to_net_qname(s: &str) -> CssQName {
    CssQName {
        ns: None,
        name: lwcstr_from_rust_str(s)
    }
}

pub fn net_qname_to_rust_str(qname: &a/CssQName) -> &a/str {
    qname.name.to_str_slice()
}

// FIXME: These methods should be unsafe
pub trait VoidPtrLike {
    static fn from_void_ptr(*c_void) -> self;
    fn to_void_ptr(&self) -> *c_void;
}
<|endoftext|>


<commit_before>use objects::User;
use objects::Chat;
use objects::MessageEntity;
use objects::Contact;
use objects::Document;
use objects::Audio;
use objects::Sticker;
use objects::Video;

/// Represents a Telegram message.
#[derive(Clone, Deserialize, Debug)]
pub struct Message {
    pub message_id: i64,
    pub from: Option<User>,
    pub date: i64,
    pub chat: Chat,
    pub forward_from: Option<User>,
    pub forward_from_chat: Option<Chat>,
    pub forward_from_message_id: Option<i64>,
    pub forward_date: Option<i64>,
    pub reply_to_message: Option<Box<Message>>,
    pub edit_date: Option<i64>,
    pub text: Option<String>,
    pub entities: Option<Vec<MessageEntity>>,
    pub audio: Option<Audio>,
    pub document: Option<Document>,
    pub game: Option<String>,
    pub photo: Option<String>,
    pub sticker: Option<Sticker>,
    pub video: Option<Video>,
    pub voice: Option<String>,
    pub caption: Option<String>,
    pub contact: Option<Contact>,
    pub location: Option<String>,
    pub venue: Option<String>,
    pub new_chat_member: Option<User>,
    pub left_chat_member: Option<User>,
    pub new_chat_title: Option<String>,
    pub new_chat_photo: Option<String>,
    pub delete_chat_photo: Option<bool>,
    pub group_chat_created: Option<bool>,
    pub supergroup_chat_created: Option<bool>,
    pub channel_chat_created: Option<bool>,
    pub migrate_to_chat_id: Option<i64>,
    pub migrate_from_chat_id: Option<i64>,
    pub pinned_message: Option<Box<Message>>,
}
<commit_msg>changed String of photo to PhotoSize Vec<commit_after>use objects::User;
use objects::Chat;
use objects::MessageEntity;
use objects::Contact;
use objects::Document;
use objects::Audio;
use objects::Sticker;
use objects::Video;
use objects::PhotoSize;

/// Represents a Telegram message.
#[derive(Clone, Deserialize, Debug)]
pub struct Message {
    pub message_id: i64,
    pub from: Option<User>,
    pub date: i64,
    pub chat: Chat,
    pub forward_from: Option<User>,
    pub forward_from_chat: Option<Chat>,
    pub forward_from_message_id: Option<i64>,
    pub forward_date: Option<i64>,
    pub reply_to_message: Option<Box<Message>>,
    pub edit_date: Option<i64>,
    pub text: Option<String>,
    pub entities: Option<Vec<MessageEntity>>,
    pub audio: Option<Audio>,
    pub document: Option<Document>,
    pub game: Option<String>,
    pub photo: Option<Vec<PhotoSize>>,
    pub sticker: Option<Sticker>,
    pub video: Option<Video>,
    pub voice: Option<String>,
    pub caption: Option<String>,
    pub contact: Option<Contact>,
    pub location: Option<String>,
    pub venue: Option<String>,
    pub new_chat_member: Option<User>,
    pub left_chat_member: Option<User>,
    pub new_chat_title: Option<String>,
    pub new_chat_photo: Option<String>,
    pub delete_chat_photo: Option<bool>,
    pub group_chat_created: Option<bool>,
    pub supergroup_chat_created: Option<bool>,
    pub channel_chat_created: Option<bool>,
    pub migrate_to_chat_id: Option<i64>,
    pub migrate_from_chat_id: Option<i64>,
    pub pinned_message: Option<Box<Message>>,
}
<|endoftext|>


<commit_before>use itertools::Itertools;

use fall_tree::AstNode;
use fall_tree::search::child_of_type_exn;

use super::Analysis;
use ::{Expr, CallExpr, IDENT};

#[derive(Debug, Eq, PartialEq)]
pub enum CallKind<'f> {
    Eof,
    Any,
    Commit,
    Not(Expr<'f>),
    Layer(Expr<'f>, Expr<'f>),
    WithSkip(Expr<'f>, Expr<'f>),
    //    Enter(u32, Expr<'f>),
    //    Exit(u32, Expr<'f>),
    //    IsIn(u32),
}

pub fn resolve<'f>(a: &Analysis<'f>, call: CallExpr<'f>) -> Option<CallKind<'f>> {
    let n_args = call.args().count();
    let expect_args = |n_expected: usize| {
        if n_expected != n_args {
            a.diagnostics.error(
                call.node(),
                format!("Wrong number of arguments, expected {}, got {}", n_expected, n_args)
            )
        }
    };

    let zero_arg = vec![
        ("any", CallKind::Any),
        ("commit", CallKind::Commit),
        ("eof", CallKind::Eof)
    ];

    for (name, kind) in zero_arg.into_iter() {
        if call.fn_name() == name {
            expect_args(0);
            return Some(kind);
        }
    }

    if call.fn_name() == "not" {
        expect_args(1);
        return call.args().next().map(CallKind::Not);
    }

    let two_arg = vec![
        ("layer", CallKind::Layer as fn(_, _) -> _),
        ("with_skip", CallKind::WithSkip)
    ];

    for (name, kind) in two_arg.into_iter() {
        if call.fn_name() == name {
            expect_args(2);
            return call.args().next_tuple()
                .map(|(a, b)| kind(a, b))
        }
    }

    a.diagnostics.error(
        child_of_type_exn(call.node(), IDENT),
        "Unresolved reference"
    );
    return None;
}

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

    use fall_tree::search;
    use fall_tree::search::ast;

    use ::test_util::parse_with_caret;

    #[test]
    fn test_resolve_no_args() {
        check_resolved("rule foo { <^eof> }", "Eof");
        check_resolved("rule foo { <^any> }", "Any");
        check_resolved("rule foo { <^commit> }", "Commit");
    }

    #[test]
    fn test_resolve_simple_args() {
        check_resolved("rule foo { <^not a> }", "Not(RefExpr@[16; 17))");
        check_resolved("rule foo { <^with_skip a b> }", "WithSkip(RefExpr@[22; 23), RefExpr@[24; 25))");
        check_resolved("rule foo { <^layer a b> }", "Layer(RefExpr@[18; 19), RefExpr@[20; 21))");
    }

    #[test]
    fn test_not() {
        resolve_call("rule foo { <^not bar>}", |c, _| {
            let c = c.unwrap();
            assert_eq!(format!("{:?}", c), "Not(RefExpr@[16; 19))");
        })
    }

    #[test]
    fn test_unresolved_call() {
        check(
            r"rule foo {  <^abracadabra>}",
            None,
            r#"[(abracadabra, "Unresolved reference")]"#
        );
    }

    #[test]
    fn wrong_arity() {
        check(
            r" rule foo { <^eof foo> }",
            Some(CallKind::Eof),
            r#"[(<eof foo>, "Wrong number of arguments, expected 0, got 1")]"#
        );

        check(
            r" rule foo { <^any foo bar> }",
            Some(CallKind::Any),
            r#"[(<any foo bar>, "Wrong number of arguments, expected 0, got 2")]"#
        );

        check(
            r" rule foo { <^commit foo bar baz> }",
            Some(CallKind::Commit),
            r#"[(<commit foo bar baz>, "Wrong number of arguments, expected 0, got 3")]"#
        );

        check(
            r" rule foo { <^not> }",
            None,
            r#"[(<not>, "Wrong number of arguments, expected 1, got 0")]"#
        );
    }

    fn check(text: &str, kind: Option<CallKind>, diagnostics: &str) {
        resolve_call(text, |c, a| {
            assert_eq!(c, kind);
            assert_eq!(a.diagnostics.debug(a.file.node().text()), diagnostics);
        })
    }

    fn check_resolved(text: &str, kind: &str) {
        resolve_call(text, |c, a| {
            let c = c.unwrap();
            assert_eq!(format!("{:?}", c), kind);
            assert_eq!(a.diagnostics.debug(a.file.node().text()), "[]");
        })
    }

    fn resolve_call<F: FnOnce(Option<CallKind>, Analysis)>(text: &str, f: F) {
        let (file, caret) = parse_with_caret(&text);
        let call = {
            let leaf = search::find_leaf_at_offset(file.root(), caret)
                .left_biased().unwrap();
            ast::ancestor_exn(leaf)
        };
        let a = Analysis::new(::ast(&file));
        let c = a.resolve_call(call);
        f(c, a)
    }
}

<commit_msg>Resolve layer calls<commit_after>use itertools::Itertools;

use fall_tree::{AstNode, AstClass};
use fall_tree::search::child_of_type_exn;
use fall_tree::search::ast;

use super::Analysis;
use ::{Expr, CallExpr, IDENT};

#[derive(Debug, Eq, PartialEq)]
pub enum CallKind<'f> {
    Eof,
    Any,
    Commit,
    Not(Expr<'f>),
    Layer(Expr<'f>, Expr<'f>),
    WithSkip(Expr<'f>, Expr<'f>),
    Enter(u32, Expr<'f>),
    Exit(u32, Expr<'f>),
    IsIn(u32),
}

pub fn resolve<'f>(a: &Analysis<'f>, call: CallExpr<'f>) -> Option<CallKind<'f>> {
    let n_args = call.args().count();
    let expect_args = |n_expected: usize| {
        if n_expected != n_args {
            a.diagnostics.error(
                call.node(),
                format!("Wrong number of arguments, expected {}, got {}", n_expected, n_args)
            )
        }
    };

    let zero_arg = vec![
        ("any", CallKind::Any),
        ("commit", CallKind::Commit),
        ("eof", CallKind::Eof)
    ];

    for (name, kind) in zero_arg.into_iter() {
        if call.fn_name() == name {
            expect_args(0);
            return Some(kind);
        }
    }

    if call.fn_name() == "not" {
        expect_args(1);
        return call.args().next().map(CallKind::Not);
    }

    let two_arg = vec![
        ("layer", CallKind::Layer as fn(_, _) -> _),
        ("with_skip", CallKind::WithSkip)
    ];

    for (name, kind) in two_arg.into_iter() {
        if call.fn_name() == name {
            expect_args(2);
            return call.args().next_tuple()
                .map(|(a, b)| kind(a, b));
        }
    }

    if call.fn_name() == "is_in" {
        expect_args(1);
        return call.args().next()
            .and_then(|ctx| resolve_context(a, ctx))
            .map(CallKind::IsIn);
    }

    let layer_expr = vec![
        ("enter", CallKind::Enter as fn(_, _) -> _),
        ("exit", CallKind::Exit),
    ];

    for (name, kind) in layer_expr.into_iter() {
        if call.fn_name() == name {
            expect_args(2);
            return call.args().next_tuple()
                .and_then(|(ctx, body)| {
                    resolve_context(a, ctx).map(|ctx| kind(ctx, body))
                });
        }
    }

    a.diagnostics.error(
        child_of_type_exn(call.node(), IDENT),
        "Unresolved reference"
    );
    return None;
}

fn resolve_context(a: &Analysis, ctx: Expr) -> Option<u32> {
    if let Some(ctx) = ast::ancestor_exn::<CallExpr>(ctx.node()).resolve_context() {
        Some(ctx)
    } else {
        a.diagnostics.error(ctx.node(), "Context should be a single quoted string");
        None
    }
}

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

    use fall_tree::search;
    use fall_tree::search::ast;

    use ::test_util::parse_with_caret;

    #[test]
    fn test_resolve_no_args() {
        check_resolved("rule foo { <^eof> }", "Eof");
        check_resolved("rule foo { <^any> }", "Any");
        check_resolved("rule foo { <^commit> }", "Commit");
    }

    #[test]
    fn test_resolve_simple_args() {
        check_resolved("rule foo { <^not a> }", "Not(RefExpr@[16; 17))");
        check_resolved("rule foo { <^with_skip a b> }", "WithSkip(RefExpr@[22; 23), RefExpr@[24; 25))");
        check_resolved("rule foo { <^layer a b> }", "Layer(RefExpr@[18; 19), RefExpr@[20; 21))");
    }

    #[test]
    fn test_resolve_layer() {
        check_resolved("rule foo { <^enter 'ctx' a> }", "Enter(0, RefExpr@[24; 25))");
        check_resolved("rule foo { <^exit  'ctx' a> }", "Exit(0, RefExpr@[24; 25))");

        check_resolved("rule foo { <is_in 'ctx1'> <^enter 'ctx2' a> }", "Enter(1, RefExpr@[40; 41))");
        check_resolved("rule foo { <is_in 'ctx1'> <^exit  'ctx2' a> }", "Exit(1, RefExpr@[40; 41))");

        check_resolved(
            "rule foo { <enter 'ctx1' a> <enter 'ctx2' b> <^is_in 'ctx2'> }",
            "IsIn(1)"
        );

        check(
            r" rule foo { <^is_in foo>}",
            None,
            r#"[(foo, "Context should be a single quoted string")]"#,
        )
    }

    #[test]
    fn test_not() {
        resolve_call("rule foo { <^not bar>}", |c, _| {
            let c = c.unwrap();
            assert_eq!(format!("{:?}", c), "Not(RefExpr@[16; 19))");
        })
    }

    #[test]
    fn test_unresolved_call() {
        check(
            r"rule foo { <^abracadabra>}",
            None,
            r#"[(abracadabra, "Unresolved reference")]"#
        );
    }

    #[test]
    fn wrong_arity() {
        check(
            r" rule foo { <^eof foo> }",
            Some(CallKind::Eof),
            r#"[(<eof foo>, "Wrong number of arguments, expected 0, got 1")]"#
        );

        check(
            r" rule foo { <^any foo bar> }",
            Some(CallKind::Any),
            r#"[(<any foo bar>, "Wrong number of arguments, expected 0, got 2")]"#
        );

        check(
            r" rule foo { <^commit foo bar baz> }",
            Some(CallKind::Commit),
            r#"[(<commit foo bar baz>, "Wrong number of arguments, expected 0, got 3")]"#
        );

        check(
            r" rule foo { <^not> }",
            None,
            r#"[(<not>, "Wrong number of arguments, expected 1, got 0")]"#
        );
    }

    fn check(text: &str, kind: Option<CallKind>, diagnostics: &str) {
        resolve_call(text, |c, a| {
            assert_eq!(c, kind);
            assert_eq!(a.diagnostics.debug(a.file.node().text()), diagnostics);
        })
    }

    fn check_resolved(text: &str, kind: &str) {
        resolve_call(text, |c, a| {
            let c = c.unwrap();
            assert_eq!(format!("{:?}", c), kind);
            assert_eq!(a.diagnostics.debug(a.file.node().text()), "[]");
        })
    }

    fn resolve_call<F: FnOnce(Option<CallKind>, Analysis)>(text: &str, f: F) {
        let (file, caret) = parse_with_caret(&text);
        let call = {
            let leaf = search::find_leaf_at_offset(file.root(), caret)
                .left_biased().unwrap();
            ast::ancestor_exn(leaf)
        };
        let a = Analysis::new(::ast(&file));
        let c = a.resolve_call(call);
        f(c, a)
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// For the purpose of this example all unused code is allowed.
#![allow(dead_code)]

extern crate cgmath;
extern crate image;
extern crate winit;

#[macro_use]
extern crate vulkano;
#[macro_use]
extern crate vulkano_shader_derive;
extern crate vulkano_win;

use vulkano_win::VkSurfaceBuild;
use vulkano::sync::GpuFuture;

use std::sync::Arc;
use std::time::Duration;

fn main() {
    // The start of this example is exactly the same as `triangle`. You should read the
    // `triangle` example if you haven't done so yet.

    let extensions = vulkano_win::required_extensions();
    let instance = vulkano::instance::Instance::new(None, &extensions, &[]).expect("failed to create instance");

    let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
                            .next().expect("no device available");
    println!("Using device: {} (type: {:?})", physical.name(), physical.ty());

    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();

    let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
                                                   window.surface().is_supported(q).unwrap_or(false))
                                                .expect("couldn't find a graphical queue family");

    let device_ext = vulkano::device::DeviceExtensions {
        khr_swapchain: true,
        .. vulkano::device::DeviceExtensions::none()
    };
    let (device, mut queues) = vulkano::device::Device::new(physical, physical.supported_features(),
                                                            &device_ext, [(queue, 0.5)].iter().cloned())
                               .expect("failed to create device");
    let queue = queues.next().unwrap();

    let (swapchain, images) = {
        let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");

        let dimensions = caps.current_extent.unwrap_or([1280, 1024]);
        let usage = caps.supported_usage_flags;

        vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count,
                                           vulkano::format::B8G8R8A8Srgb, dimensions, 1,
                                           usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
                                           vulkano::swapchain::CompositeAlpha::Opaque,
                                           vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
    };

    #[derive(Debug, Clone)]
    struct Vertex { position: [f32; 2] }
    impl_vertex!(Vertex, position);

    let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[Vertex]>
                               ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(),
                                       Some(queue.family()), [
                                           Vertex { position: [-0.5, -0.5 ] },
                                           Vertex { position: [-0.5,  0.5 ] },
                                           Vertex { position: [ 0.5, -0.5 ] },
                                           Vertex { position: [ 0.5,  0.5 ] },
                                       ].iter().cloned()).expect("failed to create buffer");

    let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
    let fs = fs::Shader::load(device.clone()).expect("failed to create shader module");

    let renderpass = Arc::new(
        single_pass_renderpass!(device.clone(),
            attachments: {
                color: {
                    load: Clear,
                    store: Store,
                    format: swapchain.format(),
                    samples: 1,
                }
            },
            pass: {
                color: [color],
                depth_stencil: {}
            }
        ).unwrap()
    );

    let texture = vulkano::image::immutable::ImmutableImage::new(device.clone(), vulkano::image::Dimensions::Dim2d { width: 93, height: 93 },
                                                                 vulkano::format::R8G8B8A8Unorm, Some(queue.family())).unwrap();

    let pixel_buffer = {
        let image = image::load_from_memory_with_format(include_bytes!("image_img.png"),
                                                        image::ImageFormat::PNG).unwrap().to_rgba();
        let image_data = image.into_raw().clone();

        let image_data_chunks = image_data.chunks(4).map(|c| [c[0], c[1], c[2], c[3]]);

        // TODO: staging buffer instead
        vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[[u8; 4]]>
            ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(),
                        Some(queue.family()), image_data_chunks)
                        .expect("failed to create buffer")
    };

    let sampler = vulkano::sampler::Sampler::new(device.clone(), vulkano::sampler::Filter::Linear,
                                                 vulkano::sampler::Filter::Linear, vulkano::sampler::MipmapMode::Nearest,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 0.0, 1.0, 0.0, 0.0).unwrap();

    let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::start()
        .vertex_input_single_buffer::<Vertex>()
        .vertex_shader(vs.main_entry_point(), ())
        .triangle_strip()
        .viewports(std::iter::once(vulkano::pipeline::viewport::Viewport {
            origin: [0.0, 0.0],
            depth_range: 0.0 .. 1.0,
            dimensions: [images[0].dimensions()[0] as f32, images[0].dimensions()[1] as f32],
        }))
        .fragment_shader(fs.main_entry_point(), ())
        .render_pass(vulkano::framebuffer::Subpass::from(renderpass.clone(), 0).unwrap())
        .build(device.clone())
        .unwrap());

    let set = Arc::new(simple_descriptor_set!(pipeline.clone(), 0, {
        tex: (texture.clone(), sampler.clone())
    }));

    let framebuffers = images.iter().map(|image| {
        Arc::new(vulkano::framebuffer::Framebuffer::start(renderpass.clone())
            .add(image.clone()).unwrap().build().unwrap())
    }).collect::<Vec<_>>();

    let mut previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>;

    loop {
        previous_frame_end.cleanup_finished();

        let (image_num, future) = vulkano::swapchain::acquire_next_image(swapchain.clone(), None).unwrap();

        let cb = vulkano::command_buffer::AutoCommandBufferBuilder::new(device.clone(), queue.family())
            .unwrap()
            .copy_buffer_to_image(pixel_buffer.clone(), texture.clone())
            .unwrap()
            //.clear_color_image(&texture, [0.0, 1.0, 0.0, 1.0])
            .begin_render_pass(
                framebuffers[image_num].clone(), false,
                vec![[0.0, 0.0, 1.0, 1.0].into()]).unwrap()
            .draw(pipeline.clone(), vulkano::command_buffer::DynamicState::none(), vertex_buffer.clone(),
                  set.clone(), ()).unwrap()
            .end_render_pass().unwrap()
            .build().unwrap();

        let future = previous_frame_end.join(future)
            .then_execute(queue.clone(), cb).unwrap()
            .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
            .then_signal_fence_and_flush().unwrap();
        previous_frame_end = Box::new(future) as Box<_>;

        let mut done = false;
        events_loop.poll_events(|ev| {
            match ev {
                winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => done = true,
                _ => ()
            }
        });
        if done { return; }
    }
}

mod vs {
    #[derive(VulkanoShader)]
    #[ty = "vertex"]
    #[src = "
#version 450

layout(location = 0) in vec2 position;
layout(location = 0) out vec2 tex_coords;

void main() {
    gl_Position = vec4(position, 0.0, 1.0);
    tex_coords = position + vec2(0.5);
}
"]
    struct Dummy;
}

mod fs {
    #[derive(VulkanoShader)]
    #[ty = "fragment"]
    #[src = "
#version 450

layout(location = 0) in vec2 tex_coords;
layout(location = 0) out vec4 f_color;

layout(set = 0, binding = 0) uniform sampler2D tex;

void main() {
    f_color = texture(tex, tex_coords);
}
"]
    struct Dummy;
}
<commit_msg>Fix #599<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// For the purpose of this example all unused code is allowed.
#![allow(dead_code)]

extern crate cgmath;
extern crate image;
extern crate winit;

#[macro_use]
extern crate vulkano;
#[macro_use]
extern crate vulkano_shader_derive;
extern crate vulkano_win;

use vulkano_win::VkSurfaceBuild;
use vulkano::sync::GpuFuture;

use std::sync::Arc;
use std::time::Duration;

fn main() {
    // The start of this example is exactly the same as `triangle`. You should read the
    // `triangle` example if you haven't done so yet.

    let extensions = vulkano_win::required_extensions();
    let instance = vulkano::instance::Instance::new(None, &extensions, &[]).expect("failed to create instance");

    let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
                            .next().expect("no device available");
    println!("Using device: {} (type: {:?})", physical.name(), physical.ty());

    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();

    let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
                                                   window.surface().is_supported(q).unwrap_or(false))
                                                .expect("couldn't find a graphical queue family");

    let device_ext = vulkano::device::DeviceExtensions {
        khr_swapchain: true,
        .. vulkano::device::DeviceExtensions::none()
    };
    let (device, mut queues) = vulkano::device::Device::new(physical, physical.supported_features(),
                                                            &device_ext, [(queue, 0.5)].iter().cloned())
                               .expect("failed to create device");
    let queue = queues.next().unwrap();

    let (swapchain, images) = {
        let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");

        let dimensions = caps.current_extent.unwrap_or([1280, 1024]);
        let usage = caps.supported_usage_flags;

        vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count,
                                           vulkano::format::B8G8R8A8Srgb, dimensions, 1,
                                           usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
                                           vulkano::swapchain::CompositeAlpha::Opaque,
                                           vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
    };

    #[derive(Debug, Clone)]
    struct Vertex { position: [f32; 2] }
    impl_vertex!(Vertex, position);

    let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[Vertex]>
                               ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(),
                                       Some(queue.family()), [
                                           Vertex { position: [-0.5, -0.5 ] },
                                           Vertex { position: [-0.5,  0.5 ] },
                                           Vertex { position: [ 0.5, -0.5 ] },
                                           Vertex { position: [ 0.5,  0.5 ] },
                                       ].iter().cloned()).expect("failed to create buffer");

    let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
    let fs = fs::Shader::load(device.clone()).expect("failed to create shader module");

    let renderpass = Arc::new(
        single_pass_renderpass!(device.clone(),
            attachments: {
                color: {
                    load: Clear,
                    store: Store,
                    format: swapchain.format(),
                    samples: 1,
                }
            },
            pass: {
                color: [color],
                depth_stencil: {}
            }
        ).unwrap()
    );

    let texture = vulkano::image::immutable::ImmutableImage::new(device.clone(), vulkano::image::Dimensions::Dim2d { width: 93, height: 93 },
                                                                 vulkano::format::R8G8B8A8Srgb, Some(queue.family())).unwrap();

    let pixel_buffer = {
        let image = image::load_from_memory_with_format(include_bytes!("image_img.png"),
                                                        image::ImageFormat::PNG).unwrap().to_rgba();
        let image_data = image.into_raw().clone();

        let image_data_chunks = image_data.chunks(4).map(|c| [c[0], c[1], c[2], c[3]]);

        // TODO: staging buffer instead
        vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[[u8; 4]]>
            ::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(),
                        Some(queue.family()), image_data_chunks)
                        .expect("failed to create buffer")
    };

    let sampler = vulkano::sampler::Sampler::new(device.clone(), vulkano::sampler::Filter::Linear,
                                                 vulkano::sampler::Filter::Linear, vulkano::sampler::MipmapMode::Nearest,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 vulkano::sampler::SamplerAddressMode::Repeat,
                                                 0.0, 1.0, 0.0, 0.0).unwrap();

    let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::start()
        .vertex_input_single_buffer::<Vertex>()
        .vertex_shader(vs.main_entry_point(), ())
        .triangle_strip()
        .viewports(std::iter::once(vulkano::pipeline::viewport::Viewport {
            origin: [0.0, 0.0],
            depth_range: 0.0 .. 1.0,
            dimensions: [images[0].dimensions()[0] as f32, images[0].dimensions()[1] as f32],
        }))
        .fragment_shader(fs.main_entry_point(), ())
        .render_pass(vulkano::framebuffer::Subpass::from(renderpass.clone(), 0).unwrap())
        .build(device.clone())
        .unwrap());

    let set = Arc::new(simple_descriptor_set!(pipeline.clone(), 0, {
        tex: (texture.clone(), sampler.clone())
    }));

    let framebuffers = images.iter().map(|image| {
        Arc::new(vulkano::framebuffer::Framebuffer::start(renderpass.clone())
            .add(image.clone()).unwrap().build().unwrap())
    }).collect::<Vec<_>>();

    let mut previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>;

    loop {
        previous_frame_end.cleanup_finished();

        let (image_num, future) = vulkano::swapchain::acquire_next_image(swapchain.clone(), None).unwrap();

        let cb = vulkano::command_buffer::AutoCommandBufferBuilder::new(device.clone(), queue.family())
            .unwrap()
            .copy_buffer_to_image(pixel_buffer.clone(), texture.clone())
            .unwrap()
            //.clear_color_image(&texture, [0.0, 1.0, 0.0, 1.0])
            .begin_render_pass(
                framebuffers[image_num].clone(), false,
                vec![[0.0, 0.0, 1.0, 1.0].into()]).unwrap()
            .draw(pipeline.clone(), vulkano::command_buffer::DynamicState::none(), vertex_buffer.clone(),
                  set.clone(), ()).unwrap()
            .end_render_pass().unwrap()
            .build().unwrap();

        let future = previous_frame_end.join(future)
            .then_execute(queue.clone(), cb).unwrap()
            .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
            .then_signal_fence_and_flush().unwrap();
        previous_frame_end = Box::new(future) as Box<_>;

        let mut done = false;
        events_loop.poll_events(|ev| {
            match ev {
                winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => done = true,
                _ => ()
            }
        });
        if done { return; }
    }
}

mod vs {
    #[derive(VulkanoShader)]
    #[ty = "vertex"]
    #[src = "
#version 450

layout(location = 0) in vec2 position;
layout(location = 0) out vec2 tex_coords;

void main() {
    gl_Position = vec4(position, 0.0, 1.0);
    tex_coords = position + vec2(0.5);
}
"]
    struct Dummy;
}

mod fs {
    #[derive(VulkanoShader)]
    #[ty = "fragment"]
    #[src = "
#version 450

layout(location = 0) in vec2 tex_coords;
layout(location = 0) out vec4 f_color;

layout(set = 0, binding = 0) uniform sampler2D tex;

void main() {
    f_color = texture(tex, tex_coords);
}
"]
    struct Dummy;
}
<|endoftext|>


<commit_before>use super::*;
use super::len::ParallelLen;
use super::state::*;

pub struct Weight<M> {
    base: M,
    weight: f64,
}

impl<M> Weight<M> {
    pub fn new(base: M, weight: f64) -> Weight<M> {
        Weight { base: base, weight: weight }
    }
}

impl<M> ParallelIterator for Weight<M>
    where M: ParallelIterator,
{
    type Item = M::Item;
    type Shared = WeightShared<M>;
    type State = WeightState<M>;

    fn drive<C: Consumer<Item=Self::Item>>(self, consumer: C) -> C::Result {
        unimplemented!()
    }

    fn state(self) -> (Self::Shared, Self::State) {
        let (base_shared, base_state) = self.base.state();
        (WeightShared { base: base_shared, weight: self.weight },
         WeightState { base: base_state })
    }
}

unsafe impl<M: BoundedParallelIterator> BoundedParallelIterator for Weight<M> {
    fn upper_bound(&mut self) -> usize {
        self.base.upper_bound()
    }
}

unsafe impl<M: ExactParallelIterator> ExactParallelIterator for Weight<M> {
    fn len(&mut self) -> usize {
        self.base.len()
    }
}

pub struct WeightState<M>
    where M: ParallelIterator
{
    base: M::State,
}

pub struct WeightShared<M>
    where M: ParallelIterator
{
    base: M::Shared,
    weight: f64,
}

unsafe impl<M> ParallelIteratorState for WeightState<M>
    where M: ParallelIterator,
{
    type Item = M::Item;
    type Shared = WeightShared<M>;

    fn len(&mut self, shared: &Self::Shared) -> ParallelLen {
        let mut l = self.base.len(&shared.base);
        l.cost *= shared.weight;
        l
    }

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

    fn next(&mut self, shared: &Self::Shared) -> Option<Self::Item> {
        self.base.next(&shared.base)
    }
}
<commit_msg>implement Producer for Weight<commit_after>use super::*;
use super::len::ParallelLen;
use super::state::*;

pub struct Weight<M> {
    base: M,
    weight: f64,
}

impl<M> Weight<M> {
    pub fn new(base: M, weight: f64) -> Weight<M> {
        Weight { base: base, weight: weight }
    }
}

impl<M> ParallelIterator for Weight<M>
    where M: ParallelIterator,
{
    type Item = M::Item;
    type Shared = WeightShared<M>;
    type State = WeightState<M>;

    fn drive<C: Consumer<Item=Self::Item>>(self, consumer: C) -> C::Result {
        unimplemented!()
    }

    fn state(self) -> (Self::Shared, Self::State) {
        let (base_shared, base_state) = self.base.state();
        (WeightShared { base: base_shared, weight: self.weight },
         WeightState { base: base_state })
    }
}

unsafe impl<M: BoundedParallelIterator> BoundedParallelIterator for Weight<M> {
    fn upper_bound(&mut self) -> usize {
        self.base.upper_bound()
    }
}

unsafe impl<M: ExactParallelIterator> ExactParallelIterator for Weight<M> {
    fn len(&mut self) -> usize {
        self.base.len()
    }
}

pub struct WeightState<M>
    where M: ParallelIterator
{
    base: M::State,
}

pub struct WeightShared<M>
    where M: ParallelIterator
{
    base: M::Shared,
    weight: f64,
}

unsafe impl<M> ParallelIteratorState for WeightState<M>
    where M: ParallelIterator,
{
    type Item = M::Item;
    type Shared = WeightShared<M>;

    fn len(&mut self, shared: &Self::Shared) -> ParallelLen {
        let mut l = self.base.len(&shared.base);
        l.cost *= shared.weight;
        l
    }

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

    fn next(&mut self, shared: &Self::Shared) -> Option<Self::Item> {
        self.base.next(&shared.base)
    }
}

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

pub struct WeightProducer<P: Producer> {
    base: P
}

impl<P: Producer> Producer for WeightProducer<P>
{
    type Item = P::Item;
    type Shared = P::Shared;
    type SeqState = P::SeqState;

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

    unsafe fn start(&mut self, shared: &P::Shared) -> P::SeqState {
        self.base.start(shared)
    }

    unsafe fn produce(&mut self,
                      shared: &P::Shared,
                      state: &mut P::SeqState)
                      -> P::Item
    {
        self.base.produce(shared, state)
    }

    unsafe fn complete(self,
                       shared: &P::Shared,
                       state: P::SeqState) {
        self.base.complete(shared, state)
    }
}
<|endoftext|>


<commit_before>use rustc_hir::intravisit;
use rustc_hir::{self, Body, FnDecl, HirId, HirIdSet, ItemKind, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
use rustc_target::abi::LayoutOf;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};

use crate::utils::span_lint;

#[derive(Copy, Clone)]
pub struct BoxedLocal {
    pub too_large_for_stack: u64,
}

declare_clippy_lint! {
    /// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would
    /// work fine.
    ///
    /// **Why is this bad?** This is an unnecessary allocation, and bad for
    /// performance. It is only necessary to allocate if you wish to move the box
    /// into something.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// # fn foo(bar: usize) {}
    ///
    /// // Bad
    /// let x = Box::new(1);
    /// foo(*x);
    /// println!("{}", *x);
    ///
    /// // Good
    /// let x = 1;
    /// foo(x);
    /// println!("{}", x);
    /// ```
    pub BOXED_LOCAL,
    perf,
    "using `Box<T>` where unnecessary"
}

fn is_non_trait_box(ty: Ty<'_>) -> bool {
    ty.is_box() && !ty.boxed_ty().is_trait()
}

struct EscapeDelegate<'a, 'tcx> {
    cx: &'a LateContext<'tcx>,
    set: HirIdSet,
    too_large_for_stack: u64,
}

impl_lint_pass!(BoxedLocal => [BOXED_LOCAL]);

impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
    fn check_fn(
        &mut self,
        cx: &LateContext<'tcx>,
        _: intravisit::FnKind<'tcx>,
        _: &'tcx FnDecl<'_>,
        body: &'tcx Body<'_>,
        _: Span,
        hir_id: HirId,
    ) {
        // If the method is an impl for a trait, don't warn.
        let parent_id = cx.tcx.hir().get_parent_item(hir_id);
        let parent_node = cx.tcx.hir().find(parent_id);

        if let Some(Node::Item(item)) = parent_node {
            if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
                return;
            }
        }

        let mut v = EscapeDelegate {
            cx,
            set: HirIdSet::default(),
            too_large_for_stack: self.too_large_for_stack,
        };

        let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
        cx.tcx.infer_ctxt().enter(|infcx| {
            ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
        });

        for node in v.set {
            span_lint(
                cx,
                BOXED_LOCAL,
                cx.tcx.hir().span(node),
                "local variable doesn't need to be boxed here",
            );
        }
    }
}

// TODO: Replace with Map::is_argument(..) when it's fixed
fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
    match map.find(id) {
        Some(Node::Binding(_)) => (),
        _ => return false,
    }

    matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_)))
}

impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, mode: ConsumeMode) {
        if cmt.place.projections.is_empty() {
            if let PlaceBase::Local(lid) = cmt.place.base {
                if let ConsumeMode::Move = mode {
                    // moved out or in. clearly can't be localized
                    self.set.remove(&lid);
                }
                let map = &self.cx.tcx.hir();
                if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
                    if self.set.contains(&lid) {
                        // let y = x where x is known
                        // remove x, insert y
                        self.set.insert(cmt.hir_id);
                        self.set.remove(&lid);
                    }
                }
            }
        }
    }

    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: ty::BorrowKind) {
        if cmt.place.projections.is_empty() {
            if let PlaceBase::Local(lid) = cmt.place.base {
                self.set.remove(&lid);
            }
        }
    }

    fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>) {
        if cmt.place.projections.is_empty() {
            let map = &self.cx.tcx.hir();
            if is_argument(*map, cmt.hir_id) {
                // Skip closure arguments
                let parent_id = map.get_parent_node(cmt.hir_id);
                if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
                    return;
                }

                if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {
                    self.set.insert(cmt.hir_id);
                }
                return;
            }
        }
    }
}

impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
    fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
        // Large types need to be boxed to avoid stack overflows.
        if ty.is_box() {
            self.cx.layout_of(ty.boxed_ty()).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
        } else {
            false
        }
    }
}
<commit_msg>clippy_lints: Do not warn against Box parameter in C FFI<commit_after>use rustc_hir::intravisit;
use rustc_hir::{self, Body, FnDecl, HirId, HirIdSet, ItemKind, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
use rustc_target::abi::LayoutOf;
use rustc_target::spec::abi::Abi;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};

use crate::utils::span_lint;

#[derive(Copy, Clone)]
pub struct BoxedLocal {
    pub too_large_for_stack: u64,
}

declare_clippy_lint! {
    /// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would
    /// work fine.
    ///
    /// **Why is this bad?** This is an unnecessary allocation, and bad for
    /// performance. It is only necessary to allocate if you wish to move the box
    /// into something.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// # fn foo(bar: usize) {}
    ///
    /// // Bad
    /// let x = Box::new(1);
    /// foo(*x);
    /// println!("{}", *x);
    ///
    /// // Good
    /// let x = 1;
    /// foo(x);
    /// println!("{}", x);
    /// ```
    pub BOXED_LOCAL,
    perf,
    "using `Box<T>` where unnecessary"
}

fn is_non_trait_box(ty: Ty<'_>) -> bool {
    ty.is_box() && !ty.boxed_ty().is_trait()
}

struct EscapeDelegate<'a, 'tcx> {
    cx: &'a LateContext<'tcx>,
    set: HirIdSet,
    too_large_for_stack: u64,
}

impl_lint_pass!(BoxedLocal => [BOXED_LOCAL]);

impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
    fn check_fn(
        &mut self,
        cx: &LateContext<'tcx>,
        fn_kind: intravisit::FnKind<'tcx>,
        _: &'tcx FnDecl<'_>,
        body: &'tcx Body<'_>,
        _: Span,
        hir_id: HirId,
    ) {
        if let Some(header) = fn_kind.header() {
            if header.abi == Abi::Cdecl {
                return;
            }
        }

        // If the method is an impl for a trait, don't warn.
        let parent_id = cx.tcx.hir().get_parent_item(hir_id);
        let parent_node = cx.tcx.hir().find(parent_id);

        if let Some(Node::Item(item)) = parent_node {
            if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
                return;
            }
        }

        let mut v = EscapeDelegate {
            cx,
            set: HirIdSet::default(),
            too_large_for_stack: self.too_large_for_stack,
        };

        let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
        cx.tcx.infer_ctxt().enter(|infcx| {
            ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
        });

        for node in v.set {
            span_lint(
                cx,
                BOXED_LOCAL,
                cx.tcx.hir().span(node),
                "local variable doesn't need to be boxed here",
            );
        }
    }
}

// TODO: Replace with Map::is_argument(..) when it's fixed
fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
    match map.find(id) {
        Some(Node::Binding(_)) => (),
        _ => return false,
    }

    matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_)))
}

impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, mode: ConsumeMode) {
        if cmt.place.projections.is_empty() {
            if let PlaceBase::Local(lid) = cmt.place.base {
                if let ConsumeMode::Move = mode {
                    // moved out or in. clearly can't be localized
                    self.set.remove(&lid);
                }
                let map = &self.cx.tcx.hir();
                if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
                    if self.set.contains(&lid) {
                        // let y = x where x is known
                        // remove x, insert y
                        self.set.insert(cmt.hir_id);
                        self.set.remove(&lid);
                    }
                }
            }
        }
    }

    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: ty::BorrowKind) {
        if cmt.place.projections.is_empty() {
            if let PlaceBase::Local(lid) = cmt.place.base {
                self.set.remove(&lid);
            }
        }
    }

    fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>) {
        if cmt.place.projections.is_empty() {
            let map = &self.cx.tcx.hir();
            if is_argument(*map, cmt.hir_id) {
                // Skip closure arguments
                let parent_id = map.get_parent_node(cmt.hir_id);
                if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
                    return;
                }

                if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {
                    self.set.insert(cmt.hir_id);
                }
                return;
            }
        }
    }
}

impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
    fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
        // Large types need to be boxed to avoid stack overflows.
        if ty.is_box() {
            self.cx.layout_of(ty.boxed_ty()).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
        } else {
            false
        }
    }
}
<|endoftext|>