<commit_before>use cli::{clear_screen, Args};
use env_logger;
use error::Result;
use gitignore;
use log;
use notification_filter::NotificationFilter;
#[cfg(target_os = "linux")]
use notify;
use pathop::PathOp;
use process::{self, Process};
use signal::{self, Signal};
use std::{
    collections::HashMap,
    io::Write,
    sync::{
        mpsc::{channel, Receiver},
        Arc, RwLock,
    },
    time::Duration,
};
use watcher::{Event, Watcher};

fn init_logger(debug: bool) {
    let mut log_builder = env_logger::Builder::new();
    let level = if debug {
        log::LevelFilter::Debug
    } else {
        log::LevelFilter::Warn
    };

    log_builder
        .format(|buf, r| writeln!(buf, "*** {}", r.args()))
        .filter(None, level)
        .init();
}

pub trait Handler {
    /// Initialises the `Handler` with a copy of the arguments.
    fn new(args: Args) -> Result<Self>
    where
        Self: Sized;

    /// Called through a manual request, such as an initial run.
    ///
    /// # Returns
    ///
    /// A `Result` which means:
    ///
    /// - `Err`: an error has occurred while processing, quit.
    /// - `Ok(true)`: everything is fine and the loop can continue.
    /// - `Ok(false)`: everything is fine but we should gracefully stop.
    fn on_manual(&mut self) -> Result<bool>;

    /// Called through a file-update request.
    ///
    /// # Parameters
    ///
    /// - `ops`: The list of events that triggered this update.
    ///
    /// # Returns
    ///
    /// A `Result` which means:
    ///
    /// - `Err`: an error has occurred while processing, quit.
    /// - `Ok(true)`: everything is fine and the loop can continue.
    /// - `Ok(false)`: everything is fine but we should gracefully stop.
    fn on_update(&mut self, ops: &[PathOp]) -> Result<bool>;
}

/// Starts watching, and calls a handler when something happens.
///
/// Given an argument structure and a `Handler` type, starts the watcher
/// loop (blocking until done).
pub fn watch<H>(args: Args) -> Result<()>
where
    H: Handler,
{
    init_logger(args.debug);
    let mut handler = H::new(args.clone())?;

    let gitignore = gitignore::load(if args.no_vcs_ignore { &[] } else { &args.paths });
    let filter = NotificationFilter::new(&args.filters, &args.ignores, gitignore)?;

    let (tx, rx) = channel();
    let poll = args.poll.clone();
    #[cfg(target_os = "linux")]
    let poll_interval = args.poll_interval.clone();
    let watcher = Watcher::new(tx.clone(), &args.paths, args.poll, args.poll_interval).or_else(|err| {
        if poll {
            return Err(err);
        }

        #[cfg(target_os = "linux")]
        {
            use nix::libc;
            let mut fallback = false;
            if let notify::Error::Io(ref e) = err {
                if e.raw_os_error() == Some(libc::ENOSPC) {
                    warn!("System notification limit is too small, falling back to polling mode. For better performance increase system limit:\n\tsysctl fs.inotify.max_user_watches=524288");
                    fallback = true;
                }
            }

            if fallback {
                return Watcher::new(tx, &args.paths, true, poll_interval);
            }
        }

        Err(err)
    })?;

    if watcher.is_polling() {
        warn!("Polling for changes every {} ms", args.poll_interval);
    }

    // Call handler initially, if necessary
    if args.run_initially && !args.once {
        if !handler.on_manual()? {
            return Ok(());
        }
    }

    loop {
        debug!("Waiting for filesystem activity");
        let paths = wait_fs(&rx, &filter, args.debounce);
        debug!("Paths updated: {:?}", paths);

        if !handler.on_update(&paths)? {
            break;
        }
    }

    Ok(())
}

pub struct ExecHandler {
    args: Args,
    signal: Option<Signal>,
    child_process: Arc<RwLock<Option<Process>>>,
}

impl ExecHandler {
    fn spawn(&mut self, ops: &[PathOp]) -> Result<()> {
        if self.args.clear_screen {
            clear_screen();
        }

        debug!("Launching child process");
        let mut guard = self.child_process.write()?;
        *guard = Some(process::spawn(&self.args.cmd, ops, self.args.no_shell)?);

        Ok(())
    }
}

impl Handler for ExecHandler {
    fn new(args: Args) -> Result<Self> {
        let child_process: Arc<RwLock<Option<Process>>> = Arc::new(RwLock::new(None));
        let weak_child = Arc::downgrade(&child_process);

        // Convert signal string to the corresponding integer
        let signal = signal::new(args.signal.clone());

        signal::install_handler(move |sig: Signal| {
            if let Some(lock) = weak_child.upgrade() {
                let strong = lock.read().unwrap();
                if let Some(ref child) = *strong {
                    match sig {
                        Signal::SIGCHLD => child.reap(), // SIGCHLD is special, initiate reap()
                        _ => child.signal(sig),
                    }
                }
            }
        });

        Ok(Self {
            args,
            signal,
            child_process,
        })
    }

    // Only returns Err() on lock poisoning.
    fn on_manual(&mut self) -> Result<bool> {
        let cls = self.args.clear_screen;
        self.args.clear_screen = false;
        self.spawn(&[])?;
        self.args.clear_screen = cls;
        Ok(true)
    }

    // Only returns Err() on lock poisoning.
    fn on_update(&mut self, ops: &[PathOp]) -> Result<bool> {
        // We have four scenarios here:
        //
        // 1. Send a specified signal to the child, wait for it to exit, then run the command again
        // 2. Send SIGTERM to the child, wait for it to exit, then run the command again
        // 3. Just send a specified signal to the child, do nothing more
        // 4. Make sure the previous run was ended, then run the command again
        //
        let scenario = (self.args.restart, self.signal.is_some());

        match scenario {
            // Custom restart behaviour (--restart was given, and --signal specified):
            // Send specified signal to the child, wait for it to exit, then run the command again
            (true, true) => {
                signal_process(&self.child_process, self.signal, true);
                self.spawn(ops)?;
            }

            // Default restart behaviour (--restart was given, but --signal wasn't specified):
            // Send SIGTERM to the child, wait for it to exit, then run the command again
            (true, false) => {
                let sigterm = signal::new(Some("SIGTERM".into()));
                signal_process(&self.child_process, sigterm, true);
                self.spawn(ops)?;
            }

            // SIGHUP scenario: --signal was given, but --restart was not
            // Just send a signal (e.g. SIGHUP) to the child, do nothing more
            (false, true) => signal_process(&self.child_process, self.signal, false),

            // Default behaviour (neither --signal nor --restart specified):
            // Make sure the previous run was ended, then run the command again
            (false, false) => {
                signal_process(&self.child_process, None, true);
                self.spawn(ops)?;
            }
        }

        // Handle once option for integration testing
        if self.args.once {
            signal_process(&self.child_process, self.signal, false);
            return Ok(false);
        }

        Ok(true)
    }
}

pub fn run(args: Args) -> Result<()> {
    watch::<ExecHandler>(args)
}

fn wait_fs(rx: &Receiver<Event>, filter: &NotificationFilter, debounce: u64) -> Vec<PathOp> {
    let mut paths = Vec::new();
    let mut cache = HashMap::new();

    loop {
        let e = rx.recv().expect("error when reading event");

        if let Some(ref path) = e.path {
            let pathop = PathOp::new(path, e.op.ok(), e.cookie);
            // Ignore cache for the initial file. Otherwise, in
            // debug mode it's hard to track what's going on
            let excluded = filter.is_excluded(path);
            if !cache.contains_key(&pathop) {
                cache.insert(pathop.clone(), excluded);
            }

            if !excluded {
                paths.push(pathop);
                break;
            }
        }
    }

    // Wait for filesystem activity to cool off
    let timeout = Duration::from_millis(debounce);
    while let Ok(e) = rx.recv_timeout(timeout) {
        if let Some(ref path) = e.path {
            let pathop = PathOp::new(path, e.op.ok(), e.cookie);
            if cache.contains_key(&pathop) {
                continue;
            }

            let excluded = filter.is_excluded(path);

            cache.insert(pathop.clone(), excluded);

            if !excluded {
                paths.push(pathop);
            }
        }
    }

    paths
}

// signal_process sends signal to process. It waits for the process to exit if wait is true
fn signal_process(process: &RwLock<Option<Process>>, signal: Option<Signal>, wait: bool) {
    let guard = process.read().unwrap();

    if let Some(ref child) = *guard {
        if let Some(s) = signal {
            child.signal(s);
        }

        if wait {
            debug!("Waiting for process to exit...");
            child.wait();
        }
    }
}
<commit_msg>[run] Move "once" logic to be entirely within handler<commit_after>use cli::{clear_screen, Args};
use env_logger;
use error::Result;
use gitignore;
use log;
use notification_filter::NotificationFilter;
#[cfg(target_os = "linux")]
use notify;
use pathop::PathOp;
use process::{self, Process};
use signal::{self, Signal};
use std::{
    collections::HashMap,
    io::Write,
    sync::{
        mpsc::{channel, Receiver},
        Arc, RwLock,
    },
    time::Duration,
};
use watcher::{Event, Watcher};

fn init_logger(debug: bool) {
    let mut log_builder = env_logger::Builder::new();
    let level = if debug {
        log::LevelFilter::Debug
    } else {
        log::LevelFilter::Warn
    };

    log_builder
        .format(|buf, r| writeln!(buf, "*** {}", r.args()))
        .filter(None, level)
        .init();
}

pub trait Handler {
    /// Initialises the `Handler` with a copy of the arguments.
    fn new(args: Args) -> Result<Self>
    where
        Self: Sized;

    /// Called through a manual request, such as an initial run.
    ///
    /// # Returns
    ///
    /// A `Result` which means:
    ///
    /// - `Err`: an error has occurred while processing, quit.
    /// - `Ok(true)`: everything is fine and the loop can continue.
    /// - `Ok(false)`: everything is fine but we should gracefully stop.
    fn on_manual(&mut self) -> Result<bool>;

    /// Called through a file-update request.
    ///
    /// # Parameters
    ///
    /// - `ops`: The list of events that triggered this update.
    ///
    /// # Returns
    ///
    /// A `Result` which means:
    ///
    /// - `Err`: an error has occurred while processing, quit.
    /// - `Ok(true)`: everything is fine and the loop can continue.
    /// - `Ok(false)`: everything is fine but we should gracefully stop.
    fn on_update(&mut self, ops: &[PathOp]) -> Result<bool>;
}

/// Starts watching, and calls a handler when something happens.
///
/// Given an argument structure and a `Handler` type, starts the watcher
/// loop (blocking until done).
pub fn watch<H>(args: Args) -> Result<()>
where
    H: Handler,
{
    init_logger(args.debug);
    let mut handler = H::new(args.clone())?;

    let gitignore = gitignore::load(if args.no_vcs_ignore { &[] } else { &args.paths });
    let filter = NotificationFilter::new(&args.filters, &args.ignores, gitignore)?;

    let (tx, rx) = channel();
    let poll = args.poll.clone();
    #[cfg(target_os = "linux")]
    let poll_interval = args.poll_interval.clone();
    let watcher = Watcher::new(tx.clone(), &args.paths, args.poll, args.poll_interval).or_else(|err| {
        if poll {
            return Err(err);
        }

        #[cfg(target_os = "linux")]
        {
            use nix::libc;
            let mut fallback = false;
            if let notify::Error::Io(ref e) = err {
                if e.raw_os_error() == Some(libc::ENOSPC) {
                    warn!("System notification limit is too small, falling back to polling mode. For better performance increase system limit:\n\tsysctl fs.inotify.max_user_watches=524288");
                    fallback = true;
                }
            }

            if fallback {
                return Watcher::new(tx, &args.paths, true, poll_interval);
            }
        }

        Err(err)
    })?;

    if watcher.is_polling() {
        warn!("Polling for changes every {} ms", args.poll_interval);
    }

    // Call handler initially, if necessary
    if args.run_initially {
        if !handler.on_manual()? {
            return Ok(());
        }
    }

    loop {
        debug!("Waiting for filesystem activity");
        let paths = wait_fs(&rx, &filter, args.debounce);
        debug!("Paths updated: {:?}", paths);

        if !handler.on_update(&paths)? {
            break;
        }
    }

    Ok(())
}

pub struct ExecHandler {
    args: Args,
    signal: Option<Signal>,
    child_process: Arc<RwLock<Option<Process>>>,
}

impl ExecHandler {
    fn spawn(&mut self, ops: &[PathOp]) -> Result<()> {
        if self.args.clear_screen {
            clear_screen();
        }

        debug!("Launching child process");
        let mut guard = self.child_process.write()?;
        *guard = Some(process::spawn(&self.args.cmd, ops, self.args.no_shell)?);

        Ok(())
    }
}

impl Handler for ExecHandler {
    fn new(args: Args) -> Result<Self> {
        let child_process: Arc<RwLock<Option<Process>>> = Arc::new(RwLock::new(None));
        let weak_child = Arc::downgrade(&child_process);

        // Convert signal string to the corresponding integer
        let signal = signal::new(args.signal.clone());

        signal::install_handler(move |sig: Signal| {
            if let Some(lock) = weak_child.upgrade() {
                let strong = lock.read().unwrap();
                if let Some(ref child) = *strong {
                    match sig {
                        Signal::SIGCHLD => child.reap(), // SIGCHLD is special, initiate reap()
                        _ => child.signal(sig),
                    }
                }
            }
        });

        Ok(Self {
            args,
            signal,
            child_process,
        })
    }

    // Only returns Err() on lock poisoning.
    fn on_manual(&mut self) -> Result<bool> {
        if self.args.once {
            return Ok(true);
        }

        let cls = self.args.clear_screen;
        self.args.clear_screen = false;
        self.spawn(&[])?;
        self.args.clear_screen = cls;
        Ok(true)
    }

    // Only returns Err() on lock poisoning.
    fn on_update(&mut self, ops: &[PathOp]) -> Result<bool> {
        // We have four scenarios here:
        //
        // 1. Send a specified signal to the child, wait for it to exit, then run the command again
        // 2. Send SIGTERM to the child, wait for it to exit, then run the command again
        // 3. Just send a specified signal to the child, do nothing more
        // 4. Make sure the previous run was ended, then run the command again
        //
        let scenario = (self.args.restart, self.signal.is_some());

        match scenario {
            // Custom restart behaviour (--restart was given, and --signal specified):
            // Send specified signal to the child, wait for it to exit, then run the command again
            (true, true) => {
                signal_process(&self.child_process, self.signal, true);
                self.spawn(ops)?;
            }

            // Default restart behaviour (--restart was given, but --signal wasn't specified):
            // Send SIGTERM to the child, wait for it to exit, then run the command again
            (true, false) => {
                let sigterm = signal::new(Some("SIGTERM".into()));
                signal_process(&self.child_process, sigterm, true);
                self.spawn(ops)?;
            }

            // SIGHUP scenario: --signal was given, but --restart was not
            // Just send a signal (e.g. SIGHUP) to the child, do nothing more
            (false, true) => signal_process(&self.child_process, self.signal, false),

            // Default behaviour (neither --signal nor --restart specified):
            // Make sure the previous run was ended, then run the command again
            (false, false) => {
                signal_process(&self.child_process, None, true);
                self.spawn(ops)?;
            }
        }

        // Handle once option for integration testing
        if self.args.once {
            signal_process(&self.child_process, self.signal, false);
            return Ok(false);
        }

        Ok(true)
    }
}

pub fn run(args: Args) -> Result<()> {
    watch::<ExecHandler>(args)
}

fn wait_fs(rx: &Receiver<Event>, filter: &NotificationFilter, debounce: u64) -> Vec<PathOp> {
    let mut paths = Vec::new();
    let mut cache = HashMap::new();

    loop {
        let e = rx.recv().expect("error when reading event");

        if let Some(ref path) = e.path {
            let pathop = PathOp::new(path, e.op.ok(), e.cookie);
            // Ignore cache for the initial file. Otherwise, in
            // debug mode it's hard to track what's going on
            let excluded = filter.is_excluded(path);
            if !cache.contains_key(&pathop) {
                cache.insert(pathop.clone(), excluded);
            }

            if !excluded {
                paths.push(pathop);
                break;
            }
        }
    }

    // Wait for filesystem activity to cool off
    let timeout = Duration::from_millis(debounce);
    while let Ok(e) = rx.recv_timeout(timeout) {
        if let Some(ref path) = e.path {
            let pathop = PathOp::new(path, e.op.ok(), e.cookie);
            if cache.contains_key(&pathop) {
                continue;
            }

            let excluded = filter.is_excluded(path);

            cache.insert(pathop.clone(), excluded);

            if !excluded {
                paths.push(pathop);
            }
        }
    }

    paths
}

// signal_process sends signal to process. It waits for the process to exit if wait is true
fn signal_process(process: &RwLock<Option<Process>>, signal: Option<Signal>, wait: bool) {
    let guard = process.read().unwrap();

    if let Some(ref child) = *guard {
        if let Some(s) = signal {
            child.signal(s);
        }

        if wait {
            debug!("Waiting for process to exit...");
            child.wait();
        }
    }
}
<|endoftext|>


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

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level
//!
//! ### Examples
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```

extern crate log;

use log::{LogLevelFilter, LogMetadata};
use std::io::Write;

#[derive(Clone, Copy, Debug)]
pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= log::max_log_level()
    }

    fn log(&self, record: &log::LogRecord) {
        if self.enabled(record.metadata()) {
            writeln!(&mut ::std::io::stderr(),
                     "{} - {}",
                     record.level(),
                     record.args())
                .unwrap();
        }
    }
}

impl StdErrLog {
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    pub fn init(&self) -> Result<(), log::SetLoggerError> {

        log::set_logger(|max_log_level| {
            if self.quiet {
                max_log_level.set(LogLevelFilter::Off);
            } else {
                max_log_level.set(self.verbosity);
            }

            Box::new(self.clone())
        })
    }
}

pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<commit_msg>don't unwrap() writeln!()<commit_after>// Copyright 2016 Doug Goldstein
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level
//!
//! ### Examples
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```

extern crate log;

use log::{LogLevelFilter, LogMetadata};
use std::io::Write;

#[derive(Clone, Copy, Debug)]
pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= log::max_log_level()
    }

    fn log(&self, record: &log::LogRecord) {
        if self.enabled(record.metadata()) {
            let _ = writeln!(&mut ::std::io::stderr(),
                             "{} - {}",
                             record.level(),
                             record.args());
        }
    }
}

impl StdErrLog {
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    pub fn init(&self) -> Result<(), log::SetLoggerError> {

        log::set_logger(|max_log_level| {
            if self.quiet {
                max_log_level.set(LogLevelFilter::Off);
            } else {
                max_log_level.set(self.verbosity);
            }

            Box::new(self.clone())
        })
    }
}

pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::error;
use std::fmt;
use std::ffi::CString;
use libc::types::os::arch::c95::{c_char, time_t};

// C function definitions
#[link(name = "raw")]
extern {
    fn libraw_init(flags: u32) -> *mut LibrawData;
    fn libraw_open_file(imgdat: *mut LibrawData, fpath: *const libc::c_char) -> i32;
    fn libraw_open_buffer(imgdat: *mut LibrawData, buffer: &[u8], bufsize: libc::size_t) -> i32;
    fn libraw_unpack(imgdat: *mut LibrawData) -> i32;
    fn libraw_unpack_thumb(imgdat: *mut LibrawData) -> i32;
}

// C struct definitions
#[repr(C)]
pub struct LibrawData {
    image: [*mut u16; 4],
    sizes: LibrawImageSizes,
    idata: LibrawIparams,
    progress_flags: u32,
    process_warnings: u32,
    color: LibrawColorData,
    other: LibrawImgOther,
    thumbnail: LibrawThumb,
    rawdata: LibrawRawData,
    parent_class: *mut libc::c_void,
}

#[repr(C)]
struct LibrawImageSizes {
    raw_height: u16,
    raw_width: u16,
    height: u16,
    width: u16,
    top_margin: u16,
    left_margin: u16,
    iheight: u16,
    iwidth: u16,
    raw_pitch: u32,
    pixel_aspect: f64,
    flip: i32,
    mask: [[u32; 8]; 4],
}

#[repr(C)]
struct LibrawIparams {
    make: [c_char; 64],
    model: [c_char; 64],
    raw_count: u32,
    dng_version: u32,
    is_foveon: u32,
    colors: i32,
    filters: u32,
    xtrans: [[c_char; 6]; 6],
    cdesc: [c_char; 5],
}

#[repr(C)]
struct LibrawColorData {
    make: [c_char; 64],
    model: [c_char; 64],
    raw_count: u32,
    dng_version: u32,
    is_foveon: u32,
    colors: i32,
    filters: u32,
    xtrans: [[c_char; 6]; 6],
    cdesc: [c_char; 5],
    phase_one_data: LibrawPh1,
    flash_used: f32,
    canon_ev: f32,
    model2: [c_char; 64],
    profile: *mut libc::c_void,
    profile_length: u32,
    black_stat: [u32; 8],
}

#[repr(C)]
struct LibrawPh1 {
    format: i32,
    key_off: i32,
    t_black: i32,
    black_off: i32,
    split_col: i32,
    tag_21a: i32,
    tag_210: f32,
}

#[repr(C)]
struct LibrawImgOther {
    iso_speed: f32,
    shutter: f32,
    aperture: f32,
    focal_len: f32,
    timestamp: time_t,
    shot_order: u32,
    gpsdata: [u32; 32],
    desc: [c_char; 512],
    artist: [c_char; 64],
}

#[repr(C)]
struct LibrawThumb {
    tformat: LibrawThumbnailFormat,
    twidth: u16,
    theight: u16,
    tlength: u32,
    tcolors: i32,
    thumb: *mut c_char,
}

#[repr(C)]
struct LibrawRawData {
    raw_alloc: *mut libc::c_void,
    raw_image: *mut u16,
    color4_image: [*mut u16; 4],
    color3_image: [*mut u16; 3],
    ph1_black: [*mut i16; 2],
    iparams: LibrawIparams,
    sizes: LibrawImageSizes,
    ioparams: LibrawInternalOutputParams,
    color: LibrawColorData,
}

#[repr(C)]
struct LibrawInternalOutputParams {
    mix_green: u32,
    raw_color: u32,
    zero_is_bad: u32,
    shrink: u16,
    fuji_width: u16,
}

// C enum definitions
#[repr(C)]
enum LibrawThumbnailFormat {
    Unknown = 0,
    Jpeg = 1,
    Bitmap = 2,
    Layer = 4,
    Rollei = 5,
}

// Errors
pub enum LibrawError {
    NulError(std::ffi::NulError),
    AllocError(LibrawAllocError),
    IOError(std::io::Error),
    LibError(LibrawLibraryError),
}

#[derive(Debug)]
pub struct LibrawAllocError;

impl fmt::Display for LibrawAllocError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "image data allocation failed".fmt(f)
    }
}

impl error::Error for LibrawAllocError {
    fn description(&self) -> &str {
        "image data allocation failed"
    }
}

#[derive(Debug)]
pub struct LibrawLibraryError;

impl fmt::Display for LibrawLibraryError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "internal libraw library error".fmt(f)
    }
}

impl error::Error for LibrawLibraryError {
    fn description(&self) -> &str {
        "internal libraw library error"
    }
}

// Higher-level unsafe methods
unsafe fn init_data() -> Result<*mut LibrawData, LibrawError> {
    // 0 = no flags
    // 1 = no memory error callback
    // 2 = non data error callback
    // 3 = both
    let data = libraw_init(3);
    if data.is_null() {
        Err(LibrawError::AllocError(LibrawAllocError))
    } else {
        Ok(data)
    }
}

unsafe fn read_img(filepath: &str) -> Result<*mut LibrawData, LibrawError> {
    let fpath = match CString::new(filepath) {
        Ok(v) => v,
        Err(e) => return Err(LibrawError::NulError(e)),
    };
    let data = try!(init_data());
    let res: i32 = libraw_open_file(data, fpath.as_ptr());
    if res > 0 {
        Err(LibrawError::IOError(std::io::Error::from_raw_os_error(res)))
    } else if res < 0 {
        Err(LibrawError::LibError(LibrawLibraryError))
    } else {
        Ok(data)
    }
}
<commit_msg>Add safe public method for loading raw file<commit_after>extern crate libc;

use std::error;
use std::fmt;
use std::path;
use std::ffi::CString;
use std::marker::PhantomData;
use libc::types::os::arch::c95::{c_char, time_t};

// C function definitions
#[link(name = "raw")]
extern {
    fn libraw_init(flags: u32) -> *mut LibrawData;
    fn libraw_open_file(imgdat: *mut LibrawData, fpath: *const libc::c_char) -> i32;
    fn libraw_open_buffer(imgdat: *mut LibrawData, buffer: &[u8], bufsize: libc::size_t) -> i32;
    fn libraw_unpack(imgdat: *mut LibrawData) -> i32;
    fn libraw_unpack_thumb(imgdat: *mut LibrawData) -> i32;
}

// C struct definitions
#[repr(C)]
pub struct LibrawData {
    image: [*mut u16; 4],
    sizes: LibrawImageSizes,
    idata: LibrawIparams,
    progress_flags: u32,
    process_warnings: u32,
    color: LibrawColorData,
    other: LibrawImgOther,
    thumbnail: LibrawThumb,
    rawdata: LibrawRawData,
    parent_class: *mut libc::c_void,
}

#[repr(C)]
struct LibrawImageSizes {
    raw_height: u16,
    raw_width: u16,
    height: u16,
    width: u16,
    top_margin: u16,
    left_margin: u16,
    iheight: u16,
    iwidth: u16,
    raw_pitch: u32,
    pixel_aspect: f64,
    flip: i32,
    mask: [[u32; 8]; 4],
}

#[repr(C)]
struct LibrawIparams {
    make: [c_char; 64],
    model: [c_char; 64],
    raw_count: u32,
    dng_version: u32,
    is_foveon: u32,
    colors: i32,
    filters: u32,
    xtrans: [[c_char; 6]; 6],
    cdesc: [c_char; 5],
}

#[repr(C)]
struct LibrawColorData {
    make: [c_char; 64],
    model: [c_char; 64],
    raw_count: u32,
    dng_version: u32,
    is_foveon: u32,
    colors: i32,
    filters: u32,
    xtrans: [[c_char; 6]; 6],
    cdesc: [c_char; 5],
    phase_one_data: LibrawPh1,
    flash_used: f32,
    canon_ev: f32,
    model2: [c_char; 64],
    profile: *mut libc::c_void,
    profile_length: u32,
    black_stat: [u32; 8],
}

#[repr(C)]
struct LibrawPh1 {
    format: i32,
    key_off: i32,
    t_black: i32,
    black_off: i32,
    split_col: i32,
    tag_21a: i32,
    tag_210: f32,
}

#[repr(C)]
struct LibrawImgOther {
    iso_speed: f32,
    shutter: f32,
    aperture: f32,
    focal_len: f32,
    timestamp: time_t,
    shot_order: u32,
    gpsdata: [u32; 32],
    desc: [c_char; 512],
    artist: [c_char; 64],
}

#[repr(C)]
struct LibrawThumb {
    tformat: LibrawThumbnailFormat,
    twidth: u16,
    theight: u16,
    tlength: u32,
    tcolors: i32,
    thumb: *mut c_char,
}

#[repr(C)]
struct LibrawRawData {
    raw_alloc: *mut libc::c_void,
    raw_image: *mut u16,
    color4_image: [*mut u16; 4],
    color3_image: [*mut u16; 3],
    ph1_black: [*mut i16; 2],
    iparams: LibrawIparams,
    sizes: LibrawImageSizes,
    ioparams: LibrawInternalOutputParams,
    color: LibrawColorData,
}

#[repr(C)]
struct LibrawInternalOutputParams {
    mix_green: u32,
    raw_color: u32,
    zero_is_bad: u32,
    shrink: u16,
    fuji_width: u16,
}

// C enum definitions
#[repr(C)]
enum LibrawThumbnailFormat {
    Unknown = 0,
    Jpeg = 1,
    Bitmap = 2,
    Layer = 4,
    Rollei = 5,
}

// Errors
pub enum LibrawError {
    NulError(std::ffi::NulError),
    AllocError(LibrawAllocError),
    IOError(std::io::Error),
    LibError(LibrawLibraryError),
}

#[derive(Debug)]
pub struct LibrawAllocError;

impl fmt::Display for LibrawAllocError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "image data allocation failed".fmt(f)
    }
}

impl error::Error for LibrawAllocError {
    fn description(&self) -> &str {
        "image data allocation failed"
    }
}

#[derive(Debug)]
pub struct LibrawLibraryError;

impl fmt::Display for LibrawLibraryError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "internal libraw library error".fmt(f)
    }
}

impl error::Error for LibrawLibraryError {
    fn description(&self) -> &str {
        "internal libraw library error"
    }
}

// Higher-level unsafe methods
// These methods may change as I find better ways to implement this
// Specifically, it might be better to read the file in Rust and pass
// the resulting buffer to libraw
unsafe fn init_data() -> Result<*mut LibrawData, LibrawError> {
    // 0 = no flags
    // 1 = no memory error callback
    // 2 = non data error callback
    // 3 = both
    let data = libraw_init(3);
    if data.is_null() {
        Err(LibrawError::AllocError(LibrawAllocError))
    } else {
        Ok(data)
    }
}

unsafe fn read_img_at_path(filepath: &str) -> Result<*mut LibrawData, LibrawError> {
    let fpath = match CString::new(filepath) {
        Ok(v) => v,
        Err(e) => return Err(LibrawError::NulError(e)),
    };
    let data = try!(init_data());
    let res: i32 = libraw_open_file(data, fpath.as_ptr());
    if res > 0 {
        Err(LibrawError::IOError(std::io::Error::from_raw_os_error(res)))
    } else if res < 0 {
        Err(LibrawError::LibError(LibrawLibraryError))
    } else {
        Ok(data)
    }
}

// Public interface
pub fn load_raw_at_path<'a>(fpath: &'a path::Path) -> Result<RawData<'a>, LibrawError> {
    let pathstr = match fpath.to_str() {
        Some(v) => v,
        None => return Err(LibrawError::AllocError(LibrawAllocError)),
    };
    unsafe {
        let unsafe_val = match read_img_at_path(pathstr) {
            Ok(v) => v,
            Err(e) => return Err(e),
        };

        let raw_dat: RawData = RawData{
            librawData: unsafe_val,
            phantom: PhantomData
        };
        Ok(raw_dat)
    }
}

pub struct RawData<'a> {
    librawData: *const LibrawData,
    phantom: PhantomData<&'a LibrawData>,
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::io;

use time::Duration;

use mind::{kickoff, iterative_deepening_kickoff};
use life::WorldState;
use space::Locale;
use identity::Team;

// Unlikely Command Integration dæmon

pub fn dæmon() {
    let mut input_buffer = String::new();
    let mut world = WorldState::new();

    loop {
        input_buffer.clear();
        io::stdin().read_line(&mut input_buffer)
            .expect("expected to be able to read stdin");

        match input_buffer.as_ref() {
            "uci\n" => {
                println!("id name Leafline");
                println!("id author Zack M. Davis and friends");
                println!("uciok");
                continue;
            }
            "isready\n" => {
                println!("readyok");
                continue;
            }
            "ucinewgame\n" => {
                world = WorldState::new();
                continue;
            }
            "quit\n" => {
                break;
            }
            _ => { /* hopefully, 'position', or 'go' */ }
        }

        let mut tokens = input_buffer.split_whitespace();
        let command = tokens.next().expect("expected a command");
        match command {
            "position" => {
                // XXX HACK: let's assume our internal WorldState is correct
                // and just look at the last-move diff
                let diff = tokens.last()
                    .expect("expected a discernable last move");
                // XXX: we're going to need better movement-parsing than this
                // to play a full game (consider secret service)
                let whence = Locale::from_algebraic(&diff[0..2]);
                let whither = Locale::from_algebraic(&diff[2..4]);
                let premonitions = world.lookahead();
                for premonition in premonitions.iter() {
                    if premonition.patch.whence == whence &&
                        premonition.patch.whither == whither {
                            world = premonition.tree;
                    }
                }
            },
            "go" => {
                let mut options = HashMap::new();
                while let Some(key) = tokens.next() {
                    let value = tokens.next()
                        .expect("expected option value").parse::<usize>()
                        .expect("expected an integer literal");
                    options.insert(key, value);
                }

                let mut forecasts;
                if let Some(depth) = options.get("depth") {
                    forecasts = kickoff(&world, *depth as u8, None, false, 2.0);
                } else {
                    let allegiance = world.initiative;
                    let (time_key, increment_key) = match allegiance {
                        Team::Orange => ("wtime", "winc"),
                        Team::Blue => ("btime", "binc")
                    };
                    let remaining_movements = options.get("movestogo")
                        .expect("expected movestogo");
                    let remaining_moments = options.get(time_key).expect(time_key);
                    let zero = 0; // XXX really? really??
                    let grace = options.get(increment_key).unwrap_or(&zero);
                    let deadline = ((remaining_moments /
                                     remaining_movements) + grace - 1200) / 1000;
                    let (beforecasts, depth) = iterative_deepening_kickoff(
                        &world, Duration::seconds(deadline as i64), false, 2.0);
                    forecasts = beforecasts;
                    println!("info depth {}", depth);
                }
                let movement = forecasts.swap_remove(0).0;
                println!("bestmove {}{}",
                         movement.patch.whence.to_algebraic(),
                         movement.patch.whither.to_algebraic());
                world = movement.tree;
            }
            s @ _ => { moral_panic!(format!("got unrecognized UCI command {:?}", s)) }
        }

    }
}
<commit_msg>don't be so conservative about the clock<commit_after>use std::collections::HashMap;
use std::io;

use time::Duration;

use mind::{kickoff, iterative_deepening_kickoff};
use life::WorldState;
use space::Locale;
use identity::Team;

// Unlikely Command Integration dæmon

pub fn dæmon() {
    let mut input_buffer = String::new();
    let mut world = WorldState::new();

    loop {
        input_buffer.clear();
        io::stdin().read_line(&mut input_buffer)
            .expect("expected to be able to read stdin");

        match input_buffer.as_ref() {
            "uci\n" => {
                println!("id name Leafline");
                println!("id author Zack M. Davis and friends");
                println!("uciok");
                continue;
            }
            "isready\n" => {
                println!("readyok");
                continue;
            }
            "ucinewgame\n" => {
                world = WorldState::new();
                continue;
            }
            "quit\n" => {
                break;
            }
            _ => { /* hopefully, 'position', or 'go' */ }
        }

        let mut tokens = input_buffer.split_whitespace();
        let command = tokens.next().expect("expected a command");
        match command {
            "position" => {
                // XXX HACK: let's assume our internal WorldState is correct
                // and just look at the last-move diff
                let diff = tokens.last()
                    .expect("expected a discernable last move");
                // XXX: we're going to need better movement-parsing than this
                // to play a full game (consider secret service)
                let whence = Locale::from_algebraic(&diff[0..2]);
                let whither = Locale::from_algebraic(&diff[2..4]);
                let premonitions = world.lookahead();
                for premonition in premonitions.iter() {
                    if premonition.patch.whence == whence &&
                        premonition.patch.whither == whither {
                            world = premonition.tree;
                    }
                }
            },
            "go" => {
                let mut options = HashMap::new();
                while let Some(key) = tokens.next() {
                    let value = tokens.next()
                        .expect("expected option value").parse::<usize>()
                        .expect("expected an integer literal");
                    options.insert(key, value);
                }

                let mut forecasts;
                if let Some(depth) = options.get("depth") {
                    forecasts = kickoff(&world, *depth as u8, None, false, 2.0);
                } else {
                    let allegiance = world.initiative;
                    let (time_key, increment_key) = match allegiance {
                        Team::Orange => ("wtime", "winc"),
                        Team::Blue => ("btime", "binc")
                    };
                    let remaining_movements = options.get("movestogo")
                        .expect("expected movestogo");
                    let remaining_moments = options.get(time_key).expect(time_key);
                    let zero = 0; // XXX really? really??
                    let grace = options.get(increment_key).unwrap_or(&zero);
                    let deadline = ((remaining_moments /
                                     remaining_movements) + grace) / 1000;
                    let (beforecasts, depth) = iterative_deepening_kickoff(
                        &world, Duration::seconds(deadline as i64), false, 2.0);
                    forecasts = beforecasts;
                    println!("info depth {}", depth);
                }
                let movement = forecasts.swap_remove(0).0;
                println!("bestmove {}{}",
                         movement.patch.whence.to_algebraic(),
                         movement.patch.whither.to_algebraic());
                world = movement.tree;
            }
            s @ _ => { moral_panic!(format!("got unrecognized UCI command {:?}", s)) }
        }

    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::cell::RefCell;

thread_local!(static EVENT_LOOP: Option<RefCell<EventLoop>> = None);

fn with_current_event_loop<F, R>(f: F) -> R
    where F: FnOnce(&RefCell<EventLoop>) -> R {
        EVENT_LOOP.with(|maybe_event_loop| {
            match maybe_event_loop {
                &None => panic!("current thread has no event loop"),
                &Some(ref event_loop) => f(event_loop),
            }
        })
    }

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

pub struct Promise<T> {
    phantom_data : ::std::marker::PhantomData<T>,
    pub node : Box<PromiseNode>,
}

impl <T> Promise <T> {
    pub fn then<F, G, R>(self, _func: F, _error_handler: G) -> Promise<R>
        where F: FnOnce(T) -> Result<R> {
            unimplemented!()
        }

    pub fn wait(self) -> Result<T> {
        unimplemented!()
    }
}

pub trait Event {
    fn fire(&mut self);
}

pub trait PromiseNode {
    /// Arms the given event when ready.
    fn on_ready(&self, event : Box<Event>);

    fn set_self_pointer(&mut self) {}
    fn get(&self);
}

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct TransformPromiseNode {
    dependency: Box<PromiseNode>,
}

/// A promise that has already been resolved to an immediate value or error.
pub struct ImmediatePromiseNode<T> {
    result: Result<T>,
}

impl <T> PromiseNode for ImmediatePromiseNode<T> {

    /// Arms the event then the promise is ready.
    fn on_ready(&self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.borrow_mut().arm_breadth_first(event);
        });
    }
    fn get(&self) {

    }
}

trait ErrorHandler {
    fn task_failed(error: Error);
}

struct TaskSetImpl {
    error_handler: Box<ErrorHandler>,
}

/// A Deque with an insertion point in the middle.
struct InsertDeque<T> {
    front: ::std::collections::VecDeque<T>,
    back: ::std::collections::VecDeque<T>,
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
    daemons: TaskSetImpl,
    running: bool,
    last_runnable_state: bool,
    events: ::std::collections::VecDeque<Box<Event>>,
    depth_first_events: ::std::collections::VecDeque<Box<Event>>,
}

impl EventLoop {

    fn arm_depth_first(&mut self, event: Box<Event>) {
        self.depth_first_events.push_front(event);
    }

    fn arm_breadth_first(&mut self, event: Box<Event>) {
        self.events.push_back(event);
    }

    /// Run the even 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(&mut self) -> bool {
        assert!(self.depth_first_events.is_empty());
        match self.events.pop_front() {
            None => return false,
            Some(mut event) => {
                // event->firing = true ?
                event.fire();
            }
        }
        while !self.depth_first_events.is_empty() {
            self.events.push_front(self.depth_first_events.pop_back().unwrap());
        }
        return true;
    }
}
<commit_msg>mut self<commit_after>#![allow(dead_code)]

use std::cell::RefCell;

thread_local!(static EVENT_LOOP: Option<RefCell<EventLoop>> = None);

fn with_current_event_loop<F, R>(f: F) -> R
    where F: FnOnce(&RefCell<EventLoop>) -> R {
        EVENT_LOOP.with(|maybe_event_loop| {
            match maybe_event_loop {
                &None => panic!("current thread has no event loop"),
                &Some(ref event_loop) => f(event_loop),
            }
        })
    }

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

pub struct Promise<T> {
    phantom_data : ::std::marker::PhantomData<T>,
    pub node : Box<PromiseNode>,
}

impl <T> Promise <T> {
    pub fn then<F, G, R>(self, _func: F, _error_handler: G) -> Promise<R>
        where F: FnOnce(T) -> Result<R> {
            unimplemented!()
        }

    pub fn wait(self) -> Result<T> {
        unimplemented!()
    }
}

pub trait Event {
    fn fire(&mut self);
}

pub trait PromiseNode {
    /// Arms the given event when ready.
    fn on_ready(&mut self, event : Box<Event>);

    fn set_self_pointer(&mut self) {}
    fn get(&self);
}

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct TransformPromiseNode {
    dependency: Box<PromiseNode>,
}

/// A promise that has already been resolved to an immediate value or error.
pub struct ImmediatePromiseNode<T> {
    result: Result<T>,
}

impl <T> PromiseNode for ImmediatePromiseNode<T> {

    /// Arms the event then the promise is ready.
    fn on_ready(&mut self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.borrow_mut().arm_breadth_first(event);
        });
    }
    fn get(&self) {

    }
}

trait ErrorHandler {
    fn task_failed(error: Error);
}

struct TaskSetImpl {
    error_handler: Box<ErrorHandler>,
}

/// A Deque with an insertion point in the middle.
struct InsertDeque<T> {
    front: ::std::collections::VecDeque<T>,
    back: ::std::collections::VecDeque<T>,
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
    daemons: TaskSetImpl,
    running: bool,
    last_runnable_state: bool,
    events: ::std::collections::VecDeque<Box<Event>>,
    depth_first_events: ::std::collections::VecDeque<Box<Event>>,
}

impl EventLoop {

    fn arm_depth_first(&mut self, event: Box<Event>) {
        self.depth_first_events.push_front(event);
    }

    fn arm_breadth_first(&mut self, event: Box<Event>) {
        self.events.push_back(event);
    }

    /// Run the even 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(&mut self) -> bool {
        assert!(self.depth_first_events.is_empty());
        match self.events.pop_front() {
            None => return false,
            Some(mut event) => {
                // event->firing = true ?
                event.fire();
            }
        }
        while !self.depth_first_events.is_empty() {
            self.events.push_front(self.depth_first_events.pop_back().unwrap());
        }
        return true;
    }
}
<|endoftext|>


<commit_before>use std::io::BufReader;
use std::io::prelude::*;
use std::process::Child;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;

/// represents a single line of output from a child process
#[derive(Debug)]
pub enum Line {
  /// a line of stdout output
  StdOut(String),
  /// a line of stderr output
  StdErr(String)
}

/// represents a source of child process line output
pub struct Lines {
  rx: Receiver<Option<Line>>,
}

/// represents an iterable of Line instances
pub struct Iter<'a> {
  lines: &'a Lines
}

impl Lines {
  pub fn iter(&self) -> Iter {
    Iter { lines: self }
  }
}

impl<'a> Iterator for Iter<'a> {
  type Item = Line;
  fn next(&mut self) -> Option<Line> {
    match self.lines.rx.recv() {
      Ok(line) => line,
            _  => None,
    }
  }
}

/// creates a new Lines instance
///
/// ```rust
///  match Command::new("...").
///      .stdout(Stdio::piped())
///      .stderr(Stdio::piped()).spawn() {
///          Ok(mut child) => {
///              let lines = pines::lines(&mut child);
///              child.wait().unwrap();
///              for l in lines.iter() {
///                  println!("{}", l)
///              }
///          },
///         _ => println!("failed to launch process")
///     }
/// ```
pub fn lines(child: &mut Child) -> Lines {
  let (tx, rx) = channel();
  fn read<R, F>(
    readable: Option<R>,
    tx: Sender<Option<Line>>,
    wrap: F
  ) where
    R: Send + 'static + Read,
    F: Send + 'static + Fn(String) -> Line {
    if let Some(r) = readable {
      thread::spawn(move || {
        let mut buf = BufReader::new(r);
        loop {
          let mut line = String::new();
            match buf.read_line(&mut line) {
                Ok(0) | Err(_)  => break,
                Ok(_)  => {
                    let _ = tx.send(Some(wrap(line)));
                }
          }
        }
      });
    } else {
      let _ = tx.send(None);
    }
  };
  read(child.stdout.take(), tx.clone(), |l| Line::StdOut(l));
  read(child.stderr.take(), tx.clone(), |l| Line::StdErr(l));
  Lines { rx: rx }
}

#[test]
fn it_works() {
}
<commit_msg>fix doc test<commit_after>use std::io::BufReader;
use std::io::prelude::*;
use std::process::Child;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;

/// represents a single line of output from a child process
#[derive(Debug)]
pub enum Line {
  /// a line of stdout output
  StdOut(String),
  /// a line of stderr output
  StdErr(String)
}

/// represents a source of child process line output
pub struct Lines {
  rx: Receiver<Option<Line>>,
}

/// represents an iterable of Line instances
pub struct Iter<'a> {
  lines: &'a Lines
}

impl Lines {
  pub fn iter(&self) -> Iter {
    Iter { lines: self }
  }
}

impl<'a> Iterator for Iter<'a> {
  type Item = Line;
  fn next(&mut self) -> Option<Line> {
    match self.lines.rx.recv() {
      Ok(line) => line,
            _  => None,
    }
  }
}

/// creates a new Lines instance
///
/// ```rust
/// use std::process::{Command, Stdio};
///  match Command::new("...")
///      .stdout(Stdio::piped())
///      .stderr(Stdio::piped()).spawn() {
///          Ok(mut child) => {
///              let lines = pine::lines(&mut child);
///              child.wait().unwrap();
///              for l in lines.iter() {
///                  println!("{:?}", l)
///              }
///          },
///         _ => println!("failed to launch process")
///     }
/// ```
pub fn lines(child: &mut Child) -> Lines {
  let (tx, rx) = channel();
  fn read<R, F>(
    readable: Option<R>,
    tx: Sender<Option<Line>>,
    wrap: F
  ) where
    R: Send + 'static + Read,
    F: Send + 'static + Fn(String) -> Line {
    if let Some(r) = readable {
      thread::spawn(move || {
        let mut buf = BufReader::new(r);
        loop {
          let mut line = String::new();
            match buf.read_line(&mut line) {
                Ok(0) | Err(_)  => break,
                Ok(_)  => {
                    let _ = tx.send(Some(wrap(line)));
                }
          }
        }
      });
    } else {
      let _ = tx.send(None);
    }
  };
  read(child.stdout.take(), tx.clone(), |l| Line::StdOut(l));
  read(child.stderr.take(), tx.clone(), |l| Line::StdErr(l));
  Lines { rx: rx }
}

#[test]
fn it_works() {
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
//! An encoder and decoder for FITS images.
//!
//! The *Flexible Image Transport System* ([FITS][fits]) is
//! > an open standard defining a digital file format useful for storage,
//! > transmission and processing of scientific and other images.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Correct link to FITS wikipedia page<commit_after>#![deny(missing_docs)]
//! An encoder and decoder for FITS images.
//!
//! The *Flexible Image Transport System* ([FITS](https://en.wikipedia.org/wiki/FITS)) is
//! > an open standard defining a digital file format useful for storage,
//! > transmission and processing of scientific and other images.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]
#![deny(missing_copy_implementations)]
#![feature(io)]
#![feature(std_misc)]

extern crate clock_ticks;
#[macro_use]
extern crate quack;

use std::old_io::timer::sleep;
use std::time::duration::Duration;
use quack::{ ActOn, Action, GetFrom, Get, Pair };
use std::cmp;

/// Whether window should close or not.
#[derive(Copy)]
pub struct ShouldClose(pub bool);

impl Sized for ShouldClose {}

/// The size of the window.
#[derive(Copy)]
pub struct Size(pub [u32; 2]);

impl Sized for Size {}

/// Tells window to swap buffers.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// window.action(SwapBuffers);
/// ~~~
#[derive(Copy)]
pub struct SwapBuffers;

impl Sized for SwapBuffers {}

/// Polls event from window.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// let e = window.action(PollEvent);
/// ~~~
#[derive(Copy)]
pub struct PollEvent;

impl Sized for PollEvent {}

/// Render arguments
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Idle arguments, such as expected idle time in seconds.
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct IdleArgs {
    /// Expected idle time in seconds.
    pub dt: f64
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
    /// Creates an idle event.
    fn idle(IdleArgs) -> Self;
}

/// Tells whether last emitted event was idle or not.
#[derive(Copy, Debug, PartialEq, Eq)]
enum Idle {
    No,
    Yes
}

#[derive(Copy, Debug)]
enum State {
    Render,
    SwapBuffers,
    UpdateLoop(Idle),
    HandleEvents,
    Update,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
#[derive(Copy)]
pub struct Ups(pub u64);

quack_set! {
    events: Events[W, I, E]
    fn (ups: Ups) [] {
        let frames = ups.0;
        events.dt_update_in_ns = BILLION / frames;
        events.dt = 1.0 / frames as f64;
    }
}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
#[derive(Copy)]
pub struct MaxFps(pub u64);

quack_set! {
    this: Events[W, I, E]
    fn (max_fps: MaxFps) [] {
        this.dt_frame_in_ns = BILLION / max_fps.0;
    }
}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ~~~ignore
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ~~~
pub struct Events<W, I, E> {
    window: W,
    state: State,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W, I, E> Events<W, I, E> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W, I, E> {
        let start = clock_ticks::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: State::Render,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W, I, E>
Iterator
for Events<W, I, E>
    where
        (ShouldClose, W): Pair<Data = ShouldClose, Object = W> + GetFrom,
        (Size, W): Pair<Data = Size, Object = W> + GetFrom,
        (SwapBuffers, W): Pair<Data = SwapBuffers, Object = W> + ActOn<()>,
        (PollEvent, W): Pair<Data = PollEvent, Object = W> + ActOn<Option<I>>,
        E: EventMap<I>,
{
    type Item = E;

    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                State::Render => {
                    let ShouldClose(should_close) = self.window.get();
                    if should_close { return None; }

                    let start_render = clock_ticks::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = State::SwapBuffers;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    State::UpdateLoop(Idle::No)
                }
                State::SwapBuffers => {
                    self.window.action(SwapBuffers);
                    State::UpdateLoop(Idle::No)
                }
                State::UpdateLoop(ref mut idle) => {
                    let current_time = clock_ticks::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        if let Some(x) = self.window.action(PollEvent) {
                            *idle = Idle::No;
                            return Some(EventMap::input(x));
                        } else if *idle == Idle::No {
                            *idle = Idle::Yes;
                            let seconds = ((next_event - current_time) as f64) / (BILLION as f64);
                            return Some(EventMap::idle(IdleArgs { dt: seconds }))
                        }
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        State::UpdateLoop(Idle::No)
                    } else if next_event == next_frame {
                        State::Render
                    } else {
                        State::HandleEvents
                    }
                }
                State::HandleEvents => {
                    // Handle all events before updating.
                    match self.window.action(PollEvent) {
                        None => State::Update,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                State::Update => {
                    self.state = State::UpdateLoop(Idle::No);
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<commit_msg>Add PhantomData to Events.<commit_after>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]
#![deny(missing_copy_implementations)]
#![feature(io)]
#![feature(std_misc)]

extern crate clock_ticks;
#[macro_use]
extern crate quack;

use std::old_io::timer::sleep;
use std::time::duration::Duration;
use quack::{ ActOn, Action, GetFrom, Get, Pair };
use std::cmp;
use std::marker::{ PhantomData };

/// Whether window should close or not.
#[derive(Copy)]
pub struct ShouldClose(pub bool);

impl Sized for ShouldClose {}

/// The size of the window.
#[derive(Copy)]
pub struct Size(pub [u32; 2]);

impl Sized for Size {}

/// Tells window to swap buffers.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// window.action(SwapBuffers);
/// ~~~
#[derive(Copy)]
pub struct SwapBuffers;

impl Sized for SwapBuffers {}

/// Polls event from window.
///
/// ~~~ignore
/// use current::Action;
///
/// ...
/// let e = window.action(PollEvent);
/// ~~~
#[derive(Copy)]
pub struct PollEvent;

impl Sized for PollEvent {}

/// Render arguments
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Idle arguments, such as expected idle time in seconds.
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct IdleArgs {
    /// Expected idle time in seconds.
    pub dt: f64
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
    /// Creates an idle event.
    fn idle(IdleArgs) -> Self;
}

/// Tells whether last emitted event was idle or not.
#[derive(Copy, Debug, PartialEq, Eq)]
enum Idle {
    No,
    Yes
}

#[derive(Copy, Debug)]
enum State {
    Render,
    SwapBuffers,
    UpdateLoop(Idle),
    HandleEvents,
    Update,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
#[derive(Copy)]
pub struct Ups(pub u64);

quack_set! {
    events: Events[W, I, E]
    fn (ups: Ups) [] {
        let frames = ups.0;
        events.dt_update_in_ns = BILLION / frames;
        events.dt = 1.0 / frames as f64;
    }
}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
#[derive(Copy)]
pub struct MaxFps(pub u64);

quack_set! {
    this: Events[W, I, E]
    fn (max_fps: MaxFps) [] {
        this.dt_frame_in_ns = BILLION / max_fps.0;
    }
}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ~~~ignore
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ~~~
pub struct Events<W, I, E> {
    window: W,
    state: State,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
    _marker_i: PhantomData<I>,
    _marker_e: PhantomData<E>,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W, I, E> Events<W, I, E> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W, I, E> {
        let start = clock_ticks::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: State::Render,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
            _marker_i: PhantomData,
            _marker_e: PhantomData,
        }
    }
}

impl<W, I, E>
Iterator
for Events<W, I, E>
    where
        (ShouldClose, W): Pair<Data = ShouldClose, Object = W> + GetFrom,
        (Size, W): Pair<Data = Size, Object = W> + GetFrom,
        (SwapBuffers, W): Pair<Data = SwapBuffers, Object = W> + ActOn<()>,
        (PollEvent, W): Pair<Data = PollEvent, Object = W> + ActOn<Option<I>>,
        E: EventMap<I>,
{
    type Item = E;

    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                State::Render => {
                    let ShouldClose(should_close) = self.window.get();
                    if should_close { return None; }

                    let start_render = clock_ticks::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = State::SwapBuffers;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    State::UpdateLoop(Idle::No)
                }
                State::SwapBuffers => {
                    self.window.action(SwapBuffers);
                    State::UpdateLoop(Idle::No)
                }
                State::UpdateLoop(ref mut idle) => {
                    let current_time = clock_ticks::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        if let Some(x) = self.window.action(PollEvent) {
                            *idle = Idle::No;
                            return Some(EventMap::input(x));
                        } else if *idle == Idle::No {
                            *idle = Idle::Yes;
                            let seconds = ((next_event - current_time) as f64) / (BILLION as f64);
                            return Some(EventMap::idle(IdleArgs { dt: seconds }))
                        }
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        State::UpdateLoop(Idle::No)
                    } else if next_event == next_frame {
                        State::Render
                    } else {
                        State::HandleEvents
                    }
                }
                State::HandleEvents => {
                    // Handle all events before updating.
                    match self.window.action(PollEvent) {
                        None => State::Update,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                State::Update => {
                    self.state = State::UpdateLoop(Idle::No);
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<|endoftext|>


<commit_before>extern crate xml;

use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;

use xml::reader::{EventReader, XmlEvent};
use xml::attribute::OwnedAttribute;

mod error;
use error::{ErrorKind, AttributeError};

pub type Coordinate = f64;

#[derive(Debug, PartialEq)]
pub struct Tag {
    pub key: String,
    pub val: String
}

#[derive(Debug, PartialEq)]
pub struct Bounds {
    pub minlat: Coordinate,
    pub minlon: Coordinate,
    pub maxlat: Coordinate,
    pub maxlon: Coordinate,
}

#[derive(Debug, PartialEq)]
pub struct Node {
    pub id: i64,
    pub lat: Coordinate,
    pub lon: Coordinate,
    pub tags: Vec<Tag>
}

#[derive(Debug)]
pub struct OSM {
    pub bounds: Option<Bounds>,
    pub nodes: Vec<Node>
}

impl OSM {
    fn empty() -> OSM {
        OSM {
            bounds: None,
            nodes: Vec::new(),
        }
    }

    pub fn parse(file: File) -> Option<OSM> {
        let mut osm = OSM::empty();

        let reader = BufReader::new(file);
        let mut parser = EventReader::new(reader);

        loop {
            match parse_element_data(&mut parser) {
                Err(ErrorKind::UnknownElement) => continue,
                Err(ErrorKind::MalformedElement) => continue,
                Err(ErrorKind::BoundsMissing(_)) => osm.bounds = None,
                Err(_) => return None,
                Ok(data) => {
                    match data {
                        ElementData::EndOfDocument => return Some(osm),
                        ElementData::Ignored => continue,
                        ElementData::Bounds(minlat, minlon, maxlat, maxlon) => {
                            osm.bounds = Some(Bounds {
                                minlat: minlat,
                                minlon: minlon,
                                maxlat: maxlat,
                                maxlon: maxlon
                            });
                        },
                        ElementData::Node(id, lat, lon, tags) => {
                            osm.nodes.push(Node {
                                id: id,
                                lat: lat,
                                lon: lon,
                                tags: tags
                            });
                        },
                        _ => ()
                    }
                }
            }
        }
    }
}

enum ElementType {
    Bounds,
    Node,
    Way,
    Relation,
    Tag
}

enum ElementData {
    Bounds(f64, f64, f64, f64),
    NodeAttrs(i64, f64, f64),
    Node(i64, f64, f64, Vec<Tag>),
    // These two are here so we can terminate and skip uninteresting data without
    // using error handling.
    EndOfDocument,
    Ignored
}

impl FromStr for ElementType {
    type Err = ErrorKind;

    fn from_str(s: &str) -> Result<ElementType, ErrorKind> {
        let downcased = s.to_lowercase();

        if downcased == "bounds" {
            return Ok(ElementType::Bounds);
        }

        if downcased == "node" {
            return Ok(ElementType::Node);
        }

        if downcased == "way" {
            return Ok(ElementType::Way);
        }

        if downcased == "relation" {
            return Ok(ElementType::Relation);
        }

        if downcased == "tag" {
            return Ok(ElementType::Tag);
        }

        Err(ErrorKind::UnknownElement)
    }
}

fn parse_element_data(parser: &mut EventReader<BufReader<File>>) -> Result<ElementData, ErrorKind> {
    let element = try!(parser.next());
    match element {
        XmlEvent::EndDocument => Ok(ElementData::EndOfDocument),
        XmlEvent::StartElement { name, attributes, .. } => {
            let element_type = try!(ElementType::from_str(&name.local_name));

            match element_type {
                ElementType::Bounds => parse_bounds(&attributes),
                ElementType::Node => parse_node(parser, &attributes),
                _ => Err(ErrorKind::UnknownElement)
            }
        },
        _ => Ok(ElementData::Ignored)
    }
}

fn parse_node(parser: &mut EventReader<BufReader<File>>, attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let node_attrs = try!(parse_node_attributes(&attrs));

    if let ElementData::NodeAttrs(id, lat, lon) = node_attrs {
        let mut tags = Vec::new();

        // Parse Node child elements, if any
        loop {
            match try!(parser.next()) {
                XmlEvent::EndElement { name } => {
                    let element_type = try!(ElementType::from_str(&name.local_name));

                    match element_type {
                        ElementType::Node => return Ok(ElementData::Node(id, lat, lon, tags)),
                        _ => continue
                    }
                },
                XmlEvent::StartElement { name, attributes, .. } => {
                    let element_type = try!(ElementType::from_str(&name.local_name));

                    match element_type {
                        ElementType::Tag => {
                            if let Some(tag) = parse_tag_attributes(&attributes) {
                                tags.push(tag);
                            }
                        },
                        // Malformed node containing illegal children, ignore whole Node
                        ElementType::Node |
                        ElementType::Relation |
                        ElementType::Way => return Err(ErrorKind::MalformedElement),
                        _ => continue
                    }
                },
                _ => continue
            }
        }
    } else {
        Err(ErrorKind::MalformedElement)
    }
}

fn parse_tag_attributes(attributes: &Vec<OwnedAttribute>) -> Option<Tag> {
    let mut iter = attributes.iter();
    iter.find(|attr| attr.name.local_name == "k")
        .and_then(|attr| Some(attr.value.clone()))
        .and_then(|key| {
            iter.find(|attr| attr.name.local_name == "v")
            .and_then(|attr| Some(attr.value.clone()))
            .and_then(|val| Some(Tag { key: key, val: val }))
        })
}

fn parse_bounds(attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let minlat = try!(find_attribute("minlat", attrs).map_err(ErrorKind::BoundsMissing));
    let minlon = try!(find_attribute("minlon", attrs).map_err(ErrorKind::BoundsMissing));
    let maxlat = try!(find_attribute("maxlat", attrs).map_err(ErrorKind::BoundsMissing));
    let maxlon = try!(find_attribute("maxlon", attrs).map_err(ErrorKind::BoundsMissing));

    Ok(ElementData::Bounds(minlat, minlon, maxlat, maxlon))
}

fn parse_node_attributes(attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let id = try!(find_attribute("id", attrs).map_err(ErrorKind::IdMissing));
    let lat = try!(find_attribute("lat", attrs).map_err(ErrorKind::CoordinateMissing));
    let lon = try!(find_attribute("lon", attrs).map_err(ErrorKind::CoordinateMissing));

    Ok(ElementData::NodeAttrs(id, lat, lon))
}

fn find_attribute<T>(name: &str, attrs: &Vec<OwnedAttribute>) -> Result<T, AttributeError>
    where AttributeError: std::convert::From<<T as std::str::FromStr>::Err>,
          T: FromStr
{
    let attr = attrs.iter().find(|attr| attr.name.local_name == name);
    match attr {
        Some(a) => {
            let val = try!(a.value.parse::<T>());
            Ok(val)
        },
        None => Err(AttributeError::Missing)
    }
}
<commit_msg>Be explicit about illegal ElementTypes inside Node<commit_after>extern crate xml;

use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;

use xml::reader::{EventReader, XmlEvent};
use xml::attribute::OwnedAttribute;

mod error;
use error::{ErrorKind, AttributeError};

pub type Coordinate = f64;

#[derive(Debug, PartialEq)]
pub struct Tag {
    pub key: String,
    pub val: String
}

#[derive(Debug, PartialEq)]
pub struct Bounds {
    pub minlat: Coordinate,
    pub minlon: Coordinate,
    pub maxlat: Coordinate,
    pub maxlon: Coordinate,
}

#[derive(Debug, PartialEq)]
pub struct Node {
    pub id: i64,
    pub lat: Coordinate,
    pub lon: Coordinate,
    pub tags: Vec<Tag>
}

#[derive(Debug)]
pub struct OSM {
    pub bounds: Option<Bounds>,
    pub nodes: Vec<Node>
}

impl OSM {
    fn empty() -> OSM {
        OSM {
            bounds: None,
            nodes: Vec::new(),
        }
    }

    pub fn parse(file: File) -> Option<OSM> {
        let mut osm = OSM::empty();

        let reader = BufReader::new(file);
        let mut parser = EventReader::new(reader);

        loop {
            match parse_element_data(&mut parser) {
                Err(ErrorKind::UnknownElement) => continue,
                Err(ErrorKind::MalformedElement) => continue,
                Err(ErrorKind::BoundsMissing(_)) => osm.bounds = None,
                Err(_) => return None,
                Ok(data) => {
                    match data {
                        ElementData::EndOfDocument => return Some(osm),
                        ElementData::Ignored => continue,
                        ElementData::Bounds(minlat, minlon, maxlat, maxlon) => {
                            osm.bounds = Some(Bounds {
                                minlat: minlat,
                                minlon: minlon,
                                maxlat: maxlat,
                                maxlon: maxlon
                            });
                        },
                        ElementData::Node(id, lat, lon, tags) => {
                            osm.nodes.push(Node {
                                id: id,
                                lat: lat,
                                lon: lon,
                                tags: tags
                            });
                        },
                        _ => ()
                    }
                }
            }
        }
    }
}

enum ElementType {
    Bounds,
    Node,
    Way,
    Relation,
    Tag
}

enum ElementData {
    Bounds(f64, f64, f64, f64),
    NodeAttrs(i64, f64, f64),
    Node(i64, f64, f64, Vec<Tag>),
    // These two are here so we can terminate and skip uninteresting data without
    // using error handling.
    EndOfDocument,
    Ignored
}

impl FromStr for ElementType {
    type Err = ErrorKind;

    fn from_str(s: &str) -> Result<ElementType, ErrorKind> {
        let downcased = s.to_lowercase();

        if downcased == "bounds" {
            return Ok(ElementType::Bounds);
        }

        if downcased == "node" {
            return Ok(ElementType::Node);
        }

        if downcased == "way" {
            return Ok(ElementType::Way);
        }

        if downcased == "relation" {
            return Ok(ElementType::Relation);
        }

        if downcased == "tag" {
            return Ok(ElementType::Tag);
        }

        Err(ErrorKind::UnknownElement)
    }
}

fn parse_element_data(parser: &mut EventReader<BufReader<File>>) -> Result<ElementData, ErrorKind> {
    let element = try!(parser.next());
    match element {
        XmlEvent::EndDocument => Ok(ElementData::EndOfDocument),
        XmlEvent::StartElement { name, attributes, .. } => {
            let element_type = try!(ElementType::from_str(&name.local_name));

            match element_type {
                ElementType::Bounds => parse_bounds(&attributes),
                ElementType::Node => parse_node(parser, &attributes),
                _ => Err(ErrorKind::UnknownElement)
            }
        },
        _ => Ok(ElementData::Ignored)
    }
}

fn parse_node(parser: &mut EventReader<BufReader<File>>, attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let node_attrs = try!(parse_node_attributes(&attrs));

    if let ElementData::NodeAttrs(id, lat, lon) = node_attrs {
        let mut tags = Vec::new();

        // Parse Node child elements, if any
        loop {
            match try!(parser.next()) {
                XmlEvent::EndElement { name } => {
                    let element_type = try!(ElementType::from_str(&name.local_name));

                    match element_type {
                        ElementType::Node => return Ok(ElementData::Node(id, lat, lon, tags)),
                        _ => continue
                    }
                },
                XmlEvent::StartElement { name, attributes, .. } => {
                    let element_type = try!(ElementType::from_str(&name.local_name));

                    match element_type {
                        ElementType::Tag => {
                            if let Some(tag) = parse_tag_attributes(&attributes) {
                                tags.push(tag);
                            }
                        },
                        // Malformed node containing illegal children, ignore whole Node
                        ElementType::Bounds |
                        ElementType::Node |
                        ElementType::Relation |
                        ElementType::Way => return Err(ErrorKind::MalformedElement)
                    }
                },
                _ => continue
            }
        }
    } else {
        Err(ErrorKind::MalformedElement)
    }
}

fn parse_tag_attributes(attributes: &Vec<OwnedAttribute>) -> Option<Tag> {
    let mut iter = attributes.iter();
    iter.find(|attr| attr.name.local_name == "k")
        .and_then(|attr| Some(attr.value.clone()))
        .and_then(|key| {
            iter.find(|attr| attr.name.local_name == "v")
            .and_then(|attr| Some(attr.value.clone()))
            .and_then(|val| Some(Tag { key: key, val: val }))
        })
}

fn parse_bounds(attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let minlat = try!(find_attribute("minlat", attrs).map_err(ErrorKind::BoundsMissing));
    let minlon = try!(find_attribute("minlon", attrs).map_err(ErrorKind::BoundsMissing));
    let maxlat = try!(find_attribute("maxlat", attrs).map_err(ErrorKind::BoundsMissing));
    let maxlon = try!(find_attribute("maxlon", attrs).map_err(ErrorKind::BoundsMissing));

    Ok(ElementData::Bounds(minlat, minlon, maxlat, maxlon))
}

fn parse_node_attributes(attrs: &Vec<OwnedAttribute>) -> Result<ElementData, ErrorKind> {
    let id = try!(find_attribute("id", attrs).map_err(ErrorKind::IdMissing));
    let lat = try!(find_attribute("lat", attrs).map_err(ErrorKind::CoordinateMissing));
    let lon = try!(find_attribute("lon", attrs).map_err(ErrorKind::CoordinateMissing));

    Ok(ElementData::NodeAttrs(id, lat, lon))
}

fn find_attribute<T>(name: &str, attrs: &Vec<OwnedAttribute>) -> Result<T, AttributeError>
    where AttributeError: std::convert::From<<T as std::str::FromStr>::Err>,
          T: FromStr
{
    let attr = attrs.iter().find(|attr| attr.name.local_name == name);
    match attr {
        Some(a) => {
            let val = try!(a.value.parse::<T>());
            Ok(val)
        },
        None => Err(AttributeError::Missing)
    }
}
<|endoftext|>


<commit_before>#![crate_name="mockstream"]
#![crate_type="lib"]
//! A reader/writer streams to mock real streams in tests.

use std::rc::{Rc};
use std::cell::{RefCell};
use std::io::{Cursor, Read, Write, Result, Error, ErrorKind};
use std::mem::swap;
use std::sync::{Arc, Mutex};

#[cfg(test)]
mod tests;

/// MockStream is Read+Write stream that stores the data written and provides the data to be read.
#[derive(Clone)]
pub struct MockStream {
	reader: Cursor<Vec<u8>>,
	writer: Cursor<Vec<u8>>,
}

impl Default for MockStream {
    fn default() -> Self {
        MockStream::new()
    }
}

fn new_cursor() -> Cursor<Vec<u8>> {
	Cursor::new(Vec::new())
}

impl MockStream {
	/// Create new empty stream
	pub fn new() -> MockStream {
		MockStream {
			reader: new_cursor(),
			writer: new_cursor(),
		}
	}

	/// Extract all bytes written by Write trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		let mut result = Vec::new();
		swap(&mut result, self.writer.get_mut());
		self.writer.set_position(0);
		result
	}

	/// Provide data to be read by Read trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		let avail = self.reader.get_ref().len();
		if self.reader.position() == avail as u64 {
			self.reader = new_cursor();
		}
		self.reader.get_mut().extend(bytes.iter().map(|c| *c));
	}
}

impl Read for MockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.reader.read(buf)
	}
}

impl Write for MockStream {
	fn write<'a>(&mut self, buf: &'a [u8]) -> Result<usize> {
		self.writer.write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.writer.flush()
	}
}

/// Reference-counted stream.
#[derive(Clone, Default)]
pub struct SharedMockStream {
	pimpl: Rc<RefCell<MockStream>>
}

impl SharedMockStream {
	/// Create empty stream
	pub fn new() -> SharedMockStream {
		SharedMockStream { pimpl: Rc::new(RefCell::new(MockStream::new())) }
	}

	/// Extract all bytes written by Write trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		self.pimpl.borrow_mut().push_bytes_to_read(bytes)
	}

	/// Provide data to be read by Read trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		self.pimpl.borrow_mut().pop_bytes_written()
	}
}

impl Read for SharedMockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.pimpl.borrow_mut().read(buf)
	}
}

impl Write for SharedMockStream {
	fn write(&mut self, buf: &[u8]) -> Result<usize> {
		self.pimpl.borrow_mut().write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.pimpl.borrow_mut().flush()
	}
}

/// Thread-safe stream.
#[derive(Clone)]
pub struct SyncMockStream {
	pimpl: Arc<Mutex<MockStream>>
}

impl SyncMockStream {
	/// Create empty stream
	pub fn new() -> SyncMockStream {
		SyncMockStream { pimpl: Arc::new(Mutex::new(MockStream::new())) }
	}

	/// Extract all bytes written by Write trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		self.pimpl.lock().unwrap().push_bytes_to_read(bytes)
	}

	/// Provide data to be read by Read trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		self.pimpl.lock().unwrap().pop_bytes_written()
	}
}

impl Read for SyncMockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.pimpl.lock().unwrap().read(buf)
	}
}

impl Write for SyncMockStream {
	fn write(&mut self, buf: &[u8]) -> Result<usize> {
		self.pimpl.lock().unwrap().write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.pimpl.lock().unwrap().flush()
	}
}

/// `FailingMockStream` mocks a stream which will fail upon read or write
///
/// # Examples
///
/// ```
/// use std::io::{Cursor, Read};
///
/// struct CountIo {}
///
/// impl CountIo {
/// 	fn read_data(&self, r: &mut Read) -> usize {
/// 		let mut count: usize = 0;
/// 		let mut retries = 3;
///
/// 		loop {
/// 			let mut buffer = [0; 5];
/// 			match r.read(&mut buffer) {
/// 				Err(_) => {
/// 					if retries == 0 { break; }
/// 					retries -= 1;
/// 				},
/// 				Ok(0) => break,
/// 				Ok(n) => count += n,
/// 			}
/// 		}
/// 		count
/// 	}
/// }
///
/// #[test]
/// fn test_io_retries() {
/// 	let mut c = Cursor::new(&b"1234"[..])
/// 			.chain(FailingMockStream::new(ErrorKind::Other, "Failing", 3))
/// 			.chain(Cursor::new(&b"5678"[..]));
///
/// 	let sut = CountIo {};
/// 	// this will fail unless read_data performs at least 3 retries on I/O errors
/// 	assert_eq!(8, sut.read_data(&mut c));
/// }
/// ```
#[derive(Clone)]
pub struct FailingMockStream {
	kind: ErrorKind,
	message: &'static str,
	repeat_count: i32,
}

impl FailingMockStream {
	/// Creates a FailingMockStream
	///
	/// When `read` or `write` is called, it will return an error `repeat_count` times.
	/// `kind` and `message` can be specified to define the exact error.
	pub fn new(kind: ErrorKind, message: &'static str, repeat_count: i32) -> FailingMockStream {
		FailingMockStream { kind: kind, message: message, repeat_count: repeat_count, }
	}

	fn error(&mut self) -> Result<usize> {
		if self.repeat_count == 0 {
			return Ok(0)
		}
		else {
			if self.repeat_count > 0 {
				self.repeat_count -= 1;
			}
			Err(Error::new(self.kind, self.message))
		}
	}
}

impl Read for FailingMockStream {
	fn read(&mut self, _: &mut [u8]) -> Result<usize> {
		self.error()
	}
}

impl Write for FailingMockStream {
	fn write(&mut self, _: &[u8]) -> Result<usize> {
		self.error()
	}

	fn flush(&mut self) -> Result<()> {
		Ok(())
	}
}
<commit_msg>Implement Default for SyncMockStream<commit_after>#![crate_name="mockstream"]
#![crate_type="lib"]
//! A reader/writer streams to mock real streams in tests.

use std::rc::{Rc};
use std::cell::{RefCell};
use std::io::{Cursor, Read, Write, Result, Error, ErrorKind};
use std::mem::swap;
use std::sync::{Arc, Mutex};

#[cfg(test)]
mod tests;

/// MockStream is Read+Write stream that stores the data written and provides the data to be read.
#[derive(Clone)]
pub struct MockStream {
	reader: Cursor<Vec<u8>>,
	writer: Cursor<Vec<u8>>,
}

impl Default for MockStream {
    fn default() -> Self {
        MockStream::new()
    }
}

fn new_cursor() -> Cursor<Vec<u8>> {
	Cursor::new(Vec::new())
}

impl MockStream {
	/// Create new empty stream
	pub fn new() -> MockStream {
		MockStream {
			reader: new_cursor(),
			writer: new_cursor(),
		}
	}

	/// Extract all bytes written by Write trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		let mut result = Vec::new();
		swap(&mut result, self.writer.get_mut());
		self.writer.set_position(0);
		result
	}

	/// Provide data to be read by Read trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		let avail = self.reader.get_ref().len();
		if self.reader.position() == avail as u64 {
			self.reader = new_cursor();
		}
		self.reader.get_mut().extend(bytes.iter().map(|c| *c));
	}
}

impl Read for MockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.reader.read(buf)
	}
}

impl Write for MockStream {
	fn write<'a>(&mut self, buf: &'a [u8]) -> Result<usize> {
		self.writer.write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.writer.flush()
	}
}

/// Reference-counted stream.
#[derive(Clone, Default)]
pub struct SharedMockStream {
	pimpl: Rc<RefCell<MockStream>>
}

impl SharedMockStream {
	/// Create empty stream
	pub fn new() -> SharedMockStream {
		SharedMockStream::default()
	}

	/// Extract all bytes written by Write trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		self.pimpl.borrow_mut().push_bytes_to_read(bytes)
	}

	/// Provide data to be read by Read trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		self.pimpl.borrow_mut().pop_bytes_written()
	}
}

impl Read for SharedMockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.pimpl.borrow_mut().read(buf)
	}
}

impl Write for SharedMockStream {
	fn write(&mut self, buf: &[u8]) -> Result<usize> {
		self.pimpl.borrow_mut().write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.pimpl.borrow_mut().flush()
	}
}

/// Thread-safe stream.
#[derive(Clone, Default)]
pub struct SyncMockStream {
	pimpl: Arc<Mutex<MockStream>>
}

impl SyncMockStream {
	/// Create empty stream
	pub fn new() -> SyncMockStream {
		SyncMockStream::default()
	}

	/// Extract all bytes written by Write trait calls.
	pub fn push_bytes_to_read(&mut self, bytes: &[u8]) {
		self.pimpl.lock().unwrap().push_bytes_to_read(bytes)
	}

	/// Provide data to be read by Read trait calls.
	pub fn pop_bytes_written(&mut self) -> Vec<u8> {
		self.pimpl.lock().unwrap().pop_bytes_written()
	}
}

impl Read for SyncMockStream {
	fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
		self.pimpl.lock().unwrap().read(buf)
	}
}

impl Write for SyncMockStream {
	fn write(&mut self, buf: &[u8]) -> Result<usize> {
		self.pimpl.lock().unwrap().write(buf)
	}

	fn flush(&mut self) -> Result<()> {
		self.pimpl.lock().unwrap().flush()
	}
}

/// `FailingMockStream` mocks a stream which will fail upon read or write
///
/// # Examples
///
/// ```
/// use std::io::{Cursor, Read};
///
/// struct CountIo {}
///
/// impl CountIo {
/// 	fn read_data(&self, r: &mut Read) -> usize {
/// 		let mut count: usize = 0;
/// 		let mut retries = 3;
///
/// 		loop {
/// 			let mut buffer = [0; 5];
/// 			match r.read(&mut buffer) {
/// 				Err(_) => {
/// 					if retries == 0 { break; }
/// 					retries -= 1;
/// 				},
/// 				Ok(0) => break,
/// 				Ok(n) => count += n,
/// 			}
/// 		}
/// 		count
/// 	}
/// }
///
/// #[test]
/// fn test_io_retries() {
/// 	let mut c = Cursor::new(&b"1234"[..])
/// 			.chain(FailingMockStream::new(ErrorKind::Other, "Failing", 3))
/// 			.chain(Cursor::new(&b"5678"[..]));
///
/// 	let sut = CountIo {};
/// 	// this will fail unless read_data performs at least 3 retries on I/O errors
/// 	assert_eq!(8, sut.read_data(&mut c));
/// }
/// ```
#[derive(Clone)]
pub struct FailingMockStream {
	kind: ErrorKind,
	message: &'static str,
	repeat_count: i32,
}

impl FailingMockStream {
	/// Creates a FailingMockStream
	///
	/// When `read` or `write` is called, it will return an error `repeat_count` times.
	/// `kind` and `message` can be specified to define the exact error.
	pub fn new(kind: ErrorKind, message: &'static str, repeat_count: i32) -> FailingMockStream {
		FailingMockStream { kind: kind, message: message, repeat_count: repeat_count, }
	}

	fn error(&mut self) -> Result<usize> {
		if self.repeat_count == 0 {
			return Ok(0)
		}
		else {
			if self.repeat_count > 0 {
				self.repeat_count -= 1;
			}
			Err(Error::new(self.kind, self.message))
		}
	}
}

impl Read for FailingMockStream {
	fn read(&mut self, _: &mut [u8]) -> Result<usize> {
		self.error()
	}
}

impl Write for FailingMockStream {
	fn write(&mut self, _: &[u8]) -> Result<usize> {
		self.error()
	}

	fn flush(&mut self) -> Result<()> {
		Ok(())
	}
}
<|endoftext|>