<commit_before>pub mod err;

pub use err::{Error, Result};

use anime::remote::SeriesInfo;
use once_cell::sync::Lazy;
use regex::Regex;
use snafu::{OptionExt, ResultExt};
use std::borrow::Cow;
use std::fs;
use std::path::{Path, PathBuf};

#[inline]
pub fn best_matching_title<'a, S>(
    name: S,
    titles: impl Iterator<Item = Cow<'a, str>>,
) -> Option<Cow<'a, str>>
where
    S: Into<String>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    closest_match(titles, MIN_CONFIDENCE, |title| {
        let title = title.to_ascii_lowercase();
        Some(strsim::jaro(&title, &name) as f32)
    })
}

#[inline]
pub fn best_matching_info<S>(name: S, items: impl Iterator<Item = SeriesInfo>) -> Option<SeriesInfo>
where
    S: Into<String>,
{
    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    closest_match(items, 0.6, |info| {
        let title = info.title.romaji.to_ascii_lowercase();
        Some(strsim::jaro_winkler(&title, &name) as f32)
    })
}

pub fn best_matching_folder<S, P>(name: S, dir: P) -> Result<PathBuf>
where
    S: Into<String>,
    P: AsRef<Path>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let dir = dir.as_ref();
    let entries = fs::read_dir(dir).context(err::FileIO { path: dir })?;

    let mut dirs = Vec::new();

    for entry in entries {
        let entry = entry.context(err::EntryIO { dir })?;
        let etype = entry.file_type().context(err::EntryIO { dir })?;

        if !etype.is_dir() {
            continue;
        }

        dirs.push(entry);
    }

    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    let dir = closest_match(dirs, MIN_CONFIDENCE, |dir| {
        let mut dir_name = parse_folder_title(dir.file_name().to_string_lossy())?;
        dir_name.make_ascii_lowercase();
        Some(strsim::jaro(&dir_name, &name) as f32)
    })
    .context(err::NoMatchingSeries { name })?;

    Ok(dir.path())
}

/// Find the best matching item in `items` via `matcher` and return it if the maximum confidence is greater than `min_confidence`.
///
/// `min_confidence` should be a value between 0.0 and 1.0.
///
/// `matcher` is used to compare each item in `items`. When returning Some, its value should be between 0.0 and 1.0.
/// This value represents the "confidence" (or similarity) between the item and some other value.
///
/// If `matcher` returns a confidence greater than 0.99, that item will be immediately returned.
pub fn closest_match<'a, I, T, F>(items: I, min_confidence: f32, matcher: F) -> Option<T>
where
    I: IntoIterator<Item = T>,
    F: Fn(&T) -> Option<f32>,
{
    let mut max_score = 0.0;
    let mut best_match = None;

    for item in items.into_iter() {
        let score = match matcher(&item) {
            Some(score) => score,
            None => continue,
        };

        if score > max_score {
            if score > 0.99 {
                return Some(item);
            }

            best_match = Some(item);
            max_score = score;
        }
    }

    if max_score < min_confidence {
        return None;
    }

    best_match
}

pub fn parse_folder_title<S>(item: S) -> Option<String>
where
    S: AsRef<str>,
{
    // This pattern parses titles out of strings like this:
    // [GroupName] Series Title (01-13) [1080p]
    static EXTRACT_SERIES_TITLE: Lazy<Regex> =
        Lazy::new(|| Regex::new(r"(?:\[.+?\]\s*)?(?P<title>.+?)(?:\(|\[|$)").unwrap());

    let caps = EXTRACT_SERIES_TITLE.captures(item.as_ref())?;
    let title = caps["title"].to_string();

    Some(title)
}
<commit_msg>detect: remove unnecessary lifetime<commit_after>pub mod err;

pub use err::{Error, Result};

use anime::remote::SeriesInfo;
use once_cell::sync::Lazy;
use regex::Regex;
use snafu::{OptionExt, ResultExt};
use std::borrow::Cow;
use std::fs;
use std::path::{Path, PathBuf};

#[inline]
pub fn best_matching_title<'a, S>(
    name: S,
    titles: impl Iterator<Item = Cow<'a, str>>,
) -> Option<Cow<'a, str>>
where
    S: Into<String>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    closest_match(titles, MIN_CONFIDENCE, |title| {
        let title = title.to_ascii_lowercase();
        Some(strsim::jaro(&title, &name) as f32)
    })
}

#[inline]
pub fn best_matching_info<S>(name: S, items: impl Iterator<Item = SeriesInfo>) -> Option<SeriesInfo>
where
    S: Into<String>,
{
    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    closest_match(items, 0.6, |info| {
        let title = info.title.romaji.to_ascii_lowercase();
        Some(strsim::jaro_winkler(&title, &name) as f32)
    })
}

pub fn best_matching_folder<S, P>(name: S, dir: P) -> Result<PathBuf>
where
    S: Into<String>,
    P: AsRef<Path>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let dir = dir.as_ref();
    let entries = fs::read_dir(dir).context(err::FileIO { path: dir })?;

    let mut dirs = Vec::new();

    for entry in entries {
        let entry = entry.context(err::EntryIO { dir })?;
        let etype = entry.file_type().context(err::EntryIO { dir })?;

        if !etype.is_dir() {
            continue;
        }

        dirs.push(entry);
    }

    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    let dir = closest_match(dirs, MIN_CONFIDENCE, |dir| {
        let mut dir_name = parse_folder_title(dir.file_name().to_string_lossy())?;
        dir_name.make_ascii_lowercase();
        Some(strsim::jaro(&dir_name, &name) as f32)
    })
    .context(err::NoMatchingSeries { name })?;

    Ok(dir.path())
}

/// Find the best matching item in `items` via `matcher` and return it if the maximum confidence is greater than `min_confidence`.
///
/// `min_confidence` should be a value between 0.0 and 1.0.
///
/// `matcher` is used to compare each item in `items`. When returning Some, its value should be between 0.0 and 1.0.
/// This value represents the "confidence" (or similarity) between the item and some other value.
///
/// If `matcher` returns a confidence greater than 0.99, that item will be immediately returned.
pub fn closest_match<I, T, F>(items: I, min_confidence: f32, matcher: F) -> Option<T>
where
    I: IntoIterator<Item = T>,
    F: Fn(&T) -> Option<f32>,
{
    let mut max_score = 0.0;
    let mut best_match = None;

    for item in items.into_iter() {
        let score = match matcher(&item) {
            Some(score) => score,
            None => continue,
        };

        if score > max_score {
            if score > 0.99 {
                return Some(item);
            }

            best_match = Some(item);
            max_score = score;
        }
    }

    if max_score < min_confidence {
        return None;
    }

    best_match
}

pub fn parse_folder_title<S>(item: S) -> Option<String>
where
    S: AsRef<str>,
{
    // This pattern parses titles out of strings like this:
    // [GroupName] Series Title (01-13) [1080p]
    static EXTRACT_SERIES_TITLE: Lazy<Regex> =
        Lazy::new(|| Regex::new(r"(?:\[.+?\]\s*)?(?P<title>.+?)(?:\(|\[|$)").unwrap());

    let caps = EXTRACT_SERIES_TITLE.captures(item.as_ref())?;
    let title = caps["title"].to_string();

    Some(title)
}
<|endoftext|>


<commit_before>#[doc(
    brief = "Provides all access to AST-related, non-sendable info",
    desc =
    "Rustdoc is intended to be parallel, and the rustc AST is filled \
     with shared boxes. The AST service attempts to provide a single \
     place to query AST-related information, shielding the rest of \
     Rustdoc from its non-sendableness."
)];

import rustc::driver::session;
import rustc::driver::driver;
import rustc::driver::diagnostic;
import rustc::driver::diagnostic::handler;
import rustc::syntax::ast;
import rustc::syntax::codemap;
import rustc::middle::ast_map;
import rustc::back::link;
import rustc::util::filesearch;
import rustc::front;
import rustc::middle::resolve;

export ctxt;
export ctxt_handler;
export srv;
export mk_srv_from_str;
export mk_srv_from_file;
export exec;

type ctxt = {
    ast: @ast::crate,
    ast_map: ast_map::map,
    exp_map: resolve::exp_map
};

type ctxt_handler<T> = fn~(ctxt: ctxt) -> T;

type srv = {
    ctxt: ctxt
};

fn mk_srv_from_str(source: str) -> srv {
    let (sess, ignore_errors) = build_session();
    {
        ctxt: build_ctxt(sess, parse::from_str_sess(sess, source),
                         ignore_errors)
    }
}

fn mk_srv_from_file(file: str) -> srv {
    let (sess, ignore_errors) = build_session();
    {
        ctxt: build_ctxt(sess, parse::from_file_sess(sess, file),
                         ignore_errors)
    }
}

fn build_ctxt(sess: session::session, ast: @ast::crate,
              ignore_errors: @mutable bool) -> ctxt {

    import rustc::front::config;

    let ast = config::strip_unconfigured_items(ast);
    let ast = front::test::modify_for_testing(sess, ast);
    let ast_map = ast_map::map_crate(*ast);
    *ignore_errors = true;
    let exp_map = resolve::resolve_crate_reexports(sess, ast_map, ast);
    *ignore_errors = false;

    {
        ast: ast,
        ast_map: ast_map,
        exp_map: exp_map
    }
}

// FIXME: this whole structure should not be duplicated here. makes it
// painful to add or remove options.
fn build_session() -> (session::session, @mutable bool) {
    let sopts: @session::options = @{
        crate_type: session::lib_crate,
        static: false,
        optimize: 0u,
        debuginfo: false,
        extra_debuginfo: false,
        verify: false,
        lint_opts: [],
        save_temps: false,
        stats: false,
        time_passes: false,
        time_llvm_passes: false,
        output_type: link::output_type_exe,
        addl_lib_search_paths: [],
        maybe_sysroot: none,
        target_triple: driver::host_triple(),
        cfg: [],
        test: false,
        parse_only: false,
        no_trans: false,
        no_asm_comments: false,
        monomorphize: false,
        warn_unused_imports: false
    };

    let codemap = codemap::new_codemap();
    let error_handlers = build_error_handlers(codemap);
    let {emitter, span_handler, ignore_errors} = error_handlers;

    let session = driver::build_session_(sopts, ".", codemap, emitter,
                                         span_handler);
    (session, ignore_errors)
}

type error_handlers = {
    emitter: diagnostic::emitter,
    span_handler: diagnostic::span_handler,
    ignore_errors: @mutable bool
};

// Build a custom error handler that will allow us to ignore non-fatal
// errors
fn build_error_handlers(
    codemap: codemap::codemap
) -> error_handlers {

    type diagnostic_handler = {
        inner: diagnostic::handler,
        ignore_errors: @mutable bool
    };

    impl of diagnostic::handler for diagnostic_handler {
        fn fatal(msg: str) -> ! { self.inner.fatal(msg) }
        fn err(msg: str) { self.inner.err(msg) }
        fn bump_err_count() {
            if !(*self.ignore_errors) {
                self.inner.bump_err_count();
            }
        }
        fn has_errors() -> bool { self.inner.has_errors() }
        fn abort_if_errors() { self.inner.abort_if_errors() }
        fn warn(msg: str) { self.inner.warn(msg) }
        fn note(msg: str) { self.inner.note(msg) }
        fn bug(msg: str) -> ! { self.inner.bug(msg) }
        fn unimpl(msg: str) -> ! { self.inner.unimpl(msg) }
        fn emit(cmsp: option<(codemap::codemap, codemap::span)>,
                msg: str, lvl: diagnostic::level) {
            self.inner.emit(cmsp, msg, lvl)
        }
    }

    let ignore_errors = @mutable false;
    let emitter = fn@(cmsp: option<(codemap::codemap, codemap::span)>,
                       msg: str, lvl: diagnostic::level) {
        if !(*ignore_errors) {
            diagnostic::emit(cmsp, msg, lvl);
        }
    };
    let inner_handler = diagnostic::mk_handler(some(emitter));
    let handler = {
        inner: inner_handler,
        ignore_errors: ignore_errors
    };
    let span_handler = diagnostic::mk_span_handler(
        handler as diagnostic::handler, codemap);

    {
        emitter: emitter,
        span_handler: span_handler,
        ignore_errors: ignore_errors
    }
}

#[test]
fn should_prune_unconfigured_items() {
    let source = "#[cfg(shut_up_and_leave_me_alone)]fn a() { }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert vec::is_empty(ctxt.ast.node.module.items);
    }
}

#[test]
fn srv_should_build_ast_map() {
    let source = "fn a() { }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert ctxt.ast_map.size() != 0u
    };
}

#[test]
fn srv_should_build_reexport_map() {
    let source = "import a::b; export b; mod a { mod b { } }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert ctxt.exp_map.size() != 0u
    };
}

#[test]
fn srv_should_resolve_external_crates() {
    let source = "use std;\
                  fn f() -> std::sha1::sha1 {\
                  std::sha1::mk_sha1() }";
    // Just testing that resolve doesn't crash
    mk_srv_from_str(source);
}

#[test]
fn srv_should_resolve_core_crate() {
    let source = "fn a() -> option { fail }";
    // Just testing that resolve doesn't crash
    mk_srv_from_str(source);
}

#[test]
fn srv_should_resolve_non_existant_imports() {
    // We want to ignore things we can't resolve. Shouldn't
    // need to be able to find external crates to create docs.
    let source = "import wooboo; fn a() { }";
    mk_srv_from_str(source);
}

#[test]
fn srv_sholud_resolve_non_existant_uses() {
    let source = "use forble; fn a() { }";
    mk_srv_from_str(source);
}

fn exec<T>(
    srv: srv,
    f: fn~(ctxt: ctxt) -> T
) -> T {
    f(srv.ctxt)
}

#[test]
fn srv_should_return_request_result() {
    let source = "fn a() { }";
    let srv = mk_srv_from_str(source);
    let result = exec(srv) {|_ctxt| 1000};
    assert result == 1000;
}
<commit_msg>rustdoc: Add a test that we can tolerate missing external crates<commit_after>#[doc(
    brief = "Provides all access to AST-related, non-sendable info",
    desc =
    "Rustdoc is intended to be parallel, and the rustc AST is filled \
     with shared boxes. The AST service attempts to provide a single \
     place to query AST-related information, shielding the rest of \
     Rustdoc from its non-sendableness."
)];

import rustc::driver::session;
import rustc::driver::driver;
import rustc::driver::diagnostic;
import rustc::driver::diagnostic::handler;
import rustc::syntax::ast;
import rustc::syntax::codemap;
import rustc::middle::ast_map;
import rustc::back::link;
import rustc::util::filesearch;
import rustc::front;
import rustc::middle::resolve;

export ctxt;
export ctxt_handler;
export srv;
export mk_srv_from_str;
export mk_srv_from_file;
export exec;

type ctxt = {
    ast: @ast::crate,
    ast_map: ast_map::map,
    exp_map: resolve::exp_map
};

type ctxt_handler<T> = fn~(ctxt: ctxt) -> T;

type srv = {
    ctxt: ctxt
};

fn mk_srv_from_str(source: str) -> srv {
    let (sess, ignore_errors) = build_session();
    {
        ctxt: build_ctxt(sess, parse::from_str_sess(sess, source),
                         ignore_errors)
    }
}

fn mk_srv_from_file(file: str) -> srv {
    let (sess, ignore_errors) = build_session();
    {
        ctxt: build_ctxt(sess, parse::from_file_sess(sess, file),
                         ignore_errors)
    }
}

fn build_ctxt(sess: session::session, ast: @ast::crate,
              ignore_errors: @mutable bool) -> ctxt {

    import rustc::front::config;

    let ast = config::strip_unconfigured_items(ast);
    let ast = front::test::modify_for_testing(sess, ast);
    let ast_map = ast_map::map_crate(*ast);
    *ignore_errors = true;
    let exp_map = resolve::resolve_crate_reexports(sess, ast_map, ast);
    *ignore_errors = false;

    {
        ast: ast,
        ast_map: ast_map,
        exp_map: exp_map
    }
}

// FIXME: this whole structure should not be duplicated here. makes it
// painful to add or remove options.
fn build_session() -> (session::session, @mutable bool) {
    let sopts: @session::options = @{
        crate_type: session::lib_crate,
        static: false,
        optimize: 0u,
        debuginfo: false,
        extra_debuginfo: false,
        verify: false,
        lint_opts: [],
        save_temps: false,
        stats: false,
        time_passes: false,
        time_llvm_passes: false,
        output_type: link::output_type_exe,
        addl_lib_search_paths: [],
        maybe_sysroot: none,
        target_triple: driver::host_triple(),
        cfg: [],
        test: false,
        parse_only: false,
        no_trans: false,
        no_asm_comments: false,
        monomorphize: false,
        warn_unused_imports: false
    };

    let codemap = codemap::new_codemap();
    let error_handlers = build_error_handlers(codemap);
    let {emitter, span_handler, ignore_errors} = error_handlers;

    let session = driver::build_session_(sopts, ".", codemap, emitter,
                                         span_handler);
    (session, ignore_errors)
}

type error_handlers = {
    emitter: diagnostic::emitter,
    span_handler: diagnostic::span_handler,
    ignore_errors: @mutable bool
};

// Build a custom error handler that will allow us to ignore non-fatal
// errors
fn build_error_handlers(
    codemap: codemap::codemap
) -> error_handlers {

    type diagnostic_handler = {
        inner: diagnostic::handler,
        ignore_errors: @mutable bool
    };

    impl of diagnostic::handler for diagnostic_handler {
        fn fatal(msg: str) -> ! { self.inner.fatal(msg) }
        fn err(msg: str) { self.inner.err(msg) }
        fn bump_err_count() {
            if !(*self.ignore_errors) {
                self.inner.bump_err_count();
            }
        }
        fn has_errors() -> bool { self.inner.has_errors() }
        fn abort_if_errors() { self.inner.abort_if_errors() }
        fn warn(msg: str) { self.inner.warn(msg) }
        fn note(msg: str) { self.inner.note(msg) }
        fn bug(msg: str) -> ! { self.inner.bug(msg) }
        fn unimpl(msg: str) -> ! { self.inner.unimpl(msg) }
        fn emit(cmsp: option<(codemap::codemap, codemap::span)>,
                msg: str, lvl: diagnostic::level) {
            self.inner.emit(cmsp, msg, lvl)
        }
    }

    let ignore_errors = @mutable false;
    let emitter = fn@(cmsp: option<(codemap::codemap, codemap::span)>,
                       msg: str, lvl: diagnostic::level) {
        if !(*ignore_errors) {
            diagnostic::emit(cmsp, msg, lvl);
        }
    };
    let inner_handler = diagnostic::mk_handler(some(emitter));
    let handler = {
        inner: inner_handler,
        ignore_errors: ignore_errors
    };
    let span_handler = diagnostic::mk_span_handler(
        handler as diagnostic::handler, codemap);

    {
        emitter: emitter,
        span_handler: span_handler,
        ignore_errors: ignore_errors
    }
}

#[test]
fn should_prune_unconfigured_items() {
    let source = "#[cfg(shut_up_and_leave_me_alone)]fn a() { }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert vec::is_empty(ctxt.ast.node.module.items);
    }
}

#[test]
fn srv_should_build_ast_map() {
    let source = "fn a() { }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert ctxt.ast_map.size() != 0u
    };
}

#[test]
fn srv_should_build_reexport_map() {
    let source = "import a::b; export b; mod a { mod b { } }";
    let srv = mk_srv_from_str(source);
    exec(srv) {|ctxt|
        assert ctxt.exp_map.size() != 0u
    };
}

#[test]
fn srv_should_resolve_external_crates() {
    let source = "use std;\
                  fn f() -> std::sha1::sha1 {\
                  std::sha1::mk_sha1() }";
    // Just testing that resolve doesn't crash
    mk_srv_from_str(source);
}

#[test]
fn srv_should_resolve_core_crate() {
    let source = "fn a() -> option { fail }";
    // Just testing that resolve doesn't crash
    mk_srv_from_str(source);
}

#[test]
fn srv_should_resolve_non_existant_imports() {
    // We want to ignore things we can't resolve. Shouldn't
    // need to be able to find external crates to create docs.
    let source = "import wooboo; fn a() { }";
    mk_srv_from_str(source);
}

#[test]
fn srv_should_resolve_non_existant_uses() {
    let source = "use forble; fn a() { }";
    mk_srv_from_str(source);
}

#[test]
fn should_ignore_external_import_paths_that_dont_exist() {
    let source = "use forble; import forble::bippy;";
    mk_srv_from_str(source);
}

fn exec<T>(
    srv: srv,
    f: fn~(ctxt: ctxt) -> T
) -> T {
    f(srv.ctxt)
}

#[test]
fn srv_should_return_request_result() {
    let source = "fn a() { }";
    let srv = mk_srv_from_str(source);
    let result = exec(srv) {|_ctxt| 1000};
    assert result == 1000;
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use {Future, Poll, Async};
use slot::{Slot, Token};
use stream::Stream;
use task;

/// Creates an in-memory channel implementation of the `Stream` trait.
///
/// This method creates a concrete implementation of the `Stream` trait which
/// can be used to send values across threads in a streaming fashion. This
/// channel is unique in that it implements back pressure to ensure that the
/// sender never outpaces the receiver. The `Sender::send` method will only
/// allow sending one message and the next message can only be sent once the
/// first was consumed.
///
/// The `Receiver` returned implements the `Stream` trait and has access to any
/// number of the associated combinators for transforming the result.
pub fn channel<T, E>() -> (Sender<T, E>, Receiver<T, E>) {
    let inner = Arc::new(Inner {
        slot: Slot::new(None),
        receiver_gone: AtomicBool::new(false),
    });
    let sender = Sender {
        inner: inner.clone(),
    };
    let receiver = Receiver {
        inner: inner,
        on_full_token: None,
    };
    (sender, receiver)
}

/// The transmission end of a channel which is used to send values.
///
/// This is created by the `channel` method in the `stream` module.
pub struct Sender<T, E> {
    inner: Arc<Inner<T, E>>,
}

/// A future returned by the `Sender::send` method which will resolve to the
/// sender once it's available to send another message.
#[must_use = "futures do nothing unless polled"]
pub struct FutureSender<T, E> {
    sender: Option<Sender<T, E>>,
    data: Option<Result<T, E>>,
    on_empty_token: Option<Token>,
}

/// The receiving end of a channel which implements the `Stream` trait.
///
/// This is a concrete implementation of a stream which can be used to represent
/// a stream of values being computed elsewhere. This is created by the
/// `channel` method in the `stream` module.
#[must_use = "streams do nothing unless polled"]
pub struct Receiver<T, E> {
    inner: Arc<Inner<T, E>>,
    on_full_token: Option<Token>,
}

struct Inner<T, E> {
    slot: Slot<Message<Result<T, E>>>,
    receiver_gone: AtomicBool,
}

enum Message<T> {
    Data(T),
    Done,
}

pub struct SendError<T, E>(Result<T, E>);

impl<T, E> Stream for Receiver<T, E> {
    type Item = T;
    type Error = E;

    fn poll(&mut self) -> Poll<Option<T>, E> {
        if let Some(token) = self.on_full_token.take() {
            self.inner.slot.cancel(token);
        }

        match self.inner.slot.try_consume() {
            Ok(Message::Data(Ok(e))) => Ok(Async::Ready(Some(e))),
            Ok(Message::Data(Err(e))) => Err(e),
            Ok(Message::Done) => Ok(Async::Ready(None)),
            Err(..) => {
                let task = task::park();
                self.on_full_token = Some(self.inner.slot.on_full(move |_| {
                    task.unpark();
                }));
                Ok(Async::NotReady)
            }
        }
    }
}

impl<T, E> Drop for Receiver<T, E> {
    fn drop(&mut self) {
        self.inner.receiver_gone.store(true, Ordering::SeqCst);
        if let Some(token) = self.on_full_token.take() {
            self.inner.slot.cancel(token);
        }
        self.inner.slot.on_full(|slot| {
            drop(slot.try_consume());
        });
    }
}

impl<T, E> Sender<T, E> {
    /// Sends a new value along this channel to the receiver.
    ///
    /// This method consumes the sender and returns a future which will resolve
    /// to the sender again when the value sent has been consumed.
    pub fn send(self, t: Result<T, E>) -> FutureSender<T, E> {
        FutureSender {
            sender: Some(self),
            data: Some(t),
            on_empty_token: None,
        }
    }
}

impl<T, E> Drop for Sender<T, E> {
    fn drop(&mut self) {
        self.inner.slot.on_empty(None, |slot, _none| {
            slot.try_produce(Message::Done).ok().unwrap();
        });
    }
}

impl<T, E> Future for FutureSender<T, E> {
    type Item = Sender<T, E>;
    type Error = SendError<T, E>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let data = self.data.take().expect("cannot poll FutureSender twice");
        let sender = self.sender.take().expect("cannot poll FutureSender twice");
        if let Some(token) = self.on_empty_token.take() {
            sender.inner.slot.cancel(token);
        }
        if sender.inner.receiver_gone.load(Ordering::SeqCst) {
            return Err(SendError(data))
        }
        match sender.inner.slot.try_produce(Message::Data(data)) {
            Ok(()) => Ok(Async::Ready(sender)),
            Err(e) => {
                let task = task::park();
                let token = sender.inner.slot.on_empty(None, move |_slot, _item| {
                    task.unpark();
                });
                self.on_empty_token = Some(token);
                self.data = Some(match e.into_inner() {
                    Message::Data(data) => data,
                    Message::Done => panic!(),
                });
                self.sender = Some(sender);
                Ok(Async::NotReady)
            }
        }
    }
}
<commit_msg>impl Debug for SendError<commit_after>use std::any::Any;
use std::error::Error;
use std::fmt;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use {Future, Poll, Async};
use slot::{Slot, Token};
use stream::Stream;
use task;

/// Creates an in-memory channel implementation of the `Stream` trait.
///
/// This method creates a concrete implementation of the `Stream` trait which
/// can be used to send values across threads in a streaming fashion. This
/// channel is unique in that it implements back pressure to ensure that the
/// sender never outpaces the receiver. The `Sender::send` method will only
/// allow sending one message and the next message can only be sent once the
/// first was consumed.
///
/// The `Receiver` returned implements the `Stream` trait and has access to any
/// number of the associated combinators for transforming the result.
pub fn channel<T, E>() -> (Sender<T, E>, Receiver<T, E>) {
    let inner = Arc::new(Inner {
        slot: Slot::new(None),
        receiver_gone: AtomicBool::new(false),
    });
    let sender = Sender {
        inner: inner.clone(),
    };
    let receiver = Receiver {
        inner: inner,
        on_full_token: None,
    };
    (sender, receiver)
}

/// The transmission end of a channel which is used to send values.
///
/// This is created by the `channel` method in the `stream` module.
pub struct Sender<T, E> {
    inner: Arc<Inner<T, E>>,
}

/// A future returned by the `Sender::send` method which will resolve to the
/// sender once it's available to send another message.
#[must_use = "futures do nothing unless polled"]
pub struct FutureSender<T, E> {
    sender: Option<Sender<T, E>>,
    data: Option<Result<T, E>>,
    on_empty_token: Option<Token>,
}

/// The receiving end of a channel which implements the `Stream` trait.
///
/// This is a concrete implementation of a stream which can be used to represent
/// a stream of values being computed elsewhere. This is created by the
/// `channel` method in the `stream` module.
#[must_use = "streams do nothing unless polled"]
pub struct Receiver<T, E> {
    inner: Arc<Inner<T, E>>,
    on_full_token: Option<Token>,
}

struct Inner<T, E> {
    slot: Slot<Message<Result<T, E>>>,
    receiver_gone: AtomicBool,
}

enum Message<T> {
    Data(T),
    Done,
}

pub struct SendError<T, E>(Result<T, E>);

impl<T, E> fmt::Debug for SendError<T, E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_tuple("SendError")
            .field(&"...")
            .finish()
    }
}

impl<T, E> fmt::Display for SendError<T, E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "send failed because receiver is gone")
    }
}

impl<T, E> Error for SendError<T, E>
    where T: Any, E: Any
{
    fn description(&self) -> &str {
        "send failed because receiver is gone"
    }
}

impl<T, E> Stream for Receiver<T, E> {
    type Item = T;
    type Error = E;

    fn poll(&mut self) -> Poll<Option<T>, E> {
        if let Some(token) = self.on_full_token.take() {
            self.inner.slot.cancel(token);
        }

        match self.inner.slot.try_consume() {
            Ok(Message::Data(Ok(e))) => Ok(Async::Ready(Some(e))),
            Ok(Message::Data(Err(e))) => Err(e),
            Ok(Message::Done) => Ok(Async::Ready(None)),
            Err(..) => {
                let task = task::park();
                self.on_full_token = Some(self.inner.slot.on_full(move |_| {
                    task.unpark();
                }));
                Ok(Async::NotReady)
            }
        }
    }
}

impl<T, E> Drop for Receiver<T, E> {
    fn drop(&mut self) {
        self.inner.receiver_gone.store(true, Ordering::SeqCst);
        if let Some(token) = self.on_full_token.take() {
            self.inner.slot.cancel(token);
        }
        self.inner.slot.on_full(|slot| {
            drop(slot.try_consume());
        });
    }
}

impl<T, E> Sender<T, E> {
    /// Sends a new value along this channel to the receiver.
    ///
    /// This method consumes the sender and returns a future which will resolve
    /// to the sender again when the value sent has been consumed.
    pub fn send(self, t: Result<T, E>) -> FutureSender<T, E> {
        FutureSender {
            sender: Some(self),
            data: Some(t),
            on_empty_token: None,
        }
    }
}

impl<T, E> Drop for Sender<T, E> {
    fn drop(&mut self) {
        self.inner.slot.on_empty(None, |slot, _none| {
            slot.try_produce(Message::Done).ok().unwrap();
        });
    }
}

impl<T, E> Future for FutureSender<T, E> {
    type Item = Sender<T, E>;
    type Error = SendError<T, E>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let data = self.data.take().expect("cannot poll FutureSender twice");
        let sender = self.sender.take().expect("cannot poll FutureSender twice");
        if let Some(token) = self.on_empty_token.take() {
            sender.inner.slot.cancel(token);
        }
        if sender.inner.receiver_gone.load(Ordering::SeqCst) {
            return Err(SendError(data))
        }
        match sender.inner.slot.try_produce(Message::Data(data)) {
            Ok(()) => Ok(Async::Ready(sender)),
            Err(e) => {
                let task = task::park();
                let token = sender.inner.slot.on_empty(None, move |_slot, _item| {
                    task.unpark();
                });
                self.on_empty_token = Some(token);
                self.data = Some(match e.into_inner() {
                    Message::Data(data) => data,
                    Message::Done => panic!(),
                });
                self.sender = Some(sender);
                Ok(Async::NotReady)
            }
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    // By local inference, the compiler knows that the type of `e` is uint
    let e = 5u;

    // Create an empty vector (a growable array)
    let mut v = Vec::new();
    // At this point the compiler doesn't know the exact type of `v`, it just
    // knows that it's a vector of something

    // Insert `e` in the vector
    v.push(e);
    // Aha! Now the compiler knows that `v` is a vector of uints.
}
<commit_msg>type: wrap line to 75 chars<commit_after>fn main() {
    // By local inference, the compiler knows that the type of `e` is uint
    let e = 5u;

    // Create an empty vector (a growable array)
    let mut v = Vec::new();
    // At this point the compiler doesn't know the exact type of `v`, it
    // just knows that it's a vector of something

    // Insert `e` in the vector
    v.push(e);
    // Aha! Now the compiler knows that `v` is a vector of uints.
}
<|endoftext|>


<commit_before>/**
 * Rust Tasks and Communication Tutorial - 2.2 Backgrounding computations: Futures
 * http://static.rust-lang.org/doc/master/tutorial-tasks.html#backgrounding-computations-futures
 *
 * @license MIT license <http://www.opensource.org/licenses/mit-license.php>
 */
extern mod extra;
extern mod fibonacci(name = "fibonacci", vers = "1.0", author = "eliovir");
#[cfg(not(test))]
use std::vec;

fn partial_sum(start: uint) -> f64 {
	// println(fmt!("partial_sum(%u)", start));
	let mut local_sum = 0f64;
	for num in range(start*100000, (start+1)*100000) {
		local_sum += (num as f64 + 1.0).pow(&-2.0);
	}
	local_sum
}
#[test]
fn test_partial_sum_5() {
	let param = 5u;
	let expected = 0.00000033f64;
	let actual = partial_sum(param);
	assert_approx_eq!(expected, actual);
}
#[cfg(not(test))]
fn main() {
	let n = 40;
	println("Setting spawn");
	/*
	 * Note that the future needs to be mutable so that it can save the result for next time get is called.
	 */
	let mut delayed_fib = extra::future::Future::spawn(proc() fibonacci::fibonacci(n));
	println("Doing something else");
	println!("fib({:d}) = {}", n, delayed_fib.get());

	/*
	 * The workload will be distributed on the available cores.
	 */
	let mut futures = vec::from_fn(1000, |ind| do extra::future::Future::spawn { partial_sum(ind) });

	let mut final_res = 0f64;
	for ft in futures.mut_iter() {
		final_res += ft.get();
	}
	println!("π^2/6 is not far from : {}", final_res);
}
<commit_msg>tutorial-tasks-02_2-backgrounding_computations.rs : correct obsolete syntax<commit_after>/**
 * Rust Tasks and Communication Tutorial - 2.2 Backgrounding computations: Futures
 * http://static.rust-lang.org/doc/master/tutorial-tasks.html#backgrounding-computations-futures
 *
 * @license MIT license <http://www.opensource.org/licenses/mit-license.php>
 */
extern mod extra;
extern mod fibonacci;
#[cfg(not(test))]
use std::vec;

fn partial_sum(start: uint) -> f64 {
	// println(fmt!("partial_sum(%u)", start));
	let mut local_sum = 0f64;
	for num in range(start*100000, (start+1)*100000) {
		local_sum += (num as f64 + 1.0).pow(&-2.0);
	}
	local_sum
}
#[test]
fn test_partial_sum_5() {
	let param = 5u;
	let expected = 0.00000033f64;
	let actual = partial_sum(param);
	assert_approx_eq!(expected, actual);
}
#[cfg(not(test))]
fn main() {
	let n = 40;
	println("Setting spawn");
	/*
	 * Note that the future needs to be mutable so that it can save the result for next time get is called.
	 */
	let mut delayed_fib = extra::future::Future::spawn(proc() fibonacci::fibonacci(n));
	println("Doing something else");
	println!("fib({:d}) = {}", n, delayed_fib.get());

	/*
	 * The workload will be distributed on the available cores.
	 */
	let mut futures = vec::from_fn(1000, |ind| do extra::future::Future::spawn { partial_sum(ind) });

	let mut final_res = 0f64;
	for ft in futures.mut_iter() {
		final_res += ft.get();
	}
	println!("π^2/6 is not far from : {}", final_res);
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufReader, BufWriter, Seek, Read, BufRead};
use std::path::Path;
use std::u32;

use crate::codecs::*;

use crate::{ImageOutputFormat, color, error::{UnsupportedError, UnsupportedErrorKind}};
use crate::image;
use crate::dynimage::DynamicImage;
use crate::error::{ImageError, ImageFormatHint, ImageResult};
use crate::image::ImageFormat;
#[allow(unused_imports)]  // When no features are supported
use crate::image::{ImageDecoder, ImageEncoder};

pub(crate) fn open_impl(path: &Path) -> ImageResult<DynamicImage> {
    let buffered_read = BufReader::new(
        File::open(path).map_err(ImageError::IoError)?
    );

    load(buffered_read, ImageFormat::from_path(path)?)
}

/// Create a new image from a Reader.
///
/// Assumes the reader is already buffered. For optimal performance,
/// consider wrapping the reader with a `BufReader::new()`.
///
/// Try [`io::Reader`] for more advanced uses.
///
/// [`io::Reader`]: io/struct.Reader.html
#[allow(unused_variables)]
// r is unused if no features are supported.
pub fn load<R: BufRead + Seek>(buffered_reader: R, format: ImageFormat) -> ImageResult<DynamicImage> {
    #[allow(unreachable_patterns)]
    // Default is unreachable if all features are supported.
    match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => DynamicImage::from_decoder(avif::AvifDecoder::new(buffered_reader)?),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => DynamicImage::from_decoder(png::PngDecoder::new(buffered_reader)?),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => DynamicImage::from_decoder(gif::GifDecoder::new(buffered_reader)?),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => DynamicImage::from_decoder(jpeg::JpegDecoder::new(buffered_reader)?),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => DynamicImage::from_decoder(webp::WebPDecoder::new(buffered_reader)?),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => DynamicImage::from_decoder(tiff::TiffDecoder::new(buffered_reader)?),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => DynamicImage::from_decoder(tga::TgaDecoder::new(buffered_reader)?),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => DynamicImage::from_decoder(dds::DdsDecoder::new(buffered_reader)?),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => DynamicImage::from_decoder(bmp::BmpDecoder::new(buffered_reader)?),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => DynamicImage::from_decoder(ico::IcoDecoder::new(buffered_reader)?),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => DynamicImage::from_decoder(hdr::HdrAdapter::new(buffered_reader)?),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => DynamicImage::from_decoder(openexr::OpenExrDecoder::new(buffered_reader)?),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => DynamicImage::from_decoder(pnm::PnmDecoder::new(buffered_reader)?),
        #[cfg(feature = "farbfeld")]
        image::ImageFormat::Farbfeld => DynamicImage::from_decoder(farbfeld::FarbfeldDecoder::new(buffered_reader)?),
        _ => Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    }
}

pub(crate) fn image_dimensions_impl(path: &Path) -> ImageResult<(u32, u32)> {
    let format = image::ImageFormat::from_path(path)?;
    let reader = BufReader::new(File::open(path)?);
    image_dimensions_with_format_impl(reader, format)
}

#[allow(unused_variables)]
// fin is unused if no features are supported.
pub(crate) fn image_dimensions_with_format_impl<R: BufRead + Seek>(buffered_read: R, format: ImageFormat)
                                                                   -> ImageResult<(u32, u32)>
{
    #[allow(unreachable_patterns,unreachable_code)]
    // Default is unreachable if all features are supported.
    // Code after the match is unreachable if none are.
    Ok(match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => avif::AvifDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => jpeg::JpegDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => png::PngDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => gif::GifDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => webp::WebPDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => tiff::TiffDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => tga::TgaDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => dds::DdsDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => bmp::BmpDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => ico::IcoDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => hdr::HdrAdapter::new(buffered_read)?.dimensions(),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => openexr::OpenExrDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => pnm::PnmDecoder::new(buffered_read)?.dimensions(),
        format => return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    })
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
) -> ImageResult<()> {
    let format =  ImageFormat::from_path(path)?;
    save_buffer_with_format_impl(path, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_with_format_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageFormat,
) -> ImageResult<()> {
    let buffered_file_write = &mut BufWriter::new(File::create(path)?); // always seekable

    let format = match format {
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            let ext = path.extension()
            .and_then(|s| s.to_str())
            .map_or("".to_string(), |s| s.to_ascii_lowercase());
            ImageOutputFormat::Pnm(match &*ext {
                "pbm" => pnm::PnmSubtype::Bitmap(pnm::SampleEncoding::Binary),
                "pgm" => pnm::PnmSubtype::Graymap(pnm::SampleEncoding::Binary),
                "ppm" => pnm::PnmSubtype::Pixmap(pnm::SampleEncoding::Binary),
                "pam" => pnm::PnmSubtype::ArbitraryMap,
                _ => { return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())) }, // Unsupported Pnm subtype.
            })
        },
        // #[cfg(feature = "hdr")]
        // image::ImageFormat::Hdr => hdr::HdrEncoder::new(fout).encode(&[Rgb<f32>], width, height), // usize
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => {
            return tiff::TiffEncoder::new(buffered_file_write).write_image(buf, width, height, color);
        },
        format => format.into(),
    };

    write_buffer_impl(buffered_file_write, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn write_buffer_impl<W: std::io::Write + Seek>(
    buffered_write: &mut W,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageOutputFormat,
) -> ImageResult<()> {
    match format {
        #[cfg(feature = "png")]
        ImageOutputFormat::Png => png::PngEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "jpeg")]
        ImageOutputFormat::Jpeg(quality) => jpeg::JpegEncoder::new_with_quality(buffered_write, quality)
            .write_image(buf, width, height, color),
        #[cfg(feature = "pnm")]
        ImageOutputFormat::Pnm(subtype) => pnm::PnmEncoder::new(buffered_write)
            .with_subtype(subtype)
            .write_image(buf, width, height, color),
        #[cfg(feature = "gif")]
        ImageOutputFormat::Gif => gif::GifEncoder::new(buffered_write).encode(buf, width, height, color),
        #[cfg(feature = "ico")]
        ImageOutputFormat::Ico => ico::IcoEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "bmp")]
        ImageOutputFormat::Bmp => bmp::BmpEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "farbfeld")]
        ImageOutputFormat::Farbfeld => farbfeld::FarbfeldEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "tga")]
        ImageOutputFormat::Tga => tga::TgaEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "openexr")]
        ImageOutputFormat::OpenExr => openexr::OpenExrEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "tiff")]
        ImageOutputFormat::Tiff => tiff::TiffEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "avif-encoder")]
        ImageOutputFormat::Avif => avif::AvifEncoder::new(buffered_write).write_image(buf, width, height, color),

        image::ImageOutputFormat::Unsupported(msg) => {
            Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Name(msg)))))
        }

        image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {},

    }
}

static MAGIC_BYTES: [(&[u8], ImageFormat); 21] = [
    (b"\x89PNG\r\n\x1a\n", ImageFormat::Png),
    (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg),
    (b"GIF89a", ImageFormat::Gif),
    (b"GIF87a", ImageFormat::Gif),
    (b"RIFF", ImageFormat::WebP), // TODO: better magic byte detection, see https://github.com/image-rs/image/issues/660
    (b"MM\x00*", ImageFormat::Tiff),
    (b"II*\x00", ImageFormat::Tiff),
    (b"DDS ", ImageFormat::Dds),
    (b"BM", ImageFormat::Bmp),
    (&[0, 0, 1, 0], ImageFormat::Ico),
    (b"#?RADIANCE", ImageFormat::Hdr),
    (b"P1", ImageFormat::Pnm),
    (b"P2", ImageFormat::Pnm),
    (b"P3", ImageFormat::Pnm),
    (b"P4", ImageFormat::Pnm),
    (b"P5", ImageFormat::Pnm),
    (b"P6", ImageFormat::Pnm),
    (b"P7", ImageFormat::Pnm),
    (b"farbfeld", ImageFormat::Farbfeld),
    (b"\0\0\0 ftypavif", ImageFormat::Avif),
    (&[0x76, 0x2f, 0x31, 0x01], ImageFormat::OpenExr), // = &exr::meta::magic_number::BYTES
];

/// Guess image format from memory block
///
/// Makes an educated guess about the image format based on the Magic Bytes at the beginning.
/// TGA is not supported by this function.
/// This is not to be trusted on the validity of the whole memory block
pub fn guess_format(buffer: &[u8]) -> ImageResult<ImageFormat> {
    match guess_format_impl(buffer) {
        Some(format) => Ok(format),
        None => Err(ImageError::Unsupported(ImageFormatHint::Unknown.into())),
    }
}

pub(crate) fn guess_format_impl(buffer: &[u8]) -> Option<ImageFormat> {
    for &(signature, format) in &MAGIC_BYTES {
        if buffer.starts_with(signature) {
            return Some(format);
        }
    }

    None
}
<commit_msg>tiff: remove redundant special case<commit_after>use std::fs::File;
use std::io::{BufReader, BufWriter, Seek, BufRead};
use std::path::Path;
use std::u32;

use crate::codecs::*;

use crate::{ImageOutputFormat, color, error::{UnsupportedError, UnsupportedErrorKind}};
use crate::image;
use crate::dynimage::DynamicImage;
use crate::error::{ImageError, ImageFormatHint, ImageResult};
use crate::image::ImageFormat;
#[allow(unused_imports)]  // When no features are supported
use crate::image::{ImageDecoder, ImageEncoder};

pub(crate) fn open_impl(path: &Path) -> ImageResult<DynamicImage> {
    let buffered_read = BufReader::new(
        File::open(path).map_err(ImageError::IoError)?
    );

    load(buffered_read, ImageFormat::from_path(path)?)
}

/// Create a new image from a Reader.
///
/// Assumes the reader is already buffered. For optimal performance,
/// consider wrapping the reader with a `BufReader::new()`.
///
/// Try [`io::Reader`] for more advanced uses.
///
/// [`io::Reader`]: io/struct.Reader.html
#[allow(unused_variables)]
// r is unused if no features are supported.
pub fn load<R: BufRead + Seek>(buffered_reader: R, format: ImageFormat) -> ImageResult<DynamicImage> {
    #[allow(unreachable_patterns)]
    // Default is unreachable if all features are supported.
    match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => DynamicImage::from_decoder(avif::AvifDecoder::new(buffered_reader)?),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => DynamicImage::from_decoder(png::PngDecoder::new(buffered_reader)?),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => DynamicImage::from_decoder(gif::GifDecoder::new(buffered_reader)?),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => DynamicImage::from_decoder(jpeg::JpegDecoder::new(buffered_reader)?),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => DynamicImage::from_decoder(webp::WebPDecoder::new(buffered_reader)?),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => DynamicImage::from_decoder(tiff::TiffDecoder::new(buffered_reader)?),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => DynamicImage::from_decoder(tga::TgaDecoder::new(buffered_reader)?),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => DynamicImage::from_decoder(dds::DdsDecoder::new(buffered_reader)?),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => DynamicImage::from_decoder(bmp::BmpDecoder::new(buffered_reader)?),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => DynamicImage::from_decoder(ico::IcoDecoder::new(buffered_reader)?),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => DynamicImage::from_decoder(hdr::HdrAdapter::new(buffered_reader)?),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => DynamicImage::from_decoder(openexr::OpenExrDecoder::new(buffered_reader)?),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => DynamicImage::from_decoder(pnm::PnmDecoder::new(buffered_reader)?),
        #[cfg(feature = "farbfeld")]
        image::ImageFormat::Farbfeld => DynamicImage::from_decoder(farbfeld::FarbfeldDecoder::new(buffered_reader)?),
        _ => Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    }
}

pub(crate) fn image_dimensions_impl(path: &Path) -> ImageResult<(u32, u32)> {
    let format = image::ImageFormat::from_path(path)?;
    let reader = BufReader::new(File::open(path)?);
    image_dimensions_with_format_impl(reader, format)
}

#[allow(unused_variables)]
// fin is unused if no features are supported.
pub(crate) fn image_dimensions_with_format_impl<R: BufRead + Seek>(buffered_read: R, format: ImageFormat)
                                                                   -> ImageResult<(u32, u32)>
{
    #[allow(unreachable_patterns,unreachable_code)]
    // Default is unreachable if all features are supported.
    // Code after the match is unreachable if none are.
    Ok(match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => avif::AvifDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => jpeg::JpegDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => png::PngDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => gif::GifDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => webp::WebPDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => tiff::TiffDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => tga::TgaDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => dds::DdsDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => bmp::BmpDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => ico::IcoDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => hdr::HdrAdapter::new(buffered_read)?.dimensions(),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => openexr::OpenExrDecoder::new(buffered_read)?.dimensions(),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => pnm::PnmDecoder::new(buffered_read)?.dimensions(),
        format => return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    })
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
) -> ImageResult<()> {
    let format =  ImageFormat::from_path(path)?;
    save_buffer_with_format_impl(path, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_with_format_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageFormat,
) -> ImageResult<()> {
    let buffered_file_write = &mut BufWriter::new(File::create(path)?); // always seekable

    let format = match format {
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            let ext = path.extension()
            .and_then(|s| s.to_str())
            .map_or("".to_string(), |s| s.to_ascii_lowercase());
            ImageOutputFormat::Pnm(match &*ext {
                "pbm" => pnm::PnmSubtype::Bitmap(pnm::SampleEncoding::Binary),
                "pgm" => pnm::PnmSubtype::Graymap(pnm::SampleEncoding::Binary),
                "ppm" => pnm::PnmSubtype::Pixmap(pnm::SampleEncoding::Binary),
                "pam" => pnm::PnmSubtype::ArbitraryMap,
                _ => { return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())) }, // Unsupported Pnm subtype.
            })
        },
        // #[cfg(feature = "hdr")]
        // image::ImageFormat::Hdr => hdr::HdrEncoder::new(fout).encode(&[Rgb<f32>], width, height), // usize
        format => format.into(),
    };

    write_buffer_impl(buffered_file_write, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn write_buffer_impl<W: std::io::Write + Seek>(
    buffered_write: &mut W,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageOutputFormat,
) -> ImageResult<()> {
    match format {
        #[cfg(feature = "png")]
        ImageOutputFormat::Png => png::PngEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "jpeg")]
        ImageOutputFormat::Jpeg(quality) => jpeg::JpegEncoder::new_with_quality(buffered_write, quality)
            .write_image(buf, width, height, color),
        #[cfg(feature = "pnm")]
        ImageOutputFormat::Pnm(subtype) => pnm::PnmEncoder::new(buffered_write)
            .with_subtype(subtype)
            .write_image(buf, width, height, color),
        #[cfg(feature = "gif")]
        ImageOutputFormat::Gif => gif::GifEncoder::new(buffered_write).encode(buf, width, height, color),
        #[cfg(feature = "ico")]
        ImageOutputFormat::Ico => ico::IcoEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "bmp")]
        ImageOutputFormat::Bmp => bmp::BmpEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "farbfeld")]
        ImageOutputFormat::Farbfeld => farbfeld::FarbfeldEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "tga")]
        ImageOutputFormat::Tga => tga::TgaEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "openexr")]
        ImageOutputFormat::OpenExr => openexr::OpenExrEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "tiff")]
        ImageOutputFormat::Tiff => tiff::TiffEncoder::new(buffered_write).write_image(buf, width, height, color),
        #[cfg(feature = "avif-encoder")]
        ImageOutputFormat::Avif => avif::AvifEncoder::new(buffered_write).write_image(buf, width, height, color),

        image::ImageOutputFormat::Unsupported(msg) => {
            Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Name(msg)))))
        }

        image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {},

    }
}

static MAGIC_BYTES: [(&[u8], ImageFormat); 21] = [
    (b"\x89PNG\r\n\x1a\n", ImageFormat::Png),
    (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg),
    (b"GIF89a", ImageFormat::Gif),
    (b"GIF87a", ImageFormat::Gif),
    (b"RIFF", ImageFormat::WebP), // TODO: better magic byte detection, see https://github.com/image-rs/image/issues/660
    (b"MM\x00*", ImageFormat::Tiff),
    (b"II*\x00", ImageFormat::Tiff),
    (b"DDS ", ImageFormat::Dds),
    (b"BM", ImageFormat::Bmp),
    (&[0, 0, 1, 0], ImageFormat::Ico),
    (b"#?RADIANCE", ImageFormat::Hdr),
    (b"P1", ImageFormat::Pnm),
    (b"P2", ImageFormat::Pnm),
    (b"P3", ImageFormat::Pnm),
    (b"P4", ImageFormat::Pnm),
    (b"P5", ImageFormat::Pnm),
    (b"P6", ImageFormat::Pnm),
    (b"P7", ImageFormat::Pnm),
    (b"farbfeld", ImageFormat::Farbfeld),
    (b"\0\0\0 ftypavif", ImageFormat::Avif),
    (&[0x76, 0x2f, 0x31, 0x01], ImageFormat::OpenExr), // = &exr::meta::magic_number::BYTES
];

/// Guess image format from memory block
///
/// Makes an educated guess about the image format based on the Magic Bytes at the beginning.
/// TGA is not supported by this function.
/// This is not to be trusted on the validity of the whole memory block
pub fn guess_format(buffer: &[u8]) -> ImageResult<ImageFormat> {
    match guess_format_impl(buffer) {
        Some(format) => Ok(format),
        None => Err(ImageError::Unsupported(ImageFormatHint::Unknown.into())),
    }
}

pub(crate) fn guess_format_impl(buffer: &[u8]) -> Option<ImageFormat> {
    for &(signature, format) in &MAGIC_BYTES {
        if buffer.starts_with(signature) {
            return Some(format);
        }
    }

    None
}
<|endoftext|>


<commit_before>//! Layout handling

extern crate rustwlc;

use rustwlc::handle::{WlcView, WlcOutput};

enum ContainerTypes {
    Root,        /* Root container, only one exists */
    Output,      /* Output, like a monitor or head */
    Workspace,   /* A workspace */
    View         /* A view (aka a window) */
}

enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

/// Like i3, everything (workspaces, containers, views) are containable.
pub trait Containable {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent<T: Containable>(&self) -> Option<T>;

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children<T: Containable>(&self) -> Vec<T>;

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool;

    /// Removes this container and all of its children
    fn remove_container(self);

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(visibilty: bool);

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64);

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64);

    /// Finds a parent container with the given type
    fn get_parent_by_type<T: Containable>(&self, type_: T) -> T;
}

/// View specific functions
pub trait Viewable {
    /// Determines if the view is full screen
    fn is_fullscreen(&self) -> bool;

    /// Figures out if the view is focused
    fn is_active(&self) -> bool;

    /// Returns true if this view is a parent is an ancestor of the child
    fn is_parent_of<T: Containable>(&self, child: T) -> bool;

    /// Returns true if this view is a child is an decedent of the parent
    fn is_child_of<T: Containable>(&self, parent: T) -> bool;

    /// Gets the active workspace of the view
    fn active_workspace<T: Containable>(&self) -> T;
}

struct Container {
    // Can't be a view, that's the View struct's job
    handle: Option<WlcOutput>,
    type_: ContainerTypes,
    layout: Layout,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

struct View {
    handle: Option<WlcView>,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}
<commit_msg>Removed accidental extern<commit_after>//! Layout handling

use rustwlc::handle::{WlcView, WlcOutput};

enum ContainerTypes {
    Root,        /* Root container, only one exists */
    Output,      /* Output, like a monitor or head */
    Workspace,   /* A workspace */
    View         /* A view (aka a window) */
}

enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

/// Like i3, everything (workspaces, containers, views) are containable.
pub trait Containable {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent<T: Containable>(&self) -> Option<T>;

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children<T: Containable>(&self) -> Vec<T>;

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool;

    /// Removes this container and all of its children
    fn remove_container(self);

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(visibilty: bool);

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64);

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64);

    /// Finds a parent container with the given type
    fn get_parent_by_type<T: Containable>(&self, type_: T) -> T;
}

/// View specific functions
pub trait Viewable {
    /// Determines if the view is full screen
    fn is_fullscreen(&self) -> bool;

    /// Figures out if the view is focused
    fn is_active(&self) -> bool;

    /// Returns true if this view is a parent is an ancestor of the child
    fn is_parent_of<T: Containable>(&self, child: T) -> bool;

    /// Returns true if this view is a child is an decedent of the parent
    fn is_child_of<T: Containable>(&self, parent: T) -> bool;

    /// Gets the active workspace of the view
    fn active_workspace<T: Containable>(&self) -> T;
}

struct Container {
    // Can't be a view, that's the View struct's job
    handle: Option<WlcOutput>,
    type_: ContainerTypes,
    layout: Layout,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

struct View {
    handle: Option<WlcView>,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}
<|endoftext|>


<commit_before>use JITVal = jit::Value;
use jit::{
    get_type,
    Function,
    Compile,
    UByte,
    SysChar,
    SysBool,
    NInt,
    NUInt,
    Int,
    UInt,
    Pointer,
    Float64
};
use JSVal = front::stdlib::value::Value;
use front::stdlib::value::{Value, VNull, to_value};
use front::stdlib::value::ResultValue;
use front::run::executor::Executor;
use std::gc::GC;
use std::c_str::CString;
/// A JIT executor
pub struct JitExecutor {
    global: JSVal
}
impl JitExecutor {
    /// Create a new JIT executor
    pub fn new() -> JitExecutor {
        JitExecutor {
            global: Value::new_global()
        }
    }

}
impl<'a> Executor<(JITVal<'a>, &'a Function<'a>)> for JitExecutor {
    #[inline]
    fn get_global_obj(&self) -> JSVal {
        self.global
    }
    fn execute(&self, comp:&(JITVal<'a>, &'a Function<'a>)) -> ResultValue {
        let &(ref val, ref func) = comp;
        func.insn_return(&convert_to_value(*func, val));
        func.set_optimization_level(5);
        func.set_recompilable();
        func.compile();
        Ok(func.with_closure3(|run:fn(JSVal, JSVal, JSVal) -> JSVal| {
            run(self.global, self.global, self.global)
        }))
    }
}

fn convert_to_value<'a>(func:&Function<'a>, val:&'a JITVal<'a>) -> JITVal<'a> {
    let val_type = val.get_type();
    let val_kind = val_type.get_kind();
    if val_kind.contains(SysBool) || val_kind.contains(UByte) {
        let bool_value = to_value::<bool>;
        let sig = get_type::<fn(bool) -> *mut int>();
        func.insn_call_native1("bool_value", bool_value, &sig, &mut [val])
    } else if val_kind.contains(Pointer) {
        let ref_t = val_type.get_ref();
        if ref_t.get_kind().contains(SysChar) {
            fn string_value(val: &i8) -> JSVal {
                unsafe {
                    let text = CString::new(val, false);
                    to_value(text.as_str().unwrap().into_string())
                }
            }
            let sig = get_type::<fn(String) -> *mut int>();
            func.insn_call_native1("string_value", string_value, &sig, &mut [val])
        } else {
            fn ptr_value(ptr: &i8) -> JSVal {
                match ptr.to_uint() {
                    0u => JSVal::undefined(),
                    1u => JSVal {
                        ptr: box(GC) VNull
                    },
                    ptr => fail!("Invalid pointer: {}", ptr)
                }
            }
            let sig = get_type::<fn(&i8) -> *mut int>();
            func.insn_call_native1("ptr_value", ptr_value, &sig, &mut [val])
        }
    } else if val_kind.contains(Int) || val_kind.contains(UInt) {
        let int_value = to_value::<i32>;
        let sig = get_type::<fn(i32) -> *mut int>();
        func.insn_call_native1("int_value", int_value, &sig, &mut [val])
    } else if val_kind.contains(NInt) || val_kind.contains(NUInt) {
        fn sys_int_value(num:int) -> JSVal {
            to_value::<i32>(num as i32)
        }
        let sig = get_type::<fn(int) -> *mut int>();
        func.insn_call_native1("sys_int_value", sys_int_value, &sig, &mut [val])
    } else if val_kind.contains(Float64) {
        let float_value = to_value::<f64>;
        let sig = get_type::<fn(f64) -> *mut int>();
        func.insn_call_native1("float_value", float_value, &sig, &mut [val])
    } else {
        fail!("Invalid kind {}", val_kind.bits())
    }
}<commit_msg>Replace *mut with *const<commit_after>use JITVal = jit::Value;
use jit::{
    get_type,
    Function,
    Compile,
    UByte,
    SysChar,
    SysBool,
    NInt,
    NUInt,
    Int,
    UInt,
    Pointer,
    Float64
};
use JSVal = front::stdlib::value::Value;
use front::stdlib::value::{Value, VNull, to_value};
use front::stdlib::value::ResultValue;
use front::run::executor::Executor;
use std::gc::GC;
use std::c_str::CString;
/// A JIT executor
pub struct JitExecutor {
    global: JSVal
}
impl JitExecutor {
    /// Create a new JIT executor
    pub fn new() -> JitExecutor {
        JitExecutor {
            global: Value::new_global()
        }
    }

}
impl<'a> Executor<(JITVal<'a>, &'a Function<'a>)> for JitExecutor {
    #[inline]
    fn get_global_obj(&self) -> JSVal {
        self.global
    }
    fn execute(&self, comp:&(JITVal<'a>, &'a Function<'a>)) -> ResultValue {
        let &(ref val, ref func) = comp;
        func.insn_return(&convert_to_value(*func, val));
        func.set_optimization_level(5);
        func.set_recompilable();
        func.compile();
        Ok(func.with_closure3(|run:fn(JSVal, JSVal, JSVal) -> JSVal| {
            run(self.global, self.global, self.global)
        }))
    }
}

fn convert_to_value<'a>(func:&Function<'a>, val:&'a JITVal<'a>) -> JITVal<'a> {
    let val_type = val.get_type();
    let val_kind = val_type.get_kind();
    if val_kind.contains(SysBool) || val_kind.contains(UByte) {
        let bool_value = to_value::<bool>;
        let sig = get_type::<fn(bool) -> *const int>();
        func.insn_call_native1("bool_value", bool_value, &sig, &mut [val])
    } else if val_kind.contains(Pointer) {
        let ref_t = val_type.get_ref();
        if ref_t.get_kind().contains(SysChar) {
            fn string_value(val: &i8) -> JSVal {
                unsafe {
                    let text = CString::new(val, false);
                    to_value(text.as_str().unwrap().into_string())
                }
            }
            let sig = get_type::<fn(String) -> *const int>();
            func.insn_call_native1("string_value", string_value, &sig, &mut [val])
        } else {
            fn ptr_value(ptr: &i8) -> JSVal {
                match ptr.to_uint() {
                    0u => JSVal::undefined(),
                    1u => JSVal {
                        ptr: box(GC) VNull
                    },
                    ptr => fail!("Invalid pointer: {}", ptr)
                }
            }
            let sig = get_type::<fn(&i8) -> *const int>();
            func.insn_call_native1("ptr_value", ptr_value, &sig, &mut [val])
        }
    } else if val_kind.contains(Int) || val_kind.contains(UInt) {
        let int_value = to_value::<i32>;
        let sig = get_type::<fn(i32) -> *const int>();
        func.insn_call_native1("int_value", int_value, &sig, &mut [val])
    } else if val_kind.contains(NInt) || val_kind.contains(NUInt) {
        fn sys_int_value(num:int) -> JSVal {
            to_value::<i32>(num as i32)
        }
        let sig = get_type::<fn(int) -> *const int>();
        func.insn_call_native1("sys_int_value", sys_int_value, &sig, &mut [val])
    } else if val_kind.contains(Float64) {
        let float_value = to_value::<f64>;
        let sig = get_type::<fn(f64) -> *const int>();
        func.insn_call_native1("float_value", float_value, &sig, &mut [val])
    } else {
        fail!("Invalid kind {}", val_kind.bits())
    }
}<|endoftext|>


<commit_before>use codespan::{ByteIndex, ByteOffset, FileId, Files, Span};

use nom::error::{ErrorKind, ParseError};
use nom::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
use nom::lib::std::str::FromStr;
use nom::Err;
use nom::{
    AsBytes, Compare, CompareResult, ExtendInto, FindSubstring, FindToken, IResult, InputIter,
    InputLength, InputTake, InputTakeAtPosition, Needed, Offset, ParseTo, Slice,
};

/// A piece of source code. Generally used to replace strings in the nom parser,
/// this structure stores extra information about the location of a fragment of
/// source code.
#[derive(Debug, Copy, Clone)]
pub struct Fragment<'source> {
    /// A reference to the parent Files object, which stores all source code
    /// being processed.
    files: &'source Files<String>,
    handle: FileId,
    span: Span,
    /// The fragment of source code represented by this object.
    source: &'source str,
}

///
pub enum MergeError {

}

impl<'s> Fragment<'s> {
    /// Construct a new parser input from a handle into a
    /// [Files](https://docs.rs/codespan/0.5.0/codespan/struct.Files.html)
    /// object.
    pub fn new(files: &'s Files<String>, handle: FileId) -> Self {
        let source = files.source(handle);
        let span = files.source_span(handle);
        Self {
            files,
            handle,
            span,
            source,
        }
    }

    /// Get the span associated with this fragment of source code.
    #[inline]
    pub fn get_span(&self) -> Span {
        self.span
    }

    /// Get the ending index of this fragment.
    /// Identical to `self.get_span().end()`.
    #[inline]
    pub fn end(&self) -> ByteIndex {
        self.span.end()
    }

    /// Get the starting index of this fragment.
    /// Identical to `self.get_span().start()`.
    #[inline]
    pub fn start(&self) -> ByteIndex {
        self.span.start()
    }

    /// Get the length of this fragment.
    /// Identical to `self.source.len()`.
    #[inline]
    pub fn len(&self) -> usize {
        self.source.len()
    }

    /// Get the source code of this fragment.
    #[inline]
    pub fn source(&self) -> &'s str {
        self.source
    }

    /// Get reference to files object.
    #[inline]
    pub fn files(&self) -> &'s Files<String> {
        self.files
    }

    /// Get the handle of this fragment's file in the parent
    /// [Files](https://docs.rs/codespan/0.5.0/codespan/struct.Files.html)
    /// object.
    #[inline]
    pub fn get_handle(&self) -> FileId {
        self.handle
    }
}

impl<'s> AsBytes for Fragment<'s> {
    #[inline]
    fn as_bytes(&self) -> &[u8] {
        self.source().as_bytes()
    }
}

impl<'s, 'o, T> Compare<T> for Fragment<'s>
where
    &'o str: Compare<T>,
    's: 'o,
{
    #[inline]
    fn compare(&self, t: T) -> CompareResult {
        self.source().compare(t)
    }

    #[inline]
    fn compare_no_case(&self, t: T) -> CompareResult {
        self.source().compare_no_case(t)
    }
}

impl<'s> ExtendInto for Fragment<'s> {
    type Item = char;
    type Extender = String;

    #[inline]
    fn new_builder(&self) -> String {
        String::new()
    }

    #[inline]
    fn extend_into(&self, acc: &mut Self::Extender) {
        self.source().extend_into(acc)
    }
}

impl<'s> FindSubstring<&str> for Fragment<'s> {
    #[inline]
    fn find_substring(&self, substr: &str) -> Option<usize> {
        self.source().find_substring(substr)
    }
}

impl<'s, 'o, T> FindToken<T> for Fragment<'s>
where
    &'o str: FindToken<T>,
    's: 'o,
{
    #[inline]
    fn find_token(&self, t: T) -> bool {
        self.source().find_token(t)
    }
}

impl<'s> InputIter for Fragment<'s> {
    type Item = <&'s str as InputIter>::Item;
    type Iter = <&'s str as InputIter>::Iter;
    type IterElem = <&'s str as InputIter>::IterElem;

    #[inline]
    fn iter_indices(&self) -> Self::Iter {
        self.source().iter_indices()
    }

    #[inline]
    fn iter_elements(&self) -> Self::IterElem {
        self.source().iter_elements()
    }

    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize>
    where
        P: Fn(Self::Item) -> bool,
    {
        self.source().position(predicate)
    }

    #[inline]
    fn slice_index(&self, count: usize) -> Option<usize> {
        self.source().slice_index(count)
    }
}

impl<'s> InputLength for Fragment<'s> {
    #[inline]
    fn input_len(&self) -> usize {
        self.len()
    }
}

impl<'s> InputTake for Fragment<'s> {
    fn take(&self, count: usize) -> Self {
        let mut frag2 = self.clone();
        frag2.source = &self.source()[..count];
        frag2.span = Span::new(self.start(), self.start() + ByteOffset(count as i64));
        frag2
    }

    fn take_split(&self, count: usize) -> (Self, Self) {
        let mut frag2 = self.clone();
        let mut frag3 = self.clone();
        frag2.source = &self.source()[..count];
        frag3.source = &self.source()[count..];
        frag2.span = Span::new(self.start(), self.start() + ByteOffset(count as i64));
        frag3.span = Span::new(self.start() + ByteOffset(count as i64), self.end());
        (frag3, frag2) // (part after, part before)
    }
}

impl<'s> InputTakeAtPosition for Fragment<'s> {
    type Item = char;

    fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(i) => Ok(self.take_split(i)),
            None => Err(Err::Incomplete(Needed::Size(1))),
        }
    }

    fn split_at_position1<P, E: ParseError<Self>>(
        &self,
        predicate: P,
        e: ErrorKind,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(0) => Err(Err::Error(E::from_error_kind(self.clone(), e))),
            Some(i) => Ok(self.take_split(i)),
            None => Err(Err::Incomplete(Needed::Size(1))),
        }
    }

    fn split_at_position_complete<P, E: ParseError<Self>>(
        &self,
        predicate: P,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(i) => Ok(self.take_split(i)),
            None => Ok(self.take_split(self.input_len())),
        }
    }

    fn split_at_position1_complete<P, E: ParseError<Self>>(
        &self,
        predicate: P,
        e: ErrorKind,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(0) => Err(Err::Error(E::from_error_kind(self.clone(), e))),
            Some(i) => Ok(self.take_split(i)),
            None => Ok(self.take_split(self.input_len())),
        }
    }
}

impl<'s> Offset for Fragment<'s> {
    fn offset(&self, second: &Self) -> usize {
        (second.span.start() - self.span.start()).0 as usize
    }
}

impl<'s, R: FromStr> ParseTo<R> for Fragment<'s> {
    #[inline]
    fn parse_to(&self) -> Option<R> {
        self.source().parse_to()
    }
}

impl<'s> Slice<Range<usize>> for Fragment<'s> {
    fn slice(&self, range: Range<usize>) -> Self {
        let mut result = self.clone();
        result.source = &self.source()[range.clone()];
        result.span = Span::new(
            self.span.start() + ByteOffset(range.start as i64),
            self.span.start() + ByteOffset(range.end as i64),
        );
        result
    }
}

impl<'s> Slice<RangeFrom<usize>> for Fragment<'s> {
    fn slice(&self, range: RangeFrom<usize>) -> Self {
        self.slice(range.start..self.len())
    }
}

impl<'s> Slice<RangeTo<usize>> for Fragment<'s> {
    fn slice(&self, range: RangeTo<usize>) -> Self {
        self.slice(0..range.end)
    }
}

impl<'s> Slice<RangeFull> for Fragment<'s> {
    fn slice(&self, _: RangeFull) -> Self {
        self.clone()
    }
}

impl<'s> PartialEq for Fragment<'s> {
    // This will fail if it is used to compare across two separate Files
    // objects.
    fn eq(&self, other: &Self) -> bool {
        other.handle == self.handle && other.span == self.span
    }
}

/// Trait for all types that have associated fragments in source code.
pub trait HasFragment<'s> {
    /// Get the associated fragment of source code.
    fn get_fragment(&self) -> Fragment<'s>;
}
<commit_msg>use ptr::eq<commit_after>use codespan::{ByteIndex, ByteOffset, FileId, Files, Span, SpanOutOfBoundsError};

use nom::error::{ErrorKind, ParseError};
use nom::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
use nom::lib::std::str::FromStr;
use nom::Err;
use nom::{
    AsBytes, Compare, CompareResult, ExtendInto, FindSubstring, FindToken, IResult, InputIter,
    InputLength, InputTake, InputTakeAtPosition, Needed, Offset, ParseTo, Slice,
};

/// A piece of source code. Generally used to replace strings in the nom parser,
/// this structure stores extra information about the location of a fragment of
/// source code.
#[derive(Debug, Copy, Clone)]
pub struct Fragment<'source> {
    /// A reference to the parent Files object, which stores all source code
    /// being processed.
    files: &'source Files<String>,
    handle: FileId,
    span: Span,
    /// The fragment of source code represented by this object.
    source: &'source str,
}

/// An error when attempting to merge two fragments.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum FragmentError {
    /// Fragments are from different files, and cannot be merged.
    HandleMismatch,
    /// Fragments are not in the same `Files<String>` object, and cannot be merged.
    FilesRefMismatch,
}

impl<'s> Fragment<'s> {
    /// Construct a new parser input from a handle into a
    /// [Files](https://docs.rs/codespan/0.5.0/codespan/struct.Files.html)
    /// object.
    pub fn new(files: &'s Files<String>, handle: FileId) -> Self {
        let source = files.source(handle);
        let span = files.source_span(handle);
        Self {
            files,
            handle,
            span,
            source,
        }
    }

    /// Get the span associated with this fragment of source code.
    #[inline]
    pub fn get_span(&self) -> Span {
        self.span
    }

    /// Get the ending index of this fragment.
    /// Identical to `self.get_span().end()`.
    #[inline]
    pub fn end(&self) -> ByteIndex {
        self.span.end()
    }

    /// Get the starting index of this fragment.
    /// Identical to `self.get_span().start()`.
    #[inline]
    pub fn start(&self) -> ByteIndex {
        self.span.start()
    }

    /// Get the length of this fragment.
    /// Identical to `self.source.len()`.
    #[inline]
    pub fn len(&self) -> usize {
        self.source.len()
    }

    /// Get the source code of this fragment.
    #[inline]
    pub fn source(&self) -> &'s str {
        self.source
    }

    /// Get reference to files object.
    #[inline]
    pub fn files(&self) -> &'s Files<String> {
        self.files
    }

    /// Get the handle of this fragment's file in the parent
    /// [Files](https://docs.rs/codespan/0.5.0/codespan/struct.Files.html)
    /// object.
    #[inline]
    pub fn get_handle(&self) -> FileId {
        self.handle
    }

    /// Check whether two `Fragment`s overlap. returns true if and only if
    /// both Fragments are from the same `Files<String>` object, and both have
    /// the same handle, and have an area of overlap.
    #[inline]
    pub fn overlap(fst: &Self, snd: &Self) -> bool {
        fst.get_handle() == snd.get_handle() &&
        std::ptr::eq(fst.files(), snd.files()) &&
        !fst.get_span().disjoint(snd.get_span())
    }

    /// Merge two fragments into one.
    /// ## Errors:
    /// - [`Fragment::FilesRefMismatch`]() when there is a mismatch between the
    ///     `Files<String>` objects referred to by the fragments.
    /// - [`Fragment::HandleMismatch`]() when there is a mismatch between the
    ///     source handles within the fragments.
    /// ## Panics:
    /// Panics when either fragment is internally corrupted such that a new
    /// source string is not able to be read from the `File<String>` object.
    pub fn merge(fst: Self, snd: Self) -> Result<Self, FragmentError> {
        if std::ptr::eq(fst.files, snd.files) {
            return Err(FragmentError::FilesRefMismatch);
        }
        else if fst.handle != snd.handle {
            return Err(FragmentError::HandleMismatch);
        }
        else {
            let span =  fst.span.merge(snd.span);
            let files = fst.files;
            let handle = fst.handle;
            let source = files.source_slice(handle, span).unwrap();
            Ok(Fragment{span, files, handle, source})
        }
    }
}

impl<'s> AsBytes for Fragment<'s> {
    #[inline]
    fn as_bytes(&self) -> &[u8] {
        self.source().as_bytes()
    }
}

impl<'s, 'o, T> Compare<T> for Fragment<'s>
where
    &'o str: Compare<T>,
    's: 'o,
{
    #[inline]
    fn compare(&self, t: T) -> CompareResult {
        self.source().compare(t)
    }

    #[inline]
    fn compare_no_case(&self, t: T) -> CompareResult {
        self.source().compare_no_case(t)
    }
}

impl<'s> ExtendInto for Fragment<'s> {
    type Item = char;
    type Extender = String;

    #[inline]
    fn new_builder(&self) -> String {
        String::new()
    }

    #[inline]
    fn extend_into(&self, acc: &mut Self::Extender) {
        self.source().extend_into(acc)
    }
}

impl<'s> FindSubstring<&str> for Fragment<'s> {
    #[inline]
    fn find_substring(&self, substr: &str) -> Option<usize> {
        self.source().find_substring(substr)
    }
}

impl<'s, 'o, T> FindToken<T> for Fragment<'s>
where
    &'o str: FindToken<T>,
    's: 'o,
{
    #[inline]
    fn find_token(&self, t: T) -> bool {
        self.source().find_token(t)
    }
}

impl<'s> InputIter for Fragment<'s> {
    type Item = <&'s str as InputIter>::Item;
    type Iter = <&'s str as InputIter>::Iter;
    type IterElem = <&'s str as InputIter>::IterElem;

    #[inline]
    fn iter_indices(&self) -> Self::Iter {
        self.source().iter_indices()
    }

    #[inline]
    fn iter_elements(&self) -> Self::IterElem {
        self.source().iter_elements()
    }

    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize>
    where
        P: Fn(Self::Item) -> bool,
    {
        self.source().position(predicate)
    }

    #[inline]
    fn slice_index(&self, count: usize) -> Option<usize> {
        self.source().slice_index(count)
    }
}

impl<'s> InputLength for Fragment<'s> {
    #[inline]
    fn input_len(&self) -> usize {
        self.len()
    }
}

impl<'s> InputTake for Fragment<'s> {
    fn take(&self, count: usize) -> Self {
        let mut frag2 = self.clone();
        frag2.source = &self.source()[..count];
        frag2.span = Span::new(self.start(), self.start() + ByteOffset(count as i64));
        frag2
    }

    fn take_split(&self, count: usize) -> (Self, Self) {
        let mut frag2 = self.clone();
        let mut frag3 = self.clone();
        frag2.source = &self.source()[..count];
        frag3.source = &self.source()[count..];
        frag2.span = Span::new(self.start(), self.start() + ByteOffset(count as i64));
        frag3.span = Span::new(self.start() + ByteOffset(count as i64), self.end());
        (frag3, frag2) // (part after, part before)
    }
}

impl<'s> InputTakeAtPosition for Fragment<'s> {
    type Item = char;

    fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(i) => Ok(self.take_split(i)),
            None => Err(Err::Incomplete(Needed::Size(1))),
        }
    }

    fn split_at_position1<P, E: ParseError<Self>>(
        &self,
        predicate: P,
        e: ErrorKind,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(0) => Err(Err::Error(E::from_error_kind(self.clone(), e))),
            Some(i) => Ok(self.take_split(i)),
            None => Err(Err::Incomplete(Needed::Size(1))),
        }
    }

    fn split_at_position_complete<P, E: ParseError<Self>>(
        &self,
        predicate: P,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(i) => Ok(self.take_split(i)),
            None => Ok(self.take_split(self.input_len())),
        }
    }

    fn split_at_position1_complete<P, E: ParseError<Self>>(
        &self,
        predicate: P,
        e: ErrorKind,
    ) -> IResult<Self, Self, E>
    where
        P: Fn(Self::Item) -> bool,
    {
        match self.source().find(predicate) {
            Some(0) => Err(Err::Error(E::from_error_kind(self.clone(), e))),
            Some(i) => Ok(self.take_split(i)),
            None => Ok(self.take_split(self.input_len())),
        }
    }
}

impl<'s> Offset for Fragment<'s> {
    fn offset(&self, second: &Self) -> usize {
        (second.span.start() - self.span.start()).0 as usize
    }
}

impl<'s, R: FromStr> ParseTo<R> for Fragment<'s> {
    #[inline]
    fn parse_to(&self) -> Option<R> {
        self.source().parse_to()
    }
}

impl<'s> Slice<Range<usize>> for Fragment<'s> {
    fn slice(&self, range: Range<usize>) -> Self {
        let mut result = self.clone();
        result.source = &self.source()[range.clone()];
        result.span = Span::new(
            self.span.start() + ByteOffset(range.start as i64),
            self.span.start() + ByteOffset(range.end as i64),
        );
        result
    }
}

impl<'s> Slice<RangeFrom<usize>> for Fragment<'s> {
    fn slice(&self, range: RangeFrom<usize>) -> Self {
        self.slice(range.start..self.len())
    }
}

impl<'s> Slice<RangeTo<usize>> for Fragment<'s> {
    fn slice(&self, range: RangeTo<usize>) -> Self {
        self.slice(0..range.end)
    }
}

impl<'s> Slice<RangeFull> for Fragment<'s> {
    fn slice(&self, _: RangeFull) -> Self {
        self.clone()
    }
}

impl<'s> PartialEq for Fragment<'s> {
    // This will fail if it is used to compare across two separate Files
    // objects.
    fn eq(&self, other: &Self) -> bool {
        other.handle == self.handle && other.span == self.span
    }
}

/// Trait for all types that have associated fragments in source code.
pub trait HasFragment<'s> {
    /// Get the associated fragment of source code.
    fn get_fragment(&self) -> Fragment<'s>;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use common::run_java;

mod common;

#[test]
fn basic() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "", &[], &["Resource exhaustion event: the JVM was unable to create a thread.",
        "ERROR: PoolStats action failed"]));
}

#[test]
fn print_memory_usage_0() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "=printMemoryUsage=0", &[], &["jvmkill killing current process"]));
}

#[test]
fn time_10_count_2() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "=time=10,count=2,printHeapHistogram=0,printMemoryUsage=0",
                      &[], &["ResourceExhausted! (1/2)", "jvmkill killing current process"]));
}

#[test]
fn parallel_time_10_count_2() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ParallelThreadExhaustion", "=time=10,count=2,printHeapHistogram=0,printMemoryUsage=0", &[],
                      &["ResourceExhausted! (1/2)", "jvmkill killing current process"]));
}
<commit_msg>Reduce expectations for parallel test<commit_after>/*
 * Copyright (c) 2015-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use common::run_java;

mod common;

#[test]
fn basic() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "", &[], &["Resource exhaustion event: the JVM was unable to create a thread.",
        "ERROR: PoolStats action failed"]));
}

#[test]
fn print_memory_usage_0() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "=printMemoryUsage=0", &[], &["jvmkill killing current process"]));
}

#[test]
fn time_10_count_2() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ThreadExhaustion", "=time=10,count=2,printHeapHistogram=0,printMemoryUsage=0",
                      &[], &["ResourceExhausted! (1/2)", "jvmkill killing current process"]));
}

#[test]
fn parallel_time_10_count_2() {
    assert!(!run_java("org.cloudfoundry.jvmkill.ParallelThreadExhaustion", "=time=10,count=2,printHeapHistogram=0,printMemoryUsage=0", &[],
                      &["jvmkill killing current process"]));
}
<|endoftext|>