<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(collections)]

extern crate crypto;
extern crate rand;

use crypto::{ symmetriccipher, buffer, aes, blockmodes };
use crypto::buffer::{ ReadBuffer, WriteBuffer, BufferResult };

use rand::{ Rng, OsRng };

// Encrypt a buffer with the given key and iv using
// AES-256/CBC/Pkcs encryption.
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {

    // Create an encryptor instance of the best performing
    // type available for the platform.
    let mut encryptor = aes::cbc_encryptor(
            aes::KeySize::KeySize256,
            key,
            iv,
            blockmodes::PkcsPadding);

    // Each encryption operation encrypts some data from
    // an input buffer into an output buffer. Those buffers
    // must be instances of RefReaderBuffer and RefWriteBuffer
    // (respectively) which keep track of how much data has been
    // read from or written to them.
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    // Each encryption operation will "make progress". "Making progress"
    // is a bit loosely defined, but basically, at the end of each operation
    // either BufferUnderflow or BufferOverflow will be returned (unless
    // there was an error). If the return value is BufferUnderflow, it means
    // that the operation ended while wanting more input data. If the return
    // value is BufferOverflow, it means that the operation ended because it
    // needed more space to output data. As long as the next call to the encryption
    // operation provides the space that was requested (either more input data
    // or more output space), the operation is guaranteed to get closer to
    // completing the full operation - ie: "make progress".
    //
    // Here, we pass the data to encrypt to the enryptor along with a fixed-size
    // output buffer. The 'true' flag indicates that the end of the data that
    // is to be encrypted is included in the input buffer (which is true, since
    // the input data includes all the data to encrypt). After each call, we copy
    // any output data to our result Vec. If we get a BufferOverflow, we keep
    // going in the loop since it means that there is more work to do. We can
    // complete as soon as we get a BufferUnderflow since the encryptor is telling
    // us that it stopped processing data due to not having any more data in the
    // input buffer.
    loop {
        let result = try!(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true));

        // "write_buffer.take_read_buffer().take_remaining()" means:
        // from the writable buffer, create a new readable buffer which
        // contains all data that has been written, and then access all
        // of that data as a slice.
        final_result.push_all(write_buffer.take_read_buffer().take_remaining());

        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => { }
        }
    }

    Ok(final_result)
}

// Decrypts a buffer with the given key and iv using
// AES-256/CBC/Pkcs encryption.
//
// This function is very similar to encrypt(), so, please reference
// comments in that function. In non-example code, if desired, it is possible to
// share much of the implementation using closures to hide the operation
// being performed. However, such code would make this example less clear.
fn decrypt(encrypted_data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = aes::cbc_decryptor(
            aes::KeySize::KeySize256,
            key,
            iv,
            blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        final_result.push_all(write_buffer.take_read_buffer().take_remaining());
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => { }
        }
    }

    Ok(final_result)
}

fn main() {
    let message = "Hello World!";

    let mut key: [u8; 32] = [0; 32];
    let mut iv: [u8; 16] = [0; 16];

    // In a real program, the key and iv may be determined
    // using some other mechanism. If a password is to be used
    // as a key, an algorithm like PBKDF2, Bcrypt, or Scrypt (all
    // supported by Rust-Crypto!) would be a good choice to derive
    // a password. For the purposes of this example, the key and
    // iv are just random values.
    let mut rng = OsRng::new().ok().unwrap();
    rng.fill_bytes(&mut key);
    rng.fill_bytes(&mut iv);

    let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap();
    let decrypted_data = decrypt(&encrypted_data[..], &key, &iv).ok().unwrap();

    assert!(message.as_bytes() == &decrypted_data[..]);
}
<commit_msg>Remove use of #![feature(collections)] from the symmetriccipher example<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate crypto;
extern crate rand;

use crypto::{ symmetriccipher, buffer, aes, blockmodes };
use crypto::buffer::{ ReadBuffer, WriteBuffer, BufferResult };

use rand::{ Rng, OsRng };

// Encrypt a buffer with the given key and iv using
// AES-256/CBC/Pkcs encryption.
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {

    // Create an encryptor instance of the best performing
    // type available for the platform.
    let mut encryptor = aes::cbc_encryptor(
            aes::KeySize::KeySize256,
            key,
            iv,
            blockmodes::PkcsPadding);

    // Each encryption operation encrypts some data from
    // an input buffer into an output buffer. Those buffers
    // must be instances of RefReaderBuffer and RefWriteBuffer
    // (respectively) which keep track of how much data has been
    // read from or written to them.
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    // Each encryption operation will "make progress". "Making progress"
    // is a bit loosely defined, but basically, at the end of each operation
    // either BufferUnderflow or BufferOverflow will be returned (unless
    // there was an error). If the return value is BufferUnderflow, it means
    // that the operation ended while wanting more input data. If the return
    // value is BufferOverflow, it means that the operation ended because it
    // needed more space to output data. As long as the next call to the encryption
    // operation provides the space that was requested (either more input data
    // or more output space), the operation is guaranteed to get closer to
    // completing the full operation - ie: "make progress".
    //
    // Here, we pass the data to encrypt to the enryptor along with a fixed-size
    // output buffer. The 'true' flag indicates that the end of the data that
    // is to be encrypted is included in the input buffer (which is true, since
    // the input data includes all the data to encrypt). After each call, we copy
    // any output data to our result Vec. If we get a BufferOverflow, we keep
    // going in the loop since it means that there is more work to do. We can
    // complete as soon as we get a BufferUnderflow since the encryptor is telling
    // us that it stopped processing data due to not having any more data in the
    // input buffer.
    loop {
        let result = try!(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true));

        // "write_buffer.take_read_buffer().take_remaining()" means:
        // from the writable buffer, create a new readable buffer which
        // contains all data that has been written, and then access all
        // of that data as a slice.
        final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));

        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => { }
        }
    }

    Ok(final_result)
}

// Decrypts a buffer with the given key and iv using
// AES-256/CBC/Pkcs encryption.
//
// This function is very similar to encrypt(), so, please reference
// comments in that function. In non-example code, if desired, it is possible to
// share much of the implementation using closures to hide the operation
// being performed. However, such code would make this example less clear.
fn decrypt(encrypted_data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = aes::cbc_decryptor(
            aes::KeySize::KeySize256,
            key,
            iv,
            blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => { }
        }
    }

    Ok(final_result)
}

fn main() {
    let message = "Hello World!";

    let mut key: [u8; 32] = [0; 32];
    let mut iv: [u8; 16] = [0; 16];

    // In a real program, the key and iv may be determined
    // using some other mechanism. If a password is to be used
    // as a key, an algorithm like PBKDF2, Bcrypt, or Scrypt (all
    // supported by Rust-Crypto!) would be a good choice to derive
    // a password. For the purposes of this example, the key and
    // iv are just random values.
    let mut rng = OsRng::new().ok().unwrap();
    rng.fill_bytes(&mut key);
    rng.fill_bytes(&mut iv);

    let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap();
    let decrypted_data = decrypt(&encrypted_data[..], &key, &iv).ok().unwrap();

    assert!(message.as_bytes() == &decrypted_data[..]);
}
<|endoftext|>


<commit_before>extern crate yaml_rust;
use self::yaml_rust::{YamlLoader, Yaml};

pub fn from_yaml(yaml_file: String) -> Vec<String> {
    let docs = YamlLoader::load_from_str(&yaml_file).unwrap();
    let doc = &docs[0];

    let key = Yaml::from_str("default");
    let default_command_list = doc.as_hash().unwrap().get(&key).unwrap();
    let yaml_commands = default_command_list.as_vec().unwrap();

    let mut result_commands = Vec::new();
    result_commands.extend(
        yaml_commands.iter().map(|e| element.as_str().unwrap().to_string()
    )

    result_commands
}
<commit_msg>Use a plain map and avoid copying<commit_after>extern crate yaml_rust;
use self::yaml_rust::{YamlLoader, Yaml};

pub fn from_yaml(yaml_file: String) -> Vec<String> {
    let docs = YamlLoader::load_from_str(&yaml_file).unwrap();
    let doc = &docs[0];

    let key = Yaml::from_str("default");
    let default_command_list = doc.as_hash().unwrap().get(&key).unwrap();
    let yaml_commands = default_command_list.as_vec().unwrap();
    yaml_commands.iter()
                 .map(|e| e.as_str().expect("expected string").to_string())
                 .collect::<Vec<_>>()
}
<|endoftext|>


<commit_before>use std::error::Error;

use diesel::*;
use diesel::backend::Backend;
use diesel::expression::NonAggregate;
use diesel::query_builder::{QueryId, QueryFragment};
use diesel::types::FromSql;
#[cfg(feature="postgres")]
use diesel::pg::Pg;
#[cfg(feature="mysql")]
use diesel::mysql::Mysql;

use table_data::TableData;
use super::data_structures::*;

pub trait UsesInformationSchema: Backend {
    type TypeColumn: SelectableExpression<
        self::information_schema::columns::table,
        types::Text,
    > + NonAggregate + QueryId + QueryFragment<Self>;

    fn type_column() -> Self::TypeColumn;
}

#[cfg(feature="postgres")]
impl UsesInformationSchema for Pg {
    type TypeColumn = self::information_schema::columns::udt_name;

    fn type_column() -> Self::TypeColumn {
        self::information_schema::columns::udt_name
    }
}

#[cfg(feature="mysql")]
impl UsesInformationSchema for Mysql {
    type TypeColumn = self::information_schema::columns::column_type;

    fn type_column() -> Self::TypeColumn {
        self::information_schema::columns::column_type
    }
}

mod information_schema {
    table! {
        information_schema.tables (table_schema, table_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            table_type -> VarChar,
        }
    }

    table! {
        information_schema.columns (table_schema, table_name, column_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            column_name -> VarChar,
            is_nullable -> VarChar,
            ordinal_position -> BigInt,
            udt_name -> VarChar,
            column_type -> VarChar,
        }
    }

    table! {
        information_schema.key_column_usage (table_schema, table_name, column_name, constraint_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            column_name -> VarChar,
            constraint_name -> VarChar,
            ordinal_position -> BigInt,
        }
    }

    table! {
        information_schema.table_constraints (table_schema, table_name, constraint_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            constraint_name -> VarChar,
            constraint_type -> VarChar,
        }
    }
}

pub fn determine_column_type(attr: &ColumnInformation) -> Result<ColumnType, Box<Error>> {
    let is_array = attr.type_name.starts_with('_');
    let tpe = if is_array {
        &attr.type_name[1..]
    } else {
        &attr.type_name
    };

    let tpe = if let Some(idx) = tpe.find('(') {
        &tpe[..idx]
    } else {
        tpe
    };

    Ok(ColumnType {
        path: vec!["diesel".into(), "types".into(), capitalize(tpe)],
        is_array: is_array,
        is_nullable: attr.nullable,
    })
}

fn capitalize(name: &str) -> String {
    name[..1].to_uppercase() + &name[1..]
}

pub fn get_table_data<Conn>(conn: &Conn, table: &TableData)
    -> QueryResult<Vec<ColumnInformation>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::columns::dsl::*;

    let type_column = <Conn::Backend as UsesInformationSchema>::type_column();
    columns.select((column_name, type_column, is_nullable))
        .filter(table_name.eq(&table.name))
        .filter(table_schema.nullable().eq(&table.schema))
        .order(ordinal_position)
        .load(conn)
}

pub fn get_primary_keys<Conn>(conn: &Conn, table: &TableData)
    -> QueryResult<Vec<String>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::table_constraints::{self, constraint_type};
    use self::information_schema::key_column_usage::dsl::*;

    let pk_query = table_constraints::table.select(table_constraints::constraint_name)
        .filter(constraint_type.eq("PRIMARY KEY"));

    key_column_usage.select(column_name)
        .filter(constraint_name.eq_any(pk_query))
        .filter(table_name.eq(&table.name))
        .filter(table_schema.nullable().eq(&table.schema))
        .order(ordinal_position)
        .load(conn)
}

pub fn load_table_names<Conn>(connection: &Conn, schema_name: Option<&str>)
    -> Result<Vec<TableData>, Box<Error>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::tables::dsl::*;

    let schema_name = schema_name.unwrap_or("public");

    tables.select((table_name, table_schema))
        .filter(table_schema.eq(schema_name))
        .filter(table_name.not_like("\\_\\_%"))
        .filter(table_type.like("BASE TABLE"))
        .load(connection)
        .map_err(Into::into)
}

#[cfg(all(test, feature="postgres"))]
mod tests {
    extern crate dotenv;

    use diesel::pg::PgConnection;
    use self::dotenv::dotenv;
    use std::env;
    use super::*;

    fn connection() -> PgConnection {
        let _ = dotenv();

        let connection_url = env::var("PG_DATABASE_URL")
            .or_else(|_| env::var("DATABASE_URL"))
            .expect("DATABASE_URL must be set in order to run tests");
        let connection = PgConnection::establish(&connection_url).unwrap();
        connection.begin_test_transaction().unwrap();
        connection
    }

    #[test]
    fn skip_views() {
        let connection = connection();

        connection.execute("CREATE TABLE a_regular_table (id SERIAL PRIMARY KEY)").unwrap();
        connection.execute("CREATE VIEW a_view AS SELECT 42").unwrap();

        let table_names = load_table_names(&connection, None).unwrap();

        assert!(table_names.contains(&TableData::new("a_regular_table", "public")));
        assert!(!table_names.contains(&TableData::new("a_view", "public")));
    }

    #[test]
    fn load_table_names_loads_from_public_schema_if_none_given() {
        let connection = connection();

        connection.execute("CREATE TABLE load_table_names_loads_from_public_schema_if_none_given (id SERIAL PRIMARY KEY)")
            .unwrap();

        let table_names = load_table_names(&connection, None).unwrap();
        for TableData { schema, .. } in table_names {
            assert_eq!(Some("public".into()), schema);
        }
    }

    #[test]
    fn load_table_names_loads_from_custom_schema() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        assert_eq!(vec![TableData::new("table_1", "test_schema")], table_names);

        connection.execute("CREATE TABLE test_schema.table_2 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        let expected = vec![
            TableData::new("table_1", "test_schema"),
            TableData::new("table_2", "test_schema"),
        ];
        assert_eq!(expected, table_names);

        connection.execute("CREATE SCHEMA other_test_schema").unwrap();
        connection.execute("CREATE TABLE other_test_schema.table_1 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        let expected = vec![
            TableData::new("table_1", "test_schema"),
            TableData::new("table_2", "test_schema"),
        ];
        assert_eq!(expected, table_names);
        let table_names = load_table_names(&connection, Some("other_test_schema")).unwrap();
        assert_eq!(vec![TableData::new("table_1", "other_test_schema")], table_names);
    }

    #[test]
    fn get_primary_keys_only_includes_primary_key() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY, not_id INTEGER)").unwrap();
        connection.execute("CREATE TABLE test_schema.table_2 (id INTEGER, id2 INTEGER, not_id INTEGER, PRIMARY KEY (id, id2))").unwrap();

        let table_1 = TableData::new("table_1", "test_schema");
        let table_2 = TableData::new("table_2", "test_schema");
        assert_eq!(vec!["id".to_string()], get_primary_keys(&connection, &table_1).unwrap());
        assert_eq!(vec!["id".to_string(), "id2".to_string()], get_primary_keys(&connection, &table_2).unwrap());
    }

    #[test]
    fn get_table_data_loads_column_information() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY, text_col VARCHAR, not_null TEXT NOT NULL)").unwrap();
        connection.execute("CREATE TABLE test_schema.table_2 (array_col VARCHAR[] NOT NULL)").unwrap();

        let table_1 = TableData::new("table_1", "test_schema");
        let table_2 = TableData::new("table_2", "test_schema");
        let id = ColumnInformation::new("id", "int4", false);
        let text_col = ColumnInformation::new("text_col", "varchar", true);
        let not_null = ColumnInformation::new("not_null", "text", false);
        let array_col = ColumnInformation::new("array_col", "_varchar", false);
        assert_eq!(Ok(vec![id, text_col, not_null]), get_table_data(&connection, &table_1));
        assert_eq!(Ok(vec![array_col]), get_table_data(&connection, &table_2));
    }
}
<commit_msg>Ensure MySQL schema inference loads tables when no schema given<commit_after>use std::error::Error;

use diesel::*;
use diesel::backend::Backend;
use diesel::expression::NonAggregate;
use diesel::query_builder::{QueryId, QueryFragment};
use diesel::types::FromSql;
#[cfg(feature="postgres")]
use diesel::pg::Pg;
#[cfg(feature="mysql")]
use diesel::mysql::Mysql;

use table_data::TableData;
use super::data_structures::*;

pub trait UsesInformationSchema: Backend {
    type TypeColumn: SelectableExpression<
        self::information_schema::columns::table,
        types::Text,
    > + NonAggregate + QueryId + QueryFragment<Self>;

    fn type_column() -> Self::TypeColumn;
    fn default_schema<C>(conn: &C) -> QueryResult<String> where
        C: Connection,
        String: FromSql<types::Text, C::Backend>;
}

#[cfg(feature="postgres")]
impl UsesInformationSchema for Pg {
    type TypeColumn = self::information_schema::columns::udt_name;

    fn type_column() -> Self::TypeColumn {
        self::information_schema::columns::udt_name
    }

    fn default_schema<C>(_conn: &C) -> QueryResult<String> {
        Ok("public".into())
    }
}

#[cfg(feature="mysql")]
impl UsesInformationSchema for Mysql {
    type TypeColumn = self::information_schema::columns::column_type;

    fn type_column() -> Self::TypeColumn {
        self::information_schema::columns::column_type
    }

    fn default_schema<C>(conn: &C) -> QueryResult<String> where
        C: Connection,
        String: FromSql<types::Text, C::Backend>,
    {
        no_arg_sql_function!(database, types::VarChar);
        select(database).get_result(conn)
    }
}

mod information_schema {
    table! {
        information_schema.tables (table_schema, table_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            table_type -> VarChar,
        }
    }

    table! {
        information_schema.columns (table_schema, table_name, column_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            column_name -> VarChar,
            is_nullable -> VarChar,
            ordinal_position -> BigInt,
            udt_name -> VarChar,
            column_type -> VarChar,
        }
    }

    table! {
        information_schema.key_column_usage (table_schema, table_name, column_name, constraint_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            column_name -> VarChar,
            constraint_name -> VarChar,
            ordinal_position -> BigInt,
        }
    }

    table! {
        information_schema.table_constraints (table_schema, table_name, constraint_name) {
            table_schema -> VarChar,
            table_name -> VarChar,
            constraint_name -> VarChar,
            constraint_type -> VarChar,
        }
    }
}

pub fn determine_column_type(attr: &ColumnInformation) -> Result<ColumnType, Box<Error>> {
    let is_array = attr.type_name.starts_with('_');
    let tpe = if is_array {
        &attr.type_name[1..]
    } else {
        &attr.type_name
    };

    let tpe = if let Some(idx) = tpe.find('(') {
        &tpe[..idx]
    } else {
        tpe
    };

    Ok(ColumnType {
        path: vec!["diesel".into(), "types".into(), capitalize(tpe)],
        is_array: is_array,
        is_nullable: attr.nullable,
    })
}

fn capitalize(name: &str) -> String {
    name[..1].to_uppercase() + &name[1..]
}

pub fn get_table_data<Conn>(conn: &Conn, table: &TableData)
    -> QueryResult<Vec<ColumnInformation>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::columns::dsl::*;

    let type_column = Conn::Backend::type_column();
    columns.select((column_name, type_column, is_nullable))
        .filter(table_name.eq(&table.name))
        .filter(table_schema.nullable().eq(&table.schema))
        .order(ordinal_position)
        .load(conn)
}

pub fn get_primary_keys<Conn>(conn: &Conn, table: &TableData)
    -> QueryResult<Vec<String>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::table_constraints::{self, constraint_type};
    use self::information_schema::key_column_usage::dsl::*;

    let pk_query = table_constraints::table.select(table_constraints::constraint_name)
        .filter(constraint_type.eq("PRIMARY KEY"));

    key_column_usage.select(column_name)
        .filter(constraint_name.eq_any(pk_query))
        .filter(table_name.eq(&table.name))
        .filter(table_schema.nullable().eq(&table.schema))
        .order(ordinal_position)
        .load(conn)
}

pub fn load_table_names<Conn>(connection: &Conn, schema_name: Option<&str>)
    -> Result<Vec<TableData>, Box<Error>> where
        Conn: Connection,
        Conn::Backend: UsesInformationSchema,
        String: FromSql<types::Text, Conn::Backend>,
{
    use self::information_schema::tables::dsl::*;

    let schema_name = match schema_name {
        Some(name) => name.into(),
        None => Conn::Backend::default_schema(connection)?,
    };

    tables.select((table_name, table_schema))
        .filter(table_schema.eq(schema_name))
        .filter(table_name.not_like("\\_\\_%"))
        .filter(table_type.like("BASE TABLE"))
        .load(connection)
        .map_err(Into::into)
}

#[cfg(all(test, feature="postgres"))]
mod tests {
    extern crate dotenv;

    use diesel::pg::PgConnection;
    use self::dotenv::dotenv;
    use std::env;
    use super::*;

    fn connection() -> PgConnection {
        let _ = dotenv();

        let connection_url = env::var("PG_DATABASE_URL")
            .or_else(|_| env::var("DATABASE_URL"))
            .expect("DATABASE_URL must be set in order to run tests");
        let connection = PgConnection::establish(&connection_url).unwrap();
        connection.begin_test_transaction().unwrap();
        connection
    }

    #[test]
    fn skip_views() {
        let connection = connection();

        connection.execute("CREATE TABLE a_regular_table (id SERIAL PRIMARY KEY)").unwrap();
        connection.execute("CREATE VIEW a_view AS SELECT 42").unwrap();

        let table_names = load_table_names(&connection, None).unwrap();

        assert!(table_names.contains(&TableData::new("a_regular_table", "public")));
        assert!(!table_names.contains(&TableData::new("a_view", "public")));
    }

    #[test]
    fn load_table_names_loads_from_public_schema_if_none_given() {
        let connection = connection();

        connection.execute("CREATE TABLE load_table_names_loads_from_public_schema_if_none_given (id SERIAL PRIMARY KEY)")
            .unwrap();

        let table_names = load_table_names(&connection, None).unwrap();
        for TableData { schema, .. } in table_names {
            assert_eq!(Some("public".into()), schema);
        }
    }

    #[test]
    fn load_table_names_loads_from_custom_schema() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        assert_eq!(vec![TableData::new("table_1", "test_schema")], table_names);

        connection.execute("CREATE TABLE test_schema.table_2 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        let expected = vec![
            TableData::new("table_1", "test_schema"),
            TableData::new("table_2", "test_schema"),
        ];
        assert_eq!(expected, table_names);

        connection.execute("CREATE SCHEMA other_test_schema").unwrap();
        connection.execute("CREATE TABLE other_test_schema.table_1 (id SERIAL PRIMARY KEY)").unwrap();

        let table_names = load_table_names(&connection, Some("test_schema")).unwrap();
        let expected = vec![
            TableData::new("table_1", "test_schema"),
            TableData::new("table_2", "test_schema"),
        ];
        assert_eq!(expected, table_names);
        let table_names = load_table_names(&connection, Some("other_test_schema")).unwrap();
        assert_eq!(vec![TableData::new("table_1", "other_test_schema")], table_names);
    }

    #[test]
    fn get_primary_keys_only_includes_primary_key() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY, not_id INTEGER)").unwrap();
        connection.execute("CREATE TABLE test_schema.table_2 (id INTEGER, id2 INTEGER, not_id INTEGER, PRIMARY KEY (id, id2))").unwrap();

        let table_1 = TableData::new("table_1", "test_schema");
        let table_2 = TableData::new("table_2", "test_schema");
        assert_eq!(vec!["id".to_string()], get_primary_keys(&connection, &table_1).unwrap());
        assert_eq!(vec!["id".to_string(), "id2".to_string()], get_primary_keys(&connection, &table_2).unwrap());
    }

    #[test]
    fn get_table_data_loads_column_information() {
        let connection = connection();

        connection.execute("CREATE SCHEMA test_schema").unwrap();
        connection.execute("CREATE TABLE test_schema.table_1 (id SERIAL PRIMARY KEY, text_col VARCHAR, not_null TEXT NOT NULL)").unwrap();
        connection.execute("CREATE TABLE test_schema.table_2 (array_col VARCHAR[] NOT NULL)").unwrap();

        let table_1 = TableData::new("table_1", "test_schema");
        let table_2 = TableData::new("table_2", "test_schema");
        let id = ColumnInformation::new("id", "int4", false);
        let text_col = ColumnInformation::new("text_col", "varchar", true);
        let not_null = ColumnInformation::new("not_null", "text", false);
        let array_col = ColumnInformation::new("array_col", "_varchar", false);
        assert_eq!(Ok(vec![id, text_col, not_null]), get_table_data(&connection, &table_1));
        assert_eq!(Ok(vec![array_col]), get_table_data(&connection, &table_2));
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/A%2BB
// not_tested

#![allow(unused_imports)]
use std::io::stdio::stdin;
use std::io::BufferedReader;

fn main() {
    let input = BufferedReader::new(stdin()).read_line().unwrap();
    let words = input.as_slice().words().take(2)
                            .map(from_str::<int>)
                            .collect::<Vec<Option<int>>>();

    let sum = match words.as_slice() {
        [Some(x), Some(y)] => x + y,
		_                  => fail!("Please enter 2 integers")
    };

    println!("{:i}", sum);
}
<commit_msg>a + b: stdin is buffered<commit_after>// Implements http://rosettacode.org/wiki/A%2BB
// not_tested

use std::io::stdio;

fn main() {
    let input = stdio::stdin().read_line().unwrap();
    let words = input.as_slice().words().take(2)
                            .map(from_str::<int>)
                            .collect::<Vec<Option<int>>>();

    let sum = match words.as_slice() {
        [Some(x), Some(y)] => x + y,
		    _ => fail!("Please enter 2 integers")
    };

    println!("{:i}", sum);
}
<|endoftext|>


<commit_before>// Copyright (c) Carl-Erwin Griffith
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without
// limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

use crate::core::codec::text::utf8;
use crate::core::codepointinfo::CodepointInfo;
use crate::core::mark::Mark;
use crate::core::screen::Screen;
use crate::core::view::View;

pub fn get_lines_offsets<'a>(
    view: &View<'a>,
    start_offset: u64,
    end_offset: u64,
    screen_width: usize,
    screen_height: usize,
) -> Vec<(u64, u64)> {
    let mut v = Vec::<(u64, u64)>::new();

    let mut m = Mark::new(start_offset);

    let doc = view.document.as_ref().unwrap().borrow_mut();

    let screen_width = ::std::cmp::max(1, screen_width);
    let screen_height = ::std::cmp::max(4, screen_height);

    // get beginning of the line @offset
    m.move_to_beginning_of_line(&doc.buffer, utf8::get_prev_codepoint);

    // and build tmp screens until end_offset if found
    let mut screen = Screen::new(screen_width, screen_height);

    let max_offset = doc.buffer.size as u64;
    let max_size = (screen_width * screen_height * 4) as usize;

    loop {
        // fill screen
        let mut data = vec![];
        doc.buffer.read(m.offset, max_size, &mut data);

        let _ = build_screen_layout(&data, m.offset, max_offset, &mut screen);

        // push lines offsets
        // FIXME: find a better way to iterate over the used lines
        for i in 0..screen.current_line_index {
            if !v.is_empty() && i == 0 {
                // do not push line range twice
                continue;
            }

            let s = screen.line[i].get_first_cpi().unwrap().offset;
            let e = screen.line[i].get_last_cpi().unwrap().offset;

            v.push((s, e));

            if s >= end_offset || e == max_offset {
                return v;
            }
        }

        // eof reached ?
        // FIXME: the api is not yet READY
        // we must find a way to cover all filled lines
        if screen.current_line_index < screen.height {
            let s = screen.line[screen.current_line_index]
                .get_first_cpi()
                .unwrap()
                .offset;

            let e = screen.line[screen.current_line_index]
                .get_last_cpi()
                .unwrap()
                .offset;
            v.push((s, e));
            return v;
        }

        // TODO: activate only in debug builds
        if 0 == 1 {
            match screen.find_cpi_by_offset(m.offset) {
                (Some(cpi), x, y) => {
                    assert_eq!(x, 0);
                    assert_eq!(y, 0);
                    assert_eq!(cpi.offset, m.offset);
                }
                _ => panic!("implementation error"),
            }
        }

        if let Some(l) = screen.get_last_used_line() {
            if let Some(cpi) = l.get_first_cpi() {
                m.offset = cpi.offset; // update next screen start
            }
        }

        screen.clear(); // prepare next screen
    }
}

//////////////////////////////////
// This function will run the configured filters
// until the screen is full or eof is reached
// the filters will be configured per view to allow multiple interpretation of the same document
// data will be replaced by a "FileMMap"
pub fn build_screen_layout(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    screen: &mut Screen,
) -> u64 {
    let max_cpi = screen.width * screen.height;

    // utf8
    let (vec, _) = decode_slice_to_vec(data, base_offset, max_offset, max_cpi);

    // hexa
    //let (vec, _) = raw_slice_to_hex_vec(data, base_offset, max_offset, max_cpi);

    screen.first_offset = base_offset;
    let mut last_pushed_offset = base_offset;
    let mut prev_cp = ' ';
    let mut column_count = 0;
    for cpi in &vec {
        if prev_cp == '\r' || prev_cp == '\n' {
            column_count = 0;
        }

        let (ok, _) = match (prev_cp, cpi.cp) {
            // TODO: handle \r\n
            (_, '\t') => {
                prev_cp = cpi.cp;
                let mut filtered_cp = *cpi;
                filtered_cp.displayed_cp = ' ';

                let mut last = (false, 0);

                let tab_size = 8;

                let padding = tab_size - (column_count % tab_size);

                for _ in 0..padding {
                    last = screen.push(filtered_cp);
                    // TODO: how to handle errors ?
                    column_count += 1;
                }
                last
            }

            _ => {
                prev_cp = cpi.cp;

                let last = screen.push(*cpi);
                // TODO: how to handle errors ?
                column_count += 1;
                last
            }
        };

        if !ok {
            break;
        }

        last_pushed_offset = cpi.offset;
    }

    screen.doc_max_offset = max_offset;
    screen.last_offset = last_pushed_offset;
    last_pushed_offset
}

fn decode_slice_to_vec(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    max_cpi: usize,
) -> (Vec<CodepointInfo>, u64) {
    let mut vec = Vec::with_capacity(max_cpi);

    let mut off: u64 = 0;
    let last_off = data.len() as u64;

    while off != last_off {
        let (cp, _, size) = utf8::get_codepoint(data, off);
        vec.push(filter_codepoint(cp, base_offset + off));
        off += size as u64;
        if vec.len() == max_cpi {
            break;
        }
    }

    // eof handling
    if base_offset + last_off == max_offset {
        vec.push(CodepointInfo {
            cp: ' ',
            displayed_cp: '$',
            offset: base_offset + last_off,
            is_selected: true,
        });
    }

    (vec, base_offset + off)
}

//
fn _raw_slice_to_hex_vec(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    max_cpi: usize,
) -> (Vec<CodepointInfo>, u64) {
    let mut vec = Vec::with_capacity(max_cpi);

    let mut off: u64 = base_offset;
    let last_off = data.len() as u64;

    let hexchars: [char; 16] = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
    ];

    while off < last_off {
        let mut width = 0;
        for i in 0..16 {
            if off + i >= last_off {
                break;
            }

            let hi: usize = (data[(off + i) as usize] >> 4) as usize;
            let low: usize = (data[(off + i) as usize] & 0x0f) as usize;

            let cp = hexchars[hi];
            vec.push(filter_codepoint(cp, off + i));
            let cp = hexchars[low];
            vec.push(filter_codepoint(cp, off + i));
            vec.push(filter_codepoint(' ', off + i));

            if vec.len() == max_cpi {
                break;
            }
            width += 1;
        }

        if 0 == 1 {
            vec.push(filter_codepoint('|', off + width));
            vec.push(filter_codepoint(' ', off + width));

            for i in 0..16 {
                if off + i >= last_off {
                    break;
                }

                let c: char = data[(off + i) as usize] as char;
                vec.push(filter_codepoint(c, off + i));
                if vec.len() == max_cpi {
                    break;
                }
            }
        }

        vec.push(filter_codepoint('\n', off));
        off += width;
    }

    // eof handling
    if last_off == max_offset {
        vec.push(CodepointInfo {
            cp: ' ',
            displayed_cp: '$',
            offset: last_off,
            is_selected: true,
        });
    }

    (vec, off)
}

// TODO return array of CodePointInfo  0x7f -> <ESC>
pub fn filter_codepoint(c: char, offset: u64) -> CodepointInfo {
    let displayed_cp: char = match c {
        '\r' | '\n' | '\t' => ' ',

        _ if c < ' ' => '�',

        _ if c == 0x7f as char => '�',

        _ => c,
    };

    CodepointInfo {
        cp: c,
        displayed_cp,
        offset,
        is_selected: false,
    }
}
<commit_msg>wip: prepare layout filters<commit_after>// Copyright (c) Carl-Erwin Griffith
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without
// limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

use crate::core::codec::text::utf8;
use crate::core::codepointinfo::CodepointInfo;
use crate::core::mark::Mark;
use crate::core::screen::Screen;
use crate::core::view::View;

pub struct Filter {}

pub struct FilterContext {}

// content_type == unicode
pub enum FilterData {
    Byte {
        val: u8,
    },

    Unicode {
        cp: u32,
        real_cp: u32,
        cp_index: u64, // be carefull used const u64 invalid_cp_index
        fragment_flag: bool,
        fragment_count: u32,
    },

    // codec_change
    CodecInfo {
        codec_id: u32,
        codec_context_id: u64, //
    },
}

pub struct FilterIoData {
    // general info
    is_valid: bool,
    end_of_pipe: bool, // skip
    quit: bool,        // close pipeline
    is_selected: bool,
    offset: u64,

    data: FilterData,
    // TODO: add style infos ?
}

/// This function computes start/end of lines between start_offset end_offset.

/// It (will) run the configured filters/plugins.

/// using the build_screen_layout function until end_offset is reached.

pub fn get_lines_offsets<'a>(
    view: &View<'a>,
    start_offset: u64,
    end_offset: u64,
    screen_width: usize,
    screen_height: usize,
) -> Vec<(u64, u64)> {
    let mut v = Vec::<(u64, u64)>::new();

    let mut m = Mark::new(start_offset);

    let doc = view.document.as_ref().unwrap().borrow_mut();

    let screen_width = ::std::cmp::max(1, screen_width);
    let screen_height = ::std::cmp::max(4, screen_height);

    // get beginning of the line @offset
    m.move_to_beginning_of_line(&doc.buffer, utf8::get_prev_codepoint);

    // and build tmp screens until end_offset if found
    let mut screen = Screen::new(screen_width, screen_height);

    let max_offset = doc.buffer.size as u64;
    let max_size = (screen_width * screen_height * 4) as usize;

    loop {
        // fill screen
        let mut data = vec![];
        doc.buffer.read(m.offset, max_size, &mut data);

        let _ = build_screen_layout(&data, m.offset, max_offset, &mut screen);

        // push lines offsets
        // FIXME: find a better way to iterate over the used lines
        for i in 0..screen.current_line_index {
            if !v.is_empty() && i == 0 {
                // do not push line range twice
                continue;
            }

            let s = screen.line[i].get_first_cpi().unwrap().offset;
            let e = screen.line[i].get_last_cpi().unwrap().offset;

            v.push((s, e));

            if s >= end_offset || e == max_offset {
                return v;
            }
        }

        // eof reached ?
        // FIXME: the api is not yet READY
        // we must find a way to cover all filled lines
        if screen.current_line_index < screen.height {
            let s = screen.line[screen.current_line_index]
                .get_first_cpi()
                .unwrap()
                .offset;

            let e = screen.line[screen.current_line_index]
                .get_last_cpi()
                .unwrap()
                .offset;
            v.push((s, e));
            return v;
        }

        // TODO: activate only in debug builds
        if 0 == 1 {
            match screen.find_cpi_by_offset(m.offset) {
                (Some(cpi), x, y) => {
                    assert_eq!(x, 0);
                    assert_eq!(y, 0);
                    assert_eq!(cpi.offset, m.offset);
                }
                _ => panic!("implementation error"),
            }
        }

        if let Some(l) = screen.get_last_used_line() {
            if let Some(cpi) = l.get_first_cpi() {
                m.offset = cpi.offset; // update next screen start
            }
        }

        screen.clear(); // prepare next screen
    }
}

// Trait filter context
fn utf8_filter(
    ctx: &mut FilterContext,
    filters_in: &mut Vec<FilterIoData>,
    filters_out: &mut Vec<FilterIoData>,
) -> u32 {
    0
}

/// This function can be considered as the core of the editor.

/// It will run the configured filters until the screen is filled or eof is reached.

/// TODO: pass list of filter function to be applied
/// 1 - utf8 || hexa
/// 2 - tabulation
pub fn build_screen_layout(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    screen: &mut Screen,
) -> u64 {
    let max_cpi = screen.width * screen.height;

    let mut filters_in: Vec<FilterIoData> = vec![]; // &mut Vec<FilterIoData>;
    let mut filter_out: Vec<FilterIoData> = vec![]; // &mut Vec<FilterIoData>,

    // always equal to number of filter ran
    let mut filter_ctx: Vec<FilterContext> = vec![]; // &mut Vec<FilterIoData>,

    // first internal pass : convert raw bytes to vec of FilterIoData::FilterData::Byte
    for (count, b) in data.iter().enumerate() {
        filters_in.push(FilterIoData {
            is_valid: true,
            end_of_pipe: false, // skip
            quit: false,        // close pipeline
            is_selected: false,
            offset: base_offset + count as u64,
            data: FilterData::Byte { val: *b },
        });
    }

    // init all filters with start_offset

    // utf8
    let (vec, _) = decode_slice_to_vec(data, base_offset, max_offset, max_cpi);

    // hexa
    //let (vec, _) = raw_slice_to_hex_vec(data, base_offset, max_offset, max_cpi);

    screen.first_offset = base_offset;
    let mut last_pushed_offset = base_offset;
    let mut prev_cp = ' ';
    let mut column_count = 0;
    for cpi in &vec {
        if prev_cp == '\r' || prev_cp == '\n' {
            column_count = 0;
        }

        let (ok, _) = match (prev_cp, cpi.cp) {
            // TODO: handle \r\n
            (_, '\t') => {
                prev_cp = cpi.cp;
                let mut filtered_cp = *cpi;
                filtered_cp.displayed_cp = ' ';

                let mut last = (false, 0);

                let tab_size = 8;

                let padding = tab_size - (column_count % tab_size);

                for _ in 0..padding {
                    last = screen.push(filtered_cp);
                    // TODO: how to handle errors ?
                    column_count += 1;
                }
                last
            }

            _ => {
                prev_cp = cpi.cp;

                let last = screen.push(*cpi);
                // TODO: how to handle errors ?
                column_count += 1;
                last
            }
        };

        if !ok {
            break;
        }

        last_pushed_offset = cpi.offset;
    }

    screen.doc_max_offset = max_offset;
    screen.last_offset = last_pushed_offset;
    last_pushed_offset
}

fn decode_slice_to_vec(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    max_cpi: usize,
) -> (Vec<CodepointInfo>, u64) {
    let mut vec = Vec::with_capacity(max_cpi);

    let mut off: u64 = 0;
    let last_off = data.len() as u64;

    while off != last_off {
        let (cp, _, size) = utf8::get_codepoint(data, off);
        vec.push(filter_codepoint(cp, base_offset + off));
        off += size as u64;
        if vec.len() == max_cpi {
            break;
        }
    }

    // eof handling
    if base_offset + last_off == max_offset {
        vec.push(CodepointInfo {
            cp: ' ',
            displayed_cp: '$',
            offset: base_offset + last_off,
            is_selected: true,
        });
    }

    (vec, base_offset + off)
}

//
fn _raw_slice_to_hex_vec(
    data: &[u8],
    base_offset: u64,
    max_offset: u64,
    max_cpi: usize,
) -> (Vec<CodepointInfo>, u64) {
    let mut vec = Vec::with_capacity(max_cpi);

    let mut off: u64 = base_offset;
    let last_off = data.len() as u64;

    let hexchars: [char; 16] = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
    ];

    while off < last_off {
        let mut width = 0;
        for i in 0..16 {
            if off + i >= last_off {
                break;
            }

            let hi: usize = (data[(off + i) as usize] >> 4) as usize;
            let low: usize = (data[(off + i) as usize] & 0x0f) as usize;

            let cp = hexchars[hi];
            vec.push(filter_codepoint(cp, off + i));
            let cp = hexchars[low];
            vec.push(filter_codepoint(cp, off + i));
            vec.push(filter_codepoint(' ', off + i));

            if vec.len() == max_cpi {
                break;
            }
            width += 1;
        }

        if 0 == 1 {
            vec.push(filter_codepoint('|', off + width));
            vec.push(filter_codepoint(' ', off + width));

            for i in 0..16 {
                if off + i >= last_off {
                    break;
                }

                let c: char = data[(off + i) as usize] as char;
                vec.push(filter_codepoint(c, off + i));
                if vec.len() == max_cpi {
                    break;
                }
            }
        }

        vec.push(filter_codepoint('\n', off));
        off += width;
    }

    // eof handling
    if last_off == max_offset {
        vec.push(CodepointInfo {
            cp: ' ',
            displayed_cp: '$',
            offset: last_off,
            is_selected: true,
        });
    }

    (vec, off)
}

// TODO return array of CodePointInfo  0x7f -> <ESC>
pub fn filter_codepoint(c: char, offset: u64) -> CodepointInfo {
    let displayed_cp: char = match c {
        '\r' | '\n' | '\t' => ' ',

        _ if c < ' ' => '�',

        _ if c == 0x7f as char => '�',

        _ => c,
    };

    CodepointInfo {
        cp: c,
        displayed_cp,
        offset,
        is_selected: false,
    }
}
<|endoftext|>


<commit_before>//! An echo server that just writes back everything that's written to it.

extern crate futures;
extern crate futures_io;
extern crate futures_mio;

use std::env;
use std::net::SocketAddr;

use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};

fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();

    // Create the event loop that will drive this server
    let mut l = futures_mio::Loop::new().unwrap();

    // Create a TCP listener which will listen for incoming connections
    let server = l.handle().tcp_listen(&addr);

    let done = server.and_then(move |socket| {
        // Once we've got the TCP listener, inform that we have it
        println!("Listening on: {}", addr);

        // Pull out the stream of incoming connections and then for each new
        // one spin up a new task copying data. We put the `socket` into a
        // `Arc` structure which then allows us to share it across the
        // read/write halves with a small shim.
        //
        // Finally we use the `io::copy` future to copy all data from the
        // reading half onto the writing half.
        socket.incoming().for_each(|(socket, addr)| {
            let socket = futures::lazy(|| futures::finished(TaskIo::new(socket)));
            let pair = socket.map(|s| s.split());
            let amt = pair.and_then(|(reader, writer)| copy(reader, writer));

            // Once all that is done we print out how much we wrote, and then
            // critically we *forget* this future which allows it to run
            // concurrently with other connections.
            amt.map(move |amt| {
                println!("wrote {} bytes to {}", amt, addr)
            }).forget();

            Ok(())
        })
    });
    l.run(done).unwrap();
}
<commit_msg>update comment and simplify echo example<commit_after>//! An echo server that just writes back everything that's written to it.

extern crate futures;
extern crate futures_io;
extern crate futures_mio;

use std::env;
use std::net::SocketAddr;

use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};

fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();

    // Create the event loop that will drive this server
    let mut l = futures_mio::Loop::new().unwrap();

    // Create a TCP listener which will listen for incoming connections
    let server = l.handle().tcp_listen(&addr);

    let done = server.and_then(move |socket| {
        // Once we've got the TCP listener, inform that we have it
        println!("Listening on: {}", addr);

        // Pull out the stream of incoming connections and then for each new
        // one spin up a new task copying data.
        //
        // We use the `io::copy` future to copy all data from the
        // reading half onto the writing half.
        socket.incoming().for_each(|(socket, addr)| {
            let (reader, writer) = TaskIo::new(socket).split();
            let amt = copy(reader, writer);

            // Once all that is done we print out how much we wrote, and then
            // critically we *forget* this future which allows it to run
            // concurrently with other connections.
            amt.map(move |amt| {
                println!("wrote {} bytes to {}", amt, addr)
            }).forget();

            Ok(())
        })
    });
    l.run(done).unwrap();
}
<|endoftext|>


<commit_before>#![deny(warnings)]
#![feature(question_mark)]

// TODO support reading from standard input

extern crate extra;
extern crate termion;

use std::env::args;
use std::fs::File;
use std::io::{self, Write, Read, StdoutLock};
use std::path::Path;

use extra::option::OptionalExt;

use termion::{clear, cursor, style, terminal_size};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::{IntoRawMode, RawTerminal};

static LONG_HELP: &'static str = /* @MANSTART{less} */ r#"
NAME
    less - view a text file.

SYNOPSIS
    less [-h | --help] [input]

DESCRIPTION
    This utility views text files. If no input file is specified as an argument, standard input is
    used.

OPTIONS
    --help, -h
        Print this manual page.

AUTHOR
    This program was written by MovingtoMars for Redox OS. Bugs, issues, or feature requests should
    be reported in the Github repository, 'redox-os/extrautils'.

COPYRIGHT
    Copyright (c) 2016 MovingtoMars

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    and associated documentation files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"#; /* @MANEND */

fn main() {
    let mut args = args().skip(1);
    let stdout = io::stdout();
    let mut stdout = stdout.lock();
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut stderr = io::stderr();

    if let Some(x) = args.next() {
        match x.as_str() {
            "--help" | "-h" => {
                // Print help.
                stdout.write(LONG_HELP.as_bytes()).try(&mut stderr);
                return;
            },
            filename => {
                let mut file = File::open(Path::new(filename)).try(&mut stderr);
                run(filename, &mut file, &mut stdin, &mut stdout).try(&mut stderr);
            }
        }

        if let Some(x) = args.next() {
            let mut file = File::open(Path::new(x.as_str())).try(&mut stderr);
            run(x.as_str(), &mut file, &mut stdin, &mut stdout).try(&mut stderr);
        }
    } else {
        writeln!(stderr, "Readin from stdin is not yet supported").try(&mut stderr);
        //run(&mut stdin, &mut stdin, &mut stdout, &mut stderr);
    };
}

struct Buffer {
    lines: Vec<String>,
    y_off: u16,
}

impl Buffer {
    fn new() -> Buffer {
        Buffer{
            lines: Vec::new(),
            y_off: 0,
        }
    }

    fn read(&mut self, from: &mut Read) -> std::io::Result<usize> {
        let mut tmp = String::new();
        let res = from.read_to_string(&mut tmp)?;

        self.lines.append(&mut tmp
            .as_str()
            .split("\n")
            .map(|x| {String::from(x)})
            .collect());

        Ok(res)
    }

    fn draw(&self, to: &mut RawTerminal<&mut StdoutLock>, w: u16, h: u16) -> std::io::Result<usize> {
        write!(to, "{}{}{}", clear::All, style::Reset, cursor::Goto(1, 1))?;

        let mut y = 0;
        let mut bytes_written = 0;

        let lines = if self.lines.len() <= h as usize {
            &self.lines
        } else if self.y_off as usize >= self.lines.len() {
            &self.lines[0..0]
        } else {
            &self.lines[self.y_off as usize..]
        };

        for line in lines {
            if line.len() > w as usize {
                bytes_written += to.write(line[..w as usize].as_bytes())?;
            } else {
                bytes_written += to.write(line.as_bytes())?;
            }

            y += 1;
            write!(to, "{}", cursor::Goto(1, y + 1))?;
            if y >= h {
                break;
            }
        }

        Ok(bytes_written)
    }

    fn scroll_up(&mut self) {
        if self.y_off > 0 {
            self.y_off -= 1;
        }
    }

    fn scroll_down(&mut self, height: u16) {
        if ((self.y_off + height) as usize) <= self.lines.len() {
            self.y_off += 1;
        }
    }
}

fn run(path: &str, file: &mut Read, controls: &mut Read, stdout: &mut StdoutLock) -> std::io::Result<()> {
    let mut stdout = stdout.into_raw_mode()?;

    let (w, h) = {
        let (w, h) = terminal_size()?;
        (w as u16, h as u16)
    };

    let mut buffer = Buffer::new();
    buffer.read(file)?;

    buffer.draw(&mut stdout, w, h - 1)?;

    write!(stdout, "{}{}{} Press q to exit.{}", cursor::Goto(1, h), style::Invert, path, style::NoInvert)?;

    stdout.flush()?;

    for c in controls.keys() {
        match c.unwrap() {
            Key::Char('q') => {
                write!(stdout, "{}{}{}", clear::All, style::Reset, cursor::Goto(1, 1))?;
                break;
            },
            Key::Char('b') | Key::PageUp => for _i in 1..h {
                buffer.scroll_up()
            },
            Key::Char(' ') | Key::PageDown => for _i in 1..h {
                buffer.scroll_down(h)
            },
            Key::Char('u') => for _i in 1..h/2 {
                buffer.scroll_up()
            },
            Key::Char('d') => for _i in 1..h/2 {
                buffer.scroll_down(h)
            },
            Key::Up | Key::Char('k') => buffer.scroll_up(),
            Key::Down | Key::Char('j') => buffer.scroll_down(h),
            _ => {},
        }

        buffer.draw(&mut stdout, w, h - 1)?;

        write!(stdout, "{}{}{} Press q to exit.{}", cursor::Goto(1, h), style::Invert, path, style::NoInvert)?;

        stdout.flush()?;
    }

    Ok(())
}
<commit_msg>WIP: Allow less to open tty is using stdin as input<commit_after>#![deny(warnings)]
#![feature(question_mark)]

// TODO support reading from standard input

extern crate extra;
extern crate termion;

use std::env::args;
use std::fs::File;
use std::io::{self, Write, Read, StdoutLock};
use std::path::Path;

use extra::option::OptionalExt;

use termion::{clear, cursor, style, terminal_size};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::{IntoRawMode, RawTerminal};

static LONG_HELP: &'static str = /* @MANSTART{less} */ r#"
NAME
    less - view a text file.

SYNOPSIS
    less [-h | --help] [input]

DESCRIPTION
    This utility views text files. If no input file is specified as an argument, standard input is
    used.

OPTIONS
    --help, -h
        Print this manual page.

AUTHOR
    This program was written by MovingtoMars for Redox OS. Bugs, issues, or feature requests should
    be reported in the Github repository, 'redox-os/extrautils'.

COPYRIGHT
    Copyright (c) 2016 MovingtoMars

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    and associated documentation files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"#; /* @MANEND */

#[cfg(target_os = "redox")]
fn terminal_path() -> String {
    use std::env;
    env::var("TTY").unwrap()
}

#[cfg(not(target_os = "redox"))]
fn terminal_path() -> String {
    "/dev/tty".to_string()
}

fn main() {
    let mut args = args().skip(1);
    let stdout = io::stdout();
    let mut stdout = stdout.lock();
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut stderr = io::stderr();

    if let Some(x) = args.next() {
        match x.as_str() {
            "--help" | "-h" => {
                // Print help.
                stdout.write(LONG_HELP.as_bytes()).try(&mut stderr);
                return;
            },
            filename => {
                let mut file = File::open(Path::new(filename)).try(&mut stderr);
                run(filename, &mut file, &mut stdin, &mut stdout).try(&mut stderr);
            }
        }

        if let Some(x) = args.next() {
            let mut file = File::open(Path::new(x.as_str())).try(&mut stderr);
            run(x.as_str(), &mut file, &mut stdin, &mut stdout).try(&mut stderr);
        }
    } else {
        let mut terminal = File::open(terminal_path()).try(&mut stderr);
        run("-", &mut stdin, &mut terminal, &mut stdout).try(&mut stderr);
    };
}

struct Buffer {
    lines: Vec<String>,
    y_off: u16,
}

impl Buffer {
    fn new() -> Buffer {
        Buffer{
            lines: Vec::new(),
            y_off: 0,
        }
    }

    fn read(&mut self, from: &mut Read) -> std::io::Result<usize> {
        let mut tmp = String::new();
        let res = from.read_to_string(&mut tmp)?;

        self.lines.append(&mut tmp
            .as_str()
            .split("\n")
            .map(|x| {String::from(x)})
            .collect());

        Ok(res)
    }

    fn draw(&self, to: &mut RawTerminal<&mut StdoutLock>, w: u16, h: u16) -> std::io::Result<usize> {
        write!(to, "{}{}{}", clear::All, style::Reset, cursor::Goto(1, 1))?;

        let mut y = 0;
        let mut bytes_written = 0;

        let lines = if self.lines.len() <= h as usize {
            &self.lines
        } else if self.y_off as usize >= self.lines.len() {
            &self.lines[0..0]
        } else {
            &self.lines[self.y_off as usize..]
        };

        for line in lines {
            if line.len() > w as usize {
                bytes_written += to.write(line[..w as usize].as_bytes())?;
            } else {
                bytes_written += to.write(line.as_bytes())?;
            }

            y += 1;
            write!(to, "{}", cursor::Goto(1, y + 1))?;
            if y >= h {
                break;
            }
        }

        Ok(bytes_written)
    }

    fn scroll_up(&mut self) {
        if self.y_off > 0 {
            self.y_off -= 1;
        }
    }

    fn scroll_down(&mut self, height: u16) {
        if ((self.y_off + height) as usize) <= self.lines.len() {
            self.y_off += 1;
        }
    }
}

fn run(path: &str, file: &mut Read, controls: &mut Read, stdout: &mut StdoutLock) -> std::io::Result<()> {
    let mut stdout = stdout.into_raw_mode()?;

    let (w, h) = {
        let (w, h) = terminal_size()?;
        (w as u16, h as u16)
    };

    let mut buffer = Buffer::new();
    buffer.read(file)?;

    buffer.draw(&mut stdout, w, h - 1)?;

    write!(stdout, "{}{}{} Press q to exit.{}", cursor::Goto(1, h), style::Invert, path, style::NoInvert)?;

    stdout.flush()?;

    for c in controls.keys() {
        match c.unwrap() {
            Key::Char('q') => {
                write!(stdout, "{}{}{}", clear::All, style::Reset, cursor::Goto(1, 1))?;
                break;
            },
            Key::Char('b') | Key::PageUp => for _i in 1..h {
                buffer.scroll_up()
            },
            Key::Char(' ') | Key::PageDown => for _i in 1..h {
                buffer.scroll_down(h)
            },
            Key::Char('u') => for _i in 1..h/2 {
                buffer.scroll_up()
            },
            Key::Char('d') => for _i in 1..h/2 {
                buffer.scroll_down(h)
            },
            Key::Up | Key::Char('k') => buffer.scroll_up(),
            Key::Down | Key::Char('j') => buffer.scroll_down(h),
            _ => {},
        }

        buffer.draw(&mut stdout, w, h - 1)?;

        write!(stdout, "{}{}{} Press q to exit.{}", cursor::Goto(1, h), style::Invert, path, style::NoInvert)?;

        stdout.flush()?;
    }

    Ok(())
}
<|endoftext|>


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

extern crate rocket;
extern crate failure;
extern crate rocket_contrib;
extern crate serde;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate ring;
extern crate diesel;
extern crate config;
#[macro_use]
extern crate clap;

extern crate _aardwolf as aardwolf;

use ring::rand::SystemRandom;
use rocket::Rocket;
use rocket_contrib::Template;
use diesel::pg::PgConnection;
use r2d2_diesel::ConnectionManager;
use config::Config;
use clap::App;
use std::path::PathBuf;
use std::env;

type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

fn db_pool(rocket: &Rocket) -> Pool {
    let database_url = rocket.config().get_str("database_url").expect("Must set Database.url in config");
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    r2d2::Pool::builder().build(manager).expect("Could not get DB connection pool")
}

fn app(config: config::Config) -> Rocket {
    let mut db_url = String::new();
    match config.get_str("Database.type").unwrap().to_lowercase().as_str() {
        "postgresql" | "postgres" => db_url.push_str("postgres://"),

        // If we reach this case, it's an error.
        // TODO: Handle it.
        _ => {}
    }

    db_url.push_str(config.get_str("Database.username").unwrap().as_str());
    db_url.push(':');
    db_url.push_str(config.get_str("Database.password").unwrap().as_str());
    db_url.push('@');
    db_url.push_str(config.get_str("Database.host").unwrap().as_str());
    db_url.push(':');
    db_url.push_str(config.get_str("Database.port").unwrap().as_str());
    db_url.push('/');
    db_url.push_str(config.get_str("Database.database").unwrap().as_str());

    let c = rocket::Config::build(rocket::config::Environment::Development)
        .address(config.get_str("Listen.address").unwrap())
        .port(config.get::<u16>("Listen.port").unwrap())
        .extra("database_url", db_url.as_str())
        .unwrap();

    let r = rocket::custom(c, true)
        .mount("/api/v1", routes![
            aardwolf::routes::applications::register_application
        ])
        .mount("/", routes![
            aardwolf::routes::auth::sign_up_form,
            aardwolf::routes::auth::sign_in_form,
            aardwolf::routes::auth::sign_up,
            aardwolf::routes::auth::sign_in,
            aardwolf::routes::auth::confirm,
            aardwolf::routes::auth::sign_out,

            aardwolf::routes::app::home,
            aardwolf::routes::app::home_redirect,
        ])
        .attach(Template::fairing())
        .manage(SystemRandom::new());

    // we need an instance of the app to access the config values in Rocket.toml,
    // so we pass it to the db_pool function, get the pool, and _then_ return the instance
    let pool = db_pool(&r);
    r.manage(pool)
}

fn configure() -> Config {
    // Set defaults
    let mut config = Config::default();
    config.set_default::<&str>("cfg_file", concat!(env!("CARGO_PKG_NAME"), ".toml")).unwrap();
    config.set_default::<&str>("log_file", concat!(env!("CARGO_PKG_NAME"), ".log")).unwrap();
    config.set_default::<&str>("Listen.address", "127.0.0.1").unwrap();
    config.set_default("Listen.port", 7878).unwrap();

    // Parse arguments
    let yaml = load_yaml!("cli.yml");
    let args = App::from_yaml(yaml)
        .name(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .get_matches();

    // Determine config file
<<<<<<< HEAD
    // TODO: Is there a better way to handle this?
=======
>>>>>>> e5f41102321ceb65d8423c6817f79d0e9943ec3d
    match env::var("AARDWOLF_CONFIG") {
        Ok(c) => {config.set("cfg_file", c).unwrap();},
        Err(_) => {}
    }

    match args.value_of("config") {
        Some(c) => {config.set("cfg_file", c).unwrap();},
        None => {}
    }

    // Merge config file and apply over-rides
    let cfg_file: PathBuf = PathBuf::from(config.get_str("cfg_file").unwrap());
    config.merge(config::File::with_name(cfg_file.to_str().unwrap())).unwrap();

<<<<<<< HEAD
    //  TODO: Is there a better way to handle this?
    match env::var("AARDWOLF_LOG") {
        Ok(l) => {config.set("log_file", l).unwrap();},
        Err(_) => {}
    }

    match args.value_of("log") {
        Some(l) => {config.set("log_file", l).unwrap();},
        None => {}
    }

=======
>>>>>>> e5f41102321ceb65d8423c6817f79d0e9943ec3d
    config
}

fn main() {
    let config = configure();

    app(config).launch();
}
<commit_msg>Fix missed conflicts.<commit_after>#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(rocket_codegen)]

extern crate rocket;
extern crate failure;
extern crate rocket_contrib;
extern crate serde;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate ring;
extern crate diesel;
extern crate config;
#[macro_use]
extern crate clap;

extern crate _aardwolf as aardwolf;

use ring::rand::SystemRandom;
use rocket::Rocket;
use rocket_contrib::Template;
use diesel::pg::PgConnection;
use r2d2_diesel::ConnectionManager;
use config::Config;
use clap::App;
use std::path::PathBuf;
use std::env;

type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

fn db_pool(rocket: &Rocket) -> Pool {
    let database_url = rocket.config().get_str("database_url").expect("Must set Database.url in config");
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    r2d2::Pool::builder().build(manager).expect("Could not get DB connection pool")
}

fn app(config: config::Config) -> Rocket {
    let mut db_url = String::new();
    match config.get_str("Database.type").unwrap().to_lowercase().as_str() {
        "postgresql" | "postgres" => db_url.push_str("postgres://"),

        // If we reach this case, it's an error.
        // TODO: Handle it.
        _ => {}
    }

    db_url.push_str(config.get_str("Database.username").unwrap().as_str());
    db_url.push(':');
    db_url.push_str(config.get_str("Database.password").unwrap().as_str());
    db_url.push('@');
    db_url.push_str(config.get_str("Database.host").unwrap().as_str());
    db_url.push(':');
    db_url.push_str(config.get_str("Database.port").unwrap().as_str());
    db_url.push('/');
    db_url.push_str(config.get_str("Database.database").unwrap().as_str());

    let c = rocket::Config::build(rocket::config::Environment::Development)
        .address(config.get_str("Listen.address").unwrap())
        .port(config.get::<u16>("Listen.port").unwrap())
        .extra("database_url", db_url.as_str())
        .unwrap();

    let r = rocket::custom(c, true)
        .mount("/api/v1", routes![
            aardwolf::routes::applications::register_application
        ])
        .mount("/", routes![
            aardwolf::routes::auth::sign_up_form,
            aardwolf::routes::auth::sign_in_form,
            aardwolf::routes::auth::sign_up,
            aardwolf::routes::auth::sign_in,
            aardwolf::routes::auth::confirm,
            aardwolf::routes::auth::sign_out,

            aardwolf::routes::app::home,
            aardwolf::routes::app::home_redirect,
        ])
        .attach(Template::fairing())
        .manage(SystemRandom::new());

    // we need an instance of the app to access the config values in Rocket.toml,
    // so we pass it to the db_pool function, get the pool, and _then_ return the instance
    let pool = db_pool(&r);
    r.manage(pool)
}

fn configure() -> Config {
    // Set defaults
    let mut config = Config::default();
    config.set_default::<&str>("cfg_file", concat!(env!("CARGO_PKG_NAME"), ".toml")).unwrap();
    config.set_default::<&str>("log_file", concat!(env!("CARGO_PKG_NAME"), ".log")).unwrap();
    config.set_default::<&str>("Listen.address", "127.0.0.1").unwrap();
    config.set_default("Listen.port", 7878).unwrap();

    // Parse arguments
    let yaml = load_yaml!("cli.yml");
    let args = App::from_yaml(yaml)
        .name(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .get_matches();

    // Determine config file
    // TODO: Is there a better way to handle this?
    match env::var("AARDWOLF_CONFIG") {
        Ok(c) => {config.set("cfg_file", c).unwrap();},
        Err(_) => {}
    }

    match args.value_of("config") {
        Some(c) => {config.set("cfg_file", c).unwrap();},
        None => {}
    }

    // Merge config file and apply over-rides
    let cfg_file: PathBuf = PathBuf::from(config.get_str("cfg_file").unwrap());
    config.merge(config::File::with_name(cfg_file.to_str().unwrap())).unwrap();

    //  TODO: Is there a better way to handle this?
    match env::var("AARDWOLF_LOG") {
        Ok(l) => {config.set("log_file", l).unwrap();},
        Err(_) => {}
    }

    match args.value_of("log") {
        Some(l) => {config.set("log_file", l).unwrap();},
        None => {}
    }

    config
}

fn main() {
    let config = configure();

    app(config).launch();
}
<|endoftext|>


<commit_before>extern crate document;

use std::cmp::min;
use std::io::File;
use std::io::BufferedWriter;
use std::io::stdio::stdout_raw;

use document::parser::Parser;

fn pretty_error(xml: &str, position: uint) -> &str {
    let s = xml.slice_from(position);
    let l = s.char_len();
    s.slice_chars(0, min(l, 15))
}

fn main() {
    let mut args = std::os::args();

    let filename = args.remove(1).expect("File required");
    let path = Path::new(filename);
    let mut file = File::open(&path);

    let data = match file.read_to_end() {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let data = match String::from_utf8(data) {
        Ok(x) => x,
        Err(x) => panic!("Unable to convert to UTF-8: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(data.as_slice()) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(data.as_slice(), point)),
    };

    let mut out = BufferedWriter::new(stdout_raw());

    {
        let d = package.as_document();
        document::writer::format_document(&d, &mut out).ok().expect("I can't output");
    }
}
<commit_msg>No need to convert to a string when Reader will do it for us<commit_after>extern crate document;

use std::cmp::min;
use std::io::File;
use std::io::BufferedWriter;
use std::io::stdio::stdout_raw;

use document::parser::Parser;

fn pretty_error(xml: &str, position: uint) -> &str {
    let s = xml.slice_from(position);
    let l = s.char_len();
    s.slice_chars(0, min(l, 15))
}

fn main() {
    let mut args = std::os::args();

    let filename = args.remove(1).expect("File required");
    let path = Path::new(filename);
    let mut file = File::open(&path);

    let data = match file.read_to_string() {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(data.as_slice()) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(data.as_slice(), point)),
    };

    let mut out = BufferedWriter::new(stdout_raw());

    {
        let d = package.as_document();
        document::writer::format_document(&d, &mut out).ok().expect("I can't output");
    }
}
<|endoftext|>


<commit_before>//!

use super::list_of_types::{ListedTypeIndex, Sublist};
use std::ptr::{self, Shared};
use std::sync::atomic::AtomicUsize;
use std::any::Any;
use std::mem;

struct ArcInnerCommon <List: Sublist, CommonData: Any> {
  index: ListedTypeIndex <List>,
  references: AtomicUsize,
  data: CommonData,
}
#[repr(C)]
struct ArcInner <List: Sublist, CommonData: Any, SpecificData: Any> {
  common: ArcInnerAlways <List, CommonData>,
  data: SpecificData,
}
pub struct DynamicArc <List: Sublist, CommonData: Any> {
  pointer: Shared <ArcInnerCommon <List, CommonData>>,
}
pub struct TypedArc <List: Sublist, CommonData: Any, SpecificData: Any> {
  pointer: Shared <ArcInner <List, CommonData, SpecificData>>,
}

impl <List: Sublist, CommonData: Any, SpecificData: Any> TypedArc <List, CommonData, SpecificData> {
  fn erase_type (self)->DynamicArc <List, CommonData> {
    DynamicArc {pointer: unsafe {mem::transmute (self.pointer)}}
  }
}
impl <List: Sublist, CommonData: Any> DynamicArc <List, CommonData> {
  /// If it's not the correct type, return the original DynamicArc
  fn downcast <SpecificData: Any> (self)->Result <TypedArc <List, CommonData, SpecificData>, DynamicArc <List, CommonData>> {
    if unsafe {self.pointer.as_ref().index} == List::index:: <SpecificData> () {
      Ok (TypedArc {pointer: unsafe {mem::transmute (self.pointer)}})
    }
    else {
      Err (self)
    }
  }
}
<commit_msg>Renamed another thing<commit_after>//!

use super::list_of_types::{ListedTypeIndex, Sublist};
use std::ptr::{self, Shared};
use std::sync::atomic::AtomicUsize;
use std::any::Any;
use std::mem;

struct ArcInnerCommon <List: Sublist, CommonData: Any> {
  index: ListedTypeIndex <List>,
  references: AtomicUsize,
  data: CommonData,
}
#[repr(C)]
struct ArcInner <List: Sublist, CommonData: Any, DifferentiatedData: Any> {
  common: ArcInnerAlways <List, CommonData>,
  differentiated: DifferentiatedData,
}
pub struct DynamicArc <List: Sublist, CommonData: Any> {
  pointer: Shared <ArcInnerCommon <List, CommonData>>,
}
pub struct TypedArc <List: Sublist, CommonData: Any, DifferentiatedData: Any> {
  pointer: Shared <ArcInner <List, CommonData, DifferentiatedData>>,
}

impl <List: Sublist, CommonData: Any, DifferentiatedData: Any> TypedArc <List, CommonData, DifferentiatedData> {
  fn erase_type (self)->DynamicArc <List, CommonData> {
    DynamicArc {pointer: unsafe {mem::transmute (self.pointer)}}
  }
}
impl <List: Sublist, CommonData: Any> DynamicArc <List, CommonData> {
  /// If it's not the correct type, return the original DynamicArc
  fn downcast <DifferentiatedData: Any> (self)->Result <TypedArc <List, CommonData, DifferentiatedData>, DynamicArc <List, CommonData>> {
    if unsafe {self.pointer.as_ref().index} == List::index:: <DifferentiatedData> () {
      Ok (TypedArc {pointer: unsafe {mem::transmute (self.pointer)}})
    }
    else {
      Err (self)
    }
  }
}
<|endoftext|>


<commit_before>use crate::common::util::*;

use std::time::{Duration, Instant};

#[test]
fn test_sleep_no_suffix() {
    let millis_100 = Duration::from_millis(100);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.1"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_100);
}

#[test]
fn test_sleep_s_suffix() {
    let millis_100 = Duration::from_millis(100);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.1s"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_100);
}

#[test]
fn test_sleep_m_suffix() {
    let millis_600 = Duration::from_millis(600);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.01m"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_600);
}

#[test]
fn test_sleep_h_suffix() {
    let millis_360 = Duration::from_millis(360);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.0001h"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_360);
}

#[test]
fn test_sleep_negative_duration() {
    new_ucmd!().args(&["-1"]).fails();
    new_ucmd!().args(&["-1s"]).fails();
    new_ucmd!().args(&["-1m"]).fails();
    new_ucmd!().args(&["-1h"]).fails();
    new_ucmd!().args(&["-1d"]).fails();
}

#[test]
fn test_sleep_zero_duration() {
    new_ucmd!().args(&["0"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0s"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0m"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0h"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0d"]).succeeds().stdout_only("");
}

#[test]
fn test_sleep_no_argument() {
    new_ucmd!().fails();
}

#[test]
fn test_sleep_sum_duration_same_suffix() {
    let millis_200 = Duration::from_millis(100 + 100);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.1s"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_200);
}

#[test]
fn test_sleep_sum_duration_different_suffix() {
    let millis_700 = Duration::from_millis(100 + 600);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.01m"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_700);
}

#[test]
fn test_sleep_sum_duration_many() {
    let millis_900 = Duration::from_millis(100 + 100 + 300 + 400);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.1s", "0.3s", "0.4s"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_900);
}

#[test]
fn test_sleep_wrong_time() {
    new_ucmd!()
        .args(&["0.1s", "abc"])
        .fails();
}
<commit_msg>tests/sleep: fmt<commit_after>use crate::common::util::*;

use std::time::{Duration, Instant};

#[test]
fn test_sleep_no_suffix() {
    let millis_100 = Duration::from_millis(100);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.1"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_100);
}

#[test]
fn test_sleep_s_suffix() {
    let millis_100 = Duration::from_millis(100);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.1s"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_100);
}

#[test]
fn test_sleep_m_suffix() {
    let millis_600 = Duration::from_millis(600);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.01m"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_600);
}

#[test]
fn test_sleep_h_suffix() {
    let millis_360 = Duration::from_millis(360);
    let before_test = Instant::now();

    new_ucmd!().args(&["0.0001h"]).succeeds().stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_360);
}

#[test]
fn test_sleep_negative_duration() {
    new_ucmd!().args(&["-1"]).fails();
    new_ucmd!().args(&["-1s"]).fails();
    new_ucmd!().args(&["-1m"]).fails();
    new_ucmd!().args(&["-1h"]).fails();
    new_ucmd!().args(&["-1d"]).fails();
}

#[test]
fn test_sleep_zero_duration() {
    new_ucmd!().args(&["0"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0s"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0m"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0h"]).succeeds().stdout_only("");
    new_ucmd!().args(&["0d"]).succeeds().stdout_only("");
}

#[test]
fn test_sleep_no_argument() {
    new_ucmd!().fails();
}

#[test]
fn test_sleep_sum_duration_same_suffix() {
    let millis_200 = Duration::from_millis(100 + 100);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.1s"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_200);
}

#[test]
fn test_sleep_sum_duration_different_suffix() {
    let millis_700 = Duration::from_millis(100 + 600);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.01m"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_700);
}

#[test]
fn test_sleep_sum_duration_many() {
    let millis_900 = Duration::from_millis(100 + 100 + 300 + 400);
    let before_test = Instant::now();

    new_ucmd!()
        .args(&["0.1s", "0.1s", "0.3s", "0.4s"])
        .succeeds()
        .stdout_only("");

    let duration = before_test.elapsed();
    assert!(duration >= millis_900);
}

#[test]
fn test_sleep_wrong_time() {
    new_ucmd!().args(&["0.1s", "abc"]).fails();
}
<|endoftext|>


<commit_before>#[derive(Debug)]
pub enum ExpectedVersion {
    Exist,      // -4 to say that the stream should exist with any number of events in it.
    NoConflict, // -2 states that this write should never conflict with anything and should always succeed.
    NotExist,   // -1 states that the stream should not exist at the time of the writing (this write will create it)
    Empty,      //  0 states that the stream should exist but should be empty
    Number(u64)
}

impl From<ExpectedVersion> for String {
    fn from(version: ExpectedVersion) -> String {
        match version {
            ExpectedVersion::Exist => "-4".to_string(),
            ExpectedVersion::NoConflict => "-2".to_string(),
            ExpectedVersion::NotExist => "-1".to_string(),
            ExpectedVersion::Empty => "0".to_string(),
            ExpectedVersion::Number(n) => n.to_string()
        }
    }
}

impl From<String> for ExpectedVersion {
    fn from(string: String) -> ExpectedVersion {
        ExpectedVersion::NotExist
    }
}
<commit_msg>Implement `impl From<String> for ExpectedVersion`<commit_after>#[derive(Debug)]
pub enum ExpectedVersion {
    Number(u64),
    Empty,             //  0 states that the stream should exist but should be empty.
    NotExist,          // -1 states that the stream should not exist at the time of the writing (this write will create it).
    NoConflict,        // -2 states that this write should never conflict with anything and should always succeed.
    Exist,             // -4 to say that the stream should exist with any number of events in it.
    Unexpected(String) // Any string (including -3 OR less than or equal -5).
}

impl From<ExpectedVersion> for String {
    fn from(version: ExpectedVersion) -> String {
        match version {
            ExpectedVersion::Number(n) => n.to_string(),
            ExpectedVersion::Empty => "0".to_string(),
            ExpectedVersion::NotExist => "-1".to_string(),
            ExpectedVersion::NoConflict => "-2".to_string(),
            ExpectedVersion::Exist => "-4".to_string(),
            ExpectedVersion::Unexpected(s) => s,
        }
    }
}

impl From<String> for ExpectedVersion {
    fn from(string: String) -> ExpectedVersion {
        match string.as_ref() {
            "-4" => ExpectedVersion::Exist,
            "-2" => ExpectedVersion::NoConflict,
            "-1" => ExpectedVersion::NotExist,
            "0" => ExpectedVersion::Empty,
            _ => ExpectedVersion::parse_number_or_unexpected(string)
        }
    }
}

impl ExpectedVersion {
    fn parse_number_or_unexpected(string: String) -> ExpectedVersion {
        match string.parse::<u64>() {
            Ok(n) => if n >= 0 { ExpectedVersion::Number(n) } else { ExpectedVersion::Unexpected(string) },
            Err(_) => ExpectedVersion::Unexpected(string)
        }
    }
}
<|endoftext|>