<commit_before>use mio::net::UdpSocket;
use mio::{Events, Interests, Poll, Token};
use std::io;

const IN: Token = Token(0);

fn main() -> io::Result<()> {
    // Set up a new socket on port 9000 to listen on.
    let socket = UdpSocket::bind("0.0.0.0:9000".parse().unwrap())?;
    // Initialize poller.
    let mut poll = Poll::new()?;
    // Register our socket with the token IN (defined above) and an interest
    // in being `READABLE`.
    poll.registry()
        .register(&socket, IN, Interests::READABLE)?;

    // Prepare a buffer for the number of events we can handle at a time.
    // Someone might wat to echo really fast so lets give it some size.
    let mut events = Events::with_capacity(1024);
    // Initialize a buffer for the UDP datagram
    let mut buf = [0; 65535];
    // Main loop
    loop {
        // Poll if we have events waiting for us on the socket.
        poll.poll(&mut events, None)?;
        // If we do iterate throuigh them
        for event in events.iter() {
            // Validate the token we registered our socket with,
            // in this example it will only ever be one but we
            // make sure it's valid non the less.
            match event.token() {
                IN => loop {
                    // In this loop we receive from the socket as long as we
                    // can read data
                    match socket.recv_from(&mut buf) {
                        Ok((n, from_addr)) => {
                            // Send the data right back from where it came from.
                            socket.send_to(&buf[..n], from_addr)?;
                        }
                        Err(e) => {
                            // If we failed to receive data we have two cases
                            if e.kind() == io::ErrorKind::WouldBlock {
                                // If the reason was `WouldBlock` we know
                                // our socket has no more data to give so
                                // we can return to the poll to wait politely.
                                break;
                            } else {
                                // If it was any other kind of error, something
                                // went wrong and we panic.
                                panic!("error: {:?}", e)
                            }
                        }
                    }
                },
                // We only have IN as a token, so this should never ever be hit
                _ => unreachable!(),
            }
        }
    }
}
<commit_msg>Return instead of panicing<commit_after>use mio::net::UdpSocket;
use mio::{Events, Interests, Poll, Token};
use std::io;

const IN: Token = Token(0);

fn main() -> io::Result<()> {
    // Set up a new socket on port 9000 to listen on.
    let socket = UdpSocket::bind("0.0.0.0:9000".parse().unwrap())?;
    // Initialize poller.
    let mut poll = Poll::new()?;
    // Register our socket with the token IN (defined above) and an interest
    // in being `READABLE`.
    poll.registry()
        .register(&socket, IN, Interests::READABLE)?;

    // Prepare a buffer for the number of events we can handle at a time.
    // Someone might wat to echo really fast so lets give it some size.
    let mut events = Events::with_capacity(1024);
    // Initialize a buffer for the UDP datagram
    let mut buf = [0; 65535];
    // Main loop
    loop {
        // Poll if we have events waiting for us on the socket.
        poll.poll(&mut events, None)?;
        // If we do iterate throuigh them
        for event in events.iter() {
            // Validate the token we registered our socket with,
            // in this example it will only ever be one but we
            // make sure it's valid non the less.
            match event.token() {
                IN => loop {
                    // In this loop we receive from the socket as long as we
                    // can read data
                    match socket.recv_from(&mut buf) {
                        Ok((n, from_addr)) => {
                            // Send the data right back from where it came from.
                            socket.send_to(&buf[..n], from_addr)?;
                        }
                        Err(e) => {
                            // If we failed to receive data we have two cases
                            if e.kind() == io::ErrorKind::WouldBlock {
                                // If the reason was `WouldBlock` we know
                                // our socket has no more data to give so
                                // we can return to the poll to wait politely.
                                break;
                            } else {
                                // If it was any other kind of error, something
                                // went wrong and we terminate with an error.
                                return Err(e);
                            }
                        }
                    }
                },
                // We only have IN as a token, so this should never ever be hit
                _ => unreachable!(),
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};

use termion::event::Key;
use termion::input::TermRead;

pub enum Event<I> {
    Input(I),
    Tick,
}

/// A small event handler that wrap termion input and tick events. Each event
/// type is handled in its own thread and returned to a common `Receiver`
pub struct Events {
    rx: mpsc::Receiver<Event<Key>>,
    input_handle: thread::JoinHandle<()>,
    ignore_exit_key: Arc<AtomicBool>,
    tick_handle: thread::JoinHandle<()>,
}

#[derive(Debug, Clone, Copy)]
pub struct Config {
    pub exit_key: Key,
    pub tick_rate: Duration,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            exit_key: Key::Char('q'),
            tick_rate: Duration::from_millis(250),
        }
    }
}

impl Events {
    pub fn new() -> Events {
        Events::with_config(Config::default())
    }

    pub fn with_config(config: Config) -> Events {
        let (tx, rx) = mpsc::channel();
        let ignore_exit_key = Arc::new(AtomicBool::new(false));
        let input_handle = {
            let tx = tx.clone();
            let ignore_exit_key = ignore_exit_key.clone();
            thread::spawn(move || {
                let stdin = io::stdin();
                for evt in stdin.keys() {
                    match evt {
                        Ok(key) => {
                            if let Err(_) = tx.send(Event::Input(key)) {
                                return;
                            }
                            if !ignore_exit_key.load(Ordering::Relaxed) && key == config.exit_key {
                                return;
                            }
                        }
                        Err(_) => {}
                    }
                }
            })
        };
        let tick_handle = {
            let tx = tx.clone();
            thread::spawn(move || {
                let tx = tx.clone();
                loop {
                    tx.send(Event::Tick).unwrap();
                    thread::sleep(config.tick_rate);
                }
            })
        };
        Events {
            rx,
            ignore_exit_key,
            input_handle,
            tick_handle,
        }
    }

    pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> {
        self.rx.recv()
    }

    pub fn disable_exit_key(&mut self) {
        self.ignore_exit_key.store(true, Ordering::Relaxed);
    }

    pub fn enable_exit_key(&mut self) {
        self.ignore_exit_key.store(false, Ordering::Relaxed);
    }
}
<commit_msg>style: run rustfmt<commit_after>use std::io;
use std::sync::mpsc;
use std::sync::{
    atomic::{AtomicBool, Ordering},
    Arc,
};
use std::thread;
use std::time::Duration;

use termion::event::Key;
use termion::input::TermRead;

pub enum Event<I> {
    Input(I),
    Tick,
}

/// A small event handler that wrap termion input and tick events. Each event
/// type is handled in its own thread and returned to a common `Receiver`
pub struct Events {
    rx: mpsc::Receiver<Event<Key>>,
    input_handle: thread::JoinHandle<()>,
    ignore_exit_key: Arc<AtomicBool>,
    tick_handle: thread::JoinHandle<()>,
}

#[derive(Debug, Clone, Copy)]
pub struct Config {
    pub exit_key: Key,
    pub tick_rate: Duration,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            exit_key: Key::Char('q'),
            tick_rate: Duration::from_millis(250),
        }
    }
}

impl Events {
    pub fn new() -> Events {
        Events::with_config(Config::default())
    }

    pub fn with_config(config: Config) -> Events {
        let (tx, rx) = mpsc::channel();
        let ignore_exit_key = Arc::new(AtomicBool::new(false));
        let input_handle = {
            let tx = tx.clone();
            let ignore_exit_key = ignore_exit_key.clone();
            thread::spawn(move || {
                let stdin = io::stdin();
                for evt in stdin.keys() {
                    match evt {
                        Ok(key) => {
                            if let Err(_) = tx.send(Event::Input(key)) {
                                return;
                            }
                            if !ignore_exit_key.load(Ordering::Relaxed) && key == config.exit_key {
                                return;
                            }
                        }
                        Err(_) => {}
                    }
                }
            })
        };
        let tick_handle = {
            let tx = tx.clone();
            thread::spawn(move || {
                let tx = tx.clone();
                loop {
                    tx.send(Event::Tick).unwrap();
                    thread::sleep(config.tick_rate);
                }
            })
        };
        Events {
            rx,
            ignore_exit_key,
            input_handle,
            tick_handle,
        }
    }

    pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> {
        self.rx.recv()
    }

    pub fn disable_exit_key(&mut self) {
        self.ignore_exit_key.store(true, Ordering::Relaxed);
    }

    pub fn enable_exit_key(&mut self) {
        self.ignore_exit_key.store(false, Ordering::Relaxed);
    }
}
<|endoftext|>


<commit_before>use num::{Num, FromPrimitive};
use std::{f32, f64};
use std::ops::{Neg, AddAssign, MulAssign, SubAssign, DivAssign};

use approx::ApproxEq;

use general::{Field, SubsetOf, SupersetOf};

#[allow(missing_docs)]

/// Trait shared by all reals.
///
/// Reals are equipped with functions that are commonly used on reals. The results of those
/// functions only have to be approximately equal to the actual theoretical values.
// FIXME: SubsetOf should be removed when specialization will be supported by rustc. This will
// allow a blancket impl: impl<T: Clone> SubsetOf<T> for T { ... }
pub trait Real: SubsetOf<Self> + SupersetOf<f64> + Field + Copy + Num + FromPrimitive +
                Neg<Output = Self> + AddAssign + MulAssign + SubAssign + DivAssign +
                ApproxEq + PartialOrd {
    fn floor(self) -> Self;
    fn ceil(self) -> Self;
    fn round(self) -> Self;
    fn trunc(self) -> Self;
    fn fract(self) -> Self;
    fn abs(self) -> Self;
    fn signum(self) -> Self;
    fn is_sign_positive(self) -> bool;
    fn is_sign_negative(self) -> bool;
    fn mul_add(self, a: Self, b: Self) -> Self;
    fn recip(self) -> Self;
    fn powi(self, n: i32) -> Self;
    fn powf(self, n: Self) -> Self;
    fn sqrt(self) -> Self;
    fn exp(self) -> Self;
    fn exp2(self) -> Self;
    fn ln(self) -> Self;
    fn log(self, base: Self) -> Self;
    fn log2(self) -> Self;
    fn log10(self) -> Self;
    fn max(self, other: Self) -> Self;
    fn min(self, other: Self) -> Self;
    fn cbrt(self) -> Self;
    fn hypot(self, other: Self) -> Self;
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn tan(self) -> Self;
    fn asin(self) -> Self;
    fn acos(self) -> Self;
    fn atan(self) -> Self;
    fn atan2(self, other: Self) -> Self;
    fn sin_cos(self) -> (Self, Self);
    fn exp_m1(self) -> Self;
    fn ln_1p(self) -> Self;
    fn sinh(self) -> Self;
    fn cosh(self) -> Self;
    fn tanh(self) -> Self;
    fn asinh(self) -> Self;
    fn acosh(self) -> Self;
    fn atanh(self) -> Self;

    fn pi() -> Self;
    fn two_pi() -> Self;
    fn frac_pi_2() -> Self;
    fn frac_pi_3() -> Self;
    fn frac_pi_4() -> Self;
    fn frac_pi_6() -> Self;
    fn frac_pi_8() -> Self;
    fn frac_1_pi() -> Self;
    fn frac_2_pi() -> Self;
    fn frac_2_sqrt_pi() -> Self;

    fn e() -> Self;
    fn log2_e() -> Self;
    fn log10_e() -> Self;
    fn ln_2() -> Self;
    fn ln_10() -> Self;
}

macro_rules! impl_real(
    ($($T:ty, $M:ident);*) => ($(
        impl Real for $T {
            #[inline]
            fn floor(self) -> Self {
                self.floor()
            }

            #[inline]
            fn ceil(self) -> Self {
                self.ceil()
            }

            #[inline]
            fn round(self) -> Self {
                self.round()
            }

            #[inline]
            fn trunc(self) -> Self {
                self.trunc()
            }

            #[inline]
            fn fract(self) -> Self {
                self.fract()
            }

            #[inline]
            fn abs(self) -> Self {
                self.abs()
            }

            #[inline]
            fn signum(self) -> Self {
                self.signum()
            }

            #[inline]
            fn is_sign_positive(self) -> bool {
                self.is_sign_positive()
            }

            #[inline]
            fn is_sign_negative(self) -> bool {
                self.is_sign_negative()
            }

            #[inline]
            fn mul_add(self, a: Self, b: Self) -> Self {
                self.mul_add(a, b)
            }

            #[inline]
            fn recip(self) -> Self {
                self.recip()
            }

            #[inline]
            fn powi(self, n: i32) -> Self {
                self.powi(n)
            }

            #[inline]
            fn powf(self, n: Self) -> Self {
                self.powf(n)
            }

            #[inline]
            fn sqrt(self) -> Self {
                self.sqrt()
            }

            #[inline]
            fn exp(self) -> Self {
                self.exp()
            }

            #[inline]
            fn exp2(self) -> Self {
                self.exp2()
            }

            #[inline]
            fn ln(self) -> Self {
                self.ln()
            }

            #[inline]
            fn log(self, base: Self) -> Self {
                self.log(base)
            }

            #[inline]
            fn log2(self) -> Self {
                self.log2()
            }

            #[inline]
            fn log10(self) -> Self {
                self.log10()
            }

            #[inline]
            fn max(self, other: Self) -> Self {
                self.max(other)
            }

            #[inline]
            fn min(self, other: Self) -> Self {
                self.min(other)
            }

            #[inline]
            fn cbrt(self) -> Self {
                self.cbrt()
            }

            #[inline]
            fn hypot(self, other: Self) -> Self {
                self.hypot(other)
            }

            #[inline]
            fn sin(self) -> Self {
                self.sin()
            }

            #[inline]
            fn cos(self) -> Self {
                self.cos()
            }

            #[inline]
            fn tan(self) -> Self {
                self.tan()
            }

            #[inline]
            fn asin(self) -> Self {
                self.asin()
            }

            #[inline]
            fn acos(self) -> Self {
                self.acos()
            }

            #[inline]
            fn atan(self) -> Self {
                self.atan()
            }

            #[inline]
            fn atan2(self, other: Self) -> Self {
                self.atan2(other)
            }

            #[inline]
            fn sin_cos(self) -> (Self, Self) {
                self.sin_cos()
            }

            #[inline]
            fn exp_m1(self) -> Self {
                self.exp_m1()
            }

            #[inline]
            fn ln_1p(self) -> Self {
                self.ln_1p()
            }

            #[inline]
            fn sinh(self) -> Self {
                self.sinh()
            }

            #[inline]
            fn cosh(self) -> Self {
                self.cosh()
            }

            #[inline]
            fn tanh(self) -> Self {
                self.tanh()
            }

            #[inline]
            fn asinh(self) -> Self {
                self.asinh()
            }

            #[inline]
            fn acosh(self) -> Self {
                self.acosh()
            }

            #[inline]
            fn atanh(self) -> Self {
                self.atanh()
            }

            /// Archimedes' constant.
            #[inline]
            fn pi() -> Self {
                $M::consts::PI
            }

            /// 2.0 * pi.
            #[inline]
            fn two_pi() -> Self {
                $M::consts::PI + $M::consts::PI
            }

            /// pi / 2.0.
            #[inline]
            fn frac_pi_2() -> Self {
                $M::consts::FRAC_PI_2
            }

            /// pi / 3.0.
            #[inline]
            fn frac_pi_3() -> Self {
                $M::consts::FRAC_PI_3
            }

            /// pi / 4.0.
            #[inline]
            fn frac_pi_4() -> Self {
                $M::consts::FRAC_PI_4
            }

            /// pi / 6.0.
            #[inline]
            fn frac_pi_6() -> Self {
                $M::consts::FRAC_PI_6
            }

            /// pi / 8.0.
            #[inline]
            fn frac_pi_8() -> Self {
                $M::consts::FRAC_PI_8
            }

            /// 1.0 / pi.
            #[inline]
            fn frac_1_pi() -> Self {
                $M::consts::FRAC_1_PI
            }

            /// 2.0 / pi.
            #[inline]
            fn frac_2_pi() -> Self {
                $M::consts::FRAC_2_PI
            }

            /// 2.0 / sqrt(pi).
            #[inline]
            fn frac_2_sqrt_pi() -> Self {
                $M::consts::FRAC_2_SQRT_PI
            }

            /// Euler's number.
            #[inline]
            fn e() -> Self {
                $M::consts::E
            }

            /// log2(e).
            #[inline]
            fn log2_e() -> Self {
                $M::consts::LOG2_E
            }

            /// log10(e).
            #[inline]
            fn log10_e() -> Self {
                $M::consts::LOG10_E
            }

            /// ln(2.0).
            #[inline]
            fn ln_2() -> Self {
                $M::consts::LN_2
            }

            /// ln(10.0).
            #[inline]
            fn ln_10() -> Self {
                $M::consts::LN_10
            }
        }
    )*)
);

impl_real!(f32,f32; f64,f64);
<commit_msg>Require that ApproxEq::Epsilon == Self for Reals.<commit_after>use num::{Num, FromPrimitive};
use std::{f32, f64};
use std::ops::{Neg, AddAssign, MulAssign, SubAssign, DivAssign};

use approx::ApproxEq;

use general::{Field, SubsetOf, SupersetOf};

#[allow(missing_docs)]

/// Trait shared by all reals.
///
/// Reals are equipped with functions that are commonly used on reals. The results of those
/// functions only have to be approximately equal to the actual theoretical values.
// FIXME: SubsetOf should be removed when specialization will be supported by rustc. This will
// allow a blancket impl: impl<T: Clone> SubsetOf<T> for T { ... }
pub trait Real: SubsetOf<Self> + SupersetOf<f64> + Field + Copy + Num + FromPrimitive +
                Neg<Output = Self> + AddAssign + MulAssign + SubAssign + DivAssign +
                ApproxEq<Epsilon = Self> + PartialOrd {
    fn floor(self) -> Self;
    fn ceil(self) -> Self;
    fn round(self) -> Self;
    fn trunc(self) -> Self;
    fn fract(self) -> Self;
    fn abs(self) -> Self;
    fn signum(self) -> Self;
    fn is_sign_positive(self) -> bool;
    fn is_sign_negative(self) -> bool;
    fn mul_add(self, a: Self, b: Self) -> Self;
    fn recip(self) -> Self;
    fn powi(self, n: i32) -> Self;
    fn powf(self, n: Self) -> Self;
    fn sqrt(self) -> Self;
    fn exp(self) -> Self;
    fn exp2(self) -> Self;
    fn ln(self) -> Self;
    fn log(self, base: Self) -> Self;
    fn log2(self) -> Self;
    fn log10(self) -> Self;
    fn max(self, other: Self) -> Self;
    fn min(self, other: Self) -> Self;
    fn cbrt(self) -> Self;
    fn hypot(self, other: Self) -> Self;
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn tan(self) -> Self;
    fn asin(self) -> Self;
    fn acos(self) -> Self;
    fn atan(self) -> Self;
    fn atan2(self, other: Self) -> Self;
    fn sin_cos(self) -> (Self, Self);
    fn exp_m1(self) -> Self;
    fn ln_1p(self) -> Self;
    fn sinh(self) -> Self;
    fn cosh(self) -> Self;
    fn tanh(self) -> Self;
    fn asinh(self) -> Self;
    fn acosh(self) -> Self;
    fn atanh(self) -> Self;

    fn pi() -> Self;
    fn two_pi() -> Self;
    fn frac_pi_2() -> Self;
    fn frac_pi_3() -> Self;
    fn frac_pi_4() -> Self;
    fn frac_pi_6() -> Self;
    fn frac_pi_8() -> Self;
    fn frac_1_pi() -> Self;
    fn frac_2_pi() -> Self;
    fn frac_2_sqrt_pi() -> Self;

    fn e() -> Self;
    fn log2_e() -> Self;
    fn log10_e() -> Self;
    fn ln_2() -> Self;
    fn ln_10() -> Self;
}

macro_rules! impl_real(
    ($($T:ty, $M:ident);*) => ($(
        impl Real for $T {
            #[inline]
            fn floor(self) -> Self {
                self.floor()
            }

            #[inline]
            fn ceil(self) -> Self {
                self.ceil()
            }

            #[inline]
            fn round(self) -> Self {
                self.round()
            }

            #[inline]
            fn trunc(self) -> Self {
                self.trunc()
            }

            #[inline]
            fn fract(self) -> Self {
                self.fract()
            }

            #[inline]
            fn abs(self) -> Self {
                self.abs()
            }

            #[inline]
            fn signum(self) -> Self {
                self.signum()
            }

            #[inline]
            fn is_sign_positive(self) -> bool {
                self.is_sign_positive()
            }

            #[inline]
            fn is_sign_negative(self) -> bool {
                self.is_sign_negative()
            }

            #[inline]
            fn mul_add(self, a: Self, b: Self) -> Self {
                self.mul_add(a, b)
            }

            #[inline]
            fn recip(self) -> Self {
                self.recip()
            }

            #[inline]
            fn powi(self, n: i32) -> Self {
                self.powi(n)
            }

            #[inline]
            fn powf(self, n: Self) -> Self {
                self.powf(n)
            }

            #[inline]
            fn sqrt(self) -> Self {
                self.sqrt()
            }

            #[inline]
            fn exp(self) -> Self {
                self.exp()
            }

            #[inline]
            fn exp2(self) -> Self {
                self.exp2()
            }

            #[inline]
            fn ln(self) -> Self {
                self.ln()
            }

            #[inline]
            fn log(self, base: Self) -> Self {
                self.log(base)
            }

            #[inline]
            fn log2(self) -> Self {
                self.log2()
            }

            #[inline]
            fn log10(self) -> Self {
                self.log10()
            }

            #[inline]
            fn max(self, other: Self) -> Self {
                self.max(other)
            }

            #[inline]
            fn min(self, other: Self) -> Self {
                self.min(other)
            }

            #[inline]
            fn cbrt(self) -> Self {
                self.cbrt()
            }

            #[inline]
            fn hypot(self, other: Self) -> Self {
                self.hypot(other)
            }

            #[inline]
            fn sin(self) -> Self {
                self.sin()
            }

            #[inline]
            fn cos(self) -> Self {
                self.cos()
            }

            #[inline]
            fn tan(self) -> Self {
                self.tan()
            }

            #[inline]
            fn asin(self) -> Self {
                self.asin()
            }

            #[inline]
            fn acos(self) -> Self {
                self.acos()
            }

            #[inline]
            fn atan(self) -> Self {
                self.atan()
            }

            #[inline]
            fn atan2(self, other: Self) -> Self {
                self.atan2(other)
            }

            #[inline]
            fn sin_cos(self) -> (Self, Self) {
                self.sin_cos()
            }

            #[inline]
            fn exp_m1(self) -> Self {
                self.exp_m1()
            }

            #[inline]
            fn ln_1p(self) -> Self {
                self.ln_1p()
            }

            #[inline]
            fn sinh(self) -> Self {
                self.sinh()
            }

            #[inline]
            fn cosh(self) -> Self {
                self.cosh()
            }

            #[inline]
            fn tanh(self) -> Self {
                self.tanh()
            }

            #[inline]
            fn asinh(self) -> Self {
                self.asinh()
            }

            #[inline]
            fn acosh(self) -> Self {
                self.acosh()
            }

            #[inline]
            fn atanh(self) -> Self {
                self.atanh()
            }

            /// Archimedes' constant.
            #[inline]
            fn pi() -> Self {
                $M::consts::PI
            }

            /// 2.0 * pi.
            #[inline]
            fn two_pi() -> Self {
                $M::consts::PI + $M::consts::PI
            }

            /// pi / 2.0.
            #[inline]
            fn frac_pi_2() -> Self {
                $M::consts::FRAC_PI_2
            }

            /// pi / 3.0.
            #[inline]
            fn frac_pi_3() -> Self {
                $M::consts::FRAC_PI_3
            }

            /// pi / 4.0.
            #[inline]
            fn frac_pi_4() -> Self {
                $M::consts::FRAC_PI_4
            }

            /// pi / 6.0.
            #[inline]
            fn frac_pi_6() -> Self {
                $M::consts::FRAC_PI_6
            }

            /// pi / 8.0.
            #[inline]
            fn frac_pi_8() -> Self {
                $M::consts::FRAC_PI_8
            }

            /// 1.0 / pi.
            #[inline]
            fn frac_1_pi() -> Self {
                $M::consts::FRAC_1_PI
            }

            /// 2.0 / pi.
            #[inline]
            fn frac_2_pi() -> Self {
                $M::consts::FRAC_2_PI
            }

            /// 2.0 / sqrt(pi).
            #[inline]
            fn frac_2_sqrt_pi() -> Self {
                $M::consts::FRAC_2_SQRT_PI
            }

            /// Euler's number.
            #[inline]
            fn e() -> Self {
                $M::consts::E
            }

            /// log2(e).
            #[inline]
            fn log2_e() -> Self {
                $M::consts::LOG2_E
            }

            /// log10(e).
            #[inline]
            fn log10_e() -> Self {
                $M::consts::LOG10_E
            }

            /// ln(2.0).
            #[inline]
            fn ln_2() -> Self {
                $M::consts::LN_2
            }

            /// ln(10.0).
            #[inline]
            fn ln_10() -> Self {
                $M::consts::LN_10
            }
        }
    )*)
);

impl_real!(f32,f32; f64,f64);
<|endoftext|>


<commit_before>pub use self::image_importer::ImageImporter;
use crate::texture::Texture;

mod image_importer;

pub type ImportResult<T> = Result<T, String>;

pub trait Importer<I> {
    type Texture: Texture;

    fn import(input: I) -> ImportResult<Self::Texture>;
}
<commit_msg>docs: Document importer module contents<commit_after>//! Defines a trait for importing arbitrary data and converting them to [Texture]s.
pub use self::image_importer::ImageImporter;
use crate::texture::Texture;

mod image_importer;

/// Result of importing data and converting it to a texture.
pub type ImportResult<T> = Result<T, String>;

/// Converter for an input type `I` to a [Texture].
pub trait Importer<I> {
    /// [Texture] type to use.
    type Texture: Texture;

    /// Import `I` yielding a texture object.
    fn import(input: I) -> ImportResult<Self::Texture>;
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{collections::HashMap, collections::HashSet};

use crate::{
    byvalue_checker::ByValueChecker,
    conversion::{api::ParseResults, ConvertError},
    type_database::TypeDatabase,
    types::make_ident,
    types::Namespace,
    types::TypeName,
    UnsafePolicy,
};
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{parse_quote, Fields, ForeignItem, Item, ItemStruct, Type};

use super::{
    super::{
        api::{Api, Use},
        utilities::generate_utilities,
    },
    bridge_name_tracker::BridgeNameTracker,
    non_pod_struct::make_non_pod,
    rust_name_tracker::RustNameTracker,
    type_converter::TypeConverter,
};

use super::parse_foreign_mod::{ForeignModParseCallbacks, ParseForeignMod};

#[derive(Copy, Clone, Eq, PartialEq)]
enum TypeKind {
    POD,                // trivial. Can be moved and copied in Rust.
    NonPOD, // has destructor or non-trivial move constructors. Can only hold by UniquePtr
    ForwardDeclaration, // no full C++ declaration available - can't even generate UniquePtr
}

/// Parses a bindgen mod in order to understand the APIs within it.
pub(crate) struct ParseBindgen<'a> {
    type_converter: TypeConverter<'a>,
    byvalue_checker: ByValueChecker,
    type_database: &'a TypeDatabase,
    bridge_name_tracker: BridgeNameTracker,
    rust_name_tracker: RustNameTracker,
    incomplete_types: HashSet<TypeName>,
    results: ParseResults,
    unsafe_policy: UnsafePolicy,
}

impl<'a> ParseBindgen<'a> {
    pub(crate) fn new(
        byvalue_checker: ByValueChecker,
        type_database: &'a TypeDatabase,
        unsafe_policy: UnsafePolicy,
    ) -> Self {
        ParseBindgen {
            type_converter: TypeConverter::new(type_database),
            byvalue_checker,
            bridge_name_tracker: BridgeNameTracker::new(),
            rust_name_tracker: RustNameTracker::new(),
            type_database,
            incomplete_types: HashSet::new(),
            results: ParseResults {
                apis: Vec::new(),
                use_stmts_by_mod: HashMap::new(),
            },
            unsafe_policy,
        }
    }

    /// Main function which goes through and performs conversion from
    /// `bindgen`-style Rust output into `cxx::bridge`-style Rust input.
    /// At present, it significantly rewrites the bindgen mod,
    /// as well as generating an additional cxx::bridge mod, and an outer
    /// mod with all sorts of 'use' statements. A valid alternative plan
    /// might be to keep the bindgen mod untouched and _only_ generate
    /// additional bindings, but the sticking point there is that it's not
    /// obviously possible to stop folks allocating opaque types in the
    /// bindgen mod. (We mark all types as opaque until we're told
    /// otherwise, which is the opposite of what bindgen does, so we can't
    /// just give it lots of directives to make all types opaque.)
    /// One future option could be to provide a mode to bindgen where
    /// everything is opaque unless specifically allowlisted to be
    /// transparent.
    pub(crate) fn convert_items(
        mut self,
        items: Vec<Item>,
        exclude_utilities: bool,
    ) -> Result<ParseResults, ConvertError> {
        if !exclude_utilities {
            generate_utilities(&mut self.results.apis);
        }
        let root_ns = Namespace::new();
        self.convert_mod_items(items, root_ns)?;
        Ok(self.results)
    }

    /// Interpret the bindgen-generated .rs for a particular
    /// mod, which corresponds to a C++ namespace.
    fn convert_mod_items(&mut self, items: Vec<Item>, ns: Namespace) -> Result<(), ConvertError> {
        // This object maintains some state specific to this namespace, i.e.
        // this particular mod.
        let mut mod_converter = ParseForeignMod::new(ns.clone());
        let mut use_statements_for_this_mod = Vec::new();
        for item in items {
            match item {
                Item::ForeignMod(mut fm) => {
                    let items = fm.items;
                    fm.items = Vec::new();
                    mod_converter.convert_foreign_mod_items(items)?;
                }
                Item::Struct(mut s) => {
                    let tyname = TypeName::new(&ns, &s.ident.to_string());
                    let type_kind = if Self::spot_forward_declaration(&s.fields) {
                        self.incomplete_types.insert(tyname.clone());
                        TypeKind::ForwardDeclaration
                    } else if self.byvalue_checker.is_pod(&tyname) {
                        TypeKind::POD
                    } else {
                        TypeKind::NonPOD
                    };
                    // We either leave a bindgen struct untouched, or we completely
                    // replace its contents with opaque nonsense.
                    let field_types = match type_kind {
                        TypeKind::POD => self.get_struct_field_types(&ns, &s)?,
                        _ => {
                            make_non_pod(&mut s);
                            HashSet::new()
                        }
                    };
                    // cxx::bridge can't cope with type aliases to generic
                    // types at the moment.
                    self.generate_type(tyname, type_kind, field_types, Some(Item::Struct(s)))?;
                }
                Item::Enum(e) => {
                    let tyname = TypeName::new(&ns, &e.ident.to_string());
                    self.generate_type(tyname, TypeKind::POD, HashSet::new(), Some(Item::Enum(e)))?;
                }
                Item::Impl(imp) => {
                    // We *mostly* ignore all impl blocks generated by bindgen.
                    // Methods also appear in 'extern "C"' blocks which
                    // we will convert instead. At that time we'll also construct
                    // synthetic impl blocks.
                    // We do however record which methods were spotted, since
                    // we have no other way of working out which functions are
                    // static methods vs plain functions.
                    mod_converter.convert_impl_items(imp);
                }
                Item::Mod(itm) => {
                    if let Some((_, items)) = itm.content {
                        let new_ns = ns.push(itm.ident.to_string());
                        self.convert_mod_items(items, new_ns)?;
                    }
                }
                Item::Use(_) => {
                    use_statements_for_this_mod.push(item);
                }
                Item::Const(itc) => {
                    // TODO the following puts this constant into
                    // the global namespace which is bug
                    // https://github.com/google/autocxx/issues/133
                    self.add_api(Api {
                        id: itc.ident.clone(),
                        ns: ns.clone(),
                        bridge_item: None,
                        extern_c_mod_item: None,
                        global_items: vec![Item::Const(itc)],
                        additional_cpp: None,
                        deps: HashSet::new(),
                        use_stmt: Use::Unused,
                        id_for_allowlist: None,
                        bindgen_mod_item: None,
                        impl_entry: None,
                    });
                }
                Item::Type(ity) => {
                    let tyname = TypeName::new(&ns, &ity.ident.to_string());
                    self.type_converter.insert_typedef(tyname, ity.ty.as_ref());
                    self.add_api(Api {
                        id: ity.ident.clone(),
                        ns: ns.clone(),
                        bridge_item: None,
                        extern_c_mod_item: None,
                        global_items: Vec::new(),
                        additional_cpp: None,
                        deps: HashSet::new(),
                        use_stmt: Use::Unused,
                        id_for_allowlist: None,
                        bindgen_mod_item: Some(Item::Type(ity)),
                        impl_entry: None,
                    });
                }
                _ => return Err(ConvertError::UnexpectedItemInMod),
            }
        }
        mod_converter.finished(self)?;

        // We don't immediately blat 'use' statements into any particular
        // Api. We'll squirrel them away and insert them into the output mod later
        // iff this mod ends up having any output items after garbage collection
        // of unnecessary APIs.
        let supers = std::iter::repeat(make_ident("super")).take(ns.depth() + 2);
        use_statements_for_this_mod.push(Item::Use(parse_quote! {
            #[allow(unused_imports)]
            use self::
                #(#supers)::*
            ::cxxbridge;
        }));
        for thing in &["UniquePtr", "CxxString"] {
            let thing = make_ident(thing);
            use_statements_for_this_mod.push(Item::Use(parse_quote! {
                #[allow(unused_imports)]
                use cxx:: #thing;
            }));
        }
        use_statements_for_this_mod.push(Item::Use(parse_quote! {
            #[allow(unused_imports)]
            use std::pin::Pin;
        }));
        self.results
            .use_stmts_by_mod
            .insert(ns, use_statements_for_this_mod);
        Ok(())
    }

    fn get_struct_field_types(
        &mut self,
        ns: &Namespace,
        s: &ItemStruct,
    ) -> Result<HashSet<TypeName>, ConvertError> {
        let mut results = HashSet::new();
        for f in &s.fields {
            let annotated = self.type_converter.convert_type(f.ty.clone(), ns)?;
            self.results.apis.extend(annotated.extra_apis);
            results.extend(annotated.types_encountered);
        }
        Ok(results)
    }

    fn spot_forward_declaration(s: &Fields) -> bool {
        s.iter()
            .filter_map(|f| f.ident.as_ref())
            .any(|id| id == "_unused")
    }

    /// Record the Api for a type, e.g. enum or struct.
    /// Code generated includes the bindgen entry itself,
    /// various entries for the cxx::bridge to ensure cxx
    /// is aware of the type, and 'use' statements for the final
    /// output mod hierarchy. All are stored in the Api which
    /// this adds.
    fn generate_type(
        &mut self,
        tyname: TypeName,
        type_nature: TypeKind,
        deps: HashSet<TypeName>,
        bindgen_mod_item: Option<Item>,
    ) -> Result<(), ConvertError> {
        let final_ident = make_ident(tyname.get_final_ident());
        let kind_item = match type_nature {
            TypeKind::POD => "Trivial",
            _ => "Opaque",
        };
        let kind_item = make_ident(kind_item);
        if self.type_database.is_on_blocklist(&tyname) {
            return Ok(());
        }
        let tynamestring = tyname.to_cpp_name();
        let mut for_extern_c_ts = if tyname.has_namespace() {
            let ns_string = tyname
                .ns_segment_iter()
                .cloned()
                .collect::<Vec<String>>()
                .join("::");
            quote! {
                #[namespace = #ns_string]
            }
        } else {
            TokenStream2::new()
        };

        let mut fulltypath: Vec<_> = ["bindgen", "root"].iter().map(|x| make_ident(x)).collect();
        for_extern_c_ts.extend(quote! {
            type #final_ident = super::bindgen::root::
        });
        for segment in tyname.ns_segment_iter() {
            let id = make_ident(segment);
            for_extern_c_ts.extend(quote! {
                #id::
            });
            fulltypath.push(id);
        }
        for_extern_c_ts.extend(quote! {
            #final_ident;
        });
        let bridge_item = match type_nature {
            TypeKind::ForwardDeclaration => None,
            _ => Some(Item::Impl(parse_quote! {
                impl UniquePtr<#final_ident> {}
            })),
        };
        fulltypath.push(final_ident.clone());
        let api = Api {
            ns: tyname.get_namespace().clone(),
            id: final_ident,
            use_stmt: Use::Used,
            global_items: vec![Item::Impl(parse_quote! {
                unsafe impl cxx::ExternType for #(#fulltypath)::* {
                    type Id = cxx::type_id!(#tynamestring);
                    type Kind = cxx::kind::#kind_item;
                }
            })],
            bridge_item,
            extern_c_mod_item: Some(ForeignItem::Verbatim(for_extern_c_ts)),
            additional_cpp: None,
            deps,
            id_for_allowlist: None,
            bindgen_mod_item,
            impl_entry: None,
        };
        self.add_api(api);
        self.type_converter.push(tyname);
        Ok(())
    }
}

impl<'a> ForeignModParseCallbacks for ParseBindgen<'a> {
    fn convert_boxed_type(
        &mut self,
        ty: Box<Type>,
        ns: &Namespace,
    ) -> Result<(Box<Type>, HashSet<TypeName>), ConvertError> {
        let annotated = self.type_converter.convert_boxed_type(ty, ns)?;
        self.results.apis.extend(annotated.extra_apis);
        Ok((annotated.ty, annotated.types_encountered))
    }

    fn is_pod(&self, ty: &TypeName) -> bool {
        self.byvalue_checker.is_pod(ty)
    }

    fn add_api(&mut self, api: Api) {
        self.results.apis.push(api);
    }

    fn get_cxx_bridge_name(
        &mut self,
        type_name: Option<&str>,
        found_name: &str,
        ns: &Namespace,
    ) -> String {
        self.bridge_name_tracker
            .get_unique_cxx_bridge_name(type_name, found_name, ns)
    }

    fn ok_to_use_rust_name(&mut self, rust_name: &str) -> bool {
        self.rust_name_tracker.ok_to_use_rust_name(rust_name)
    }

    fn is_on_allowlist(&self, type_name: &TypeName) -> bool {
        self.type_database.is_on_allowlist(type_name)
    }

    fn avoid_generating_type(&self, type_name: &TypeName) -> bool {
        self.type_database.is_on_blocklist(type_name) || self.incomplete_types.contains(type_name)
    }

    fn should_be_unsafe(&self) -> bool {
        self.unsafe_policy == UnsafePolicy::AllFunctionsUnsafe
    }
}
<commit_msg>Remove now-redundant error handling.<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{collections::HashMap, collections::HashSet};

use crate::{
    byvalue_checker::ByValueChecker,
    conversion::{api::ParseResults, ConvertError},
    type_database::TypeDatabase,
    types::make_ident,
    types::Namespace,
    types::TypeName,
    UnsafePolicy,
};
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{parse_quote, Fields, ForeignItem, Item, ItemStruct, Type};

use super::{
    super::{
        api::{Api, Use},
        utilities::generate_utilities,
    },
    bridge_name_tracker::BridgeNameTracker,
    non_pod_struct::make_non_pod,
    rust_name_tracker::RustNameTracker,
    type_converter::TypeConverter,
};

use super::parse_foreign_mod::{ForeignModParseCallbacks, ParseForeignMod};

#[derive(Copy, Clone, Eq, PartialEq)]
enum TypeKind {
    POD,                // trivial. Can be moved and copied in Rust.
    NonPOD, // has destructor or non-trivial move constructors. Can only hold by UniquePtr
    ForwardDeclaration, // no full C++ declaration available - can't even generate UniquePtr
}

/// Parses a bindgen mod in order to understand the APIs within it.
pub(crate) struct ParseBindgen<'a> {
    type_converter: TypeConverter<'a>,
    byvalue_checker: ByValueChecker,
    type_database: &'a TypeDatabase,
    bridge_name_tracker: BridgeNameTracker,
    rust_name_tracker: RustNameTracker,
    incomplete_types: HashSet<TypeName>,
    results: ParseResults,
    unsafe_policy: UnsafePolicy,
}

impl<'a> ParseBindgen<'a> {
    pub(crate) fn new(
        byvalue_checker: ByValueChecker,
        type_database: &'a TypeDatabase,
        unsafe_policy: UnsafePolicy,
    ) -> Self {
        ParseBindgen {
            type_converter: TypeConverter::new(type_database),
            byvalue_checker,
            bridge_name_tracker: BridgeNameTracker::new(),
            rust_name_tracker: RustNameTracker::new(),
            type_database,
            incomplete_types: HashSet::new(),
            results: ParseResults {
                apis: Vec::new(),
                use_stmts_by_mod: HashMap::new(),
            },
            unsafe_policy,
        }
    }

    /// Main function which goes through and performs conversion from
    /// `bindgen`-style Rust output into `cxx::bridge`-style Rust input.
    /// At present, it significantly rewrites the bindgen mod,
    /// as well as generating an additional cxx::bridge mod, and an outer
    /// mod with all sorts of 'use' statements. A valid alternative plan
    /// might be to keep the bindgen mod untouched and _only_ generate
    /// additional bindings, but the sticking point there is that it's not
    /// obviously possible to stop folks allocating opaque types in the
    /// bindgen mod. (We mark all types as opaque until we're told
    /// otherwise, which is the opposite of what bindgen does, so we can't
    /// just give it lots of directives to make all types opaque.)
    /// One future option could be to provide a mode to bindgen where
    /// everything is opaque unless specifically allowlisted to be
    /// transparent.
    pub(crate) fn convert_items(
        mut self,
        items: Vec<Item>,
        exclude_utilities: bool,
    ) -> Result<ParseResults, ConvertError> {
        if !exclude_utilities {
            generate_utilities(&mut self.results.apis);
        }
        let root_ns = Namespace::new();
        self.convert_mod_items(items, root_ns)?;
        Ok(self.results)
    }

    /// Interpret the bindgen-generated .rs for a particular
    /// mod, which corresponds to a C++ namespace.
    fn convert_mod_items(&mut self, items: Vec<Item>, ns: Namespace) -> Result<(), ConvertError> {
        // This object maintains some state specific to this namespace, i.e.
        // this particular mod.
        let mut mod_converter = ParseForeignMod::new(ns.clone());
        let mut use_statements_for_this_mod = Vec::new();
        for item in items {
            match item {
                Item::ForeignMod(mut fm) => {
                    let items = fm.items;
                    fm.items = Vec::new();
                    mod_converter.convert_foreign_mod_items(items)?;
                }
                Item::Struct(mut s) => {
                    let tyname = TypeName::new(&ns, &s.ident.to_string());
                    let type_kind = if Self::spot_forward_declaration(&s.fields) {
                        self.incomplete_types.insert(tyname.clone());
                        TypeKind::ForwardDeclaration
                    } else if self.byvalue_checker.is_pod(&tyname) {
                        TypeKind::POD
                    } else {
                        TypeKind::NonPOD
                    };
                    // We either leave a bindgen struct untouched, or we completely
                    // replace its contents with opaque nonsense.
                    let field_types = match type_kind {
                        TypeKind::POD => self.get_struct_field_types(&ns, &s)?,
                        _ => {
                            make_non_pod(&mut s);
                            HashSet::new()
                        }
                    };
                    // cxx::bridge can't cope with type aliases to generic
                    // types at the moment.
                    self.generate_type(tyname, type_kind, field_types, Some(Item::Struct(s)));
                }
                Item::Enum(e) => {
                    let tyname = TypeName::new(&ns, &e.ident.to_string());
                    self.generate_type(tyname, TypeKind::POD, HashSet::new(), Some(Item::Enum(e)));
                }
                Item::Impl(imp) => {
                    // We *mostly* ignore all impl blocks generated by bindgen.
                    // Methods also appear in 'extern "C"' blocks which
                    // we will convert instead. At that time we'll also construct
                    // synthetic impl blocks.
                    // We do however record which methods were spotted, since
                    // we have no other way of working out which functions are
                    // static methods vs plain functions.
                    mod_converter.convert_impl_items(imp);
                }
                Item::Mod(itm) => {
                    if let Some((_, items)) = itm.content {
                        let new_ns = ns.push(itm.ident.to_string());
                        self.convert_mod_items(items, new_ns)?;
                    }
                }
                Item::Use(_) => {
                    use_statements_for_this_mod.push(item);
                }
                Item::Const(itc) => {
                    // TODO the following puts this constant into
                    // the global namespace which is bug
                    // https://github.com/google/autocxx/issues/133
                    self.add_api(Api {
                        id: itc.ident.clone(),
                        ns: ns.clone(),
                        bridge_item: None,
                        extern_c_mod_item: None,
                        global_items: vec![Item::Const(itc)],
                        additional_cpp: None,
                        deps: HashSet::new(),
                        use_stmt: Use::Unused,
                        id_for_allowlist: None,
                        bindgen_mod_item: None,
                        impl_entry: None,
                    });
                }
                Item::Type(ity) => {
                    let tyname = TypeName::new(&ns, &ity.ident.to_string());
                    self.type_converter.insert_typedef(tyname, ity.ty.as_ref());
                    self.add_api(Api {
                        id: ity.ident.clone(),
                        ns: ns.clone(),
                        bridge_item: None,
                        extern_c_mod_item: None,
                        global_items: Vec::new(),
                        additional_cpp: None,
                        deps: HashSet::new(),
                        use_stmt: Use::Unused,
                        id_for_allowlist: None,
                        bindgen_mod_item: Some(Item::Type(ity)),
                        impl_entry: None,
                    });
                }
                _ => return Err(ConvertError::UnexpectedItemInMod),
            }
        }
        mod_converter.finished(self)?;

        // We don't immediately blat 'use' statements into any particular
        // Api. We'll squirrel them away and insert them into the output mod later
        // iff this mod ends up having any output items after garbage collection
        // of unnecessary APIs.
        let supers = std::iter::repeat(make_ident("super")).take(ns.depth() + 2);
        use_statements_for_this_mod.push(Item::Use(parse_quote! {
            #[allow(unused_imports)]
            use self::
                #(#supers)::*
            ::cxxbridge;
        }));
        for thing in &["UniquePtr", "CxxString"] {
            let thing = make_ident(thing);
            use_statements_for_this_mod.push(Item::Use(parse_quote! {
                #[allow(unused_imports)]
                use cxx:: #thing;
            }));
        }
        use_statements_for_this_mod.push(Item::Use(parse_quote! {
            #[allow(unused_imports)]
            use std::pin::Pin;
        }));
        self.results
            .use_stmts_by_mod
            .insert(ns, use_statements_for_this_mod);
        Ok(())
    }

    fn get_struct_field_types(
        &mut self,
        ns: &Namespace,
        s: &ItemStruct,
    ) -> Result<HashSet<TypeName>, ConvertError> {
        let mut results = HashSet::new();
        for f in &s.fields {
            let annotated = self.type_converter.convert_type(f.ty.clone(), ns)?;
            self.results.apis.extend(annotated.extra_apis);
            results.extend(annotated.types_encountered);
        }
        Ok(results)
    }

    fn spot_forward_declaration(s: &Fields) -> bool {
        s.iter()
            .filter_map(|f| f.ident.as_ref())
            .any(|id| id == "_unused")
    }

    /// Record the Api for a type, e.g. enum or struct.
    /// Code generated includes the bindgen entry itself,
    /// various entries for the cxx::bridge to ensure cxx
    /// is aware of the type, and 'use' statements for the final
    /// output mod hierarchy. All are stored in the Api which
    /// this adds.
    fn generate_type(
        &mut self,
        tyname: TypeName,
        type_nature: TypeKind,
        deps: HashSet<TypeName>,
        bindgen_mod_item: Option<Item>,
    ) {
        let final_ident = make_ident(tyname.get_final_ident());
        let kind_item = match type_nature {
            TypeKind::POD => "Trivial",
            _ => "Opaque",
        };
        let kind_item = make_ident(kind_item);
        if self.type_database.is_on_blocklist(&tyname) {
            return;
        }
        let tynamestring = tyname.to_cpp_name();
        let mut for_extern_c_ts = if tyname.has_namespace() {
            let ns_string = tyname
                .ns_segment_iter()
                .cloned()
                .collect::<Vec<String>>()
                .join("::");
            quote! {
                #[namespace = #ns_string]
            }
        } else {
            TokenStream2::new()
        };

        let mut fulltypath: Vec<_> = ["bindgen", "root"].iter().map(|x| make_ident(x)).collect();
        for_extern_c_ts.extend(quote! {
            type #final_ident = super::bindgen::root::
        });
        for segment in tyname.ns_segment_iter() {
            let id = make_ident(segment);
            for_extern_c_ts.extend(quote! {
                #id::
            });
            fulltypath.push(id);
        }
        for_extern_c_ts.extend(quote! {
            #final_ident;
        });
        let bridge_item = match type_nature {
            TypeKind::ForwardDeclaration => None,
            _ => Some(Item::Impl(parse_quote! {
                impl UniquePtr<#final_ident> {}
            })),
        };
        fulltypath.push(final_ident.clone());
        let api = Api {
            ns: tyname.get_namespace().clone(),
            id: final_ident,
            use_stmt: Use::Used,
            global_items: vec![Item::Impl(parse_quote! {
                unsafe impl cxx::ExternType for #(#fulltypath)::* {
                    type Id = cxx::type_id!(#tynamestring);
                    type Kind = cxx::kind::#kind_item;
                }
            })],
            bridge_item,
            extern_c_mod_item: Some(ForeignItem::Verbatim(for_extern_c_ts)),
            additional_cpp: None,
            deps,
            id_for_allowlist: None,
            bindgen_mod_item,
            impl_entry: None,
        };
        self.add_api(api);
        self.type_converter.push(tyname);
    }
}

impl<'a> ForeignModParseCallbacks for ParseBindgen<'a> {
    fn convert_boxed_type(
        &mut self,
        ty: Box<Type>,
        ns: &Namespace,
    ) -> Result<(Box<Type>, HashSet<TypeName>), ConvertError> {
        let annotated = self.type_converter.convert_boxed_type(ty, ns)?;
        self.results.apis.extend(annotated.extra_apis);
        Ok((annotated.ty, annotated.types_encountered))
    }

    fn is_pod(&self, ty: &TypeName) -> bool {
        self.byvalue_checker.is_pod(ty)
    }

    fn add_api(&mut self, api: Api) {
        self.results.apis.push(api);
    }

    fn get_cxx_bridge_name(
        &mut self,
        type_name: Option<&str>,
        found_name: &str,
        ns: &Namespace,
    ) -> String {
        self.bridge_name_tracker
            .get_unique_cxx_bridge_name(type_name, found_name, ns)
    }

    fn ok_to_use_rust_name(&mut self, rust_name: &str) -> bool {
        self.rust_name_tracker.ok_to_use_rust_name(rust_name)
    }

    fn is_on_allowlist(&self, type_name: &TypeName) -> bool {
        self.type_database.is_on_allowlist(type_name)
    }

    fn avoid_generating_type(&self, type_name: &TypeName) -> bool {
        self.type_database.is_on_blocklist(type_name) || self.incomplete_types.contains(type_name)
    }

    fn should_be_unsafe(&self) -> bool {
        self.unsafe_policy == UnsafePolicy::AllFunctionsUnsafe
    }
}
<|endoftext|>


<commit_before>//! Iron's Middleware and Handler System
//!
//! Iron's Middleware system is best modeled with a diagram.
//!
//! ```plain
//! [b] = BeforeMiddleware
//! [a] = AfterMiddleware
//! [[h]] = AroundMiddleware
//! [h] = Handler
//! ```
//!
//! With no errors, the flow looks like:
//!
//! ```plain
//! [b] -> [b] -> [b] -> [[[[h]]]] -> [a] -> [a] -> [a] -> [a]
//! ```
//!
//! A request first travels through all BeforeMiddleware, then a Response is generated
//! by the Handler, which can be an arbitrary nesting of AroundMiddleware, then all
//! AfterMiddleware are called with both the Request and Response. After all AfterMiddleware
//! have been fired, the response is written back to the client.
//!
//! Iron's error handling system is pragmatic and focuses on tracking two pieces
//! of information for error receivers (other middleware):
//!
//! * The cause of the error
//! * The result (what to do about) the error.
//!
//! The cause of the error is represented simply by the error itself, and the result
//! of the error, representing the action to take in response to the error, is a complete
//! Response, which will be sent at the end of the error flow.
//!
//! When an error is thrown in Iron by any middleware or handler returning an `Err`
//! variant with an `IronError`, the flow of the Request switches to the error flow,
//! which proceeds to just call the `catch` method of middleware and sidesteps the
//! `Handler` entirely, since there is already a Response in the error.
//!
//! A Request can exit the error flow by returning an Ok from any of the catch methods.
//! This resumes the flow at the middleware immediately following the middleware which
//! handled the error. It is impossible to "go back" to an earlier middleware that was
//! skipped.
//!
//! Generally speaking, returning a 5XX error code means that the error flow should be
//! entered by raising an explicit error. Dealing with 4XX errors is trickier, since
//! the server may not want to recognize an error that is entirely the clients fault;
//! handling of 4XX error codes is up to to each application and middleware author.
//!
//! Middleware authors should be cognizant that their middleware may be skipped during
//! the error flow. Anything that *must* be done to each Request or Response should
//! be run during both the normal and error flow by implementing the `catch` method to
//! also do the necessary action.
//!

use std::any::Any;
use std::sync::Arc;
use {Request, Response, IronResult, IronError};

/// `Handler`s are responsible for handling requests by creating Responses from Requests.
pub trait Handler: Send + Sync + Any {
    /// Produce a `Response` from a Request, with the possibility of error.
    fn handle(&self, &mut Request) -> IronResult<Response>;
}

/// `BeforeMiddleware` are fired before a `Handler` is called inside of a Chain.
///
/// `BeforeMiddleware` are responsible for doing request pre-processing that requires
/// the ability to change control-flow, such as authorization middleware, or for editing
/// the request by modifying the headers.
///
/// `BeforeMiddleware` only have access to the Request, if you need to modify or read
/// a Response, you will need `AfterMiddleware`. Middleware which wishes to send an
/// early response that is not an error cannot be `BeforeMiddleware`, but should
/// instead be `AroundMiddleware`.
pub trait BeforeMiddleware: Send + Sync + Any {
    /// Do whatever work this middleware should do with a `Request` object.
    fn before(&self, _: &mut Request) -> IronResult<()> { Ok(()) }

    /// Respond to an error thrown by a previous `BeforeMiddleware`.
    ///
    /// Returning a `Ok` will cause the request to resume the normal flow at the
    /// next `BeforeMiddleware`, or if this was the last `BeforeMiddleware`,
    /// at the `Handler`.
    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> { Err(err) }
}

/// `AfterMiddleware` are fired after a `Handler` is called inside of a Chain.
///
/// `AfterMiddleware` receive both a `Request` and a `Response` and are responsible for doing
/// any response post-processing.
///
/// `AfterMiddleware` should *not* overwrite the contents of a Response. In
/// the common case, a complete response is generated by the Chain's `Handler` and
/// `AfterMiddleware` simply do post-processing of that Response, such as
/// adding headers or logging.
pub trait AfterMiddleware: Send + Sync + Any {
    /// Do whatever post-processing this middleware should do.
    fn after(&self, _: &mut Request, res: Response) -> IronResult<Response> {
        Ok(res)
    }

    /// Respond to an error thrown by previous `AfterMiddleware`, the `Handler`,
    /// or a `BeforeMiddleware`.
    ///
    /// Returning `Ok` will cause the request to resume the normal flow at the
    /// next `AfterMiddleware`.
    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<Response> {
        Err(err)
    }
}

/// AroundMiddleware are used to wrap and replace the `Handler` in a `Chain`.
///
/// AroundMiddleware produce `Handler`s through their `around` method, which is
/// called once on insertion into a Chain or can be called manually outside of a
/// `Chain`.
pub trait AroundMiddleware {
    /// Produce a `Handler` from this `AroundMiddleware` given another `Handler`.
    ///
    /// Usually this means wrapping the handler and editing the `Request` on the
    /// way in and the `Response` on the way out.
    ///
    /// This is called only once, when an `AroundMiddleware` is added to a `Chain`
    /// using `Chain::around`, it is passed the `Chain`'s current `Handler`.
    fn around(self, handler: Box<Handler>) -> Box<Handler>;
}

/// The middleware chain used in Iron.
///
/// This is a canonical implementation of Iron's middleware system,
/// but Iron's infrastructure is flexible enough to allow alternate
/// systems.
pub struct Chain {
    befores: Vec<Box<BeforeMiddleware>>,
    afters: Vec<Box<AfterMiddleware>>,

    // Internal invariant: this is always Some
    handler: Option<Box<Handler>>
}

impl Chain {
    /// Construct a new ChainBuilder from a `Handler`.
    pub fn new<H: Handler>(handler: H) -> Chain {
        Chain {
            befores: vec![],
            afters: vec![],
            handler: Some(Box::new(handler) as Box<Handler>)
        }
    }

    /// Link both a before and after middleware to the chain at once.
    ///
    /// Middleware that have a Before and After piece should have a constructor
    /// which returns both as a tuple, so it can be passed directly to link.
    pub fn link<B, A>(&mut self, link: (B, A)) -> &mut Chain
    where A: AfterMiddleware, B: BeforeMiddleware {
        let (before, after) = link;
        self.befores.push(Box::new(before) as Box<BeforeMiddleware>);
        self.afters.push(Box::new(after) as Box<AfterMiddleware>);
        self
    }

    /// Link a `BeforeMiddleware` to the `Chain`, after all previously linked
    /// `BeforeMiddleware`.
    pub fn link_before<B>(&mut self, before: B) -> &mut Chain
    where B: BeforeMiddleware {
        self.befores.push(Box::new(before) as Box<BeforeMiddleware>);
        self
    }

    /// Link a `AfterMiddleware` to the `Chain`, after all previously linked
    /// `AfterMiddleware`.
    pub fn link_after<A>(&mut self, after: A) -> &mut Chain
    where A: AfterMiddleware {
        self.afters.push(Box::new(after) as Box<AfterMiddleware>);
        self
    }

    /// Apply an `AroundMiddleware` to the `Handler` in this `Chain`.
    ///
    /// Note: This function is being renamed `link_around()`, and will
    /// eventually be removed.
    pub fn around<A>(&mut self, around: A) -> &mut Chain
    where A: AroundMiddleware {
        self.link_around(around)
    }

    /// Apply an `AroundMiddleware` to the `Handler` in this `Chain`.
    pub fn link_around<A>(&mut self, around: A) -> &mut Chain
    where A: AroundMiddleware {
        let mut handler = self.handler.take().unwrap();
        handler = around.around(handler);
        self.handler = Some(handler);
        self
    }
}

impl Handler for Chain {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        // Kick off at befores, which will continue into handler
        // then afters.
        self.continue_from_before(req, 0)
    }
}

impl Chain {
    ///////////////// Implementation Helpers /////////////////

    // Enter the error flow from a before middleware, starting
    // at the passed index.
    //
    // If the index is out of bounds for the before middleware Vec,
    // this instead behaves the same as fail_from_handler.
    fn fail_from_before(&self, req: &mut Request, index: usize,
                        mut err: IronError) -> IronResult<Response> {
        // If this was the last before, yield to next phase.
        if index >= self.befores.len() {
            return self.fail_from_handler(req, err)
        }

        for (i, before) in self.befores[index..].iter().enumerate() {
            err = match before.catch(req, err) {
                Err(err) => err,
                Ok(()) => return self.continue_from_before(req, index + i + 1)
            };
        }

        // Next phase
        self.fail_from_handler(req, err)
    }

    // Enter the error flow from an errored handle, starting with the
    // first AfterMiddleware.
    fn fail_from_handler(&self, req: &mut Request,
                         err: IronError) -> IronResult<Response> {
        // Yield to next phase, nothing to do here.
        self.fail_from_after(req, 0, err)
    }

    // Enter the error flow from an errored after middleware, starting
    // with the passed index.
    //
    // If the index is out of bounds for the after middleware Vec,
    // this instead just returns the passed error.
    fn fail_from_after(&self, req: &mut Request, index: usize,
                       mut err: IronError) -> IronResult<Response> {
        // If this was the last after, we're done.
        if index == self.afters.len() { return Err(err) }

        for (i, after) in self.afters[index..].iter().enumerate() {
            err = match after.catch(req, err) {
                Err(err) => err,
                Ok(res) => return self.continue_from_after(req, index + i + 1, res)
            }
        }

        // Done
        Err(err)
    }

    // Enter the normal flow in the before middleware, starting with the passed
    // index.
    fn continue_from_before(&self, req: &mut Request,
                            index: usize) -> IronResult<Response> {
        // If this was the last beforemiddleware, start at the handler.
        if index >= self.befores.len() {
            return self.continue_from_handler(req)
        }

        for (i, before) in self.befores[index..].iter().enumerate() {
            match before.before(req) {
                Ok(()) => {},
                Err(err) => return self.fail_from_before(req, index + i + 1, err)
            }
        }

        // Yield to next phase.
        self.continue_from_handler(req)
    }

    // Enter the normal flow at the handler.
    fn continue_from_handler(&self, req: &mut Request) -> IronResult<Response> {
        // unwrap is safe because it's always Some
        match self.handler.as_ref().unwrap().handle(req) {
            Ok(res) => self.continue_from_after(req, 0, res),
            Err(err) => self.fail_from_handler(req, err)
        }
    }

    // Enter the normal flow in the after middleware, starting with the passed
    // index.
    fn continue_from_after(&self, req: &mut Request, index: usize,
                            mut res: Response) -> IronResult<Response> {
        // If this was the last after middleware, we're done.
        if index >= self.afters.len() {
            return Ok(res);
        }

        for (i, after) in self.afters[index..].iter().enumerate() {
            res = match after.after(req, res) {
                Ok(r) => r,
                Err(err) => return self.fail_from_after(req, index + i + 1, err)
            }
        }

        // We made it with no error!
        Ok(res)
    }
}

impl<F> Handler for F
where F: Send + Sync + Any + Fn(&mut Request) -> IronResult<Response> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        (*self)(req)
    }
}

impl Handler for Box<Handler> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        (**self).handle(req)
    }
}

impl<F> BeforeMiddleware for F
where F: Send + Sync + Any + Fn(&mut Request) -> IronResult<()> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (*self)(req)
    }
}

impl BeforeMiddleware for Box<BeforeMiddleware> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (**self).before(req)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        (**self).catch(req, err)
    }
}

impl<T> BeforeMiddleware for Arc<T> where T: BeforeMiddleware {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (**self).before(req)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        (**self).catch(req, err)
    }
}

impl<F> AfterMiddleware for F
where F: Send + Sync + Any + Fn(&mut Request, Response) -> IronResult<Response> {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (*self)(req, res)
    }
}

impl AfterMiddleware for Box<AfterMiddleware> {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (**self).after(req, res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (**self).catch(req, err)
    }
}

impl<T> AfterMiddleware for Arc<T> where T: AfterMiddleware {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (**self).after(req, res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (**self).catch(req, err)
    }
}

impl<F> AroundMiddleware for F
where F: FnOnce(Box<Handler>) -> Box<Handler> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        self(handler)
    }
}

#[cfg(test)]
mod test;
<commit_msg>Pull changes from https://github.com/iron/iron/pull/436<commit_after>//! Iron's Middleware and Handler System
//!
//! Iron's Middleware system is best modeled with a diagram.
//!
//! ```plain
//! [b] = BeforeMiddleware
//! [a] = AfterMiddleware
//! [[h]] = AroundMiddleware
//! [h] = Handler
//! ```
//!
//! With no errors, the flow looks like:
//!
//! ```plain
//! [b] -> [b] -> [b] -> [[[[h]]]] -> [a] -> [a] -> [a] -> [a]
//! ```
//!
//! A request first travels through all BeforeMiddleware, then a Response is generated
//! by the Handler, which can be an arbitrary nesting of AroundMiddleware, then all
//! AfterMiddleware are called with both the Request and Response. After all AfterMiddleware
//! have been fired, the response is written back to the client.
//!
//! Iron's error handling system is pragmatic and focuses on tracking two pieces
//! of information for error receivers (other middleware):
//!
//! * The cause of the error
//! * The result (what to do about) the error.
//!
//! The cause of the error is represented simply by the error itself, and the result
//! of the error, representing the action to take in response to the error, is a complete
//! Response, which will be sent at the end of the error flow.
//!
//! When an error is thrown in Iron by any middleware or handler returning an `Err`
//! variant with an `IronError`, the flow of the Request switches to the error flow,
//! which proceeds to just call the `catch` method of middleware and sidesteps the
//! `Handler` entirely, since there is already a Response in the error.
//!
//! A Request can exit the error flow by returning an Ok from any of the catch methods.
//! This resumes the flow at the middleware immediately following the middleware which
//! handled the error. It is impossible to "go back" to an earlier middleware that was
//! skipped.
//!
//! Generally speaking, returning a 5XX error code means that the error flow should be
//! entered by raising an explicit error. Dealing with 4XX errors is trickier, since
//! the server may not want to recognize an error that is entirely the clients fault;
//! handling of 4XX error codes is up to to each application and middleware author.
//!
//! Middleware authors should be cognizant that their middleware may be skipped during
//! the error flow. Anything that *must* be done to each Request or Response should
//! be run during both the normal and error flow by implementing the `catch` method to
//! also do the necessary action.
//!

use std::sync::Arc;
use {Request, Response, IronResult, IronError};

/// `Handler`s are responsible for handling requests by creating Responses from Requests.
pub trait Handler: Send + Sync + 'static {
    /// Produce a `Response` from a Request, with the possibility of error.
    fn handle(&self, &mut Request) -> IronResult<Response>;
}

/// `BeforeMiddleware` are fired before a `Handler` is called inside of a Chain.
///
/// `BeforeMiddleware` are responsible for doing request pre-processing that requires
/// the ability to change control-flow, such as authorization middleware, or for editing
/// the request by modifying the headers.
///
/// `BeforeMiddleware` only have access to the Request, if you need to modify or read
/// a Response, you will need `AfterMiddleware`. Middleware which wishes to send an
/// early response that is not an error cannot be `BeforeMiddleware`, but should
/// instead be `AroundMiddleware`.
pub trait BeforeMiddleware: Send + Sync + 'static {
    /// Do whatever work this middleware should do with a `Request` object.
    fn before(&self, _: &mut Request) -> IronResult<()> { Ok(()) }

    /// Respond to an error thrown by a previous `BeforeMiddleware`.
    ///
    /// Returning a `Ok` will cause the request to resume the normal flow at the
    /// next `BeforeMiddleware`, or if this was the last `BeforeMiddleware`,
    /// at the `Handler`.
    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> { Err(err) }
}

/// `AfterMiddleware` are fired after a `Handler` is called inside of a Chain.
///
/// `AfterMiddleware` receive both a `Request` and a `Response` and are responsible for doing
/// any response post-processing.
///
/// `AfterMiddleware` should *not* overwrite the contents of a Response. In
/// the common case, a complete response is generated by the Chain's `Handler` and
/// `AfterMiddleware` simply do post-processing of that Response, such as
/// adding headers or logging.
pub trait AfterMiddleware: Send + Sync + 'static {
    /// Do whatever post-processing this middleware should do.
    fn after(&self, _: &mut Request, res: Response) -> IronResult<Response> {
        Ok(res)
    }

    /// Respond to an error thrown by previous `AfterMiddleware`, the `Handler`,
    /// or a `BeforeMiddleware`.
    ///
    /// Returning `Ok` will cause the request to resume the normal flow at the
    /// next `AfterMiddleware`.
    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<Response> {
        Err(err)
    }
}

/// AroundMiddleware are used to wrap and replace the `Handler` in a `Chain`.
///
/// AroundMiddleware produce `Handler`s through their `around` method, which is
/// called once on insertion into a Chain or can be called manually outside of a
/// `Chain`.
pub trait AroundMiddleware {
    /// Produce a `Handler` from this `AroundMiddleware` given another `Handler`.
    ///
    /// Usually this means wrapping the handler and editing the `Request` on the
    /// way in and the `Response` on the way out.
    ///
    /// This is called only once, when an `AroundMiddleware` is added to a `Chain`
    /// using `Chain::around`, it is passed the `Chain`'s current `Handler`.
    fn around(self, handler: Box<Handler>) -> Box<Handler>;
}

/// The middleware chain used in Iron.
///
/// This is a canonical implementation of Iron's middleware system,
/// but Iron's infrastructure is flexible enough to allow alternate
/// systems.
pub struct Chain {
    befores: Vec<Box<BeforeMiddleware>>,
    afters: Vec<Box<AfterMiddleware>>,

    // Internal invariant: this is always Some
    handler: Option<Box<Handler>>
}

impl Chain {
    /// Construct a new ChainBuilder from a `Handler`.
    pub fn new<H: Handler>(handler: H) -> Chain {
        Chain {
            befores: vec![],
            afters: vec![],
            handler: Some(Box::new(handler) as Box<Handler>)
        }
    }

    /// Link both a before and after middleware to the chain at once.
    ///
    /// Middleware that have a Before and After piece should have a constructor
    /// which returns both as a tuple, so it can be passed directly to link.
    pub fn link<B, A>(&mut self, link: (B, A)) -> &mut Chain
    where A: AfterMiddleware, B: BeforeMiddleware {
        let (before, after) = link;
        self.befores.push(Box::new(before) as Box<BeforeMiddleware>);
        self.afters.push(Box::new(after) as Box<AfterMiddleware>);
        self
    }

    /// Link a `BeforeMiddleware` to the `Chain`, after all previously linked
    /// `BeforeMiddleware`.
    pub fn link_before<B>(&mut self, before: B) -> &mut Chain
    where B: BeforeMiddleware {
        self.befores.push(Box::new(before) as Box<BeforeMiddleware>);
        self
    }

    /// Link a `AfterMiddleware` to the `Chain`, after all previously linked
    /// `AfterMiddleware`.
    pub fn link_after<A>(&mut self, after: A) -> &mut Chain
    where A: AfterMiddleware {
        self.afters.push(Box::new(after) as Box<AfterMiddleware>);
        self
    }

    /// Apply an `AroundMiddleware` to the `Handler` in this `Chain`.
    ///
    /// Note: This function is being renamed `link_around()`, and will
    /// eventually be removed.
    pub fn around<A>(&mut self, around: A) -> &mut Chain
    where A: AroundMiddleware {
        self.link_around(around)
    }

    /// Apply an `AroundMiddleware` to the `Handler` in this `Chain`.
    pub fn link_around<A>(&mut self, around: A) -> &mut Chain
    where A: AroundMiddleware {
        let mut handler = self.handler.take().unwrap();
        handler = around.around(handler);
        self.handler = Some(handler);
        self
    }
}

impl Handler for Chain {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        // Kick off at befores, which will continue into handler
        // then afters.
        self.continue_from_before(req, 0)
    }
}

impl Chain {
    ///////////////// Implementation Helpers /////////////////

    // Enter the error flow from a before middleware, starting
    // at the passed index.
    //
    // If the index is out of bounds for the before middleware Vec,
    // this instead behaves the same as fail_from_handler.
    fn fail_from_before(&self, req: &mut Request, index: usize,
                        mut err: IronError) -> IronResult<Response> {
        // If this was the last before, yield to next phase.
        if index >= self.befores.len() {
            return self.fail_from_handler(req, err)
        }

        for (i, before) in self.befores[index..].iter().enumerate() {
            err = match before.catch(req, err) {
                Err(err) => err,
                Ok(()) => return self.continue_from_before(req, index + i + 1)
            };
        }

        // Next phase
        self.fail_from_handler(req, err)
    }

    // Enter the error flow from an errored handle, starting with the
    // first AfterMiddleware.
    fn fail_from_handler(&self, req: &mut Request,
                         err: IronError) -> IronResult<Response> {
        // Yield to next phase, nothing to do here.
        self.fail_from_after(req, 0, err)
    }

    // Enter the error flow from an errored after middleware, starting
    // with the passed index.
    //
    // If the index is out of bounds for the after middleware Vec,
    // this instead just returns the passed error.
    fn fail_from_after(&self, req: &mut Request, index: usize,
                       mut err: IronError) -> IronResult<Response> {
        // If this was the last after, we're done.
        if index == self.afters.len() { return Err(err) }

        for (i, after) in self.afters[index..].iter().enumerate() {
            err = match after.catch(req, err) {
                Err(err) => err,
                Ok(res) => return self.continue_from_after(req, index + i + 1, res)
            }
        }

        // Done
        Err(err)
    }

    // Enter the normal flow in the before middleware, starting with the passed
    // index.
    fn continue_from_before(&self, req: &mut Request,
                            index: usize) -> IronResult<Response> {
        // If this was the last beforemiddleware, start at the handler.
        if index >= self.befores.len() {
            return self.continue_from_handler(req)
        }

        for (i, before) in self.befores[index..].iter().enumerate() {
            match before.before(req) {
                Ok(()) => {},
                Err(err) => return self.fail_from_before(req, index + i + 1, err)
            }
        }

        // Yield to next phase.
        self.continue_from_handler(req)
    }

    // Enter the normal flow at the handler.
    fn continue_from_handler(&self, req: &mut Request) -> IronResult<Response> {
        // unwrap is safe because it's always Some
        match self.handler.as_ref().unwrap().handle(req) {
            Ok(res) => self.continue_from_after(req, 0, res),
            Err(err) => self.fail_from_handler(req, err)
        }
    }

    // Enter the normal flow in the after middleware, starting with the passed
    // index.
    fn continue_from_after(&self, req: &mut Request, index: usize,
                            mut res: Response) -> IronResult<Response> {
        // If this was the last after middleware, we're done.
        if index >= self.afters.len() {
            return Ok(res);
        }

        for (i, after) in self.afters[index..].iter().enumerate() {
            res = match after.after(req, res) {
                Ok(r) => r,
                Err(err) => return self.fail_from_after(req, index + i + 1, err)
            }
        }

        // We made it with no error!
        Ok(res)
    }
}

impl<F> Handler for F
where F: Send + Sync + 'static + Fn(&mut Request) -> IronResult<Response> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        (*self)(req)
    }
}

impl Handler for Box<Handler> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        (**self).handle(req)
    }
}

impl<F> BeforeMiddleware for F
where F: Send + Sync + 'static + Fn(&mut Request) -> IronResult<()> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (*self)(req)
    }
}

impl BeforeMiddleware for Box<BeforeMiddleware> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (**self).before(req)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        (**self).catch(req, err)
    }
}

impl<T> BeforeMiddleware for Arc<T> where T: BeforeMiddleware {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        (**self).before(req)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        (**self).catch(req, err)
    }
}

impl<F> AfterMiddleware for F
where F: Send + Sync + 'static + Fn(&mut Request, Response) -> IronResult<Response> {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (*self)(req, res)
    }
}

impl AfterMiddleware for Box<AfterMiddleware> {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (**self).after(req, res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (**self).catch(req, err)
    }
}

impl<T> AfterMiddleware for Arc<T> where T: AfterMiddleware {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        (**self).after(req, res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        (**self).catch(req, err)
    }
}

impl<F> AroundMiddleware for F
where F: FnOnce(Box<Handler>) -> Box<Handler> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        self(handler)
    }
}

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>
fn is_prime(num :u64) -> bool {
    for i in range(2, num) {
        if num % i == 0 {
            return false
        }
    }
    true
}

fn fatorize_prime(num :u64) {
    for i in range(2, num) {
        if num % i == 0 && is_prime(i) {
            println!("{}", i);
        }
    }
}

#[test]
fn is_prime_test() {
    assert!(is_prime(4) == false, "{} {} {}", is_prime(4), false, 4);
}

#[test]
fn is_prime_test2() {
    assert!(is_prime(5) == true, "{} {} {}", is_prime(5), true, 5);
}

fn main() {
    fatorize_prime(2332377667);
}<commit_msg>Build a more perfomant function that utilizes sqrt.<commit_after>fn is_prime(num :f64) -> bool {
    for i in range(2, num.sqrt() as u64) {
        if num as u64 % i == 0 {
            return false
        }
    }
    true
}

fn fatorize_prime(num :f64) {
    for i in range(2, num.sqrt() as u64) {
        if num as u64 % i == 0 && is_prime(i as f64) {
            println!("{}", i);
        }
    }
}

#[test]
fn is_prime_test() {
    assert!(is_prime(4) == false, "{} {} {}", is_prime(4), false, 4);
}

#[test]
fn is_prime_test2() {
    assert!(is_prime(5) == true, "{} {} {}", is_prime(5), true, 5);
}

fn main() {
    fatorize_prime(233237766723323232f64);
}<|endoftext|>