<commit_before>//! A document store with a flexible query language and built-in undo support.

use rusqlite::{params, Connection};
use std::path::Path;
use std::result::Result as Result_;
use thiserror::Error;

use crate::object::*;
use crate::query;

pub type Result<T, E = StoreError> = Result_<T, E>;

#[derive(Error, Debug)]
pub enum StoreError {
    #[error("database error")]
    Sqlite(#[from] rusqlite::Error),

    #[error("could not de/serialize object")]
    Serialization(#[from] serde_json::Error),
}

trait AsStoreResult<T> {
    fn as_store_result(self) -> Result<T>;
}

impl<T, E> AsStoreResult<T> for Result_<T, E>
where
    E: Into<StoreError>,
{
    fn as_store_result(self) -> Result<T> {
        self.map_err(|e| e.into())
    }
}

pub struct Store {
    conn: Connection,
}

impl Store {
    pub fn open(path: impl AsRef<Path>) -> Result<Store> {
        let mut store = Store {
            conn: Connection::open(path)?,
        };

        // Make SQLite use a write-ahead instead of a delete-based journal; see
        // [the SQLite documentation](https://www.sqlite.org/wal.html) for more info.
        store.conn.pragma_update(None, "journal_mode", &"WAL")?;

        // Check that the JSON1 extension is working.
        store
            .conn
            .prepare("SELECT json(\"{}\")")?
            .query(params![])
            // Explicitly ignore the value.
            .map(|_| {})?;

        store.upgrade_if_needed()?;

        Ok(store)
    }

    fn upgrade_if_needed(&mut self) -> Result<()> {
        // We check the version of the database and upgrade it if necessary.
        // Conveniently, this starts at 0 in an empty database.
        let version = self
            .conn
            .prepare("SELECT user_version from pragma_user_version")?
            .query_row(params![], |row| row.get::<usize, i64>(0))? as usize;

        // We use `AUTOINCREMENT` on the objects table so that IDs are not reused.
        let updates = [
            "
                CREATE TABLE objects (
                    object_id INTEGER PRIMARY KEY AUTOINCREMENT,
                    properties TEXT
                );
            ",
            "
                CREATE TABLE object_changes (
                    serial INTEGER PRIMARY KEY,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    object_id INTEGER,
                    action TEXT,
                    previous TEXT
                );
                CREATE TABLE checkpoints (
                    checkpoint_id INTEGER PRIMARY KEY,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    serial INTEGER
                );
            ",
        ];

        // We set the `user_version` after each update to ensure updates are not applied twice if one
        // in a sequence of updates fails.
        for (version, update) in updates.iter().enumerate().skip(version) {
            self.conn.execute_batch(update)?;
            self.conn
                .pragma_update(None, "user_version", &(version as i64))?;
        }

        Ok(())
    }

    pub fn all(&self) -> Collection {
        Collection {
            conn: &self.conn,
            query: Box::new(query::Empty {}),
        }
    }

    pub fn query(&self, query: Box<dyn query::QueryNode>) -> Collection {
        Collection {
            conn: &self.conn,
            query,
        }
    }

    pub fn add(&mut self, object: Object) -> Result<i64> {
        let object_serialized = serde_json::to_string(&object)?;

        self.conn
            .prepare("INSERT INTO objects(properties) VALUES(?)")?
            .execute(params![object_serialized])?;

        Ok(self.conn.last_insert_rowid() as i64)
    }
}

pub struct Collection<'a> {
    conn: &'a Connection,
    query: Box<dyn query::QueryNode>,
}

impl<'a> Collection<'a> {
    fn prepare_with_query(
        &self,
        prefix: &str,
    ) -> Result<(rusqlite::Statement, Vec<Box<dyn rusqlite::ToSql>>)> {
        let (where_clause, params) = self.query.to_sql_clause();
        Ok((
            self.conn
                .prepare(&format!("{} WHERE {}", prefix, where_clause))?,
            params,
        ))
    }

    pub fn len(&self) -> Result<usize> {
        let (mut statement, params) = self.prepare_with_query("SELECT COUNT(*) FROM objects")?;
        Ok(statement
            // This workaround can be removed when https://github.com/rusqlite/rusqlite/issues/700
            // is closed
            .query_row(params, |row| row.get::<usize, i64>(0))? as usize)
    }

    pub fn iter(&self) -> Result<impl Iterator<Item = Object> + 'a> {
        let (mut statement, params) =
            self.prepare_with_query("SELECT object_id, properties FROM objects")?;

        let rows = statement.query_and_then(params, |row| {
            Ok((row.get::<usize, i64>(0)?, row.get::<usize, String>(1)?))
        })?;

        let result = Ok(rows
            .map(|r: rusqlite::Result<(i64, String)>| {
                r.as_store_result()
                    .and_then(|(object_id, serialized_object)| {
                        let mut object =
                            serde_json::from_str::<Object>(&serialized_object).as_store_result()?;

                        object.insert("object-id".to_string(), PropValue::Number(object_id));
                        Ok(object)
                    })
            })
            .collect::<Result<Vec<Object>>>()?
            .into_iter());

        result
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use tempdir::TempDir;

    fn open_store(tempdir: &TempDir, name: &str) -> Store {
        Store::open(tempdir.path().join(name)).unwrap()
    }

    fn test_dir() -> TempDir {
        TempDir::new("qualia-store").unwrap()
    }

    fn mkobject_(proplist: serde_json::Value) -> Object {
        let proplist_map = proplist.as_object().unwrap();

        proplist_map
            .iter()
            .map(|(k, v)| (k.clone(), PropValue::from(v)))
            .collect()
    }

    macro_rules! mkobject {
        ( $($x:tt)* ) => {
            mkobject_(json!({ $($x)* }))
        };
    }

    fn sort_objects(objects: &mut Vec<Object>) {
        objects.sort_by_key(|o| {
            o.get("name")
                .expect("test objects should have a name")
                .as_str()
                .expect("`name` of test objects should be a string")
                .clone()
        })
    }

    #[test]
    fn new_store_is_empty() -> Result<()> {
        assert_eq!(open_store(&test_dir(), "store.qualia").all().len()?, 0);

        Ok(())
    }

    #[test]
    fn added_objects_exist() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        store.add(mkobject!("name": "b", "c": "d"))?;
        store.add(mkobject!("name": "d", "c": "f"))?;
        store.add(mkobject!("name": "c", "c": "e"))?;

        let all = store.all();

        assert_eq!(all.len()?, 3);
        let mut all_objects = all.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut all_objects);
        assert_eq!(
            all_objects,
            vec![
                mkobject!("name": "b", "c": "d", "object-id": 1),
                mkobject!("name": "c", "c": "e", "object-id": 3),
                mkobject!("name": "d", "c": "f", "object-id": 2)
            ],
        );

        Ok(())
    }

    #[test]
    fn added_objects_can_be_found() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        store.add(mkobject!("name": "b", "c": "d"))?;
        store.add(mkobject!("name": "d", "c": "f"))?;

        let found = store.query(Box::new(query::PropEqual {
            name: "name".to_string(),
            value: "d".to_string(),
        }));

        assert_eq!(found.len()?, 1);
        let mut found_objects = found.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut found_objects);
        assert_eq!(
            found_objects,
            vec![mkobject!("name": "d", "c": "f", "object-id": 2)],
        );

        Ok(())
    }

    #[test]
    fn adding_objects_returns_their_id() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        let object_id = store.add(mkobject!("name": "b", "c": "d"))?;

        let found = store.query(Box::new(query::PropEqual {
            name: "name".to_string(),
            value: "b".to_string(),
        }));

        assert_eq!(found.len()?, 1);
        let mut found_objects = found.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut found_objects);
        assert_eq!(
            found_objects,
            vec![mkobject!("name": "b", "c": "d", "object-id": object_id)],
        );

        Ok(())
    }
}
<commit_msg>Fix database migrations<commit_after>//! A document store with a flexible query language and built-in undo support.

use rusqlite::{params, Connection};
use std::path::Path;
use std::result::Result as Result_;
use thiserror::Error;

use crate::object::*;
use crate::query;

pub type Result<T, E = StoreError> = Result_<T, E>;

#[derive(Error, Debug)]
pub enum StoreError {
    #[error("database error")]
    Sqlite(#[from] rusqlite::Error),

    #[error("could not de/serialize object")]
    Serialization(#[from] serde_json::Error),
}

trait AsStoreResult<T> {
    fn as_store_result(self) -> Result<T>;
}

impl<T, E> AsStoreResult<T> for Result_<T, E>
where
    E: Into<StoreError>,
{
    fn as_store_result(self) -> Result<T> {
        self.map_err(|e| e.into())
    }
}

pub struct Store {
    conn: Connection,
}

impl Store {
    pub fn open(path: impl AsRef<Path>) -> Result<Store> {
        let mut store = Store {
            conn: Connection::open(path)?,
        };

        // Make SQLite use a write-ahead instead of a delete-based journal; see
        // [the SQLite documentation](https://www.sqlite.org/wal.html) for more info.
        store.conn.pragma_update(None, "journal_mode", &"WAL")?;

        // Check that the JSON1 extension is working.
        store
            .conn
            .prepare("SELECT json(\"{}\")")?
            .query(params![])
            // Explicitly ignore the value.
            .map(|_| {})?;

        store.upgrade_if_needed()?;

        Ok(store)
    }

    fn upgrade_if_needed(&mut self) -> Result<()> {
        // We check the version of the database and upgrade it if necessary.
        // Conveniently, this starts at 0 in an empty database.
        let version = self
            .conn
            .prepare("SELECT user_version from pragma_user_version")?
            .query_row(params![], |row| row.get::<usize, i64>(0))? as usize;

        // We use `AUTOINCREMENT` on the objects table so that IDs are not reused.
        let updates = [
            "
                CREATE TABLE objects (
                    object_id INTEGER PRIMARY KEY AUTOINCREMENT,
                    properties TEXT
                );
            ",
            "
                CREATE TABLE object_changes (
                    serial INTEGER PRIMARY KEY,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    object_id INTEGER,
                    action TEXT,
                    previous TEXT
                );
                CREATE TABLE checkpoints (
                    checkpoint_id INTEGER PRIMARY KEY,
                    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    serial INTEGER
                );
            ",
        ];

        // We set the `user_version` after each update to ensure updates are not applied twice if one
        // in a sequence of updates fails.
        for (version, update) in updates.iter().enumerate().skip(version) {
            self.conn.execute_batch(update)?;
            self.conn
                .pragma_update(None, "user_version", &((version + 1) as i64))?;
        }

        Ok(())
    }

    pub fn all(&self) -> Collection {
        Collection {
            conn: &self.conn,
            query: Box::new(query::Empty {}),
        }
    }

    pub fn query(&self, query: Box<dyn query::QueryNode>) -> Collection {
        Collection {
            conn: &self.conn,
            query,
        }
    }

    pub fn add(&mut self, object: Object) -> Result<i64> {
        let object_serialized = serde_json::to_string(&object)?;

        self.conn
            .prepare("INSERT INTO objects(properties) VALUES(?)")?
            .execute(params![object_serialized])?;

        Ok(self.conn.last_insert_rowid() as i64)
    }
}

pub struct Collection<'a> {
    conn: &'a Connection,
    query: Box<dyn query::QueryNode>,
}

impl<'a> Collection<'a> {
    fn prepare_with_query(
        &self,
        prefix: &str,
    ) -> Result<(rusqlite::Statement, Vec<Box<dyn rusqlite::ToSql>>)> {
        let (where_clause, params) = self.query.to_sql_clause();
        Ok((
            self.conn
                .prepare(&format!("{} WHERE {}", prefix, where_clause))?,
            params,
        ))
    }

    pub fn len(&self) -> Result<usize> {
        let (mut statement, params) = self.prepare_with_query("SELECT COUNT(*) FROM objects")?;
        Ok(statement
            // This workaround can be removed when https://github.com/rusqlite/rusqlite/issues/700
            // is closed
            .query_row(params, |row| row.get::<usize, i64>(0))? as usize)
    }

    pub fn iter(&self) -> Result<impl Iterator<Item = Object> + 'a> {
        let (mut statement, params) =
            self.prepare_with_query("SELECT object_id, properties FROM objects")?;

        let rows = statement.query_and_then(params, |row| {
            Ok((row.get::<usize, i64>(0)?, row.get::<usize, String>(1)?))
        })?;

        let result = Ok(rows
            .map(|r: rusqlite::Result<(i64, String)>| {
                r.as_store_result()
                    .and_then(|(object_id, serialized_object)| {
                        let mut object =
                            serde_json::from_str::<Object>(&serialized_object).as_store_result()?;

                        object.insert("object-id".to_string(), PropValue::Number(object_id));
                        Ok(object)
                    })
            })
            .collect::<Result<Vec<Object>>>()?
            .into_iter());

        result
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use tempdir::TempDir;

    fn open_store(tempdir: &TempDir, name: &str) -> Store {
        Store::open(tempdir.path().join(name)).unwrap()
    }

    fn test_dir() -> TempDir {
        TempDir::new("qualia-store").unwrap()
    }

    fn mkobject_(proplist: serde_json::Value) -> Object {
        let proplist_map = proplist.as_object().unwrap();

        proplist_map
            .iter()
            .map(|(k, v)| (k.clone(), PropValue::from(v)))
            .collect()
    }

    macro_rules! mkobject {
        ( $($x:tt)* ) => {
            mkobject_(json!({ $($x)* }))
        };
    }

    fn sort_objects(objects: &mut Vec<Object>) {
        objects.sort_by_key(|o| {
            o.get("name")
                .expect("test objects should have a name")
                .as_str()
                .expect("`name` of test objects should be a string")
                .clone()
        })
    }

    #[test]
    fn new_store_is_empty() -> Result<()> {
        assert_eq!(open_store(&test_dir(), "store.qualia").all().len()?, 0);

        Ok(())
    }

    #[test]
    fn added_objects_exist() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        store.add(mkobject!("name": "b", "c": "d"))?;
        store.add(mkobject!("name": "d", "c": "f"))?;
        store.add(mkobject!("name": "c", "c": "e"))?;

        let all = store.all();

        assert_eq!(all.len()?, 3);
        let mut all_objects = all.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut all_objects);
        assert_eq!(
            all_objects,
            vec![
                mkobject!("name": "b", "c": "d", "object-id": 1),
                mkobject!("name": "c", "c": "e", "object-id": 3),
                mkobject!("name": "d", "c": "f", "object-id": 2)
            ],
        );

        Ok(())
    }

    #[test]
    fn added_objects_can_be_found() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        store.add(mkobject!("name": "b", "c": "d"))?;
        store.add(mkobject!("name": "d", "c": "f"))?;

        let found = store.query(Box::new(query::PropEqual {
            name: "name".to_string(),
            value: "d".to_string(),
        }));

        assert_eq!(found.len()?, 1);
        let mut found_objects = found.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut found_objects);
        assert_eq!(
            found_objects,
            vec![mkobject!("name": "d", "c": "f", "object-id": 2)],
        );

        Ok(())
    }

    #[test]
    fn adding_objects_returns_their_id() -> Result<()> {
        let test_dir = test_dir();
        let mut store = open_store(&test_dir, "store.qualia");

        let object_id = store.add(mkobject!("name": "b", "c": "d"))?;

        let found = store.query(Box::new(query::PropEqual {
            name: "name".to_string(),
            value: "b".to_string(),
        }));

        assert_eq!(found.len()?, 1);
        let mut found_objects = found.iter()?.collect::<Vec<Object>>();
        sort_objects(&mut found_objects);
        assert_eq!(
            found_objects,
            vec![mkobject!("name": "b", "c": "d", "object-id": object_id)],
        );

        Ok(())
    }
}
<|endoftext|>


<commit_before>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use clause::*;

    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🐟", "!🚀"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🐟"]));
        assert!(term.contains(&symbol!["!🚀"]));
    }

    #[test]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🐟", "!🚀"];

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🐟"]);
        assert!(! term.contains(&symbol!["🐟"]));

        term.remove(symbol!["!🚀"]);
        assert!(! term.contains(&symbol!["!🚀"]));
    }

    #[test]
    fn lrs_compare_terms() {
        let a = term!["A", "B"];
        let b = term!["B", "C"];
        let clause = clause![a, b];

        assert!(clause.contains(&term!["A", "B"]));
        assert!(clause.contains(&term!["B", "A"]));

        assert!(clause.contains(&term!["C", "B"]));
        assert!(! clause.contains(&term!["C", "D"]));
    }

    #[test]
    fn lrs_compare_clauses() {
        let c1 = clause![term!["A"]];
        let c2 = clause![term!["A"]];
        assert_eq!(c1, c2);

        let c3 = clause![term!["A", "B"], term!["!B"]];
        let c4 = clause![term!["B", "A"], term!["!B"]];
        assert_eq!(c3, c4);

        let c5 = clause![term!["A", "B"], term!["B"]];
        let c6 = clause![term!["A"], term!["!B"]];
        assert!(c5 != c6);
    }

    #[test]
    fn lrs_simple_reduce() {
        let a1 = term!["A", "!B"];
        let b1 = term!["C", "!D"];
        let c1 = term!["E"];

        let mut clause = clause![a1, b1, c1];
        clause.reduce();

        /* We should no longer contain "E" */
        assert!(! clause.contains(&term!["E"]));

        ///// More complex example
        let a2 = term!["A", "!B"];
        let b2 = term!["C", "!D"];
        let c2 = term!["E"];
        let d = term!["F"];

        let mut cl2 = clause![a2.clone(), b2.clone(), c2, d];
        cl2.reduce();
        cl2.reduce();

        /* Should now look like {A, !B} & {C, !D} */
        assert_eq!(cl2, clause![a2, b2]);
    }
}
<commit_msg>Adding merge reduce test which has to introduce differential branching to pass<commit_after>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use clause::*;

    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🐟", "!🚀"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🐟"]));
        assert!(term.contains(&symbol!["!🚀"]));
    }

    #[test]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🐟", "!🚀"];

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🐟"]);
        assert!(! term.contains(&symbol!["🐟"]));

        term.remove(symbol!["!🚀"]);
        assert!(! term.contains(&symbol!["!🚀"]));
    }

    #[test]
    fn lrs_compare_terms() {
        let a = term!["A", "B"];
        let b = term!["B", "C"];
        let clause = clause![a, b];

        assert!(clause.contains(&term!["A", "B"]));
        assert!(clause.contains(&term!["B", "A"]));

        assert!(clause.contains(&term!["C", "B"]));
        assert!(! clause.contains(&term!["C", "D"]));
    }

    #[test]
    fn lrs_compare_clauses() {
        let c1 = clause![term!["A"]];
        let c2 = clause![term!["A"]];
        assert_eq!(c1, c2);

        let c3 = clause![term!["A", "B"], term!["!B"]];
        let c4 = clause![term!["B", "A"], term!["!B"]];
        assert_eq!(c3, c4);

        let c5 = clause![term!["A", "B"], term!["B"]];
        let c6 = clause![term!["A"], term!["!B"]];
        assert!(c5 != c6);
    }

    #[test]
    fn lrs_simple_reduce() {
        let a1 = term!["A", "!B"];
        let b1 = term!["C", "!D"];
        let c1 = term!["E"];

        let mut clause = clause![a1, b1, c1];
        clause.reduce();

        /* We should no longer contain "E" */
        assert!(! clause.contains(&term!["E"]));

        ///// More complex example
        let a2 = term!["A", "!B"];
        let b2 = term!["C", "!D"];
        let c2 = term!["E"];
        let d = term!["F"];

        let mut cl2 = clause![a2.clone(), b2.clone(), c2, d];
        cl2.reduce();
        cl2.reduce();

        /* Should now look like {A, !B} & {C, !D} */
        assert_eq!(cl2, clause![a2, b2]);
    }

    #[test]
    fn lrs_merge_reduce() {
        let a1 = term!["A", "!B"];
        let b1 = term!["A", "B"];
        let c1 = term!["C", "!D"];

        let mut cl1 = clause![a1, b1, c1];
        cl1.reduce();
        assert_eq!(cl1, clause![term!["A"], term!["C", "!D"]]);

        /* ...Oh fuck this is a difficult one... */
        let a2 = term!["A", "!B"];
        let b2 = term!["A", "B"];
        let c2 = term!["!A", "D"];

        let mut cl2 = clause![a2, b2, c2];
        cl2.reduce();
        cl2.reduce();

        /* It needs to have picked a2 and b2 first 😟 */
        assert_eq!(cl2, clause![term!["D"]]);
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Eq, PartialEq)]
pub struct Posn {
    offset: u32,
    line: u32,
    column: u32
}

#[derive(Debug, Eq, PartialEq)]
pub struct Span {
    start: Posn,
    end: Posn
}

#[derive(Debug, PartialEq)]
#[allow(dead_code)]
pub enum Token {
    Null,
    True,
    False,

    // 11.6.2.1 Keywords
    Break,
    Case,
    Catch,
    Class,
    Const,
    Continue,
    Debugger,
    Default,
    Delete,
    Do,
    Else,
    Export,
    Extends,
    Finally,
    For,
    Function,
    If,
    Import,
    In,
    Instanceof,
    Let,
    New,
    Return,
    Static,
    Super,
    Switch,
    This,
    Throw,
    Try,
    Typeof,
    Var,
    Void,
    While,
    With,
    Yield,

    // 11.6.2.2 Future Reserved Words
    Enum,
    Await,
    Implements,
    Interface,
    Package,
    Private,
    Protected,
    Public,

    // 11.7 Punctuators
    LBrace,
    RBrace,
    LParen,
    RParen,
    LBrack,
    RBrack,
    Dot,
    Ellipsis,
    Semi,
    Comma,
    LAngle,
    RAngle,
    LEq,
    GEq,
    Eq,
    NEq,
    StrictEq,
    StrictNEq,
    Plus,
    Minus,
    Star,
    Mod,
    Slash,
    Inc,
    Dec,
    LShift,
    RShift,
    URShift,
    BitAnd,
    BitOr,
    BitXor,
    Bang,
    Tilde,
    LogicalAnd,
    LogicalOr,
    Question,
    Colon,
    Assign,
    PlusAssign,
    MinusAssign,
    StarAssign,
    SlashAssign,
    ModAssign,
    LShiftAssign,
    RShiftAssign,
    URShiftAssign,
    BitAndAssign,
    BitOrAssign,
    BitXorAssign,
    Arrow,

    DecimalInt(String),
    BinaryInt(String),
    OctalInt(String),
    HexInt(String),
    Float(String),

    String(String),
    RegExp(String),

    Identifier(String),

    Newline,
    Error(char)
}
<commit_msg>Posn should be transparent and copyable<commit_after>#[derive(Debug, Copy, Eq, PartialEq)]
pub struct Posn {
    pub offset: u32,
    pub line: u32,
    pub column: u32
}

#[derive(Debug, Eq, PartialEq)]
pub struct Span {
    start: Posn,
    end: Posn
}

#[derive(Debug, PartialEq)]
#[allow(dead_code)]
pub enum Token {
    Null,
    True,
    False,

    // 11.6.2.1 Keywords
    Break,
    Case,
    Catch,
    Class,
    Const,
    Continue,
    Debugger,
    Default,
    Delete,
    Do,
    Else,
    Export,
    Extends,
    Finally,
    For,
    Function,
    If,
    Import,
    In,
    Instanceof,
    Let,
    New,
    Return,
    Static,
    Super,
    Switch,
    This,
    Throw,
    Try,
    Typeof,
    Var,
    Void,
    While,
    With,
    Yield,

    // 11.6.2.2 Future Reserved Words
    Enum,
    Await,
    Implements,
    Interface,
    Package,
    Private,
    Protected,
    Public,

    // 11.7 Punctuators
    LBrace,
    RBrace,
    LParen,
    RParen,
    LBrack,
    RBrack,
    Dot,
    Ellipsis,
    Semi,
    Comma,
    LAngle,
    RAngle,
    LEq,
    GEq,
    Eq,
    NEq,
    StrictEq,
    StrictNEq,
    Plus,
    Minus,
    Star,
    Mod,
    Slash,
    Inc,
    Dec,
    LShift,
    RShift,
    URShift,
    BitAnd,
    BitOr,
    BitXor,
    Bang,
    Tilde,
    LogicalAnd,
    LogicalOr,
    Question,
    Colon,
    Assign,
    PlusAssign,
    MinusAssign,
    StarAssign,
    SlashAssign,
    ModAssign,
    LShiftAssign,
    RShiftAssign,
    URShiftAssign,
    BitAndAssign,
    BitOrAssign,
    BitXorAssign,
    Arrow,

    DecimalInt(String),
    BinaryInt(String),
    OctalInt(String),
    HexInt(String),
    Float(String),

    String(String),
    RegExp(String),

    Identifier(String),

    Newline,
    Error(char)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use jsapi::JSTracer;

use serialize::Encoder;

impl Encoder<()> for JSTracer {
    fn emit_nil(&mut self) -> Result<(), ()> { Ok(()) }
    fn emit_uint(&mut self, _v: uint) -> Result<(), ()> { Ok(()) }
    fn emit_u64(&mut self, _v: u64) -> Result<(), ()> { Ok(()) }
    fn emit_u32(&mut self, __v: u32) -> Result<(), ()> { Ok(()) }
    fn emit_u16(&mut self, _v: u16) -> Result<(), ()> { Ok(()) }
    fn emit_u8(&mut self, _v: u8) -> Result<(), ()> { Ok(()) }
    fn emit_int(&mut self, _v: int) -> Result<(), ()> { Ok(()) }
    fn emit_i64(&mut self, _v: i64) -> Result<(), ()> { Ok(()) }
    fn emit_i32(&mut self, _v: i32) -> Result<(), ()> { Ok(()) }
    fn emit_i16(&mut self, _v: i16) -> Result<(), ()> { Ok(()) }
    fn emit_i8(&mut self, _v: i8) -> Result<(), ()> { Ok(()) }
    fn emit_bool(&mut self, _v: bool) -> Result<(), ()> { Ok(()) }
    fn emit_f64(&mut self, _v: f64) -> Result<(), ()> { Ok(()) }
    fn emit_f32(&mut self, _v: f32) -> Result<(), ()> { Ok(()) }
    fn emit_char(&mut self, _v: char) -> Result<(), ()> { Ok(()) }
    fn emit_str(&mut self, _v: &str) -> Result<(), ()> { Ok(()) }
    fn emit_enum(&mut self, _name: &str, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_variant_arg(&mut self, _a_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_struct_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_struct_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_arg(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_struct_arg(&mut self, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_option(&mut self, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_option_none(&mut self) -> Result<(), ()> { Ok(()) }
    fn emit_option_some(&mut self, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_seq(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_seq_elt(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
}
<commit_msg>Remove unused trace.rs.<commit_after><|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use color::Color;
use geom::size::Size2D;
use geom::matrix::Matrix4;
use layers::Layer;
use std::rc::Rc;

pub struct Scene<T> {
    pub root: Option<Rc<Layer<T>>>,
    pub size: Size2D<f32>,
    pub transform: Matrix4<f32>,
    pub background_color: Color
}

pub fn Scene<T>(size: Size2D<f32>, transform: Matrix4<f32>) -> Scene<T> {
    Scene {
        root: None,
        size: size,
        transform: transform,
        background_color: Color {
                  r: 0.38f32,
                  g: 0.36f32,
                  b: 0.36f32,
                  a: 1.0f32
              }
    }
}

impl<T> Scene<T> {
    // FIXME: Workaround for cross-crate bug regarding mutability of class fields
    pub fn set_transform(&mut self, new_transform: Matrix4<f32>) {
        self.transform = new_transform;
    }
}

<commit_msg>Remove the unused Scene::set_transform method<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use color::Color;
use geom::size::Size2D;
use geom::matrix::Matrix4;
use layers::Layer;
use std::rc::Rc;

pub struct Scene<T> {
    pub root: Option<Rc<Layer<T>>>,
    pub size: Size2D<f32>,
    pub transform: Matrix4<f32>,
    pub background_color: Color
}

pub fn Scene<T>(size: Size2D<f32>, transform: Matrix4<f32>) -> Scene<T> {
    Scene {
        root: None,
        size: size,
        transform: transform,
        background_color: Color {
                  r: 0.38f32,
                  g: 0.36f32,
                  b: 0.36f32,
                  a: 1.0f32
              }
    }
}

<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

use crate::formatter::fast::options::FastFormatterOptions;
use crate::formatter::fast::trait_options::SpecializedFormatterTraitOptions;

/// Default [`FastFormatter`] options
///
/// [`FastFormatter`]: type.FastFormatter.html
#[allow(missing_copy_implementations)]
#[allow(missing_debug_implementations)]
pub struct DefaultFastFormatterTraitOptions;

impl SpecializedFormatterTraitOptions for DefaultFastFormatterTraitOptions {
	const __IS_FAST_FORMATTER: bool = true;

	/// Set to `true` so symbol resolvers can be used
	const ENABLE_SYMBOL_RESOLVER: bool = true;

	/// Enables support for formatting `db`, `dw`, `dd`, `dq`.
	///
	/// For fastest code, this should be *disabled*, not enabled.
	const ENABLE_DB_DW_DD_DQ: bool = true;

	/// Add a space after the operand separator
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov rax, rcx`
	/// 👍 | `false` | `mov rax,rcx`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn space_after_operand_separator(options: &FastFormatterOptions) -> bool {
		options.space_after_operand_separator()
	}

	/// Show `RIP+displ` or the virtual address
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,[rip+12345678h]`
	/// 👍 | `false` | `mov eax,[1029384756AFBECDh]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn rip_relative_addresses(options: &FastFormatterOptions) -> bool {
		options.rip_relative_addresses()
	}

	/// Use pseudo instructions
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// 👍 | `true` | `vcmpnltsd xmm2,xmm6,xmm3`
	/// _ | `false` | `vcmpsd xmm2,xmm6,xmm3,5h`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn use_pseudo_ops(options: &FastFormatterOptions) -> bool {
		options.use_pseudo_ops()
	}

	/// Show the original value after the symbol name
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,[myfield (12345678)]`
	/// 👍 | `false` | `mov eax,[myfield]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn show_symbol_address(options: &FastFormatterOptions) -> bool {
		options.show_symbol_address()
	}

	/// Always show the effective segment register. If the option is `false`, only show the segment register if
	/// there's a segment override prefix.
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,ds:[ecx]`
	/// 👍 | `false` | `mov eax,[ecx]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn always_show_segment_register(options: &FastFormatterOptions) -> bool {
		options.always_show_segment_register()
	}

	/// Always show the size of memory operands
	///
	/// Default | Value | Example | Example
	/// --------|-------|---------|--------
	/// _ | `true` | `mov eax,dword ptr [ebx]` | `add byte ptr [eax],0x12`
	/// 👍 | `false` | `mov eax,[ebx]` | `add byte ptr [eax],0x12`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn always_show_memory_size(options: &FastFormatterOptions) -> bool {
		options.always_show_memory_size()
	}

	/// Use uppercase hex digits
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// 👍 | `true` | `0xFF`
	/// _ | `false` | `0xff`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn uppercase_hex(options: &FastFormatterOptions) -> bool {
		options.uppercase_hex()
	}

	/// Use a hex prefix (`0x`) or a hex suffix (`h`)
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `0x5A`
	/// 👍 | `false` | `5Ah`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn use_hex_prefix(options: &FastFormatterOptions) -> bool {
		options.use_hex_prefix()
	}
}
<commit_msg>Add doc comment since `#[doc(hidden)]` can't be used there<commit_after>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

use crate::formatter::fast::options::FastFormatterOptions;
use crate::formatter::fast::trait_options::SpecializedFormatterTraitOptions;

/// Default [`FastFormatter`] options
///
/// [`FastFormatter`]: type.FastFormatter.html
#[allow(missing_copy_implementations)]
#[allow(missing_debug_implementations)]
pub struct DefaultFastFormatterTraitOptions;

impl SpecializedFormatterTraitOptions for DefaultFastFormatterTraitOptions {
	/// DO NOT USE: NOT PART OF THE PUBLIC API
	const __IS_FAST_FORMATTER: bool = true;

	/// Set to `true` so symbol resolvers can be used
	const ENABLE_SYMBOL_RESOLVER: bool = true;

	/// Enables support for formatting `db`, `dw`, `dd`, `dq`.
	///
	/// For fastest code, this should be *disabled*, not enabled.
	const ENABLE_DB_DW_DD_DQ: bool = true;

	/// Add a space after the operand separator
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov rax, rcx`
	/// 👍 | `false` | `mov rax,rcx`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn space_after_operand_separator(options: &FastFormatterOptions) -> bool {
		options.space_after_operand_separator()
	}

	/// Show `RIP+displ` or the virtual address
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,[rip+12345678h]`
	/// 👍 | `false` | `mov eax,[1029384756AFBECDh]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn rip_relative_addresses(options: &FastFormatterOptions) -> bool {
		options.rip_relative_addresses()
	}

	/// Use pseudo instructions
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// 👍 | `true` | `vcmpnltsd xmm2,xmm6,xmm3`
	/// _ | `false` | `vcmpsd xmm2,xmm6,xmm3,5h`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn use_pseudo_ops(options: &FastFormatterOptions) -> bool {
		options.use_pseudo_ops()
	}

	/// Show the original value after the symbol name
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,[myfield (12345678)]`
	/// 👍 | `false` | `mov eax,[myfield]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn show_symbol_address(options: &FastFormatterOptions) -> bool {
		options.show_symbol_address()
	}

	/// Always show the effective segment register. If the option is `false`, only show the segment register if
	/// there's a segment override prefix.
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `mov eax,ds:[ecx]`
	/// 👍 | `false` | `mov eax,[ecx]`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn always_show_segment_register(options: &FastFormatterOptions) -> bool {
		options.always_show_segment_register()
	}

	/// Always show the size of memory operands
	///
	/// Default | Value | Example | Example
	/// --------|-------|---------|--------
	/// _ | `true` | `mov eax,dword ptr [ebx]` | `add byte ptr [eax],0x12`
	/// 👍 | `false` | `mov eax,[ebx]` | `add byte ptr [eax],0x12`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn always_show_memory_size(options: &FastFormatterOptions) -> bool {
		options.always_show_memory_size()
	}

	/// Use uppercase hex digits
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// 👍 | `true` | `0xFF`
	/// _ | `false` | `0xff`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn uppercase_hex(options: &FastFormatterOptions) -> bool {
		options.uppercase_hex()
	}

	/// Use a hex prefix (`0x`) or a hex suffix (`h`)
	///
	/// Default | Value | Example
	/// --------|-------|--------
	/// _ | `true` | `0x5A`
	/// 👍 | `false` | `5Ah`
	///
	/// # Arguments
	///
	/// * `options`: Current formatter options
	#[must_use]
	#[inline]
	fn use_hex_prefix(options: &FastFormatterOptions) -> bool {
		options.use_hex_prefix()
	}
}
<|endoftext|>


<commit_before><commit_msg>Cleanups println()<commit_after><|endoftext|>


<commit_before>pub struct KeyBuilder {
    key: Vec<u8>,
}

impl KeyBuilder {
    pub fn new() -> KeyBuilder {
        KeyBuilder {
            key: Vec::new(),
        }
    }

    pub fn with_capacity(size: usize) -> KeyBuilder {
        KeyBuilder {
            key: Vec::with_capacity(size),
        }
    }

    pub fn doc_key_mapping(key: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + key.len());
        kb.push_char(b'k');
        kb.push_string(key);
        kb
    }

    pub fn term_dict_mapping(term: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + term.len());
        kb.push_char(b't');
        kb.push_string(term);
        kb
    }

    pub fn chunk_active(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'a');
        kb
    }

    pub fn chunk_dir_list(chunk: u32, field_ord: u32, term_ord: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'd');
        kb.push_string(field_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(term_ord.to_string().as_bytes());
        kb
    }

    pub fn chunk_stat(chunk: u32, name: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b's');
        kb.push_string(name);
        kb
    }

    pub fn chunk_del_list(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'x');
        kb
    }

    #[inline]
    pub fn key(&self) -> &[u8] {
        &self.key[..]
    }

    #[inline]
    pub fn push_char(&mut self, c: u8) {
        if c == b'/' || c == b'\\' {
            self.key.push(b'\\');
        }
        self.key.push(c);
    }

    pub fn push_string(&mut self, s: &[u8]) {
        for c in s {
            self.push_char(*c);
        }
    }

    pub fn separator(&mut self) {
        self.key.push(b'/');
    }

    pub fn chunk(&mut self, chunk: u32) {
        self.key.push(b'c');
        self.push_string(chunk.to_string().as_bytes());
    }
}<commit_msg>Revert "Change key format"<commit_after>pub struct KeyBuilder {
    key: Vec<u8>,
}

impl KeyBuilder {
    pub fn new() -> KeyBuilder {
        KeyBuilder {
            key: Vec::new(),
        }
    }

    pub fn with_capacity(size: usize) -> KeyBuilder {
        KeyBuilder {
            key: Vec::with_capacity(size),
        }
    }

    pub fn doc_key_mapping(key: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + key.len());
        kb.push_char(b'k');
        kb.push_string(key);
        kb
    }

    pub fn term_dict_mapping(term: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + term.len());
        kb.push_char(b't');
        kb.push_string(term);
        kb
    }

    pub fn chunk_active(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'a');
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_dir_list(chunk: u32, field_ord: u32, term_ord: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'd');
        kb.push_string(field_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(term_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_stat(chunk: u32, name: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b's');
        kb.push_string(name);
        kb.separator();
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_del_list(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'x');
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    #[inline]
    pub fn key(&self) -> &[u8] {
        &self.key[..]
    }

    #[inline]
    pub fn push_char(&mut self, c: u8) {
        if c == b'/' || c == b'\\' {
            self.key.push(b'\\');
        }
        self.key.push(c);
    }

    pub fn push_string(&mut self, s: &[u8]) {
        for c in s {
            self.push_char(*c);
        }
    }

    pub fn separator(&mut self) {
        self.key.push(b'/');
    }
}<|endoftext|>


<commit_before>use std::collections::HashSet;

struct WorldMap{
    map: HashSet<(i8, i8)>
}

fn get_neighbours_coordinates(cell_coordinates: (i8,i8)) -> HashSet<(i8,i8)> {
    let mut neighbour_coordinates = HashSet::new();
    let (x, y) = cell_coordinates;
    neighbour_coordinates.insert((x-1, y-1));
    neighbour_coordinates.insert((x-1, y));
    neighbour_coordinates.insert((x-1, y+1));
    neighbour_coordinates.insert((x, y-1));
    neighbour_coordinates.insert((x, y+1));
    neighbour_coordinates.insert((x+1, y-1));
    neighbour_coordinates.insert((x+1, y));
    neighbour_coordinates.insert((x+1, y+1));
    return neighbour_coordinates;
}

impl WorldMap{

    fn empty() -> WorldMap {
        return WorldMap::new( HashSet::new() );
    }

    fn new(new_map: HashSet<(i8,i8)>) -> WorldMap {
        return WorldMap { map: new_map };
    }

    fn mark_cell_as_alive(&self, cell_coordinates: (i8, i8)) -> WorldMap {
        let mut new_map = self.map.clone();
        new_map.insert(cell_coordinates);
        let new_world = WorldMap::new(new_map);
        return new_world;
    }

    fn is_cell_alive(&self, cell_coordinates: (i8,i8)) -> bool {
        return self.map.contains(&cell_coordinates);
    }

    fn count_alive_neighbours(&self, cell_coordinates: (i8, i8)) -> usize {
        let neighbour_coordinates = get_neighbours_coordinates(cell_coordinates);
        let neighbours_alive = self.map.intersection(&neighbour_coordinates).collect::<Vec<&(i8,i8)>>();
        return neighbours_alive.len();
    }
}

#[test]
fn the_only_alive_cell_should_have_no_alive_neighbours() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let new_world = world.mark_cell_as_alive(coords);
    let alive_neighbours_count = new_world.count_alive_neighbours(coords);
    assert_eq!(0, alive_neighbours_count);
}

#[test]
fn alive_neighbour_on_the_diagonal_should_count() {
    let (x, y) = (0,0);
    let coords = (x,y);
    let world = WorldMap::empty();
    let new_world1 = world.mark_cell_as_alive(coords);
    let new_world2 = new_world1.mark_cell_as_alive((x, y+1));
    let alive_neighbours_count = new_world2.count_alive_neighbours(coords);
    assert_eq!(1, alive_neighbours_count);
}

#[test]
fn is_cell_alive_should_return_true_for_alive_cell() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let new_world = world.mark_cell_as_alive(coords);
    let is_alive = new_world.is_cell_alive(coords);
    assert_eq!(true, is_alive);
}

#[test]
fn is_cell_alive_should_return_false_for_dead_cell() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let is_alive = world.is_cell_alive(coords);
    assert_eq!(false, is_alive);
}
<commit_msg>rules 1 and 2 implemented<commit_after>use std::collections::HashSet;

struct WorldMap{
    map: HashSet<(i8, i8)>
}

fn get_neighbours_coordinates(cell_coordinates: (i8,i8)) -> HashSet<(i8,i8)> {
    let mut neighbour_coordinates = HashSet::new();
    let (x, y) = cell_coordinates;
    neighbour_coordinates.insert((x-1, y-1));
    neighbour_coordinates.insert((x-1, y));
    neighbour_coordinates.insert((x-1, y+1));
    neighbour_coordinates.insert((x, y-1));
    neighbour_coordinates.insert((x, y+1));
    neighbour_coordinates.insert((x+1, y-1));
    neighbour_coordinates.insert((x+1, y));
    neighbour_coordinates.insert((x+1, y+1));
    return neighbour_coordinates;
}

impl WorldMap{

    fn empty() -> WorldMap {
        return WorldMap::new( HashSet::new() );
    }

    fn new(new_map: HashSet<(i8,i8)>) -> WorldMap {
        return WorldMap { map: new_map };
    }

    fn mark_cell_alive(&self, cell_coordinates: (i8, i8)) -> WorldMap {
        let mut new_map = self.map.clone();
        new_map.insert(cell_coordinates);
        let new_world = WorldMap::new(new_map);
        return new_world;
    }

    fn is_cell_alive(&self, cell_coordinates: (i8,i8)) -> bool {
        return self.map.contains(&cell_coordinates);
    }

    fn count_alive_neighbours(&self, cell_coordinates: (i8, i8)) -> usize {
        let neighbour_coordinates = get_neighbours_coordinates(cell_coordinates);
        let neighbours_alive = self.map.intersection(&neighbour_coordinates).collect::<Vec<&(i8,i8)>>();
        return neighbours_alive.len();
    }

    fn should_live(&self, cell_coordinates: (i8,i8)) -> bool {
        let alive_neighbours_count = self.count_alive_neighbours(cell_coordinates);
        let result = match alive_neighbours_count {
            0...1 => false,
            2...3 => true,
            _ => panic!("wrong number of neighbours: {}", alive_neighbours_count)
        };
        return result;
    }
}

#[test]
// rule 1
fn alive_cell_with_no_alive_neighbours_should_die() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let new_world = world.mark_cell_alive(coords);
    let should_die = !new_world.should_live(coords);
    assert!(should_die);
}

#[test]
// rule 1
fn alive_cell_with_one_alive_neighbour_should_die() {
    let (x, y) = (0,0);
    let coords = (x,y);
    let world = WorldMap::empty();
    let new_world = world.
        mark_cell_alive(coords).
        mark_cell_alive((x, y+1));
    let should_die = !new_world.should_live(coords);
    assert!(should_die);
}

#[test]
// rule 2
fn alive_cell_with_two_alive_neighbours_should_stay_alive() {
    let (x, y) = (0,0);
    let coords = (x,y);
    let world = WorldMap::empty();
    let new_world = world.
        mark_cell_alive(coords).
        mark_cell_alive((x, y+1)).
        mark_cell_alive((x-1, y+1));
    let should_live = new_world.should_live(coords);
    assert!(should_live);
}

#[test]
// rule 2
fn alive_cell_with_three_alive_neighbours_should_stay_alive() {
    let (x, y) = (0,0);
    let coords = (x,y);
    let world = WorldMap::empty();
    let new_world = world.
        mark_cell_alive(coords).
        mark_cell_alive((x, y+1)).
        mark_cell_alive((x-1, y)).
        mark_cell_alive((x-1, y+1));
    let should_live = new_world.should_live(coords);
    assert!(should_live);
}
#[test]
fn the_only_alive_cell_should_have_no_alive_neighbours() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let new_world = world.mark_cell_alive(coords);
    let alive_neighbours_count = new_world.count_alive_neighbours(coords);
    assert_eq!(0, alive_neighbours_count);
}

#[test]
fn alive_neighbour_on_the_diagonal_should_count() {
    let (x, y) = (0,0);
    let coords = (x,y);
    let world = WorldMap::empty();
    let new_world = world.
        mark_cell_alive(coords).
        mark_cell_alive((x, y+1));
    let alive_neighbours_count = new_world.count_alive_neighbours(coords);
    assert_eq!(1, alive_neighbours_count);
}

#[test]
fn is_cell_alive_should_return_true_for_alive_cell() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let new_world = world.mark_cell_alive(coords);
    let is_alive = new_world.is_cell_alive(coords);
    assert_eq!(true, is_alive);
}

#[test]
fn is_cell_alive_should_return_false_for_dead_cell() {
    let coords = (0,0);
    let world = WorldMap::empty();
    let is_alive = world.is_cell_alive(coords);
    assert_eq!(false, is_alive);
}
<|endoftext|>


<commit_before>#![crate_id(name = "md5sum", vers = "1.0.0", author = "Arcterus")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate crypto = "rust-crypto";
extern crate getopts;
extern crate libc;

use std::io::fs::File;
use std::io::stdio::stdin_raw;
use std::io::BufferedReader;
use std::os;
use crypto::digest::Digest;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "md5sum";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {

    let program = args.get(0).clone();

    let opts = [
        getopts::optflag("b", "binary", "read in binary mode"),
        getopts::optflag("c", "check", "read MD5 sums from the FILEs and check them"),
        getopts::optflag("", "tag", "create a BSD-style checksum"),
        getopts::optflag("t", "text", "read in text mode (default)"),
        getopts::optflag("q", "quiet", "don't print OK for each successfully verified file"),
        getopts::optflag("s", "status", "don't output anything, status code shows success"),
        getopts::optflag("", "strict", "exit non-zero for improperly formatted checksum lines"),
        getopts::optflag("w", "warn", "warn about improperly formatted checksum lines"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f.to_err_msg())
    };

    if matches.opt_present("help") {
        println!("{} v{}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTION]... [FILE]...", program);
        println!("");
        print!("{}", getopts::usage("Compute and check MD5 message digests.", opts));
    } else if matches.opt_present("version") {
        println!("{} v{}", NAME, VERSION);
    } else {
        let binary = matches.opt_present("binary");
        let check = matches.opt_present("check");
        let tag = matches.opt_present("tag");
        let status = matches.opt_present("status");
        let quiet = matches.opt_present("quiet") || status;
        let strict = matches.opt_present("strict");
        let warn = matches.opt_present("warn") && !status;
        let files = if matches.free.is_empty() {
            vec!("-".to_string())
        } else {
            matches.free
        };
        match md5sum(files, binary, check, tag, status, quiet, strict, warn) {
            Ok(()) => return 0,
            Err(e) => return e
        }
    }

    return 0;
}

fn md5sum(files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) -> Result<(), int> {
    let mut md5 = crypto::md5::Md5::new();
    let bytes = md5.output_bits() / 4;
    let mut bad_format = 0;
    let mut failed = 0;
    for filename in files.iter() {
        let filename: &str = filename.as_slice();
        let mut file = BufferedReader::new(
            if filename == "-" {
                box stdin_raw() as Box<Reader>
            } else {
                box safe_unwrap!(File::open(&Path::new(filename))) as Box<Reader>
            }
        );
        if check {
            let mut buffer = file;
            //let mut buffer = BufferedReader::new(file);
            for (i, line) in buffer.lines().enumerate() {
                let line = safe_unwrap!(line);
                let (ck_filename, sum) = match from_gnu(line.as_slice(), bytes) {
                    Some(m) => m,
                    None => match from_bsd(line.as_slice(), bytes) {
                        Some(m) => m,
                        None => {
                            bad_format += 1;
                            if strict {
                                return Err(1);
                            }
                            if warn {
                                show_warning!("{}: {}: improperly formatted MD5 checksum line", filename, i + 1);
                            }
                            continue;
                        }
                    }
                };
                let real_sum = calc_sum(&mut md5, &mut safe_unwrap!(File::open(&Path::new(ck_filename))), binary);
                if sum == real_sum.as_slice() {
                    if !quiet {
                        println!("{}: OK", ck_filename);
                    }
                } else {
                    if !status {
                        println!("{}: FAILED", ck_filename);
                    }
                    failed += 1;
                    return Err(1);
                }
            }
        } else {
            let sum = calc_sum(&mut md5, &mut file, binary);
            if tag {
                println!("MD5 ({}) = {}", filename, sum);
            } else {
                println!("{}  {}", sum, filename);
            }
        }
    }
    if !status {
        if bad_format == 1 {
            show_warning!("{} line is improperly formatted", bad_format);
        } else if bad_format > 1 {
            show_warning!("{} lines are improperly formatted", bad_format);
        }
        if failed > 0 {
            show_warning!("{} computed checksum did NOT match", failed);
        }
    }

    return Ok(());
}

fn calc_sum(md5: &mut crypto::md5::Md5, file: &mut Reader, binary: bool) -> String {
    let data =
        if binary {
            (safe_unwrap!(file.read_to_end()))
        } else {
            (safe_unwrap!(file.read_to_str())).into_bytes()
        };
    md5.reset();
    md5.input(data.as_slice());
    md5.result_str()
}

fn from_gnu<'a>(line: &'a str, bytes: uint) -> Option<(&'a str, &'a str)> {
    let sum = line.slice_to(bytes);
    if sum.len() < bytes || line.slice(bytes, bytes + 2) != "  " {
        None
    } else {
        Some((line.slice(bytes + 2, line.len() - 1), sum))
    }
}

fn from_bsd<'a>(line: &'a str, bytes: uint) -> Option<(&'a str, &'a str)> {
    if line.slice(0, 5) == "MD5 (" {
        let rparen = match line.find(')') {
            Some(m) => m,
            None => return None
        };
        if rparen > 5 && line.slice(rparen + 1, rparen + 4) == " = " && line.len() - 1 == rparen + 4 + bytes {
            return Some((line.slice(5, rparen), line.slice(rparen + 4, line.len() - 1)));
        }
    }
    None
}
<commit_msg>Restore error handling to md5sum<commit_after>#![crate_id(name = "md5sum", vers = "1.0.0", author = "Arcterus")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate crypto = "rust-crypto";
extern crate getopts;
extern crate libc;

use std::io::fs::File;
use std::io::stdio::stdin_raw;
use std::io::BufferedReader;
use std::os;
use crypto::digest::Digest;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "md5sum";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {

    let program = args.get(0).clone();

    let opts = [
        getopts::optflag("b", "binary", "read in binary mode"),
        getopts::optflag("c", "check", "read MD5 sums from the FILEs and check them"),
        getopts::optflag("", "tag", "create a BSD-style checksum"),
        getopts::optflag("t", "text", "read in text mode (default)"),
        getopts::optflag("q", "quiet", "don't print OK for each successfully verified file"),
        getopts::optflag("s", "status", "don't output anything, status code shows success"),
        getopts::optflag("", "strict", "exit non-zero for improperly formatted checksum lines"),
        getopts::optflag("w", "warn", "warn about improperly formatted checksum lines"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f.to_err_msg())
    };

    if matches.opt_present("help") {
        println!("{} v{}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTION]... [FILE]...", program);
        println!("");
        print!("{}", getopts::usage("Compute and check MD5 message digests.", opts));
    } else if matches.opt_present("version") {
        println!("{} v{}", NAME, VERSION);
    } else {
        let binary = matches.opt_present("binary");
        let check = matches.opt_present("check");
        let tag = matches.opt_present("tag");
        let status = matches.opt_present("status");
        let quiet = matches.opt_present("quiet") || status;
        let strict = matches.opt_present("strict");
        let warn = matches.opt_present("warn") && !status;
        let files = if matches.free.is_empty() {
            vec!("-".to_string())
        } else {
            matches.free
        };
        match md5sum(files, binary, check, tag, status, quiet, strict, warn) {
            Ok(()) => return 0,
            Err(e) => return e
        }
    }

    return 0;
}

fn md5sum(files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) -> Result<(), int> {
    let mut md5 = crypto::md5::Md5::new();
    let bytes = md5.output_bits() / 4;
    let mut bad_format = 0;
    let mut failed = 0;
    for filename in files.iter() {
        let filename: &str = filename.as_slice();
        let mut file = BufferedReader::new(
            if filename == "-" {
                box stdin_raw() as Box<Reader>
            } else {
                box safe_unwrap!(File::open(&Path::new(filename))) as Box<Reader>
            }
        );
        if check {
            let mut buffer = file;
            //let mut buffer = BufferedReader::new(file);
            for (i, line) in buffer.lines().enumerate() {
                let line = safe_unwrap!(line);
                let (ck_filename, sum) = match from_gnu(line.as_slice(), bytes) {
                    Some(m) => m,
                    None => match from_bsd(line.as_slice(), bytes) {
                        Some(m) => m,
                        None => {
                            bad_format += 1;
                            if strict {
                                return Err(1);
                            }
                            if warn {
                                show_warning!("{}: {}: improperly formatted MD5 checksum line", filename, i + 1);
                            }
                            continue;
                        }
                    }
                };
                let real_sum = calc_sum(&mut md5, &mut safe_unwrap!(File::open(&Path::new(ck_filename))), binary);
                if sum == real_sum.as_slice() {
                    if !quiet {
                        println!("{}: OK", ck_filename);
                    }
                } else {
                    if !status {
                        println!("{}: FAILED", ck_filename);
                    }
                    failed += 1;
                }
            }
        } else {
            let sum = calc_sum(&mut md5, &mut file, binary);
            if tag {
                println!("MD5 ({}) = {}", filename, sum);
            } else {
                println!("{}  {}", sum, filename);
            }
        }
    }
    if !status {
        if bad_format == 1 {
            show_warning!("{} line is improperly formatted", bad_format);
        } else if bad_format > 1 {
            show_warning!("{} lines are improperly formatted", bad_format);
        }
        if failed > 0 {
            show_warning!("{} computed checksum did NOT match", failed);
        }
    }

    return Ok(());
}

fn calc_sum(md5: &mut crypto::md5::Md5, file: &mut Reader, binary: bool) -> String {
    let data =
        if binary {
            (safe_unwrap!(file.read_to_end()))
        } else {
            (safe_unwrap!(file.read_to_str())).into_bytes()
        };
    md5.reset();
    md5.input(data.as_slice());
    md5.result_str()
}

fn from_gnu<'a>(line: &'a str, bytes: uint) -> Option<(&'a str, &'a str)> {
    let sum = line.slice_to(bytes);
    if sum.len() < bytes || line.slice(bytes, bytes + 2) != "  " {
        None
    } else {
        Some((line.slice(bytes + 2, line.len() - 1), sum))
    }
}

fn from_bsd<'a>(line: &'a str, bytes: uint) -> Option<(&'a str, &'a str)> {
    if line.slice(0, 5) == "MD5 (" {
        let rparen = match line.find(')') {
            Some(m) => m,
            None => return None
        };
        if rparen > 5 && line.slice(rparen + 1, rparen + 4) == " = " && line.len() - 1 == rparen + 4 + bytes {
            return Some((line.slice(5, rparen), line.slice(rparen + 4, line.len() - 1)));
        }
    }
    None
}
<|endoftext|>


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

#[macro_use]
extern crate average;
extern crate rand;
extern crate rand_distr;

use average::Histogram;
use rand::distributions::Distribution;
use rand::FromEntropy;
use std as core;

const N_BINS: usize = 100;
const N_SAMPLES: u32 = 1_000_000;
const TOL: f64 = 1e-3;
define_histogram!(hist, 100);
use hist::Histogram as Histogram100;

#[test]
fn unit_sphere() {
    const N_DIM: usize = 3;
    let h = Histogram100::with_const_width(-1., 1.);
    let mut histograms = [h.clone(), h.clone(), h];
    let dist = rand_distr::UnitSphere;
    let mut rng = rand::rngs::SmallRng::from_entropy();
    for _ in 0..N_SAMPLES {
        let v: [f64; 3] = dist.sample(&mut rng);
        for i in 0..N_DIM {
            histograms[i].add(v[i]).map_err(
                |e| { println!("v: {}", v[i]); e }
            ).unwrap();
        }
    }
    for h in &histograms {
        let sum: u64 = h.bins().iter().sum();
        println!("{:?}", h);
        for &b in h.bins() {
            let p = (b as f64) / (sum as f64);
            assert!((p - 1.0 / (N_BINS as f64)).abs() < TOL, "{}", p);
        }
    }
}

#[test]
fn unit_circle() {
    use std::f64::consts::PI;
    let mut h = Histogram100::with_const_width(-PI, PI);
    let dist = rand_distr::UnitCircle;
    let mut rng = rand::rngs::SmallRng::from_entropy();
    for _ in 0..N_SAMPLES {
        let v: [f64; 2] = dist.sample(&mut rng);
        h.add(v[0].atan2(v[1])).unwrap();
    }
    let sum: u64 = h.bins().iter().sum();
    println!("{:?}", h);
    for &b in h.bins() {
        let p = (b as f64) / (sum as f64);
        assert!((p - 1.0 / (N_BINS as f64)).abs() < TOL, "{}", p);
    }
}
<commit_msg>Try to fix CI<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate average;
extern crate rand;
extern crate rand_distr;
extern crate core;

use average::Histogram;
use rand::distributions::Distribution;
use rand::FromEntropy;

const N_BINS: usize = 100;
const N_SAMPLES: u32 = 1_000_000;
const TOL: f64 = 1e-3;
define_histogram!(hist, 100);
use hist::Histogram as Histogram100;

#[test]
fn unit_sphere() {
    const N_DIM: usize = 3;
    let h = Histogram100::with_const_width(-1., 1.);
    let mut histograms = [h.clone(), h.clone(), h];
    let dist = rand_distr::UnitSphere;
    let mut rng = rand::rngs::SmallRng::from_entropy();
    for _ in 0..N_SAMPLES {
        let v: [f64; 3] = dist.sample(&mut rng);
        for i in 0..N_DIM {
            histograms[i].add(v[i]).map_err(
                |e| { println!("v: {}", v[i]); e }
            ).unwrap();
        }
    }
    for h in &histograms {
        let sum: u64 = h.bins().iter().sum();
        println!("{:?}", h);
        for &b in h.bins() {
            let p = (b as f64) / (sum as f64);
            assert!((p - 1.0 / (N_BINS as f64)).abs() < TOL, "{}", p);
        }
    }
}

#[test]
fn unit_circle() {
    use std::f64::consts::PI;
    let mut h = Histogram100::with_const_width(-PI, PI);
    let dist = rand_distr::UnitCircle;
    let mut rng = rand::rngs::SmallRng::from_entropy();
    for _ in 0..N_SAMPLES {
        let v: [f64; 2] = dist.sample(&mut rng);
        h.add(v[0].atan2(v[1])).unwrap();
    }
    let sum: u64 = h.bins().iter().sum();
    println!("{:?}", h);
    for &b in h.bins() {
        let p = (b as f64) / (sum as f64);
        assert!((p - 1.0 / (N_BINS as f64)).abs() < TOL, "{}", p);
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::ffi;
use std::mem;
use std::os::raw;
use std::ptr;
use std::slice;

use image::Pixel;
use image::RgbaImage;
use image::Rgba;
use libc;
use x11::xlib;
use x11::xrandr;

use util;

pub const ALL_PLANES: libc::c_ulong = !0;

pub struct Display {
    handle: *mut xlib::Display,
}

pub struct Image {
    handle: *mut xlib::XImage,
}

pub struct ScreenRectIter<'a> {
    dpy: &'a Display,
    res: *mut xrandr::XRRScreenResources,
    crtcs: &'a [xrandr::RRCrtc],
    i: usize,
}

impl Display {
    pub fn open(name: Option<ffi::CString>) -> Option<Display> {
        unsafe {
            let name = match name {
                None => ptr::null(),
                Some(cstr) => cstr.as_ptr(),
            };
            let d = xlib::XOpenDisplay(name);

            if d.is_null() {
                return None;
            }

            Some(Display {
                handle: d,
            })
        }
    }

    pub fn get_default_root(&self) -> xlib::Window {
        unsafe {
            xlib::XDefaultRootWindow(self.handle)
        }
    }

    pub fn get_window_rect(&self, window: xlib::Window) -> util::Rect {
        unsafe {
            let mut attrs = mem::uninitialized();
            xlib::XGetWindowAttributes(self.handle, window, &mut attrs);

            let mut root = 0;
            let mut parent = 0;
            let mut children: *mut xlib::Window = ptr::null_mut();
            let mut nchildren = 0;
            xlib::XQueryTree(self.handle, window, &mut root, &mut parent,
                             &mut children, &mut nchildren);
            if !children.is_null() {
                xlib::XFree(children as *mut raw::c_void);
            }

            let mut x = attrs.x;
            let mut y = attrs.y;

            if parent != 0 {
                let mut child = 0;
                xlib::XTranslateCoordinates(self.handle, parent, root, attrs.x, attrs.y,
                                            &mut x, &mut y, &mut child);
            }

            util::Rect {
                x: x,
                y: y,
                w: attrs.width,
                h: attrs.height,
            }
        }
    }

    pub fn get_image(&self, window: xlib::Window, rect: util::Rect, plane_mask: libc::c_ulong,
                     format: libc::c_int) -> Option<Image> {
        unsafe {
            let image = xlib::XGetImage(self.handle, window,
                                        rect.x, rect.y,
                                        rect.w as libc::c_uint, rect.h as libc::c_uint,
                                        plane_mask, format);

            if image.is_null() {
                return None;
            }

            Some(Image::from_raw_ximage(image))
        }
    }

    pub fn get_screen_rects(&self, root: xlib::Window) -> Option<ScreenRectIter> {
        unsafe {
            let xrr_res = xrandr::XRRGetScreenResourcesCurrent(self.handle, root);

            if xrr_res.is_null() {
                return None
            }

            Some(ScreenRectIter {
                dpy: &self,
                res: xrr_res,
                crtcs: slice::from_raw_parts((*xrr_res).crtcs, (*xrr_res).ncrtc as usize),
                i: 0,
            })
        }
    }
}

impl Drop for Display {
    fn drop(&mut self) {
        unsafe {
            xlib::XCloseDisplay(self.handle);
        }
    }
}

impl Image {
    pub fn from_raw_ximage(ximage: *mut xlib::XImage) -> Image {
        Image {
            handle: ximage,
        }
    }

    pub fn into_image_buffer(&self) -> Option<RgbaImage> {
        unsafe {
            // Extract values from the XImage into our own scope
            macro_rules! get {
                ($($a:ident),+) => ($(let $a = (*self.handle).$a;)+);
            }
            get!(width, height,
                 byte_order, depth, bytes_per_line, bits_per_pixel,
                 red_mask, green_mask, blue_mask);

            // Pixel size
            let stride = match (depth, bits_per_pixel) {
                (24, 24) => 3,
                (24, 32) | (32, 32) => 4,
                _ => return None,
            };

            // Compute subpixel offsets into each pixel according the the bitmasks X gives us
            // Only 8 bit, byte-aligned values are supported
            // Truncate masks to the lower 32 bits as that is the maximum pixel size
            macro_rules! channel_offset {
                ($mask:expr) => (match (byte_order, $mask & 0xFFFFFFFF) {
                    (0, 0xFF) | (1, 0xFF000000) => 0,
                    (0, 0xFF00) | (1, 0xFF0000) => 1,
                    (0, 0xFF0000) | (1, 0xFF00) => 2,
                    (0, 0xFF000000) | (1, 0xFF) => 3,
                    _ => return None,
                })
            }
            let red_offset = channel_offset!(red_mask);
            let green_offset = channel_offset!(green_mask);
            let blue_offset = channel_offset!(blue_mask);
            let alpha_offset = channel_offset!(!(red_mask | green_mask | blue_mask));

            // Wrap the pixel buffer into a slice
            let size = (bytes_per_line * height) as usize;
            let data = slice::from_raw_parts((*self.handle).data as *const u8, size);

            // Finally, generate the image object
            Some(RgbaImage::from_fn(width as u32, height as u32, |x, y| {
                macro_rules! subpixel {
                    ($channel_offset:ident) => (data[(y * bytes_per_line as u32
                                                + x * stride as u32
                                                + $channel_offset) as usize]);
                }
                Rgba::from_channels(subpixel!(red_offset),
                                    subpixel!(green_offset),
                                    subpixel!(blue_offset),
                                    // Make the alpha channel fully opaque if none is provided
                                    if depth == 24 { 0xFF } else { subpixel!(alpha_offset) })
            }))
        }
    }
}

impl Drop for Image {
    fn drop(&mut self) {
        unsafe {
            xlib::XDestroyImage(self.handle);
        }
    }
}

impl<'a> Iterator for ScreenRectIter<'a> {
    type Item = util::Rect;

    fn next(&mut self) -> Option<Self::Item> {
        if self.i >= self.crtcs.len() {
            return None
        }

        unsafe {
            // TODO Handle failure here?
            let crtc = xrandr::XRRGetCrtcInfo((*self.dpy).handle, self.res, self.crtcs[self.i]);
            let x = (*crtc).x;
            let y = (*crtc).y;
            let w = (*crtc).width;
            let h = (*crtc).height;
            xrandr::XRRFreeCrtcInfo(crtc);

            self.i += 1;

            //Some((w as i32, h as i32, x as i32, y as i32))
            Some(util::Rect {
                x: x,
                y: y,
                w: w as i32,
                h: h as i32,
            })
        }
    }
}

impl<'a> Drop for ScreenRectIter<'a> {
    fn drop(&mut self) {
        unsafe {
            xrandr::XRRFreeScreenResources(self.res);
        }
    }
}

pub fn parse_geometry(g: ffi::CString) -> util::Rect {
    unsafe {
        let mut x = 0;
        let mut y = 0;
        let mut w = 0;
        let mut h = 0;
        xlib::XParseGeometry(g.as_ptr() as *const i8, &mut x, &mut y, &mut w, &mut h);

        util::Rect {
            x: x,
            y: y,
            w: w as i32,
            h: h as i32,
        }
    }
}
<commit_msg>cast to *const c_char instead of *const i8 (#11)<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::ffi;
use std::mem;
use std::os::raw;
use std::ptr;
use std::slice;

use image::Pixel;
use image::RgbaImage;
use image::Rgba;
use libc;
use x11::xlib;
use x11::xrandr;

use util;

pub const ALL_PLANES: libc::c_ulong = !0;

pub struct Display {
    handle: *mut xlib::Display,
}

pub struct Image {
    handle: *mut xlib::XImage,
}

pub struct ScreenRectIter<'a> {
    dpy: &'a Display,
    res: *mut xrandr::XRRScreenResources,
    crtcs: &'a [xrandr::RRCrtc],
    i: usize,
}

impl Display {
    pub fn open(name: Option<ffi::CString>) -> Option<Display> {
        unsafe {
            let name = match name {
                None => ptr::null(),
                Some(cstr) => cstr.as_ptr(),
            };
            let d = xlib::XOpenDisplay(name);

            if d.is_null() {
                return None;
            }

            Some(Display {
                handle: d,
            })
        }
    }

    pub fn get_default_root(&self) -> xlib::Window {
        unsafe {
            xlib::XDefaultRootWindow(self.handle)
        }
    }

    pub fn get_window_rect(&self, window: xlib::Window) -> util::Rect {
        unsafe {
            let mut attrs = mem::uninitialized();
            xlib::XGetWindowAttributes(self.handle, window, &mut attrs);

            let mut root = 0;
            let mut parent = 0;
            let mut children: *mut xlib::Window = ptr::null_mut();
            let mut nchildren = 0;
            xlib::XQueryTree(self.handle, window, &mut root, &mut parent,
                             &mut children, &mut nchildren);
            if !children.is_null() {
                xlib::XFree(children as *mut raw::c_void);
            }

            let mut x = attrs.x;
            let mut y = attrs.y;

            if parent != 0 {
                let mut child = 0;
                xlib::XTranslateCoordinates(self.handle, parent, root, attrs.x, attrs.y,
                                            &mut x, &mut y, &mut child);
            }

            util::Rect {
                x: x,
                y: y,
                w: attrs.width,
                h: attrs.height,
            }
        }
    }

    pub fn get_image(&self, window: xlib::Window, rect: util::Rect, plane_mask: libc::c_ulong,
                     format: libc::c_int) -> Option<Image> {
        unsafe {
            let image = xlib::XGetImage(self.handle, window,
                                        rect.x, rect.y,
                                        rect.w as libc::c_uint, rect.h as libc::c_uint,
                                        plane_mask, format);

            if image.is_null() {
                return None;
            }

            Some(Image::from_raw_ximage(image))
        }
    }

    pub fn get_screen_rects(&self, root: xlib::Window) -> Option<ScreenRectIter> {
        unsafe {
            let xrr_res = xrandr::XRRGetScreenResourcesCurrent(self.handle, root);

            if xrr_res.is_null() {
                return None
            }

            Some(ScreenRectIter {
                dpy: &self,
                res: xrr_res,
                crtcs: slice::from_raw_parts((*xrr_res).crtcs, (*xrr_res).ncrtc as usize),
                i: 0,
            })
        }
    }
}

impl Drop for Display {
    fn drop(&mut self) {
        unsafe {
            xlib::XCloseDisplay(self.handle);
        }
    }
}

impl Image {
    pub fn from_raw_ximage(ximage: *mut xlib::XImage) -> Image {
        Image {
            handle: ximage,
        }
    }

    pub fn into_image_buffer(&self) -> Option<RgbaImage> {
        unsafe {
            // Extract values from the XImage into our own scope
            macro_rules! get {
                ($($a:ident),+) => ($(let $a = (*self.handle).$a;)+);
            }
            get!(width, height,
                 byte_order, depth, bytes_per_line, bits_per_pixel,
                 red_mask, green_mask, blue_mask);

            // Pixel size
            let stride = match (depth, bits_per_pixel) {
                (24, 24) => 3,
                (24, 32) | (32, 32) => 4,
                _ => return None,
            };

            // Compute subpixel offsets into each pixel according the the bitmasks X gives us
            // Only 8 bit, byte-aligned values are supported
            // Truncate masks to the lower 32 bits as that is the maximum pixel size
            macro_rules! channel_offset {
                ($mask:expr) => (match (byte_order, $mask & 0xFFFFFFFF) {
                    (0, 0xFF) | (1, 0xFF000000) => 0,
                    (0, 0xFF00) | (1, 0xFF0000) => 1,
                    (0, 0xFF0000) | (1, 0xFF00) => 2,
                    (0, 0xFF000000) | (1, 0xFF) => 3,
                    _ => return None,
                })
            }
            let red_offset = channel_offset!(red_mask);
            let green_offset = channel_offset!(green_mask);
            let blue_offset = channel_offset!(blue_mask);
            let alpha_offset = channel_offset!(!(red_mask | green_mask | blue_mask));

            // Wrap the pixel buffer into a slice
            let size = (bytes_per_line * height) as usize;
            let data = slice::from_raw_parts((*self.handle).data as *const u8, size);

            // Finally, generate the image object
            Some(RgbaImage::from_fn(width as u32, height as u32, |x, y| {
                macro_rules! subpixel {
                    ($channel_offset:ident) => (data[(y * bytes_per_line as u32
                                                + x * stride as u32
                                                + $channel_offset) as usize]);
                }
                Rgba::from_channels(subpixel!(red_offset),
                                    subpixel!(green_offset),
                                    subpixel!(blue_offset),
                                    // Make the alpha channel fully opaque if none is provided
                                    if depth == 24 { 0xFF } else { subpixel!(alpha_offset) })
            }))
        }
    }
}

impl Drop for Image {
    fn drop(&mut self) {
        unsafe {
            xlib::XDestroyImage(self.handle);
        }
    }
}

impl<'a> Iterator for ScreenRectIter<'a> {
    type Item = util::Rect;

    fn next(&mut self) -> Option<Self::Item> {
        if self.i >= self.crtcs.len() {
            return None
        }

        unsafe {
            // TODO Handle failure here?
            let crtc = xrandr::XRRGetCrtcInfo((*self.dpy).handle, self.res, self.crtcs[self.i]);
            let x = (*crtc).x;
            let y = (*crtc).y;
            let w = (*crtc).width;
            let h = (*crtc).height;
            xrandr::XRRFreeCrtcInfo(crtc);

            self.i += 1;

            //Some((w as i32, h as i32, x as i32, y as i32))
            Some(util::Rect {
                x: x,
                y: y,
                w: w as i32,
                h: h as i32,
            })
        }
    }
}

impl<'a> Drop for ScreenRectIter<'a> {
    fn drop(&mut self) {
        unsafe {
            xrandr::XRRFreeScreenResources(self.res);
        }
    }
}

pub fn parse_geometry(g: ffi::CString) -> util::Rect {
    unsafe {
        let mut x = 0;
        let mut y = 0;
        let mut w = 0;
        let mut h = 0;
        xlib::XParseGeometry(g.as_ptr() as *const raw::c_char, &mut x, &mut y, &mut w, &mut h);

        util::Rect {
            x: x,
            y: y,
            w: w as i32,
            h: h as i32,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>rustup: #[derive(Clone)]<commit_after><|endoftext|>


<commit_before><commit_msg>Factored out sending quit and block messages into own functions<commit_after><|endoftext|>


<commit_before><commit_msg>Add .debug_rnglists to the list of sections that can appear in a DWO.<commit_after><|endoftext|>