<commit_before>extern crate kafka;
extern crate getopts;
extern crate env_logger;

use std::{env, io, fmt, process};
use std::ascii::AsciiExt;

use kafka::consumer::{Consumer, FetchOffset, GroupOffsetStorage};

/// This is a very simple command line application reading from a
/// specific kafka topic and dumping the messages to standard output.
fn main() {
    env_logger::init().unwrap();

    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = process(cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

fn process(cfg: Config) -> Result<(), Error> {
    let mut c =
        try!(Consumer::from_hosts(cfg.brokers, cfg.topic)
             .with_group(cfg.group)
             .with_fetch_max_wait_time(1000)
             .with_fetch_min_bytes(1_000)
             .with_fetch_max_bytes_per_partition(100_000)
             .with_retry_max_bytes_limit(1_000_000)
             .with_offset_storage(cfg.offset_storage)
             .create());

    let do_commit = !cfg.no_commit;
    loop {
        for ms in try!(c.poll()).iter() {
            for m in ms.messages() {
                let s = String::from_utf8_lossy(m.value);
                println!("{}:{}@{}: {}", ms.topic(), ms.partition(), m.offset, s.trim());
            }
            c.consume_messageset(ms);
        }
        if do_commit {
            try!(c.commit_consumed());
        }
    }
}

// --------------------------------------------------------------------

enum Error {
    Kafka(kafka::error::Error),
    Io(io::Error),
    Literal(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::Kafka(ref e) => write!(f, "kafka-error: {}", e),
            &Error::Io(ref e) => write!(f, "io-error: {}", e),
            &Error::Literal(ref s) => write!(f, "{}", s),
        }
    }
}

impl From<kafka::error::Error> for Error {
    fn from(e: kafka::error::Error) -> Self { Error::Kafka(e) }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self { Error::Io(e) }
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    group: String,
    topic: String,
    no_commit: bool,
    offset_storage: GroupOffsetStorage,
}

impl Config {
    fn from_cmdline() -> Result<Config, Error> {
        let args: Vec<_> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topic", "Specify target topic", "NAME");
        opts.optopt("", "group", "Specify the consumer group", "NAME");
        opts.optflag("", "no-commit", "Do not commit consumed messages");
        opts.optopt("", "offsets", "Specify the offset store [zookeeper, kafka]", "STORE");

        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(Error::Literal(e.to_string())),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", args[0]);
            return Err(Error::Literal(opts.usage(&brief)));
        }

        let mut offset_storage = GroupOffsetStorage::Zookeeper;
        if let Some(s) = m.opt_str("offsets") {
            if s.eq_ignore_ascii_case("zookeeper") {
                offset_storage = GroupOffsetStorage::Zookeeper;
            } else if s.eq_ignore_ascii_case("kafka") {
                offset_storage = GroupOffsetStorage::Kafka;
            } else {
                return Err(Error::Literal(format!("unknown offset store: {}", s)));
            }
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            group: m.opt_str("group")
                .unwrap_or_else(|| String::new()),
            topic: m.opt_str("topic")
                .unwrap_or_else(|| "my-topic".to_owned()),
            no_commit: m.opt_present("no-commit"),
            offset_storage: offset_storage,
        })
   }
}
<commit_msg>Remove unused "use"<commit_after>extern crate kafka;
extern crate getopts;
extern crate env_logger;

use std::{env, io, fmt, process};
use std::ascii::AsciiExt;

use kafka::consumer::{Consumer, GroupOffsetStorage};

/// This is a very simple command line application reading from a
/// specific kafka topic and dumping the messages to standard output.
fn main() {
    env_logger::init().unwrap();

    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = process(cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

fn process(cfg: Config) -> Result<(), Error> {
    let mut c =
        try!(Consumer::from_hosts(cfg.brokers, cfg.topic)
             .with_group(cfg.group)
             .with_fetch_max_wait_time(1000)
             .with_fetch_min_bytes(1_000)
             .with_fetch_max_bytes_per_partition(100_000)
             .with_retry_max_bytes_limit(1_000_000)
             .with_offset_storage(cfg.offset_storage)
             .create());

    let do_commit = !cfg.no_commit;
    loop {
        for ms in try!(c.poll()).iter() {
            for m in ms.messages() {
                let s = String::from_utf8_lossy(m.value);
                println!("{}:{}@{}: {}", ms.topic(), ms.partition(), m.offset, s.trim());
            }
            c.consume_messageset(ms);
        }
        if do_commit {
            try!(c.commit_consumed());
        }
    }
}

// --------------------------------------------------------------------

enum Error {
    Kafka(kafka::error::Error),
    Io(io::Error),
    Literal(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::Kafka(ref e) => write!(f, "kafka-error: {}", e),
            &Error::Io(ref e) => write!(f, "io-error: {}", e),
            &Error::Literal(ref s) => write!(f, "{}", s),
        }
    }
}

impl From<kafka::error::Error> for Error {
    fn from(e: kafka::error::Error) -> Self { Error::Kafka(e) }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self { Error::Io(e) }
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    group: String,
    topic: String,
    no_commit: bool,
    offset_storage: GroupOffsetStorage,
}

impl Config {
    fn from_cmdline() -> Result<Config, Error> {
        let args: Vec<_> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topic", "Specify target topic", "NAME");
        opts.optopt("", "group", "Specify the consumer group", "NAME");
        opts.optflag("", "no-commit", "Do not commit consumed messages");
        opts.optopt("", "offsets", "Specify the offset store [zookeeper, kafka]", "STORE");

        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(Error::Literal(e.to_string())),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", args[0]);
            return Err(Error::Literal(opts.usage(&brief)));
        }

        let mut offset_storage = GroupOffsetStorage::Zookeeper;
        if let Some(s) = m.opt_str("offsets") {
            if s.eq_ignore_ascii_case("zookeeper") {
                offset_storage = GroupOffsetStorage::Zookeeper;
            } else if s.eq_ignore_ascii_case("kafka") {
                offset_storage = GroupOffsetStorage::Kafka;
            } else {
                return Err(Error::Literal(format!("unknown offset store: {}", s)));
            }
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            group: m.opt_str("group")
                .unwrap_or_else(|| String::new()),
            topic: m.opt_str("topic")
                .unwrap_or_else(|| "my-topic".to_owned()),
            no_commit: m.opt_present("no-commit"),
            offset_storage: offset_storage,
        })
   }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::path::Path;
use std::time::Duration;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<usize> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u))
        })
    };
    let rv = rv.unwrap();

    // Hack up our own formatting for the duration to make it easier for scripts
    // to parse (always use the same number of decimal places and the same unit).
    const NANOS_PER_SEC: f64 = 1_000_000_000.0;
    let secs = dur.secs() as f64;
    let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC;

    let mem_string = match get_resident() {
        Some(n) => {
            let mb = n as f64 / 1_000_000.0;
            format!("; rss: {}MB", mb.round() as usize)
        }
        None => "".to_owned(),
    };
    println!("{}time: {:.3}{}\t{}", repeat("  ").take(old).collect::<String>(),
             secs, mem_string, what);

    DEPTH.with(|slot| slot.set(old));

    rv
}

// Memory reporting
fn get_resident() -> Option<usize> {
    if cfg!(unix) {
        get_proc_self_statm_field(1)
    } else {
        None
    }
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

fn get_proc_self_statm_field(field: usize) -> Option<usize> {
    use std::fs::File;
    use std::io::Read;

    assert!(cfg!(unix));

    let mut f = option_try!(File::open("/proc/self/statm").ok());
    let mut contents = String::new();
    option_try!(f.read_to_string(&mut contents).ok());
    let s = option_try!(contents.split_whitespace().nth(field));
    let npages = option_try!(s.parse::<usize>().ok());
    Some(npages * ::std::env::page_size())
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Examples
/// ```
/// struct Context {
///    cache: RefCell<HashMap<usize, usize>>
/// }
///
/// fn factorial(ctxt: &Context, n: usize) -> usize {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).cloned();
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}
<commit_msg>Report memory use in time-passes on Windows<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::path::Path;
use std::time::Duration;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<usize> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u))
        })
    };
    let rv = rv.unwrap();

    // Hack up our own formatting for the duration to make it easier for scripts
    // to parse (always use the same number of decimal places and the same unit).
    const NANOS_PER_SEC: f64 = 1_000_000_000.0;
    let secs = dur.secs() as f64;
    let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC;

    let mem_string = match get_resident() {
        Some(n) => {
            let mb = n as f64 / 1_000_000.0;
            format!("; rss: {}MB", mb.round() as usize)
        }
        None => "".to_owned(),
    };
    println!("{}time: {:.3}{}\t{}", repeat("  ").take(old).collect::<String>(),
             secs, mem_string, what);

    DEPTH.with(|slot| slot.set(old));

    rv
}

// Memory reporting
#[cfg(unix)]
fn get_resident() -> Option<usize> {
    get_proc_self_statm_field(1)
}

#[cfg(windows)]
fn get_resident() -> Option<usize> {
    get_working_set_size()
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

#[cfg(windows)]
fn get_working_set_size() -> Option<usize> {
    use libc::{BOOL, DWORD, HANDLE, SIZE_T, GetCurrentProcess};
    use std::mem;
    #[repr(C)] #[allow(non_snake_case)]
    struct PROCESS_MEMORY_COUNTERS {
        cb: DWORD,
        PageFaultCount: DWORD,
        PeakWorkingSetSize: SIZE_T,
        WorkingSetSize: SIZE_T,
        QuotaPeakPagedPoolUsage: SIZE_T,
        QuotaPagedPoolUsage: SIZE_T,
        QuotaPeakNonPagedPoolUsage: SIZE_T,
        QuotaNonPagedPoolUsage: SIZE_T,
        PagefileUsage: SIZE_T,
        PeakPagefileUsage: SIZE_T,
    }
    type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
    #[link(name = "psapi")]
    extern "system" {
        fn GetProcessMemoryInfo(Process: HANDLE,
                                ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
                                cb: DWORD) -> BOOL;
    }
    let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() };
    pmc.cb = mem::size_of_val(&pmc) as DWORD;
    match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
        0 => None,
        _ => Some(pmc.WorkingSetSize as usize),
    }
}

#[cfg_attr(windows, allow(dead_code))]
fn get_proc_self_statm_field(field: usize) -> Option<usize> {
    use std::fs::File;
    use std::io::Read;

    assert!(cfg!(unix));

    let mut f = option_try!(File::open("/proc/self/statm").ok());
    let mut contents = String::new();
    option_try!(f.read_to_string(&mut contents).ok());
    let s = option_try!(contents.split_whitespace().nth(field));
    let npages = option_try!(s.parse::<usize>().ok());
    Some(npages * ::std::env::page_size())
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Examples
/// ```
/// struct Context {
///    cache: RefCell<HashMap<usize, usize>>
/// }
///
/// fn factorial(ctxt: &Context, n: usize) -> usize {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).cloned();
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}
<|endoftext|>


<commit_before>
use npffi;
use pyffi;

use cpython::*;
use super::NPY_TYPES;

pub struct PyArrayDescr(PyObject);

impl PyArrayDescr {
    pub fn as_ptr(&self) -> *mut npffi::PyArray_Descr {
        self.0.as_ptr() as *mut npffi::PyArray_Descr
    }

    pub fn steal_ptr(self) -> *mut npffi::PyArray_Descr {
        self.0.steal_ptr() as *mut npffi::PyArray_Descr
    }

    pub unsafe fn from_owned_ptr(py: Python, ptr: *mut npffi::PyArray_Descr) -> Self {
        let obj = PyObject::from_owned_ptr(py, ptr as *mut pyffi::PyObject);
        PyArrayDescr(obj)
    }

    pub unsafe fn from_borrowed_ptr(py: Python, ptr: *mut npffi::PyArray_Descr) -> Self {
        let obj = PyObject::from_borrowed_ptr(py, ptr as *mut pyffi::PyObject);
        PyArrayDescr(obj)
    }

    pub fn new(py: Python, typenum: NPY_TYPES) -> Self {
        unsafe {
            let ptr = npffi::PyArray_DescrFromType(typenum as i32);
            Self::from_owned_ptr(py, ptr)
        }
    }
}

impl ToPyObject for PyArrayDescr {
    type ObjectType = Self;

    fn to_py_object(&self, py: Python) -> Self {
        PyClone::clone_ref(self, py)
    }
}

impl PythonObject for PyArrayDescr {
    #[inline]
    fn as_object(&self) -> &PyObject {
        &self.0
    }

    #[inline]
    fn into_object(self) -> PyObject {
        self.0
    }

    #[inline]
    unsafe fn unchecked_downcast_from(obj: PyObject) -> Self {
        PyArrayDescr(obj)
    }

    #[inline]
    unsafe fn unchecked_downcast_borrow_from<'a>(obj: &'a PyObject) -> &'a Self {
        ::std::mem::transmute(obj)
    }
}
<commit_msg>Remove PyArrayDescr<commit_after><|endoftext|>


<commit_before>extern crate algs4;

use algs4::union_find::quick_find;
use algs4::union_find::quick_union;
use algs4::union_find::weighted_quick_union;
use algs4::union_find::improved;

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();

    let n = lines.next().unwrap().unwrap().parse().unwrap();
    let mut uf = quick_find::UF::new(n);

    for line in lines {
        let segs: Vec<usize> = line.unwrap().split(' ').map(|n| n.parse().unwrap()).collect();
        let p = segs[0];
        let q = segs[1];

        if !uf.connected(p, q) {
            uf.union(p, q);
            println!("{} {}", p, q)
        }
    }

    uf.dump()
}
<commit_msg>example/union_find: fix missing import<commit_after>extern crate algs4;

use std::io::prelude::*;
use std::io;

use algs4::union_find::quick_find;
use algs4::union_find::quick_union;
use algs4::union_find::weighted_quick_union;
use algs4::union_find::improved;

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();

    let n = lines.next().unwrap().unwrap().parse().unwrap();
    let mut uf = quick_find::UF::new(n);

    for line in lines {
        let segs: Vec<usize> = line.unwrap().split(' ').map(|n| n.parse().unwrap()).collect();
        let p = segs[0];
        let q = segs[1];

        if !uf.connected(p, q) {
            uf.union(p, q);
            println!("{} {}", p, q)
        }
    }

    // uf.dump()
}
<|endoftext|>


<commit_before>use self::Direction::*;

pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

pub fn char_to_direction(ch : char) -> Option<Direction> {
    match ch {
        'w'|',' => Some(Up),
        's'|'o' => Some(Down),
        'a'     => Some(Left),
        'd'|'e' => Some(Right),
        _       => None
    }
}

#[derive(Clone, Copy)]
pub struct Coord {
    pub col : u16,
    pub row : u16,
}

impl Coord {
    pub fn at(col : u16, row : u16) -> Self {
        Self {
            col: col,
            row: row,
        }
    }
}

pub fn clamp(x : u16, min : u16, max : u16) -> u16 {
    if x < min { min } else if x > max { max } else { x }
}
<commit_msg>Working<commit_after>use self::Direction::*;

pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

pub fn char_to_direction(ch : char) -> Option<Direction> {
    match ch {
        'w'|',' => Some(Up),
        's'|'o' => Some(Down),
        'a'     => Some(Left),
        'd'|'e' => Some(Right),
        _       => None
    }
}

#[derive(Clone, Copy)]
pub struct Coord {
    pub col : u16,
    pub row : u16,
}

pub fn clamp(x : u16, min : u16, max : u16) -> u16 {
    if x < min { min } else if x > max { max } else { x }
}
<|endoftext|>


<commit_before>//! Contains detailed error representation.

use std::error::Error;
use std::fmt;
use std::io;

use crate::color::ExtendedColorType;
use crate::image::ImageFormat;

/// The generic error type for image operations.
///
/// This high level enum is allows, by variant matching, a rough separation of concerns between
/// underlying IO, the caller, format specifications, and the `image` implementation.
#[derive(Debug)]
pub enum ImageError {
    /// An error was encountered while decoding.
    ///
    /// This means that the input data did not conform to the specification of some image format,
    /// or that no format could be determined, or that it did not match format specific
    /// requirements set by the caller.
    Decoding(DecodingError),

    /// An error was encountered while encoding.
    ///
    /// The input image can not be encoded with the chosen format, for example because the
    /// specification has no representation for its color space or because a necessary conversion
    /// is ambiguous. In some cases it might also happen that the dimensions can not be used with
    /// the format.
    Encoding(EncodingError),

    /// An error was encountered in inputs arguments.
    ///
    /// This is a catch-all case for strictly internal operations such as scaling, conversions,
    /// etc. that involve no external format specifications.
    Parameter(ParameterError),

    /// Completing the operation would have required more resources than allowed.
    ///
    /// Errors of this type are limits set by the user or environment, *not* inherent in a specific
    /// format or operation that was executed.
    Limits(LimitError),

    /// An operation can not be completed by the chosen abstraction.
    ///
    /// This means that it might be possible for the operation to succeed in general but
    /// * it requires a disabled feature,
    /// * the implementation does not yet exist, or
    /// * no abstraction for a lower level could be found.
    Unsupported(UnsupportedError),

    /// An error occurred while interacting with the environment.
    IoError(io::Error),
}

/// The implementation for an operation was not provided.
///
/// See the variant [`Unsupported`] for more documentation.
///
/// [`Unsupported`]: struct.ImageError.html#variant.Unsupported
#[derive(Debug)]
pub struct UnsupportedError {
    format: ImageFormatHint,
    kind: UnsupportedErrorKind,
}

/// Details what feature is not supported.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum UnsupportedErrorKind {
    /// The required color type can not be handled.
    Color(ExtendedColorType),
    /// An image format is not supported.
    Format(ImageFormatHint),
    /// Some feature specified by string.
    /// This is discouraged and is likely to get deprecated (but not removed).
    GenericFeature(String),
    #[doc(hidden)]
    __NonExhaustive,
}

#[derive(Debug)]
pub struct EncodingError {
    format: ImageFormatHint,
    message: String,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

#[derive(Debug)]
pub struct ParameterError {
    kind: ParameterErrorKind,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

/// Details how a parameter is malformed.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum ParameterErrorKind {
    /// Repeated an operation for which error that could not be cloned was emitted already.
    FailedAlready,
    /// The dimensions passed are wrong.
    DimensionMismatch,
    /// A string describing the parameter.
    /// This is discouraged and is likely to get deprecated (but not removed).
    Generic(String),
    #[doc(hidden)]
    __NonExhaustive,
}

#[derive(Debug)]
pub struct DecodingError {
    format: ImageFormatHint,
    message: Option<String>,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

#[derive(Debug)]
pub struct LimitError {
    kind: LimitErrorKind,
    // do we need an underlying error?
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
#[allow(missing_copy_implementations)] // Might be non-Copy in the future.
pub enum LimitErrorKind {
    DimensionError,
    InsufficientMemory,
    #[doc(hidden)]
    __NonExhaustive,
}

/// A best effort representation for image formats.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum ImageFormatHint {
    /// The format is known exactly.
    Exact(ImageFormat),

    /// The format can be identified by a name.
    Name(String),

    /// A common path extension for the format is known.
    PathExtension(std::path::PathBuf),

    /// The format is not known or could not be determined.
    Unknown,

    #[doc(hidden)]
    __NonExhaustive,
}

#[allow(non_upper_case_globals)]
#[allow(non_snake_case)]
impl ImageError {
    pub(crate) const InsufficientMemory: Self =
        ImageError::Limits(LimitError {
            kind: LimitErrorKind::InsufficientMemory,
        });

    pub(crate) const DimensionError: Self =
        ImageError::Parameter(ParameterError {
            kind: ParameterErrorKind::DimensionMismatch,
            underlying: None,
        });

    pub(crate) const ImageEnd: Self =
        ImageError::Parameter(ParameterError {
            kind: ParameterErrorKind::FailedAlready,
            underlying: None,
        });

    pub(crate) fn UnsupportedError(message: String) -> Self {
        ImageError::Unsupported(UnsupportedError::legacy_from_string(message))
    }

    pub(crate) fn UnsupportedColor(color: ExtendedColorType) -> Self {
        ImageError::Unsupported(UnsupportedError::new(
            ImageFormatHint::Unknown,
            UnsupportedErrorKind::Color(color),
        ))
    }

    pub(crate) fn FormatError(message: String) -> Self {
        ImageError::Decoding(DecodingError::legacy_from_string(message))
    }
}

impl UnsupportedError {
    pub fn new(format: ImageFormatHint, kind: UnsupportedErrorKind) -> Self {
        UnsupportedError {
            format,
            kind,
        }
    }

    pub(crate) fn legacy_from_string(message: String) -> Self {
        UnsupportedError {
            format: ImageFormatHint::Unknown,
            kind: UnsupportedErrorKind::GenericFeature(message),
        }
    }

    pub fn kind(&self) -> UnsupportedErrorKind {
        self.kind.clone()
    }

    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }
}

impl DecodingError {
    pub fn new(format: ImageFormatHint) -> Self {
        DecodingError {
            format,
            message: None,
            underlying: None,
        }
    }

    pub fn with_underlying(
        format: ImageFormatHint,
        err: impl Into<Box<dyn Error + Send + Sync>>,
    ) -> Self {
        DecodingError {
            format,
            message: None,
            underlying: Some(err.into()),
        }
    }

    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }

    pub(crate) fn legacy_from_string(message: String) -> Self {
        DecodingError {
            format: ImageFormatHint::Unknown,
            message: Some(message),
            underlying: None,
        }
    }

    /// Not quite legacy but also highly discouraged.
    /// This is just since the string typing is prevalent in the `image` decoders...
    // TODO: maybe a Cow? A constructor from `&'static str` wouldn't be too bad.
    pub(crate) fn with_message(
        format: ImageFormatHint,
        message: String,
    ) -> Self {
        DecodingError {
            format,
            message: Some(message),
            underlying: None,
        }
    }

    fn message(&self) -> &str {
        match self.message {
            Some(ref st) => st.as_str(),
            None => "",
        }
    }
}

impl EncodingError {
    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }
}

impl ParameterError {
    pub fn new(kind: ParameterErrorKind) -> Self {
        ParameterError {
            kind,
            underlying: None,
        }
    }

    pub fn kind(&self) -> ParameterErrorKind {
        self.kind.clone()
    }
}

impl LimitError {
    pub fn kind(&self) -> LimitErrorKind {
        self.kind.clone()
    }
}

impl From<io::Error> for ImageError {
    fn from(err: io::Error) -> ImageError {
        ImageError::IoError(err)
    }
}

impl From<ImageFormat> for ImageFormatHint {
    fn from(format: ImageFormat) -> Self {
        ImageFormatHint::Exact(format)
    }
}

impl From<&'_ std::path::Path> for ImageFormatHint {
    fn from(path: &'_ std::path::Path) -> Self {
        match path.extension() {
            Some(ext) => ImageFormatHint::PathExtension(ext.into()),
            None => ImageFormatHint::Unknown,
        }
    }
}

impl From<ImageFormatHint> for UnsupportedError {
    fn from(hint: ImageFormatHint) -> Self {
        UnsupportedError {
            format: hint.clone(),
            kind: UnsupportedErrorKind::Format(hint),
        }
    }
}

/// Result of an image decoding/encoding process
pub type ImageResult<T> = Result<T, ImageError>;

impl fmt::Display for ImageError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self {
            ImageError::IoError(err) => err.fmt(fmt),
            ImageError::Decoding(err) => err.fmt(fmt),
            ImageError::Encoding(err) => err.fmt(fmt),
            ImageError::Parameter(err) => err.fmt(fmt),
            ImageError::Limits(err) => err.fmt(fmt),
            ImageError::Unsupported(err) => err.fmt(fmt),
        }
    }
}

impl Error for ImageError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            ImageError::IoError(err) => err.source(),
            ImageError::Decoding(err) => err.source(),
            ImageError::Encoding(err) => err.source(),
            ImageError::Parameter(err) => err.source(),
            ImageError::Limits(err) => err.source(),
            ImageError::Unsupported(err) => err.source(),
        }
    }
}

impl fmt::Display for UnsupportedError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.kind {
            UnsupportedErrorKind::Format(ImageFormatHint::Unknown) => write!(
                fmt,
                "The image format could not be determined",
            ),
            UnsupportedErrorKind::Format(format @ ImageFormatHint::PathExtension(_)) => write!(
                fmt,
                "The file extension {} was not recognized as an image format",
                format,
            ),
            UnsupportedErrorKind::Format(format) => write!(
                fmt,
                "The image format {} is not supported",
                format,
            ),
            UnsupportedErrorKind::Color(color) => write!(
                fmt,
                "The decoder for {} does not support the color type `{:?}`",
                self.format,
                color,
            ),
            UnsupportedErrorKind::GenericFeature(message) => {
                match &self.format {
                    ImageFormatHint::Unknown => write!(
                        fmt,
                        "The decoder does not support the format feature {}",
                        message,
                    ),
                    other => write!(
                        fmt,
                        "The decoder for {} does not support the format features {}",
                        other,
                        message,
                    ),
                }
            },
            UnsupportedErrorKind::__NonExhaustive => unreachable!()
        }
    }
}

impl Error for UnsupportedError { }

impl fmt::Display for ParameterError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.kind {
            ParameterErrorKind::DimensionMismatch => write!(
                fmt,
                "The Image's dimensions are either too \
                 small or too large"
            ),
            ParameterErrorKind::FailedAlready => write!(
                fmt,
                "The end the image stream has been reached due to a previous error"
            ),
            ParameterErrorKind::Generic(message) => write!(
                fmt,
                "The parameter is malformed: {}",
                message,
            ),
            ParameterErrorKind::__NonExhaustive => unreachable!(),
        }?;

        if let Some(underlying) = &self.underlying {
            write!(fmt, "\n{}", underlying)?;
        }

        Ok(())
    }
}

impl Error for ParameterError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for EncodingError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.underlying {
            Some(underlying) => write!(
                fmt,
                "Format error encoding {}: {}\n{}",
                self.format,
                self.message,
                underlying,
            ),
            None => write!(
                fmt,
                "Format error encoding {}: {}",
                self.format,
                self.message,
            ),
        }
    }
}

impl Error for EncodingError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for DecodingError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.underlying {
            None => match self.format {
                ImageFormatHint::Unknown => write!(
                    fmt,
                    "Format error: {}",
                    self.message(),
                ),
                _ => write!(
                    fmt,
                    "Format error decoding {}: {}",
                    self.format,
                    self.message(),
                ),
            },
            Some(underlying) => write!(
                fmt,
                "Format error decoding {}: {}\n{}",
                self.format,
                self.message(),
                underlying,
            ),
        }
    }
}

impl Error for DecodingError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for LimitError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self.kind {
            LimitErrorKind::InsufficientMemory => write!(fmt, "Insufficient memory"),
            LimitErrorKind::DimensionError => write!(fmt, "Image is too large"),
            LimitErrorKind::__NonExhaustive => unreachable!(),
        }
    }
}

impl Error for LimitError { }

impl fmt::Display for ImageFormatHint {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self {
            ImageFormatHint::Exact(format) => write!(fmt, "{:?}", format),
            ImageFormatHint::Name(name) => write!(fmt, "`{}`", name),
            ImageFormatHint::PathExtension(ext) => write!(fmt, "`.{:?}`", ext),
            ImageFormatHint::Unknown => write!(fmt, "`Unknown`"),
            ImageFormatHint::__NonExhaustive => unreachable!(),
        }
    }
}
<commit_msg>Add test/assertions for ImageError marker impls<commit_after>//! Contains detailed error representation.

use std::{fmt, io, mem};
use std::error::Error;

use crate::color::ExtendedColorType;
use crate::image::ImageFormat;

/// The generic error type for image operations.
///
/// This high level enum is allows, by variant matching, a rough separation of concerns between
/// underlying IO, the caller, format specifications, and the `image` implementation.
#[derive(Debug)]
pub enum ImageError {
    /// An error was encountered while decoding.
    ///
    /// This means that the input data did not conform to the specification of some image format,
    /// or that no format could be determined, or that it did not match format specific
    /// requirements set by the caller.
    Decoding(DecodingError),

    /// An error was encountered while encoding.
    ///
    /// The input image can not be encoded with the chosen format, for example because the
    /// specification has no representation for its color space or because a necessary conversion
    /// is ambiguous. In some cases it might also happen that the dimensions can not be used with
    /// the format.
    Encoding(EncodingError),

    /// An error was encountered in inputs arguments.
    ///
    /// This is a catch-all case for strictly internal operations such as scaling, conversions,
    /// etc. that involve no external format specifications.
    Parameter(ParameterError),

    /// Completing the operation would have required more resources than allowed.
    ///
    /// Errors of this type are limits set by the user or environment, *not* inherent in a specific
    /// format or operation that was executed.
    Limits(LimitError),

    /// An operation can not be completed by the chosen abstraction.
    ///
    /// This means that it might be possible for the operation to succeed in general but
    /// * it requires a disabled feature,
    /// * the implementation does not yet exist, or
    /// * no abstraction for a lower level could be found.
    Unsupported(UnsupportedError),

    /// An error occurred while interacting with the environment.
    IoError(io::Error),
}

/// The implementation for an operation was not provided.
///
/// See the variant [`Unsupported`] for more documentation.
///
/// [`Unsupported`]: struct.ImageError.html#variant.Unsupported
#[derive(Debug)]
pub struct UnsupportedError {
    format: ImageFormatHint,
    kind: UnsupportedErrorKind,
}

/// Details what feature is not supported.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum UnsupportedErrorKind {
    /// The required color type can not be handled.
    Color(ExtendedColorType),
    /// An image format is not supported.
    Format(ImageFormatHint),
    /// Some feature specified by string.
    /// This is discouraged and is likely to get deprecated (but not removed).
    GenericFeature(String),
    #[doc(hidden)]
    __NonExhaustive,
}

#[derive(Debug)]
pub struct EncodingError {
    format: ImageFormatHint,
    message: String,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

#[derive(Debug)]
pub struct ParameterError {
    kind: ParameterErrorKind,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

/// Details how a parameter is malformed.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum ParameterErrorKind {
    /// Repeated an operation for which error that could not be cloned was emitted already.
    FailedAlready,
    /// The dimensions passed are wrong.
    DimensionMismatch,
    /// A string describing the parameter.
    /// This is discouraged and is likely to get deprecated (but not removed).
    Generic(String),
    #[doc(hidden)]
    __NonExhaustive,
}

#[derive(Debug)]
pub struct DecodingError {
    format: ImageFormatHint,
    message: Option<String>,
    underlying: Option<Box<dyn Error + Send + Sync>>,
}

#[derive(Debug)]
pub struct LimitError {
    kind: LimitErrorKind,
    // do we need an underlying error?
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
#[allow(missing_copy_implementations)] // Might be non-Copy in the future.
pub enum LimitErrorKind {
    DimensionError,
    InsufficientMemory,
    #[doc(hidden)]
    __NonExhaustive,
}

/// A best effort representation for image formats.
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum ImageFormatHint {
    /// The format is known exactly.
    Exact(ImageFormat),

    /// The format can be identified by a name.
    Name(String),

    /// A common path extension for the format is known.
    PathExtension(std::path::PathBuf),

    /// The format is not known or could not be determined.
    Unknown,

    #[doc(hidden)]
    __NonExhaustive,
}

// Internal implementation block for ImageError.
#[allow(non_upper_case_globals)]
#[allow(non_snake_case)]
impl ImageError {
    pub(crate) const InsufficientMemory: Self =
        ImageError::Limits(LimitError {
            kind: LimitErrorKind::InsufficientMemory,
        });

    pub(crate) const DimensionError: Self =
        ImageError::Parameter(ParameterError {
            kind: ParameterErrorKind::DimensionMismatch,
            underlying: None,
        });

    pub(crate) const ImageEnd: Self =
        ImageError::Parameter(ParameterError {
            kind: ParameterErrorKind::FailedAlready,
            underlying: None,
        });

    pub(crate) fn UnsupportedError(message: String) -> Self {
        ImageError::Unsupported(UnsupportedError::legacy_from_string(message))
    }

    pub(crate) fn UnsupportedColor(color: ExtendedColorType) -> Self {
        ImageError::Unsupported(UnsupportedError::new(
            ImageFormatHint::Unknown,
            UnsupportedErrorKind::Color(color),
        ))
    }

    pub(crate) fn FormatError(message: String) -> Self {
        ImageError::Decoding(DecodingError::legacy_from_string(message))
    }
}

impl UnsupportedError {
    pub fn new(format: ImageFormatHint, kind: UnsupportedErrorKind) -> Self {
        UnsupportedError {
            format,
            kind,
        }
    }

    pub(crate) fn legacy_from_string(message: String) -> Self {
        UnsupportedError {
            format: ImageFormatHint::Unknown,
            kind: UnsupportedErrorKind::GenericFeature(message),
        }
    }

    pub fn kind(&self) -> UnsupportedErrorKind {
        self.kind.clone()
    }

    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }
}

impl DecodingError {
    pub fn new(format: ImageFormatHint) -> Self {
        DecodingError {
            format,
            message: None,
            underlying: None,
        }
    }

    pub fn with_underlying(
        format: ImageFormatHint,
        err: impl Into<Box<dyn Error + Send + Sync>>,
    ) -> Self {
        DecodingError {
            format,
            message: None,
            underlying: Some(err.into()),
        }
    }

    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }

    pub(crate) fn legacy_from_string(message: String) -> Self {
        DecodingError {
            format: ImageFormatHint::Unknown,
            message: Some(message),
            underlying: None,
        }
    }

    /// Not quite legacy but also highly discouraged.
    /// This is just since the string typing is prevalent in the `image` decoders...
    // TODO: maybe a Cow? A constructor from `&'static str` wouldn't be too bad.
    pub(crate) fn with_message(
        format: ImageFormatHint,
        message: String,
    ) -> Self {
        DecodingError {
            format,
            message: Some(message),
            underlying: None,
        }
    }

    fn message(&self) -> &str {
        match self.message {
            Some(ref st) => st.as_str(),
            None => "",
        }
    }
}

impl EncodingError {
    pub fn format_hint(&self) -> ImageFormatHint {
        self.format.clone()
    }
}

impl ParameterError {
    pub fn new(kind: ParameterErrorKind) -> Self {
        ParameterError {
            kind,
            underlying: None,
        }
    }

    pub fn kind(&self) -> ParameterErrorKind {
        self.kind.clone()
    }
}

impl LimitError {
    pub fn kind(&self) -> LimitErrorKind {
        self.kind.clone()
    }
}

impl From<io::Error> for ImageError {
    fn from(err: io::Error) -> ImageError {
        ImageError::IoError(err)
    }
}

impl From<ImageFormat> for ImageFormatHint {
    fn from(format: ImageFormat) -> Self {
        ImageFormatHint::Exact(format)
    }
}

impl From<&'_ std::path::Path> for ImageFormatHint {
    fn from(path: &'_ std::path::Path) -> Self {
        match path.extension() {
            Some(ext) => ImageFormatHint::PathExtension(ext.into()),
            None => ImageFormatHint::Unknown,
        }
    }
}

impl From<ImageFormatHint> for UnsupportedError {
    fn from(hint: ImageFormatHint) -> Self {
        UnsupportedError {
            format: hint.clone(),
            kind: UnsupportedErrorKind::Format(hint),
        }
    }
}

/// Result of an image decoding/encoding process
pub type ImageResult<T> = Result<T, ImageError>;

impl fmt::Display for ImageError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self {
            ImageError::IoError(err) => err.fmt(fmt),
            ImageError::Decoding(err) => err.fmt(fmt),
            ImageError::Encoding(err) => err.fmt(fmt),
            ImageError::Parameter(err) => err.fmt(fmt),
            ImageError::Limits(err) => err.fmt(fmt),
            ImageError::Unsupported(err) => err.fmt(fmt),
        }
    }
}

impl Error for ImageError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            ImageError::IoError(err) => err.source(),
            ImageError::Decoding(err) => err.source(),
            ImageError::Encoding(err) => err.source(),
            ImageError::Parameter(err) => err.source(),
            ImageError::Limits(err) => err.source(),
            ImageError::Unsupported(err) => err.source(),
        }
    }
}

impl fmt::Display for UnsupportedError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.kind {
            UnsupportedErrorKind::Format(ImageFormatHint::Unknown) => write!(
                fmt,
                "The image format could not be determined",
            ),
            UnsupportedErrorKind::Format(format @ ImageFormatHint::PathExtension(_)) => write!(
                fmt,
                "The file extension {} was not recognized as an image format",
                format,
            ),
            UnsupportedErrorKind::Format(format) => write!(
                fmt,
                "The image format {} is not supported",
                format,
            ),
            UnsupportedErrorKind::Color(color) => write!(
                fmt,
                "The decoder for {} does not support the color type `{:?}`",
                self.format,
                color,
            ),
            UnsupportedErrorKind::GenericFeature(message) => {
                match &self.format {
                    ImageFormatHint::Unknown => write!(
                        fmt,
                        "The decoder does not support the format feature {}",
                        message,
                    ),
                    other => write!(
                        fmt,
                        "The decoder for {} does not support the format features {}",
                        other,
                        message,
                    ),
                }
            },
            UnsupportedErrorKind::__NonExhaustive => unreachable!()
        }
    }
}

impl Error for UnsupportedError { }

impl fmt::Display for ParameterError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.kind {
            ParameterErrorKind::DimensionMismatch => write!(
                fmt,
                "The Image's dimensions are either too \
                 small or too large"
            ),
            ParameterErrorKind::FailedAlready => write!(
                fmt,
                "The end the image stream has been reached due to a previous error"
            ),
            ParameterErrorKind::Generic(message) => write!(
                fmt,
                "The parameter is malformed: {}",
                message,
            ),
            ParameterErrorKind::__NonExhaustive => unreachable!(),
        }?;

        if let Some(underlying) = &self.underlying {
            write!(fmt, "\n{}", underlying)?;
        }

        Ok(())
    }
}

impl Error for ParameterError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for EncodingError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.underlying {
            Some(underlying) => write!(
                fmt,
                "Format error encoding {}: {}\n{}",
                self.format,
                self.message,
                underlying,
            ),
            None => write!(
                fmt,
                "Format error encoding {}: {}",
                self.format,
                self.message,
            ),
        }
    }
}

impl Error for EncodingError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for DecodingError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match &self.underlying {
            None => match self.format {
                ImageFormatHint::Unknown => write!(
                    fmt,
                    "Format error: {}",
                    self.message(),
                ),
                _ => write!(
                    fmt,
                    "Format error decoding {}: {}",
                    self.format,
                    self.message(),
                ),
            },
            Some(underlying) => write!(
                fmt,
                "Format error decoding {}: {}\n{}",
                self.format,
                self.message(),
                underlying,
            ),
        }
    }
}

impl Error for DecodingError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.underlying {
            None => None,
            Some(source) => Some(&**source),
        }
    }
}

impl fmt::Display for LimitError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self.kind {
            LimitErrorKind::InsufficientMemory => write!(fmt, "Insufficient memory"),
            LimitErrorKind::DimensionError => write!(fmt, "Image is too large"),
            LimitErrorKind::__NonExhaustive => unreachable!(),
        }
    }
}

impl Error for LimitError { }

impl fmt::Display for ImageFormatHint {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self {
            ImageFormatHint::Exact(format) => write!(fmt, "{:?}", format),
            ImageFormatHint::Name(name) => write!(fmt, "`{}`", name),
            ImageFormatHint::PathExtension(ext) => write!(fmt, "`.{:?}`", ext),
            ImageFormatHint::Unknown => write!(fmt, "`Unknown`"),
            ImageFormatHint::__NonExhaustive => unreachable!(),
        }
    }
}

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

    #[allow(dead_code)]
    // This will fail to compile if the size of this type is large.
    const ASSERT_SMALLISH: usize = [0][(mem::size_of::<ImageError>() >= 200) as usize];

    #[test]
    fn test_send_sync_stability() {
        fn assert_send_sync<T: Send + Sync>() { }

        assert_send_sync::<ImageError>();
    }
}
<|endoftext|>


<commit_before>//! Error types and conversion functions.

use std;
use std::error::Error;
use std::fmt;
use std::sync::Arc;

use gfx;
use glutin;
use winit;

use gilrs;
use image;
use lyon;
use rodio::decoder::DecoderError;
use toml;
use zip;

/// An enum containing all kinds of game framework errors.
#[derive(Debug, Clone)]
pub enum GameError {
    /// An error in the filesystem layout
    FilesystemError(String),
    /// An error in the config file
    ConfigError(String),
    /// Happens when an `winit::EventsLoopProxy` attempts to
    /// wake up an `winit::EventsLoop` that no longer exists.
    EventLoopError(String),
    /// An error trying to load a resource, such as getting an invalid image file.
    ResourceLoadError(String),
    /// Unable to find a resource; the `Vec` is the paths it searched for and associated errors
    ResourceNotFound(String, Vec<(std::path::PathBuf, GameError)>),
    /// Something went wrong in the renderer
    RenderError(String),
    /// Something went wrong in the audio playback
    AudioError(String),
    /// Something went wrong trying to set or get window properties.
    WindowError(String),
    /// Something went wrong trying to create a window
    WindowCreationError(Arc<glutin::CreationError>),
    /// Something went wrong trying to read from a file
    IOError(Arc<std::io::Error>),
    /// Something went wrong trying to load/render a font
    FontError(String),
    /// Something went wrong applying video settings.
    VideoError(String),
    /// Something went wrong compiling shaders
    ShaderProgramError(gfx::shade::ProgramError),
    /// Something went wrong with the `gilrs` gamepad-input library.
    GamepadError(String),
    /// Something went wrong with the `lyon` shape-tesselation library.
    LyonError(String),
}

impl fmt::Display for GameError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GameError::ConfigError(ref s) => write!(f, "Config error: {}", s),
            GameError::ResourceLoadError(ref s) => write!(f, "Error loading resource: {}", s),
            GameError::ResourceNotFound(ref s, ref paths) => write!(
                f,
                "Resource not found: {}, searched in paths {:?}",
                s, paths
            ),
            GameError::WindowError(ref e) => write!(f, "Window creation error: {}", e),
            _ => write!(f, "GameError {:?}", self),
        }
    }
}

impl Error for GameError {
    fn cause(&self) -> Option<&dyn Error> {
        match *self {
            GameError::WindowCreationError(ref e) => Some(&**e),
            GameError::IOError(ref e) => Some(&**e),
            GameError::ShaderProgramError(ref e) => Some(e),
            _ => None,
        }
    }
}

/// A convenient result type consisting of a return type and a `GameError`
pub type GameResult<T = ()> = Result<T, GameError>;

impl From<std::io::Error> for GameError {
    fn from(e: std::io::Error) -> GameError {
        GameError::IOError(Arc::new(e))
    }
}

impl From<toml::de::Error> for GameError {
    fn from(e: toml::de::Error) -> GameError {
        let errstr = format!("TOML decode error: {}", e.description());

        GameError::ConfigError(errstr)
    }
}

impl From<toml::ser::Error> for GameError {
    fn from(e: toml::ser::Error) -> GameError {
        let errstr = format!("TOML error (possibly encoding?): {}", e.description());
        GameError::ConfigError(errstr)
    }
}

impl From<zip::result::ZipError> for GameError {
    fn from(e: zip::result::ZipError) -> GameError {
        let errstr = format!("Zip error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<DecoderError> for GameError {
    fn from(e: DecoderError) -> GameError {
        let errstr = format!("Audio decoder error: {:?}", e);
        GameError::AudioError(errstr)
    }
}

impl From<image::ImageError> for GameError {
    fn from(e: image::ImageError) -> GameError {
        let errstr = format!("Image load error: {}", e.description());
        GameError::ResourceLoadError(errstr)
    }
}

impl From<gfx::PipelineStateError<std::string::String>> for GameError {
    fn from(e: gfx::PipelineStateError<std::string::String>) -> GameError {
        let errstr = format!(
            "Error constructing pipeline!\nThis should probably not be \
             happening; it probably means an error in a shader or \
             something.\nError was: {:?}",
            e
        );
        GameError::VideoError(errstr)
    }
}

impl From<gfx::mapping::Error> for GameError {
    fn from(e: gfx::mapping::Error) -> GameError {
        let errstr = format!("Buffer mapping error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl<S, D> From<gfx::CopyError<S, D>> for GameError
where
    S: fmt::Debug,
    D: fmt::Debug,
{
    fn from(e: gfx::CopyError<S, D>) -> GameError {
        let errstr = format!("Memory copy error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::CombinedError> for GameError {
    fn from(e: gfx::CombinedError) -> GameError {
        let errstr = format!("Texture+view load error: {}", e.description());
        GameError::VideoError(errstr)
    }
}

impl From<gfx::texture::CreationError> for GameError {
    fn from(e: gfx::texture::CreationError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::ResourceViewError> for GameError {
    fn from(e: gfx::ResourceViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::TargetViewError> for GameError {
    fn from(e: gfx::TargetViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl<T> From<gfx::UpdateError<T>> for GameError
where
    T: fmt::Debug + fmt::Display + 'static,
{
    fn from(e: gfx::UpdateError<T>) -> GameError {
        let errstr = format!("Buffer update error: {}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::shade::ProgramError> for GameError {
    fn from(e: gfx::shade::ProgramError) -> GameError {
        GameError::ShaderProgramError(e)
    }
}

impl From<winit::EventsLoopClosed> for GameError {
    fn from(_: glutin::EventsLoopClosed) -> GameError {
        let e = "An event loop proxy attempted to wake up an event loop that no longer exists."
            .to_owned();
        GameError::EventLoopError(e)
    }
}

impl From<glutin::CreationError> for GameError {
    fn from(s: glutin::CreationError) -> GameError {
        GameError::WindowCreationError(Arc::new(s))
    }
}

impl From<glutin::ContextError> for GameError {
    fn from(s: glutin::ContextError) -> GameError {
        GameError::RenderError(format!("OpenGL context error: {}", s))
    }
}

impl From<gilrs::Error> for GameError {
    fn from(s: gilrs::Error) -> GameError {
        let errstr = format!("Gamepad error: {}", s);
        GameError::GamepadError(errstr)
    }
}

impl From<lyon::lyon_tessellation::TessellationError> for GameError {
    fn from(s: lyon::lyon_tessellation::TessellationError) -> GameError {
        let errstr = format!(
            "Error while tesselating shape (did you give it an infinity or NaN?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}

impl From<lyon::lyon_tessellation::geometry_builder::GeometryBuilderError> for GameError {
    fn from(s: lyon::lyon_tessellation::geometry_builder::GeometryBuilderError) -> GameError {
        let errstr = format!(
            "Error while building geometry (did you give it too many vertices?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}
<commit_msg>Remove deprecated Error::description<commit_after>//! Error types and conversion functions.

use std;
use std::error::Error;
use std::fmt;
use std::sync::Arc;

use gfx;
use glutin;
use winit;

use gilrs;
use image;
use lyon;
use rodio::decoder::DecoderError;
use toml;
use zip;

/// An enum containing all kinds of game framework errors.
#[derive(Debug, Clone)]
pub enum GameError {
    /// An error in the filesystem layout
    FilesystemError(String),
    /// An error in the config file
    ConfigError(String),
    /// Happens when an `winit::EventsLoopProxy` attempts to
    /// wake up an `winit::EventsLoop` that no longer exists.
    EventLoopError(String),
    /// An error trying to load a resource, such as getting an invalid image file.
    ResourceLoadError(String),
    /// Unable to find a resource; the `Vec` is the paths it searched for and associated errors
    ResourceNotFound(String, Vec<(std::path::PathBuf, GameError)>),
    /// Something went wrong in the renderer
    RenderError(String),
    /// Something went wrong in the audio playback
    AudioError(String),
    /// Something went wrong trying to set or get window properties.
    WindowError(String),
    /// Something went wrong trying to create a window
    WindowCreationError(Arc<glutin::CreationError>),
    /// Something went wrong trying to read from a file
    IOError(Arc<std::io::Error>),
    /// Something went wrong trying to load/render a font
    FontError(String),
    /// Something went wrong applying video settings.
    VideoError(String),
    /// Something went wrong compiling shaders
    ShaderProgramError(gfx::shade::ProgramError),
    /// Something went wrong with the `gilrs` gamepad-input library.
    GamepadError(String),
    /// Something went wrong with the `lyon` shape-tesselation library.
    LyonError(String),
}

impl fmt::Display for GameError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GameError::ConfigError(ref s) => write!(f, "Config error: {}", s),
            GameError::ResourceLoadError(ref s) => write!(f, "Error loading resource: {}", s),
            GameError::ResourceNotFound(ref s, ref paths) => write!(
                f,
                "Resource not found: {}, searched in paths {:?}",
                s, paths
            ),
            GameError::WindowError(ref e) => write!(f, "Window creation error: {}", e),
            _ => write!(f, "GameError {:?}", self),
        }
    }
}

impl Error for GameError {
    fn cause(&self) -> Option<&dyn Error> {
        match *self {
            GameError::WindowCreationError(ref e) => Some(&**e),
            GameError::IOError(ref e) => Some(&**e),
            GameError::ShaderProgramError(ref e) => Some(e),
            _ => None,
        }
    }
}

/// A convenient result type consisting of a return type and a `GameError`
pub type GameResult<T = ()> = Result<T, GameError>;

impl From<std::io::Error> for GameError {
    fn from(e: std::io::Error) -> GameError {
        GameError::IOError(Arc::new(e))
    }
}

impl From<toml::de::Error> for GameError {
    fn from(e: toml::de::Error) -> GameError {
        let errstr = format!("TOML decode error: {}", e);

        GameError::ConfigError(errstr)
    }
}

impl From<toml::ser::Error> for GameError {
    fn from(e: toml::ser::Error) -> GameError {
        let errstr = format!("TOML error (possibly encoding?): {}", e);
        GameError::ConfigError(errstr)
    }
}

impl From<zip::result::ZipError> for GameError {
    fn from(e: zip::result::ZipError) -> GameError {
        let errstr = format!("Zip error: {}", e);
        GameError::ResourceLoadError(errstr)
    }
}

impl From<DecoderError> for GameError {
    fn from(e: DecoderError) -> GameError {
        let errstr = format!("Audio decoder error: {:?}", e);
        GameError::AudioError(errstr)
    }
}

impl From<image::ImageError> for GameError {
    fn from(e: image::ImageError) -> GameError {
        let errstr = format!("Image load error: {}", e);
        GameError::ResourceLoadError(errstr)
    }
}

impl From<gfx::PipelineStateError<std::string::String>> for GameError {
    fn from(e: gfx::PipelineStateError<std::string::String>) -> GameError {
        let errstr = format!(
            "Error constructing pipeline!\nThis should probably not be \
             happening; it probably means an error in a shader or \
             something.\nError was: {:?}",
            e
        );
        GameError::VideoError(errstr)
    }
}

impl From<gfx::mapping::Error> for GameError {
    fn from(e: gfx::mapping::Error) -> GameError {
        let errstr = format!("Buffer mapping error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl<S, D> From<gfx::CopyError<S, D>> for GameError
where
    S: fmt::Debug,
    D: fmt::Debug,
{
    fn from(e: gfx::CopyError<S, D>) -> GameError {
        let errstr = format!("Memory copy error: {:?}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::CombinedError> for GameError {
    fn from(e: gfx::CombinedError) -> GameError {
        let errstr = format!("Texture+view load error: {}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::texture::CreationError> for GameError {
    fn from(e: gfx::texture::CreationError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::ResourceViewError> for GameError {
    fn from(e: gfx::ResourceViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl From<gfx::TargetViewError> for GameError {
    fn from(e: gfx::TargetViewError) -> GameError {
        gfx::CombinedError::from(e).into()
    }
}

impl<T> From<gfx::UpdateError<T>> for GameError
where
    T: fmt::Debug + fmt::Display + 'static,
{
    fn from(e: gfx::UpdateError<T>) -> GameError {
        let errstr = format!("Buffer update error: {}", e);
        GameError::VideoError(errstr)
    }
}

impl From<gfx::shade::ProgramError> for GameError {
    fn from(e: gfx::shade::ProgramError) -> GameError {
        GameError::ShaderProgramError(e)
    }
}

impl From<winit::EventsLoopClosed> for GameError {
    fn from(_: glutin::EventsLoopClosed) -> GameError {
        let e = "An event loop proxy attempted to wake up an event loop that no longer exists."
            .to_owned();
        GameError::EventLoopError(e)
    }
}

impl From<glutin::CreationError> for GameError {
    fn from(s: glutin::CreationError) -> GameError {
        GameError::WindowCreationError(Arc::new(s))
    }
}

impl From<glutin::ContextError> for GameError {
    fn from(s: glutin::ContextError) -> GameError {
        GameError::RenderError(format!("OpenGL context error: {}", s))
    }
}

impl From<gilrs::Error> for GameError {
    fn from(s: gilrs::Error) -> GameError {
        let errstr = format!("Gamepad error: {}", s);
        GameError::GamepadError(errstr)
    }
}

impl From<lyon::lyon_tessellation::TessellationError> for GameError {
    fn from(s: lyon::lyon_tessellation::TessellationError) -> GameError {
        let errstr = format!(
            "Error while tesselating shape (did you give it an infinity or NaN?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}

impl From<lyon::lyon_tessellation::geometry_builder::GeometryBuilderError> for GameError {
    fn from(s: lyon::lyon_tessellation::geometry_builder::GeometryBuilderError) -> GameError {
        let errstr = format!(
            "Error while building geometry (did you give it too many vertices?): {:?}",
            s
        );
        GameError::LyonError(errstr)
    }
}
<|endoftext|>


<commit_before>#![feature(inclusive_range_syntax)]
//src: https://github.com/rustomax/rust-iterators#digging-deeper

fn main() {
	for j in 1...3 {
		for i in (1..11).map(|x| x +j) {
			print!("{} ", i);
		}
        println!("");
	}
}
<commit_msg>min/max of vector elements via iter()<commit_after>#![feature(inclusive_range_syntax)]
//src: https://github.com/rustomax/rust-iterators#digging-deeper

fn main() {
    for j in 1...3 {
        for i in (1..11).map(|x| x +j) {
            print!("{} ", i);
        }
        println!("");
    }

    let v = vec![3, 5, 0, -2, 3, 4, 1];
//    let v:Vec<i32> = vec![];
    let max = v.iter().max();
    let min = v.iter().min();

    println!("max = {:?}, min = {:?}", max, min);

    // output: max = Some(5), min = Some(-2)
}
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 Y. T. Chung

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

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

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

#![allow(dead_code)]

use std::io::{self, Read, BufRead, Write};
use std::cmp;

use crypto::{Cipher, CipherVariant};

/// Reader wrapper that will decrypt data automatically
pub struct DecryptedReader<R>
    where R: Read + 'static
{
    reader: R,
    buffer: Vec<u8>,
    cipher: CipherVariant,
    pos: usize,
    sent_final: bool,
}

const BUFFER_SIZE: usize = 2048;

impl<R> DecryptedReader<R>
    where R: Read + 'static
{
    pub fn new(r: R, cipher: CipherVariant) -> DecryptedReader<R> {
        DecryptedReader {
            reader: r,
            buffer: Vec::new(),
            cipher: cipher,
            pos: 0,
            sent_final: false,
        }
    }

    pub fn get_ref(&self) -> &R {
        &self.reader
    }

    /// Gets a mutable reference to the underlying reader.
    ///
    /// # Warning
    ///
    /// It is inadvisable to read directly from or write directly to the
    /// underlying reader.
    pub fn get_mut(&mut self) -> &mut R {
        &mut self.reader
    }

    /// Unwraps this `DecryptedReader`, returning the underlying reader.
    ///
    /// The internal buffer is flushed before returning the reader. Any leftover
    /// data in the read buffer is lost.
    pub fn into_inner(self) -> R {
        self.reader
    }
}

impl<R> BufRead for DecryptedReader<R>
    where R: Read + 'static
{
    fn fill_buf<'b>(&'b mut self) -> io::Result<&'b [u8]> {
        while self.pos >= self.buffer.len() {
            if self.sent_final {
                return Ok(&[]);
            }

            let mut incoming = [0u8; BUFFER_SIZE];
            self.buffer.clear();
            match self.reader.read(&mut incoming) {
                Ok(0) => {
                    // EOF
                    try!(self.cipher
                        .finalize(&mut self.buffer));
                    self.sent_final = true;
                }
                Ok(l) => {
                    try!(self.cipher
                        .update(&incoming[..l], &mut self.buffer));
                }
                Err(err) => {
                    return Err(err);
                }
            }

            self.pos = 0;
        }

        Ok(&self.buffer[self.pos..])
    }

    fn consume(&mut self, amt: usize) {
        self.pos = cmp::min(self.pos + amt, self.buffer.len());
    }
}

impl<R> Read for DecryptedReader<R>
    where R: Read + 'static
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let nread = {
            let mut available = try!(self.fill_buf());
            try!(available.read(buf))
        };
        self.consume(nread);
        Ok(nread)
    }
}

/// Writer wrapper that will encrypt data automatically
pub struct EncryptedWriter<W>
    where W: Write + 'static
{
    writer: W,
    cipher: CipherVariant,
    buffer: Vec<u8>,
}

impl<W> EncryptedWriter<W>
    where W: Write + 'static
{
    /// Creates a new EncryptedWriter
    pub fn new(w: W, cipher: CipherVariant) -> EncryptedWriter<W> {
        EncryptedWriter {
            writer: w,
            cipher: cipher,
            buffer: Vec::new(),
        }
    }

    /// Finalize the cipher, which will writes the final block into buffer
    pub fn finalize(&mut self) -> io::Result<()> {
        self.buffer.clear();
        match self.cipher.finalize(&mut self.buffer) {
            Ok(..) => {
                self.writer
                    .write_all(&self.buffer[..])
                    .and_then(|_| self.writer.flush())
            }
            Err(err) => Err(From::from(err)),
        }
    }

    /// Get reference to the inner writer
    pub fn get_ref(&self) -> &W {
        &self.writer
    }

    /// Gets a mutable reference to the underlying writer.
    ///
    /// # Warning
    ///
    /// It is inadvisable to read directly from or write directly to the
    /// underlying writer.
    pub fn get_mut(&mut self) -> &mut W {
        &mut self.writer
    }
}

impl<W> Write for EncryptedWriter<W>
    where W: Write + 'static
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.buffer.clear();
        match self.cipher.update(buf, &mut self.buffer) {
            Ok(..) => {
                match self.writer.write_all(&self.buffer[..]) {
                    Ok(..) => Ok(buf.len()),
                    Err(err) => Err(err),
                }
            }
            Err(err) => Err(From::from(err)),
        }
    }

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

impl<W> Drop for EncryptedWriter<W>
    where W: Write + 'static
{
    fn drop(&mut self) {
        let _ = self.finalize();
    }
}
<commit_msg>Fixed #28, should not use write_all on non-blocking sockets<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 Y. T. Chung

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

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

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

#![allow(dead_code)]

use std::io::{self, Read, BufRead, Write};
use std::cmp;

use crypto::{Cipher, CipherVariant};

/// Reader wrapper that will decrypt data automatically
pub struct DecryptedReader<R>
    where R: Read + 'static
{
    reader: R,
    buffer: Vec<u8>,
    cipher: CipherVariant,
    pos: usize,
    sent_final: bool,
}

const BUFFER_SIZE: usize = 2048;

impl<R> DecryptedReader<R>
    where R: Read + 'static
{
    pub fn new(r: R, cipher: CipherVariant) -> DecryptedReader<R> {
        DecryptedReader {
            reader: r,
            buffer: Vec::new(),
            cipher: cipher,
            pos: 0,
            sent_final: false,
        }
    }

    pub fn get_ref(&self) -> &R {
        &self.reader
    }

    /// Gets a mutable reference to the underlying reader.
    ///
    /// # Warning
    ///
    /// It is inadvisable to read directly from or write directly to the
    /// underlying reader.
    pub fn get_mut(&mut self) -> &mut R {
        &mut self.reader
    }

    /// Unwraps this `DecryptedReader`, returning the underlying reader.
    ///
    /// The internal buffer is flushed before returning the reader. Any leftover
    /// data in the read buffer is lost.
    pub fn into_inner(self) -> R {
        self.reader
    }
}

impl<R> BufRead for DecryptedReader<R>
    where R: Read + 'static
{
    fn fill_buf<'b>(&'b mut self) -> io::Result<&'b [u8]> {
        while self.pos >= self.buffer.len() {
            if self.sent_final {
                return Ok(&[]);
            }

            let mut incoming = [0u8; BUFFER_SIZE];
            self.buffer.clear();
            match self.reader.read(&mut incoming) {
                Ok(0) => {
                    // EOF
                    try!(self.cipher
                        .finalize(&mut self.buffer));
                    self.sent_final = true;
                }
                Ok(l) => {
                    try!(self.cipher
                        .update(&incoming[..l], &mut self.buffer));
                }
                Err(err) => {
                    return Err(err);
                }
            }

            self.pos = 0;
        }

        Ok(&self.buffer[self.pos..])
    }

    fn consume(&mut self, amt: usize) {
        self.pos = cmp::min(self.pos + amt, self.buffer.len());
    }
}

impl<R> Read for DecryptedReader<R>
    where R: Read + 'static
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let nread = {
            let mut available = try!(self.fill_buf());
            try!(available.read(buf))
        };
        self.consume(nread);
        Ok(nread)
    }
}

/// Writer wrapper that will encrypt data automatically
pub struct EncryptedWriter<W>
    where W: Write + 'static
{
    writer: W,
    cipher: CipherVariant,
    buffer: Vec<u8>,
}

impl<W> EncryptedWriter<W>
    where W: Write + 'static
{
    /// Creates a new EncryptedWriter
    pub fn new(w: W, cipher: CipherVariant) -> EncryptedWriter<W> {
        EncryptedWriter {
            writer: w,
            cipher: cipher,
            buffer: Vec::new(),
        }
    }

    /// Finalize the cipher, which will writes the final block into buffer
    pub fn finalize(&mut self) -> io::Result<()> {
        match self.cipher.finalize(&mut self.buffer) {
            Ok(..) => {
                self.writer
                    .write_all(&self.buffer[..])
                    .and_then(|_| self.writer.flush())
            }
            Err(err) => Err(From::from(err)),
        }
    }

    /// Get reference to the inner writer
    pub fn get_ref(&self) -> &W {
        &self.writer
    }

    /// Gets a mutable reference to the underlying writer.
    ///
    /// # Warning
    ///
    /// It is inadvisable to read directly from or write directly to the
    /// underlying writer.
    pub fn get_mut(&mut self) -> &mut W {
        &mut self.writer
    }
}

impl<W> Write for EncryptedWriter<W>
    where W: Write + 'static
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.cipher.update(buf, &mut self.buffer) {
            Ok(..) => {
                let len = try!(self.writer.write(&self.buffer[..]));
                self.buffer.drain(..len);
                Ok(len)
            }
            Err(err) => Err(From::from(err)),
        }
    }

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

impl<W> Drop for EncryptedWriter<W>
    where W: Write + 'static
{
    fn drop(&mut self) {
        let _ = self.finalize();
    }
}
<|endoftext|>