<commit_before>use Cursive;
use With;
use event::{Callback, Event, EventResult};
use std::collections::HashMap;
use std::rc::Rc;
use view::{View, ViewWrapper};

/// A simple wrapper view that catches some ignored event from its child.
///
/// If the event doesn't have a corresponding callback, it will stay ignored.
///
/// # Examples
///
/// ```
/// # use cursive::event;;
/// # use cursive::views::{OnEventView, TextView};
/// let view = OnEventView::new(TextView::new("This view has an event!"))
///                         .on_event('q', |s| s.quit())
///                         .on_event(event::Key::Esc, |s| s.quit());
/// ```
pub struct OnEventView<T: View> {
    inner: T,
    callbacks: HashMap<Event, Action<T>>,
}

type InnerCallback<T> = Rc<Box<Fn(&mut T) -> Option<EventResult>>>;

struct Action<T> {
    phase: TriggerPhase,
    callback: InnerCallback<T>,
}

impl<T> Clone for Action<T> {
    fn clone(&self) -> Self {
        Action {
            phase: self.phase.clone(),
            callback: Rc::clone(&self.callback),
        }
    }
}

#[derive(PartialEq, Clone)]
enum TriggerPhase {
    BeforeChild,
    AfterChild,
}

impl<T: View> OnEventView<T> {
    /// Wraps the given view in a new OnEventView.
    pub fn new(view: T) -> Self {
        OnEventView {
            inner: view,
            callbacks: HashMap::new(),
        }
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// Chainable variant.
    pub fn on_event<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        self.with(|s| s.set_on_event(event, cb))
    }

    /// Registers a callback when the given event is received.
    ///
    /// The child will never receive this event.
    ///
    /// Chainable variant.
    pub fn on_pre_event<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        self.with(|s| s.set_on_pre_event(event, cb))
    }

    /// Registers a callback when the given event is received.
    ///
    /// The given callback will be run before the child view sees the event.
    /// * If the result is `None`, then the child view is given the event as
    ///   usual.
    /// * Otherwise, it bypasses the child view and directly processes the
    ///   result.
    ///
    /// Chainable variant.
    pub fn on_pre_event_inner<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.with(|s| s.set_on_pre_event_inner(event, cb))
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// If the child view ignores the event, `cb` will be called with the
    /// child view as argument.
    /// If the result is not `None`, it will be processed as well.
    ///
    /// Chainable variant.
    pub fn on_event_inner<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.with(|s| s.set_on_event_inner(event, cb))
    }

    /// Registers a callback when the given event is ignored by the child.
    pub fn set_on_event<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        let cb = Callback::from_fn(cb);
        let action =
            move |_: &mut T| Some(EventResult::Consumed(Some(cb.clone())));

        self.set_on_event_inner(event, action);
    }

    /// Registers a callback when the given event is received.
    ///
    /// The child will never receive this event.
    pub fn set_on_pre_event<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        let cb = Callback::from_fn(cb);
        let action =
            move |_: &mut T| Some(EventResult::Consumed(Some(cb.clone())));

        self.set_on_pre_event_inner(event, action);
    }

    /// Registers a callback when the given event is received.
    ///
    /// The given callback will be run before the child view sees the event.
    /// * If the result is `None`, then the child view is given the event as
    ///   usual.
    /// * Otherwise, it bypasses the child view and directly processes the
    ///   result.
    pub fn set_on_pre_event_inner<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.callbacks.insert(
            event.into(),
            Action {
                phase: TriggerPhase::BeforeChild,
                callback: Rc::new(Box::new(cb)),
            },
        );
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// If the child view ignores the event, `cb` will be called with the
    /// child view as argument.
    /// If the result is not `None`, it will be processed as well.
    pub fn set_on_event_inner<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.callbacks.insert(
            event.into(),
            Action {
                phase: TriggerPhase::AfterChild,
                callback: Rc::new(Box::new(cb)),
            },
        );
    }
}

impl<T: View> ViewWrapper for OnEventView<T> {
    wrap_impl!(self.inner: T);

    fn wrap_on_event(&mut self, event: Event) -> EventResult {
        let action = self.callbacks.get(&event).cloned();
        let pre_child = action
            .as_ref()
            .map(|a| a.phase == TriggerPhase::BeforeChild)
            .unwrap_or(false);

        if pre_child {
            action
                .and_then(|a| (*a.callback)(&mut self.inner))
                .unwrap_or_else(|| self.inner.on_event(event))
        } else {
            self.inner.on_event(event).or_else(|| {
                action
                    .and_then(|a| (*a.callback)(&mut self.inner))
                    .unwrap_or(EventResult::Ignored)
            })
        }
    }
}
<commit_msg>OnEventView: better doc<commit_after>use Cursive;
use With;
use event::{Callback, Event, EventResult};
use std::collections::HashMap;
use std::rc::Rc;
use view::{View, ViewWrapper};

/// A wrapper view that can react to events.
///
/// This view registers a set of callbacks tied to specific events, to be run
/// in certain conditions.
///
/// * Some callbacks are called only for vents ignored by the wrapped view
///   (those registered by [`on_event`] or [`on_event_inner`])
/// * Others are processed first, and can control whether the child view should
///   be given the event (those registered by [`on_pre_event`] or
///   [`on_pre_event_inner`]).
///
/// "Inner" callbacks ([`on_event_inner`] and [`on_pre_event_inner`]) are given
/// a reference to the inner wrapped view (but not to the `Cursive` root). They
/// can then return another callback, taking only a `&mut Cursive` root as
/// argument.
///
/// "Simple" callbacks ([`on_event`] and [`on_pre_event`]) skip this first
/// phase and are only called with a `&mut Cursive`.
///
/// [`on_event`]: struct.OnEventView.html#method.on_event
/// [`on_pre_event`]: struct.OnEventView.html#method.on_pre_event
/// [`on_event_inner`]: struct.OnEventView.html#method.on_event_inner
/// [`on_pre_event_inner`]: struct.OnEventView.html#method.on_pre_event_inner
///
/// # Examples
///
/// ```
/// # use cursive::event;;
/// # use cursive::views::{OnEventView, TextView};
/// let view = OnEventView::new(TextView::new("This view has an event!"))
///                         .on_event('q', |s| s.quit())
///                         .on_event(event::Key::Esc, |s| s.quit());
/// ```
pub struct OnEventView<T: View> {
    inner: T,
    callbacks: HashMap<Event, Action<T>>,
}

type InnerCallback<T> = Rc<Box<Fn(&mut T) -> Option<EventResult>>>;

struct Action<T> {
    phase: TriggerPhase,
    callback: InnerCallback<T>,
}

impl<T> Clone for Action<T> {
    fn clone(&self) -> Self {
        Action {
            phase: self.phase.clone(),
            callback: Rc::clone(&self.callback),
        }
    }
}

#[derive(PartialEq, Clone)]
enum TriggerPhase {
    BeforeChild,
    AfterChild,
}

impl<T: View> OnEventView<T> {
    /// Wraps the given view in a new OnEventView.
    pub fn new(view: T) -> Self {
        OnEventView {
            inner: view,
            callbacks: HashMap::new(),
        }
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// Chainable variant.
    pub fn on_event<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        self.with(|s| s.set_on_event(event, cb))
    }

    /// Registers a callback when the given event is received.
    ///
    /// The child will never receive this event.
    ///
    /// Chainable variant.
    pub fn on_pre_event<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        self.with(|s| s.set_on_pre_event(event, cb))
    }

    /// Registers a callback when the given event is received.
    ///
    /// The given callback will be run before the child view sees the event.
    ///
    /// * If the result is `None`, then the child view is given the event as
    ///   usual.
    /// * Otherwise, it bypasses the child view and directly processes the
    ///   result.
    ///
    /// Chainable variant.
    pub fn on_pre_event_inner<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.with(|s| s.set_on_pre_event_inner(event, cb))
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// If the child view ignores the event, `cb` will be called with the
    /// child view as argument.
    /// If the result is not `None`, it will be processed as well.
    ///
    /// Chainable variant.
    pub fn on_event_inner<F, E>(self, event: E, cb: F) -> Self
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.with(|s| s.set_on_event_inner(event, cb))
    }

    /// Registers a callback when the given event is ignored by the child.
    pub fn set_on_event<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        let cb = Callback::from_fn(cb);
        let action =
            move |_: &mut T| Some(EventResult::Consumed(Some(cb.clone())));

        self.set_on_event_inner(event, action);
    }

    /// Registers a callback when the given event is received.
    ///
    /// The child will never receive this event.
    pub fn set_on_pre_event<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut Cursive) + 'static,
    {
        let cb = Callback::from_fn(cb);
        let action =
            move |_: &mut T| Some(EventResult::Consumed(Some(cb.clone())));

        self.set_on_pre_event_inner(event, action);
    }

    /// Registers a callback when the given event is received.
    ///
    /// The given callback will be run before the child view sees the event.
    ///
    /// * If the result is `None`, then the child view is given the event as
    ///   usual.
    /// * Otherwise, it bypasses the child view and directly processes the
    ///   result.
    pub fn set_on_pre_event_inner<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.callbacks.insert(
            event.into(),
            Action {
                phase: TriggerPhase::BeforeChild,
                callback: Rc::new(Box::new(cb)),
            },
        );
    }

    /// Registers a callback when the given event is ignored by the child.
    ///
    /// If the child view ignores the event, `cb` will be called with the
    /// child view as argument.
    /// If the result is not `None`, it will be processed as well.
    pub fn set_on_event_inner<F, E>(&mut self, event: E, cb: F)
    where
        E: Into<Event>,
        F: Fn(&mut T) -> Option<EventResult> + 'static,
    {
        self.callbacks.insert(
            event.into(),
            Action {
                phase: TriggerPhase::AfterChild,
                callback: Rc::new(Box::new(cb)),
            },
        );
    }
}

impl<T: View> ViewWrapper for OnEventView<T> {
    wrap_impl!(self.inner: T);

    fn wrap_on_event(&mut self, event: Event) -> EventResult {
        let action = self.callbacks.get(&event).cloned();
        let pre_child = action
            .as_ref()
            .map(|a| a.phase == TriggerPhase::BeforeChild)
            .unwrap_or(false);

        if pre_child {
            action
                .and_then(|a| (*a.callback)(&mut self.inner))
                .unwrap_or_else(|| self.inner.on_event(event))
        } else {
            self.inner.on_event(event).or_else(|| {
                action
                    .and_then(|a| (*a.callback)(&mut self.inner))
                    .unwrap_or(EventResult::Ignored)
            })
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
extern crate macho;

use std::env;
use std::fs;
use std::io::Read;
use nom::IResult;

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() != 2 {
        println!("Usage: {} <file>", args[0]);
        return;
    }

    let mut fh = fs::File::open(&args[1]).unwrap();
    let mut buf: Vec<u8> = Vec::new();
    let _ = fh.read_to_end(&mut buf);

    match macho::MachHeader::parse(&buf[..]) {
        Some(header) => {
            println!("{:?}", header);
        },
        None => {
            panic!("Error parsing header")
        }

    }
}
<commit_msg>Unused import<commit_after>#[macro_use]
extern crate nom;
extern crate macho;

use std::env;
use std::fs;
use std::io::Read;

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() != 2 {
        println!("Usage: {} <file>", args[0]);
        return;
    }

    let mut fh = fs::File::open(&args[1]).unwrap();
    let mut buf: Vec<u8> = Vec::new();
    let _ = fh.read_to_end(&mut buf);

    match macho::MachHeader::parse(&buf[..]) {
        Some(header) => {
            println!("{:?}", header);
        },
        None => {
            panic!("Error parsing header")
        }

    }
}
<|endoftext|>


<commit_before>extern crate gcc;

use std::path::{ PathBuf, Path };
use std::process::Command;

struct Perl {
    bin: String,
}

impl Perl {
    fn new() -> Perl {
        Perl {
            bin: std::env::var("PERL").unwrap_or("perl".to_owned()),
        }
    }

    fn cfg(&self, key: &str) -> String {
        let out = Command::new(&self.bin)
            .arg("-MConfig")
            .arg("-e")
            .arg(format!("print $Config::Config{{{}}}", key))
            .output()
            .unwrap();

        String::from_utf8(out.stdout).unwrap()
    }

    fn run(&self, script: &str) {
        let status = Command::new(&self.bin)
            .arg(script)
            .status()
            .unwrap();
        assert!(status.success());
    }

    fn path_core(&self) -> PathBuf {
        let archlib = self.cfg("archlibexp");
        Path::new(&archlib).join("CORE")
    }
}

fn build_ouro(perl: &Perl) {
    let mut gcc = gcc::Config::new();

    let ccflags = perl.cfg("ccflags");
    for flag in ccflags.split_whitespace() {
        gcc.flag(flag);
    }

    gcc.include(&perl.path_core());

    gcc.file("ouroboros/libouroboros.c");
    gcc.compile("libouroboros.a");
}

fn main() {
    let perl = Perl::new();

    build_ouro(&perl);

    perl.run("build/regen.pl");

    if perl.cfg("multiplicity") == "true" {
        println!("cargo:rustc-cfg=perl_multiplicity");
    }

    if perl.cfg("useshrplib") == "true" {
        println!("cargo:rustc-cfg=perl_useshrplib");

        // Make sure ld links to libperl that matches current perl interpreter, instead of whatever
        // is libperl version exists in default linker search path. $archlibexp/CORE is hard-coded
        // installation path for default perl so this ought to be enough in most cases.
        println!("cargo:rustc-link-search=native={}", perl.path_core().to_str().unwrap());
    }
}
<commit_msg>Fix multiplicity cfg flag.<commit_after>extern crate gcc;

use std::path::{ PathBuf, Path };
use std::process::Command;

struct Perl {
    bin: String,
}

impl Perl {
    fn new() -> Perl {
        Perl {
            bin: std::env::var("PERL").unwrap_or("perl".to_owned()),
        }
    }

    fn cfg(&self, key: &str) -> String {
        let out = Command::new(&self.bin)
            .arg("-MConfig")
            .arg("-e")
            .arg(format!("print $Config::Config{{{}}}", key))
            .output()
            .unwrap();

        String::from_utf8(out.stdout).unwrap()
    }

    fn run(&self, script: &str) {
        let status = Command::new(&self.bin)
            .arg(script)
            .status()
            .unwrap();
        assert!(status.success());
    }

    fn path_core(&self) -> PathBuf {
        let archlib = self.cfg("archlibexp");
        Path::new(&archlib).join("CORE")
    }
}

fn build_ouro(perl: &Perl) {
    let mut gcc = gcc::Config::new();

    let ccflags = perl.cfg("ccflags");
    for flag in ccflags.split_whitespace() {
        gcc.flag(flag);
    }

    gcc.include(&perl.path_core());

    gcc.file("ouroboros/libouroboros.c");
    gcc.compile("libouroboros.a");
}

fn main() {
    let perl = Perl::new();

    build_ouro(&perl);

    perl.run("build/regen.pl");

    if perl.cfg("usemultiplicity") == "define" {
        println!("cargo:rustc-cfg=perl_multiplicity");
    }

    if perl.cfg("useshrplib") == "true" {
        println!("cargo:rustc-cfg=perl_useshrplib");

        // Make sure ld links to libperl that matches current perl interpreter, instead of whatever
        // is libperl version exists in default linker search path. $archlibexp/CORE is hard-coded
        // installation path for default perl so this ought to be enough in most cases.
        println!("cargo:rustc-link-search=native={}", perl.path_core().to_str().unwrap());
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::time::Instant;
use std::time::Duration;
use super::entry::{Entry, EntryId};
use super::storage::Storage;
use super::sync::Receiver;

///
/// Minimum duration between expiration checks in seconds
///
const CHECK_INTERVAL: u64 = 1;

///
/// Duration of sleep between loop turns (in milliseconds)
///
const SLEEP_DURATION: u64 = 100;

pub trait Listener<T: Send + 'static>: Send {
    fn on_expired(&self, entry: Vec<Entry<T>>);
}

#[derive(Debug)]
pub enum Command<T: Send + 'static> {
    AddEntry(Entry<T>),
    RemoveEntry(EntryId),
}

pub struct Worker<T: Send + 'static> {
    storage: Storage<T>,
    receiver: Receiver<Command<T>>,
    listener: Box<Listener<T>>,
    last_checked: Option<Instant>,
}

pub fn spawn_worker<T: Send + 'static>(
    storage: Storage<T>,
    receiver: Receiver<Command<T>>,
    listener: Box<Listener<T>>,
) -> thread::JoinHandle<()> {
    thread::spawn(move || {
        let worker = Worker::new(storage, receiver, listener);

        worker.run();
    })
}

impl<T: Send + 'static> Worker<T> {
    pub fn new(
        storage: Storage<T>,
        receiver: Receiver<Command<T>>,
        listener: Box<Listener<T>>,
    ) -> Worker<T> {
        Worker {
            storage,
            receiver,
            listener,
            last_checked: None,
        }
    }

    pub fn run(mut self) {
        let sleep_dur = Duration::from_millis(SLEEP_DURATION);

        loop {
            let mut should_sleep = true;

            if self.receiver.has_incoming() {
                should_sleep = false;

                self.handle_incoming();
            }

            if self.needs_checking() {
                should_sleep = false;

                self.check_expired();
            }

            if should_sleep {
                thread::sleep(sleep_dur);
            }
        }
    }

    fn handle_incoming(&mut self) {
        let incoming = self.receiver.recv();

        match incoming {
            Err(_) => panic!("channel disconnected"),
            Ok(command) => self.handle_command(command),
        }
    }

    fn handle_command(&mut self, command: Command<T>) {
        match command {
            Command::AddEntry(entry) => {
                self.storage.add_entry(entry);
            }
            Command::RemoveEntry(id) => {
                self.storage.remove_entry(id);
            }
        }
    }

    fn check_expired(&mut self) {
        self.last_checked = Some(Instant::now());
        self.listener.on_expired(self.storage.expire_entries());
    }

    fn needs_checking(&self) -> bool {
        match self.last_checked {
            None => true,
            Some(value) => {
                return value.elapsed().as_secs() >= CHECK_INTERVAL;
            }
        }
    }
}
<commit_msg>Improve worker run loop<commit_after>use std::thread;
use std::time::Instant;
use std::time::Duration;
use super::entry::{Entry, EntryId};
use super::storage::Storage;
use super::sync::Receiver;

///
/// Minimum duration between expiration checks in seconds
///
const CHECK_INTERVAL: u64 = 1;

///
/// Duration of sleep between loop turns (in milliseconds)
///
const SLEEP_DURATION: u64 = 100;

pub trait Listener<T: Send + 'static>: Send {
    fn on_expired(&self, entry: Vec<Entry<T>>);
}

#[derive(Debug)]
pub enum Command<T: Send + 'static> {
    AddEntry(Entry<T>),
    RemoveEntry(EntryId),
}

#[derive(Debug)]
enum Action {
    ReceiveCommand,
    CheckExpired,
    Sleep,
}

pub struct Worker<T: Send + 'static> {
    storage: Storage<T>,
    receiver: Receiver<Command<T>>,
    listener: Box<Listener<T>>,
    last_checked: Option<Instant>,
}

pub fn spawn_worker<T: Send + 'static>(
    storage: Storage<T>,
    receiver: Receiver<Command<T>>,
    listener: Box<Listener<T>>,
) -> thread::JoinHandle<()> {
    thread::spawn(move || {
        let worker = Worker::new(storage, receiver, listener);

        worker.run();
    })
}

impl<T: Send + 'static> Worker<T> {
    pub fn new(
        storage: Storage<T>,
        receiver: Receiver<Command<T>>,
        listener: Box<Listener<T>>,
    ) -> Worker<T> {
        Worker {
            storage,
            receiver,
            listener,
            last_checked: None,
        }
    }

    pub fn run(mut self) {
        let sleep_dur = Duration::from_millis(SLEEP_DURATION);

        loop {
            match self.determine_action() {
                Action::ReceiveCommand => self.handle_incoming(),
                Action::CheckExpired => self.check_expired(),
                Action::Sleep => thread::sleep(sleep_dur),
            }
        }
    }

    fn determine_action(&self) -> Action {
        if self.receiver.has_incoming() {
            return Action::ReceiveCommand;
        }

        if self.needs_checking() {
            return Action::CheckExpired;
        }

        Action::Sleep
    }

    fn handle_incoming(&mut self) {
        let incoming = self.receiver.recv();

        match incoming {
            Err(_) => panic!("channel disconnected"),
            Ok(command) => self.handle_command(command),
        }
    }

    fn handle_command(&mut self, command: Command<T>) {
        match command {
            Command::AddEntry(entry) => self.storage.add_entry(entry),
            Command::RemoveEntry(id) => self.storage.remove_entry(id),
        }
    }

    fn check_expired(&mut self) {
        self.last_checked = Some(Instant::now());
        self.listener.on_expired(self.storage.expire_entries());
    }

    fn needs_checking(&self) -> bool {
        match self.last_checked {
            None => true,
            Some(value) => {
                return value.elapsed().as_secs() >= CHECK_INTERVAL;
            }
        }
    }
}
<|endoftext|>


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

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(not(feature="clippy"), allow(unknown_lints))]
extern crate env_logger;

#[cfg(feature = "amqp0-codegen")]
extern crate amqp0_codegen as codegen;
#[cfg(feature = "amqp0-specs")]
extern crate amqp0_specs as specs;

fn main() {
    amqp0::build();
}

#[cfg(not(feature = "amqp0-specs"))]
mod amqp0 {
    pub fn build() {
        println!("Skipping build (neither amqp0-build-primitives nor amqp0-pregen-primitives specified)");
    }
}

#[cfg(feature = "amqp0-specs")]
mod amqp0 {
    use std::env;
    use std::path::{Path, PathBuf};

    use env_logger;
    use codegen;
    use codegen::primalgen::ModulesWriter;
    use specs::specs as amqp0_specs;

    const BUILDER_CRATES: &'static [&'static str] = &["amqp0-codegen"];
    const BUILDER_REBUILD: &'static [&'static str] = &["amqp0-build-primitives"];
    const BUILDER_PREGEN: &'static [&'static str] = &["amqp0-build-primitives"];

    struct PrimitivesSource {
        base_dir: PathBuf,
    }

    impl codegen::Source for PrimitivesSource {
        fn name(&self) -> &str { "amqp0-primitives" }
        fn crates(&self) -> &[&str] { BUILDER_CRATES }

        fn rebuild_features(&self) -> &[&str] { BUILDER_REBUILD }
        fn pregeneration_features(&self) -> &[&str] { BUILDER_PREGEN }

        fn base_dir(&self) -> &Path { &self.base_dir }
        fn should_format(&self) -> bool { cfg!(feature = "rustfmt") }
    }

    pub fn build() {
        let base_dir = if cfg!(feature = "amqp0-pregen-primitives") {
            PathBuf::from("pregen")
        } else {
            env::var_os("OUT_DIR")
                .map(PathBuf::from)
                .expect("Error: OUT_DIR not set")
        };

        env_logger::init().unwrap();
        println!("Building primitives from amqpspec");

        let source = PrimitivesSource { base_dir: base_dir };
        let writer = ModulesWriter::new(&source, amqp0_specs());
        writer.write_files().unwrap();
    }
}<commit_msg>[primitives] Correct the pregen feature name documented in the pregenerated files.<commit_after>// Copyright 2016 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(not(feature="clippy"), allow(unknown_lints))]
extern crate env_logger;

#[cfg(feature = "amqp0-codegen")]
extern crate amqp0_codegen as codegen;
#[cfg(feature = "amqp0-specs")]
extern crate amqp0_specs as specs;

fn main() {
    amqp0::build();
}

#[cfg(not(feature = "amqp0-specs"))]
mod amqp0 {
    pub fn build() {
        println!("Skipping build (neither amqp0-build-primitives nor amqp0-pregen-primitives specified)");
    }
}

#[cfg(feature = "amqp0-specs")]
mod amqp0 {
    use std::env;
    use std::path::{Path, PathBuf};

    use env_logger;
    use codegen;
    use codegen::primalgen::ModulesWriter;
    use specs::specs as amqp0_specs;

    const BUILDER_CRATES: &'static [&'static str] = &["amqp0-codegen"];
    const BUILDER_REBUILD: &'static [&'static str] = &["amqp0-build-primitives"];
    const BUILDER_PREGEN: &'static [&'static str] = &["amqp0-pregen-primitives"];

    struct PrimitivesSource {
        base_dir: PathBuf,
    }

    impl codegen::Source for PrimitivesSource {
        fn name(&self) -> &str { "amqp0-primitives" }
        fn crates(&self) -> &[&str] { BUILDER_CRATES }

        fn rebuild_features(&self) -> &[&str] { BUILDER_REBUILD }
        fn pregeneration_features(&self) -> &[&str] { BUILDER_PREGEN }

        fn base_dir(&self) -> &Path { &self.base_dir }
        fn should_format(&self) -> bool { cfg!(feature = "rustfmt") }
    }

    pub fn build() {
        let base_dir = if cfg!(feature = "amqp0-pregen-primitives") {
            PathBuf::from("pregen")
        } else {
            env::var_os("OUT_DIR")
                .map(PathBuf::from)
                .expect("Error: OUT_DIR not set")
        };

        env_logger::init().unwrap();
        println!("Building primitives from amqpspec");

        let source = PrimitivesSource { base_dir: base_dir };
        let writer = ModulesWriter::new(&source, amqp0_specs());
        writer.write_files().unwrap();
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate afterparty;
extern crate hyper;

use afterparty::{Delivery, Event, Hub};

use hyper::Server;

pub fn main() {
    env_logger::init().unwrap();
    let addr = format!("0.0.0.0:{}", 4567);
    let mut hub = Hub::new();
    hub.handle("pull_request", |delivery: &Delivery| {
        println!("rec delivery {:#?}", delivery);
        /*match delivery.payload {
            Event::PullRequest { ref action, ref sender, .. } => {
                println!("sender {} action {}", sender.login, action)
            }
            _ => (),
        }*/
    });
    let srvc = Server::http(&addr[..])
                   .unwrap()
                   .handle(hub);
    println!("listening on {}", addr);
    srvc.unwrap();
}
<commit_msg>unused import<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate afterparty;
extern crate hyper;

use afterparty::{Delivery, Hub};

use hyper::Server;

pub fn main() {
    env_logger::init().unwrap();
    let addr = format!("0.0.0.0:{}", 4567);
    let mut hub = Hub::new();
    hub.handle("pull_request", |delivery: &Delivery| {
        println!("rec delivery {:#?}", delivery);
        /*match delivery.payload {
            Event::PullRequest { ref action, ref sender, .. } => {
                println!("sender {} action {}", sender.login, action)
            }
            _ => (),
        }*/
    });
    let srvc = Server::http(&addr[..])
                   .unwrap()
                   .handle(hub);
    println!("listening on {}", addr);
    srvc.unwrap();
}
<|endoftext|>


<commit_before>use rusoto_core::signature;

/// URL encodes an S3 object key. This is necessary for `copy_object` and `upload_part_copy`,
/// which require the `copy_source` field to be URL encoded.
///
/// # Examples
///
/// ```
/// use rusoto_s3::CopyObjectRequest;
///
/// let request = CopyObjectRequest {
///     bucket: "my-bucket".to_owned(),
///     key: "my-key".to_owned(),
///     copy_source: rusoto_s3::util::encode_key("other-buckét/key-to-cöpy"),
///     ..Default::default()
/// };
pub fn encode_key<T: AsRef<str>>(key: T) -> String {
    signature::encode_uri_path(key.as_ref())
}
<commit_msg>Add code block closing tag to encode_key docs<commit_after>use rusoto_core::signature;

/// URL encodes an S3 object key. This is necessary for `copy_object` and `upload_part_copy`,
/// which require the `copy_source` field to be URL encoded.
///
/// # Examples
///
/// ```
/// use rusoto_s3::CopyObjectRequest;
///
/// let request = CopyObjectRequest {
///     bucket: "my-bucket".to_owned(),
///     key: "my-key".to_owned(),
///     copy_source: rusoto_s3::util::encode_key("other-buckét/key-to-cöpy"),
///     ..Default::default()
/// };
/// ```
pub fn encode_key<T: AsRef<str>>(key: T) -> String {
    signature::encode_uri_path(key.as_ref())
}
<|endoftext|>


<commit_before>//! Support for mock HTTP servers that verify pacts.

use pact_matching::models::*;
use pact_mock_server::*;
use pact_mock_server::matching::MatchResult;
use std::{
  fmt::Write as FmtWrite,
  env,
  io::{self, prelude::*},
  thread
};
use url::Url;
use futures::future::*;

/// This trait is implemented by types which allow us to start a mock server.
pub trait StartMockServer {
    /// Start a mock server running in a background thread.
    fn start_mock_server(&self) -> BackgroundMockServer;

    /// Asynchronously spawn a mock server onto the current tokio runtime.
    fn spawn_mock_server(&self) -> BoxFuture<'static, SpawnedMockServer>;
}

impl StartMockServer for Pact {
    fn start_mock_server(&self) -> BackgroundMockServer {
        BackgroundMockServer::new(self.clone())
    }

    fn spawn_mock_server(&self) -> BoxFuture<'static, SpawnedMockServer> {
        SpawnedMockServer::new(self.clone()).boxed()
    }
}

///
/// A trait for accessing the properties of a mock server.
///
pub trait ValidatingMockServer {
    /// The URL of our mock server. You can make normal HTTP requests using this
    /// as the base URL.
    fn url(&self) -> &Url;

    /// Given a path string, return a URL pointing to that path on the mock
    /// server. If the `path` cannot be parsed as URL, **this function will
    /// panic**. For a non-panicking version, call `.url()` instead and build
    /// this path yourself.
    fn path<P: AsRef<str>>(&self, path: P) -> Url;

    /// Returns the current status of the mock server
    fn status(&self) -> Vec<MatchResult>;
}

/// Inner struct for shared data and behaviour of mock servers
struct InnerServer {
    // A description of our mock server, for use in error messages.
    description: String,
    // The URL of our mock server.
    url: Url,
    // The mock server instance
    mock_server: mock_server::MockServer,
    // The running server's asynchronous join handle
    server_handle: Option<tokio::task::JoinHandle<()>>,
}

impl InnerServer {
    fn new(
        mock_server: mock_server::MockServer,
        server_handle: tokio::task::JoinHandle<()>
    ) -> InnerServer {
        let description = format!("{}/{}", mock_server.pact.consumer.name, mock_server.pact.provider.name);
        let url_str = mock_server.url();
        InnerServer {
            description,
            url: url_str.parse().expect("invalid mock server URL"),
            mock_server,
            server_handle: Some(server_handle)
        }
    }

    /// Initialize the inner mock server instance
    async fn init_mock_server(
        pact: Pact
    ) -> Result<(mock_server::MockServer, impl std::future::Future<Output = ()>), String> {
        mock_server::MockServer::new(
            "".into(),
            pact,
            ([0, 0, 0, 0], 0 as u16).into()
        ).await
    }

    /// Helper function called by our `drop` implementation. This basically exists
    /// so that it can return `Err(message)` whenever needed without making the
    /// flow control in `drop` ultra-complex.
    fn drop_helper(&mut self) -> Result<(), String> {
        // Look up any mismatches which occurred.
        let mismatches = self.mock_server.mismatches();

        if mismatches.is_empty() {
            // Success! Write out the generated pact file.
            self.mock_server.write_pact(&Some(env::var("PACT_OUTPUT_DIR").unwrap_or("target/pacts".to_owned())))
                .map_err(|err| format!("error writing pact: {}", err))?;
            Ok(())
        } else {
            // Failure. Format our errors.
            let mut msg = format!(
                "mock server {} failed verification:\n",
                self.description,
            );
            for mismatch in mismatches {
                match mismatch {
                    MatchResult::RequestMatch(_) => {
                        unreachable!("list of mismatches contains a match");
                    }
                    MatchResult::RequestMismatch(interaction, mismatches) => {
                        let _ = writeln!(
                            &mut msg,
                            "- interaction {:?}:",
                            interaction.description,
                        );
                        for m in mismatches {
                            let _ = writeln!(&mut msg, "  - {}", m.description());
                        }
                    }
                    MatchResult::RequestNotFound(request) => {
                        let _ = writeln!(&mut msg, "- received unexpected request:");
                        let _ = writeln!(&mut msg, "{:#?}", request);
                    }
                    MatchResult::MissingRequest(interaction) => {
                        let _ = writeln!(
                            &mut msg,
                            "- interaction {:?} expected, but never occurred",
                            interaction.description,
                        );
                        let _ = writeln!(&mut msg, "{:#?}", interaction.request);
                    }
                }
            }
            Err(msg)
        }
    }
}

///
/// A mock server running synchronously, in a background thread.
/// Convenient when used with synchronous code.
///
pub struct BackgroundMockServer {
    inner: InnerServer,
    runtime: tokio::runtime::Runtime
}

impl BackgroundMockServer {
    /// Create a new mock server which handles requests as described in the
    /// pact, and runs in a background thread
    pub fn new(pact: Pact) -> BackgroundMockServer {
        let mut runtime = tokio::runtime::Builder::new()
            .threaded_scheduler()
            .num_threads(1)
            .enable_all()
            .build()
            .unwrap();

        let (mock_server, future) = runtime.block_on(InnerServer::init_mock_server(pact))
            .expect("error initializing mock server");

        BackgroundMockServer {
            inner: InnerServer::new(mock_server, runtime.spawn(future)),
            runtime,
        }
    }

    fn drop_helper(&mut self) -> Result<(), String> {
        let server_handle = self.inner.server_handle
            .take()
            .expect("Server was already shut down");
        self.inner.mock_server.shutdown().ok();

        self.runtime.block_on(server_handle).unwrap();

        self.inner.drop_helper()
    }
}

impl ValidatingMockServer for BackgroundMockServer {
    fn url(&self) -> &Url {
        &self.inner.url
    }

    fn path<P: AsRef<str>>(&self, path: P) -> Url {
        // We panic here because this a _test_ library, the `?` operator is
        // useless in tests, and filling up our test code with piles of `unwrap`
        // calls is ugly.
        self.inner.url.join(path.as_ref()).expect("could not parse URL")
    }

    fn status(&self) -> Vec<MatchResult> {
        self.inner.mock_server.mismatches()
    }
}

impl Drop for BackgroundMockServer {
    fn drop(&mut self) {
        let result = self.drop_helper();
        if let Err(msg) = result {
            panic_or_print_error(&msg);
        }
    }
}

///
/// A mock server implementation that is spawned onto the implicit current
/// tokio runtime that drives the current unit test via tokio::test.
/// After use, the server must be explitcly and asynchronously disposed by a call to
/// shutdown(). If not, the test runtime might end up deadlocked.
///
#[must_use = "Remember to call shutdown().await"]
pub struct SpawnedMockServer {
    inner: InnerServer
}

impl SpawnedMockServer {
    /// Asynchronously create and spawn a new mock server
    pub async fn new(pact: Pact) -> SpawnedMockServer {
        let (mock_server, future) = InnerServer::init_mock_server(pact)
            .await
            .expect("error initializing mock server");

        SpawnedMockServer {
            inner: InnerServer::new(mock_server, tokio::spawn(future))
        }
    }

    /// Asynchronously shut down the server.
    /// This is necessary before the test runtime gets destroyed.
    /// The reason is that the mock server is spawned as a background task.
    /// When the tokio test runtime tries to shut down, it will wait for
    /// all its running tasks to complete. Only by first awaiting the server's
    /// JoinHandle can the shutdown procedure be properly executed.
    pub async fn shutdown(mut self) {
        // Send the server shutdown signal
        self.inner.mock_server.shutdown().unwrap();

        let server_handle = self.inner.server_handle
            .take()
            .expect("Server was already shut down");

        // Await the running server's task's join handle
        server_handle.await.unwrap();
    }

    fn drop_helper(&mut self) -> Result<(), String> {
        if self.inner.server_handle.is_some() {
            panic!("Running in spawned mode, the server should be shut down using shutdown().await");
        }
        self.inner.drop_helper()
    }
}

impl ValidatingMockServer for SpawnedMockServer {
    fn url(&self) -> &Url {
        &self.inner.url
    }

    fn path<P: AsRef<str>>(&self, path: P) -> Url {
        // We panic here because this a _test_ library, the `?` operator is
        // useless in tests, and filling up our test code with piles of `unwrap`
        // calls is ugly.
        self.inner.url.join(path.as_ref()).expect("could not parse URL")
    }

    fn status(&self) -> Vec<MatchResult> {
        self.inner.mock_server.mismatches()
    }
}

impl Drop for SpawnedMockServer {
    fn drop(&mut self) {
        let result = self.drop_helper();
        if let Err(msg) = result {
            panic_or_print_error(&msg);
        }
    }
}

/// Either panic with `msg`, or if we're already in the middle of a panic,
/// just print `msg` to standard error.
fn panic_or_print_error(msg: &str) {
    if thread::panicking() {
        // The current thread is panicking, so don't try to panic again, because
        // double panics don't print useful explanations of why the test failed.
        // Instead, just print to `stderr`. Ignore any errors, because there's
        // not much we can do if we can't panic and we can't write to `stderr`.
        let _ = writeln!(io::stderr(), "{}", msg);
    } else {
        panic!("{}", msg);
    }
}
<commit_msg>Add more doc<commit_after>//! Support for mock HTTP servers that verify pacts.

use pact_matching::models::*;
use pact_mock_server::*;
use pact_mock_server::matching::MatchResult;
use std::{
  fmt::Write as FmtWrite,
  env,
  io::{self, prelude::*},
  thread
};
use url::Url;
use futures::future::*;

/// This trait is implemented by types which allow us to start a mock server.
pub trait StartMockServer {
    /// Start a mock server running in a background thread.
    fn start_mock_server(&self) -> BackgroundMockServer;

    /// Asynchronously spawn a mock server onto the current tokio runtime.
    /// Note that the returned server should be shut down after use by calling server.shutdown().await.
    fn spawn_mock_server(&self) -> BoxFuture<'static, SpawnedMockServer>;
}

impl StartMockServer for Pact {
    fn start_mock_server(&self) -> BackgroundMockServer {
        BackgroundMockServer::new(self.clone())
    }

    fn spawn_mock_server(&self) -> BoxFuture<'static, SpawnedMockServer> {
        SpawnedMockServer::new(self.clone()).boxed()
    }
}

///
/// A trait for accessing the properties of a mock server.
///
pub trait ValidatingMockServer {
    /// The URL of our mock server. You can make normal HTTP requests using this
    /// as the base URL.
    fn url(&self) -> &Url;

    /// Given a path string, return a URL pointing to that path on the mock
    /// server. If the `path` cannot be parsed as URL, **this function will
    /// panic**. For a non-panicking version, call `.url()` instead and build
    /// this path yourself.
    fn path<P: AsRef<str>>(&self, path: P) -> Url;

    /// Returns the current status of the mock server
    fn status(&self) -> Vec<MatchResult>;
}

/// Inner struct for shared data and behaviour of mock servers
struct InnerServer {
    // A description of our mock server, for use in error messages.
    description: String,
    // The URL of our mock server.
    url: Url,
    // The mock server instance
    mock_server: mock_server::MockServer,
    // The running server's asynchronous join handle
    server_handle: Option<tokio::task::JoinHandle<()>>,
}

impl InnerServer {
    fn new(
        mock_server: mock_server::MockServer,
        server_handle: tokio::task::JoinHandle<()>
    ) -> InnerServer {
        let description = format!("{}/{}", mock_server.pact.consumer.name, mock_server.pact.provider.name);
        let url_str = mock_server.url();
        InnerServer {
            description,
            url: url_str.parse().expect("invalid mock server URL"),
            mock_server,
            server_handle: Some(server_handle)
        }
    }

    /// Initialize the inner mock server instance
    async fn init_mock_server(
        pact: Pact
    ) -> Result<(mock_server::MockServer, impl std::future::Future<Output = ()>), String> {
        mock_server::MockServer::new(
            "".into(),
            pact,
            ([0, 0, 0, 0], 0 as u16).into()
        ).await
    }

    /// Helper function called by our `drop` implementation. This basically exists
    /// so that it can return `Err(message)` whenever needed without making the
    /// flow control in `drop` ultra-complex.
    fn drop_helper(&mut self) -> Result<(), String> {
        // Look up any mismatches which occurred.
        let mismatches = self.mock_server.mismatches();

        if mismatches.is_empty() {
            // Success! Write out the generated pact file.
            self.mock_server.write_pact(&Some(env::var("PACT_OUTPUT_DIR").unwrap_or("target/pacts".to_owned())))
                .map_err(|err| format!("error writing pact: {}", err))?;
            Ok(())
        } else {
            // Failure. Format our errors.
            let mut msg = format!(
                "mock server {} failed verification:\n",
                self.description,
            );
            for mismatch in mismatches {
                match mismatch {
                    MatchResult::RequestMatch(_) => {
                        unreachable!("list of mismatches contains a match");
                    }
                    MatchResult::RequestMismatch(interaction, mismatches) => {
                        let _ = writeln!(
                            &mut msg,
                            "- interaction {:?}:",
                            interaction.description,
                        );
                        for m in mismatches {
                            let _ = writeln!(&mut msg, "  - {}", m.description());
                        }
                    }
                    MatchResult::RequestNotFound(request) => {
                        let _ = writeln!(&mut msg, "- received unexpected request:");
                        let _ = writeln!(&mut msg, "{:#?}", request);
                    }
                    MatchResult::MissingRequest(interaction) => {
                        let _ = writeln!(
                            &mut msg,
                            "- interaction {:?} expected, but never occurred",
                            interaction.description,
                        );
                        let _ = writeln!(&mut msg, "{:#?}", interaction.request);
                    }
                }
            }
            Err(msg)
        }
    }
}

///
/// A mock server running synchronously, in a background thread.
/// Convenient when used with synchronous code.
///
pub struct BackgroundMockServer {
    inner: InnerServer,
    runtime: tokio::runtime::Runtime
}

impl BackgroundMockServer {
    /// Create a new mock server which handles requests as described in the
    /// pact, and runs in a background thread
    pub fn new(pact: Pact) -> BackgroundMockServer {
        let mut runtime = tokio::runtime::Builder::new()
            .threaded_scheduler()
            .num_threads(1)
            .enable_all()
            .build()
            .unwrap();

        let (mock_server, future) = runtime.block_on(InnerServer::init_mock_server(pact))
            .expect("error initializing mock server");

        BackgroundMockServer {
            inner: InnerServer::new(mock_server, runtime.spawn(future)),
            runtime,
        }
    }

    fn drop_helper(&mut self) -> Result<(), String> {
        let server_handle = self.inner.server_handle
            .take()
            .expect("Server was already shut down");
        self.inner.mock_server.shutdown().ok();

        self.runtime.block_on(server_handle).unwrap();

        self.inner.drop_helper()
    }
}

impl ValidatingMockServer for BackgroundMockServer {
    fn url(&self) -> &Url {
        &self.inner.url
    }

    fn path<P: AsRef<str>>(&self, path: P) -> Url {
        // We panic here because this a _test_ library, the `?` operator is
        // useless in tests, and filling up our test code with piles of `unwrap`
        // calls is ugly.
        self.inner.url.join(path.as_ref()).expect("could not parse URL")
    }

    fn status(&self) -> Vec<MatchResult> {
        self.inner.mock_server.mismatches()
    }
}

impl Drop for BackgroundMockServer {
    fn drop(&mut self) {
        let result = self.drop_helper();
        if let Err(msg) = result {
            panic_or_print_error(&msg);
        }
    }
}

///
/// A mock server implementation that is spawned onto the implicit current
/// tokio runtime that drives the current unit test via tokio::test.
/// After use, the server must be explitcly and asynchronously disposed by a call to
/// shutdown(). If not, the test runtime might end up deadlocked.
///
#[must_use = "Remember to call shutdown().await"]
pub struct SpawnedMockServer {
    inner: InnerServer
}

impl SpawnedMockServer {
    /// Asynchronously create and spawn a new mock server
    pub async fn new(pact: Pact) -> SpawnedMockServer {
        let (mock_server, future) = InnerServer::init_mock_server(pact)
            .await
            .expect("error initializing mock server");

        SpawnedMockServer {
            inner: InnerServer::new(mock_server, tokio::spawn(future))
        }
    }

    /// Asynchronously shut down the server.
    /// This is necessary before the test runtime gets destroyed.
    /// The reason is that the mock server is spawned as a background task.
    /// When the tokio test runtime tries to shut down, it will wait for
    /// all its running tasks to complete. Only by first awaiting the server's
    /// JoinHandle can the shutdown procedure be properly executed.
    pub async fn shutdown(mut self) {
        // Send the server shutdown signal
        self.inner.mock_server.shutdown().unwrap();

        let server_handle = self.inner.server_handle
            .take()
            .expect("Server was already shut down");

        // Await the running server's task's join handle
        server_handle.await.unwrap();
    }

    fn drop_helper(&mut self) -> Result<(), String> {
        if self.inner.server_handle.is_some() {
            panic!("Running in spawned mode, the server should be shut down using shutdown().await");
        }
        self.inner.drop_helper()
    }
}

impl ValidatingMockServer for SpawnedMockServer {
    fn url(&self) -> &Url {
        &self.inner.url
    }

    fn path<P: AsRef<str>>(&self, path: P) -> Url {
        // We panic here because this a _test_ library, the `?` operator is
        // useless in tests, and filling up our test code with piles of `unwrap`
        // calls is ugly.
        self.inner.url.join(path.as_ref()).expect("could not parse URL")
    }

    fn status(&self) -> Vec<MatchResult> {
        self.inner.mock_server.mismatches()
    }
}

impl Drop for SpawnedMockServer {
    fn drop(&mut self) {
        let result = self.drop_helper();
        if let Err(msg) = result {
            panic_or_print_error(&msg);
        }
    }
}

/// Either panic with `msg`, or if we're already in the middle of a panic,
/// just print `msg` to standard error.
fn panic_or_print_error(msg: &str) {
    if thread::panicking() {
        // The current thread is panicking, so don't try to panic again, because
        // double panics don't print useful explanations of why the test failed.
        // Instead, just print to `stderr`. Ignore any errors, because there's
        // not much we can do if we can't panic and we can't write to `stderr`.
        let _ = writeln!(io::stderr(), "{}", msg);
    } else {
        panic!("{}", msg);
    }
}
<|endoftext|>


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

//! Generic pass for performing an operation on all descriptions

use core::prelude::*;

use astsrv;
use doc::ItemUtils;
use doc;
use fold::Fold;
use fold;
use pass::Pass;
use util::NominalOp;

use std::par;
use std::cell::Cell;

pub fn mk_pass(name: ~str, op: fn~(&str) -> ~str) -> Pass {
    let op = Cell(op);
    Pass {
        name: copy name,
        f: fn~(move op, srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
            run(srv, doc, op.take())
        }
    }
}

type Op = fn~(&str) -> ~str;

#[allow(non_implicitly_copyable_typarams)]
fn run(
    _srv: astsrv::Srv,
    doc: doc::Doc,
    op: Op
) -> doc::Doc {
    let op = NominalOp {
        op: move op
    };
    let fold = Fold {
        fold_item: fold_item,
        fold_enum: fold_enum,
        fold_trait: fold_trait,
        fold_impl: fold_impl,
        .. fold::default_any_fold(move op)
    };
    (fold.fold_doc)(&fold, doc)
}

fn maybe_apply_op(op: NominalOp<Op>, s: &Option<~str>) -> Option<~str> {
    s.map(|s| (op.op)(*s) )
}

fn fold_item(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::ItemDoc
) -> doc::ItemDoc {
    let doc = fold::default_seq_fold_item(fold, doc);

    doc::ItemDoc {
        brief: maybe_apply_op(copy fold.ctxt, &doc.brief),
        desc: maybe_apply_op(copy fold.ctxt, &doc.desc),
        sections: apply_to_sections(copy fold.ctxt, copy doc.sections),
        .. doc
    }
}

fn apply_to_sections(
    +op: NominalOp<Op>,
    sections: ~[doc::Section]
) -> ~[doc::Section] {
    par::map(sections, |section, copy op| doc::Section {
        header: (op.op)(copy section.header),
        body: (op.op)(copy section.body)
    })
}

fn fold_enum(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::EnumDoc) -> doc::EnumDoc {
    let doc = fold::default_seq_fold_enum(fold, doc);
    let fold_copy = copy *fold;

    doc::EnumDoc {
        variants: do par::map(doc.variants) |variant, copy fold_copy| {
            doc::VariantDoc {
                desc: maybe_apply_op(copy fold_copy.ctxt, &variant.desc),
                .. copy *variant
            }
        },
        .. doc
    }
}

fn fold_trait(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::TraitDoc
) -> doc::TraitDoc {
    let doc = fold::default_seq_fold_trait(fold, doc);

    doc::TraitDoc {
        methods: apply_to_methods(copy fold.ctxt, copy doc.methods),
        .. doc
    }
}

fn apply_to_methods(
    op: NominalOp<Op>,
    docs: ~[doc::MethodDoc]
) -> ~[doc::MethodDoc] {
    let op = copy op;
    do par::map(docs) |doc| {
        doc::MethodDoc {
            brief: maybe_apply_op(copy op, &doc.brief),
            desc: maybe_apply_op(copy op, &doc.desc),
            sections: apply_to_sections(copy op, copy doc.sections),
            .. copy *doc
        }
    }
}

fn fold_impl(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::ImplDoc
) -> doc::ImplDoc {
    let doc = fold::default_seq_fold_impl(fold, doc);

    doc::ImplDoc {
        methods: apply_to_methods(copy fold.ctxt, copy doc.methods),
        .. doc
    }
}

#[test]
fn should_execute_op_on_enum_brief() {
    let doc = test::mk_doc(~"#[doc = \" a \"] enum a { b }");
    assert doc.cratemod().enums()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_enum_desc() {
    let doc = test::mk_doc(~"#[doc = \" a \"] enum a { b }");
    assert doc.cratemod().enums()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_variant_desc() {
    let doc = test::mk_doc(~"enum a { #[doc = \" a \"] b }");
    assert doc.cratemod().enums()[0].variants[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] trait i { fn a(); }");
    assert doc.cratemod().traits()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] trait i { fn a(); }");
    assert doc.cratemod().traits()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_method_brief() {
    let doc = test::mk_doc(
        ~"trait i { #[doc = \" a \"] fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].brief == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_method_desc() {
    let doc = test::mk_doc(
        ~"trait i { #[doc = \" a \"] fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] impl int { fn a() { } }");
    assert doc.cratemod().impls()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] impl int { fn a() { } }");
    assert doc.cratemod().impls()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_method_brief() {
    let doc = test::mk_doc(
        ~"impl int { #[doc = \" a \"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].brief == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_method_desc() {
    let doc = test::mk_doc(
        ~"impl int { #[doc = \" a \"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_type_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] type t = int;");
    assert doc.cratemod().types()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_type_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] type t = int;");
    assert doc.cratemod().types()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_on_item_section_headers() {
    let doc = test::mk_doc(
        ~"#[doc = \"\
         #    Header    \n\
         Body\"]\
         fn a() { }");
    assert doc.cratemod().fns()[0].sections()[0].header == ~"Header";
}

#[test]
fn should_execute_on_item_section_bodies() {
    let doc = test::mk_doc(
        ~"#[doc = \"\
         # Header\n\
         Body      \"]\
         fn a() { }");
    assert doc.cratemod().fns()[0].sections()[0].body == ~"Body";
}

#[test]
fn should_execute_on_trait_method_section_headers() {
    let doc = test::mk_doc(
        ~"trait i {
         #[doc = \"\
         # Header    \n\
         Body\"]\
         fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].sections[0].header
        == ~"Header";
}

#[test]
fn should_execute_on_trait_method_section_bodies() {
    let doc = test::mk_doc(
        ~"trait i {
         #[doc = \"\
         # Header\n\
         Body     \"]\
         fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].sections[0].body == ~"Body";
}

#[test]
fn should_execute_on_impl_method_section_headers() {
    let doc = test::mk_doc(
        ~"impl bool {
         #[doc = \"\
         # Header   \n\
         Body\"]\
         fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].sections[0].header
        == ~"Header";
}

#[test]
fn should_execute_on_impl_method_section_bodies() {
    let doc = test::mk_doc(
        ~"impl bool {
         #[doc = \"\
         # Header\n\
         Body    \"]\
         fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].sections[0].body == ~"Body";
}

#[cfg(test)]
mod test {
    use astsrv;
    use attr_pass;
    use desc_to_brief_pass;
    use doc;
    use extract;
    use sectionalize_pass;
    use text_pass::mk_pass;

    use core::str;

    pub fn mk_doc(source: ~str) -> doc::Doc {
        do astsrv::from_str(copy source) |srv| {
            let doc = extract::from_srv(srv.clone(), ~"");
            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc);
            (mk_pass(~"", |s| str::trim(s) ).f)(srv.clone(), doc)
        }
    }
}
<commit_msg>rustdoc: Remove stray mode<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Generic pass for performing an operation on all descriptions

use core::prelude::*;

use astsrv;
use doc::ItemUtils;
use doc;
use fold::Fold;
use fold;
use pass::Pass;
use util::NominalOp;

use std::par;
use std::cell::Cell;

pub fn mk_pass(name: ~str, op: fn~(&str) -> ~str) -> Pass {
    let op = Cell(op);
    Pass {
        name: copy name,
        f: fn~(move op, srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
            run(srv, doc, op.take())
        }
    }
}

type Op = fn~(&str) -> ~str;

#[allow(non_implicitly_copyable_typarams)]
fn run(
    _srv: astsrv::Srv,
    doc: doc::Doc,
    op: Op
) -> doc::Doc {
    let op = NominalOp {
        op: move op
    };
    let fold = Fold {
        fold_item: fold_item,
        fold_enum: fold_enum,
        fold_trait: fold_trait,
        fold_impl: fold_impl,
        .. fold::default_any_fold(move op)
    };
    (fold.fold_doc)(&fold, doc)
}

fn maybe_apply_op(op: NominalOp<Op>, s: &Option<~str>) -> Option<~str> {
    s.map(|s| (op.op)(*s) )
}

fn fold_item(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::ItemDoc
) -> doc::ItemDoc {
    let doc = fold::default_seq_fold_item(fold, doc);

    doc::ItemDoc {
        brief: maybe_apply_op(copy fold.ctxt, &doc.brief),
        desc: maybe_apply_op(copy fold.ctxt, &doc.desc),
        sections: apply_to_sections(copy fold.ctxt, copy doc.sections),
        .. doc
    }
}

fn apply_to_sections(
    op: NominalOp<Op>,
    sections: ~[doc::Section]
) -> ~[doc::Section] {
    par::map(sections, |section, copy op| doc::Section {
        header: (op.op)(copy section.header),
        body: (op.op)(copy section.body)
    })
}

fn fold_enum(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::EnumDoc) -> doc::EnumDoc {
    let doc = fold::default_seq_fold_enum(fold, doc);
    let fold_copy = copy *fold;

    doc::EnumDoc {
        variants: do par::map(doc.variants) |variant, copy fold_copy| {
            doc::VariantDoc {
                desc: maybe_apply_op(copy fold_copy.ctxt, &variant.desc),
                .. copy *variant
            }
        },
        .. doc
    }
}

fn fold_trait(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::TraitDoc
) -> doc::TraitDoc {
    let doc = fold::default_seq_fold_trait(fold, doc);

    doc::TraitDoc {
        methods: apply_to_methods(copy fold.ctxt, copy doc.methods),
        .. doc
    }
}

fn apply_to_methods(
    op: NominalOp<Op>,
    docs: ~[doc::MethodDoc]
) -> ~[doc::MethodDoc] {
    let op = copy op;
    do par::map(docs) |doc| {
        doc::MethodDoc {
            brief: maybe_apply_op(copy op, &doc.brief),
            desc: maybe_apply_op(copy op, &doc.desc),
            sections: apply_to_sections(copy op, copy doc.sections),
            .. copy *doc
        }
    }
}

fn fold_impl(
    fold: &fold::Fold<NominalOp<Op>>,
    doc: doc::ImplDoc
) -> doc::ImplDoc {
    let doc = fold::default_seq_fold_impl(fold, doc);

    doc::ImplDoc {
        methods: apply_to_methods(copy fold.ctxt, copy doc.methods),
        .. doc
    }
}

#[test]
fn should_execute_op_on_enum_brief() {
    let doc = test::mk_doc(~"#[doc = \" a \"] enum a { b }");
    assert doc.cratemod().enums()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_enum_desc() {
    let doc = test::mk_doc(~"#[doc = \" a \"] enum a { b }");
    assert doc.cratemod().enums()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_variant_desc() {
    let doc = test::mk_doc(~"enum a { #[doc = \" a \"] b }");
    assert doc.cratemod().enums()[0].variants[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] trait i { fn a(); }");
    assert doc.cratemod().traits()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] trait i { fn a(); }");
    assert doc.cratemod().traits()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_method_brief() {
    let doc = test::mk_doc(
        ~"trait i { #[doc = \" a \"] fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].brief == Some(~"a");
}

#[test]
fn should_execute_op_on_trait_method_desc() {
    let doc = test::mk_doc(
        ~"trait i { #[doc = \" a \"] fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] impl int { fn a() { } }");
    assert doc.cratemod().impls()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] impl int { fn a() { } }");
    assert doc.cratemod().impls()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_method_brief() {
    let doc = test::mk_doc(
        ~"impl int { #[doc = \" a \"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].brief == Some(~"a");
}

#[test]
fn should_execute_op_on_impl_method_desc() {
    let doc = test::mk_doc(
        ~"impl int { #[doc = \" a \"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].desc == Some(~"a");
}

#[test]
fn should_execute_op_on_type_brief() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] type t = int;");
    assert doc.cratemod().types()[0].brief() == Some(~"a");
}

#[test]
fn should_execute_op_on_type_desc() {
    let doc = test::mk_doc(
        ~"#[doc = \" a \"] type t = int;");
    assert doc.cratemod().types()[0].desc() == Some(~"a");
}

#[test]
fn should_execute_on_item_section_headers() {
    let doc = test::mk_doc(
        ~"#[doc = \"\
         #    Header    \n\
         Body\"]\
         fn a() { }");
    assert doc.cratemod().fns()[0].sections()[0].header == ~"Header";
}

#[test]
fn should_execute_on_item_section_bodies() {
    let doc = test::mk_doc(
        ~"#[doc = \"\
         # Header\n\
         Body      \"]\
         fn a() { }");
    assert doc.cratemod().fns()[0].sections()[0].body == ~"Body";
}

#[test]
fn should_execute_on_trait_method_section_headers() {
    let doc = test::mk_doc(
        ~"trait i {
         #[doc = \"\
         # Header    \n\
         Body\"]\
         fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].sections[0].header
        == ~"Header";
}

#[test]
fn should_execute_on_trait_method_section_bodies() {
    let doc = test::mk_doc(
        ~"trait i {
         #[doc = \"\
         # Header\n\
         Body     \"]\
         fn a(); }");
    assert doc.cratemod().traits()[0].methods[0].sections[0].body == ~"Body";
}

#[test]
fn should_execute_on_impl_method_section_headers() {
    let doc = test::mk_doc(
        ~"impl bool {
         #[doc = \"\
         # Header   \n\
         Body\"]\
         fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].sections[0].header
        == ~"Header";
}

#[test]
fn should_execute_on_impl_method_section_bodies() {
    let doc = test::mk_doc(
        ~"impl bool {
         #[doc = \"\
         # Header\n\
         Body    \"]\
         fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].sections[0].body == ~"Body";
}

#[cfg(test)]
mod test {
    use astsrv;
    use attr_pass;
    use desc_to_brief_pass;
    use doc;
    use extract;
    use sectionalize_pass;
    use text_pass::mk_pass;

    use core::str;

    pub fn mk_doc(source: ~str) -> doc::Doc {
        do astsrv::from_str(copy source) |srv| {
            let doc = extract::from_srv(srv.clone(), ~"");
            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc);
            (mk_pass(~"", |s| str::trim(s) ).f)(srv.clone(), doc)
        }
    }
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// 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.

//! Generic char output trait.

use core::str::{Str, StrPrelude};
use core::slice::SlicePrelude;
use core::iter::range;

use core::mem::zeroed;

use util::strconv;

/// CharIO provides interface for outputting characters.
///
/// This trait implements the common functions to output strings and numbers,
/// requiring only one method: `putc`.
pub trait CharIO {
  /// Outputs a character.
  fn putc(&self, value: char);

  /// Outputs a string.
  fn puts(&self, s: &str) {
    let chars : &[u8] = s.as_slice().as_bytes();
    for i in range(0, s.len()) {
      let c : char = chars[i] as char;
      self.putc(c);
    }
  }

  /// Outputs an integer with given base.
  fn putint(&self, i: u32, base: u32) {
    let mut buf : [u8, ..32] = unsafe { zeroed() };
    let bsl : &mut [u8] = buf;
    strconv::itoa(i, bsl, base);

    for &i in bsl.iter() {
      if i == 0 {
        break;
      }
      self.putc(i as char);
    }
  }

  /// Outputs an integer.
  fn puti(&self, i: u32) {
    self.putint(i, 10);
  }

  /// Outputs an integer as a hex string.
  fn puth(&self, i: u32) {
    self.putint(i, 16);
  }
}

#[cfg(test)]
pub mod test {
  use core::cell::RefCell;

  use drivers::chario::CharIO;

  pub struct TestCharIOData {
    last_char: char,
    putc_calls: uint,
  }

  pub struct TestCharIO {
    data: RefCell<TestCharIOData>
  }

  impl CharIO for TestCharIO {
    fn putc(&self, value: char) {
      let mut data = self.data.borrow_mut();
      data.putc_calls += 1;
      data.last_char = value;
    }
  }

  impl TestCharIO {
    pub fn new() -> TestCharIO {
      TestCharIO {
        data: RefCell::new(TestCharIOData {
          last_char: '\0',
          putc_calls: 0,
        }),
      }
    }

    fn get_last_char(&self) -> char {
      self.data.borrow().last_char
    }

    fn get_and_reset_putc_calls(&self) -> uint {
      let current = self.data.borrow().putc_calls;
      self.data.borrow_mut().putc_calls = 0;
      current
    }
  }

  #[test]
  fn putc_should_store_a_char() {
    let io = TestCharIO::new();
    io.putc('a');
    assert!(io.get_last_char() == 'a');
    io.putc('z');
    assert!(io.get_last_char() == 'z');
  }

  #[test]
  fn puti_should_store_a_number_as_char() {
    let io = TestCharIO::new();
    io.puti(3);
    assert!(io.get_last_char() == '3');
    io.puti(9);
    assert!(io.get_last_char() == '9');
    io.puti(10);
    assert!(io.get_last_char() == '0');
    io.puti(11);
    assert!(io.get_last_char() == '1');
  }

  #[test]
  fn puth_should_store_a_number_as_char() {
    let io = TestCharIO::new();
    io.puth(3);
    assert!(io.get_last_char() == '3');
    io.puth(9);
    assert!(io.get_last_char() == '9');
    io.puth(10);
    assert!(io.get_last_char() == 'a');
    io.puth(11);
    assert!(io.get_last_char() == 'b');
    io.puth(16);
    assert!(io.get_last_char() == '0');
    io.puth(17);
    assert!(io.get_last_char() == '1');
  }

  #[test]
  fn putint_should_work_with_different_bases() {
    let io = TestCharIO::new();
    io.putint(0, 2);
    assert!(io.get_last_char() == '0');
    io.putint(1, 2);
    assert!(io.get_last_char() == '1');
    io.putint(2, 2);
    assert!(io.get_last_char() == '0');
    io.putint(3, 2);
    assert!(io.get_last_char() == '1');
    io.putint(7, 7);
    assert!(io.get_last_char() == '0');
    io.putint(8, 7);
    assert!(io.get_last_char() == '1');
    io.putint(12, 7);
    assert!(io.get_last_char() == '5');
    io.putint(14, 7);
    assert!(io.get_last_char() == '0');
  }

  #[test]
  fn puts_should_leave_us_with_just_the_last_char() {
    let io = TestCharIO::new();
    io.puts("fu!");
    assert!(io.get_last_char() == '!');
    assert!(io.get_and_reset_putc_calls() == 3);
    io.puts("\n\t");
    assert!(io.get_last_char() == '\t');
    assert!(io.get_and_reset_putc_calls() == 2);
  }
}
<commit_msg>chario: Fix type mismatch<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// 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.

//! Generic char output trait.

use core::str::{Str, StrPrelude};
use core::slice::SlicePrelude;
use core::iter::range;

use core::mem::zeroed;

use util::strconv;

/// CharIO provides interface for outputting characters.
///
/// This trait implements the common functions to output strings and numbers,
/// requiring only one method: `putc`.
pub trait CharIO {
  /// Outputs a character.
  fn putc(&self, value: char);

  /// Outputs a string.
  fn puts(&self, s: &str) {
    let chars : &[u8] = s.as_slice().as_bytes();
    for i in range(0, s.len()) {
      let c : char = chars[i] as char;
      self.putc(c);
    }
  }

  /// Outputs an integer with given base.
  fn putint(&self, i: u32, base: u32) {
    let mut buf : [u8, ..32] = unsafe { zeroed() };
    let bsl : &mut [u8] = &mut buf;
    strconv::itoa(i, bsl, base);

    for &i in bsl.iter() {
      if i == 0 {
        break;
      }
      self.putc(i as char);
    }
  }

  /// Outputs an integer.
  fn puti(&self, i: u32) {
    self.putint(i, 10);
  }

  /// Outputs an integer as a hex string.
  fn puth(&self, i: u32) {
    self.putint(i, 16);
  }
}

#[cfg(test)]
pub mod test {
  use core::cell::RefCell;

  use drivers::chario::CharIO;

  pub struct TestCharIOData {
    last_char: char,
    putc_calls: uint,
  }

  pub struct TestCharIO {
    data: RefCell<TestCharIOData>
  }

  impl CharIO for TestCharIO {
    fn putc(&self, value: char) {
      let mut data = self.data.borrow_mut();
      data.putc_calls += 1;
      data.last_char = value;
    }
  }

  impl TestCharIO {
    pub fn new() -> TestCharIO {
      TestCharIO {
        data: RefCell::new(TestCharIOData {
          last_char: '\0',
          putc_calls: 0,
        }),
      }
    }

    fn get_last_char(&self) -> char {
      self.data.borrow().last_char
    }

    fn get_and_reset_putc_calls(&self) -> uint {
      let current = self.data.borrow().putc_calls;
      self.data.borrow_mut().putc_calls = 0;
      current
    }
  }

  #[test]
  fn putc_should_store_a_char() {
    let io = TestCharIO::new();
    io.putc('a');
    assert!(io.get_last_char() == 'a');
    io.putc('z');
    assert!(io.get_last_char() == 'z');
  }

  #[test]
  fn puti_should_store_a_number_as_char() {
    let io = TestCharIO::new();
    io.puti(3);
    assert!(io.get_last_char() == '3');
    io.puti(9);
    assert!(io.get_last_char() == '9');
    io.puti(10);
    assert!(io.get_last_char() == '0');
    io.puti(11);
    assert!(io.get_last_char() == '1');
  }

  #[test]
  fn puth_should_store_a_number_as_char() {
    let io = TestCharIO::new();
    io.puth(3);
    assert!(io.get_last_char() == '3');
    io.puth(9);
    assert!(io.get_last_char() == '9');
    io.puth(10);
    assert!(io.get_last_char() == 'a');
    io.puth(11);
    assert!(io.get_last_char() == 'b');
    io.puth(16);
    assert!(io.get_last_char() == '0');
    io.puth(17);
    assert!(io.get_last_char() == '1');
  }

  #[test]
  fn putint_should_work_with_different_bases() {
    let io = TestCharIO::new();
    io.putint(0, 2);
    assert!(io.get_last_char() == '0');
    io.putint(1, 2);
    assert!(io.get_last_char() == '1');
    io.putint(2, 2);
    assert!(io.get_last_char() == '0');
    io.putint(3, 2);
    assert!(io.get_last_char() == '1');
    io.putint(7, 7);
    assert!(io.get_last_char() == '0');
    io.putint(8, 7);
    assert!(io.get_last_char() == '1');
    io.putint(12, 7);
    assert!(io.get_last_char() == '5');
    io.putint(14, 7);
    assert!(io.get_last_char() == '0');
  }

  #[test]
  fn puts_should_leave_us_with_just_the_last_char() {
    let io = TestCharIO::new();
    io.puts("fu!");
    assert!(io.get_last_char() == '!');
    assert!(io.get_and_reset_putc_calls() == 3);
    io.puts("\n\t");
    assert!(io.get_last_char() == '\t');
    assert!(io.get_and_reset_putc_calls() == 2);
  }
}
<|endoftext|>


<commit_before>#![cfg(feature = "encoding")]

#![feature(test)]
extern crate test;

#[macro_use]
extern crate lambda_calculus as lambda;

use test::Bencher;
use lambda::data::numerals::church::*;
use lambda::*;

#[bench]
fn church_succ(b: &mut Bencher) {
    b.iter(|| { beta(app!(succ(), 1.into_church()), HAP, 0) } );
}

#[bench]
fn church_pred(b: &mut Bencher) {
    b.iter(|| { beta(app!(pred(), 1.into_church()), HAP, 0) } );
}

#[bench]
fn church_sub(b: &mut Bencher) {
    b.iter(|| { beta(app!(sub(), 2.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_add(b: &mut Bencher) {
    b.iter(|| { beta(app!(add(), 2.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_mult(b: &mut Bencher) {
    b.iter(|| { beta(app!(mult(), 2.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_pow(b: &mut Bencher) {
    b.iter(|| { beta(app!(pow(), 2.into_church(), 2.into_church()), NOR, 0) } );
}

#[bench]
fn church_div(b: &mut Bencher) {
    b.iter(|| { beta(app!(div(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_quot(b: &mut Bencher) {
    b.iter(|| { beta(app!(quot(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_rem(b: &mut Bencher) {
    b.iter(|| { beta(app!(rem(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_eq(b: &mut Bencher) {
    b.iter(|| { beta(app!(eq(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_neq(b: &mut Bencher) {
    b.iter(|| { beta(app!(neq(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_gt(b: &mut Bencher) {
    b.iter(|| { beta(app!(gt(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_lt(b: &mut Bencher) {
    b.iter(|| { beta(app!(lt(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_geq(b: &mut Bencher) {
    b.iter(|| { beta(app!(geq(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_leq(b: &mut Bencher) {
    b.iter(|| { beta(app!(leq(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_min(b: &mut Bencher) {
    b.iter(|| { beta(app!(min(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_max(b: &mut Bencher) {
    b.iter(|| { beta(app!(max(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_lshift(b: &mut Bencher) {
    b.iter(|| { beta(app!(lshift(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_rshift(b: &mut Bencher) {
    b.iter(|| { beta(app!(rshift(), 3.into_church(), 2.into_church()), HAP, 0) } );
}

#[bench]
fn church_fac(b: &mut Bencher) {
    b.iter(|| { beta(app!(fac(), 3.into_church()), HAP, 0) } );
}
<commit_msg>add a benchmarking macro<commit_after>#![cfg(feature = "encoding")]

#![feature(test)]
extern crate test;

#[macro_use]
extern crate lambda_calculus as lambda;

use test::Bencher;
use lambda::data::numerals::church::*;
use lambda::*;

macro_rules! bench_num {
    ($name:ident, $conversion:ident, $function:ident, $order:expr, $($n:expr),+) => (
        #[bench]
        fn $name(b: &mut Bencher) {
            b.iter(|| { beta(app!($function(), $($n.$conversion()),*), $order, 0) } );
        }
    );
}

bench_num!(church_succ, into_church, succ, HAP, 1);
bench_num!(church_pred, into_church, pred, HAP, 1);
bench_num!(church_add,  into_church, add,  HAP, 2, 2);
bench_num!(church_sub,  into_church, sub,  HAP, 2, 2);
bench_num!(church_mult, into_church, mult, HAP, 2, 2);
bench_num!(church_pow,  into_church, pow,  HAP, 2, 2);
bench_num!(church_div,  into_church, div,  HAP, 2, 2);
bench_num!(church_quot, into_church, quot, HAP, 2, 2);
bench_num!(church_rem,  into_church, rem,  HAP, 2, 2);
bench_num!(church_eq,   into_church, eq,   HAP, 2, 2);
bench_num!(church_neq,  into_church, neq,  HAP, 2, 2);
bench_num!(church_gt,   into_church, gt,   HAP, 2, 2);
bench_num!(church_lt,   into_church, lt,   HAP, 2, 2);
bench_num!(church_geq,  into_church, geq,  HAP, 2, 2);
bench_num!(church_leq,  into_church, leq,  HAP, 2, 2);
bench_num!(church_min,  into_church, min,  HAP, 2, 2);
bench_num!(church_max,  into_church, max,  HAP, 2, 2);
bench_num!(church_lshift, into_church, lshift,  HAP, 2, 2);
bench_num!(church_rshift, into_church, rshift,  HAP, 2, 2);
bench_num!(church_fac,   into_church, fac, HAP, 3);
<|endoftext|>


<commit_before>use syntax::{
    ast::{self, AstNode},
    SyntaxElement, TextRange, TextSize, T,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     <|>dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let new_contents = adjusted_macro_contents(&macro_call)?;

    let macro_text_range = macro_call.syntax().text_range();
    let macro_end = if macro_call.semicolon_token().is_some() {
        macro_text_range.end() - TextSize::of(';')
    } else {
        macro_text_range.end()
    };

    acc.add(
        AssistId("remove_dbg", AssistKind::Refactor),
        "Remove dbg!()",
        macro_text_range,
        |builder| {
            builder.replace(TextRange::new(macro_text_range.start(), macro_end), new_contents);
        },
    )
}

fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> {
    let contents = get_valid_macrocall_contents(&macro_call, "dbg")?;
    let is_leaf = macro_call.syntax().next_sibling().is_none();
    let macro_text_with_brackets = macro_call.token_tree()?.syntax().text();
    let slice_index = if is_leaf || !needs_parentheses_around_macro_contents(contents) {
        TextRange::new(TextSize::of('('), macro_text_with_brackets.len() - TextSize::of(')'))
    } else {
        // leave parenthesis around macro contents to preserve the semantics
        TextRange::up_to(macro_text_with_brackets.len())
    };
    Some(macro_text_with_brackets.slice(slice_index).to_string())
}

/// Verifies that the given macro_call actually matches the given name
/// and contains proper ending tokens, then returns the contents between the ending tokens
fn get_valid_macrocall_contents(
    macro_call: &ast::MacroCall,
    macro_name: &str,
) -> Option<Vec<SyntaxElement>> {
    let path = macro_call.path()?;
    let name_ref = path.segment()?.name_ref()?;

    // Make sure it is actually a dbg-macro call, dbg followed by !
    let excl = path.syntax().next_sibling_or_token()?;
    if name_ref.text() != macro_name || excl.kind() != T![!] {
        return None;
    }

    let mut children_with_tokens = macro_call.token_tree()?.syntax().children_with_tokens();
    let first_child = children_with_tokens.next()?;
    let mut contents_between_brackets = children_with_tokens.collect::<Vec<_>>();
    let last_child = contents_between_brackets.pop()?;

    if contents_between_brackets.is_empty() {
        None
    } else {
        match (first_child.kind(), last_child.kind()) {
            (T!['('], T![')']) | (T!['['], T![']']) | (T!['{'], T!['}']) => {
                Some(contents_between_brackets)
            }
            _ => None,
        }
    }
}

fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) -> bool {
    if macro_contents.len() < 2 {
        return false;
    }

    let mut macro_contents_kind_not_in_brackets = Vec::with_capacity(macro_contents.len());

    let mut first_bracket_in_macro = None;
    let mut unpaired_brackets_in_contents = Vec::new();
    for element in macro_contents {
        match element.kind() {
            T!['('] | T!['['] | T!['{'] => {
                if let None = first_bracket_in_macro {
                    first_bracket_in_macro = Some(element.clone())
                }
                unpaired_brackets_in_contents.push(element);
            }
            T![')'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['('])
                {
                    return true;
                }
            }
            T![']'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['['])
                {
                    return true;
                }
            }
            T!['}'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['{'])
                {
                    return true;
                }
            }
            other_kind => {
                if unpaired_brackets_in_contents.is_empty() {
                    macro_contents_kind_not_in_brackets.push(other_kind);
                }
            }
        }
    }

    !unpaired_brackets_in_contents.is_empty()
        || matches!(first_bracket_in_macro, Some(bracket) if bracket.kind() != T!['('])
        || macro_contents_kind_not_in_brackets
            .into_iter()
            .any(|macro_contents_kind| macro_contents_kind.is_punct())
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};

    use super::*;

    #[test]
    fn test_remove_dbg() {
        check_assist(remove_dbg, "<|>dbg!(1 + 1)", "1 + 1");

        check_assist(remove_dbg, "dbg!<|>((1 + 1))", "(1 + 1)");

        check_assist(remove_dbg, "dbg!(1 <|>+ 1)", "1 + 1");

        check_assist(remove_dbg, "let _ = <|>dbg!(1 + 1)", "let _ = 1 + 1");

        check_assist(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "
fn foo(n: usize) {
    if let Some(_) = n.checked_sub(4) {
        // ...
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_with_brackets_and_braces() {
        check_assist(remove_dbg, "dbg![<|>1 + 1]", "1 + 1");
        check_assist(remove_dbg, "dbg!{<|>1 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "<|>vec![1, 2, 3]");
        check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)");
        check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7");
    }

    #[test]
    fn test_remove_dbg_target() {
        check_assist_target(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "dbg!(n.checked_sub(4))",
        );
    }

    #[test]
    fn test_remove_dbg_keep_semicolon() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        // not quite though
        // adding a comment at the end of the line makes
        // the ast::MacroCall to include the semicolon at the end
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
    }

    #[test]
    fn remove_dbg_from_non_leaf_simple_expression() {
        check_assist(
            remove_dbg,
            "
fn main() {
    let mut a = 1;
    while dbg!<|>(a) < 10000 {
        a += 1;
    }
}
",
            "
fn main() {
    let mut a = 1;
    while a < 10000 {
        a += 1;
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_keep_expression() {
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(a + b).foo();"#,
            r#"let res = (a + b).foo();"#,
        );
    }

    #[test]
    fn test_remove_dbg_from_inside_fn() {
        check_assist_target(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            "dbg!(5 + 10)",
        );

        check_assist(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(5 + 10);
    println!("{}", x);
}"#,
        );
    }
}
<commit_msg>One more test<commit_after>use syntax::{
    ast::{self, AstNode},
    SyntaxElement, TextRange, TextSize, T,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     <|>dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let new_contents = adjusted_macro_contents(&macro_call)?;

    let macro_text_range = macro_call.syntax().text_range();
    let macro_end = if macro_call.semicolon_token().is_some() {
        macro_text_range.end() - TextSize::of(';')
    } else {
        macro_text_range.end()
    };

    acc.add(
        AssistId("remove_dbg", AssistKind::Refactor),
        "Remove dbg!()",
        macro_text_range,
        |builder| {
            builder.replace(TextRange::new(macro_text_range.start(), macro_end), new_contents);
        },
    )
}

fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> {
    let contents = get_valid_macrocall_contents(&macro_call, "dbg")?;
    let is_leaf = macro_call.syntax().next_sibling().is_none();
    let macro_text_with_brackets = macro_call.token_tree()?.syntax().text();
    let slice_index = if is_leaf || !needs_parentheses_around_macro_contents(contents) {
        TextRange::new(TextSize::of('('), macro_text_with_brackets.len() - TextSize::of(')'))
    } else {
        // leave parenthesis around macro contents to preserve the semantics
        TextRange::up_to(macro_text_with_brackets.len())
    };
    Some(macro_text_with_brackets.slice(slice_index).to_string())
}

/// Verifies that the given macro_call actually matches the given name
/// and contains proper ending tokens, then returns the contents between the ending tokens
fn get_valid_macrocall_contents(
    macro_call: &ast::MacroCall,
    macro_name: &str,
) -> Option<Vec<SyntaxElement>> {
    let path = macro_call.path()?;
    let name_ref = path.segment()?.name_ref()?;

    // Make sure it is actually a dbg-macro call, dbg followed by !
    let excl = path.syntax().next_sibling_or_token()?;
    if name_ref.text() != macro_name || excl.kind() != T![!] {
        return None;
    }

    let mut children_with_tokens = macro_call.token_tree()?.syntax().children_with_tokens();
    let first_child = children_with_tokens.next()?;
    let mut contents_between_brackets = children_with_tokens.collect::<Vec<_>>();
    let last_child = contents_between_brackets.pop()?;

    if contents_between_brackets.is_empty() {
        None
    } else {
        match (first_child.kind(), last_child.kind()) {
            (T!['('], T![')']) | (T!['['], T![']']) | (T!['{'], T!['}']) => {
                Some(contents_between_brackets)
            }
            _ => None,
        }
    }
}

fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) -> bool {
    if macro_contents.len() < 2 {
        return false;
    }

    let mut macro_contents_kind_not_in_brackets = Vec::with_capacity(macro_contents.len());

    let mut first_bracket_in_macro = None;
    let mut unpaired_brackets_in_contents = Vec::new();
    for element in macro_contents {
        match element.kind() {
            T!['('] | T!['['] | T!['{'] => {
                if let None = first_bracket_in_macro {
                    first_bracket_in_macro = Some(element.clone())
                }
                unpaired_brackets_in_contents.push(element);
            }
            T![')'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['('])
                {
                    return true;
                }
            }
            T![']'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['['])
                {
                    return true;
                }
            }
            T!['}'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['{'])
                {
                    return true;
                }
            }
            other_kind => {
                if unpaired_brackets_in_contents.is_empty() {
                    macro_contents_kind_not_in_brackets.push(other_kind);
                }
            }
        }
    }

    !unpaired_brackets_in_contents.is_empty()
        || matches!(first_bracket_in_macro, Some(bracket) if bracket.kind() != T!['('])
        || macro_contents_kind_not_in_brackets
            .into_iter()
            .any(|macro_contents_kind| macro_contents_kind.is_punct())
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};

    use super::*;

    #[test]
    fn test_remove_dbg() {
        check_assist(remove_dbg, "<|>dbg!(1 + 1)", "1 + 1");

        check_assist(remove_dbg, "dbg!<|>((1 + 1))", "(1 + 1)");

        check_assist(remove_dbg, "dbg!(1 <|>+ 1)", "1 + 1");

        check_assist(remove_dbg, "let _ = <|>dbg!(1 + 1)", "let _ = 1 + 1");

        check_assist(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "
fn foo(n: usize) {
    if let Some(_) = n.checked_sub(4) {
        // ...
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_with_brackets_and_braces() {
        check_assist(remove_dbg, "dbg![<|>1 + 1]", "1 + 1");
        check_assist(remove_dbg, "dbg!{<|>1 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "<|>vec![1, 2, 3]");
        check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)");
        check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7");
    }

    #[test]
    fn test_remove_dbg_target() {
        check_assist_target(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "dbg!(n.checked_sub(4))",
        );
    }

    #[test]
    fn test_remove_dbg_keep_semicolon() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        // not quite though
        // adding a comment at the end of the line makes
        // the ast::MacroCall to include the semicolon at the end
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
    }

    #[test]
    fn remove_dbg_from_non_leaf_simple_expression() {
        check_assist(
            remove_dbg,
            "
fn main() {
    let mut a = 1;
    while dbg!<|>(a) < 10000 {
        a += 1;
    }
}
",
            "
fn main() {
    let mut a = 1;
    while a < 10000 {
        a += 1;
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_keep_expression() {
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(a + b).foo();"#,
            r#"let res = (a + b).foo();"#,
        );

        check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#);
    }

    #[test]
    fn test_remove_dbg_from_inside_fn() {
        check_assist_target(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            "dbg!(5 + 10)",
        );

        check_assist(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(5 + 10);
    println!("{}", x);
}"#,
        );
    }
}
<|endoftext|>