<commit_before>extern crate translator;

extern crate piston;
extern crate piston_window;

use piston::event_loop::{Events, EventLoop};

fn main() {
    let window: piston_window::PistonWindow = piston_window::WindowSettings::new("Hello Conrod", [800, 600])
                                                  .exit_on_esc(true)
                                                  .vsync(true)
                                                  .build()
                                                  .unwrap();

    for event in window.ups(60) {
    }
}
<commit_msg>Use (more)<commit_after>extern crate translator;

extern crate piston;
extern crate piston_window;

use piston_window::{PistonWindow, WindowSettings};
use piston::event_loop::{Events, EventLoop};

fn main() {
    let window: PistonWindow = WindowSettings::new("Hello Conrod", [800, 600])
                                                  .exit_on_esc(true)
                                                  .vsync(true)
                                                  .build()
                                                  .unwrap();

    for event in window.ups(60) {
    }
}
<|endoftext|>


<commit_before>use nom::{alphanumeric, digit, eof, is_alphanumeric, line_ending, multispace};
use nom::{IResult, Err, ErrorKind, Needed};
use std::str;
use std::str::FromStr;

use column::{Column, FunctionExpression};
use table::Table;

#[derive(Clone, Debug, Hash, PartialEq)]
pub enum Operator {
    Not,
    And,
    Or,
    Like,
    NotLike,
    Equal,
    NotEqual,
    Greater,
    GreaterOrEqual,
    Less,
    LessOrEqual,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum FieldExpression {
    All,
    Seq(Vec<Column>),
}

impl Default for FieldExpression {
    fn default() -> FieldExpression {
        FieldExpression::All
    }
}

#[inline]
pub fn is_sql_identifier(chr: u8) -> bool {
    // XXX(malte): dot should not be in here once we have proper alias handling
    is_alphanumeric(chr) || chr == '_' as u8
}

#[inline]
pub fn is_fp_number(chr: u8) -> bool {
    is_alphanumeric(chr) || chr == '.' as u8
}

/// Parses a SQL identifier (alphanumeric and "_").
named!(pub fp_number<&[u8], &[u8]>,
// f64::from_str(&format!("{}.{}", integral, fractional)).unwrap()
//      integral: map_res!(take_while1!(is_digit), str::from_utf8) ~
//      fractional: map_res!(take_while!(is_digit), str::from_utf8),
    take_while1!(is_fp_number)
);

named!(pub column_function<&[u8], FunctionExpression>,
    alt_complete!(
        chain!(
            caseless_tag!("count") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Count(columns)
            }
        )
    |   chain!(
            caseless_tag!("sum") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Sum(columns)
            }
        )
    |   chain!(
            caseless_tag!("avg") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Avg(columns)
            }
        )
    |   chain!(
            caseless_tag!("max") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Max(columns)
            }
        )
    |   chain!(
            caseless_tag!("min") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Min(columns)
            }
        )
    |   chain!(
            caseless_tag!("group_concat") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::GroupConcat(columns)
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function ~
            alias: opt!(chain!(
                multispace ~
                caseless_tag!("as") ~
                multispace ~
                alias: map_res!(sql_identifier, str::from_utf8),
                || { alias }
            )),
            || {
                Column {
                    name: match alias {
                        Some(a) => String::from(a),
                        None => String::from("anon_fn"),
                    },
                    table: None,
                    function: Some(function),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8),
            || {
                Column {
                    name: String::from(column),
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL identifier (alphanumeric and "_").
named!(pub sql_identifier<&[u8], &[u8]>,
    take_while1!(is_sql_identifier)
);

/// Parse an unsigned integer.
named!(pub unsigned_number<&[u8], u64>,
    map_res!(
        map_res!(digit, str::from_utf8),
        FromStr::from_str
    )
);

/// Parse a terminator that ends a SQL statement.
named!(pub statement_terminator,
    delimited!(opt!(multispace),
               alt_complete!(tag!(";") | line_ending | eof),
               opt!(multispace)
    )
);

/// Parse binary comparison operators
named!(pub binary_comparison_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("not_like"), |_| Operator::NotLike)
         | map!(caseless_tag!("like"), |_| Operator::Like)
         | map!(caseless_tag!("<>"), |_| Operator::NotEqual)
         | map!(caseless_tag!(">="), |_| Operator::GreaterOrEqual)
         | map!(caseless_tag!("<="), |_| Operator::LessOrEqual)
         | map!(caseless_tag!("="), |_| Operator::Equal)
         | map!(caseless_tag!("<"), |_| Operator::Less)
         | map!(caseless_tag!(">"), |_| Operator::Greater)
    )
);

/// Parse logical operators
named!(pub binary_logical_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("and"), |_| Operator::And)
         | map!(caseless_tag!("or"), |_| Operator::Or)
    )
);

/// Parse unary comparison operators
named!(pub unary_comparison_operator<&[u8], &str>,
    map_res!(
        alt_complete!(
               tag_s!(b"ISNULL")
             | tag_s!(b"NOT")
             | tag_s!(b"-") // ??? (number neg)
        ),
        str::from_utf8
    )
);

/// Parse unary comparison operators
named!(pub unary_negation_operator<&[u8], Operator>,
    alt_complete!(
          map!(caseless_tag!("not"), |_| Operator::Not)
        | map!(caseless_tag!("!"), |_| Operator::Not)
    )
);

/// Parse rule for a comma-separated list.
named!(pub field_list<&[u8], Vec<Column> >,
       many0!(
           chain!(
               fieldname: column_identifier ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       ||{}
                   ))
               ),
               || { fieldname }
           )
       )
);

/// Parse list of columns/fields.
/// XXX(malte): add support for named table notation
named!(pub field_expr<&[u8], FieldExpression>,
       alt_complete!(
           tag!("*") => { |_| FieldExpression::All }
         | map!(field_list, |v| FieldExpression::Seq(v))
       )
);

/// Parse list of table names.
/// XXX(malte): add support for aliases
named!(pub table_list<&[u8], Vec<Table> >,
       many0!(
           chain!(
               table: table_reference ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       || {}
                   ))
               ),
               || { table }
           )
       )
);

/// Parse a list of values (e.g., for INSERT syntax).
/// XXX(malte): proper value type
named!(pub value_list<&[u8], Vec<&str> >,
       many0!(
           map_res!(
               chain!(
                   val: alt_complete!(
                         tag_s!(b"?")
                       | tag_s!(b"CURRENT_TIMESTAMP")
                       | delimited!(tag!("'"), alphanumeric, tag!("'"))
                       | fp_number
                   ) ~
                   opt!(
                       complete!(chain!(
                           multispace? ~
                           tag!(",") ~
                           multispace?,
                           ||{}
                       ))
                   ),
                   || { val }
               ),
               str::from_utf8
           )
       )
);

/// Parse a reference to a named table
/// XXX(malte): add support for schema.table notation
named!(pub table_reference<&[u8], Table>,
    chain!(
        table: map_res!(sql_identifier, str::from_utf8) ~
        alias: opt!(
            complete!(chain!(
                multispace ~
                caseless_tag!("as") ~
                multispace ~
                alias: map_res!(sql_identifier, str::from_utf8),
                || { String::from(alias) }
            ))
        ),
        || {
            Table {
                name: String::from(table),
                alias: alias,
            }
        }
    )
);

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

    #[test]
    fn sql_identifiers() {
        let id1 = b"foo";
        let id2 = b"f_o_o";
        let id3 = b"foo12";
        let id4 = b":fo oo";

        assert!(sql_identifier(id1).is_done());
        assert!(sql_identifier(id2).is_done());
        assert!(sql_identifier(id3).is_done());
        assert!(sql_identifier(id4).is_err());
    }

    #[test]
    fn simple_column_function() {
        let qs = b"max(addr_id)";

        let res = column_identifier(qs);
        let expected_fields = FieldExpression::Seq(vec![Column::from("addr_id")]);
        let expected_fn = Some(FunctionExpression::Max(expected_fields));
        let expected = Column {
            name: String::from("anon_fn"),
            table: None,
            function: expected_fn,
        };
        assert_eq!(res.unwrap().1, expected);
    }
}
<commit_msg>Fix comment<commit_after>use nom::{alphanumeric, digit, eof, is_alphanumeric, line_ending, multispace};
use nom::{IResult, Err, ErrorKind, Needed};
use std::str;
use std::str::FromStr;

use column::{Column, FunctionExpression};
use table::Table;

#[derive(Clone, Debug, Hash, PartialEq)]
pub enum Operator {
    Not,
    And,
    Or,
    Like,
    NotLike,
    Equal,
    NotEqual,
    Greater,
    GreaterOrEqual,
    Less,
    LessOrEqual,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum FieldExpression {
    All,
    Seq(Vec<Column>),
}

impl Default for FieldExpression {
    fn default() -> FieldExpression {
        FieldExpression::All
    }
}

#[inline]
pub fn is_sql_identifier(chr: u8) -> bool {
    // XXX(malte): dot should not be in here once we have proper alias handling
    is_alphanumeric(chr) || chr == '_' as u8
}

#[inline]
pub fn is_fp_number(chr: u8) -> bool {
    is_alphanumeric(chr) || chr == '.' as u8
}

/// Parses a floating point number (very badly).
named!(pub fp_number<&[u8], &[u8]>,
// f64::from_str(&format!("{}.{}", integral, fractional)).unwrap()
//      integral: map_res!(take_while1!(is_digit), str::from_utf8) ~
//      fractional: map_res!(take_while!(is_digit), str::from_utf8),
    take_while1!(is_fp_number)
);

named!(pub column_function<&[u8], FunctionExpression>,
    alt_complete!(
        chain!(
            caseless_tag!("count") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Count(columns)
            }
        )
    |   chain!(
            caseless_tag!("sum") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Sum(columns)
            }
        )
    |   chain!(
            caseless_tag!("avg") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Avg(columns)
            }
        )
    |   chain!(
            caseless_tag!("max") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Max(columns)
            }
        )
    |   chain!(
            caseless_tag!("min") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::Min(columns)
            }
        )
    |   chain!(
            caseless_tag!("group_concat") ~
            columns: delimited!(tag!("("), field_expr, tag!(")")),
            || {
                FunctionExpression::GroupConcat(columns)
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function ~
            alias: opt!(chain!(
                multispace ~
                caseless_tag!("as") ~
                multispace ~
                alias: map_res!(sql_identifier, str::from_utf8),
                || { alias }
            )),
            || {
                Column {
                    name: match alias {
                        Some(a) => String::from(a),
                        None => String::from("anon_fn"),
                    },
                    table: None,
                    function: Some(function),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8),
            || {
                Column {
                    name: String::from(column),
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL identifier (alphanumeric and "_").
named!(pub sql_identifier<&[u8], &[u8]>,
    take_while1!(is_sql_identifier)
);

/// Parse an unsigned integer.
named!(pub unsigned_number<&[u8], u64>,
    map_res!(
        map_res!(digit, str::from_utf8),
        FromStr::from_str
    )
);

/// Parse a terminator that ends a SQL statement.
named!(pub statement_terminator,
    delimited!(opt!(multispace),
               alt_complete!(tag!(";") | line_ending | eof),
               opt!(multispace)
    )
);

/// Parse binary comparison operators
named!(pub binary_comparison_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("not_like"), |_| Operator::NotLike)
         | map!(caseless_tag!("like"), |_| Operator::Like)
         | map!(caseless_tag!("<>"), |_| Operator::NotEqual)
         | map!(caseless_tag!(">="), |_| Operator::GreaterOrEqual)
         | map!(caseless_tag!("<="), |_| Operator::LessOrEqual)
         | map!(caseless_tag!("="), |_| Operator::Equal)
         | map!(caseless_tag!("<"), |_| Operator::Less)
         | map!(caseless_tag!(">"), |_| Operator::Greater)
    )
);

/// Parse logical operators
named!(pub binary_logical_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("and"), |_| Operator::And)
         | map!(caseless_tag!("or"), |_| Operator::Or)
    )
);

/// Parse unary comparison operators
named!(pub unary_comparison_operator<&[u8], &str>,
    map_res!(
        alt_complete!(
               tag_s!(b"ISNULL")
             | tag_s!(b"NOT")
             | tag_s!(b"-") // ??? (number neg)
        ),
        str::from_utf8
    )
);

/// Parse unary comparison operators
named!(pub unary_negation_operator<&[u8], Operator>,
    alt_complete!(
          map!(caseless_tag!("not"), |_| Operator::Not)
        | map!(caseless_tag!("!"), |_| Operator::Not)
    )
);

/// Parse rule for a comma-separated list.
named!(pub field_list<&[u8], Vec<Column> >,
       many0!(
           chain!(
               fieldname: column_identifier ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       ||{}
                   ))
               ),
               || { fieldname }
           )
       )
);

/// Parse list of columns/fields.
/// XXX(malte): add support for named table notation
named!(pub field_expr<&[u8], FieldExpression>,
       alt_complete!(
           tag!("*") => { |_| FieldExpression::All }
         | map!(field_list, |v| FieldExpression::Seq(v))
       )
);

/// Parse list of table names.
/// XXX(malte): add support for aliases
named!(pub table_list<&[u8], Vec<Table> >,
       many0!(
           chain!(
               table: table_reference ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       || {}
                   ))
               ),
               || { table }
           )
       )
);

/// Parse a list of values (e.g., for INSERT syntax).
/// XXX(malte): proper value type
named!(pub value_list<&[u8], Vec<&str> >,
       many0!(
           map_res!(
               chain!(
                   val: alt_complete!(
                         tag_s!(b"?")
                       | tag_s!(b"CURRENT_TIMESTAMP")
                       | delimited!(tag!("'"), alphanumeric, tag!("'"))
                       | fp_number
                   ) ~
                   opt!(
                       complete!(chain!(
                           multispace? ~
                           tag!(",") ~
                           multispace?,
                           ||{}
                       ))
                   ),
                   || { val }
               ),
               str::from_utf8
           )
       )
);

/// Parse a reference to a named table
/// XXX(malte): add support for schema.table notation
named!(pub table_reference<&[u8], Table>,
    chain!(
        table: map_res!(sql_identifier, str::from_utf8) ~
        alias: opt!(
            complete!(chain!(
                multispace ~
                caseless_tag!("as") ~
                multispace ~
                alias: map_res!(sql_identifier, str::from_utf8),
                || { String::from(alias) }
            ))
        ),
        || {
            Table {
                name: String::from(table),
                alias: alias,
            }
        }
    )
);

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

    #[test]
    fn sql_identifiers() {
        let id1 = b"foo";
        let id2 = b"f_o_o";
        let id3 = b"foo12";
        let id4 = b":fo oo";

        assert!(sql_identifier(id1).is_done());
        assert!(sql_identifier(id2).is_done());
        assert!(sql_identifier(id3).is_done());
        assert!(sql_identifier(id4).is_err());
    }

    #[test]
    fn simple_column_function() {
        let qs = b"max(addr_id)";

        let res = column_identifier(qs);
        let expected_fields = FieldExpression::Seq(vec![Column::from("addr_id")]);
        let expected_fn = Some(FunctionExpression::Max(expected_fields));
        let expected = Column {
            name: String::from("anon_fn"),
            table: None,
            function: expected_fn,
        };
        assert_eq!(res.unwrap().1, expected);
    }
}
<|endoftext|>


<commit_before>use nom::{alphanumeric, digit, eof, is_alphanumeric, line_ending, multispace};
use nom::{IResult, Err, ErrorKind, Needed};
use std::fmt::{self, Display};
use std::str;
use std::str::FromStr;

use column::{Column, FunctionExpression};
use keywords::sql_keyword;
use table::Table;

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum SqlType {
    Char(u16),
    Varchar(u16),
    Int(u16),
    Bigint(u16),
    Tinyint(u16),
    Blob,
    Longblob,
    Mediumblob,
    Tinyblob,
    Double,
    Float,
    Real,
    Tinytext,
    Mediumtext,
    Text,
    Date,
    Timestamp,
    Varbinary(u16),
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum Literal {
    Null,
    Integer(i64),
    String(String),
    Blob(Vec<u8>),
    CurrentTime,
    CurrentDate,
    CurrentTimestamp,
}

#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
pub enum Operator {
    Not,
    And,
    Or,
    Like,
    NotLike,
    Equal,
    NotEqual,
    Greater,
    GreaterOrEqual,
    Less,
    LessOrEqual,
}

impl Display for Operator {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let op = match *self {
            Operator::Not => "not",
            Operator::And => "and",
            Operator::Or => "or",
            Operator::Like => "like",
            Operator::NotLike => "not_like",
            Operator::Equal => "=",
            Operator::NotEqual => "!=",
            Operator::Greater => ">",
            Operator::GreaterOrEqual => ">=",
            Operator::Less => "<",
            Operator::LessOrEqual => "<=",
        };
        write!(f, "{}", op)
    }
}

#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
pub enum TableKey {
    PrimaryKey(Vec<Column>),
    UniqueKey(Option<String>, Vec<Column>),
    FulltextKey(Option<String>, Vec<Column>),
    Key(String, Vec<Column>),
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FieldExpression {
    All,
    AllInTable(String),
    Col(Column),
}

impl Display for FieldExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FieldExpression::All => write!(f, "*"),
            FieldExpression::AllInTable(ref table) => write!(f, "{}.*", table),
            FieldExpression::Col(ref col) => write!(f, "{}", col.name.as_str()),
        }
    }
}

impl Default for FieldExpression {
    fn default() -> FieldExpression {
        FieldExpression::All
    }
}

#[inline]
pub fn is_sql_identifier(chr: u8) -> bool {
    // XXX(malte): dot should not be in here once we have proper alias handling
    is_alphanumeric(chr) || chr == '_' as u8
}

#[inline]
pub fn is_fp_number(chr: u8) -> bool {
    is_alphanumeric(chr) || chr == '.' as u8
}

/// Parses a floating point number (very badly).
named!(pub fp_number<&[u8], &[u8]>,
// f64::from_str(&format!("{}.{}", integral, fractional)).unwrap()
//      integral: map_res!(take_while1!(is_digit), str::from_utf8) ~
//      fractional: map_res!(take_while!(is_digit), str::from_utf8),
    take_while1!(is_fp_number)
);

/// Parses the arguments for an agregation function, and also returns whether the distinct flag is
/// present.
named!(pub function_arguments<&[u8], (Column, bool)>,
       chain!(
           distinct: opt!(chain!(
               caseless_tag!("distinct") ~
               multispace,
               ||{}
           )) ~
           column: column_identifier_no_alias,
           || {
               (column, distinct.is_some())
           }
       )
);

named!(pub column_function<&[u8], FunctionExpression>,
    alt_complete!(
        chain!(
            caseless_tag!("count(*)"),
            || {
                FunctionExpression::CountStar
            }
        )
    |   chain!(
            caseless_tag!("count") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Count(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("sum") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Sum(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("avg") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Avg(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("max") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Max(args.0.clone())
            }
        )
    |   chain!(
            caseless_tag!("min") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Min(args.0.clone())
            }
        )
    |   chain!(
            caseless_tag!("group_concat") ~
            spec: delimited!(tag!("("),
                       complete!(chain!(
                               column: column_identifier_no_alias ~
                               seperator: opt!(
                                   chain!(
                                       multispace? ~
                                       caseless_tag!("separator") ~
                                       sep: delimited!(tag!("'"), opt!(alphanumeric), tag!("'")) ~
                                       multispace?,
                                       || { sep.unwrap_or("".as_bytes()) }
                                   )
                               ),
                               || { (column, seperator) }
                       )),
                       tag!(")")),
            || {
                let (ref col, ref sep) = spec;
                let sep = match *sep {
                    // default separator is a comma, see MySQL manual §5.7
                    None => String::from(","),
                    Some(s) => String::from_utf8(s.to_vec()).unwrap(),
                };

                FunctionExpression::GroupConcat(col.clone(), sep)
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier_no_alias<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function,
            || {
                Column {
                    name: format!("{}", function),
                    alias: None,
                    table: None,
                    function: Some(Box::new(function)),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8),
            || {
                Column {
                    name: String::from(column),
                    alias: None,
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function ~
            alias: opt!(as_alias),
            || {
                Column {
                    name: match alias {
                        None => format!("{}", function),
                        Some(a) => String::from(a),
                    },
                    alias: match alias {
                        None => None,
                        Some(a) => Some(String::from(a)),
                    },
                    table: None,
                    function: Some(Box::new(function)),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8) ~
            alias: opt!(as_alias),
            || {
                Column {
                    name: String::from(column),
                    alias: match alias {
                        None => None,
                        Some(a) => Some(String::from(a)),
                    },
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL identifier (alphanumeric and "_").
named!(pub sql_identifier<&[u8], &[u8]>,
    alt_complete!(
          chain!(
                not!(peek!(sql_keyword)) ~
                ident: take_while1!(is_sql_identifier),
                || { ident }
          )
        | delimited!(tag!("`"), take_while1!(is_sql_identifier), tag!("`"))
        | delimited!(tag!("'"), take_while1!(is_sql_identifier), tag!("'"))
    )
);

/// Parse an unsigned integer.
named!(pub unsigned_number<&[u8], u64>,
    map_res!(
        map_res!(digit, str::from_utf8),
        FromStr::from_str
    )
);

/// Parse a terminator that ends a SQL statement.
named!(pub statement_terminator,
    delimited!(opt!(multispace),
               alt_complete!(tag!(";") | line_ending | eof),
               opt!(multispace)
    )
);

/// Parse binary comparison operators
named!(pub binary_comparison_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("not_like"), |_| Operator::NotLike)
         | map!(caseless_tag!("like"), |_| Operator::Like)
         | map!(caseless_tag!("!="), |_| Operator::NotEqual)
         | map!(caseless_tag!("<>"), |_| Operator::NotEqual)
         | map!(caseless_tag!(">="), |_| Operator::GreaterOrEqual)
         | map!(caseless_tag!("<="), |_| Operator::LessOrEqual)
         | map!(caseless_tag!("="), |_| Operator::Equal)
         | map!(caseless_tag!("<"), |_| Operator::Less)
         | map!(caseless_tag!(">"), |_| Operator::Greater)
    )
);

/// Parse rule for AS-based aliases for SQL entities.
named!(pub as_alias<&[u8], &str>,
    complete!(
        chain!(
            multispace ~
            opt!(chain!(caseless_tag!("as") ~ multispace, ||{})) ~
            alias: map_res!(sql_identifier, str::from_utf8),
            || { alias }
        )
    )
);

/// Parse rule for a comma-separated list of fields without aliases.
named!(pub field_list<&[u8], Vec<Column> >,
       many0!(
           chain!(
               fieldname: column_identifier_no_alias ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       ||{}
                   ))
               ),
               || { fieldname }
           )
       )
);

/// Parse list of column/field definitions.
/// XXX(malte): add support for named table notation
named!(pub field_definition_expr<&[u8], Vec<FieldExpression>>,
       many0!(
           chain!(
               field: alt_complete!(
                   chain!(
                       tag!("*"),
                       || {
                           FieldExpression::All
                       }
                   )
                 | chain!(
                     table: table_reference ~ tag!(".*"),
                     || {
                         FieldExpression::AllInTable(table.name.clone())
                     }
                 )
                 | chain!(
                     column: column_identifier,
                     || {
                         FieldExpression::Col(column)
                     }
                 )
               ) ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                           tag!(",") ~
                           multispace?,
                       ||{}
                   ))
               ),
               || { field }
           )
       )
);

/// Parse list of table names.
/// XXX(malte): add support for aliases
named!(pub table_list<&[u8], Vec<Table> >,
       many0!(
           chain!(
               table: table_reference ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       || {}
                   ))
               ),
               || { table }
           )
       )
);

/// Parse a list of values (e.g., for INSERT syntax).
/// XXX(malte): proper value type
named!(pub value_list<&[u8], Vec<&str> >,
       many0!(
           map_res!(
               chain!(
                   val: alt_complete!(
                         tag_s!(b"?")
                       | tag_s!(b"CURRENT_TIMESTAMP")
                       | delimited!(tag!("'"), alphanumeric, tag!("'"))
                       | fp_number
                   ) ~
                   opt!(
                       complete!(chain!(
                           multispace? ~
                           tag!(",") ~
                           multispace?,
                           ||{}
                       ))
                   ),
                   || { val }
               ),
               str::from_utf8
           )
       )
);

/// Parse a reference to a named table
/// XXX(malte): add support for schema.table notation
named!(pub table_reference<&[u8], Table>,
    chain!(
        table: map_res!(sql_identifier, str::from_utf8) ~
        alias: opt!(as_alias),
        || {
            Table {
                name: String::from(table),
                alias: match alias {
                    Some(a) => Some(String::from(a)),
                    None => None,
                }
            }
        }
    )
);

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

    #[test]
    fn sql_identifiers() {
        let id1 = b"foo";
        let id2 = b"f_o_o";
        let id3 = b"foo12";
        let id4 = b":fo oo";
        let id5 = b"primary ";
        let id6 = b"`primary`";

        assert!(sql_identifier(id1).is_done());
        assert!(sql_identifier(id2).is_done());
        assert!(sql_identifier(id3).is_done());
        assert!(sql_identifier(id4).is_err());
        assert!(sql_identifier(id5).is_err());
        assert!(sql_identifier(id6).is_done());
    }

    #[test]
    fn simple_column_function() {
        let qs = b"max(addr_id)";

        let res = column_identifier(qs);
        let expected = Column {
            name: String::from("max(addr_id)"),
            alias: None,
            table: None,
            function: Some(Box::new(FunctionExpression::Max(Column::from("addr_id")))),
        };
        assert_eq!(res.unwrap().1, expected);
    }
}
<commit_msg>Remove redundant comment<commit_after>use nom::{alphanumeric, digit, eof, is_alphanumeric, line_ending, multispace};
use nom::{IResult, Err, ErrorKind, Needed};
use std::fmt::{self, Display};
use std::str;
use std::str::FromStr;

use column::{Column, FunctionExpression};
use keywords::sql_keyword;
use table::Table;

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum SqlType {
    Char(u16),
    Varchar(u16),
    Int(u16),
    Bigint(u16),
    Tinyint(u16),
    Blob,
    Longblob,
    Mediumblob,
    Tinyblob,
    Double,
    Float,
    Real,
    Tinytext,
    Mediumtext,
    Text,
    Date,
    Timestamp,
    Varbinary(u16),
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum Literal {
    Null,
    Integer(i64),
    String(String),
    Blob(Vec<u8>),
    CurrentTime,
    CurrentDate,
    CurrentTimestamp,
}

#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
pub enum Operator {
    Not,
    And,
    Or,
    Like,
    NotLike,
    Equal,
    NotEqual,
    Greater,
    GreaterOrEqual,
    Less,
    LessOrEqual,
}

impl Display for Operator {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let op = match *self {
            Operator::Not => "not",
            Operator::And => "and",
            Operator::Or => "or",
            Operator::Like => "like",
            Operator::NotLike => "not_like",
            Operator::Equal => "=",
            Operator::NotEqual => "!=",
            Operator::Greater => ">",
            Operator::GreaterOrEqual => ">=",
            Operator::Less => "<",
            Operator::LessOrEqual => "<=",
        };
        write!(f, "{}", op)
    }
}

#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
pub enum TableKey {
    PrimaryKey(Vec<Column>),
    UniqueKey(Option<String>, Vec<Column>),
    FulltextKey(Option<String>, Vec<Column>),
    Key(String, Vec<Column>),
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FieldExpression {
    All,
    AllInTable(String),
    Col(Column),
}

impl Display for FieldExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FieldExpression::All => write!(f, "*"),
            FieldExpression::AllInTable(ref table) => write!(f, "{}.*", table),
            FieldExpression::Col(ref col) => write!(f, "{}", col.name.as_str()),
        }
    }
}

impl Default for FieldExpression {
    fn default() -> FieldExpression {
        FieldExpression::All
    }
}

#[inline]
pub fn is_sql_identifier(chr: u8) -> bool {
    is_alphanumeric(chr) || chr == '_' as u8
}

#[inline]
pub fn is_fp_number(chr: u8) -> bool {
    is_alphanumeric(chr) || chr == '.' as u8
}

/// Parses a floating point number (very badly).
named!(pub fp_number<&[u8], &[u8]>,
// f64::from_str(&format!("{}.{}", integral, fractional)).unwrap()
//      integral: map_res!(take_while1!(is_digit), str::from_utf8) ~
//      fractional: map_res!(take_while!(is_digit), str::from_utf8),
    take_while1!(is_fp_number)
);

/// Parses the arguments for an agregation function, and also returns whether the distinct flag is
/// present.
named!(pub function_arguments<&[u8], (Column, bool)>,
       chain!(
           distinct: opt!(chain!(
               caseless_tag!("distinct") ~
               multispace,
               ||{}
           )) ~
           column: column_identifier_no_alias,
           || {
               (column, distinct.is_some())
           }
       )
);

named!(pub column_function<&[u8], FunctionExpression>,
    alt_complete!(
        chain!(
            caseless_tag!("count(*)"),
            || {
                FunctionExpression::CountStar
            }
        )
    |   chain!(
            caseless_tag!("count") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Count(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("sum") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Sum(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("avg") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Avg(args.0.clone(), args.1)
            }
        )
    |   chain!(
            caseless_tag!("max") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Max(args.0.clone())
            }
        )
    |   chain!(
            caseless_tag!("min") ~
            args: delimited!(tag!("("), function_arguments, tag!(")")),
            || {
                FunctionExpression::Min(args.0.clone())
            }
        )
    |   chain!(
            caseless_tag!("group_concat") ~
            spec: delimited!(tag!("("),
                       complete!(chain!(
                               column: column_identifier_no_alias ~
                               seperator: opt!(
                                   chain!(
                                       multispace? ~
                                       caseless_tag!("separator") ~
                                       sep: delimited!(tag!("'"), opt!(alphanumeric), tag!("'")) ~
                                       multispace?,
                                       || { sep.unwrap_or("".as_bytes()) }
                                   )
                               ),
                               || { (column, seperator) }
                       )),
                       tag!(")")),
            || {
                let (ref col, ref sep) = spec;
                let sep = match *sep {
                    // default separator is a comma, see MySQL manual §5.7
                    None => String::from(","),
                    Some(s) => String::from_utf8(s.to_vec()).unwrap(),
                };

                FunctionExpression::GroupConcat(col.clone(), sep)
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier_no_alias<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function,
            || {
                Column {
                    name: format!("{}", function),
                    alias: None,
                    table: None,
                    function: Some(Box::new(function)),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8),
            || {
                Column {
                    name: String::from(column),
                    alias: None,
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL column identifier in the table.column format
named!(pub column_identifier<&[u8], Column>,
    alt_complete!(
        chain!(
            function: column_function ~
            alias: opt!(as_alias),
            || {
                Column {
                    name: match alias {
                        None => format!("{}", function),
                        Some(a) => String::from(a),
                    },
                    alias: match alias {
                        None => None,
                        Some(a) => Some(String::from(a)),
                    },
                    table: None,
                    function: Some(Box::new(function)),
                }
            }
        )
        | chain!(
            table: opt!(
                chain!(
                    tbl_name: map_res!(sql_identifier, str::from_utf8) ~
                    tag!("."),
                    || { tbl_name }
                )
            ) ~
            column: map_res!(sql_identifier, str::from_utf8) ~
            alias: opt!(as_alias),
            || {
                Column {
                    name: String::from(column),
                    alias: match alias {
                        None => None,
                        Some(a) => Some(String::from(a)),
                    },
                    table: match table {
                        None => None,
                        Some(t) => Some(String::from(t)),
                    },
                    function: None,
                }
            }
        )
    )
);

/// Parses a SQL identifier (alphanumeric and "_").
named!(pub sql_identifier<&[u8], &[u8]>,
    alt_complete!(
          chain!(
                not!(peek!(sql_keyword)) ~
                ident: take_while1!(is_sql_identifier),
                || { ident }
          )
        | delimited!(tag!("`"), take_while1!(is_sql_identifier), tag!("`"))
        | delimited!(tag!("'"), take_while1!(is_sql_identifier), tag!("'"))
    )
);

/// Parse an unsigned integer.
named!(pub unsigned_number<&[u8], u64>,
    map_res!(
        map_res!(digit, str::from_utf8),
        FromStr::from_str
    )
);

/// Parse a terminator that ends a SQL statement.
named!(pub statement_terminator,
    delimited!(opt!(multispace),
               alt_complete!(tag!(";") | line_ending | eof),
               opt!(multispace)
    )
);

/// Parse binary comparison operators
named!(pub binary_comparison_operator<&[u8], Operator>,
    alt_complete!(
           map!(caseless_tag!("not_like"), |_| Operator::NotLike)
         | map!(caseless_tag!("like"), |_| Operator::Like)
         | map!(caseless_tag!("!="), |_| Operator::NotEqual)
         | map!(caseless_tag!("<>"), |_| Operator::NotEqual)
         | map!(caseless_tag!(">="), |_| Operator::GreaterOrEqual)
         | map!(caseless_tag!("<="), |_| Operator::LessOrEqual)
         | map!(caseless_tag!("="), |_| Operator::Equal)
         | map!(caseless_tag!("<"), |_| Operator::Less)
         | map!(caseless_tag!(">"), |_| Operator::Greater)
    )
);

/// Parse rule for AS-based aliases for SQL entities.
named!(pub as_alias<&[u8], &str>,
    complete!(
        chain!(
            multispace ~
            opt!(chain!(caseless_tag!("as") ~ multispace, ||{})) ~
            alias: map_res!(sql_identifier, str::from_utf8),
            || { alias }
        )
    )
);

/// Parse rule for a comma-separated list of fields without aliases.
named!(pub field_list<&[u8], Vec<Column> >,
       many0!(
           chain!(
               fieldname: column_identifier_no_alias ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       ||{}
                   ))
               ),
               || { fieldname }
           )
       )
);

/// Parse list of column/field definitions.
/// XXX(malte): add support for named table notation
named!(pub field_definition_expr<&[u8], Vec<FieldExpression>>,
       many0!(
           chain!(
               field: alt_complete!(
                   chain!(
                       tag!("*"),
                       || {
                           FieldExpression::All
                       }
                   )
                 | chain!(
                     table: table_reference ~ tag!(".*"),
                     || {
                         FieldExpression::AllInTable(table.name.clone())
                     }
                 )
                 | chain!(
                     column: column_identifier,
                     || {
                         FieldExpression::Col(column)
                     }
                 )
               ) ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                           tag!(",") ~
                           multispace?,
                       ||{}
                   ))
               ),
               || { field }
           )
       )
);

/// Parse list of table names.
/// XXX(malte): add support for aliases
named!(pub table_list<&[u8], Vec<Table> >,
       many0!(
           chain!(
               table: table_reference ~
               opt!(
                   complete!(chain!(
                       multispace? ~
                       tag!(",") ~
                       multispace?,
                       || {}
                   ))
               ),
               || { table }
           )
       )
);

/// Parse a list of values (e.g., for INSERT syntax).
/// XXX(malte): proper value type
named!(pub value_list<&[u8], Vec<&str> >,
       many0!(
           map_res!(
               chain!(
                   val: alt_complete!(
                         tag_s!(b"?")
                       | tag_s!(b"CURRENT_TIMESTAMP")
                       | delimited!(tag!("'"), alphanumeric, tag!("'"))
                       | fp_number
                   ) ~
                   opt!(
                       complete!(chain!(
                           multispace? ~
                           tag!(",") ~
                           multispace?,
                           ||{}
                       ))
                   ),
                   || { val }
               ),
               str::from_utf8
           )
       )
);

/// Parse a reference to a named table
/// XXX(malte): add support for schema.table notation
named!(pub table_reference<&[u8], Table>,
    chain!(
        table: map_res!(sql_identifier, str::from_utf8) ~
        alias: opt!(as_alias),
        || {
            Table {
                name: String::from(table),
                alias: match alias {
                    Some(a) => Some(String::from(a)),
                    None => None,
                }
            }
        }
    )
);

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

    #[test]
    fn sql_identifiers() {
        let id1 = b"foo";
        let id2 = b"f_o_o";
        let id3 = b"foo12";
        let id4 = b":fo oo";
        let id5 = b"primary ";
        let id6 = b"`primary`";

        assert!(sql_identifier(id1).is_done());
        assert!(sql_identifier(id2).is_done());
        assert!(sql_identifier(id3).is_done());
        assert!(sql_identifier(id4).is_err());
        assert!(sql_identifier(id5).is_err());
        assert!(sql_identifier(id6).is_done());
    }

    #[test]
    fn simple_column_function() {
        let qs = b"max(addr_id)";

        let res = column_identifier(qs);
        let expected = Column {
            name: String::from("max(addr_id)"),
            alias: None,
            table: None,
            function: Some(Box::new(FunctionExpression::Max(Column::from("addr_id")))),
        };
        assert_eq!(res.unwrap().1, expected);
    }
}
<|endoftext|>


<commit_before>//! Pool configuration.
use std::fmt;
use std::time::Duration;

use {HandleError, NopErrorHandler, CustomizeConnection, NopConnectionCustomizer};

/// A builder for `Config`.
///
/// See the documentation of `Config` for more details about the default value
/// and meaning of the configuration parameters.
#[derive(Debug)]
pub struct Builder<C, E> {
    c: Config<C, E>,
}

impl<C, E> Builder<C, E> {
    /// Constructs a new `Builder`.
    ///
    /// Parameters are initialized with their default values.
    pub fn new() -> Builder<C, E> {
        Builder {
            c: Config::default(),
        }
    }

    /// Sets `pool_size`.
    ///
    /// # Panics
    ///
    /// Panics if `pool_size` is 0.
    pub fn pool_size(mut self, pool_size: u32) -> Builder<C, E> {
        assert!(pool_size > 0, "pool_size must be positive");
        self.c.pool_size = pool_size;
        self
    }

    /// Sets `helper_threads`.
    ///
    /// # Panics
    ///
    /// Panics if `helper_threads` is 0.
    pub fn helper_threads(mut self, helper_threads: u32) -> Builder<C, E> {
        assert!(helper_threads > 0, "helper_threads must be positive");
        self.c.helper_threads = helper_threads;
        self
    }

    /// Sets `test_on_check_out`.
    pub fn test_on_check_out(mut self, test_on_check_out: bool) -> Builder<C, E> {
        self.c.test_on_check_out = test_on_check_out;
        self
    }

    /// Sets `initialization_fail_fast`.
    pub fn initialization_fail_fast(mut self, initialization_fail_fast: bool) -> Builder<C, E> {
        self.c.initialization_fail_fast = initialization_fail_fast;
        self
    }

    /// Sets `idle_timeout`.
    ///
    /// # Panics
    ///
    /// Panics if `idle_timeout` is set to the zero `Duration`.
    pub fn idle_timeout(mut self, idle_timeout: Option<Duration>) -> Builder<C, E> {
        assert!(idle_timeout != Some(Duration::from_secs(0)), "idle_timeout must be nonzero");
        self.c.idle_timeout = idle_timeout;
        self
    }

    /// Sets `connection_timeout` to the specified duration.
    ///
    /// # Panics
    ///
    /// Panics if `connection_timeout` is the zero duration
    pub fn connection_timeout(mut self, connection_timeout: Duration) -> Builder<C, E> {
        assert!(connection_timeout.as_secs() > 0 || connection_timeout.subsec_nanos() > 0,
                "connection_timeout must be positive");
        self.c.connection_timeout = connection_timeout;
        self
    }

    /// # Deprecated
    ///
    /// Use `connection_timeout` instead.
    pub fn connection_timeout_ms(self, connection_timeout_ms: u32) -> Builder<C, E> {
        self.connection_timeout(Duration::from_millis(connection_timeout_ms as u64))
    }

    /// Sets the `error_handler`.
    pub fn error_handler(mut self, error_handler: Box<HandleError<E>>) -> Builder<C, E> {
        self.c.error_handler = error_handler;
        self
    }

    /// Sets the `connection_customizer`.
    pub fn connection_customizer(mut self, connection_customizer: Box<CustomizeConnection<C, E>>)
                                 -> Builder<C, E> {
        self.c.connection_customizer = connection_customizer;
        self
    }

    /// Consumes the `Builder`, turning it into a `Config`.
    pub fn build(self) -> Config<C, E> {
        self.c
    }
}

/// A struct specifying the runtime configuration of a pool.
///
/// `Config` implements `Default`, which provides a set of reasonable default
/// values. It can be constructed using a `Builder`.
pub struct Config<C, E> {
    pool_size: u32,
    helper_threads: u32,
    test_on_check_out: bool,
    initialization_fail_fast: bool,
    idle_timeout: Option<Duration>,
    connection_timeout: Duration,
    error_handler: Box<HandleError<E>>,
    connection_customizer: Box<CustomizeConnection<C, E>>,
}

impl<C, E> fmt::Debug for Config<C, E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Config")
            .field("pool_size", &self.pool_size)
            .field("helper_threads", &self.helper_threads)
            .field("test_on_check_out", &self.test_on_check_out)
            .field("initialization_fail_fast", &self.initialization_fail_fast)
            .field("idle_timeout", &self.idle_timeout)
            .field("connection_timeout", &self.connection_timeout)
            .finish()
    }
}

impl<C, E> Default for Config<C, E> {
    fn default() -> Config<C, E> {
        Config {
            pool_size: 10,
            helper_threads: 3,
            test_on_check_out: true,
            initialization_fail_fast: true,
            idle_timeout: Some(Duration::from_secs(10 * 60)),
            connection_timeout: Duration::from_secs(30),
            error_handler: Box::new(NopErrorHandler),
            connection_customizer: Box::new(NopConnectionCustomizer),
        }
    }
}

impl<C, E> Config<C, E> {
    /// Creates a new `Builder` which can be used to construct a customized
    /// `Config`.
    ///
    /// All parameters are initialized to their default values.
    pub fn builder() -> Builder<C, E> {
        Builder::new()
    }

    /// The number of connections managed by the pool.
    ///
    /// Defaults to 10.
    pub fn pool_size(&self) -> u32 {
        self.pool_size
    }

    /// The number of threads that the pool will use for asynchronous
    /// operations such as connection creation and health checks.
    ///
    /// Defaults to 3.
    pub fn helper_threads(&self) -> u32 {
        self.helper_threads
    }

    /// If true, the health of a connection will be verified via a call to
    /// `ConnectionManager::is_valid` before it is checked out of the pool.
    ///
    /// Defaults to true.
    pub fn test_on_check_out(&self) -> bool {
        self.test_on_check_out
    }

    /// If true, `Pool::new` will synchronously initialize its connections,
    /// returning an error if they could not be created.
    ///
    /// Defaults to true.
    pub fn initialization_fail_fast(&self) -> bool {
        self.initialization_fail_fast
    }

    /// If set, connections will be closed after sitting idle for this long.
    ///
    /// Defaults to 10 minutes.
    pub fn idle_timeout(&self) -> Option<Duration> {
        self.idle_timeout
    }

    /// Calls to `Pool::get` will wait this long for a connection to become
    /// available before returning an error.
    ///
    /// Defaults to 30 seconds.
    pub fn connection_timeout(&self) -> Duration {
        self.connection_timeout
    }

    /// # Deprecated
    ///
    /// Use `connection_timeout` instead.
    pub fn connection_timeout_ms(&self) -> u32 {
        self.connection_timeout.as_secs() as u32 * 1000 +
            self.connection_timeout.subsec_nanos() / 1_000_000
    }

    /// The handler for error reported in the pool.
    ///
    /// Defaults to `r2d2::NopErrorHandler`.
    pub fn error_handler(&self) -> &HandleError<E> {
        &*self.error_handler
    }

    /// The connection customizer used by the pool.
    ///
    /// Defaults to `r2d2::NopConnectionCustomizer`.
    pub fn connection_customizer(&self) -> &CustomizeConnection<C, E> {
        &*self.connection_customizer
    }
}
<commit_msg>Clarify accuracy bounds in docs<commit_after>//! Pool configuration.
use std::fmt;
use std::time::Duration;

use {HandleError, NopErrorHandler, CustomizeConnection, NopConnectionCustomizer};

/// A builder for `Config`.
///
/// See the documentation of `Config` for more details about the default value
/// and meaning of the configuration parameters.
#[derive(Debug)]
pub struct Builder<C, E> {
    c: Config<C, E>,
}

impl<C, E> Builder<C, E> {
    /// Constructs a new `Builder`.
    ///
    /// Parameters are initialized with their default values.
    pub fn new() -> Builder<C, E> {
        Builder {
            c: Config::default(),
        }
    }

    /// Sets `pool_size`.
    ///
    /// # Panics
    ///
    /// Panics if `pool_size` is 0.
    pub fn pool_size(mut self, pool_size: u32) -> Builder<C, E> {
        assert!(pool_size > 0, "pool_size must be positive");
        self.c.pool_size = pool_size;
        self
    }

    /// Sets `helper_threads`.
    ///
    /// # Panics
    ///
    /// Panics if `helper_threads` is 0.
    pub fn helper_threads(mut self, helper_threads: u32) -> Builder<C, E> {
        assert!(helper_threads > 0, "helper_threads must be positive");
        self.c.helper_threads = helper_threads;
        self
    }

    /// Sets `test_on_check_out`.
    pub fn test_on_check_out(mut self, test_on_check_out: bool) -> Builder<C, E> {
        self.c.test_on_check_out = test_on_check_out;
        self
    }

    /// Sets `initialization_fail_fast`.
    pub fn initialization_fail_fast(mut self, initialization_fail_fast: bool) -> Builder<C, E> {
        self.c.initialization_fail_fast = initialization_fail_fast;
        self
    }

    /// Sets `idle_timeout`.
    ///
    /// # Panics
    ///
    /// Panics if `idle_timeout` is set to the zero `Duration`.
    pub fn idle_timeout(mut self, idle_timeout: Option<Duration>) -> Builder<C, E> {
        assert!(idle_timeout != Some(Duration::from_secs(0)), "idle_timeout must be nonzero");
        self.c.idle_timeout = idle_timeout;
        self
    }

    /// Sets `connection_timeout` to the specified duration.
    ///
    /// # Panics
    ///
    /// Panics if `connection_timeout` is the zero duration
    pub fn connection_timeout(mut self, connection_timeout: Duration) -> Builder<C, E> {
        assert!(connection_timeout.as_secs() > 0 || connection_timeout.subsec_nanos() > 0,
                "connection_timeout must be positive");
        self.c.connection_timeout = connection_timeout;
        self
    }

    /// # Deprecated
    ///
    /// Use `connection_timeout` instead.
    pub fn connection_timeout_ms(self, connection_timeout_ms: u32) -> Builder<C, E> {
        self.connection_timeout(Duration::from_millis(connection_timeout_ms as u64))
    }

    /// Sets the `error_handler`.
    pub fn error_handler(mut self, error_handler: Box<HandleError<E>>) -> Builder<C, E> {
        self.c.error_handler = error_handler;
        self
    }

    /// Sets the `connection_customizer`.
    pub fn connection_customizer(mut self, connection_customizer: Box<CustomizeConnection<C, E>>)
                                 -> Builder<C, E> {
        self.c.connection_customizer = connection_customizer;
        self
    }

    /// Consumes the `Builder`, turning it into a `Config`.
    pub fn build(self) -> Config<C, E> {
        self.c
    }
}

/// A struct specifying the runtime configuration of a pool.
///
/// `Config` implements `Default`, which provides a set of reasonable default
/// values. It can be constructed using a `Builder`.
pub struct Config<C, E> {
    pool_size: u32,
    helper_threads: u32,
    test_on_check_out: bool,
    initialization_fail_fast: bool,
    idle_timeout: Option<Duration>,
    connection_timeout: Duration,
    error_handler: Box<HandleError<E>>,
    connection_customizer: Box<CustomizeConnection<C, E>>,
}

impl<C, E> fmt::Debug for Config<C, E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Config")
            .field("pool_size", &self.pool_size)
            .field("helper_threads", &self.helper_threads)
            .field("test_on_check_out", &self.test_on_check_out)
            .field("initialization_fail_fast", &self.initialization_fail_fast)
            .field("idle_timeout", &self.idle_timeout)
            .field("connection_timeout", &self.connection_timeout)
            .finish()
    }
}

impl<C, E> Default for Config<C, E> {
    fn default() -> Config<C, E> {
        Config {
            pool_size: 10,
            helper_threads: 3,
            test_on_check_out: true,
            initialization_fail_fast: true,
            idle_timeout: Some(Duration::from_secs(10 * 60)),
            connection_timeout: Duration::from_secs(30),
            error_handler: Box::new(NopErrorHandler),
            connection_customizer: Box::new(NopConnectionCustomizer),
        }
    }
}

impl<C, E> Config<C, E> {
    /// Creates a new `Builder` which can be used to construct a customized
    /// `Config`.
    ///
    /// All parameters are initialized to their default values.
    pub fn builder() -> Builder<C, E> {
        Builder::new()
    }

    /// The number of connections managed by the pool.
    ///
    /// Defaults to 10.
    pub fn pool_size(&self) -> u32 {
        self.pool_size
    }

    /// The number of threads that the pool will use for asynchronous
    /// operations such as connection creation and health checks.
    ///
    /// Defaults to 3.
    pub fn helper_threads(&self) -> u32 {
        self.helper_threads
    }

    /// If true, the health of a connection will be verified via a call to
    /// `ConnectionManager::is_valid` before it is checked out of the pool.
    ///
    /// Defaults to true.
    pub fn test_on_check_out(&self) -> bool {
        self.test_on_check_out
    }

    /// If true, `Pool::new` will synchronously initialize its connections,
    /// returning an error if they could not be created.
    ///
    /// Defaults to true.
    pub fn initialization_fail_fast(&self) -> bool {
        self.initialization_fail_fast
    }

    /// If set, connections will be closed after sitting idle within 30 seconds
    /// of this duration.
    ///
    /// Defaults to 10 minutes.
    pub fn idle_timeout(&self) -> Option<Duration> {
        self.idle_timeout
    }

    /// Calls to `Pool::get` will wait this long for a connection to become
    /// available before returning an error.
    ///
    /// Defaults to 30 seconds.
    pub fn connection_timeout(&self) -> Duration {
        self.connection_timeout
    }

    /// # Deprecated
    ///
    /// Use `connection_timeout` instead.
    pub fn connection_timeout_ms(&self) -> u32 {
        self.connection_timeout.as_secs() as u32 * 1000 +
            self.connection_timeout.subsec_nanos() / 1_000_000
    }

    /// The handler for error reported in the pool.
    ///
    /// Defaults to `r2d2::NopErrorHandler`.
    pub fn error_handler(&self) -> &HandleError<E> {
        &*self.error_handler
    }

    /// The connection customizer used by the pool.
    ///
    /// Defaults to `r2d2::NopConnectionCustomizer`.
    pub fn connection_customizer(&self) -> &CustomizeConnection<C, E> {
        &*self.connection_customizer
    }
}
<|endoftext|>


<commit_before>#![feature(convert)]

extern crate dna;

#[test]
#[ignore]
fn test_acid_equals_acid() {
    assert_eq!(dna::RibonucleicAcid::new("CGA"), dna::RibonucleicAcid::new("CGA"));
    assert!(dna::RibonucleicAcid::new("CGA") != dna::RibonucleicAcid::new("AGC"));
}

#[test]
#[ignore]
fn test_transcribes_cytosine_guanine() {
    assert_eq!(dna::RibonucleicAcid::new("G"), dna::DeoxyribonucleicAcid::new("C").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_guanine_cytosine() {
    assert_eq!(dna::RibonucleicAcid::new("C"), dna::DeoxyribonucleicAcid::new("G").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_adenine_uracil() {
    assert_eq!(dna::RibonucleicAcid::new("U"), dna::DeoxyribonucleicAcid::new("A").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_thymine_to_adenine() {
    assert_eq!(dna::RibonucleicAcid::new("A"), dna::DeoxyribonucleicAcid::new("T").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_all_dna_to_rna() {
    assert_eq!(dna::RibonucleicAcid::new("UGCACCAGAAUU"), dna::DeoxyribonucleicAcid::new("ACGTGGTCTTAA").to_rna())
}

#[test]
#[ignore]
fn test_acid_converts_to_string() {
    assert_eq!(dna::RibonucleicAcid::new("AGC").as_ref(), "AGC");
    assert_eq!(dna::RibonucleicAcid::new("CGA").as_ref(), "CGA");
}
<commit_msg>Remove feature flag<commit_after>extern crate dna;

#[test]
#[ignore]
fn test_acid_equals_acid() {
    assert_eq!(dna::RibonucleicAcid::new("CGA"), dna::RibonucleicAcid::new("CGA"));
    assert!(dna::RibonucleicAcid::new("CGA") != dna::RibonucleicAcid::new("AGC"));
}

#[test]
#[ignore]
fn test_transcribes_cytosine_guanine() {
    assert_eq!(dna::RibonucleicAcid::new("G"), dna::DeoxyribonucleicAcid::new("C").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_guanine_cytosine() {
    assert_eq!(dna::RibonucleicAcid::new("C"), dna::DeoxyribonucleicAcid::new("G").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_adenine_uracil() {
    assert_eq!(dna::RibonucleicAcid::new("U"), dna::DeoxyribonucleicAcid::new("A").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_thymine_to_adenine() {
    assert_eq!(dna::RibonucleicAcid::new("A"), dna::DeoxyribonucleicAcid::new("T").to_rna());
}

#[test]
#[ignore]
fn test_transcribes_all_dna_to_rna() {
    assert_eq!(dna::RibonucleicAcid::new("UGCACCAGAAUU"), dna::DeoxyribonucleicAcid::new("ACGTGGTCTTAA").to_rna())
}

#[test]
#[ignore]
fn test_acid_converts_to_string() {
    assert_eq!(dna::RibonucleicAcid::new("AGC").as_ref(), "AGC");
    assert_eq!(dna::RibonucleicAcid::new("CGA").as_ref(), "CGA");
}
<|endoftext|>


<commit_before>use libc::{c_char, c_uint};
use ffi::prelude::{LLVMBuilderRef, LLVMValueRef};
use ffi::{core, LLVMBuilder};
use cbox::{CBox, DisposeRef};
use std::{mem, ptr};
use block::BasicBlock;
use context::Context;
use ty::Type;
use value::Value;

static NULL_NAME:[c_char; 1] = [0];

/// This provides a uniform API for creating instructions and inserting them into a basic block
pub struct Builder;
native_ref!(&Builder = LLVMBuilderRef);
macro_rules! bin_op(
    ($name:ident, $func:ident) => (
        pub fn $name(&self, left: &Value, right: &Value) -> &Value {
            unsafe { core::$func(self.into(), left.into(), right.into(), NULL_NAME.as_ptr()) }.into()
        }
    );
);
macro_rules! un_op(
    ($name:ident, $func:ident) => (
        pub fn $name(&self, value: &Value) -> &Value {
            unsafe { core::$func(self.into(), value.into(), NULL_NAME.as_ptr() as *const c_char) }.into()
        }
    );
);
impl Builder {
    /// Create a new builder in the context given
    pub fn new(context: &Context) -> CBox<Builder> {
        CBox::new(unsafe { core::LLVMCreateBuilderInContext(context.into()) }.into())
    }
    /// Position the builder at the end of `block`
    pub fn position_at_end(&self, block: &BasicBlock) {
        unsafe { core::LLVMPositionBuilderAtEnd(self.into(), block.into()) }
    }
    /// Build an instruction that returns from the function with void
    pub fn build_ret_void(&self) -> &Value {
        unsafe { core::LLVMBuildRetVoid(self.into()) }.into()
    }
    /// Build an instruction that returns from the function with `value`
    pub fn build_ret(&self, value: &Value) -> &Value {
        unsafe { core::LLVMBuildRet(self.into(), value.into()) }.into()
    }
    /// Build an instruction that allocates an array with the element type `elem` and the size `size`
    ///
    /// The size of this array will be the `size` of elem times `size`
    pub fn build_array_alloca(&self, elem: &Type, size: &Value) -> &Value {
        unsafe { core::LLVMBuildArrayAlloca(self.into(), elem.into(), size.into(), ptr::null_mut()) }.into()
    }
    pub fn build_alloca(&self, ty: &Type) -> &Value {
        unsafe { core::LLVMBuildAlloca(self.into(), ty.into(), ptr::null_mut()) }.into()
    }
    /// Frees the `val`
    pub fn build_free(&self, val: &Value) -> &Value {
        unsafe { core::LLVMBuildFree(self.into(), val.into()) }.into()
    }
    /// Store the value `val` in `ptr`
    pub fn build_store(&self, val: &Value, ptr: &Value) -> &Value {
        unsafe { core::LLVMBuildStore(self.into(), val.into(), ptr.into()) }.into()
    }
    /// Build an instruction that branches to `dest`
    pub fn build_br(&self, dest: &BasicBlock) -> &Value {
        unsafe { core::LLVMBuildBr(self.into(), dest.into()).into() }
    }
    /// Build an instruction that branches to `if_block` if `cond` evaluates to true, and `else_block` otherwise
    pub fn build_cond_br(&self, cond: &Value, if_block: &BasicBlock, else_block: Option<&BasicBlock>) -> &Value {
        unsafe { core::LLVMBuildCondBr(self.into(), cond.into(), if_block.into(), mem::transmute(else_block)).into() }
    }
    /// Build an instruction that calls the function `func` with the arguments `args`
    pub fn build_call(&self, func: &Value, args: &[&Value]) -> &Value {
        unsafe { core::LLVMBuildCall(self.into(), func.into(), args.as_ptr() as *mut LLVMValueRef, args.len() as c_uint, NULL_NAME.as_ptr()).into() }
    }
    /// Build an instruction that yields to `true_val` if `cond` is equal to `1`, and `false_val` otherwise
    pub fn build_select(&self, cond: &Value, true_val: &Value, false_val: &Value) -> &Value {
        unsafe { core::LLVMBuildSelect(self.into(), cond.into(), true_val.into(), false_val.into(), NULL_NAME.as_ptr()).into() }
    }
    /// Build an instruction that casts a value into a certain type
    pub fn build_bit_cast(&self, value: &Value, dest: &Type) -> &Value {
        unsafe { core::LLVMBuildBitCast(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
    }
    un_op!{build_load, LLVMBuildLoad}
    un_op!{build_neg, LLVMBuildNeg}
    un_op!{build_not, LLVMBuildNot}
    bin_op!{build_add, LLVMBuildAdd}
    bin_op!{build_sub, LLVMBuildSub}
    bin_op!{build_mul, LLVMBuildMul}
    bin_op!{build_fdiv, LLVMBuildFDiv}
    bin_op!{build_sdiv, LLVMBuildSDiv}
    bin_op!{build_shl, LLVMBuildShl}
    bin_op!{build_ashr, LLVMBuildAShr}
    bin_op!{build_and, LLVMBuildAnd}
    bin_op!{build_or, LLVMBuildOr}
}

impl DisposeRef for Builder {
    type RefTo = LLVMBuilder;
    #[inline(always)]
    unsafe fn dispose(ptr: LLVMBuilderRef) {
        core::LLVMDisposeBuilder(ptr)
    }
}
<commit_msg>Add support for GEP instruction<commit_after>use libc::{c_char, c_uint};
use ffi::prelude::{LLVMBuilderRef, LLVMValueRef};
use ffi::{core, LLVMBuilder};
use cbox::{CBox, DisposeRef};
use std::{mem, ptr};
use block::BasicBlock;
use context::Context;
use ty::Type;
use value::Value;

static NULL_NAME:[c_char; 1] = [0];

/// This provides a uniform API for creating instructions and inserting them into a basic block
pub struct Builder;
native_ref!(&Builder = LLVMBuilderRef);
macro_rules! bin_op(
    ($name:ident, $func:ident) => (
        pub fn $name(&self, left: &Value, right: &Value) -> &Value {
            unsafe { core::$func(self.into(), left.into(), right.into(), NULL_NAME.as_ptr()) }.into()
        }
    );
);
macro_rules! un_op(
    ($name:ident, $func:ident) => (
        pub fn $name(&self, value: &Value) -> &Value {
            unsafe { core::$func(self.into(), value.into(), NULL_NAME.as_ptr() as *const c_char) }.into()
        }
    );
);
impl Builder {
    /// Create a new builder in the context given
    pub fn new(context: &Context) -> CBox<Builder> {
        CBox::new(unsafe { core::LLVMCreateBuilderInContext(context.into()) }.into())
    }
    /// Position the builder at the end of `block`
    pub fn position_at_end(&self, block: &BasicBlock) {
        unsafe { core::LLVMPositionBuilderAtEnd(self.into(), block.into()) }
    }
    /// Build an instruction that returns from the function with void
    pub fn build_ret_void(&self) -> &Value {
        unsafe { core::LLVMBuildRetVoid(self.into()) }.into()
    }
    /// Build an instruction that returns from the function with `value`
    pub fn build_ret(&self, value: &Value) -> &Value {
        unsafe { core::LLVMBuildRet(self.into(), value.into()) }.into()
    }
    /// Build an instruction that allocates an array with the element type `elem` and the size `size`
    ///
    /// The size of this array will be the `size` of elem times `size`
    pub fn build_array_alloca(&self, elem: &Type, size: &Value) -> &Value {
        unsafe { core::LLVMBuildArrayAlloca(self.into(), elem.into(), size.into(), ptr::null_mut()) }.into()
    }
    pub fn build_alloca(&self, ty: &Type) -> &Value {
        unsafe { core::LLVMBuildAlloca(self.into(), ty.into(), ptr::null_mut()) }.into()
    }
    /// Frees the `val`
    pub fn build_free(&self, val: &Value) -> &Value {
        unsafe { core::LLVMBuildFree(self.into(), val.into()) }.into()
    }
    /// Store the value `val` in `ptr`
    pub fn build_store(&self, val: &Value, ptr: &Value) -> &Value {
        unsafe { core::LLVMBuildStore(self.into(), val.into(), ptr.into()) }.into()
    }
    /// Build an instruction that branches to `dest`
    pub fn build_br(&self, dest: &BasicBlock) -> &Value {
        unsafe { core::LLVMBuildBr(self.into(), dest.into()).into() }
    }
    /// Build an instruction that branches to `if_block` if `cond` evaluates to true, and `else_block` otherwise
    pub fn build_cond_br(&self, cond: &Value, if_block: &BasicBlock, else_block: Option<&BasicBlock>) -> &Value {
        unsafe { core::LLVMBuildCondBr(self.into(), cond.into(), if_block.into(), mem::transmute(else_block)).into() }
    }
    /// Build an instruction that calls the function `func` with the arguments `args`
    pub fn build_call(&self, func: &Value, args: &[&Value]) -> &Value {
        unsafe { core::LLVMBuildCall(self.into(), func.into(), args.as_ptr() as *mut LLVMValueRef, args.len() as c_uint, NULL_NAME.as_ptr()).into() }
    }
    /// Build an instruction that yields to `true_val` if `cond` is equal to `1`, and `false_val` otherwise
    pub fn build_select(&self, cond: &Value, true_val: &Value, false_val: &Value) -> &Value {
        unsafe { core::LLVMBuildSelect(self.into(), cond.into(), true_val.into(), false_val.into(), NULL_NAME.as_ptr()).into() }
    }
    /// Build an instruction that casts a value into a certain type
    pub fn build_bit_cast(&self, value: &Value, dest: &Type) -> &Value {
        unsafe { core::LLVMBuildBitCast(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
    }
    /// Build an instruction that computes the address of a subelement of an aggregate data structure
    ///
    /// Basically type-safe pointer arithmetic
    pub fn build_gep(&self, pointer: &Value, indices: &[&Value]) -> &Value {
        unsafe { core::LLVMBuildGEP(self.into(), pointer.into(), indices.as_ptr() as *mut LLVMValueRef, indices.len() as c_uint, NULL_NAME.as_ptr()).into() }
    }
    un_op!{build_load, LLVMBuildLoad}
    un_op!{build_neg, LLVMBuildNeg}
    un_op!{build_not, LLVMBuildNot}
    bin_op!{build_add, LLVMBuildAdd}
    bin_op!{build_sub, LLVMBuildSub}
    bin_op!{build_mul, LLVMBuildMul}
    bin_op!{build_fdiv, LLVMBuildFDiv}
    bin_op!{build_sdiv, LLVMBuildSDiv}
    bin_op!{build_shl, LLVMBuildShl}
    bin_op!{build_ashr, LLVMBuildAShr}
    bin_op!{build_and, LLVMBuildAnd}
    bin_op!{build_or, LLVMBuildOr}
}

impl DisposeRef for Builder {
    type RefTo = LLVMBuilder;
    #[inline(always)]
    unsafe fn dispose(ptr: LLVMBuilderRef) {
        core::LLVMDisposeBuilder(ptr)
    }
}
<|endoftext|>


<commit_before>use ffi;
use types::*;

#[derive(Debug,Clone,Copy,PartialEq)]
pub enum Direction {
    Input,
    Output,
}

/// Represents what we know about a device
#[derive(Clone, Debug)]
pub struct DeviceInfo {
    /// The `PortMidiDeviceId` used with `OutputPort::new` and `InputPort::new`
    id: PortMidiDeviceId,
    /// The name of the device
    name: String,
    dir: Direction,
}
impl DeviceInfo {
    // TODO: return a Result with an error if `dev_inf_ptr` is NULL (invalid id)
    pub fn new(id: PortMidiDeviceId) -> Result<Self> {
        let dev_inf_ptr = unsafe { ffi::Pm_GetDeviceInfo(id) };
        if dev_inf_ptr.is_null() {
            Err(Error::PortMidi(ffi::PmError::PmInvalidDeviceId))
        } else {
            let name = unsafe { ffi::ptr_to_string((*dev_inf_ptr).name).unwrap() };
            let direction = if unsafe { (*dev_inf_ptr).input != 0 } {
                Direction::Input
            } else {
                Direction::Output
            };

            Ok(DeviceInfo {
                id: id,
                name: name,
                dir: direction,
            })
        }
    }

    pub fn is_input(&self) -> bool {
        match self.dir {
            Direction::Input => true,
            _ => false,
        }
    }

    pub fn is_output(&self) -> bool {
        !self.is_input()
    }

    pub fn name(self) -> String {
        self.name
    }

    pub fn id(&self) -> PortMidiDeviceId {
        self.id
    }
}
<commit_msg>Implement `Display` for `DeviceInfo`<commit_after>use ffi;
use types::*;
use std::fmt;

#[derive(Debug,Clone,Copy,PartialEq)]
pub enum Direction {
    Input,
    Output,
}

/// Represents what we know about a device
#[derive(Clone, Debug)]
pub struct DeviceInfo {
    /// The `PortMidiDeviceId` used with `OutputPort::new` and `InputPort::new`
    id: PortMidiDeviceId,
    /// The name of the device
    name: String,
    dir: Direction,
}
impl DeviceInfo {
    // TODO: return a Result with an error if `dev_inf_ptr` is NULL (invalid id)
    pub fn new(id: PortMidiDeviceId) -> Result<Self> {
        let dev_inf_ptr = unsafe { ffi::Pm_GetDeviceInfo(id) };
        if dev_inf_ptr.is_null() {
            Err(Error::PortMidi(ffi::PmError::PmInvalidDeviceId))
        } else {
            let name = unsafe { ffi::ptr_to_string((*dev_inf_ptr).name).unwrap() };
            let direction = if unsafe { (*dev_inf_ptr).input != 0 } {
                Direction::Input
            } else {
                Direction::Output
            };

            Ok(DeviceInfo {
                id: id,
                name: name,
                dir: direction,
            })
        }
    }

    pub fn is_input(&self) -> bool {
        match self.dir {
            Direction::Input => true,
            _ => false,
        }
    }

    pub fn is_output(&self) -> bool {
        !self.is_input()
    }

    pub fn name(&self) -> &String {
        &self.name
    }

    pub fn direction(&self) -> Direction {
        self.dir
    }

    pub fn id(&self) -> PortMidiDeviceId {
        self.id
    }
}
impl fmt::Display for DeviceInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}) {:?}: {}", self.id(), self.direction(), self.name())
    }
}
<|endoftext|>


<commit_before>use std::f32;
use linalg::{point, vector};

/// Ray is a standard 3D ray, starting at origin `o` and heading in direction `d`
/// The min and max points along the ray can be specified with `min_t` and `max_t`
/// `depth` is the recursion depth of the ray
#[deriving(Show, Copy)]
pub struct Ray {
    /// Origin of the ray
    pub o: point::Point,
    /// Direction the ray is heading
    pub d: vector::Vector,
    /// Point along the ray that the actual ray starts at, `p = o + min_t * d`
    pub min_t: f32,
    /// Point along the ray at which it stops, will be inf if the ray is infinite
    pub max_t: f32,
    /// Recursion depth of the ray
    pub depth: i32,
}

impl Ray {
    /// Create a new ray from `o` heading in `d` with infinite length
    pub fn new(o: point::Point, d: vector::Vector) -> Ray {
        Ray { o: o, d: d, min_t: 0f32, max_t: f32::INFINITY, depth: 0 }
    }
    /// Create a new segment ray from `o + min_t * d` to `o + max_t * d`
    pub fn segment(o: point::Point, d: vector::Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: o, d: d, min_t: min_t, max_t: max_t, depth: 0}
    }
    /// Create a child ray from the parent starting at `o` and heading in `d`
    pub fn child(&self, o: point::Point, d: vector::Vector) -> Ray {
        Ray { o: o, d: d, min_t: 0f32, max_t: f32::INFINITY, depth: self.depth + 1 }
    }
    /// Create a child ray segment from `o + min_t * d` to `o + max_t * d`
    pub fn child_segment(&self, o: point::Point, d: vector::Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: o, d: d, min_t: min_t, max_t: max_t, depth: self.depth + 1}
    }
    /// Evaulate the ray equation at some t value and return the point
    /// returns result of `self.o + t * self.d`
    fn at(&self, t: f32) -> point::Point {
        self.o + self.d * t
    }
}

<commit_msg>Should borrow params to ray<commit_after>use std::f32;
use linalg::point::Point;
use linalg::vector::Vector;

/// Ray is a standard 3D ray, starting at origin `o` and heading in direction `d`
/// The min and max points along the ray can be specified with `min_t` and `max_t`
/// `depth` is the recursion depth of the ray
#[deriving(Show, Copy)]
pub struct Ray {
    /// Origin of the ray
    pub o: Point,
    /// Direction the ray is heading
    pub d: Vector,
    /// Point along the ray that the actual ray starts at, `p = o + min_t * d`
    pub min_t: f32,
    /// Point along the ray at which it stops, will be inf if the ray is infinite
    pub max_t: f32,
    /// Recursion depth of the ray
    pub depth: i32,
}

impl Ray {
    /// Create a new ray from `o` heading in `d` with infinite length
    pub fn new(o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: 0 }
    }
    /// Create a new segment ray from `o + min_t * d` to `o + max_t * d`
    pub fn segment(o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: 0}
    }
    /// Create a child ray from the parent starting at `o` and heading in `d`
    pub fn child(&self, o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: self.depth + 1 }
    }
    /// Create a child ray segment from `o + min_t * d` to `o + max_t * d`
    pub fn child_segment(&self, o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: self.depth + 1}
    }
    /// Evaulate the ray equation at some t value and return the point
    /// returns result of `self.o + t * self.d`
    fn at(&self, t: f32) -> Point {
        self.o + self.d * t
    }
}

<|endoftext|>


<commit_before>use alloc::boxed::Box;

use collections::vec::Vec;

use common::memory;

use disk::Disk;

use drivers::pciconfig::PciConfig;

use schemes::Result;

use self::hba::{HbaMem, HbaPort, HbaPortType};

pub mod fis;
pub mod hba;

pub struct Ahci;

impl Ahci {
    pub fn disks(mut pci: PciConfig) -> Vec<Box<Disk>> {
        let mut ret: Vec<Box<Disk>> = Vec::new();

        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        debugln!("AHCI on: {:X} IRQ: {:X}", base as usize, irq);

        let pi = unsafe { &mut * (base as *mut HbaMem) }.pi.read();

        for i in 0..32 {
            if pi & 1 << i == 1 << i {
                let mut disk = box AhciDisk {
                    port: &mut unsafe { &mut * (base as *mut HbaMem) }.ports[i]
                };

                let port_type = disk.port.probe();
                debugln!("Port {}: {:?}", i, port_type);
                match port_type {
                    HbaPortType::SATA => {
                        disk.port.init();
                        ret.push(disk);
                    },
                    _ => ()
                }
            }
        }

        ret
    }
}

pub struct AhciDisk {
    port: &'static mut HbaPort
}

impl Disk for AhciDisk {
    fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, false)
    }

    fn write(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, true)
    }
}
<commit_msg>Add private constructor for `AhciDisk`<commit_after>use alloc::boxed::Box;

use collections::vec::Vec;

use common::memory;

use disk::Disk;

use drivers::pciconfig::PciConfig;

use schemes::Result;

use self::hba::{HbaMem, HbaPort, HbaPortType};

pub mod fis;
pub mod hba;

pub struct Ahci;

impl Ahci {
    pub fn disks(mut pci: PciConfig) -> Vec<Box<Disk>> {
        let mut ret: Vec<Box<Disk>> = Vec::new();

        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        debugln!("AHCI on: {:X} IRQ: {:X}", base as usize, irq);

        let pi = unsafe { &mut * (base as *mut HbaMem) }.pi.read();

        for i in 0..32 {
            if pi & 1 << i == 1 << i {
                let mut disk = box AhciDisk::new(base, i);
                let port_type = disk.port.probe();
                debugln!("Port {}: {:?}", i, port_type);
                match port_type {
                    HbaPortType::SATA => {
                        disk.port.init();
                        ret.push(disk);
                    },
                    _ => ()
                }
            }
        }

        ret
    }
}

pub struct AhciDisk {
    port: &'static mut HbaPort
}

impl AhciDisk {
    fn new(base: usize, port_index: usize) -> Self {
        AhciDisk {
            port: &mut unsafe { &mut * (base as *mut HbaMem) }.ports[port_index]
        }
    }
}

impl Disk for AhciDisk {
    fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, false)
    }

    fn write(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, true)
    }
}
<|endoftext|>


<commit_before>// Copyright (c) Aptos
// SPDX-License-Identifier: Apache-2.0

#[cfg(test)]
mod tests;

use super::{BackupHandle, BackupHandleRef, FileHandle, FileHandleRef};

use crate::{
    storage::{BackupStorage, ShellSafeName, TextLine},
    utils::{error_notes::ErrorNotes, path_exists, PathToString},
};
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use std::path::{Path, PathBuf};
use tokio::{
    fs::{create_dir, create_dir_all, read_dir, OpenOptions},
    io::{AsyncRead, AsyncWrite, AsyncWriteExt},
};

#[derive(Parser)]
pub struct LocalFsOpt {
    #[clap(
        long = "dir",
        parse(from_os_str),
        help = "Target local dir to hold backups."
    )]
    pub dir: PathBuf,
}

/// A storage backend that stores everything in a local directory.
pub struct LocalFs {
    /// The path where everything is stored.
    dir: PathBuf,
}

impl LocalFs {
    const METADATA_DIR: &'static str = "metadata";

    pub fn new(dir: PathBuf) -> Self {
        Self { dir }
    }

    pub fn new_with_opt(opt: LocalFsOpt) -> Self {
        Self::new(opt.dir)
    }

    pub fn metadata_dir(&self) -> PathBuf {
        self.dir.join(Self::METADATA_DIR)
    }
}

#[async_trait]
impl BackupStorage for LocalFs {
    async fn create_backup(&self, name: &ShellSafeName) -> Result<BackupHandle> {
        create_dir(self.dir.join(name.as_ref()))
            .await
            .err_notes(name)?;
        Ok(name.to_string())
    }

    async fn create_for_write(
        &self,
        backup_handle: &BackupHandleRef,
        name: &ShellSafeName,
    ) -> Result<(FileHandle, Box<dyn AsyncWrite + Send + Unpin>)> {
        let file_handle = Path::new(backup_handle)
            .join(name.as_ref())
            .path_to_string()?;
        let abs_path = self.dir.join(&file_handle).path_to_string()?;
        let file = OpenOptions::new()
            .write(true)
            .create_new(true)
            .open(&abs_path)
            .await
            .err_notes(&abs_path)?;
        Ok((file_handle, Box::new(file)))
    }

    async fn open_for_read(
        &self,
        file_handle: &FileHandleRef,
    ) -> Result<Box<dyn AsyncRead + Send + Unpin>> {
        let path = self.dir.join(file_handle);
        let file = OpenOptions::new()
            .read(true)
            .open(&path)
            .await
            .err_notes(&path)?;
        Ok(Box::new(file))
    }

    async fn save_metadata_line(&self, name: &ShellSafeName, content: &TextLine) -> Result<()> {
        let dir = self.metadata_dir();
        create_dir_all(&dir).await.err_notes(name)?; // in case not yet created

        let path = dir.join(name.as_ref());
        let mut file = OpenOptions::new()
            .write(true)
            .create_new(true)
            .open(&path)
            .await
            .err_notes(&path)?;
        file.write_all(content.as_ref().as_bytes())
            .await
            .err_notes(&path)?;

        Ok(())
    }

    async fn list_metadata_files(&self) -> Result<Vec<FileHandle>> {
        let dir = self.metadata_dir();
        let rel_path = Path::new(Self::METADATA_DIR);

        let mut res = Vec::new();
        if path_exists(&dir).await {
            let mut entries = read_dir(&dir).await.err_notes(&dir)?;
            while let Some(entry) = entries.next_entry().await.err_notes(&dir)? {
                res.push(rel_path.join(entry.file_name()).path_to_string()?)
            }
        }
        Ok(res)
    }
}
<commit_msg>[backup] Create parent directories if they dont exist<commit_after>// Copyright (c) Aptos
// SPDX-License-Identifier: Apache-2.0

#[cfg(test)]
mod tests;

use super::{BackupHandle, BackupHandleRef, FileHandle, FileHandleRef};

use crate::{
    storage::{BackupStorage, ShellSafeName, TextLine},
    utils::{error_notes::ErrorNotes, path_exists, PathToString},
};
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use std::path::{Path, PathBuf};
use tokio::{
    fs::{create_dir_all, read_dir, OpenOptions},
    io::{AsyncRead, AsyncWrite, AsyncWriteExt},
};

#[derive(Parser)]
pub struct LocalFsOpt {
    #[clap(
        long = "dir",
        parse(from_os_str),
        help = "Target local dir to hold backups."
    )]
    pub dir: PathBuf,
}

/// A storage backend that stores everything in a local directory.
pub struct LocalFs {
    /// The path where everything is stored.
    dir: PathBuf,
}

impl LocalFs {
    const METADATA_DIR: &'static str = "metadata";

    pub fn new(dir: PathBuf) -> Self {
        Self { dir }
    }

    pub fn new_with_opt(opt: LocalFsOpt) -> Self {
        Self::new(opt.dir)
    }

    pub fn metadata_dir(&self) -> PathBuf {
        self.dir.join(Self::METADATA_DIR)
    }
}

#[async_trait]
impl BackupStorage for LocalFs {
    async fn create_backup(&self, name: &ShellSafeName) -> Result<BackupHandle> {
        create_dir_all(self.dir.join(name.as_ref()))
            .await
            .err_notes(self.dir.join(name.as_ref()))?;
        Ok(name.to_string())
    }

    async fn create_for_write(
        &self,
        backup_handle: &BackupHandleRef,
        name: &ShellSafeName,
    ) -> Result<(FileHandle, Box<dyn AsyncWrite + Send + Unpin>)> {
        let file_handle = Path::new(backup_handle)
            .join(name.as_ref())
            .path_to_string()?;
        let abs_path = self.dir.join(&file_handle).path_to_string()?;
        let file = OpenOptions::new()
            .write(true)
            .create_new(true)
            .open(&abs_path)
            .await
            .err_notes(&abs_path)?;
        Ok((file_handle, Box::new(file)))
    }

    async fn open_for_read(
        &self,
        file_handle: &FileHandleRef,
    ) -> Result<Box<dyn AsyncRead + Send + Unpin>> {
        let path = self.dir.join(file_handle);
        let file = OpenOptions::new()
            .read(true)
            .open(&path)
            .await
            .err_notes(&path)?;
        Ok(Box::new(file))
    }

    async fn save_metadata_line(&self, name: &ShellSafeName, content: &TextLine) -> Result<()> {
        let dir = self.metadata_dir();
        create_dir_all(&dir).await.err_notes(name)?; // in case not yet created

        let path = dir.join(name.as_ref());
        let mut file = OpenOptions::new()
            .write(true)
            .create_new(true)
            .open(&path)
            .await
            .err_notes(&path)?;
        file.write_all(content.as_ref().as_bytes())
            .await
            .err_notes(&path)?;

        Ok(())
    }

    async fn list_metadata_files(&self) -> Result<Vec<FileHandle>> {
        let dir = self.metadata_dir();
        let rel_path = Path::new(Self::METADATA_DIR);

        let mut res = Vec::new();
        if path_exists(&dir).await {
            let mut entries = read_dir(&dir).await.err_notes(&dir)?;
            while let Some(entry) = entries.next_entry().await.err_notes(&dir)? {
                res.push(rel_path.join(entry.file_name()).path_to_string()?)
            }
        }
        Ok(res)
    }
}
<|endoftext|>