<commit_before>use std::hash::Hash;
use std::path::Path;
use std::ops::{Deref, DerefMut};
use std::collections::HashMap;

use perlin_core::index::Index;
use perlin_core::index::posting::DocId;

use language::PipelineBucket;

mod filter;
mod hierarchy;

pub use field::filter::Filter;
pub use field::hierarchy::Hierarchy;

pub enum FieldSupplement<T> {
    None,
    Filter(Filter<T>),
    Hierarchy(Hierarchy<T>),
}

pub struct Field<T: Hash + Eq> {
    index: Index<T>,
    supplement: FieldSupplement<T>,
}

impl<T: Hash + Eq + Ord + Clone + 'static> Field<T> {
    pub fn commit(&mut self) {
        self.index.commit();

        if let FieldSupplement::Filter(ref mut filter) = self.supplement {
            filter.commit(&self.index);
        }
    }
}

impl<TTerm> PipelineBucket<TTerm> for Field<TTerm>
    where TTerm: Hash + Eq + Ord
{
    fn put(&mut self, doc_id: DocId, term: TTerm) {
        self.index.index_term(doc_id, term);
    }
}

impl<T: Hash + Eq> DerefMut for Field<T> {
    fn deref_mut(&mut self) -> &mut Index<T> {
        &mut self.index
    }
}

impl<T: Hash + Eq> Deref for Field<T> {
    type Target = Index<T>;
    fn deref(&self) -> &Index<T> {
        &self.index
    }
}

pub struct Fields<T: Hash + Eq> {
    pub fields: HashMap<String, Field<T>>,
}

impl<T: Hash + Eq + Ord> Fields<T> {
    pub fn commit(&mut self) {
        for field in self.fields.values_mut() {
            field.commit();
        }
    }

    pub fn add_field(&mut self,
                     name: String,
                     path: &Path,
                     supplement: FieldSupplement<T>)
                     -> Result<(), ()> {
        use perlin_core::page_manager::{RamPageCache, FsPageManager};
        use perlin_core::index::vocabulary::SharedVocabulary;
        use perlin_core::index::Index;
        if self.fields.contains_key(&name) {
            return Err(());
        } else {
            let page_cache =
                RamPageCache::new(FsPageManager::new(&path.join(format!("{}_page_cache", name))));
            self.fields.insert(name,
                               Field {
                                   index: Index::new(page_cache, SharedVocabulary::new()),
                                   supplement,
                               });
            return Ok(());
        }
    }

    pub fn new() -> Self {
        Fields { fields: HashMap::new() }
    }
}

#[cfg(test)]
mod tests {
    use perlin_core::index::posting::DocId;
    use field::{Fields};

    use rust_stemmers::Algorithm;

    #[derive(PerlinDocument)]
    pub struct FilterTest {
        body: Fields<String>,
    }
    // pub use self::perlin_impl::FilterTestIndex;
    // mod perlin_impl {
    //     use super::*;
    //     use std::path::{Path, PathBuf};
    //     use std::borrow::Cow;
    //     use document_index::Pipeline;
    //     use document_index::QueryPipeline;
    //     use document_index::QueryResultIterator;
    //     use query::Operand;
    //     use query::Query;
    //     use perlin_core::index::posting::{PostingIterator, DocId};
    //     use perlin_core::index::vocabulary::TermId;
    //     pub struct FilterTestIndex {
    //         pub documents: FilterTest,
    //         pub query_pipeline: Option<QueryPipeline<FilterTest>>,
    //         pub doc_counter: DocId,
    //     }
    //     impl FilterTestIndex {
    //         pub fn create(base_path: PathBuf) -> Self {
    //             FilterTestIndex {
    //                 documents: FilterTest::create(&base_path),
    //                 query_pipeline: None,
    //                 doc_counter: DocId::none(),
    //             }
    //         }
    //         pub fn commit(&mut self) {
    //             self.documents.commit();
    //         }
    // pub fn set_query_pipeline(&mut self, pipe:
    // QueryPipeline<FilterTest>) {
    //             self.query_pipeline = Some(pipe);
    //         }
    //         pub fn run_query<'a>(&'a self, query: Query<'a>) -> Operand<'a> {
    //             if let Some(ref query_pipe) = self.query_pipeline {
    //                 query_pipe(&self.documents, query)
    //             } else {
    //                 {
    //                     panic!()
    //                 };
    //             }
    //         }
    //     }
    //     impl FilterTest {
    //         pub fn create(path: &Path) -> Self {
    //             use perlin_core::page_manager::{RamPageCache, FsPageManager};
    //             use perlin_core::index::vocabulary::SharedVocabulary;
    //             use perlin_core::index::Index;
    //             let body_page_cache =
    //                 RamPageCache::new(
    // FsPageManager::new(&path.join("body_page_cache")));
    //             let number_page_cache =
    //                 RamPageCache::new(
    // FsPageManager::new(&path.join("number_page_cache")));
    //             FilterTest {
    //                 body: Index::new(body_page_cache, SharedVocabulary::new()),
    // number: FilterField::new(Index::new(number_page_cache,
    // SharedVocabulary::new())),
    //             }
    //         }
    //         pub fn commit(&mut self) {
    //             self.body.commit();
    //             self.number.commit();
    //         }
    //     }
    // }

}
<commit_msg>add term_doc_ratio to field<commit_after>use std::hash::Hash;
use std::path::Path;
use std::ops::{Deref, DerefMut};
use std::collections::HashMap;

use perlin_core::index::Index;
use perlin_core::index::posting::DocId;

use language::PipelineBucket;

mod filter;
mod hierarchy;

pub use field::filter::Filter;
pub use field::hierarchy::Hierarchy;

pub enum FieldSupplement<T> {
    None,
    Filter(Filter<T>),
    Hierarchy(Hierarchy<T>),
}

pub struct Field<T: Hash + Eq> {
    index: Index<T>,
    pub term_doc_ratio: f32,
    pub supplement: FieldSupplement<T>,
}

impl<T: Hash + Eq + Ord + Clone + 'static> Field<T> {
    pub fn commit(&mut self) {
        self.index.commit();

        if let FieldSupplement::Filter(ref mut filter) = self.supplement {
            filter.commit(&self.index);
        }
    }
}

impl<TTerm> PipelineBucket<TTerm> for Field<TTerm>
    where TTerm: Hash + Eq + Ord
{
    fn put(&mut self, doc_id: DocId, term: TTerm) {
        self.index.index_term(doc_id, term);
    }
}

impl<T: Hash + Eq> DerefMut for Field<T> {
    fn deref_mut(&mut self) -> &mut Index<T> {
        &mut self.index
    }
}

impl<T: Hash + Eq> Deref for Field<T> {
    type Target = Index<T>;
    fn deref(&self) -> &Index<T> {
        &self.index
    }
}

pub struct Fields<T: Hash + Eq> {
    pub fields: HashMap<String, Field<T>>,
}

impl<T: Hash + Eq + Ord> Fields<T> {
    pub fn commit(&mut self) {
        for field in self.fields.values_mut() {
            field.commit();
        }
    }

    pub fn add_field(&mut self,
                     name: String,
                     path: &Path,
                     supplement: FieldSupplement<T>)
                     -> Result<(), ()> {
        use perlin_core::page_manager::{RamPageCache, FsPageManager};
        use perlin_core::index::vocabulary::SharedVocabulary;
        use perlin_core::index::Index;
        if self.fields.contains_key(&name) {
            return Err(());
        } else {
            let page_cache =
                RamPageCache::new(FsPageManager::new(&path.join(format!("{}_page_cache", name))));
            self.fields.insert(name,
                               Field {
                                   index: Index::new(page_cache, SharedVocabulary::new()),
                                   term_doc_ratio: 1.0,
                                   supplement,
                               });
            return Ok(());
        }
    }

    pub fn new() -> Self {
        Fields { fields: HashMap::new() }
    }
}

#[cfg(test)]
mod tests {
    use perlin_core::index::posting::DocId;
    use field::{Fields};

    use rust_stemmers::Algorithm;

    #[derive(PerlinDocument)]
    pub struct FilterTest {
        body: Fields<String>,
    }
    // pub use self::perlin_impl::FilterTestIndex;
    // mod perlin_impl {
    //     use super::*;
    //     use std::path::{Path, PathBuf};
    //     use std::borrow::Cow;
    //     use document_index::Pipeline;
    //     use document_index::QueryPipeline;
    //     use document_index::QueryResultIterator;
    //     use query::Operand;
    //     use query::Query;
    //     use perlin_core::index::posting::{PostingIterator, DocId};
    //     use perlin_core::index::vocabulary::TermId;
    //     pub struct FilterTestIndex {
    //         pub documents: FilterTest,
    //         pub query_pipeline: Option<QueryPipeline<FilterTest>>,
    //         pub doc_counter: DocId,
    //     }
    //     impl FilterTestIndex {
    //         pub fn create(base_path: PathBuf) -> Self {
    //             FilterTestIndex {
    //                 documents: FilterTest::create(&base_path),
    //                 query_pipeline: None,
    //                 doc_counter: DocId::none(),
    //             }
    //         }
    //         pub fn commit(&mut self) {
    //             self.documents.commit();
    //         }
    // pub fn set_query_pipeline(&mut self, pipe:
    // QueryPipeline<FilterTest>) {
    //             self.query_pipeline = Some(pipe);
    //         }
    //         pub fn run_query<'a>(&'a self, query: Query<'a>) -> Operand<'a> {
    //             if let Some(ref query_pipe) = self.query_pipeline {
    //                 query_pipe(&self.documents, query)
    //             } else {
    //                 {
    //                     panic!()
    //                 };
    //             }
    //         }
    //     }
    //     impl FilterTest {
    //         pub fn create(path: &Path) -> Self {
    //             use perlin_core::page_manager::{RamPageCache, FsPageManager};
    //             use perlin_core::index::vocabulary::SharedVocabulary;
    //             use perlin_core::index::Index;
    //             let body_page_cache =
    //                 RamPageCache::new(
    // FsPageManager::new(&path.join("body_page_cache")));
    //             let number_page_cache =
    //                 RamPageCache::new(
    // FsPageManager::new(&path.join("number_page_cache")));
    //             FilterTest {
    //                 body: Index::new(body_page_cache, SharedVocabulary::new()),
    // number: FilterField::new(Index::new(number_page_cache,
    // SharedVocabulary::new())),
    //             }
    //         }
    //         pub fn commit(&mut self) {
    //             self.body.commit();
    //             self.number.commit();
    //         }
    //     }
    // }

}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::string;
use rustc_serialize::{Encodable, Encoder};

#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub enum Value {
    Null,
    Boolean(bool),
    Integer(i64),
    Float(f64),
    String(string::String),
    List(self::List),
    Map(self::Map),
}

pub type List = Vec<Value>;
pub type Map = BTreeMap<String, Value>;

impl<'a> Encodable for Value {
    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
        match *self {
            Value::Null => e.emit_nil(),
            Value::Boolean(v) => v.encode(e),
            Value::Integer(v) => v.encode(e),
            Value::Float(v) => v.encode(e),
            Value::String(ref v) => v.encode(e),
            Value::List(ref v) => v.encode(e),
            Value::Map(ref v) => v.encode(e),
        }
    }
}

#[cfg(test)]
mod tests {
    use ::v1::packstream::serialize::encode;
    use super::{Value, Map};

    #[test]
    fn serialize_null() {
        assert_eq!(encode(&()).unwrap(), encode(&Value::Null).unwrap());
    }

    #[test]
    fn serialize_bool() {
        assert_eq!(encode(&true).unwrap(), encode(&Value::Boolean(true)).unwrap());
        assert_eq!(encode(&false).unwrap(), encode(&Value::Boolean(false)).unwrap());
    }

    #[test]
    fn serialize_int() {
        assert_eq!(encode(&-9_223_372_036_854_775_808_i64).unwrap(), encode(&Value::Integer(-9_223_372_036_854_775_808_i64)).unwrap());
        assert_eq!(encode(&-2_147_483_648).unwrap(), encode(&Value::Integer(-2_147_483_648)).unwrap());
        assert_eq!(encode(&-32_768).unwrap(), encode(&Value::Integer(-32_768)).unwrap());
        assert_eq!(encode(&-128).unwrap(), encode(&Value::Integer(-128)).unwrap());
        assert_eq!(encode(&127).unwrap(), encode(&Value::Integer(127)).unwrap());
        assert_eq!(encode(&32_767).unwrap(), encode(&Value::Integer(32_767)).unwrap());
        assert_eq!(encode(&2_147_483_647).unwrap(), encode(&Value::Integer(2_147_483_647)).unwrap());
        assert_eq!(encode(&9_223_372_036_854_775_807_i64).unwrap(), encode(&Value::Integer(9_223_372_036_854_775_807_i64)).unwrap());
    }

    #[test]
    fn serialize_float() {
        assert_eq!(encode(&1.1).unwrap(), encode(&Value::Float(1.1)).unwrap());
        assert_eq!(encode(&-1.1).unwrap(), encode(&Value::Float(-1.1)).unwrap());
    }

    #[test]
    fn serialize_string() {
        assert_eq!(encode(&"abc".to_owned()).unwrap(), encode(&Value::String("abc".to_owned())).unwrap());
        assert_eq!(encode(&"abcdefghijklmnopqrstuvwxyz".to_owned()).unwrap(), encode(&Value::String("abcdefghijklmnopqrstuvwxyz".to_owned())).unwrap());
    }

    #[test]
    fn serialize_list() {
        assert_eq!(encode(&vec![1; 15]).unwrap(), encode(&Value::List(vec![Value::Integer(1); 15])).unwrap());
        assert_eq!(encode(&vec![1; 256]).unwrap(), encode(&Value::List(vec![Value::Integer(1); 256])).unwrap());
    }

    #[test]
    fn serialize_map() {
        let closure = |mut acc: Map, i: i64| { acc.insert(format!("{}", i), Value::Integer(i)); acc };
        let input = (0..15).fold(Map::new(), &closure);
        assert_eq!(encode(&input).unwrap(), encode(&Value::Map(input)).unwrap());

        let input = (0..256).fold(Map::new(), &closure);
        assert_eq!(encode(&input).unwrap(), encode(&Value::Map(input)).unwrap());
    }
}
<commit_msg>remove unnecessary lifetime<commit_after>use std::collections::BTreeMap;
use std::string;
use rustc_serialize::{Encodable, Encoder};

#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub enum Value {
    Null,
    Boolean(bool),
    Integer(i64),
    Float(f64),
    String(string::String),
    List(self::List),
    Map(self::Map),
}

pub type List = Vec<Value>;
pub type Map = BTreeMap<String, Value>;

impl Encodable for Value {
    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
        match *self {
            Value::Null => e.emit_nil(),
            Value::Boolean(v) => v.encode(e),
            Value::Integer(v) => v.encode(e),
            Value::Float(v) => v.encode(e),
            Value::String(ref v) => v.encode(e),
            Value::List(ref v) => v.encode(e),
            Value::Map(ref v) => v.encode(e),
        }
    }
}

#[cfg(test)]
mod tests {
    use ::v1::packstream::serialize::encode;
    use super::{Value, Map};

    #[test]
    fn serialize_null() {
        assert_eq!(encode(&()).unwrap(), encode(&Value::Null).unwrap());
    }

    #[test]
    fn serialize_bool() {
        assert_eq!(encode(&true).unwrap(), encode(&Value::Boolean(true)).unwrap());
        assert_eq!(encode(&false).unwrap(), encode(&Value::Boolean(false)).unwrap());
    }

    #[test]
    fn serialize_int() {
        assert_eq!(encode(&-9_223_372_036_854_775_808_i64).unwrap(), encode(&Value::Integer(-9_223_372_036_854_775_808_i64)).unwrap());
        assert_eq!(encode(&-2_147_483_648).unwrap(), encode(&Value::Integer(-2_147_483_648)).unwrap());
        assert_eq!(encode(&-32_768).unwrap(), encode(&Value::Integer(-32_768)).unwrap());
        assert_eq!(encode(&-128).unwrap(), encode(&Value::Integer(-128)).unwrap());
        assert_eq!(encode(&127).unwrap(), encode(&Value::Integer(127)).unwrap());
        assert_eq!(encode(&32_767).unwrap(), encode(&Value::Integer(32_767)).unwrap());
        assert_eq!(encode(&2_147_483_647).unwrap(), encode(&Value::Integer(2_147_483_647)).unwrap());
        assert_eq!(encode(&9_223_372_036_854_775_807_i64).unwrap(), encode(&Value::Integer(9_223_372_036_854_775_807_i64)).unwrap());
    }

    #[test]
    fn serialize_float() {
        assert_eq!(encode(&1.1).unwrap(), encode(&Value::Float(1.1)).unwrap());
        assert_eq!(encode(&-1.1).unwrap(), encode(&Value::Float(-1.1)).unwrap());
    }

    #[test]
    fn serialize_string() {
        assert_eq!(encode(&"abc".to_owned()).unwrap(), encode(&Value::String("abc".to_owned())).unwrap());
        assert_eq!(encode(&"abcdefghijklmnopqrstuvwxyz".to_owned()).unwrap(), encode(&Value::String("abcdefghijklmnopqrstuvwxyz".to_owned())).unwrap());
    }

    #[test]
    fn serialize_list() {
        assert_eq!(encode(&vec![1; 15]).unwrap(), encode(&Value::List(vec![Value::Integer(1); 15])).unwrap());
        assert_eq!(encode(&vec![1; 256]).unwrap(), encode(&Value::List(vec![Value::Integer(1); 256])).unwrap());
    }

    #[test]
    fn serialize_map() {
        let closure = |mut acc: Map, i: i64| { acc.insert(format!("{}", i), Value::Integer(i)); acc };
        let input = (0..15).fold(Map::new(), &closure);
        assert_eq!(encode(&input).unwrap(), encode(&Value::Map(input)).unwrap());

        let input = (0..256).fold(Map::new(), &closure);
        assert_eq!(encode(&input).unwrap(), encode(&Value::Map(input)).unwrap());
    }
}
<|endoftext|>


<commit_before>#![feature(env)]

extern crate postgres;
extern crate r2d2;
extern crate r2d2_postgres;
extern crate rustless;
extern crate typemap;
extern crate time;
extern crate "rustc-serialize" as rustc_serialize;
extern crate iron;

use std::env;
use rustc_serialize::json;

use rustless::prelude::*;

// A set of helpful types we need to shorten things
pub type PostgresPool = r2d2::Pool<r2d2_postgres::PostgresConnectionManager>;
pub type PostgresPooledConnection<'a> = r2d2::PooledConnection<'a, r2d2_postgres::PostgresConnectionManager>;

// A unit struct we need to store our pool into TypeMap
// See `typemap` docs for clarification.
pub struct AppDb;
impl ::typemap::Key for AppDb {
    type Value = PostgresPool;
}

// Let's create a shorthand function to simplify a DB access within our
// endpoints.
pub trait DatabaseExt: rustless::Extensible {
    fn db(&self) -> PostgresPooledConnection;
}
impl DatabaseExt for rustless::Application {
    fn db(&self) -> PostgresPooledConnection {
        self.ext().get::<AppDb>().unwrap().get().unwrap()
    }
}

/// Our main model
#[derive(Debug, RustcEncodable)]
pub struct Jedi {
    id: i32,
    name: String,
    force_level: i32
}

/// This function creates a pool of connections to PostgreSQL database
/// using `r2d2_postgres` functionality. See `r2d2_postgres` docs for clarification.
#[allow(dead_code)]
pub fn setup_db(connection_str: &str, pool_size: u32) -> PostgresPool {
    let manager = r2d2_postgres::PostgresConnectionManager::new(connection_str, postgres::SslMode::None);
    let config = r2d2::Config {
        pool_size: pool_size,
        test_on_check_out: true,
        ..::std::default::Default::default()
    };

    let handler = Box::new(r2d2::NoopErrorHandler);
    r2d2::Pool::new(config, manager, handler).unwrap()
}

/// The function creates and fills the main table of our data.
fn setup_tables(cn: &postgres::Connection) {
   cn.batch_execute(r#"
        DROP TABLE IF EXISTS jedi CASCADE;
        CREATE TABLE jedi (
            id          serial PRIMARY KEY,
            name        varchar(40) NOT NULL,
            force_level integer NOT NULL
        );

        INSERT INTO jedi (name, force_level) VALUES
            ('Luke Skywalker', 100),
            ('Mace Windu', 90),
            ('Obi-Wan Kenoby', 99),
            ('Kit Fisto', 70),
            ('Count Dooku', 99),
            ('Darth Maul', 70),
            ('Anakin Skywalker', 100);

    "#).unwrap();
}

#[allow(dead_code)]
fn main() {
    let api = rustless::Api::build(|api| {
        api.prefix("api");
        api.version("v1", rustless::Versioning::Path);

        api.get("jedi", |endpoint| {
            endpoint.handle(|mut client, _params| {
                // Note that .db() is an extension methods that we created with DatabaseExt
                let cn = client.app.db();

                // See `rust-postgres` docs for clarification.
                let statement = cn.prepare("SELECT id, name, force_level FROM jedi;").ok().expect("Connection is broken");
                let jedi_list: Vec<Jedi> = statement.query(&[]).unwrap().map(|row| {
                    Jedi {
                        id: row.get(0),
                        name: row.get(1),
                        force_level: row.get(2)
                    }
                }).collect();

                // Here we set right content type and send our answer back to the client
                client.set_json_content_type();
                client.text(json::encode(&jedi_list).ok().unwrap())
            })
        });
    });

    let mut app = rustless::Application::new(api);
    let connection_str = env::var_string("POSTGRES_CONNECTION").ok().expect("Provide POSTGRES_CONNECTION environment variable");
    let pool = setup_db(&connection_str[], 5);

    {
        // We create a new scope because we need the connection only for `setup_tables(..)` call
        let connection = pool.get().unwrap();
        setup_tables(&*connection);
    }

    // Here we use TypeMap to store out database pool
    app.ext.insert::<AppDb>(pool);

    // See `iron` docs for clarification.
    let chain = iron::Chain::new(app);
    iron::Iron::new(chain).listen("localhost:4000").unwrap();

    println!("On 4000");
}<commit_msg>refactor(example): use GenericConnection<commit_after>#![feature(env)]

extern crate postgres;
extern crate r2d2;
extern crate r2d2_postgres;
extern crate rustless;
extern crate typemap;
extern crate time;
extern crate "rustc-serialize" as rustc_serialize;
extern crate iron;

use std::env;
use rustc_serialize::json;

use rustless::prelude::*;

// A set of helpful types we need to shorten things
pub type PostgresPool = r2d2::Pool<r2d2_postgres::PostgresConnectionManager>;
pub type PostgresPooledConnection<'a> = r2d2::PooledConnection<'a, r2d2_postgres::PostgresConnectionManager>;

// A unit struct we need to store our pool into TypeMap
// See `typemap` docs for clarification.
pub struct AppDb;
impl ::typemap::Key for AppDb {
    type Value = PostgresPool;
}

// Let's create a shorthand function to simplify a DB access within our
// endpoints.
pub trait DatabaseExt: rustless::Extensible {
    fn db(&self) -> PostgresPooledConnection;
}
impl DatabaseExt for rustless::Application {
    fn db(&self) -> PostgresPooledConnection {
        self.ext().get::<AppDb>().unwrap().get().unwrap()
    }
}

/// Our main model
#[derive(Debug, RustcEncodable)]
pub struct Jedi {
    id: i32,
    name: String,
    force_level: i32
}

/// This function creates a pool of connections to PostgreSQL database
/// using `r2d2_postgres` functionality. See `r2d2_postgres` docs for clarification.
#[allow(dead_code)]
pub fn setup_db(connection_str: &str, pool_size: u32) -> PostgresPool {
    let manager = r2d2_postgres::PostgresConnectionManager::new(connection_str, postgres::SslMode::None);
    let config = r2d2::Config {
        pool_size: pool_size,
        test_on_check_out: true,
        ..::std::default::Default::default()
    };

    let handler = Box::new(r2d2::NoopErrorHandler);
    r2d2::Pool::new(config, manager, handler).unwrap()
}

/// The function creates and fills the main table of our data.
fn setup_tables(cn: &postgres::GenericConnection) {
   cn.batch_execute(r#"
        DROP TABLE IF EXISTS jedi CASCADE;
        CREATE TABLE jedi (
            id          serial PRIMARY KEY,
            name        varchar(40) NOT NULL,
            force_level integer NOT NULL
        );

        INSERT INTO jedi (name, force_level) VALUES
            ('Luke Skywalker', 100),
            ('Mace Windu', 90),
            ('Obi-Wan Kenoby', 99),
            ('Kit Fisto', 70),
            ('Count Dooku', 99),
            ('Darth Maul', 70),
            ('Anakin Skywalker', 100);

    "#).unwrap();
}

#[allow(dead_code)]
fn main() {
    let api = rustless::Api::build(|api| {
        api.prefix("api");
        api.version("v1", rustless::Versioning::Path);

        api.get("jedi", |endpoint| {
            endpoint.handle(|mut client, _params| {
                // Note that .db() is an extension methods that we created with DatabaseExt
                let cn = client.app.db();

                // See `rust-postgres` docs for clarification.
                let statement = cn.prepare("SELECT id, name, force_level FROM jedi;").ok().expect("Connection is broken");
                let jedi_list: Vec<Jedi> = statement.query(&[]).unwrap().map(|row| {
                    Jedi {
                        id: row.get(0),
                        name: row.get(1),
                        force_level: row.get(2)
                    }
                }).collect();

                // Here we set right content type and send our answer back to the client
                client.set_json_content_type();
                client.text(json::encode(&jedi_list).ok().unwrap())
            })
        });
    });

    let mut app = rustless::Application::new(api);
    let connection_str = env::var_string("POSTGRES_CONNECTION").ok().expect("Provide POSTGRES_CONNECTION environment variable");
    let pool = setup_db(&connection_str[], 5);

    {
        // We create a new scope because we need the connection only for `setup_tables(..)` call
        let connection = pool.get().unwrap();
        setup_tables(&*connection);
    }

    // Here we use TypeMap to store out database pool
    app.ext.insert::<AppDb>(pool);

    // See `iron` docs for clarification.
    let chain = iron::Chain::new(app);
    iron::Iron::new(chain).listen("localhost:4000").unwrap();

    println!("On 4000");
}<|endoftext|>


<commit_before>mod mat;
mod score;
pub mod bonus;
pub mod consts;

use std::ascii::AsciiExt;
pub use self::score::Score;

/// Searches for needle's chars in the haystack
///
/// # Examples
///
/// ```
/// assert!(rff::fuzzy::matches("amo", "app/models/order"));
/// ```
#[inline]
pub fn matches(needle: &str, haystack: &str) -> bool {
    if needle == "" || needle == haystack {
        return true;
    }

    let mut hchars = haystack.chars();

    needle.chars().all(|n| {
        while let Some(h) = hchars.next() {
            if eq(n, h) {
                return true
            }
        }

        false
    })
}

/// Compares two characters case-insensitively
#[inline(always)]
fn eq(a: char, b: char) -> bool {
    match a {
        _ if a == b => true,
        _ if a.is_ascii() || b.is_ascii() => a.eq_ignore_ascii_case(&b),
        _ => a.to_lowercase().eq(b.to_lowercase())
    }
}

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

    #[test]
    fn test_eq() {
        assert!(eq('a', 'A'));
        assert!(eq('山', '山'));
        assert!(!eq('a', 'b'));
    }

    #[test]
    fn test_matches() {
        assert!(matches("a", "a"));
        assert!(matches("a", "abc"));
        assert!(matches("abc", "abc"));
        assert!(matches("ABC", "abc"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("test", "t/e/s/t"));
        assert!(matches("test", "t💣e💣s💣t"));
        assert!(matches("💣💣💣", "t💣e💣s💣t"));

        assert!(!matches("abc", "ab"));
        assert!(!matches("abc", "cab"));
        assert!(!matches("abc", ""));

        assert!(matches("", ""));
        assert!(matches("", "ab"));

        // UTF-8 case testing
        assert!(matches("a", "A"));
        assert!(matches("A", "a"));
        assert!(matches("山", "山"));
        assert!(matches("café", "CAFÉ"));
        assert!(matches("weiß", "WEIẞ"));
    }
}
<commit_msg>Assert Cyrillic characters match correctly<commit_after>mod mat;
mod score;
pub mod bonus;
pub mod consts;

use std::ascii::AsciiExt;
pub use self::score::Score;

/// Searches for needle's chars in the haystack
///
/// # Examples
///
/// ```
/// assert!(rff::fuzzy::matches("amo", "app/models/order"));
/// ```
#[inline]
pub fn matches(needle: &str, haystack: &str) -> bool {
    if needle == "" || needle == haystack {
        return true;
    }

    let mut hchars = haystack.chars();

    needle.chars().all(|n| {
        while let Some(h) = hchars.next() {
            if eq(n, h) {
                return true
            }
        }

        false
    })
}

/// Compares two characters case-insensitively
#[inline(always)]
fn eq(a: char, b: char) -> bool {
    match a {
        _ if a == b => true,
        _ if a.is_ascii() || b.is_ascii() => a.eq_ignore_ascii_case(&b),
        _ => a.to_lowercase().eq(b.to_lowercase())
    }
}

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

    #[test]
    fn test_eq() {
        assert!(eq('a', 'A'));
        assert!(eq('山', '山'));
        assert!(!eq('a', 'b'));
    }

    #[test]
    fn test_matches() {
        assert!(matches("a", "a"));
        assert!(matches("a", "abc"));
        assert!(matches("abc", "abc"));
        assert!(matches("ABC", "abc"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("test", "t/e/s/t"));
        assert!(matches("test", "t💣e💣s💣t"));
        assert!(matches("💣💣💣", "t💣e💣s💣t"));

        assert!(!matches("abc", "ab"));
        assert!(!matches("abc", "cab"));
        assert!(!matches("abc", ""));

        assert!(matches("", ""));
        assert!(matches("", "ab"));

        // UTF-8 case testing
        assert!(matches("a", "A"));
        assert!(matches("A", "a"));
        assert!(matches("山", "山"));
        assert!(matches("café", "CAFÉ"));
        assert!(matches("weiß", "WEIẞ"));
        assert!(matches("хди́ь", "ХОДИ́ТЬ"));
    }
}
<|endoftext|>


<commit_before>extern crate log;
#[macro_use]
extern crate wlroots;

use std::{env, thread, process::Command};

use log::LevelFilter;
use wlroots::{area::{Area, Origin, Size},
              compositor,
              cursor::{self, Cursor, xcursor},
              input::{self, keyboard, pointer},
              output::{self, layout::Layout},
              render::{matrix, Renderer},
              seat::{self, Seat},
              shell::xdg_shell_v6,
              surface,
              utils::{Handleable, log::Logger, current_time}};
use wlroots::wlroots_sys::wlr_key_state::WLR_KEY_PRESSED;
use wlroots::xkbcommon::xkb::keysyms::{KEY_Escape, KEY_F1, KEY_XF86Switch_VT_1, KEY_XF86Switch_VT_12};
use wlroots::wlroots_dehandle;

struct State {
    xcursor_manager: xcursor::Manager,
    keyboard: Option<keyboard::Handle>,
    layout: output::layout::Handle,
    cursor: cursor::Handle,
    shells: Vec<xdg_shell_v6::Handle>,
    seat_handle: Option<seat::Handle>
}

impl State {
    fn new(xcursor_manager: xcursor::Manager,
           layout: output::layout::Handle,
           cursor: cursor::Handle)
           -> Self {
        State { xcursor_manager,
                layout,
                cursor,
                keyboard: None,
                seat_handle: None,
                shells: vec![] }
    }
}

struct SeatHandlerEx;

struct CursorEx;

impl cursor::Handler for CursorEx {}

impl seat::Handler for SeatHandlerEx {}

struct XdgV6ShellHandlerEx;
struct OutputLayoutEx;

impl output::layout::Handler for OutputLayoutEx {}

impl xdg_shell_v6::Handler for XdgV6ShellHandlerEx {
    fn destroyed(&mut self, compositor: compositor::Handle, shell: xdg_shell_v6::Handle) {
        with_handles!([(compositor: {compositor})] => {
            let state: &mut State = compositor.downcast();
            let weak = shell;
            if let Some(index) = state.shells.iter().position(|s| *s == weak) {
                state.shells.remove(index);
            }
        }).unwrap();
    }
}

struct SurfaceEx;

impl surface::Handler for SurfaceEx {
    fn on_commit(&mut self, _: compositor::Handle, surface: surface::Handle) {
        wlr_log!(WLR_DEBUG, "Commiting for surface {:?}", surface);
    }
}

#[wlroots_dehandle]
fn new_surface(compositor: compositor::Handle,
               shell: xdg_shell_v6::Handle)
               -> (Option<Box<xdg_shell_v6::Handler>>, Option<Box<surface::Handler>>) {
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let shell = shell;
        shell.ping();
        let state: &mut State = compositor.downcast();
        state.shells.push(shell.weak_reference());
        #[dehandle] let layout = &state.layout;
        for (output, _) in layout.outputs() {
            #[dehandle] let output = output;
            output.schedule_frame()
        }
    }
    (Some(Box::new(XdgV6ShellHandlerEx)), Some(Box::new(SurfaceEx)))
}

struct ExOutput;

struct ExPointer;

struct ExKeyboardHandler;

#[wlroots_dehandle]
fn output_added<'output>(compositor: compositor::Handle,
                         builder: output::Builder<'output>)
                         -> Option<output::BuilderResult<'output>> {
    let result = builder.build_best_mode(ExOutput);
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let output = &result.output;
        let state: &mut State = compositor.data.downcast_mut().unwrap();
        // TODO use output config if present instead of auto
        #[dehandle] let layout = state.layout.clone();
        #[dehandle] let cursor = state.cursor.clone();
        layout.add_auto(output);
        cursor.attach_output_layout(layout);
        state.xcursor_manager.load(output.scale());
        state.xcursor_manager.set_cursor_image("left_ptr".to_string(), cursor);
        let (x, y) = cursor.coords();
        // https://en.wikipedia.org/wiki/Mouse_warping
        cursor.warp(None, x, y);
    }
    Some(result)
}

impl keyboard::Handler for ExKeyboardHandler {
    #[wlroots_dehandle]
    fn on_key(&mut self,
              compositor_handle: compositor::Handle,
              keyboard_handle: keyboard::Handle,
              key_event: &keyboard::event::Key) {
        for key in key_event.pressed_keys() {
            match key {
               KEY_Escape =>  {
                  compositor::terminate();
                  return;
               },
               KEY_F1 => {
                   if key_event.key_state() == WLR_KEY_PRESSED {
                        thread::spawn(move || {
                            Command::new("weston-terminal").output().unwrap();
                        });
                        return;
                   }
                },
                KEY_XF86Switch_VT_1 ... KEY_XF86Switch_VT_12 => {
                    compositor_handle.run(|compositor| {

                        if let Some(mut session) = compositor.backend.get_session() {
                            session.change_vt(key - KEY_XF86Switch_VT_1 + 1);
                        }
                    }).unwrap();
                    return;
                }
               _ => {/*do nothing*/}
            }
        };

        #[dehandle] let compositor = compositor_handle;
        let state: &mut State = compositor.downcast();
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = keyboard_handle;

        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_key(key_event.time_msec(),
                                 key_event.keycode(),
                                 key_event.key_state() as u32);
    }

     #[wlroots_dehandle]
    fn modifiers(&mut self,
                 compositor_handle: compositor::Handle,
                 keyboard_handle: keyboard::Handle) {
        #[dehandle] let compositor = compositor_handle;
        let state: &mut State = compositor.downcast();
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = keyboard_handle;

        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_modifiers(&mut keyboard.get_modifier_masks());
    }
}

impl pointer::Handler for ExPointer {
    #[wlroots_dehandle]
    fn on_motion_absolute(&mut self,
                          compositor: compositor::Handle,
                          _: pointer::Handle,
                          event: &pointer::event::AbsoluteMotion) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        let (x, y) = event.pos();
        #[dehandle] let cursor = &state.cursor;
        cursor.warp_absolute(event.device(), x, y)
    }

    #[wlroots_dehandle]
    fn on_motion(&mut self,
                 compositor: compositor::Handle,
                 _: pointer::Handle,
                 event: &pointer::event::Motion) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        let (delta_x, delta_y) = event.delta();
        #[dehandle] let cursor = &state.cursor;
        cursor.move_relative(event.device(), delta_x, delta_y)
    }

    #[wlroots_dehandle]
    fn on_button(&mut self,
                 compositor: compositor::Handle, _:
                 pointer::Handle,
                 _: &pointer::event::Button) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        #[dehandle] let shell = &state.shells[0];
        match shell.state() {
            Some(&mut xdg_shell_v6::ShellState::TopLevel(ref mut toplevel)) => {
                toplevel.set_activated(true);
            }
            _ => {}
        };
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = state.keyboard.clone().unwrap();
        #[dehandle] let surface = shell.surface();
        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_enter(surface,
                                   &mut keyboard.keycodes(),
                                   &mut keyboard.get_modifier_masks())
    }
}

impl output::Handler for ExOutput {
    #[wlroots_dehandle]
    fn on_frame(&mut self, compositor: compositor::Handle, output: output::Handle) {
        #[dehandle] let compositor = compositor;
        #[dehandle] let output = output;
        let state: &mut State = compositor.data.downcast_mut().unwrap();
        let renderer = compositor.renderer
            .as_mut()
            .expect("Compositor was not loaded with a renderer");
        let mut render_context = renderer.render(output, None);
        render_context.clear([0.25, 0.25, 0.25, 1.0]);
        render_shells(state, &mut render_context)
    }
}

fn pointer_added(_: compositor::Handle,
                 _: pointer::Handle)
                 -> Option<Box<pointer::Handler>> {
    Some(Box::new(ExPointer))
}

#[wlroots_dehandle]
fn keyboard_added(compositor: compositor::Handle,
                  keyboard: keyboard::Handle)
                  -> Option<Box<keyboard::Handler>> {
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let keyboard = keyboard;
        let state: &mut State = compositor.downcast();
        state.keyboard = Some(keyboard.weak_reference());
        #[dehandle] let seat = state.seat_handle.as_ref().unwrap();
        seat.set_keyboard(keyboard.input_device());
    }
    Some(Box::new(ExKeyboardHandler))
}

fn main() {
    Logger::init(LevelFilter::Debug, None);
    let cursor = Cursor::create(Box::new(CursorEx));
    let mut xcursor_manager =
        xcursor::Manager::create("default".to_string(), 24).expect("Could not create xcursor \
                                                                    manager");
    xcursor_manager.load(1.0);
    cursor.run(|c| xcursor_manager.set_cursor_image("left_ptr".to_string(), c))
        .unwrap();
    let layout = Layout::create(Box::new(OutputLayoutEx));

    let output_builder = output::manager::Builder::default().output_added(output_added);
    let input_builder = input::manager::Builder::default()
        .keyboard_added(keyboard_added)
        .pointer_added(pointer_added);
    let xdg_shell_v6_builder = xdg_shell_v6::manager::Builder::default()
        .surface_added(new_surface);
    let mut compositor =
        compositor::Builder::new().gles2(true)
        .wl_shm(true)
        .input_manager(input_builder)
        .output_manager(output_builder)
        .xdg_shell_v6_manager(xdg_shell_v6_builder)
        .build_auto(State::new(xcursor_manager, layout, cursor));

    {
        let seat_handle =
            Seat::create(&mut compositor, "seat0".into(), Box::new(SeatHandlerEx));
        seat_handle.run(|seat| {
            seat.set_capabilities(seat::Capability::all());
        })
            .unwrap();
        let state: &mut State = compositor.downcast();
        state.seat_handle = Some(seat_handle);
    }
    env::set_var("WAYLAND_DISPLAY", compositor.socket_name());
    compositor.run();
}

/// Render the shells in the current compositor state on the given output.
#[wlroots_dehandle]
fn render_shells(state: &mut State, renderer: &mut Renderer) {
    let shells = state.shells.clone();
    for mut shell in shells {
        #[dehandle] let shell = shell;
        #[dehandle] let surface = shell.surface();
        #[dehandle] let layout = &state.layout;
        let (width, height) = surface.current_state().size();
        let (render_width, render_height) =
            (width * renderer.output.scale() as i32,
             height * renderer.output.scale() as i32);
        let (lx, ly) = (0.0, 0.0);
        let render_box = Area::new(Origin::new(lx as i32, ly as i32),
                                   Size::new(render_width,
                                             render_height));
        if layout.intersects(renderer.output, render_box) {
            let transform = renderer.output.get_transform().invert();
            let matrix = matrix::project_box(render_box,
                                             transform,
                                             0.0,
                                             renderer.output
                                             .transform_matrix());
            if let Some(texture) = surface.texture().as_ref() {
                renderer.render_texture_with_matrix(texture, matrix);
            }
            surface.send_frame_done(current_time());
        }
    }
}
<commit_msg>pressed state handling<commit_after>extern crate log;
#[macro_use]
extern crate wlroots;

use std::{env, thread, process::Command};

use log::LevelFilter;
use wlroots::{area::{Area, Origin, Size},
              compositor,
              cursor::{self, Cursor, xcursor},
              input::{self, keyboard, pointer},
              output::{self, layout::Layout},
              render::{matrix, Renderer},
              seat::{self, Seat},
              shell::xdg_shell_v6,
              surface,
              utils::{Handleable, log::Logger, current_time}};
use wlroots::wlroots_sys::wlr_key_state::WLR_KEY_PRESSED;
use wlroots::xkbcommon::xkb::keysyms::{KEY_Escape, KEY_F1, KEY_XF86Switch_VT_1, KEY_XF86Switch_VT_12};
use wlroots::wlroots_dehandle;

struct State {
    xcursor_manager: xcursor::Manager,
    keyboard: Option<keyboard::Handle>,
    layout: output::layout::Handle,
    cursor: cursor::Handle,
    shells: Vec<xdg_shell_v6::Handle>,
    seat_handle: Option<seat::Handle>
}

impl State {
    fn new(xcursor_manager: xcursor::Manager,
           layout: output::layout::Handle,
           cursor: cursor::Handle)
           -> Self {
        State { xcursor_manager,
                layout,
                cursor,
                keyboard: None,
                seat_handle: None,
                shells: vec![] }
    }
}

struct SeatHandlerEx;

struct CursorEx;

impl cursor::Handler for CursorEx {}

impl seat::Handler for SeatHandlerEx {}

struct XdgV6ShellHandlerEx;
struct OutputLayoutEx;

impl output::layout::Handler for OutputLayoutEx {}

impl xdg_shell_v6::Handler for XdgV6ShellHandlerEx {
    fn destroyed(&mut self, compositor: compositor::Handle, shell: xdg_shell_v6::Handle) {
        with_handles!([(compositor: {compositor})] => {
            let state: &mut State = compositor.downcast();
            let weak = shell;
            if let Some(index) = state.shells.iter().position(|s| *s == weak) {
                state.shells.remove(index);
            }
        }).unwrap();
    }
}

struct SurfaceEx;

impl surface::Handler for SurfaceEx {
    fn on_commit(&mut self, _: compositor::Handle, surface: surface::Handle) {
        wlr_log!(WLR_DEBUG, "Commiting for surface {:?}", surface);
    }
}

#[wlroots_dehandle]
fn new_surface(compositor: compositor::Handle,
               shell: xdg_shell_v6::Handle)
               -> (Option<Box<xdg_shell_v6::Handler>>, Option<Box<surface::Handler>>) {
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let shell = shell;
        shell.ping();
        let state: &mut State = compositor.downcast();
        state.shells.push(shell.weak_reference());
        #[dehandle] let layout = &state.layout;
        for (output, _) in layout.outputs() {
            #[dehandle] let output = output;
            output.schedule_frame()
        }
    }
    (Some(Box::new(XdgV6ShellHandlerEx)), Some(Box::new(SurfaceEx)))
}

struct ExOutput;

struct ExPointer;

struct ExKeyboardHandler;

#[wlroots_dehandle]
fn output_added<'output>(compositor: compositor::Handle,
                         builder: output::Builder<'output>)
                         -> Option<output::BuilderResult<'output>> {
    let result = builder.build_best_mode(ExOutput);
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let output = &result.output;
        let state: &mut State = compositor.data.downcast_mut().unwrap();
        // TODO use output config if present instead of auto
        #[dehandle] let layout = state.layout.clone();
        #[dehandle] let cursor = state.cursor.clone();
        layout.add_auto(output);
        cursor.attach_output_layout(layout);
        state.xcursor_manager.load(output.scale());
        state.xcursor_manager.set_cursor_image("left_ptr".to_string(), cursor);
        let (x, y) = cursor.coords();
        // https://en.wikipedia.org/wiki/Mouse_warping
        cursor.warp(None, x, y);
    }
    Some(result)
}

impl keyboard::Handler for ExKeyboardHandler {
    #[wlroots_dehandle]
    fn on_key(&mut self,
              compositor_handle: compositor::Handle,
              keyboard_handle: keyboard::Handle,
              key_event: &keyboard::event::Key) {
        if key_event.key_state() == WLR_KEY_PRESSED {
            for key in key_event.pressed_keys() {
                match key {
                    KEY_Escape =>  {
                        compositor::terminate();
                        return;
                    },
                    KEY_F1 => {
                        thread::spawn(move || {
                            Command::new("weston-terminal").output().unwrap();
                        });
                        return;
                    },
                    KEY_XF86Switch_VT_1 ... KEY_XF86Switch_VT_12 => {
                        compositor_handle.run(|compositor| {

                            if let Some(mut session) = compositor.backend.get_session() {
                                session.change_vt(key - KEY_XF86Switch_VT_1 + 1);
                            }
                        }).unwrap();
                        return;
                    }
                _ => {/*do nothing*/}
                }
            }
        }

        #[dehandle] let compositor = compositor_handle;
        let state: &mut State = compositor.downcast();
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = keyboard_handle;

        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_key(key_event.time_msec(),
                                 key_event.keycode(),
                                 key_event.key_state() as u32);
    }

     #[wlroots_dehandle]
    fn modifiers(&mut self,
                 compositor_handle: compositor::Handle,
                 keyboard_handle: keyboard::Handle) {
        #[dehandle] let compositor = compositor_handle;
        let state: &mut State = compositor.downcast();
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = keyboard_handle;

        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_modifiers(&mut keyboard.get_modifier_masks());
    }
}

impl pointer::Handler for ExPointer {
    #[wlroots_dehandle]
    fn on_motion_absolute(&mut self,
                          compositor: compositor::Handle,
                          _: pointer::Handle,
                          event: &pointer::event::AbsoluteMotion) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        let (x, y) = event.pos();
        #[dehandle] let cursor = &state.cursor;
        cursor.warp_absolute(event.device(), x, y)
    }

    #[wlroots_dehandle]
    fn on_motion(&mut self,
                 compositor: compositor::Handle,
                 _: pointer::Handle,
                 event: &pointer::event::Motion) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        let (delta_x, delta_y) = event.delta();
        #[dehandle] let cursor = &state.cursor;
        cursor.move_relative(event.device(), delta_x, delta_y)
    }

    #[wlroots_dehandle]
    fn on_button(&mut self,
                 compositor: compositor::Handle, _:
                 pointer::Handle,
                 _: &pointer::event::Button) {
        #[dehandle] let compositor = compositor;
        let state: &mut State = compositor.downcast();
        #[dehandle] let shell = &state.shells[0];
        match shell.state() {
            Some(&mut xdg_shell_v6::ShellState::TopLevel(ref mut toplevel)) => {
                toplevel.set_activated(true);
            }
            _ => {}
        };
        #[dehandle] let seat = state.seat_handle.clone().unwrap();
        #[dehandle] let keyboard = state.keyboard.clone().unwrap();
        #[dehandle] let surface = shell.surface();
        seat.set_keyboard(keyboard.input_device());
        seat.keyboard_notify_enter(surface,
                                   &mut keyboard.keycodes(),
                                   &mut keyboard.get_modifier_masks())
    }
}

impl output::Handler for ExOutput {
    #[wlroots_dehandle]
    fn on_frame(&mut self, compositor: compositor::Handle, output: output::Handle) {
        #[dehandle] let compositor = compositor;
        #[dehandle] let output = output;
        let state: &mut State = compositor.data.downcast_mut().unwrap();
        let renderer = compositor.renderer
            .as_mut()
            .expect("Compositor was not loaded with a renderer");
        let mut render_context = renderer.render(output, None);
        render_context.clear([0.25, 0.25, 0.25, 1.0]);
        render_shells(state, &mut render_context)
    }
}

fn pointer_added(_: compositor::Handle,
                 _: pointer::Handle)
                 -> Option<Box<pointer::Handler>> {
    Some(Box::new(ExPointer))
}

#[wlroots_dehandle]
fn keyboard_added(compositor: compositor::Handle,
                  keyboard: keyboard::Handle)
                  -> Option<Box<keyboard::Handler>> {
    {
        #[dehandle] let compositor = compositor;
        #[dehandle] let keyboard = keyboard;
        let state: &mut State = compositor.downcast();
        state.keyboard = Some(keyboard.weak_reference());
        #[dehandle] let seat = state.seat_handle.as_ref().unwrap();
        seat.set_keyboard(keyboard.input_device());
    }
    Some(Box::new(ExKeyboardHandler))
}

fn main() {
    Logger::init(LevelFilter::Debug, None);
    let cursor = Cursor::create(Box::new(CursorEx));
    let mut xcursor_manager =
        xcursor::Manager::create("default".to_string(), 24).expect("Could not create xcursor \
                                                                    manager");
    xcursor_manager.load(1.0);
    cursor.run(|c| xcursor_manager.set_cursor_image("left_ptr".to_string(), c))
        .unwrap();
    let layout = Layout::create(Box::new(OutputLayoutEx));

    let output_builder = output::manager::Builder::default().output_added(output_added);
    let input_builder = input::manager::Builder::default()
        .keyboard_added(keyboard_added)
        .pointer_added(pointer_added);
    let xdg_shell_v6_builder = xdg_shell_v6::manager::Builder::default()
        .surface_added(new_surface);
    let mut compositor =
        compositor::Builder::new().gles2(true)
        .wl_shm(true)
        .input_manager(input_builder)
        .output_manager(output_builder)
        .xdg_shell_v6_manager(xdg_shell_v6_builder)
        .build_auto(State::new(xcursor_manager, layout, cursor));

    {
        let seat_handle =
            Seat::create(&mut compositor, "seat0".into(), Box::new(SeatHandlerEx));
        seat_handle.run(|seat| {
            seat.set_capabilities(seat::Capability::all());
        })
            .unwrap();
        let state: &mut State = compositor.downcast();
        state.seat_handle = Some(seat_handle);
    }
    env::set_var("WAYLAND_DISPLAY", compositor.socket_name());
    compositor.run();
}

/// Render the shells in the current compositor state on the given output.
#[wlroots_dehandle]
fn render_shells(state: &mut State, renderer: &mut Renderer) {
    let shells = state.shells.clone();
    for mut shell in shells {
        #[dehandle] let shell = shell;
        #[dehandle] let surface = shell.surface();
        #[dehandle] let layout = &state.layout;
        let (width, height) = surface.current_state().size();
        let (render_width, render_height) =
            (width * renderer.output.scale() as i32,
             height * renderer.output.scale() as i32);
        let (lx, ly) = (0.0, 0.0);
        let render_box = Area::new(Origin::new(lx as i32, ly as i32),
                                   Size::new(render_width,
                                             render_height));
        if layout.intersects(renderer.output, render_box) {
            let transform = renderer.output.get_transform().invert();
            let matrix = matrix::project_box(render_box,
                                             transform,
                                             0.0,
                                             renderer.output
                                             .transform_matrix());
            if let Some(texture) = surface.texture().as_ref() {
                renderer.render_texture_with_matrix(texture, matrix);
            }
            surface.send_frame_done(current_time());
        }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{self, BufRead, BufReader, Cursor, Read, Seek, SeekFrom};
use std::path::Path;

use crate::dynimage::DynamicImage;
use crate::image::ImageFormat;
use crate::error::{ImageFormatHint, UnsupportedError, UnsupportedErrorKind};
use crate::{ImageError, ImageResult};

use super::free_functions;

/// A multi-format image reader.
///
/// Wraps an input reader to facilitate automatic detection of an image's format, appropriate
/// decoding method, and dispatches into the set of supported [`ImageDecoder`] implementations.
///
/// ## Usage
///
/// Opening a file, deducing the format based on the file path automatically, and trying to decode
/// the image contained can be performed by constructing the reader and immediately consuming it.
///
/// ```no_run
/// # use image::ImageError;
/// # use image::io::Reader;
/// # fn main() -> Result<(), ImageError> {
/// let image = Reader::open("path/to/image.png")?
///     .decode()?;
/// # Ok(()) }
/// ```
///
/// It is also possible to make a guess based on the content. This is especially handy if the
/// source is some blob in memory and you have constructed the reader in another way. Here is an
/// example with a `pnm` black-and-white subformat that encodes its pixel matrix with ascii values.
///
#[cfg_attr(feature = "pnm", doc = "```")]
#[cfg_attr(not(feature = "pnm"), doc = "```no_run")]
/// # use image::ImageError;
/// # use image::io::Reader;
/// # fn main() -> Result<(), ImageError> {
/// use std::io::Cursor;
/// use image::ImageFormat;
///
/// let raw_data = b"P1 2 2\n\
///     0 1\n\
///     1 0\n";
///
/// let mut reader = Reader::new(Cursor::new(raw_data))
///     .with_guessed_format()
///     .expect("Cursor io never fails");
/// assert_eq!(reader.format(), Some(ImageFormat::Pnm));
///
/// let image = reader.decode()?;
/// # Ok(()) }
/// ```
///
/// As a final fallback or if only a specific format must be used, the reader always allows manual
/// specification of the supposed image format with [`set_format`].
///
/// [`set_format`]: #method.set_format
/// [`ImageDecoder`]: ../trait.ImageDecoder.html
pub struct Reader<R: Read> {
    /// The reader.
    inner: R,
    /// The format, if one has been set or deduced.
    format: Option<ImageFormat>,
}

impl<R: Read> Reader<R> {
    /// Create a new image reader without a preset format.
    ///
    /// It is possible to guess the format based on the content of the read object with
    /// [`guess_format`], or to set the format directly with [`set_format`].
    ///
    /// [`guess_format`]: #method.guess_format
    /// [`set_format`]: method.set_format
    pub fn new(reader: R) -> Self {
        Reader {
            inner: reader,
            format: None,
        }
    }

    /// Construct a reader with specified format.
    pub fn with_format(reader: R, format: ImageFormat) -> Self {
        Reader {
            inner: reader,
            format: Some(format),
        }
    }

    /// Get the currently determined format.
    pub fn format(&self) -> Option<ImageFormat> {
        self.format
    }

    /// Supply the format as which to interpret the read image.
    pub fn set_format(&mut self, format: ImageFormat) {
        self.format = Some(format);
    }

    /// Remove the current information on the image format.
    ///
    /// Note that many operations require format information to be present and will return e.g. an
    /// `ImageError::Unsupported` when the image format has not been set.
    pub fn clear_format(&mut self) {
        self.format = None;
    }

    /// Unwrap the reader.
    pub fn into_inner(self) -> R {
        self.inner
    }
}

impl Reader<BufReader<File>> {
    /// Open a file to read, format will be guessed from path.
    ///
    /// This will not attempt any io operation on the opened file.
    ///
    /// If you want to inspect the content for a better guess on the format, which does not depend
    /// on file extensions, follow this call with a call to [`guess_format`].
    ///
    /// [`guess_format`]: #method.guess_format
    pub fn open<P>(path: P) -> io::Result<Self> where P: AsRef<Path> {
        Self::open_impl(path.as_ref())
    }

    fn open_impl(path: &Path) -> io::Result<Self> {
        let file = File::open(path)?;
        Ok(Reader {
            inner: BufReader::new(file),
            format: ImageFormat::from_path(path).ok(),
        })
    }
}

impl<R: BufRead + Seek> Reader<R> {
    /// Make a format guess based on the content, replacing it on success.
    ///
    /// Returns `Ok` with the guess if no io error occurs. Additionally, replaces the current
    /// format if the guess was successful. If the guess was not unable to determine a format then
    /// the current format of the reader is unchanged.
    ///
    /// Returns an error if the underlying reader fails. The format is unchanged. The error is a
    /// `std::io::Error` and not `ImageError` since the only error case is an error when the
    /// underlying reader seeks.
    ///
    /// When an error occurs, the reader may not have been properly reset and it is potentially
    /// hazardous to continue with more io.
    ///
    /// ## Usage
    ///
    /// This supplements the path based type deduction from [`open`](Reader::open) with content based deduction.
    /// This is more common in Linux and UNIX operating systems and also helpful if the path can
    /// not be directly controlled.
    ///
    /// ```no_run
    /// # use image::ImageError;
    /// # use image::io::Reader;
    /// # fn main() -> Result<(), ImageError> {
    /// let image = Reader::open("image.unknown")?
    ///     .with_guessed_format()?
    ///     .decode()?;
    /// # Ok(()) }
    /// ```
    pub fn with_guessed_format(mut self) -> io::Result<Self> {
        let format = self.guess_format()?;
        // Replace format if found, keep current state if not.
        self.format = format.or(self.format);
        Ok(self)
    }

    fn guess_format(&mut self) -> io::Result<Option<ImageFormat>> {
        let mut start = [0; 16];

        // Save current offset, read start, restore offset.
        let cur = self.inner.seek(SeekFrom::Current(0))?;
        let len = io::copy(
            // Accept shorter files but read at most 16 bytes.
            &mut self.inner.by_ref().take(16),
            &mut Cursor::new(&mut start[..]))?;
        self.inner.seek(SeekFrom::Start(cur))?;

        Ok(free_functions::guess_format_impl(&start[..len as usize]))
    }

    /// Read the image dimensions.
    ///
    /// Uses the current format to construct the correct reader for the format.
    ///
    /// If no format was determined, returns an `ImageError::Unsupported`.
    pub fn into_dimensions(mut self) -> ImageResult<(u32, u32)> {
        let format = self.require_format()?;
        free_functions::image_dimensions_with_format_impl(self.inner, format)
    }

    /// Read the image (replaces `load`).
    ///
    /// Uses the current format to construct the correct reader for the format.
    ///
    /// If no format was determined, returns an `ImageError::Unsupported`.
    pub fn decode(mut self) -> ImageResult<DynamicImage> {
        let format = self.require_format()?;
        free_functions::load(self.inner, format)
    }

    fn require_format(&mut self) -> ImageResult<ImageFormat> {
        self.format.ok_or_else(||
            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Unknown))))
    }
}
<commit_msg>Fix the method reference to with_guessed_format<commit_after>use std::fs::File;
use std::io::{self, BufRead, BufReader, Cursor, Read, Seek, SeekFrom};
use std::path::Path;

use crate::dynimage::DynamicImage;
use crate::image::ImageFormat;
use crate::error::{ImageFormatHint, UnsupportedError, UnsupportedErrorKind};
use crate::{ImageError, ImageResult};

use super::free_functions;

/// A multi-format image reader.
///
/// Wraps an input reader to facilitate automatic detection of an image's format, appropriate
/// decoding method, and dispatches into the set of supported [`ImageDecoder`] implementations.
///
/// ## Usage
///
/// Opening a file, deducing the format based on the file path automatically, and trying to decode
/// the image contained can be performed by constructing the reader and immediately consuming it.
///
/// ```no_run
/// # use image::ImageError;
/// # use image::io::Reader;
/// # fn main() -> Result<(), ImageError> {
/// let image = Reader::open("path/to/image.png")?
///     .decode()?;
/// # Ok(()) }
/// ```
///
/// It is also possible to make a guess based on the content. This is especially handy if the
/// source is some blob in memory and you have constructed the reader in another way. Here is an
/// example with a `pnm` black-and-white subformat that encodes its pixel matrix with ascii values.
///
#[cfg_attr(feature = "pnm", doc = "```")]
#[cfg_attr(not(feature = "pnm"), doc = "```no_run")]
/// # use image::ImageError;
/// # use image::io::Reader;
/// # fn main() -> Result<(), ImageError> {
/// use std::io::Cursor;
/// use image::ImageFormat;
///
/// let raw_data = b"P1 2 2\n\
///     0 1\n\
///     1 0\n";
///
/// let mut reader = Reader::new(Cursor::new(raw_data))
///     .with_guessed_format()
///     .expect("Cursor io never fails");
/// assert_eq!(reader.format(), Some(ImageFormat::Pnm));
///
/// let image = reader.decode()?;
/// # Ok(()) }
/// ```
///
/// As a final fallback or if only a specific format must be used, the reader always allows manual
/// specification of the supposed image format with [`set_format`].
///
/// [`set_format`]: #method.set_format
/// [`ImageDecoder`]: ../trait.ImageDecoder.html
pub struct Reader<R: Read> {
    /// The reader.
    inner: R,
    /// The format, if one has been set or deduced.
    format: Option<ImageFormat>,
}

impl<R: Read> Reader<R> {
    /// Create a new image reader without a preset format.
    ///
    /// It is possible to guess the format based on the content of the read object with
    /// [`with_guessed_format`], or to set the format directly with [`set_format`].
    ///
    /// [`with_guessed_format`]: #method.with_guessed_format
    /// [`set_format`]: method.set_format
    pub fn new(reader: R) -> Self {
        Reader {
            inner: reader,
            format: None,
        }
    }

    /// Construct a reader with specified format.
    pub fn with_format(reader: R, format: ImageFormat) -> Self {
        Reader {
            inner: reader,
            format: Some(format),
        }
    }

    /// Get the currently determined format.
    pub fn format(&self) -> Option<ImageFormat> {
        self.format
    }

    /// Supply the format as which to interpret the read image.
    pub fn set_format(&mut self, format: ImageFormat) {
        self.format = Some(format);
    }

    /// Remove the current information on the image format.
    ///
    /// Note that many operations require format information to be present and will return e.g. an
    /// `ImageError::Unsupported` when the image format has not been set.
    pub fn clear_format(&mut self) {
        self.format = None;
    }

    /// Unwrap the reader.
    pub fn into_inner(self) -> R {
        self.inner
    }
}

impl Reader<BufReader<File>> {
    /// Open a file to read, format will be guessed from path.
    ///
    /// This will not attempt any io operation on the opened file.
    ///
    /// If you want to inspect the content for a better guess on the format, which does not depend
    /// on file extensions, follow this call with a call to [`with_guessed_format`].
    ///
    /// [`with_guessed_format`]: #method.with_guessed_format
    pub fn open<P>(path: P) -> io::Result<Self> where P: AsRef<Path> {
        Self::open_impl(path.as_ref())
    }

    fn open_impl(path: &Path) -> io::Result<Self> {
        let file = File::open(path)?;
        Ok(Reader {
            inner: BufReader::new(file),
            format: ImageFormat::from_path(path).ok(),
        })
    }
}

impl<R: BufRead + Seek> Reader<R> {
    /// Make a format guess based on the content, replacing it on success.
    ///
    /// Returns `Ok` with the guess if no io error occurs. Additionally, replaces the current
    /// format if the guess was successful. If the guess was not unable to determine a format then
    /// the current format of the reader is unchanged.
    ///
    /// Returns an error if the underlying reader fails. The format is unchanged. The error is a
    /// `std::io::Error` and not `ImageError` since the only error case is an error when the
    /// underlying reader seeks.
    ///
    /// When an error occurs, the reader may not have been properly reset and it is potentially
    /// hazardous to continue with more io.
    ///
    /// ## Usage
    ///
    /// This supplements the path based type deduction from [`open`](Reader::open) with content based deduction.
    /// This is more common in Linux and UNIX operating systems and also helpful if the path can
    /// not be directly controlled.
    ///
    /// ```no_run
    /// # use image::ImageError;
    /// # use image::io::Reader;
    /// # fn main() -> Result<(), ImageError> {
    /// let image = Reader::open("image.unknown")?
    ///     .with_guessed_format()?
    ///     .decode()?;
    /// # Ok(()) }
    /// ```
    pub fn with_guessed_format(mut self) -> io::Result<Self> {
        let format = self.guess_format()?;
        // Replace format if found, keep current state if not.
        self.format = format.or(self.format);
        Ok(self)
    }

    fn guess_format(&mut self) -> io::Result<Option<ImageFormat>> {
        let mut start = [0; 16];

        // Save current offset, read start, restore offset.
        let cur = self.inner.seek(SeekFrom::Current(0))?;
        let len = io::copy(
            // Accept shorter files but read at most 16 bytes.
            &mut self.inner.by_ref().take(16),
            &mut Cursor::new(&mut start[..]))?;
        self.inner.seek(SeekFrom::Start(cur))?;

        Ok(free_functions::guess_format_impl(&start[..len as usize]))
    }

    /// Read the image dimensions.
    ///
    /// Uses the current format to construct the correct reader for the format.
    ///
    /// If no format was determined, returns an `ImageError::Unsupported`.
    pub fn into_dimensions(mut self) -> ImageResult<(u32, u32)> {
        let format = self.require_format()?;
        free_functions::image_dimensions_with_format_impl(self.inner, format)
    }

    /// Read the image (replaces `load`).
    ///
    /// Uses the current format to construct the correct reader for the format.
    ///
    /// If no format was determined, returns an `ImageError::Unsupported`.
    pub fn decode(mut self) -> ImageResult<DynamicImage> {
        let format = self.require_format()?;
        free_functions::load(self.inner, format)
    }

    fn require_format(&mut self) -> ImageResult<ImageFormat> {
        self.format.ok_or_else(||
            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Unknown))))
    }
}
<|endoftext|>


<commit_before>use std::ops;

/// A owned window around an underlying buffer.
///
/// Normally slices work great for considering sub-portions of a buffer, but
/// unfortunately a slice is a *borrowed* type in Rust which has an associated
/// lifetime. When working with future and async I/O these lifetimes are not
/// always appropriate, and are sometimes difficult to store in tasks. This
/// type strives to fill this gap by providing an "owned slice" around an
/// underlying buffer of bytes.
///
/// A `Window<T>` wraps an underlying buffer, `T`, and has configurable
/// start/end indexes to alter the behavior of the `AsRef<[u8]>` implementation
/// that this type carries.
///
/// This type can be particularly useful when working with the `write_all`
/// combinator in this crate. Data can be sliced via `Window`, consumed by
/// `write_all`, and then earned back once the write operation finishes through
/// the `into_inner` method on this type.
pub struct Window<T> {
    inner: T,
    range: ops::Range<usize>,
}

impl<T: AsRef<[u8]>> Window<T> {
    /// Creates a new window around the buffer `t` defaulting to the entire
    /// slice.
    ///
    /// Further methods can be called on the returned `Window<T>` to alter the
    /// window into the data provided.
    pub fn new(t: T) -> Window<T> {
        Window {
            range: 0..t.as_ref().len(),
            inner: t,
        }
    }

    /// Gets a shared reference to the underlying buffer inside of this
    /// `Window`.
    pub fn get_ref(&self) -> &T {
        &self.inner
    }

    /// Gets a mutable reference to the underlying buffer inside of this
    /// `Window`.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.inner
    }

    /// Consumes this `Window`, returning the underlying buffer.
    pub fn into_inner(self) -> T {
        self.inner
    }

    /// Returns the starting index of this window into the underlying buffer
    /// `T`.
    pub fn start(&self) -> usize {
        self.range.start
    }

    /// Returns the end index of this window into the underlying buffer
    /// `T`.
    pub fn end(&self) -> usize {
        self.range.end
    }

    /// Changes the starting index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `start` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    pub fn set_start(&mut self, start: usize) -> &mut Window<T> {
        assert!(start < self.inner.as_ref().len());
        assert!(start <= self.range.end);
        self.range.start = start;
        self
    }

    /// Changes the end index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `end` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    pub fn set_end(&mut self, end: usize) -> &mut Window<T> {
        assert!(end < self.inner.as_ref().len());
        assert!(self.range.start <= end);
        self.range.end = end;
        self
    }

    // TODO: how about a generic set() method along the lines of:
    //
    //       buffer.set(..3)
    //             .set(0..2)
    //             .set(4..)
    //
    // etc.
}

impl<T: AsRef<[u8]>> AsRef<[u8]> for Window<T> {
    fn as_ref(&self) -> &[u8] {
        &self.inner.as_ref()[self.range.start..self.range.end]
    }
}

impl<T: AsMut<[u8]>> AsMut<[u8]> for Window<T> {
    fn as_mut(&mut self) -> &mut [u8] {
        &mut self.inner.as_mut()[self.range.start..self.range.end]
    }
}
<commit_msg>Allow start and end of window to match length of underlying slice.<commit_after>use std::ops;

/// A owned window around an underlying buffer.
///
/// Normally slices work great for considering sub-portions of a buffer, but
/// unfortunately a slice is a *borrowed* type in Rust which has an associated
/// lifetime. When working with future and async I/O these lifetimes are not
/// always appropriate, and are sometimes difficult to store in tasks. This
/// type strives to fill this gap by providing an "owned slice" around an
/// underlying buffer of bytes.
///
/// A `Window<T>` wraps an underlying buffer, `T`, and has configurable
/// start/end indexes to alter the behavior of the `AsRef<[u8]>` implementation
/// that this type carries.
///
/// This type can be particularly useful when working with the `write_all`
/// combinator in this crate. Data can be sliced via `Window`, consumed by
/// `write_all`, and then earned back once the write operation finishes through
/// the `into_inner` method on this type.
pub struct Window<T> {
    inner: T,
    range: ops::Range<usize>,
}

impl<T: AsRef<[u8]>> Window<T> {
    /// Creates a new window around the buffer `t` defaulting to the entire
    /// slice.
    ///
    /// Further methods can be called on the returned `Window<T>` to alter the
    /// window into the data provided.
    pub fn new(t: T) -> Window<T> {
        Window {
            range: 0..t.as_ref().len(),
            inner: t,
        }
    }

    /// Gets a shared reference to the underlying buffer inside of this
    /// `Window`.
    pub fn get_ref(&self) -> &T {
        &self.inner
    }

    /// Gets a mutable reference to the underlying buffer inside of this
    /// `Window`.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.inner
    }

    /// Consumes this `Window`, returning the underlying buffer.
    pub fn into_inner(self) -> T {
        self.inner
    }

    /// Returns the starting index of this window into the underlying buffer
    /// `T`.
    pub fn start(&self) -> usize {
        self.range.start
    }

    /// Returns the end index of this window into the underlying buffer
    /// `T`.
    pub fn end(&self) -> usize {
        self.range.end
    }

    /// Changes the starting index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `start` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    pub fn set_start(&mut self, start: usize) -> &mut Window<T> {
        assert!(start <= self.inner.as_ref().len());
        assert!(start <= self.range.end);
        self.range.start = start;
        self
    }

    /// Changes the end index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `end` is out of bounds for the underlying
    /// slice or if it comes before the `start` configured in this window.
    pub fn set_end(&mut self, end: usize) -> &mut Window<T> {
        assert!(end <= self.inner.as_ref().len());
        assert!(self.range.start <= end);
        self.range.end = end;
        self
    }

    // TODO: how about a generic set() method along the lines of:
    //
    //       buffer.set(..3)
    //             .set(0..2)
    //             .set(4..)
    //
    // etc.
}

impl<T: AsRef<[u8]>> AsRef<[u8]> for Window<T> {
    fn as_ref(&self) -> &[u8] {
        &self.inner.as_ref()[self.range.start..self.range.end]
    }
}

impl<T: AsMut<[u8]>> AsMut<[u8]> for Window<T> {
    fn as_mut(&mut self) -> &mut [u8] {
        &mut self.inner.as_mut()[self.range.start..self.range.end]
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Élisabeth HENRY.
//
// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

use super::Parser;
extern crate test;
use self::test::Bencher;

static TEST:&'static str = "This is some text string. We want to detect repetitions in it.
Why? Because repetitions are bad, very bad, so we want to highlight them. In order to have benches
that are not utterly worthless, it is required to have some variance in the text, so even if we are gonna repeat
this string quite a while it must be a bit longer, so I am writing senseless stuff. I guess this is long enough now ?
Well, alright, let's say it is. ";
static N_REPET:u32 = 100;

fn get_input() -> String {
    let mut s = TEST.to_string();
    for _ in 1..N_REPET {
        s = s + TEST;
    }

    s
}

#[bench]
fn bench_clone(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        ast.clone();
    });
}

#[bench]
fn bench_html(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(true);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_html2(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(false);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_terminal(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_terminal(&ast.clone());
    });
}

#[bench]
fn bench_markdown(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_markdown(&mut ast.clone());
    });
}

#[bench]
fn bench_tokenize(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    b.iter(|| {
        parser.tokenize(&s).unwrap();
    });
}

#[bench]
fn bench_local(b:&mut Bencher) {
    let s = get_input();
//    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_fuzzy(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_total(b:&mut Bencher) {
    let s = get_input();
    b.iter(|| {
        let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
        let mut ast = parser.tokenize(&s).unwrap();
        parser.detect_local(&mut ast, 1.9);
        parser.ast_to_html(&mut ast, true);
    });
}

#[bench]
fn bench_local_readme(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_readme_fuzzy(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_global(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_global(&mut ast.clone(), 0.01);
    });
}

<commit_msg>bench.rs: removed unnecessary mut<commit_after>// Copyright (C) 2015 Élisabeth HENRY.
//
// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

use super::Parser;
extern crate test;
use self::test::Bencher;

static TEST:&'static str = "This is some text string. We want to detect repetitions in it.
Why? Because repetitions are bad, very bad, so we want to highlight them. In order to have benches
that are not utterly worthless, it is required to have some variance in the text, so even if we are gonna repeat
this string quite a while it must be a bit longer, so I am writing senseless stuff. I guess this is long enough now ?
Well, alright, let's say it is. ";
static N_REPET:u32 = 100;

fn get_input() -> String {
    let mut s = TEST.to_string();
    for _ in 1..N_REPET {
        s.push_str(TEST);
    }

    s
}

#[bench]
fn bench_clone(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        ast.clone();
    });
}

#[bench]
fn bench_html(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(true);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_html2(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_html(false);
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_html(&mut ast.clone(), false);
    });
}

#[bench]
fn bench_terminal(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_terminal(&ast.clone());
    });
}

#[bench]
fn bench_markdown(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let mut ast = parser.tokenize(&s).unwrap();
    parser.detect_local(&mut ast, 2.0);
    b.iter(|| {
        parser.ast_to_markdown(&mut ast.clone());
    });
}

#[bench]
fn bench_tokenize(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    b.iter(|| {
        parser.tokenize(&s).unwrap();
    });
}

#[bench]
fn bench_local(b:&mut Bencher) {
    let s = get_input();
//    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_fuzzy(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_total(b:&mut Bencher) {
    let s = get_input();
    b.iter(|| {
        let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
        let mut ast = parser.tokenize(&s).unwrap();
        parser.detect_local(&mut ast, 1.9);
        parser.ast_to_html(&mut ast, true);
    });
}

#[bench]
fn bench_local_readme(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_local_readme_fuzzy(b:&mut Bencher) {
    //    let s = get_input();
    let s = include_str!("../../README.md");
    let parser = Parser::new("english").unwrap().with_fuzzy(Some(0.5));
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_local(&mut ast.clone(), 1.9);
    });
}

#[bench]
fn bench_global(b:&mut Bencher) {
    let s = get_input();
    let parser = Parser::new("english").unwrap();
    let ast = parser.tokenize(&s).unwrap();
    b.iter(|| {
        parser.detect_global(&mut ast.clone(), 0.01);
    });
}

<|endoftext|>


<commit_before>use crate::buffer::Cursor;
use crate::error::{self, Error};
use crate::sealed::lookahead::Sealed;
use crate::span::IntoSpans;
use crate::token::Token;
use proc_macro2::{Delimiter, Span};
use std::cell::RefCell;

/// Support for checking the next token in a stream to decide how to parse.
///
/// An important advantage over [`ParseStream::peek`] is that here we
/// automatically construct an appropriate error message based on the token
/// alternatives that get peeked. If you are producing your own error message,
/// go ahead and use `ParseStream::peek` instead.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
/// [`ParseStream::lookahead1`]: crate::parse::ParseBuffer::lookahead1
///
/// # Example
///
/// ```
/// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Result, Token, TypeParam};
/// use syn::parse::{Parse, ParseStream};
///
/// // A generic parameter, a single one of the comma-separated elements inside
/// // angle brackets in:
/// //
/// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
/// //
/// // On invalid input, lookahead gives us a reasonable error message.
/// //
/// //     error: expected one of: identifier, lifetime, `const`
/// //       |
/// //     5 |     fn f<!Sized>() {}
/// //       |          ^
/// enum GenericParam {
///     Type(TypeParam),
///     Lifetime(LifetimeDef),
///     Const(ConstParam),
/// }
///
/// impl Parse for GenericParam {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let lookahead = input.lookahead1();
///         if lookahead.peek(Ident) {
///             input.parse().map(GenericParam::Type)
///         } else if lookahead.peek(Lifetime) {
///             input.parse().map(GenericParam::Lifetime)
///         } else if lookahead.peek(Token![const]) {
///             input.parse().map(GenericParam::Const)
///         } else {
///             Err(lookahead.error())
///         }
///     }
/// }
/// ```
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<&'static str>>,
}

pub fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
    Lookahead1 {
        scope,
        cursor,
        comparisons: RefCell::new(Vec::new()),
    }
}

fn peek_impl(
    lookahead: &Lookahead1,
    peek: fn(Cursor) -> bool,
    display: fn() -> &'static str,
) -> bool {
    if peek(lookahead.cursor) {
        return true;
    }
    lookahead.comparisons.borrow_mut().push(display());
    false
}

impl<'a> Lookahead1<'a> {
    /// Looks at the next token in the parse stream to determine whether it
    /// matches the requested type of token.
    ///
    /// # Syntax
    ///
    /// Note that this method does not use turbofish syntax. Pass the peek type
    /// inside of parentheses.
    ///
    /// - `input.peek(Token![struct])`
    /// - `input.peek(Token![==])`
    /// - `input.peek(Ident)` *(does not accept keywords)*
    /// - `input.peek(Ident::peek_any)`
    /// - `input.peek(Lifetime)`
    /// - `input.peek(token::Brace)`
    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        peek_impl(self, T::Token::peek, T::Token::display)
    }

    /// Triggers an error at the current position of the parse stream.
    ///
    /// The error message will identify all of the expected token types that
    /// have been peeked against this lookahead instance.
    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => {
                if self.cursor.eof() {
                    Error::new(self.scope, "unexpected end of input")
                } else {
                    Error::new(self.cursor.span(), "unexpected token")
                }
            }
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            2 => {
                let message = format!("expected {} or {}", comparisons[0], comparisons[1]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let join = comparisons.join(", ");
                let message = format!("expected one of: {}", join);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
/// without consuming it from the stream.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
///
/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
pub trait Peek: Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Peek for F {
    type Token = T;
}

pub enum TokenMarker {}

impl<S> IntoSpans<S> for TokenMarker {
    fn into_spans(self) -> S {
        match self {}
    }
}

pub fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
    cursor.group(delimiter).is_some()
}

impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
<commit_msg>Improve lookahead documentation<commit_after>use crate::buffer::Cursor;
use crate::error::{self, Error};
use crate::sealed::lookahead::Sealed;
use crate::span::IntoSpans;
use crate::token::Token;
use proc_macro2::{Delimiter, Span};
use std::cell::RefCell;

/// Support for checking the next token in a stream to decide how to parse.
///
/// An important advantage over [`ParseStream::peek`] is that here we
/// automatically construct an appropriate error message based on the token
/// alternatives that get peeked. If you are producing your own error message,
/// go ahead and use `ParseStream::peek` instead.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
/// [`ParseStream::lookahead1`]: crate::parse::ParseBuffer::lookahead1
///
/// Please be aware that advancing the source stream with parse() will not advance
/// the lookahead object.
///
/// # Example
///
/// ```
/// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Result, Token, TypeParam};
/// use syn::parse::{Parse, ParseStream};
///
/// // A generic parameter, a single one of the comma-separated elements inside
/// // angle brackets in:
/// //
/// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
/// //
/// // On invalid input, lookahead gives us a reasonable error message.
/// //
/// //     error: expected one of: identifier, lifetime, `const`
/// //       |
/// //     5 |     fn f<!Sized>() {}
/// //       |          ^
/// enum GenericParam {
///     Type(TypeParam),
///     Lifetime(LifetimeDef),
///     Const(ConstParam),
/// }
///
/// impl Parse for GenericParam {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let lookahead = input.lookahead1();
///         if lookahead.peek(Ident) {
///             input.parse().map(GenericParam::Type)
///         } else if lookahead.peek(Lifetime) {
///             input.parse().map(GenericParam::Lifetime)
///         } else if lookahead.peek(Token![const]) {
///             input.parse().map(GenericParam::Const)
///         } else {
///             Err(lookahead.error())
///         }
///     }
/// }
/// ```
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<&'static str>>,
}

pub fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
    Lookahead1 {
        scope,
        cursor,
        comparisons: RefCell::new(Vec::new()),
    }
}

fn peek_impl(
    lookahead: &Lookahead1,
    peek: fn(Cursor) -> bool,
    display: fn() -> &'static str,
) -> bool {
    if peek(lookahead.cursor) {
        return true;
    }
    lookahead.comparisons.borrow_mut().push(display());
    false
}

impl<'a> Lookahead1<'a> {
    /// Looks at the next token in the parse stream to determine whether it
    /// matches the requested type of token.
    ///
    /// # Syntax
    ///
    /// Note that this method does not use turbofish syntax. Pass the peek type
    /// inside of parentheses.
    ///
    /// - `input.peek(Token![struct])`
    /// - `input.peek(Token![==])`
    /// - `input.peek(Ident)` *(does not accept keywords)*
    /// - `input.peek(Ident::peek_any)`
    /// - `input.peek(Lifetime)`
    /// - `input.peek(token::Brace)`
    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        peek_impl(self, T::Token::peek, T::Token::display)
    }

    /// Triggers an error at the current position of the parse stream.
    ///
    /// The error message will identify all of the expected token types that
    /// have been peeked against this lookahead instance.
    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => {
                if self.cursor.eof() {
                    Error::new(self.scope, "unexpected end of input")
                } else {
                    Error::new(self.cursor.span(), "unexpected token")
                }
            }
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            2 => {
                let message = format!("expected {} or {}", comparisons[0], comparisons[1]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let join = comparisons.join(", ");
                let message = format!("expected one of: {}", join);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
/// without consuming it from the stream.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
///
/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
pub trait Peek: Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Peek for F {
    type Token = T;
}

pub enum TokenMarker {}

impl<S> IntoSpans<S> for TokenMarker {
    fn into_spans(self) -> S {
        match self {}
    }
}

pub fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
    cursor.group(delimiter).is_some()
}

impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
<|endoftext|>