<commit_before>//! `Future`-powered I/O at the core of Tokio
//!
//! This crate uses the [`futures`] crate to provide an event loop ("reactor
//! core") which can be used to drive I/O like TCP and UDP. All asynchronous I/O
//! is powered by the [`mio`] crate.
//!
//! [`futures`]: ../futures/index.html
//! [`mio`]: ../mio/index.html
//!
//! The concrete types provided in this crate are relatively bare bones but are
//! intended to be the essential foundation for further projects needing an
//! event loop. In this crate you'll find:
//!
//! * TCP, both streams and listeners.
//! * UDP sockets.
//! * An event loop to run futures.
//!
//! More functionality is likely to be added over time, but otherwise the crate
//! is intended to be flexible, with the [`PollEvented`] type accepting any
//! type that implements [`mio::Evented`]. For example, the [`tokio-uds`] crate
//! uses [`PollEvented`] to provide support for Unix domain sockets.
//!
//! [`PollEvented`]: ./reactor/struct.PollEvented.html
//! [`mio::Evented`]: ../mio/event/trait.Evented.html
//! [`tokio-uds`]: https://crates.io/crates/tokio-uds
//!
//! Some other important tasks covered by this crate are:
//!
//! * All I/O is futures-aware. If any action in this crate returns "not ready"
//!   or "would block", then the current future task is scheduled to receive a
//!   notification when it would otherwise make progress.
//!
//! You can find more extensive documentation in terms of tutorials at
//! [https://tokio.rs](https://tokio.rs).
//!
//! # Examples
//!
//! A simple TCP echo server:
//!
//! ```no_run
//! extern crate futures;
//! extern crate futures_cpupool;
//! extern crate tokio;
//! extern crate tokio_io;
//!
//! use futures::prelude::*;
//! use futures::future::Executor;
//! use futures_cpupool::CpuPool;
//! use tokio_io::AsyncRead;
//! use tokio_io::io::copy;
//! use tokio::net::TcpListener;
//!
//! fn main() {
//!     let pool = CpuPool::new_num_cpus();
//!
//!     // Bind the server's socket.
//!     let addr = "127.0.0.1:12345".parse().unwrap();
//!     let listener = TcpListener::bind(&addr)
//!         .expect("unable to bind TCP listener");
//!
//!     // Pull out a stream of sockets for incoming connections
//!     let server = listener.incoming().for_each(|(sock, _)| {
//!         // Split up the reading and writing parts of the
//!         // socket.
//!         let (reader, writer) = sock.split();
//!
//!         // A future that echos the data and returns how
//!         // many bytes were copied...
//!         let bytes_copied = copy(reader, writer);
//!
//!         // ... after which we'll print what happened.
//!         let handle_conn = bytes_copied.map(|amt| {
//!             println!("wrote {:?} bytes", amt)
//!         }).map_err(|err| {
//!             eprintln!("IO error {:?}", err)
//!         });
//!
//!         // Spawn the future as a concurrent task.
//!         pool.execute(handle_conn).unwrap();
//!
//!         Ok(())
//!     });
//!
//!     // Spin up the server on this thread
//!     server.wait().unwrap();
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/tokio-core/0.1")]
#![deny(missing_docs)]
//#![deny(warnings)]
#![warn(missing_debug_implementations)]

extern crate bytes;
#[macro_use]
extern crate futures;
extern crate iovec;
extern crate mio;
extern crate slab;
#[macro_use]
extern crate tokio_io;

#[macro_use]
extern crate log;

pub mod net;
pub mod reactor;
<commit_msg>Uncomment `deny(warnings)`<commit_after>//! `Future`-powered I/O at the core of Tokio
//!
//! This crate uses the [`futures`] crate to provide an event loop ("reactor
//! core") which can be used to drive I/O like TCP and UDP. All asynchronous I/O
//! is powered by the [`mio`] crate.
//!
//! [`futures`]: ../futures/index.html
//! [`mio`]: ../mio/index.html
//!
//! The concrete types provided in this crate are relatively bare bones but are
//! intended to be the essential foundation for further projects needing an
//! event loop. In this crate you'll find:
//!
//! * TCP, both streams and listeners.
//! * UDP sockets.
//! * An event loop to run futures.
//!
//! More functionality is likely to be added over time, but otherwise the crate
//! is intended to be flexible, with the [`PollEvented`] type accepting any
//! type that implements [`mio::Evented`]. For example, the [`tokio-uds`] crate
//! uses [`PollEvented`] to provide support for Unix domain sockets.
//!
//! [`PollEvented`]: ./reactor/struct.PollEvented.html
//! [`mio::Evented`]: ../mio/event/trait.Evented.html
//! [`tokio-uds`]: https://crates.io/crates/tokio-uds
//!
//! Some other important tasks covered by this crate are:
//!
//! * All I/O is futures-aware. If any action in this crate returns "not ready"
//!   or "would block", then the current future task is scheduled to receive a
//!   notification when it would otherwise make progress.
//!
//! You can find more extensive documentation in terms of tutorials at
//! [https://tokio.rs](https://tokio.rs).
//!
//! # Examples
//!
//! A simple TCP echo server:
//!
//! ```no_run
//! extern crate futures;
//! extern crate futures_cpupool;
//! extern crate tokio;
//! extern crate tokio_io;
//!
//! use futures::prelude::*;
//! use futures::future::Executor;
//! use futures_cpupool::CpuPool;
//! use tokio_io::AsyncRead;
//! use tokio_io::io::copy;
//! use tokio::net::TcpListener;
//!
//! fn main() {
//!     let pool = CpuPool::new_num_cpus();
//!
//!     // Bind the server's socket.
//!     let addr = "127.0.0.1:12345".parse().unwrap();
//!     let listener = TcpListener::bind(&addr)
//!         .expect("unable to bind TCP listener");
//!
//!     // Pull out a stream of sockets for incoming connections
//!     let server = listener.incoming().for_each(|(sock, _)| {
//!         // Split up the reading and writing parts of the
//!         // socket.
//!         let (reader, writer) = sock.split();
//!
//!         // A future that echos the data and returns how
//!         // many bytes were copied...
//!         let bytes_copied = copy(reader, writer);
//!
//!         // ... after which we'll print what happened.
//!         let handle_conn = bytes_copied.map(|amt| {
//!             println!("wrote {:?} bytes", amt)
//!         }).map_err(|err| {
//!             eprintln!("IO error {:?}", err)
//!         });
//!
//!         // Spawn the future as a concurrent task.
//!         pool.execute(handle_conn).unwrap();
//!
//!         Ok(())
//!     });
//!
//!     // Spin up the server on this thread
//!     server.wait().unwrap();
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/tokio-core/0.1")]
#![deny(missing_docs)]
#![deny(warnings)]
#![warn(missing_debug_implementations)]

extern crate bytes;
#[macro_use]
extern crate futures;
extern crate iovec;
extern crate mio;
extern crate slab;
#[macro_use]
extern crate tokio_io;

#[macro_use]
extern crate log;

pub mod net;
pub mod reactor;
<|endoftext|>


<commit_before>//! Guessing of MIME types by file extension.
//!
//! Uses a static list of file-extension : MIME type mappings.
#![cfg_attr(feature = "bench", feature(test))]

extern crate mime;
extern crate phf;
extern crate unicase;

pub use mime::Mime;
use unicase::UniCase;

use std::ffi::OsStr;
use std::path::Path;

include!("mime_types_generated.rs");

struct TopLevelExts {
    start: usize,
    end: usize,
    subs: phf::Map<UniCase<&'static str>, (usize, usize)>,
}

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

#[cfg(test)]
#[path = "mime_types.rs"]
mod mime_types_src;

/// Guess the MIME type of `path` by its extension (as defined by `Path::extension()`).
///
/// If `path` has no extension, or its extension has no known MIME type mapping,
/// then the MIME type is assumed to be `application/octet-stream`.
///
/// ##Note
/// **Guess** is the operative word here, as there are no guarantees that the contents of the file
/// that `path` points to match the MIME type associated with the path's extension.
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn guess_mime_type<P: AsRef<Path>>(path: P) -> Mime {
    guess_mime_type_opt(path)
        .unwrap_or_else(octet_stream)
}

/// Guess the MIME type of `path` by its extension (as defined by `Path::extension()`).
///
/// If `path` has no extension, or its extension has no known MIME type mapping,
/// then `None` is returned.
///
/// ##Note
/// **Guess** is the operative word here, as there are no guarantees that the contents of the file
/// that `path` points to match the MIME type associated with the path's extension.
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn guess_mime_type_opt<P: AsRef<Path>>(path: P) -> Option<Mime> {
    let ext = path.as_ref().extension().and_then(OsStr::to_str).unwrap_or("");

    get_mime_type_opt(ext)
}

/// Get the MIME type associated with a file extension.
///
/// If there is no association for the extension, or `ext` is empty,
/// `application/octet-stream` is returned.
pub fn get_mime_type(search_ext: &str) -> Mime {
    get_mime_type_opt(search_ext)
        .unwrap_or_else(octet_stream)
}

/// Get the MIME type associated with a file extension.
///
/// If there is no association for the extension, or `ext` is empty,
/// `None` is returned.
pub fn get_mime_type_opt(search_ext: &str) -> Option<Mime> {
    get_mime_type_str(search_ext)
        .map(|mime| mime.parse::<Mime>().unwrap())
}

/// Get the MIME type string associated with a file extension. Case-insensitive.
///
/// If `search_ext` is not already lowercase,
/// it will be converted to lowercase to facilitate the search.
///
/// Returns `None` if `search_ext` is empty or an associated extension was not found.
pub fn get_mime_type_str(search_ext: &str) -> Option<&'static str> {
    if search_ext.is_empty() { return None; }

    map_lookup(&MIME_TYPES, search_ext).cloned()
}

/// Get a list of known extensions for a given `Mime`.
///
/// Ignores parameters (only searches with `<main type>/<subtype>`). Case-insensitive (for extension types).
///
/// Returns `None` if the MIME type is unknown.
///
/// ###Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
pub fn get_mime_extensions(mime: &Mime) -> Option<&'static [&'static str]> {
    get_extensions(&mime.0, &mime.1)
}

/// Get a list of known extensions for a MIME type string.
///
/// Ignores parameters (only searches `<main type>/<subtype>`). Case-insensitive.
///
/// Returns `None` if the MIME type is unknown.
///
/// ###Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
///
/// ###Panics
/// If `mime_str` is not a valid MIME type specifier (naive).
pub fn get_mime_extensions_str(mut mime_str: &str) -> Option<&'static [&'static str]> {
    mime_str = mime_str.trim();

    if let Some(sep_idx) = mime_str.find(';') {
        mime_str = &mime_str[..sep_idx];
    }

    let (top, sub) = {
        let split_idx = mime_str.find('/').unwrap();
        (&mime_str[..split_idx], &mime_str[split_idx + 1 ..])
    };

    get_extensions(top, sub)
}

/// Get the extensions for a given top-level and sub-level of a MIME type
/// (`{toplevel}/{sublevel}`).
///
/// Returns `None` if `toplevel` or `sublevel` are unknown.
///
/// ###Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> {
    if toplevel == "*" {
        return Some(EXTS);
    }

    let top = try_opt!(map_lookup(&REV_MAPPINGS, toplevel));

    if sublevel == "*" {
        return Some(&EXTS[top.start .. top.end]);
    }

    let sub = try_opt!(map_lookup(&top.subs, sublevel));
    Some(&EXTS[sub.0 .. sub.1])
}

/// Get the MIME type for `application/octet-stream` (generic binary stream)
pub fn octet_stream() -> Mime {
    "application/octet-stream".parse().unwrap()
}

fn map_lookup<'map, V>(map: &'map phf::Map<UniCase<&'static str>, V>, key: &str) -> Option<&'map V> {
    // This transmute should be safe as `get` will not store the reference with
    // the expanded lifetime. This is due to `Borrow` being overly strict and
    // can't have an impl for `&'static str` to `Borrow<&'a str>`.
    //
    // See https://github.com/rust-lang/rust/issues/28853#issuecomment-158735548
    let key = unsafe { ::std::mem::transmute::<_, &'static str>(key) };
    map.get(&UniCase(key))
}

#[cfg(test)]
mod tests {
    use mime::Mime;
    use std::ascii::AsciiExt;
    use std::path::Path;
    use super::{get_mime_type, guess_mime_type, MIME_TYPES};
    use super::{get_mime_type_opt, guess_mime_type_opt};

    #[test]
    fn test_mime_type_guessing() {
        assert_eq!(get_mime_type("gif").to_string(), "image/gif".to_string());
        assert_eq!(get_mime_type("TXT").to_string(), "text/plain".to_string());
        assert_eq!(get_mime_type("blahblah").to_string(), "application/octet-stream".to_string());

        assert_eq!(guess_mime_type(Path::new("/path/to/file.gif")).to_string(), "image/gif".to_string());
        assert_eq!(guess_mime_type("/path/to/file.gif").to_string(), "image/gif".to_string());
    }

    #[test]
    fn test_mime_type_guessing_opt() {
        assert_eq!(get_mime_type_opt("gif").unwrap().to_string(), "image/gif".to_string());
        assert_eq!(get_mime_type_opt("TXT").unwrap().to_string(), "text/plain".to_string());
        assert_eq!(get_mime_type_opt("blahblah"), None);

        assert_eq!(guess_mime_type_opt("/path/to/file.gif").unwrap().to_string(), "image/gif".to_string());
        assert_eq!(guess_mime_type_opt("/path/to/file"), None);
    }

    #[test]
    fn test_are_mime_types_parseable() {
        for (_, mime) in &MIME_TYPES {
            mime.parse::<Mime>().unwrap();
        }
    }

    // RFC: Is this test necessary anymore? --@cybergeek94, 2/1/2016
    #[test]
    fn test_are_extensions_ascii() {
        for (ext, _) in &MIME_TYPES {
            assert!(ext.is_ascii(), "Extension not ASCII: {:?}", ext);
        }
    }

    #[test]
    fn test_are_extensions_sorted() {
        use mime_types_src::MIME_TYPES;

        for (&(ext, _), &(n_ext, _)) in MIME_TYPES.iter().zip(MIME_TYPES.iter().skip(1)) {
            assert!(
                ext <= n_ext,
                "Extensions in src/mime_types should be sorted alphabetically
                in ascending order. Failed assert: {:?} <= {:?}",
                ext, n_ext
            );
        }
    }

}

#[cfg(feature = "bench")]
mod bench {
    extern crate test;

    use self::test::Bencher;

    use super::{get_mime_type_str, MIME_TYPES};

    /// WARNING: this may take a while!
    #[bench]
    fn bench_mime_str(b: &mut Bencher) {
        for (mime_ext, _) in &MIME_TYPES {
            b.iter(|| {
                get_mime_type_str(mime_ext).expect(mime_ext);
            });
        }
    }

    #[bench]
    fn bench_mime_str_uppercase(b: &mut Bencher) {
        let uppercased : Vec<_> = MIME_TYPES.into_iter().map(|(s, _)| s.to_uppercase()).collect();

        for mime_ext in &uppercased {
            b.iter(|| {
                get_mime_type_str(mime_ext).expect(mime_ext);
            });
        }
    }
}
<commit_msg>lib.rs: fix headers in docs<commit_after>//! Guessing of MIME types by file extension.
//!
//! Uses a static list of file-extension : MIME type mappings.
#![cfg_attr(feature = "bench", feature(test))]

extern crate mime;
extern crate phf;
extern crate unicase;

pub use mime::Mime;
use unicase::UniCase;

use std::ffi::OsStr;
use std::path::Path;

include!("mime_types_generated.rs");

struct TopLevelExts {
    start: usize,
    end: usize,
    subs: phf::Map<UniCase<&'static str>, (usize, usize)>,
}

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

#[cfg(test)]
#[path = "mime_types.rs"]
mod mime_types_src;

/// Guess the MIME type of `path` by its extension (as defined by `Path::extension()`).
///
/// If `path` has no extension, or its extension has no known MIME type mapping,
/// then the MIME type is assumed to be `application/octet-stream`.
///
/// ## Note
/// **Guess** is the operative word here, as there are no guarantees that the contents of the file
/// that `path` points to match the MIME type associated with the path's extension.
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn guess_mime_type<P: AsRef<Path>>(path: P) -> Mime {
    guess_mime_type_opt(path)
        .unwrap_or_else(octet_stream)
}

/// Guess the MIME type of `path` by its extension (as defined by `Path::extension()`).
///
/// If `path` has no extension, or its extension has no known MIME type mapping,
/// then `None` is returned.
///
/// ## Note
/// **Guess** is the operative word here, as there are no guarantees that the contents of the file
/// that `path` points to match the MIME type associated with the path's extension.
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn guess_mime_type_opt<P: AsRef<Path>>(path: P) -> Option<Mime> {
    let ext = path.as_ref().extension().and_then(OsStr::to_str).unwrap_or("");

    get_mime_type_opt(ext)
}

/// Get the MIME type associated with a file extension.
///
/// If there is no association for the extension, or `ext` is empty,
/// `application/octet-stream` is returned.
pub fn get_mime_type(search_ext: &str) -> Mime {
    get_mime_type_opt(search_ext)
        .unwrap_or_else(octet_stream)
}

/// Get the MIME type associated with a file extension.
///
/// If there is no association for the extension, or `ext` is empty,
/// `None` is returned.
pub fn get_mime_type_opt(search_ext: &str) -> Option<Mime> {
    get_mime_type_str(search_ext)
        .map(|mime| mime.parse::<Mime>().unwrap())
}

/// Get the MIME type string associated with a file extension. Case-insensitive.
///
/// If `search_ext` is not already lowercase,
/// it will be converted to lowercase to facilitate the search.
///
/// Returns `None` if `search_ext` is empty or an associated extension was not found.
pub fn get_mime_type_str(search_ext: &str) -> Option<&'static str> {
    if search_ext.is_empty() { return None; }

    map_lookup(&MIME_TYPES, search_ext).cloned()
}

/// Get a list of known extensions for a given `Mime`.
///
/// Ignores parameters (only searches with `<main type>/<subtype>`). Case-insensitive (for extension types).
///
/// Returns `None` if the MIME type is unknown.
///
/// ### Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
pub fn get_mime_extensions(mime: &Mime) -> Option<&'static [&'static str]> {
    get_extensions(&mime.0, &mime.1)
}

/// Get a list of known extensions for a MIME type string.
///
/// Ignores parameters (only searches `<main type>/<subtype>`). Case-insensitive.
///
/// Returns `None` if the MIME type is unknown.
///
/// ### Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
///
/// ### Panics
/// If `mime_str` is not a valid MIME type specifier (naive).
pub fn get_mime_extensions_str(mut mime_str: &str) -> Option<&'static [&'static str]> {
    mime_str = mime_str.trim();

    if let Some(sep_idx) = mime_str.find(';') {
        mime_str = &mime_str[..sep_idx];
    }

    let (top, sub) = {
        let split_idx = mime_str.find('/').unwrap();
        (&mime_str[..split_idx], &mime_str[split_idx + 1 ..])
    };

    get_extensions(top, sub)
}

/// Get the extensions for a given top-level and sub-level of a MIME type
/// (`{toplevel}/{sublevel}`).
///
/// Returns `None` if `toplevel` or `sublevel` are unknown.
///
/// ### Wildcards
/// If the top-level of the MIME type is a wildcard (`*`), returns all extensions.
///
/// If the sub-level of the MIME type is a wildcard, returns all extensions for the top-level.
pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> {
    if toplevel == "*" {
        return Some(EXTS);
    }

    let top = try_opt!(map_lookup(&REV_MAPPINGS, toplevel));

    if sublevel == "*" {
        return Some(&EXTS[top.start .. top.end]);
    }

    let sub = try_opt!(map_lookup(&top.subs, sublevel));
    Some(&EXTS[sub.0 .. sub.1])
}

/// Get the MIME type for `application/octet-stream` (generic binary stream)
pub fn octet_stream() -> Mime {
    "application/octet-stream".parse().unwrap()
}

fn map_lookup<'map, V>(map: &'map phf::Map<UniCase<&'static str>, V>, key: &str) -> Option<&'map V> {
    // This transmute should be safe as `get` will not store the reference with
    // the expanded lifetime. This is due to `Borrow` being overly strict and
    // can't have an impl for `&'static str` to `Borrow<&'a str>`.
    //
    // See https://github.com/rust-lang/rust/issues/28853#issuecomment-158735548
    let key = unsafe { ::std::mem::transmute::<_, &'static str>(key) };
    map.get(&UniCase(key))
}

#[cfg(test)]
mod tests {
    use mime::Mime;
    use std::ascii::AsciiExt;
    use std::path::Path;
    use super::{get_mime_type, guess_mime_type, MIME_TYPES};
    use super::{get_mime_type_opt, guess_mime_type_opt};

    #[test]
    fn test_mime_type_guessing() {
        assert_eq!(get_mime_type("gif").to_string(), "image/gif".to_string());
        assert_eq!(get_mime_type("TXT").to_string(), "text/plain".to_string());
        assert_eq!(get_mime_type("blahblah").to_string(), "application/octet-stream".to_string());

        assert_eq!(guess_mime_type(Path::new("/path/to/file.gif")).to_string(), "image/gif".to_string());
        assert_eq!(guess_mime_type("/path/to/file.gif").to_string(), "image/gif".to_string());
    }

    #[test]
    fn test_mime_type_guessing_opt() {
        assert_eq!(get_mime_type_opt("gif").unwrap().to_string(), "image/gif".to_string());
        assert_eq!(get_mime_type_opt("TXT").unwrap().to_string(), "text/plain".to_string());
        assert_eq!(get_mime_type_opt("blahblah"), None);

        assert_eq!(guess_mime_type_opt("/path/to/file.gif").unwrap().to_string(), "image/gif".to_string());
        assert_eq!(guess_mime_type_opt("/path/to/file"), None);
    }

    #[test]
    fn test_are_mime_types_parseable() {
        for (_, mime) in &MIME_TYPES {
            mime.parse::<Mime>().unwrap();
        }
    }

    // RFC: Is this test necessary anymore? --@cybergeek94, 2/1/2016
    #[test]
    fn test_are_extensions_ascii() {
        for (ext, _) in &MIME_TYPES {
            assert!(ext.is_ascii(), "Extension not ASCII: {:?}", ext);
        }
    }

    #[test]
    fn test_are_extensions_sorted() {
        use mime_types_src::MIME_TYPES;

        for (&(ext, _), &(n_ext, _)) in MIME_TYPES.iter().zip(MIME_TYPES.iter().skip(1)) {
            assert!(
                ext <= n_ext,
                "Extensions in src/mime_types should be sorted alphabetically
                in ascending order. Failed assert: {:?} <= {:?}",
                ext, n_ext
            );
        }
    }

}

#[cfg(feature = "bench")]
mod bench {
    extern crate test;

    use self::test::Bencher;

    use super::{get_mime_type_str, MIME_TYPES};

    /// WARNING: this may take a while!
    #[bench]
    fn bench_mime_str(b: &mut Bencher) {
        for (mime_ext, _) in &MIME_TYPES {
            b.iter(|| {
                get_mime_type_str(mime_ext).expect(mime_ext);
            });
        }
    }

    #[bench]
    fn bench_mime_str_uppercase(b: &mut Bencher) {
        let uppercased : Vec<_> = MIME_TYPES.into_iter().map(|(s, _)| s.to_uppercase()).collect();

        for mime_ext in &uppercased {
            b.iter(|| {
                get_mime_type_str(mime_ext).expect(mime_ext);
            });
        }
    }
}
<|endoftext|>


<commit_before>#![feature(zero_one)]

extern crate openblas;

use std::marker::{PhantomData};
use std::num::{Zero};

pub mod linalg;

pub trait ArrayIndex: Copy {
  fn least_stride(&self) -> Self;
  fn flat_len(&self) -> usize;
  fn offset(&self, stride: Self) -> usize;
  fn diff(&self, rhs: Self) -> Self;

  /*fn major_iter(self) -> MajorIter<Self> where Self: Default {
    MajorIter{
      idx:          Default::default(),
      upper_bound:  self,
    }
  }*/
}

impl ArrayIndex for usize {
  fn least_stride(&self) -> Self {
    1
  }

  fn flat_len(&self) -> usize {
    *self
  }

  fn offset(&self, stride: Self) -> usize {
    *self * stride
  }

  fn diff(&self, rhs: Self) -> Self {
    *self - rhs
  }
}

impl ArrayIndex for (usize, usize) {
  fn least_stride(&self) -> Self {
    (1, self.0)
  }

  fn flat_len(&self) -> usize {
    self.0 * self.1
  }

  fn offset(&self, stride: Self) -> usize {
    //stride.0 * (self.0 + stride.1 * self.1)
    stride.0 * self.0 + stride.1 * self.1
  }

  fn diff(&self, rhs: Self) -> Self {
    (self.0 - rhs.0, self.1 - rhs.1)
  }
}

impl ArrayIndex for (usize, usize, usize) {
  fn least_stride(&self) -> Self {
    (1, self.0, self.0 * self.1)
  }

  fn flat_len(&self) -> usize {
    self.0 * self.1 * self.2
  }

  fn offset(&self, stride: Self) -> usize {
    //stride.0 * (self.0 + stride.1 * (self.1 + stride.2 * self.2))
    stride.0 * self.0 + stride.1 * self.1 + stride.2 * self.2
  }

  fn diff(&self, rhs: Self) -> Self {
    (self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
  }
}

pub trait Reshape<'a, Idx, Target> where Idx: ArrayIndex {
  fn reshape(&'a self, dim: Idx) -> Target;
  fn reshape_stride(&'a self, dim: Idx, stride: Idx) -> Target { unimplemented!(); }
}

pub trait ReshapeMut<'a, Idx, Target> where Idx: ArrayIndex {
  fn reshape_mut(&'a mut self, dim: Idx) -> Target;
  fn reshape_mut_stride(&'a mut self, dim: Idx, stride: Idx) -> Target { unimplemented!(); }
}

pub trait View<'a, Idx, Target> where Idx: ArrayIndex {
  fn view(&'a self, lo: Idx, hi: Idx) -> Target;
}

pub trait ViewMut<'a, Idx, Target> where Idx: ArrayIndex {
  fn view_mut(&'a mut self, lo: Idx, hi: Idx) -> Target;
}

pub trait AsView<'a, Target> {
  fn as_view(&'a self) -> Target;
}

pub trait AsViewMut<'a, Target> {
  fn as_view_mut(&'a mut self) -> Target;
}

impl<'a, T> Reshape<'a, (usize, usize), Array2dView<'a, T>> for [T] where T: Copy {
  fn reshape(&'a self, dim: (usize, usize)) -> Array2dView<'a, T> {
    // Assume unit stride.
    Array2dView{
      data_buf: self,
      dim:      dim,
      stride:   dim.least_stride(),
    }
  }
}

impl<'a, T> ReshapeMut<'a, (usize, usize), Array2dViewMut<'a, T>> for [T] where T: Copy {
  fn reshape_mut(&'a mut self, dim: (usize, usize)) -> Array2dViewMut<'a, T> {
    // Assume unit stride.
    Array2dViewMut{
      data_buf: self,
      dim:      dim,
      stride:   dim.least_stride(),
    }
  }
}

pub trait ArrayStorage<T>: Clone + AsRef<[T]> + AsMut<[T]> {}

impl<T> ArrayStorage<T> for Vec<T> where T: Copy {}

#[derive(Clone)]
pub struct Array1d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      usize,
  stride:   usize,
  _marker:  PhantomData<T>,
}

impl<T> Array1d<T> where T: Copy + Zero {
  pub fn zeros(dim: usize) -> Array1d<T> {
    let len = dim.flat_len();
    let mut data = Vec::with_capacity(len);
    unsafe { data.set_len(len) };
    for i in 0 .. len {
      data[i] = T::zero();
    }
    Array1d{
      data_buf: data,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }
}

impl<T, S> Array1d<T, S> where T: Copy, S: ArrayStorage<T> {
}

#[derive(Clone)]
pub struct Array2d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      (usize, usize),
  stride:   (usize, usize),
  _marker:  PhantomData<T>,
}

impl<T> Array2d<T> where T: Copy + Zero {
  pub fn zeros(dim: (usize, usize)) -> Array2d<T> {
    let len = dim.flat_len();
    let mut data = Vec::with_capacity(len);
    unsafe { data.set_len(len) };
    for i in 0 .. len {
      data[i] = T::zero();
    }
    Array2d{
      data_buf: data,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }
}

impl<T, S> Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  pub fn from_storage(dim: (usize, usize), data_buf: S) -> Array2d<T, S> {
    assert_eq!(dim.flat_len(), data_buf.as_ref().len());
    Array2d{
      data_buf: data_buf,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }

  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }

  pub fn as_slice(&self) -> &[T] {
    self.data_buf.as_ref()
  }

  pub fn as_mut_slice(&mut self) -> &mut [T] {
    self.data_buf.as_mut()
  }
}

impl<'a, T, S> AsView<'a, Array2dView<'a, T>> for Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  fn as_view(&'a self) -> Array2dView<'a, T> {
    Array2dView{
      data_buf: self.data_buf.as_ref(),
      dim:      self.dim,
      stride:   self.stride,
    }
  }
}

impl<'a, T, S> AsViewMut<'a, Array2dViewMut<'a, T>> for Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  fn as_view_mut(&'a mut self) -> Array2dViewMut<'a, T> {
    Array2dViewMut{
      data_buf: self.data_buf.as_mut(),
      dim:      self.dim,
      stride:   self.stride,
    }
  }
}

pub struct Array2dView<'a, T> where T: 'a + Copy {
  data_buf: &'a [T],
  dim:      (usize, usize),
  stride:   (usize, usize),
}

impl<'a> Array2dView<'a, f32> {
  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }
}

impl<'a, T> View<'a, (usize, usize), Array2dView<'a, T>> for Array2dView<'a, T> where T: 'a + Copy {
  fn view(&'a self, lo: (usize, usize), hi: (usize, usize)) -> Array2dView<'a, T> {
    let lo_offset = lo.offset(self.stride);
    let hi_offset = hi.offset(self.stride);
    let new_dim = hi.diff(lo);
    Array2dView{
      data_buf: &self.data_buf[lo_offset .. hi_offset],
      dim:      new_dim,
      stride:   self.stride,
    }
  }
}

pub struct Array2dViewMut<'a, T> where T: 'a + Copy {
  data_buf: &'a mut [T],
  dim:      (usize, usize),
  stride:   (usize, usize),
}

impl<'a, T> ViewMut<'a, (usize, usize), Array2dViewMut<'a, T>> for Array2dViewMut<'a, T> where T: 'a + Copy {
  fn view_mut(&'a mut self, lo: (usize, usize), hi: (usize, usize)) -> Array2dViewMut<'a, T> {
    let lo_offset = lo.offset(self.stride);
    let hi_offset = hi.offset(self.stride);
    let new_dim = hi.diff(lo);
    Array2dViewMut{
      data_buf: &mut self.data_buf[lo_offset .. hi_offset],
      dim:      new_dim,
      stride:   self.stride,
    }
  }
}

impl<'a> Array2dViewMut<'a, f32> {
  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }

  pub fn set_constant(&'a mut self, alpha: f32) {
    for i in 0 .. self.dim.flat_len() {
      self.data_buf[i] = alpha;
    }
  }
}

#[derive(Clone)]
pub struct Array3d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      (usize, usize, usize),
  stride:   (usize, usize, usize),
  _marker:  PhantomData<T>,
}

impl<T, S> Array3d<T, S> where T: Copy, S: ArrayStorage<T> {
  pub fn from_storage(dim: (usize, usize, usize), data_buf: S) -> Array3d<T, S> {
    assert_eq!(dim.flat_len(), data_buf.as_ref().len());
    Array3d{
      data_buf: data_buf,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }

  pub fn dim(&self) -> (usize, usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize, usize) {
    self.stride
  }

  pub fn as_slice(&self) -> &[T] {
    self.data_buf.as_ref()
  }

  pub fn as_mut_slice(&mut self) -> &mut [T] {
    self.data_buf.as_mut()
  }
}
<commit_msg>Fix subview indexing.<commit_after>#![feature(zero_one)]

extern crate openblas;

use std::marker::{PhantomData};
use std::num::{Zero};

pub mod linalg;

pub trait ArrayIndex: Copy {
  fn least_stride(&self) -> Self;
  fn flat_len(&self) -> usize;
  fn offset(&self, stride: Self) -> usize;
  fn diff(&self, rhs: Self) -> Self;

  /*fn major_iter(self) -> MajorIter<Self> where Self: Default {
    MajorIter{
      idx:          Default::default(),
      upper_bound:  self,
    }
  }*/
}

impl ArrayIndex for usize {
  fn least_stride(&self) -> Self {
    1
  }

  fn flat_len(&self) -> usize {
    *self
  }

  fn offset(&self, stride: Self) -> usize {
    *self * stride
  }

  fn diff(&self, rhs: Self) -> Self {
    *self - rhs
  }
}

impl ArrayIndex for (usize, usize) {
  fn least_stride(&self) -> Self {
    (1, self.0)
  }

  fn flat_len(&self) -> usize {
    self.0 * self.1
  }

  fn offset(&self, stride: Self) -> usize {
    //stride.0 * (self.0 + stride.1 * self.1)
    stride.0 * self.0 + stride.1 * self.1
  }

  fn diff(&self, rhs: Self) -> Self {
    (self.0 - rhs.0, self.1 - rhs.1)
  }
}

impl ArrayIndex for (usize, usize, usize) {
  fn least_stride(&self) -> Self {
    (1, self.0, self.0 * self.1)
  }

  fn flat_len(&self) -> usize {
    self.0 * self.1 * self.2
  }

  fn offset(&self, stride: Self) -> usize {
    //stride.0 * (self.0 + stride.1 * (self.1 + stride.2 * self.2))
    stride.0 * self.0 + stride.1 * self.1 + stride.2 * self.2
  }

  fn diff(&self, rhs: Self) -> Self {
    (self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
  }
}

pub trait Reshape<'a, Idx, Target> where Idx: ArrayIndex {
  fn reshape(&'a self, dim: Idx) -> Target;
  fn reshape_stride(&'a self, dim: Idx, stride: Idx) -> Target { unimplemented!(); }
}

pub trait ReshapeMut<'a, Idx, Target> where Idx: ArrayIndex {
  fn reshape_mut(&'a mut self, dim: Idx) -> Target;
  fn reshape_mut_stride(&'a mut self, dim: Idx, stride: Idx) -> Target { unimplemented!(); }
}

pub trait View<'a, Idx, Target> where Idx: ArrayIndex {
  fn view(&'a self, lo: Idx, hi: Idx) -> Target;
}

pub trait ViewMut<'a, Idx, Target> where Idx: ArrayIndex {
  fn view_mut(&'a mut self, lo: Idx, hi: Idx) -> Target;
}

pub trait AsView<'a, Target> {
  fn as_view(&'a self) -> Target;
}

pub trait AsViewMut<'a, Target> {
  fn as_view_mut(&'a mut self) -> Target;
}

impl<'a, T> Reshape<'a, (usize, usize), Array2dView<'a, T>> for [T] where T: Copy {
  fn reshape(&'a self, dim: (usize, usize)) -> Array2dView<'a, T> {
    // Assume unit stride.
    Array2dView{
      data_buf: self,
      dim:      dim,
      stride:   dim.least_stride(),
    }
  }
}

impl<'a, T> ReshapeMut<'a, (usize, usize), Array2dViewMut<'a, T>> for [T] where T: Copy {
  fn reshape_mut(&'a mut self, dim: (usize, usize)) -> Array2dViewMut<'a, T> {
    // Assume unit stride.
    Array2dViewMut{
      data_buf: self,
      dim:      dim,
      stride:   dim.least_stride(),
    }
  }
}

pub trait ArrayStorage<T>: Clone + AsRef<[T]> + AsMut<[T]> {}

impl<T> ArrayStorage<T> for Vec<T> where T: Copy {}

#[derive(Clone)]
pub struct Array1d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      usize,
  stride:   usize,
  _marker:  PhantomData<T>,
}

impl<T> Array1d<T> where T: Copy + Zero {
  pub fn zeros(dim: usize) -> Array1d<T> {
    let len = dim.flat_len();
    let mut data = Vec::with_capacity(len);
    unsafe { data.set_len(len) };
    for i in 0 .. len {
      data[i] = T::zero();
    }
    Array1d{
      data_buf: data,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }
}

impl<T, S> Array1d<T, S> where T: Copy, S: ArrayStorage<T> {
}

#[derive(Clone)]
pub struct Array2d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      (usize, usize),
  stride:   (usize, usize),
  _marker:  PhantomData<T>,
}

impl<T> Array2d<T> where T: Copy + Zero {
  pub fn zeros(dim: (usize, usize)) -> Array2d<T> {
    let len = dim.flat_len();
    let mut data = Vec::with_capacity(len);
    unsafe { data.set_len(len) };
    for i in 0 .. len {
      data[i] = T::zero();
    }
    Array2d{
      data_buf: data,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }
}

impl<T, S> Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  pub fn from_storage(dim: (usize, usize), data_buf: S) -> Array2d<T, S> {
    assert_eq!(dim.flat_len(), data_buf.as_ref().len());
    Array2d{
      data_buf: data_buf,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }

  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }

  pub fn as_slice(&self) -> &[T] {
    self.data_buf.as_ref()
  }

  pub fn as_mut_slice(&mut self) -> &mut [T] {
    self.data_buf.as_mut()
  }
}

impl<'a, T, S> AsView<'a, Array2dView<'a, T>> for Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  fn as_view(&'a self) -> Array2dView<'a, T> {
    Array2dView{
      data_buf: self.data_buf.as_ref(),
      dim:      self.dim,
      stride:   self.stride,
    }
  }
}

impl<'a, T, S> AsViewMut<'a, Array2dViewMut<'a, T>> for Array2d<T, S> where T: Copy, S: ArrayStorage<T> {
  fn as_view_mut(&'a mut self) -> Array2dViewMut<'a, T> {
    Array2dViewMut{
      data_buf: self.data_buf.as_mut(),
      dim:      self.dim,
      stride:   self.stride,
    }
  }
}

pub struct Array2dView<'a, T> where T: 'a + Copy {
  data_buf: &'a [T],
  dim:      (usize, usize),
  stride:   (usize, usize),
}

impl<'a> Array2dView<'a, f32> {
  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }
}

impl<'a, T> View<'a, (usize, usize), Array2dView<'a, T>> for Array2dView<'a, T> where T: 'a + Copy {
  fn view(&'a self, lo: (usize, usize), hi: (usize, usize)) -> Array2dView<'a, T> {
    let new_dim = hi.diff(lo);
    let new_offset = lo.offset(self.stride);
    let new_offset_end = new_offset + new_dim.flat_len();
    Array2dView{
      data_buf: &self.data_buf[new_offset .. new_offset_end],
      dim:      new_dim,
      stride:   self.stride,
    }
  }
}

pub struct Array2dViewMut<'a, T> where T: 'a + Copy {
  data_buf: &'a mut [T],
  dim:      (usize, usize),
  stride:   (usize, usize),
}

impl<'a, T> ViewMut<'a, (usize, usize), Array2dViewMut<'a, T>> for Array2dViewMut<'a, T> where T: 'a + Copy {
  fn view_mut(&'a mut self, lo: (usize, usize), hi: (usize, usize)) -> Array2dViewMut<'a, T> {
    let new_dim = hi.diff(lo);
    let new_offset = lo.offset(self.stride);
    let new_offset_end = new_offset + new_dim.flat_len();
    Array2dViewMut{
      data_buf: &mut self.data_buf[new_offset .. new_offset_end],
      dim:      new_dim,
      stride:   self.stride,
    }
  }
}

impl<'a> Array2dViewMut<'a, f32> {
  pub fn dim(&self) -> (usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize) {
    self.stride
  }

  pub fn set_constant(&'a mut self, alpha: f32) {
    for i in 0 .. self.dim.flat_len() {
      self.data_buf[i] = alpha;
    }
  }
}

#[derive(Clone)]
pub struct Array3d<T, S=Vec<T>> where T: Copy, S: ArrayStorage<T> {
  data_buf: S,
  dim:      (usize, usize, usize),
  stride:   (usize, usize, usize),
  _marker:  PhantomData<T>,
}

impl<T, S> Array3d<T, S> where T: Copy, S: ArrayStorage<T> {
  pub fn from_storage(dim: (usize, usize, usize), data_buf: S) -> Array3d<T, S> {
    assert_eq!(dim.flat_len(), data_buf.as_ref().len());
    Array3d{
      data_buf: data_buf,
      dim:      dim,
      stride:   dim.least_stride(),
      _marker:  PhantomData,
    }
  }

  pub fn dim(&self) -> (usize, usize, usize) {
    self.dim
  }

  pub fn stride(&self) -> (usize, usize, usize) {
    self.stride
  }

  pub fn as_slice(&self) -> &[T] {
    self.data_buf.as_ref()
  }

  pub fn as_mut_slice(&mut self) -> &mut [T] {
    self.data_buf.as_mut()
  }
}
<|endoftext|>


<commit_before>/*!
Miscellaneous utilities grab-bag.

 */

#![crate_name="calx"]
#![feature(core, collections, std_misc, thread_sleep)]
#![feature(plugin, custom_attribute)]
#![plugin(regex_macros, glium_macros)]

extern crate collections;
extern crate "rustc-serialize" as rustc_serialize;
extern crate time;
extern crate rand;
extern crate regex;
extern crate image;
extern crate glutin;
#[macro_use]
extern crate glium;

use std::num::wrapping::Wrapping;

pub use rgb::{Rgb, Rgba};
pub use geom::{V2, V3, Rect, RectIter};
pub use img::{color_key};
pub use atlas::{AtlasBuilder, Atlas, AtlasItem};
pub use dijkstra::{DijkstraNode, Dijkstra};
pub use encode_rng::{EncodeRng};

mod atlas;
mod dijkstra;
mod geom;
mod encode_rng;
mod img;
mod primitive;
mod rgb;

pub mod backend;
pub mod color;
pub mod text;
pub mod timing;
pub mod vorud;

pub trait Color: Sized {
    fn to_rgba(&self) -> [f32; 4];
    fn from_color<C: Color>(color: &C) -> Self;

    fn from_rgba(rgba: [f32; 4]) -> Self {
        Color::from_color(&rgb::Rgba::new(
                (rgba[0] * 255.0) as u8,
                (rgba[1] * 255.0) as u8,
                (rgba[2] * 255.0) as u8,
                (rgba[3] * 255.0) as u8))
    }
}

/// Clamp a value to range.
pub fn clamp<C: PartialOrd+Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn { mn }
    else if x > mx { mx }
    else { x }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) + Wrapping(1376312589))
        & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Rectangle anchoring points.
#[derive(Copy, PartialEq, Debug)]
pub enum Anchor {
    TopLeft,
    TopRight,
    BottomLeft,
    BottomRight,
    Top,
    Left,
    Right,
    Bottom,
    Center
}

#[cfg(test)]
mod test {
    #[test]
    fn test_noise() {
        use super::noise;

        for i in 0i32..100 {
            assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
        }
    }
}
<commit_msg>Application data paths<commit_after>/*!
Miscellaneous utilities grab-bag.

 */

#![crate_name="calx"]
#![feature(core, collections, std_misc, thread_sleep)]
#![feature(plugin, custom_attribute)]
#![plugin(regex_macros, glium_macros)]

extern crate collections;
extern crate "rustc-serialize" as rustc_serialize;
extern crate time;
extern crate rand;
extern crate regex;
extern crate image;
extern crate glutin;
#[macro_use]
extern crate glium;

use std::env;
use std::path::{Path, PathBuf};
use std::num::wrapping::Wrapping;

pub use rgb::{Rgb, Rgba};
pub use geom::{V2, V3, Rect, RectIter};
pub use img::{color_key};
pub use atlas::{AtlasBuilder, Atlas, AtlasItem};
pub use dijkstra::{DijkstraNode, Dijkstra};
pub use encode_rng::{EncodeRng};

mod atlas;
mod dijkstra;
mod geom;
mod encode_rng;
mod img;
mod primitive;
mod rgb;

pub mod backend;
pub mod color;
pub mod text;
pub mod timing;
pub mod vorud;

pub trait Color: Sized {
    fn to_rgba(&self) -> [f32; 4];
    fn from_color<C: Color>(color: &C) -> Self;

    fn from_rgba(rgba: [f32; 4]) -> Self {
        Color::from_color(&rgb::Rgba::new(
                (rgba[0] * 255.0) as u8,
                (rgba[1] * 255.0) as u8,
                (rgba[2] * 255.0) as u8,
                (rgba[3] * 255.0) as u8))
    }
}

/// Clamp a value to range.
pub fn clamp<C: PartialOrd+Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn { mn }
    else if x > mx { mx }
    else { x }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) + Wrapping(1376312589))
        & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Rectangle anchoring points.
#[derive(Copy, PartialEq, Debug)]
pub enum Anchor {
    TopLeft,
    TopRight,
    BottomLeft,
    BottomRight,
    Top,
    Left,
    Right,
    Bottom,
    Center
}

/// Return the application data directory path for the current platform.
#[cfg(target_os = "macos")]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        format!("{}/Library/Application Support/{}",
                env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(target_os = "windows")]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
    format!("{}\\{}", env::var("APPDATA").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        &format!("{}/.config/{}", env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(test)]
mod test {
    #[test]
    fn test_noise() {
        use super::noise;

        for i in 0i32..100 {
            assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 Sam Doshi (sam@metal-fish.co.uk)
// Copyright 2013-2014 Philippe Delrieu (philippe.delrieu@free.fr)
//
// Licensed under either of
//          Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
//          MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT).
// This file may not be copied, modified, or distributed except according to those terms.
use std::ptr;
use std::os::raw::c_char;

mod ffi;
mod device;
pub use device::*;
mod io;
pub use io::*;
mod global;
pub use global::*;

pub use ffi::PmError;
pub mod types;
pub use types::*;

pub const HDRLENGTH: i32 = 50;
pub const PM_HOST_ERROR_MSG_LEN: i32 = 256;
<commit_msg>Remove unused imports<commit_after>// Copyright 2014-2015 Sam Doshi (sam@metal-fish.co.uk)
// Copyright 2013-2014 Philippe Delrieu (philippe.delrieu@free.fr)
//
// Licensed under either of
//          Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
//          MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT).
// This file may not be copied, modified, or distributed except according to those terms.
mod ffi;
mod device;
pub use device::*;
mod io;
pub use io::*;
mod global;
pub use global::*;

pub use ffi::PmError;
pub mod types;
pub use types::*;

pub const HDRLENGTH: i32 = 50;
pub const PM_HOST_ERROR_MSG_LEN: i32 = 256;
<|endoftext|>


<commit_before>mod ffi;

use std::ffi::CStr;
use std::marker::PhantomData;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;

#[derive(Clone, Copy)]
pub struct Symbol(ffi::TSSymbol);

pub type Language = *const ffi::TSLanguage;

pub trait Utf16Input {
    fn read(&mut self) -> &[u16];
    fn seek(&mut self, u32, Point);
}

pub trait Utf8Input {
    fn read(&mut self) -> &[u8];
    fn seek(&mut self, u32, Point);
}

#[derive(Debug, PartialEq, Eq)]
pub enum LogType {
    Parse,
    Lex,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Point {
    pub row: u32,
    pub column: u32,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct InputEdit {
    pub start_byte: u32,
    pub old_end_byte: u32,
    pub new_end_byte: u32,
    pub start_position: Point,
    pub old_end_position: Point,
    pub new_end_position: Point,
}

pub struct Node<'a>(ffi::TSNode, PhantomData<&'a ()>);

pub struct Parser(*mut ffi::TSParser);

pub struct Tree(*mut ffi::TSTree, ffi::TSInputEncoding);

pub struct TreeCursor<'a>(ffi::TSTreeCursor, PhantomData<&'a ()>);

struct FlatInput<'a> {
    bytes: &'a [u8],
    offset: usize,
}

impl Parser {
    pub fn new() -> Parser {
        unsafe {
            let parser = ffi::ts_parser_new();
            Parser(parser)
        }
    }

    pub fn set_language(&mut self, language: Language) {
        unsafe {
            ffi::ts_parser_set_language(self.0, language);
        }
    }

    pub fn set_logger<F: FnMut(LogType, &str) -> ()>(&mut self, logger: Option<&mut F>) {
        unsafe extern "C" fn log<F: FnMut(LogType, &str) -> ()>(
            payload: *mut c_void,
            c_log_type: ffi::TSLogType,
            c_message: *const c_char,
        ) {
            let callback = (payload as *mut F).as_mut().unwrap();
            if let Ok(message) = CStr::from_ptr(c_message).to_str() {
                let log_type = if c_log_type == ffi::TSLogType_TSLogTypeParse {
                    LogType::Parse
                } else {
                    LogType::Lex
                };
                callback(log_type, message);
            }
        };

        let c_logger;
        if let Some(logger) = logger {
            c_logger = ffi::TSLogger {
                payload: logger as *mut F as *mut c_void,
                log: Some(log::<F>),
            };
        } else {
            c_logger = ffi::TSLogger { payload: ptr::null_mut(), log: None };
        }

        unsafe { ffi::ts_parser_set_logger(self.0, c_logger) };
    }

    pub fn parse_str(&mut self, input: &str, old_tree: Option<Tree>) -> Option<Tree> {
        let mut input = FlatInput { bytes: input.as_bytes(), offset: 0};
        self.parse_utf8(&mut input, old_tree)
    }

    pub fn parse_utf8<T: Utf8Input>(
        &mut self,
        input: &mut T,
        old_tree: Option<Tree>,
    ) -> Option<Tree> {
        unsafe extern "C" fn read<T: Utf8Input>(
            payload: *mut c_void,
            bytes_read: *mut u32,
        ) -> *const c_char {
            let input = (payload as *mut T).as_mut().unwrap();
            let result = input.read();
            *bytes_read = result.len() as u32;
            return result.as_ptr() as *const c_char;
        };

        unsafe extern "C" fn seek<T: Utf8Input>(
            payload: *mut c_void,
            byte: u32,
            position: ffi::TSPoint,
        ) -> c_int {
            let input = (payload as *mut T).as_mut().unwrap();
            input.seek(
                byte,
                Point {
                    row: position.row,
                    column: position.column,
                },
            );
            return 1;
        };

        let c_input = ffi::TSInput {
            payload: input as *mut T as *mut c_void,
            read: Some(read::<T>),
            seek: Some(seek::<T>),
            encoding: ffi::TSInputEncoding_TSInputEncodingUTF8,
        };

        let old_tree_ptr = old_tree.map_or(ptr::null_mut(), |t| t.0);

        let new_tree_ptr = unsafe { ffi::ts_parser_parse(self.0, old_tree_ptr, c_input) };
        if new_tree_ptr.is_null() {
            None
        } else {
            Some(Tree(new_tree_ptr, ffi::TSInputEncoding_TSInputEncodingUTF8))
        }
    }

    pub fn parse_utf16<T: Utf16Input>(
        &mut self,
        input: &mut T,
        old_tree: Option<Tree>,
    ) -> Option<Tree> {
        unsafe extern "C" fn read<T: Utf16Input>(
            payload: *mut c_void,
            bytes_read: *mut u32,
        ) -> *const c_char {
            let input = (payload as *mut T).as_mut().unwrap();
            let result = input.read();
            *bytes_read = result.len() as u32 * 2;
            return result.as_ptr() as *const c_char;
        };

        unsafe extern "C" fn seek<T: Utf16Input>(
            payload: *mut c_void,
            byte: u32,
            position: ffi::TSPoint,
        ) -> c_int {
            let input = (payload as *mut T).as_mut().unwrap();
            input.seek(
                byte / 2,
                Point {
                    row: position.row,
                    column: position.column / 2,
                },
            );
            return 1;
        };

        let c_input = ffi::TSInput {
            payload: input as *mut T as *mut c_void,
            read: Some(read::<T>),
            seek: Some(seek::<T>),
            encoding: ffi::TSInputEncoding_TSInputEncodingUTF8,
        };

        let old_tree_ptr = old_tree.map_or(ptr::null_mut(), |t| t.0);

        let new_tree_ptr = unsafe { ffi::ts_parser_parse(self.0, old_tree_ptr, c_input) };
        if new_tree_ptr.is_null() {
            None
        } else {
            Some(Tree(
                new_tree_ptr,
                ffi::TSInputEncoding_TSInputEncodingUTF16,
            ))
        }
    }
}

impl Drop for Parser {
    fn drop(&mut self) {
        unsafe { ffi::ts_parser_delete(self.0) }
    }
}

impl Tree {
    pub fn root_node(&self) -> Node {
        Node::new(unsafe { ffi::ts_tree_root_node(self.0) }).unwrap()
    }

    pub fn edit(&mut self, edit: &InputEdit) {
        let edit = ffi::TSInputEdit {
            start_byte: edit.start_byte,
            old_end_byte: edit.old_end_byte,
            new_end_byte: edit.new_end_byte,
            start_point: edit.start_position.into(),
            old_end_point: edit.old_end_position.into(),
            new_end_point: edit.new_end_position.into(),
        };
        unsafe { ffi::ts_tree_edit(self.0, &edit) };
    }

    pub fn walk(&self) -> TreeCursor {
        TreeCursor(unsafe { ffi::ts_tree_cursor_new(self.0) }, PhantomData)
    }
}

impl Drop for Tree {
    fn drop(&mut self) {
        unsafe { ffi::ts_tree_delete(self.0) }
    }
}

impl Clone for Tree {
    fn clone(&self) -> Tree {
        unsafe { Tree(ffi::ts_tree_copy(self.0), self.1) }
    }
}

impl<'a> Node<'a> {
    fn new(node: ffi::TSNode) -> Option<Self> {
        if node.id.is_null() {
            None
        } else {
            Some(Node(node, PhantomData))
        }
    }

    pub fn name(&self) -> &'static str {
        unsafe { CStr::from_ptr(ffi::ts_node_type(self.0)) }.to_str().unwrap()
    }

    pub fn start_index(&self) -> u32 {
        unsafe { ffi::ts_node_start_byte(self.0) }
    }

    pub fn end_index(&self) -> u32 {
        unsafe { ffi::ts_node_end_byte(self.0) }
    }

    pub fn start_position(&self) -> Point {
        let result = unsafe { ffi::ts_node_start_point(self.0) };
        Point {
            row: result.row,
            column: result.column,
        }
    }

    pub fn end_position(&self) -> Point {
        let result = unsafe { ffi::ts_node_end_point(self.0) };
        Point {
            row: result.row,
            column: result.column,
        }
    }

    pub fn child(&self, i: u32) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_child(self.0, i) })
    }

    pub fn child_count(&self) -> u32 {
        unsafe { ffi::ts_node_child_count(self.0) }
    }

    pub fn parent(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_parent(self.0) })
    }

    pub fn to_sexp(&self) -> String {
        let c_string = unsafe { ffi::ts_node_string(self.0) };
        let result = unsafe { CStr::from_ptr(c_string) }.to_str().unwrap().to_string();
        unsafe { free(c_string as *mut c_void) };
        result
    }
}

extern "C" { fn free(pointer: *mut c_void); }

impl<'a> TreeCursor<'a> {
    fn node(&'a self) -> Node<'a> {
        Node(
            unsafe { ffi::ts_tree_cursor_current_node(&self.0) },
            PhantomData,
        )
    }

    fn goto_first_child(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_first_child(&mut self.0) };
    }

    fn goto_parent(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_parent(&mut self.0) };
    }

    fn goto_next_sibling(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_next_sibling(&mut self.0) };
    }

    fn goto_first_child_for_index(&mut self, index: u32) -> Option<u32> {
        let result = unsafe { ffi::ts_tree_cursor_goto_first_child_for_byte(&mut self.0, index) };
        if result < 0 {
            None
        } else {
            Some(result as u32)
        }
    }
}

impl<'a> Drop for TreeCursor<'a> {
    fn drop(&mut self) {
        unsafe { ffi::ts_tree_cursor_delete(&mut self.0) }
    }
}

impl Into<ffi::TSPoint> for Point {
    fn into(self) -> ffi::TSPoint {
        ffi::TSPoint {
            row: self.row,
            column: self.column,
        }
    }
}

impl<'a> Utf8Input for FlatInput<'a> {
    fn read(&mut self) -> &[u8] {
        let result = &self.bytes[self.offset..];
        self.offset = self.bytes.len();
        result
    }

    fn seek(&mut self, offset: u32, _position: Point) {
        self.offset = offset as usize;
    }
}

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

    fn rust() -> Language { unsafe { tree_sitter_rust() } }
    extern "C" { fn tree_sitter_rust() -> Language; }

    #[test]
    fn test_basic_parsing() {
        let mut parser = Parser::new();
        parser.set_language(rust());

        let tree = parser.parse_str("
            struct Stuff {}
            fn main() {}
        ", None).unwrap();

        let root_node = tree.root_node();
        assert_eq!(root_node.name(), "source_file");

        assert_eq!(
            root_node.to_sexp(),
            "(source_file (struct_item (type_identifier) (field_declaration_list)) (function_item (identifier) (parameters) (block)))"
        );

        let struct_node = root_node.child(0).unwrap();
        assert_eq!(struct_node.name(), "struct_item");
    }

    #[test]
    fn test_logging() {
        let mut parser = Parser::new();
        parser.set_language(rust());

        let mut messages = Vec::new();
        parser.set_logger(Some(&mut |log_type, message| {
            messages.push((log_type, message.to_string()));
        }));

        parser.parse_str("
            struct Stuff {}
            fn main() {}
        ", None).unwrap();

        assert!(messages.contains(&(LogType::Parse, "reduce sym:struct_item, child_count:3".to_string())));
        assert!(messages.contains(&(LogType::Lex, "skip character:' '".to_string())));
    }
}
<commit_msg>Add more public methods and tests<commit_after>mod ffi;

use std::ffi::CStr;
use std::marker::PhantomData;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;

#[derive(Clone, Copy)]
pub struct Symbol(ffi::TSSymbol);

pub type Language = *const ffi::TSLanguage;

pub trait Utf16Input {
    fn read(&mut self) -> &[u16];
    fn seek(&mut self, u32, Point);
}

pub trait Utf8Input {
    fn read(&mut self) -> &[u8];
    fn seek(&mut self, u32, Point);
}

#[derive(Debug, PartialEq, Eq)]
pub enum LogType {
    Parse,
    Lex,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Point {
    pub row: u32,
    pub column: u32,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct InputEdit {
    pub start_byte: u32,
    pub old_end_byte: u32,
    pub new_end_byte: u32,
    pub start_position: Point,
    pub old_end_position: Point,
    pub new_end_position: Point,
}

pub struct Node<'a>(ffi::TSNode, PhantomData<&'a ()>);

pub struct Parser(*mut ffi::TSParser);

pub struct Tree(*mut ffi::TSTree, ffi::TSInputEncoding);

pub struct TreeCursor<'a>(ffi::TSTreeCursor, PhantomData<&'a ()>);

struct FlatInput<'a> {
    bytes: &'a [u8],
    offset: usize,
}

impl Parser {
    pub fn new() -> Parser {
        unsafe {
            let parser = ffi::ts_parser_new();
            Parser(parser)
        }
    }

    pub fn set_language(&mut self, language: Language) {
        unsafe {
            ffi::ts_parser_set_language(self.0, language);
        }
    }

    pub fn set_logger<F: FnMut(LogType, &str) -> ()>(&mut self, logger: Option<&mut F>) {
        unsafe extern "C" fn log<F: FnMut(LogType, &str) -> ()>(
            payload: *mut c_void,
            c_log_type: ffi::TSLogType,
            c_message: *const c_char,
        ) {
            let callback = (payload as *mut F).as_mut().unwrap();
            if let Ok(message) = CStr::from_ptr(c_message).to_str() {
                let log_type = if c_log_type == ffi::TSLogType_TSLogTypeParse {
                    LogType::Parse
                } else {
                    LogType::Lex
                };
                callback(log_type, message);
            }
        };

        let c_logger;
        if let Some(logger) = logger {
            c_logger = ffi::TSLogger {
                payload: logger as *mut F as *mut c_void,
                log: Some(log::<F>),
            };
        } else {
            c_logger = ffi::TSLogger { payload: ptr::null_mut(), log: None };
        }

        unsafe { ffi::ts_parser_set_logger(self.0, c_logger) };
    }

    pub fn parse_str(&mut self, input: &str, old_tree: Option<Tree>) -> Option<Tree> {
        let mut input = FlatInput { bytes: input.as_bytes(), offset: 0};
        self.parse_utf8(&mut input, old_tree)
    }

    pub fn parse_utf8<T: Utf8Input>(
        &mut self,
        input: &mut T,
        old_tree: Option<Tree>,
    ) -> Option<Tree> {
        unsafe extern "C" fn read<T: Utf8Input>(
            payload: *mut c_void,
            bytes_read: *mut u32,
        ) -> *const c_char {
            let input = (payload as *mut T).as_mut().unwrap();
            let result = input.read();
            *bytes_read = result.len() as u32;
            return result.as_ptr() as *const c_char;
        };

        unsafe extern "C" fn seek<T: Utf8Input>(
            payload: *mut c_void,
            byte: u32,
            position: ffi::TSPoint,
        ) -> c_int {
            let input = (payload as *mut T).as_mut().unwrap();
            input.seek(
                byte,
                Point {
                    row: position.row,
                    column: position.column,
                },
            );
            return 1;
        };

        let c_input = ffi::TSInput {
            payload: input as *mut T as *mut c_void,
            read: Some(read::<T>),
            seek: Some(seek::<T>),
            encoding: ffi::TSInputEncoding_TSInputEncodingUTF8,
        };

        let old_tree_ptr = old_tree.map_or(ptr::null_mut(), |t| t.0);

        let new_tree_ptr = unsafe { ffi::ts_parser_parse(self.0, old_tree_ptr, c_input) };
        if new_tree_ptr.is_null() {
            None
        } else {
            Some(Tree(new_tree_ptr, ffi::TSInputEncoding_TSInputEncodingUTF8))
        }
    }

    pub fn parse_utf16<T: Utf16Input>(
        &mut self,
        input: &mut T,
        old_tree: Option<Tree>,
    ) -> Option<Tree> {
        unsafe extern "C" fn read<T: Utf16Input>(
            payload: *mut c_void,
            bytes_read: *mut u32,
        ) -> *const c_char {
            let input = (payload as *mut T).as_mut().unwrap();
            let result = input.read();
            *bytes_read = result.len() as u32 * 2;
            return result.as_ptr() as *const c_char;
        };

        unsafe extern "C" fn seek<T: Utf16Input>(
            payload: *mut c_void,
            byte: u32,
            position: ffi::TSPoint,
        ) -> c_int {
            let input = (payload as *mut T).as_mut().unwrap();
            input.seek(
                byte / 2,
                Point {
                    row: position.row,
                    column: position.column / 2,
                },
            );
            return 1;
        };

        let c_input = ffi::TSInput {
            payload: input as *mut T as *mut c_void,
            read: Some(read::<T>),
            seek: Some(seek::<T>),
            encoding: ffi::TSInputEncoding_TSInputEncodingUTF8,
        };

        let old_tree_ptr = old_tree.map_or(ptr::null_mut(), |t| t.0);

        let new_tree_ptr = unsafe { ffi::ts_parser_parse(self.0, old_tree_ptr, c_input) };
        if new_tree_ptr.is_null() {
            None
        } else {
            Some(Tree(
                new_tree_ptr,
                ffi::TSInputEncoding_TSInputEncodingUTF16,
            ))
        }
    }
}

impl Drop for Parser {
    fn drop(&mut self) {
        unsafe { ffi::ts_parser_delete(self.0) }
    }
}

impl Tree {
    pub fn root_node(&self) -> Node {
        Node::new(unsafe { ffi::ts_tree_root_node(self.0) }).unwrap()
    }

    pub fn edit(&mut self, edit: &InputEdit) {
        let edit = ffi::TSInputEdit {
            start_byte: edit.start_byte,
            old_end_byte: edit.old_end_byte,
            new_end_byte: edit.new_end_byte,
            start_point: edit.start_position.into(),
            old_end_point: edit.old_end_position.into(),
            new_end_point: edit.new_end_position.into(),
        };
        unsafe { ffi::ts_tree_edit(self.0, &edit) };
    }

    pub fn walk(&self) -> TreeCursor {
        TreeCursor(unsafe { ffi::ts_tree_cursor_new(self.0) }, PhantomData)
    }
}

impl Drop for Tree {
    fn drop(&mut self) {
        unsafe { ffi::ts_tree_delete(self.0) }
    }
}

impl Clone for Tree {
    fn clone(&self) -> Tree {
        unsafe { Tree(ffi::ts_tree_copy(self.0), self.1) }
    }
}

impl<'a> Node<'a> {
    fn new(node: ffi::TSNode) -> Option<Self> {
        if node.id.is_null() {
            None
        } else {
            Some(Node(node, PhantomData))
        }
    }

    pub fn kind(&self) -> &'static str {
        unsafe { CStr::from_ptr(ffi::ts_node_type(self.0)) }.to_str().unwrap()
    }

    pub fn is_named(&self) -> bool {
        unsafe { ffi::ts_node_is_named(self.0) }
    }

    pub fn has_changes(&self) -> bool {
        unsafe { ffi::ts_node_has_changes(self.0) }
    }

    pub fn has_error(&self) -> bool {
        unsafe { ffi::ts_node_has_error(self.0) }
    }

    pub fn start_byte(&self) -> u32 {
        unsafe { ffi::ts_node_start_byte(self.0) }
    }

    pub fn end_byte(&self) -> u32 {
        unsafe { ffi::ts_node_end_byte(self.0) }
    }

    pub fn start_position(&self) -> Point {
        let result = unsafe { ffi::ts_node_start_point(self.0) };
        Point {
            row: result.row,
            column: result.column,
        }
    }

    pub fn end_position(&self) -> Point {
        let result = unsafe { ffi::ts_node_end_point(self.0) };
        Point {
            row: result.row,
            column: result.column,
        }
    }

    pub fn child(&self, i: u32) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_child(self.0, i) })
    }

    pub fn child_count(&self) -> u32 {
        unsafe { ffi::ts_node_child_count(self.0) }
    }

    pub fn named_child(&self, i: u32) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_named_child(self.0, i) })
    }

    pub fn named_child_count(&self) -> u32 {
        unsafe { ffi::ts_node_named_child_count(self.0) }
    }

    pub fn parent(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_parent(self.0) })
    }

    pub fn next_sibling(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_next_sibling(self.0) })
    }

    pub fn prev_sibling(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_prev_sibling(self.0) })
    }

    pub fn next_named_sibling(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_next_named_sibling(self.0) })
    }

    pub fn prev_named_sibling(&self) -> Option<Node> {
        Self::new(unsafe { ffi::ts_node_prev_named_sibling(self.0) })
    }

    pub fn to_sexp(&self) -> String {
        let c_string = unsafe { ffi::ts_node_string(self.0) };
        let result = unsafe { CStr::from_ptr(c_string) }.to_str().unwrap().to_string();
        unsafe { free(c_string as *mut c_void) };
        result
    }
}

extern "C" { fn free(pointer: *mut c_void); }

impl<'a> TreeCursor<'a> {
    pub fn node(&'a self) -> Node<'a> {
        Node(
            unsafe { ffi::ts_tree_cursor_current_node(&self.0) },
            PhantomData,
        )
    }

    pub fn goto_first_child(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_first_child(&mut self.0) };
    }

    pub fn goto_parent(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_parent(&mut self.0) };
    }

    pub fn goto_next_sibling(&mut self) -> bool {
        return unsafe { ffi::ts_tree_cursor_goto_next_sibling(&mut self.0) };
    }

    pub fn goto_first_child_for_index(&mut self, index: u32) -> Option<u32> {
        let result = unsafe { ffi::ts_tree_cursor_goto_first_child_for_byte(&mut self.0, index) };
        if result < 0 {
            None
        } else {
            Some(result as u32)
        }
    }
}

impl<'a> Drop for TreeCursor<'a> {
    fn drop(&mut self) {
        unsafe { ffi::ts_tree_cursor_delete(&mut self.0) }
    }
}

impl Into<ffi::TSPoint> for Point {
    fn into(self) -> ffi::TSPoint {
        ffi::TSPoint {
            row: self.row,
            column: self.column,
        }
    }
}

impl<'a> Utf8Input for FlatInput<'a> {
    fn read(&mut self) -> &[u8] {
        let result = &self.bytes[self.offset..];
        self.offset = self.bytes.len();
        result
    }

    fn seek(&mut self, offset: u32, _position: Point) {
        self.offset = offset as usize;
    }
}

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

    fn rust() -> Language { unsafe { tree_sitter_rust() } }
    extern "C" { fn tree_sitter_rust() -> Language; }

    #[test]
    fn test_basic_parsing() {
        let mut parser = Parser::new();
        parser.set_language(rust());

        let tree = parser.parse_str("
            struct Stuff {}
            fn main() {}
        ", None).unwrap();

        let root_node = tree.root_node();
        assert_eq!(root_node.kind(), "source_file");

        assert_eq!(
            root_node.to_sexp(),
            "(source_file (struct_item (type_identifier) (field_declaration_list)) (function_item (identifier) (parameters) (block)))"
        );

        let struct_node = root_node.child(0).unwrap();
        assert_eq!(struct_node.kind(), "struct_item");
    }

    #[test]
    fn test_logging() {
        let mut parser = Parser::new();
        parser.set_language(rust());

        let mut messages = Vec::new();
        parser.set_logger(Some(&mut |log_type, message| {
            messages.push((log_type, message.to_string()));
        }));

        parser.parse_str("
            struct Stuff {}
            fn main() {}
        ", None).unwrap();

        assert!(messages.contains(&(LogType::Parse, "reduce sym:struct_item, child_count:3".to_string())));
        assert!(messages.contains(&(LogType::Lex, "skip character:' '".to_string())));
    }

    #[test]
    fn test_tree_cursor() {
        let mut parser = Parser::new();
        parser.set_language(rust());

        let tree = parser.parse_str("
            struct Stuff {
                a: A;
                b: Option<B>,
            }
        ", None).unwrap();

        let mut cursor = tree.walk();
        assert_eq!(cursor.node().kind(), "source_file");

        assert!(cursor.goto_first_child());
        assert_eq!(cursor.node().kind(), "struct_item");

        assert!(cursor.goto_first_child());
        assert_eq!(cursor.node().kind(), "struct");
        assert_eq!(cursor.node().is_named(), false);

        assert!(cursor.goto_next_sibling());
        assert_eq!(cursor.node().kind(), "type_identifier");
        assert_eq!(cursor.node().is_named(), true);

        assert!(cursor.goto_next_sibling());
        assert_eq!(cursor.node().kind(), "field_declaration_list");
        assert_eq!(cursor.node().is_named(), true);
    }

    #[test]
    fn test_custom_utf8_input() {
        struct LineBasedInput {
            lines: &'static [&'static str],
            row: usize,
            column: usize,
        }

        impl Utf8Input for LineBasedInput {
            fn read(&mut self) -> &[u8] {
                if self.row < self.lines.len() {
                    let result = &self.lines[self.row].as_bytes()[self.column..];
                    self.row += 1;
                    self.column = 0;
                    result
                } else {
                    &[]
                }
            }

            fn seek(&mut self, _byte: u32, position: Point) {
                self.row = position.row as usize;
                self.column = position.column as usize;
            }
        }

        let mut parser = Parser::new();
        parser.set_language(rust());

        let mut input = LineBasedInput {
            lines: &[
                "pub fn main() {",
                "}",
            ],
            row: 0,
            column: 0
        };

        let tree = parser.parse_utf8(&mut input, None).unwrap();
        let root = tree.root_node();
        assert_eq!(root.kind(), "source_file");
        assert_eq!(root.has_error(), false);

        let child = root.child(0).unwrap();
        assert_eq!(child.kind(), "function_item");
    }
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(asm)]
#![feature(const_fn)]
#![feature(lang_items)]

#![feature(alloc)]
#![allow(unknown_lints)]
#![no_std]

extern crate alloc;
#[cfg(not(test))]
extern crate allocator;
extern crate spin;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate collections;
#[macro_use]
extern crate log;

#[macro_use]
pub mod linux;

pub mod cli;
pub mod dispatch_table;
pub mod gdt;
pub mod hash_map;
pub mod interrupts;
pub mod isr;
pub mod runtime;
pub mod vmx;
pub mod serial_logger;

include!(concat!(env!("OUT_DIR"), "/version.rs"));

#[no_mangle]
pub extern "C" fn rustyvisor_load(_heap: *mut u8, _heap_size: u64, _: *mut u8, _: u64) -> u32 {
    #[cfg(not(test))]
    {
        allocator::init(_heap_size, _heap);
        match serial_logger::init() {
            Ok(()) => {}
            Err(_e) => return 1,
        }
    }

    info!("{}", VERSION);

    #[cfg(feature = "runtime_tests")]
    runtime_tests();

    0
}

#[no_mangle]
pub extern "C" fn rustyvisor_unload() {
     let _ = serial_logger::fini();
}

#[cfg(feature = "runtime_tests")]
fn runtime_tests() {
    info!("Executing runtime tests...");

    gdt::runtime_tests::run();
    interrupts::runtime_tests::run();

    info!("Runtime tests succeeded");
}
<commit_msg>Adjust visibility<commit_after>#![feature(collections)]
#![feature(asm)]
#![feature(const_fn)]
#![feature(lang_items)]

#![feature(alloc)]
#![allow(unknown_lints)]
#![no_std]

extern crate alloc;
#[cfg(not(test))]
extern crate allocator;
extern crate spin;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate collections;
#[macro_use]
extern crate log;

mod cli;
pub mod dispatch_table;
mod gdt;
pub mod hash_map;
pub mod interrupts;
mod isr;
pub mod runtime;
pub mod vmx;
mod serial_logger;

include!(concat!(env!("OUT_DIR"), "/version.rs"));

#[no_mangle]
pub extern "C" fn rustyvisor_load(_heap: *mut u8, _heap_size: u64, _: *mut u8, _: u64) -> u32 {
    #[cfg(not(test))]
    {
        allocator::init(_heap_size, _heap);
        match serial_logger::init() {
            Ok(()) => {}
            Err(_e) => return 1,
        }
    }

    info!("{}", VERSION);

    #[cfg(feature = "runtime_tests")]
    runtime_tests();

    0
}

#[no_mangle]
pub extern "C" fn rustyvisor_unload() {
     let _ = serial_logger::fini();
}

#[cfg(feature = "runtime_tests")]
fn runtime_tests() {
    info!("Executing runtime tests...");

    gdt::runtime_tests::run();
    interrupts::runtime_tests::run();

    info!("Runtime tests succeeded");
}
<|endoftext|>


<commit_before>//! This crate contains a JPEG decoder.
//!
//! # Examples
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! let pixels = decoder.decode().expect("failed to decode image");
//! let metadata = decoder.info().unwrap();
//! ```
//!
//! Get metadata from a file without decoding it:
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! decoder.read_info().expect("failed to read metadata");
//! let metadata = decoder.info().unwrap();
//! ```

#![deny(missing_docs)]

extern crate byteorder;
#[cfg(feature="rayon")]
extern crate rayon;

pub use decoder::{Decoder, ImageInfo, PixelFormat};
pub use error::{Error, UnsupportedFeature};

mod decoder;
mod error;
mod huffman;
mod idct;
mod marker;
mod parser;
mod upsampler;
mod worker;
<commit_msg>Mark crate [forbid(unsafe_code)]<commit_after>//! This crate contains a JPEG decoder.
//!
//! # Examples
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! let pixels = decoder.decode().expect("failed to decode image");
//! let metadata = decoder.info().unwrap();
//! ```
//!
//! Get metadata from a file without decoding it:
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! decoder.read_info().expect("failed to read metadata");
//! let metadata = decoder.info().unwrap();
//! ```

#![deny(missing_docs)]
#![forbid(unsafe_code)]

extern crate byteorder;
#[cfg(feature="rayon")]
extern crate rayon;

pub use decoder::{Decoder, ImageInfo, PixelFormat};
pub use error::{Error, UnsupportedFeature};

mod decoder;
mod error;
mod huffman;
mod idct;
mod marker;
mod parser;
mod upsampler;
mod worker;
<|endoftext|>


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

extern crate mio;

use std::cell::{Cell, RefCell};
use std::rc::Rc;
use private::{promise_node, Event, BoolEvent, PromiseAndFulfillerHub,
              EVENT_LOOP, with_current_event_loop, PromiseNode};

pub mod io;

mod private;
mod handle_table;

pub type Error = Box<::std::error::Error>;
pub type Result<T> = ::std::result::Result<T, Error>;

/// The basic primitive of asynchronous computation in GJ.
pub struct Promise<T> where T: 'static {
    node : Box<PromiseNode<T>>,
}

impl <T> Promise <T> where T: 'static {
    pub fn then<F, R>(self, func: F) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<Promise<R>>,
              R: 'static {
                  self.then_else(func, |e| { return Err(e); })
        }

    pub fn then_else<F, G, R>(self, func: F, error_handler: G) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<Promise<R>>,
              G: 'static + FnOnce(Error) -> Result<Promise<R>>,
              R: 'static {
            let intermediate = Box::new(promise_node::Transform::new(self.node, func, error_handler));
            Promise { node: Box::new(promise_node::Chain::new(intermediate)) }
        }

    pub fn map<F, R>(self, func: F) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<R>,
              R: 'static {
            self.map_else(func, |e| { return Err(e); })
        }

    pub fn map_else<F, G, R>(self, func: F, error_handler: G) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<R>,
              G: 'static + FnOnce(Error) -> Result<R>,
              R: 'static {
            Promise { node: Box::new(promise_node::Transform::new(self.node, func, error_handler)) }
        }

    /// Runs the event loop until the promise is fulfilled.
    ///
    /// The `WaitScope` argument ensures that `wait()` can only be called the top level of a program.
    /// Waiting within event callbacks is disallowed.
    pub fn wait(mut self, _wait_scope: &WaitScope) -> Result<T> {
        with_current_event_loop(move |event_loop| {
            let fired = ::std::rc::Rc::new(::std::cell::Cell::new(false));
            let done_event = BoolEvent::new(fired.clone());
            let (handle, dropper) = private::EventHandle::new(Box::new(done_event));
            self.node.on_ready(handle);

            //event_loop.running = true;

            while !fired.get() {
                if !event_loop.turn() {
                    // No events in the queue.
                    event_loop.event_port.borrow_mut().wait();
                }
            }

            self.node.get()
        })
    }

    pub fn fulfilled(value: T) -> Promise<T> {
        return Promise { node: Box::new(promise_node::Immediate::new(Ok(value))) };
    }

    pub fn rejected(error: Error) -> Promise<T> {
        return Promise { node: Box::new(promise_node::Immediate::new(Err(error))) };
    }
}

pub struct WaitScope(::std::marker::PhantomData<*mut u8>); // impl !Sync for WaitScope {}

/// Interface between an `EventLoop` and events originating from outside of the loop's thread.
pub trait EventPort {
    /// Waits for an external event to arrive, sleeping if necessary.
    /// Returns true if wake() has been called from another thread.
    fn wait(&mut self) -> bool;

    /// Checks whether any external events have arrived, but does not sleep.
    /// Returns true if wake() has been called from another thread.
    fn poll(&mut self) -> bool;

    /// Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it
    /// transitions from empty -> runnable or runnable -> empty. This is typically useful when
    /// intergrating with an external event loop; if the loop is currently runnable then you should
    /// arrange to call run() on it soon. The default implementation does nothing.
    fn set_runnable(&mut self, _runnable: bool) { }

    fn wake(&mut self) { unimplemented!(); }
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
//    daemons: TaskSetImpl,
    event_port: RefCell<io::MioEventPort>,
    running: bool,
    _last_runnable_state: bool,
    events: RefCell<handle_table::HandleTable<private::EventNode>>,
    head: Cell<private::EventHandle>,
    tail: Cell<private::EventHandle>,
    depth_first_insertion_point: Cell<private::EventHandle>,
}

impl EventLoop {
    pub fn top_level<F>(f: F) where F: FnOnce(&WaitScope) {
        let mut events = handle_table::HandleTable::<private::EventNode>::new();
        let dummy = private::EventNode { event: None, next: None, prev: None };
        let head_handle = private::EventHandle(events.push(dummy));

        EVENT_LOOP.with(move |maybe_event_loop| {
            let event_loop = EventLoop {
                event_port: RefCell::new(io::MioEventPort::new().unwrap()),
                running: false,
                _last_runnable_state: false,
                events: RefCell::new(events),
                head: Cell::new(head_handle),
                tail: Cell::new(head_handle),
                depth_first_insertion_point: Cell::new(head_handle), // insert after this node
            };

            assert!(maybe_event_loop.borrow().is_none());
            *maybe_event_loop.borrow_mut() = Some(event_loop);
        });
        let wait_scope = WaitScope(::std::marker::PhantomData );
        f(&wait_scope);
    }

    fn arm_depth_first(&self, event_handle: private::EventHandle) {

        let insertion_node_next = self.events.borrow()[self.depth_first_insertion_point.get().0].next;

        match insertion_node_next {
            Some(next_handle) => {
                self.events.borrow_mut()[next_handle.0].prev = Some(event_handle);
                self.events.borrow_mut()[event_handle.0].next = Some(next_handle);
            }
            None => {
            }
        }

        self.events.borrow_mut()[event_handle.0].prev = Some(self.depth_first_insertion_point.get());
        self.events.borrow_mut()[self.depth_first_insertion_point.get().0].next = Some(event_handle);
        self.depth_first_insertion_point.set(event_handle);
    }

    fn arm_breadth_first(&self, event_handle: private::EventHandle) {
        let events = &mut *self.events.borrow_mut();
        events[self.tail.get().0].next = Some(event_handle);
        events[event_handle.0].prev = Some(self.tail.get());
        self.tail.set(event_handle);
    }

    /// Runs the event loop for `max_turn_count` turns or until there is nothing left to be done,
    /// whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will
    /// call the `EventPort`'s `set_runnable(false)` if the queue becomes empty.
    pub fn run(&mut self, max_turn_count : u32) {
        self.running = true;

        for _ in 0..max_turn_count {
            if !self.turn() {
                break;
            }
        }
    }

    fn turn(&self) -> bool {

        let mut event_handle = match self.events.borrow()[self.head.get().0].next {
            None => return false,
            Some(event_handle) => { event_handle }
        };
        self.depth_first_insertion_point.set(event_handle);

        // When we're firing, head is the dummy event, as always. head.next is the firing event.
        // depth-first-insertion-point starts out as the firing event.
        // tail is the last event in the queue. If there are no further events,
        // tail is the firing event.

        let mut event = ::std::mem::replace(&mut self.events.borrow_mut()[event_handle.0].event, None)
            .expect("No event to fire?");
        event.fire();

        let event_node = self.events.borrow_mut().remove(event_handle.0).unwrap();

        // event_node.next.prev = event_node.prev
        match event_node.next {
            Some(e) => {
                self.events.borrow_mut()[e.0].prev = event_node.prev;
            }
            None => {}
        }

        // event_node.prev.next = event_node.next
        match event_node.prev {
            Some(e) => {
                self.events.borrow_mut()[e.0].next = event_node.next;
            }
            None => {}
        }

        if self.tail.get() == event_handle {
            self.tail.set(self.head.get());
        }
        return true;
    }
}

/// A callback which can be used to fulfill a promise.
pub trait PromiseFulfiller<T> where T: 'static {
    fn fulfill(self: Box<Self>, value: T);
    fn reject(self: Box<Self>, error: Error);
}

pub fn new_promise_and_fulfiller<T>() -> (Promise<T>, Box<PromiseFulfiller<T>>) where T: 'static {
    let result = ::std::rc::Rc::new(::std::cell::RefCell::new(PromiseAndFulfillerHub::new()));
    let result_promise : Promise<T> = Promise { node: Box::new(result.clone())};
    (result_promise, Box::new(result))
}

/// Holds a collection of Promise<()>s and ensures that each executes to comleteion.
/// Destroying a TaskSet automatically cancels all of its unfinished promises.
pub struct TaskSet {
    task_set_impl: Rc<RefCell<private::TaskSetImpl>>,
}

impl TaskSet {
    pub fn new(error_handler: Box<ErrorHandler>) -> TaskSet {
        TaskSet { task_set_impl : Rc::new(RefCell::new(private::TaskSetImpl::new(error_handler))) }
    }

    pub fn add(&mut self, promise: Promise<()>) {
        private::TaskSetImpl::add(self.task_set_impl.clone(), promise.node);
    }
}

pub trait ErrorHandler {
    fn task_failed(&mut self, error: Error);
}

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

extern crate mio;

use std::cell::{Cell, RefCell};
use std::rc::Rc;
use private::{promise_node, Event, BoolEvent, PromiseAndFulfillerHub,
              EVENT_LOOP, with_current_event_loop, PromiseNode};

pub mod io;

mod private;
mod handle_table;

pub type Error = Box<::std::error::Error>;
pub type Result<T> = ::std::result::Result<T, Error>;

/// The basic primitive of asynchronous computation in GJ.
pub struct Promise<T> where T: 'static {
    node : Box<PromiseNode<T>>,
}

impl <T> Promise <T> where T: 'static {
    pub fn then<F, R>(self, func: F) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<Promise<R>>,
              R: 'static {
                  self.then_else(func, |e| { return Err(e); })
        }

    pub fn then_else<F, G, R>(self, func: F, error_handler: G) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<Promise<R>>,
              G: 'static + FnOnce(Error) -> Result<Promise<R>>,
              R: 'static {
            let intermediate = Box::new(promise_node::Transform::new(self.node, func, error_handler));
            Promise { node: Box::new(promise_node::Chain::new(intermediate)) }
        }

    pub fn map<F, R>(self, func: F) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<R>,
              R: 'static {
            self.map_else(func, |e| { return Err(e); })
        }

    pub fn map_else<F, G, R>(self, func: F, error_handler: G) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<R>,
              G: 'static + FnOnce(Error) -> Result<R>,
              R: 'static {
            Promise { node: Box::new(promise_node::Transform::new(self.node, func, error_handler)) }
        }

    /// Runs the event loop until the promise is fulfilled.
    ///
    /// The `WaitScope` argument ensures that `wait()` can only be called the top level of a program.
    /// Waiting within event callbacks is disallowed.
    pub fn wait(mut self, _wait_scope: &WaitScope) -> Result<T> {
        with_current_event_loop(move |event_loop| {
            let fired = ::std::rc::Rc::new(::std::cell::Cell::new(false));
            let done_event = BoolEvent::new(fired.clone());
            let (handle, dropper) = private::EventHandle::new(Box::new(done_event));
            self.node.on_ready(handle);

            //event_loop.running = true;

            while !fired.get() {
                if !event_loop.turn() {
                    // No events in the queue.
                    event_loop.event_port.borrow_mut().wait();
                }
            }

            self.node.get()
        })
    }

    pub fn fulfilled(value: T) -> Promise<T> {
        return Promise { node: Box::new(promise_node::Immediate::new(Ok(value))) };
    }

    pub fn rejected(error: Error) -> Promise<T> {
        return Promise { node: Box::new(promise_node::Immediate::new(Err(error))) };
    }
}

pub struct WaitScope(::std::marker::PhantomData<*mut u8>); // impl !Sync for WaitScope {}

/// Interface between an `EventLoop` and events originating from outside of the loop's thread.
pub trait EventPort {
    /// Waits for an external event to arrive, sleeping if necessary.
    /// Returns true if wake() has been called from another thread.
    fn wait(&mut self) -> bool;

    /// Checks whether any external events have arrived, but does not sleep.
    /// Returns true if wake() has been called from another thread.
    fn poll(&mut self) -> bool;

    /// Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it
    /// transitions from empty -> runnable or runnable -> empty. This is typically useful when
    /// intergrating with an external event loop; if the loop is currently runnable then you should
    /// arrange to call run() on it soon. The default implementation does nothing.
    fn set_runnable(&mut self, _runnable: bool) { }

    fn wake(&mut self) { unimplemented!(); }
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
//    daemons: TaskSetImpl,
    event_port: RefCell<io::MioEventPort>,
    running: bool,
    _last_runnable_state: bool,
    events: RefCell<handle_table::HandleTable<private::EventNode>>,
    head: Cell<private::EventHandle>,
    tail: Cell<private::EventHandle>,
    depth_first_insertion_point: Cell<private::EventHandle>,
}

impl EventLoop {
    pub fn top_level<F>(f: F) where F: FnOnce(&WaitScope) {
        let mut events = handle_table::HandleTable::<private::EventNode>::new();
        let dummy = private::EventNode { event: None, next: None, prev: None };
        let head_handle = private::EventHandle(events.push(dummy));

        EVENT_LOOP.with(move |maybe_event_loop| {
            let event_loop = EventLoop {
                event_port: RefCell::new(io::MioEventPort::new().unwrap()),
                running: false,
                _last_runnable_state: false,
                events: RefCell::new(events),
                head: Cell::new(head_handle),
                tail: Cell::new(head_handle),
                depth_first_insertion_point: Cell::new(head_handle), // insert after this node
            };

            assert!(maybe_event_loop.borrow().is_none());
            *maybe_event_loop.borrow_mut() = Some(event_loop);
        });
        let wait_scope = WaitScope(::std::marker::PhantomData );
        f(&wait_scope);
    }

    fn arm_depth_first(&self, event_handle: private::EventHandle) {

        let insertion_node_next = self.events.borrow()[self.depth_first_insertion_point.get().0].next;

        match insertion_node_next {
            Some(next_handle) => {
                self.events.borrow_mut()[next_handle.0].prev = Some(event_handle);
                self.events.borrow_mut()[event_handle.0].next = Some(next_handle);
            }
            None => {
                self.tail.set(event_handle);
            }
        }

        self.events.borrow_mut()[event_handle.0].prev = Some(self.depth_first_insertion_point.get());
        self.events.borrow_mut()[self.depth_first_insertion_point.get().0].next = Some(event_handle);
        self.depth_first_insertion_point.set(event_handle);
    }

    fn arm_breadth_first(&self, event_handle: private::EventHandle) {
        let events = &mut *self.events.borrow_mut();
        events[self.tail.get().0].next = Some(event_handle);
        events[event_handle.0].prev = Some(self.tail.get());
        self.tail.set(event_handle);
    }

    /// Runs the event loop for `max_turn_count` turns or until there is nothing left to be done,
    /// whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will
    /// call the `EventPort`'s `set_runnable(false)` if the queue becomes empty.
    pub fn run(&mut self, max_turn_count : u32) {
        self.running = true;

        for _ in 0..max_turn_count {
            if !self.turn() {
                break;
            }
        }
    }

    fn turn(&self) -> bool {

        let mut event_handle = match self.events.borrow()[self.head.get().0].next {
            None => return false,
            Some(event_handle) => { event_handle }
        };
        self.depth_first_insertion_point.set(event_handle);

        // When we're firing, head is the dummy event, as always. head.next is the firing event.
        // depth-first-insertion-point starts out as the firing event.
        // tail is the last event in the queue. If there are no further events,
        // tail is the firing event.

        let mut event = ::std::mem::replace(&mut self.events.borrow_mut()[event_handle.0].event, None)
            .expect("No event to fire?");
        event.fire();

        let event_node = self.events.borrow_mut().remove(event_handle.0).unwrap();

        // event_node.next.prev = event_node.prev
        match event_node.next {
            Some(e) => {
                self.events.borrow_mut()[e.0].prev = event_node.prev;
            }
            None => {}
        }

        // event_node.prev.next = event_node.next
        match event_node.prev {
            Some(e) => {
                self.events.borrow_mut()[e.0].next = event_node.next;
            }
            None => {}
        }

        if self.tail.get() == event_handle {
            self.tail.set(self.head.get());
        }
        return true;
    }
}

/// A callback which can be used to fulfill a promise.
pub trait PromiseFulfiller<T> where T: 'static {
    fn fulfill(self: Box<Self>, value: T);
    fn reject(self: Box<Self>, error: Error);
}

pub fn new_promise_and_fulfiller<T>() -> (Promise<T>, Box<PromiseFulfiller<T>>) where T: 'static {
    let result = ::std::rc::Rc::new(::std::cell::RefCell::new(PromiseAndFulfillerHub::new()));
    let result_promise : Promise<T> = Promise { node: Box::new(result.clone())};
    (result_promise, Box::new(result))
}

/// Holds a collection of Promise<()>s and ensures that each executes to comleteion.
/// Destroying a TaskSet automatically cancels all of its unfinished promises.
pub struct TaskSet {
    task_set_impl: Rc<RefCell<private::TaskSetImpl>>,
}

impl TaskSet {
    pub fn new(error_handler: Box<ErrorHandler>) -> TaskSet {
        TaskSet { task_set_impl : Rc::new(RefCell::new(private::TaskSetImpl::new(error_handler))) }
    }

    pub fn add(&mut self, promise: Promise<()>) {
        private::TaskSetImpl::add(self.task_set_impl.clone(), promise.node);
    }
}

pub trait ErrorHandler {
    fn task_failed(&mut self, error: Error);
}

<|endoftext|>