<commit_before>// During tests, we disable the renderer and that causes a bunch of warnings
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::env;
use std::thread;
use std::process::{self, Stdio};
use std::time::Instant;
use std::cell::RefCell;
use std::sync::mpsc;

use piston_window::math;

use client;
use canvas;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path};
use query::{Query, Request, DrawingCommand, Response};
use radians::{self, Radians};
use {Point, Distance, Event};

use self::DrawingCommand::*;

#[cfg(any(feature = "test", test))]
fn renderer_client(_: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let command = if cfg!(windows) {
        "dir"
    } else {
        "ls"
    };
    let mut test_proc = process::Command::new(command)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("test process failed to start");
    test_proc.kill().expect("test process could not be killed!");
    let handle = thread::spawn(move || {});
    (test_proc, handle)
}

#[cfg(not(any(feature = "test", test)))]
fn renderer_client(response_tx: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let current_exe = env::current_exe()
        .expect("Could not read path of the currently running executable")
        .into_os_string();
    let mut renderer_process = process::Command::new(current_exe)
        .env("RUN_TURTLE_CANVAS", "true")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("renderer process failed to start");

    let renderer_stdout = renderer_process.stdout.take()
        .expect("renderer process was not opened with stdout");
    let handle = thread::spawn(move || {
        client::run(renderer_stdout, response_tx);
    });

    (renderer_process, handle)
}

pub struct TurtleWindow {
    renderer: RefCell<process::Child>,
    thread_handle: RefCell<Option<thread::JoinHandle<()>>>,
    /// Channel for receiving responses from the rendering process
    response_channel: mpsc::Receiver<Response>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        // This needs to be called as close to the start of the program as possible
        // Since Turtle::new() is called at the beginning of many turtle programs, we do so here
        // to make sure this call occurs when it should.
        canvas::start();

        let (response_tx, response_rx) = mpsc::channel();
        let (renderer_process, handle) = renderer_client(response_tx);

        Self {
            renderer: RefCell::new(renderer_process),
            thread_handle: RefCell::new(Some(handle)),
            response_channel: response_rx,
        }
    }

    pub fn fetch_turtle(&self) -> TurtleState {
        self.send_query(Query::Request(Request::TurtleState));
        match self.wait_for_response() {
            Response::TurtleState(state) => {
                println!("{:?}", state);
                state
            },
            _ => panic!("bug: the renderer process did not sent back TurtleState"),
        }
    }

    pub fn update_turtle(&mut self, turtle: TurtleState) {
        unimplemented!();
    }

    pub fn fetch_drawing(&self) -> DrawingState {
        unimplemented!();
    }

    pub fn update_drawing(&mut self, drawing: DrawingState) {
        unimplemented!();
    }

    fn fetch_temporary_path(&self) -> Option<Path> {
        unimplemented!();
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
        unimplemented!();
    }

    /// See [`Turtle::poll_event()`](struct.Turtle.html#method.poll_event).
    pub fn poll_event(&mut self) -> Option<Event> {
        //TODO: query for an event, then read the response
        unimplemented!();
        //match self.response_channel.try_recv() {
        //    Ok(event) => Some(event),
        //    Err(TryRecvError::Empty) => None, // Do nothing
        //    // The window has been closed
        //    Err(TryRecvError::Disconnected) => self.exit_process(), // Quit
        //}
    }

    /// Begin filling the shape drawn by the turtle's movements.
    pub fn begin_fill(&mut self) {
        let fill_color = self.fetch_turtle().fill_color;
        self.send_drawing_command(BeginFill(fill_color));
    }

    /// Stop filling the current shape
    pub fn end_fill(&mut self) {
        self.send_drawing_command(EndFill);
    }

    /// Clear the turtle's drawings
    pub fn clear(&mut self) {
        assert!(self.fetch_temporary_path().is_none(),
            "bug: The temporary path was still set when the renderer was asked to clear the drawing");
        self.send_drawing_command(Clear);
    }

    /// Move the turtle to the given position without changing its heading.
    pub fn go_to(&mut self, end: Point) {
        let (start, speed, pen) = {
            let turtle = self.fetch_turtle();
            (turtle.position, turtle.speed, turtle.pen.clone())
        };

        let distance = math::square_len(math::sub(start, end)).sqrt();
        let speed = speed.to_absolute(); // px per second
        // We take the absolute value because the time is always positive, even if distance is negative
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {start, end, pen},
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&mut self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let (start, speed, heading, pen) = {
            let turtle = self.fetch_turtle();
            (turtle.position, turtle.speed, turtle.heading, turtle.pen.clone())
        };
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        // We take the absolute value because the time is always positive, even if distance is negative
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {start, end, pen},
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&mut self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = self.fetch_turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        // We take the absolute value because the time is always positive, even if angle is negative
        let total_millis = total_millis.to_radians().abs();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&mut self, animation: A) {
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.fetch_turtle();
                let status = animation.advance(&mut turtle);
                self.update_turtle(turtle);
                status
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        self.send_drawing_command(StorePath(path));
                    }

                    break;
                },
            }
        }
    }

    fn send_drawing_command(&self, command: DrawingCommand) {
        self.send_query(Query::Drawing(command));
    }

    // During tests, we disable the renderer. That means that if we let this code run, it will
    // quit the application during the tests and make it look like everything passes.
    // We disable this code so that none of that happens.
    #[cfg(any(feature = "test", test))]
    fn send_query(&self, _: Query) {}

    #[inline]
    #[cfg(not(any(feature = "test", test)))]
    fn send_query(&self, query: Query) {
        let result = if let Some(ref mut stdin) = self.renderer.borrow_mut().stdin {
            client::send_query(stdin, &query)
        }
        else {
            unreachable!("bug: renderer process was not opened with stdin");
        };

        result.unwrap_or_else(|_| {
            // Something went wrong while sending the query, check if the renderer process
            // panicked (exited with an error)
            match self.renderer.borrow_mut().try_wait() {
                Ok(Some(status)) => {
                    if status.success() {
                        // The window/renderer process was closed normally
                        process::exit(0);
                    }
                    else {
                        // Something went wrong, likely the other thread panicked
                        process::exit(1);
                    }
                },
                Ok(None) => panic!("bug: failed to send query even though renderer process was still running"),
                Err(_) => panic!("bug: unable to check the exit status of the renderer process"),
            }
        });
    }

    fn wait_for_response(&self) -> Response {
        match self.response_channel.recv() {
            Ok(response) => response,
            // The client thread has exited, that means that the renderer process has exited
            // and the window has closed
            Err(_) => self.exit_process(), // Quit
        }
    }

    /// Exits the current process with the correct error code
    ///
    /// Panics if the thread handle has already been consumed
    #[inline]
    fn exit_process(&self) -> ! {
        if let Some(handle) = self.thread_handle.borrow_mut().take() {
            // First check if the other thread panicked before it quit
            match handle.join() {
                Ok(_) => match self.renderer.borrow_mut().try_wait() {
                    Ok(Some(status)) => {
                        if status.success() {
                            // The window/renderer process was closed normally
                            process::exit(0);
                        }
                        else {
                            // Something went wrong, likely the other thread panicked
                            process::exit(1);
                        }
                    },
                    Ok(None) => match self.renderer.borrow_mut().wait() {
                        Ok(status) => {
                            if status.success() {
                                process::exit(0);
                            }
                            else {
                                process::exit(1);
                            }
                        },
                        Err(_) => unreachable!("bug: renderer process never ran even though we exited"),
                    },
                    Err(_) => panic!("bug: unable to check the exit status of the renderer process after client thread quit"),
                },
                // If this returns an error, the other thread panicked
                Err(_) => process::exit(1),
            }
        }
        else {
            unreachable!("bug: the thread handle was used but the process did not end");
        }
    }
}

#[cfg(not(any(feature = "test", test)))]
impl Drop for TurtleWindow {
    fn drop(&mut self) {
        // If the current thread is panicking, we want to abort right away
        // because otherwise there is code in the rendering thread that will call
        // process::exit(0) and then the exit code will be 0 instead of 1
        if thread::panicking() {
            process::exit(1);
        }

        // If this is just a normal ending of the main thread, we want to leave the renderer
        // running so that the user can see their drawing as long as they keep the window open
        //TODO: Maybe we should wait on the renderer_process instead of (or in addition to?) this thread
        if let Some(handle) = self.thread_handle.borrow_mut().take() {
            handle.join().unwrap_or_else(|_| {
                // If this returns an error, the other thread panicked
                process::exit(1);
            });
        }
    }
}
<commit_msg>Removed println! leftover from debugging<commit_after>// During tests, we disable the renderer and that causes a bunch of warnings
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::env;
use std::thread;
use std::process::{self, Stdio};
use std::time::Instant;
use std::cell::RefCell;
use std::sync::mpsc;

use piston_window::math;

use client;
use canvas;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path};
use query::{Query, Request, DrawingCommand, Response};
use radians::{self, Radians};
use {Point, Distance, Event};

use self::DrawingCommand::*;

#[cfg(any(feature = "test", test))]
fn renderer_client(_: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let command = if cfg!(windows) {
        "dir"
    } else {
        "ls"
    };
    let mut test_proc = process::Command::new(command)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("test process failed to start");
    test_proc.kill().expect("test process could not be killed!");
    let handle = thread::spawn(move || {});
    (test_proc, handle)
}

#[cfg(not(any(feature = "test", test)))]
fn renderer_client(response_tx: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let current_exe = env::current_exe()
        .expect("Could not read path of the currently running executable")
        .into_os_string();
    let mut renderer_process = process::Command::new(current_exe)
        .env("RUN_TURTLE_CANVAS", "true")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("renderer process failed to start");

    let renderer_stdout = renderer_process.stdout.take()
        .expect("renderer process was not opened with stdout");
    let handle = thread::spawn(move || {
        client::run(renderer_stdout, response_tx);
    });

    (renderer_process, handle)
}

pub struct TurtleWindow {
    renderer: RefCell<process::Child>,
    thread_handle: RefCell<Option<thread::JoinHandle<()>>>,
    /// Channel for receiving responses from the rendering process
    response_channel: mpsc::Receiver<Response>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        // This needs to be called as close to the start of the program as possible
        // Since Turtle::new() is called at the beginning of many turtle programs, we do so here
        // to make sure this call occurs when it should.
        canvas::start();

        let (response_tx, response_rx) = mpsc::channel();
        let (renderer_process, handle) = renderer_client(response_tx);

        Self {
            renderer: RefCell::new(renderer_process),
            thread_handle: RefCell::new(Some(handle)),
            response_channel: response_rx,
        }
    }

    pub fn fetch_turtle(&self) -> TurtleState {
        self.send_query(Query::Request(Request::TurtleState));
        match self.wait_for_response() {
            Response::TurtleState(state) => {
                state
            },
            _ => panic!("bug: the renderer process did not sent back TurtleState"),
        }
    }

    pub fn update_turtle(&mut self, turtle: TurtleState) {
        unimplemented!();
    }

    pub fn fetch_drawing(&self) -> DrawingState {
        unimplemented!();
    }

    pub fn update_drawing(&mut self, drawing: DrawingState) {
        unimplemented!();
    }

    fn fetch_temporary_path(&self) -> Option<Path> {
        unimplemented!();
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
        unimplemented!();
    }

    /// See [`Turtle::poll_event()`](struct.Turtle.html#method.poll_event).
    pub fn poll_event(&mut self) -> Option<Event> {
        //TODO: query for an event, then read the response
        unimplemented!();
        //match self.response_channel.try_recv() {
        //    Ok(event) => Some(event),
        //    Err(TryRecvError::Empty) => None, // Do nothing
        //    // The window has been closed
        //    Err(TryRecvError::Disconnected) => self.exit_process(), // Quit
        //}
    }

    /// Begin filling the shape drawn by the turtle's movements.
    pub fn begin_fill(&mut self) {
        let fill_color = self.fetch_turtle().fill_color;
        self.send_drawing_command(BeginFill(fill_color));
    }

    /// Stop filling the current shape
    pub fn end_fill(&mut self) {
        self.send_drawing_command(EndFill);
    }

    /// Clear the turtle's drawings
    pub fn clear(&mut self) {
        assert!(self.fetch_temporary_path().is_none(),
            "bug: The temporary path was still set when the renderer was asked to clear the drawing");
        self.send_drawing_command(Clear);
    }

    /// Move the turtle to the given position without changing its heading.
    pub fn go_to(&mut self, end: Point) {
        let (start, speed, pen) = {
            let turtle = self.fetch_turtle();
            (turtle.position, turtle.speed, turtle.pen.clone())
        };

        let distance = math::square_len(math::sub(start, end)).sqrt();
        let speed = speed.to_absolute(); // px per second
        // We take the absolute value because the time is always positive, even if distance is negative
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {start, end, pen},
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&mut self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let (start, speed, heading, pen) = {
            let turtle = self.fetch_turtle();
            (turtle.position, turtle.speed, turtle.heading, turtle.pen.clone())
        };
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        // We take the absolute value because the time is always positive, even if distance is negative
        let total_millis = (distance / speed * 1000.).abs();

        let animation = MoveAnimation {
            path: Path {start, end, pen},
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&mut self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = self.fetch_turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        // We take the absolute value because the time is always positive, even if angle is negative
        let total_millis = total_millis.to_radians().abs();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&mut self, animation: A) {
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.fetch_turtle();
                let status = animation.advance(&mut turtle);
                self.update_turtle(turtle);
                status
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        self.send_drawing_command(StorePath(path));
                    }

                    break;
                },
            }
        }
    }

    fn send_drawing_command(&self, command: DrawingCommand) {
        self.send_query(Query::Drawing(command));
    }

    // During tests, we disable the renderer. That means that if we let this code run, it will
    // quit the application during the tests and make it look like everything passes.
    // We disable this code so that none of that happens.
    #[cfg(any(feature = "test", test))]
    fn send_query(&self, _: Query) {}

    #[inline]
    #[cfg(not(any(feature = "test", test)))]
    fn send_query(&self, query: Query) {
        let result = if let Some(ref mut stdin) = self.renderer.borrow_mut().stdin {
            client::send_query(stdin, &query)
        }
        else {
            unreachable!("bug: renderer process was not opened with stdin");
        };

        result.unwrap_or_else(|_| {
            // Something went wrong while sending the query, check if the renderer process
            // panicked (exited with an error)
            match self.renderer.borrow_mut().try_wait() {
                Ok(Some(status)) => {
                    if status.success() {
                        // The window/renderer process was closed normally
                        process::exit(0);
                    }
                    else {
                        // Something went wrong, likely the other thread panicked
                        process::exit(1);
                    }
                },
                Ok(None) => panic!("bug: failed to send query even though renderer process was still running"),
                Err(_) => panic!("bug: unable to check the exit status of the renderer process"),
            }
        });
    }

    fn wait_for_response(&self) -> Response {
        match self.response_channel.recv() {
            Ok(response) => response,
            // The client thread has exited, that means that the renderer process has exited
            // and the window has closed
            Err(_) => self.exit_process(), // Quit
        }
    }

    /// Exits the current process with the correct error code
    ///
    /// Panics if the thread handle has already been consumed
    #[inline]
    fn exit_process(&self) -> ! {
        if let Some(handle) = self.thread_handle.borrow_mut().take() {
            // First check if the other thread panicked before it quit
            match handle.join() {
                Ok(_) => match self.renderer.borrow_mut().try_wait() {
                    Ok(Some(status)) => {
                        if status.success() {
                            // The window/renderer process was closed normally
                            process::exit(0);
                        }
                        else {
                            // Something went wrong, likely the other thread panicked
                            process::exit(1);
                        }
                    },
                    Ok(None) => match self.renderer.borrow_mut().wait() {
                        Ok(status) => {
                            if status.success() {
                                process::exit(0);
                            }
                            else {
                                process::exit(1);
                            }
                        },
                        Err(_) => unreachable!("bug: renderer process never ran even though we exited"),
                    },
                    Err(_) => panic!("bug: unable to check the exit status of the renderer process after client thread quit"),
                },
                // If this returns an error, the other thread panicked
                Err(_) => process::exit(1),
            }
        }
        else {
            unreachable!("bug: the thread handle was used but the process did not end");
        }
    }
}

#[cfg(not(any(feature = "test", test)))]
impl Drop for TurtleWindow {
    fn drop(&mut self) {
        // If the current thread is panicking, we want to abort right away
        // because otherwise there is code in the rendering thread that will call
        // process::exit(0) and then the exit code will be 0 instead of 1
        if thread::panicking() {
            process::exit(1);
        }

        // If this is just a normal ending of the main thread, we want to leave the renderer
        // running so that the user can see their drawing as long as they keep the window open
        //TODO: Maybe we should wait on the renderer_process instead of (or in addition to?) this thread
        if let Some(handle) = self.thread_handle.borrow_mut().take() {
            handle.join().unwrap_or_else(|_| {
                // If this returns an error, the other thread panicked
                process::exit(1);
            });
        }
    }
}
<|endoftext|>


<commit_before>use {Borrowed, Value, Field, Matrix2d};
use vecmath::{identity};
use {View};

/// An animation inbetweening context.
pub struct TweenContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
}

impl<'a> View<'a> for TweenContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

<commit_msg>Sorted use alphabetically<commit_after>use {
    Borrowed,
    Field,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity
};

/// An animation inbetweening context.
pub struct TweenContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
}

impl<'a> View<'a> for TweenContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenContext<'a> {
        TweenContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

<|endoftext|>


<commit_before>use std::marker::PhantomData;

use ast::{InputValue, Selection, FromInputValue, ToInputValue};
use value::Value;

use schema::meta::MetaType;

use executor::{Executor, Registry};
use types::base::GraphQLType;

/// An ID as defined by the GraphQL specification
///
/// Represented as a string, but can be converted _to_ from an integer as well.
pub struct ID(String);

graphql_scalar!(ID as "ID" {
    resolve(&self) -> Value {
        Value::string(&self.0)
    }

    from_input_value(v: &InputValue) -> Option<ID> {
        match *v {
            InputValue::String(ref s) => Some(ID(s.to_owned())),
            InputValue::Int(i) => Some(ID(format!("{}", i))),
            _ => None
        }
    }
});

graphql_scalar!(String as "String" {
    resolve(&self) -> Value {
        Value::string(self)
    }

    from_input_value(v: &InputValue) -> Option<String> {
        match *v {
            InputValue::String(ref s) => Some(s.clone()),
            _ => None,
        }
    }
});

impl<'a> GraphQLType for &'a str {
    type Context = ();

    fn name() -> Option<&'static str> {
        Some("String")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_scalar_type::<String>().into_meta()
    }

    fn resolve(&self, _: Option<&[Selection]>, _: &Executor<Self::Context>) -> Value {
        Value::string(self)
    }
}

impl<'a> ToInputValue for &'a str {
    fn to(&self) -> InputValue {
        InputValue::string(self)
    }
}

graphql_scalar!(bool as "Boolean" {
    resolve(&self) -> Value {
        Value::boolean(*self)
    }

    from_input_value(v: &InputValue) -> Option<bool> {
        match *v {
            InputValue::Boolean(b) => Some(b),
            _ => None,
        }
    }
});

graphql_scalar!(i64 as "Int" {
    resolve(&self) -> Value {
        Value::int(*self)
    }

    from_input_value(v: &InputValue) -> Option<i64> {
        match *v {
            InputValue::Int(i) => Some(i),
            _ => None,
        }
    }
});

graphql_scalar!(f64 as "Float" {
    resolve(&self) -> Value {
        Value::float(*self)
    }

    from_input_value(v: &InputValue) -> Option<f64> {
        match *v {
            InputValue::Int(i) => Some(i as f64),
            InputValue::Float(f) => Some(f),
            _ => None,
        }
    }
});

impl GraphQLType for () {
    type Context = ();

    fn name() -> Option<&'static str> {
        Some("__Unit")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_scalar_type::<Self>().into_meta()
    }
}

impl FromInputValue for () {
    fn from(_: &InputValue) -> Option<()> {
        None
    }
}

/// Utility type to define read-only schemas
///
/// If you instantiate `RootNode` with this as the mutation, no mutation will be
/// generated for the schema.
pub struct EmptyMutation<T> {
    phantom: PhantomData<T>,
}

impl<T> EmptyMutation<T> {
    /// Construct a new empty mutation
    pub fn new() -> EmptyMutation<T> {
        EmptyMutation {
            phantom: PhantomData,
        }
    }
}

impl<T> GraphQLType for EmptyMutation<T> {
    type Context = T;

    fn name() -> Option<&'static str> {
        Some("__EmptyMutation")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_object_type::<Self>(&[]).into_meta()
    }
}
<commit_msg>Implement traits for ID to make it usable outside its module<commit_after>use std::convert::From;
use std::marker::PhantomData;
use std::ops::Deref;

use ast::{InputValue, Selection, FromInputValue, ToInputValue};
use value::Value;

use schema::meta::MetaType;

use executor::{Executor, Registry};
use types::base::GraphQLType;

/// An ID as defined by the GraphQL specification
///
/// Represented as a string, but can be converted _to_ from an integer as well.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ID(String);

impl From<String> for ID {
    fn from(s: String) -> ID {
        ID(s)
    }
}

impl Deref for ID {
    type Target = str;

    fn deref(&self) -> &str {
        &self.0
    }
}

graphql_scalar!(ID as "ID" {
    resolve(&self) -> Value {
        Value::string(&self.0)
    }

    from_input_value(v: &InputValue) -> Option<ID> {
        match *v {
            InputValue::String(ref s) => Some(ID(s.to_owned())),
            InputValue::Int(i) => Some(ID(format!("{}", i))),
            _ => None
        }
    }
});

graphql_scalar!(String as "String" {
    resolve(&self) -> Value {
        Value::string(self)
    }

    from_input_value(v: &InputValue) -> Option<String> {
        match *v {
            InputValue::String(ref s) => Some(s.clone()),
            _ => None,
        }
    }
});

impl<'a> GraphQLType for &'a str {
    type Context = ();

    fn name() -> Option<&'static str> {
        Some("String")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_scalar_type::<String>().into_meta()
    }

    fn resolve(&self, _: Option<&[Selection]>, _: &Executor<Self::Context>) -> Value {
        Value::string(self)
    }
}

impl<'a> ToInputValue for &'a str {
    fn to(&self) -> InputValue {
        InputValue::string(self)
    }
}

graphql_scalar!(bool as "Boolean" {
    resolve(&self) -> Value {
        Value::boolean(*self)
    }

    from_input_value(v: &InputValue) -> Option<bool> {
        match *v {
            InputValue::Boolean(b) => Some(b),
            _ => None,
        }
    }
});

graphql_scalar!(i64 as "Int" {
    resolve(&self) -> Value {
        Value::int(*self)
    }

    from_input_value(v: &InputValue) -> Option<i64> {
        match *v {
            InputValue::Int(i) => Some(i),
            _ => None,
        }
    }
});

graphql_scalar!(f64 as "Float" {
    resolve(&self) -> Value {
        Value::float(*self)
    }

    from_input_value(v: &InputValue) -> Option<f64> {
        match *v {
            InputValue::Int(i) => Some(i as f64),
            InputValue::Float(f) => Some(f),
            _ => None,
        }
    }
});

impl GraphQLType for () {
    type Context = ();

    fn name() -> Option<&'static str> {
        Some("__Unit")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_scalar_type::<Self>().into_meta()
    }
}

impl FromInputValue for () {
    fn from(_: &InputValue) -> Option<()> {
        None
    }
}

/// Utility type to define read-only schemas
///
/// If you instantiate `RootNode` with this as the mutation, no mutation will be
/// generated for the schema.
pub struct EmptyMutation<T> {
    phantom: PhantomData<T>,
}

impl<T> EmptyMutation<T> {
    /// Construct a new empty mutation
    pub fn new() -> EmptyMutation<T> {
        EmptyMutation {
            phantom: PhantomData,
        }
    }
}

impl<T> GraphQLType for EmptyMutation<T> {
    type Context = T;

    fn name() -> Option<&'static str> {
        Some("__EmptyMutation")
    }

    fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r> {
        registry.build_object_type::<Self>(&[]).into_meta()
    }
}

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

    #[test]
    fn test_id_from_string() {
        let actual = ID::from(String::from("foo"));
        let expected = ID(String::from("foo"));
        assert_eq!(actual, expected);
    }

    #[test]
    fn test_id_deref() {
        let id = ID(String::from("foo"));
        assert_eq!(id.len(), 3);
    }
}
<|endoftext|>


<commit_before>use sqlite;
use std::path::Path;

use {Options, Result};

pub const DEFAULT_FILE: &'static str = "bullet.sqlite3";
pub const DEFAULT_TABLE: &'static str = "bullet";

macro_rules! create_sql(
    ($table:expr, $fields:expr) => (
        format!(r#"
CREATE TABLE IF NOT EXISTS {} (id INTEGER PRIMARY KEY AUTOINCREMENT, {});
        "#, $table, $fields)
    );
);

macro_rules! insert_sql(
    ($table:expr, $fields:expr, $values:expr) => (
        format!(r#"
INSERT INTO {} ({}) VALUES ({});
        "#, $table, $fields, $values)
    );
);

pub struct Database<'l> {
    backend: sqlite::Database<'l>,
    table: String,
}

#[derive(Clone, Copy)]
pub enum ColumnKind {
    Float,
    Integer,
}

#[derive(Clone, Copy)]
pub enum ColumnValue {
    Float(f64),
    Integer(i64),
}

pub struct Recorder<'l> {
    backend: sqlite::Statement<'l>,
}

impl<'l> Database<'l> {
    pub fn open(options: &Options) -> Result<Database<'l>> {
        Ok(Database {
            backend: match options.get::<String>("database") {
                Some(ref value) => ok!(sqlite::open(&Path::new(value))),
                _ => ok!(sqlite::open(&Path::new(DEFAULT_FILE))),
            },
            table: match options.get::<String>("table") {
                Some(table) => table,
                _ => String::from(DEFAULT_TABLE),
            },
        })
    }

    pub fn record(&'l self, columns: &[(ColumnKind, &str)]) -> Result<Recorder<'l>> {
        let mut fields = String::new();
        for &(kind, name) in columns.iter() {
            if !fields.is_empty() {
                fields.push_str(", ");
            }
            fields.push_str(name);
            match kind {
                ColumnKind::Float => fields.push_str(" REAL"),
                ColumnKind::Integer => fields.push_str(" INTEGER"),
            }
        }
        ok!(self.backend.execute(&create_sql!(&self.table, &fields)));

        Recorder::new(self, columns)
    }
}

impl<'l> Recorder<'l> {
    pub fn new(database: &'l Database, columns: &[(ColumnKind, &str)]) -> Result<Recorder<'l>> {
        let mut fields = String::new();
        let mut values = String::new();
        for &(_, name) in columns.iter() {
            if !fields.is_empty() {
                fields.push_str(", ");
                values.push_str(", ");
            }
            fields.push_str(name);
            values.push_str("?");
        }

        Ok(Recorder {
            backend: ok!(database.backend.prepare(&insert_sql!(&database.table, fields, values))),
        })
    }

    pub fn write(&mut self, columns: &[ColumnValue]) -> Result<()> {
        use sqlite::{Binding, State};

        let mut bindings = Vec::with_capacity(columns.len());
        for (i, &value) in columns.iter().enumerate() {
            match value {
                ColumnValue::Float(value) => bindings.push(Binding::Float(i + 1, value)),
                ColumnValue::Integer(value) => bindings.push(Binding::Integer(i + 1, value)),
            }
        }

        ok!(self.backend.reset());
        ok!(self.backend.bind(&bindings));

        match ok!(self.backend.step()) {
            State::Done => Ok(()),
            _ => raise!("cannot write data into the database"),
        }
    }
}
<commit_msg>Set a busy handler for SQLite<commit_after>use sqlite;
use std::path::Path;

use {Options, Result};

pub const DEFAULT_FILE: &'static str = "bullet.sqlite3";
pub const DEFAULT_TABLE: &'static str = "bullet";

macro_rules! create_sql(
    ($table:expr, $fields:expr) => (
        format!(r#"
CREATE TABLE IF NOT EXISTS {} (id INTEGER PRIMARY KEY AUTOINCREMENT, {});
        "#, $table, $fields)
    );
);

macro_rules! insert_sql(
    ($table:expr, $fields:expr, $values:expr) => (
        format!(r#"
INSERT INTO {} ({}) VALUES ({});
        "#, $table, $fields, $values)
    );
);

pub struct Database<'l> {
    backend: sqlite::Database<'l>,
    table: String,
}

#[derive(Clone, Copy)]
pub enum ColumnKind {
    Float,
    Integer,
}

#[derive(Clone, Copy)]
pub enum ColumnValue {
    Float(f64),
    Integer(i64),
}

pub struct Recorder<'l> {
    backend: sqlite::Statement<'l>,
}

impl<'l> Database<'l> {
    pub fn open(options: &Options) -> Result<Database<'l>> {
        let mut backend = match options.get::<String>("database") {
            Some(ref value) => ok!(sqlite::open(&Path::new(value))),
            _ => ok!(sqlite::open(&Path::new(DEFAULT_FILE))),
        };
        ok!(backend.set_busy_handler(|_| true));
        Ok(Database {
            backend: backend,
            table: match options.get::<String>("table") {
                Some(table) => table,
                _ => String::from(DEFAULT_TABLE),
            },
        })
    }

    pub fn record(&'l self, columns: &[(ColumnKind, &str)]) -> Result<Recorder<'l>> {
        let mut fields = String::new();
        for &(kind, name) in columns.iter() {
            if !fields.is_empty() {
                fields.push_str(", ");
            }
            fields.push_str(name);
            match kind {
                ColumnKind::Float => fields.push_str(" REAL"),
                ColumnKind::Integer => fields.push_str(" INTEGER"),
            }
        }
        ok!(self.backend.execute(&create_sql!(&self.table, &fields)));

        Recorder::new(self, columns)
    }
}

impl<'l> Recorder<'l> {
    pub fn new(database: &'l Database, columns: &[(ColumnKind, &str)]) -> Result<Recorder<'l>> {
        let mut fields = String::new();
        let mut values = String::new();
        for &(_, name) in columns.iter() {
            if !fields.is_empty() {
                fields.push_str(", ");
                values.push_str(", ");
            }
            fields.push_str(name);
            values.push_str("?");
        }

        Ok(Recorder {
            backend: ok!(database.backend.prepare(&insert_sql!(&database.table, fields, values))),
        })
    }

    pub fn write(&mut self, columns: &[ColumnValue]) -> Result<()> {
        use sqlite::{Binding, State};

        let mut bindings = Vec::with_capacity(columns.len());
        for (i, &value) in columns.iter().enumerate() {
            match value {
                ColumnValue::Float(value) => bindings.push(Binding::Float(i + 1, value)),
                ColumnValue::Integer(value) => bindings.push(Binding::Integer(i + 1, value)),
            }
        }

        ok!(self.backend.reset());
        ok!(self.backend.bind(&bindings));

        match ok!(self.backend.step()) {
            State::Done => Ok(()),
            _ => raise!("cannot write data into the database"),
        }
    }
}
<|endoftext|>


<commit_before>//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
//! [`Box`], and the owner can decide to mutate the contents, which live on the
//! heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
//! only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using [`Box`]) is too
//! constraining for an application, and is often paired with the [`Cell`] or
//! [`RefCell`] types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
//! provides all the same functionality of [`Rc`], except it requires that the
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
//! sendable while [`Rc<T>`][`Rc`] is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.
//!
//! [`Arc`]: sync/index.html
//! [`Box`]: boxed/index.html
//! [`Cell`]: ../core/cell/index.html
//! [`Rc`]: rc/index.html
//! [`RefCell`]: ../core/cell/index.html

#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
    html_root_url = "https://doc.rust-lang.org/nightly/",
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![no_std]
#![needs_allocator]
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings
#![allow(explicit_outlives_requirements)]
#![allow(incomplete_features)]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(const_generic_impls_guard)]
#![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)]
#![feature(const_if_match)]
#![feature(cow_is_borrowed)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(container_error_extra)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(fundamental)]
#![feature(internal_uninit_const)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(pattern)]
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(unsized_locals)]
#![feature(allocator_internals)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
#![feature(alloc_layout_extra)]
#![feature(try_trait)]
#![feature(associated_type_bounds)]

// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
pub mod borrow;
pub mod collections;
pub mod fmt;
pub mod prelude;
pub mod raw_vec;
pub mod rc;
pub mod slice;
pub mod str;
pub mod string;
#[cfg(target_has_atomic = "ptr")]
pub mod sync;
#[cfg(test)]
mod tests;
pub mod vec;

#[cfg(not(test))]
mod std {
    pub use core::ops; // RangeFull
}

#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
pub mod __export {
    pub use core::format_args;
}
<commit_msg>Add `#![doc(html_playground_url = ...)]` to alloc crate<commit_after>//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
//! [`Box`], and the owner can decide to mutate the contents, which live on the
//! heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
//! only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using [`Box`]) is too
//! constraining for an application, and is often paired with the [`Cell`] or
//! [`RefCell`] types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
//! provides all the same functionality of [`Rc`], except it requires that the
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
//! sendable while [`Rc<T>`][`Rc`] is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.
//!
//! [`Arc`]: sync/index.html
//! [`Box`]: boxed/index.html
//! [`Cell`]: ../core/cell/index.html
//! [`Rc`]: rc/index.html
//! [`RefCell`]: ../core/cell/index.html

#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
    html_root_url = "https://doc.rust-lang.org/nightly/",
    html_playground_url = "https://play.rust-lang.org/",
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![no_std]
#![needs_allocator]
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings
#![allow(explicit_outlives_requirements)]
#![allow(incomplete_features)]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(const_generic_impls_guard)]
#![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)]
#![feature(const_if_match)]
#![feature(cow_is_borrowed)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(container_error_extra)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(fundamental)]
#![feature(internal_uninit_const)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(pattern)]
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(unsized_locals)]
#![feature(allocator_internals)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
#![feature(alloc_layout_extra)]
#![feature(try_trait)]
#![feature(associated_type_bounds)]

// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
pub mod borrow;
pub mod collections;
pub mod fmt;
pub mod prelude;
pub mod raw_vec;
pub mod rc;
pub mod slice;
pub mod str;
pub mod string;
#[cfg(target_has_atomic = "ptr")]
pub mod sync;
#[cfg(test)]
mod tests;
pub mod vec;

#[cfg(not(test))]
mod std {
    pub use core::ops; // RangeFull
}

#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
pub mod __export {
    pub use core::format_args;
}
<|endoftext|>


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

//! Unsafe casting functions

use mem;
use intrinsics;
use ptr::copy_nonoverlapping_memory;

/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    let mut dest: U = mem::uninit();
    let dest_ptr: *mut u8 = transmute(&mut dest);
    let src_ptr: *u8 = transmute(src);
    copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
    dest
}

/**
 * Move a thing into the void
 *
 * The forget function will take ownership of the provided value but neglect
 * to run any required cleanup or memory-management operations on it.
 */
#[inline]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }

/**
 * Force-increment the reference count on a shared box. If used
 * carelessly, this can leak the box.
 */
#[inline]
pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }

/**
 * Transform a value of one type into a value of another type.
 * Both types must have the same size and alignment.
 *
 * # Example
 *
 * ```rust
 * use std::cast;
 *
 * let v: &[u8] = unsafe { cast::transmute("L") };
 * assert!(v == [76u8]);
 * ```
 */
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
    intrinsics::transmute(thing)
}

/// Coerce an immutable reference to be mutable.
#[inline]
#[deprecated="casting &T to &mut T is undefined behaviour: use Cell<T>, RefCell<T> or Unsafe<T>"]
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }

/// Coerce a reference to have an arbitrary associated lifetime.
#[inline]
pub unsafe fn transmute_lifetime<'a,'b,T>(ptr: &'a T) -> &'b T {
    transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
    transmute(ptr)
}

/// Coerce a mutable reference to have an arbitrary associated lifetime.
#[inline]
pub unsafe fn transmute_mut_lifetime<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
    transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute_lifetime(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
    transmute_mut_lifetime(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
    transmute_lifetime(ptr)
}

/****************************************************************************
 * Tests
 ****************************************************************************/

#[cfg(test)]
mod tests {
    use cast::{bump_box_refcount, transmute};
    use raw;
    use realstd::str::StrAllocating;

    #[test]
    fn test_transmute_copy() {
        assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
    }

    #[test]
    fn test_bump_managed_refcount() {
        unsafe {
            let managed = @"box box box".to_owned();      // refcount 1
            bump_box_refcount(managed);     // refcount 2
            let ptr: *int = transmute(managed); // refcount 2
            let _box1: @~str = ::cast::transmute_copy(&ptr);
            let _box2: @~str = ::cast::transmute_copy(&ptr);
            assert!(*_box1 == "box box box".to_owned());
            assert!(*_box2 == "box box box".to_owned());
            // Will destroy _box1 and _box2. Without the bump, this would
            // use-after-free. With too many bumps, it would leak.
        }
    }

    #[test]
    fn test_transmute() {
        unsafe {
            let x = @100u8;
            let x: *raw::Box<u8> = transmute(x);
            assert!((*x).data == 100);
            let _x: @int = transmute(x);
        }
    }

    #[test]
    fn test_transmute2() {
        unsafe {
            assert_eq!(box [76u8], transmute("L".to_owned()));
        }
    }
}
<commit_msg>std: Remove bump_box_refcount. Deprecated and unused. Deprecused.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Unsafe casting functions

use mem;
use intrinsics;
use ptr::copy_nonoverlapping_memory;

/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    let mut dest: U = mem::uninit();
    let dest_ptr: *mut u8 = transmute(&mut dest);
    let src_ptr: *u8 = transmute(src);
    copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
    dest
}

/**
 * Move a thing into the void
 *
 * The forget function will take ownership of the provided value but neglect
 * to run any required cleanup or memory-management operations on it.
 */
#[inline]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }

/**
 * Transform a value of one type into a value of another type.
 * Both types must have the same size and alignment.
 *
 * # Example
 *
 * ```rust
 * use std::cast;
 *
 * let v: &[u8] = unsafe { cast::transmute("L") };
 * assert!(v == [76u8]);
 * ```
 */
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
    intrinsics::transmute(thing)
}

/// Coerce an immutable reference to be mutable.
#[inline]
#[deprecated="casting &T to &mut T is undefined behaviour: use Cell<T>, RefCell<T> or Unsafe<T>"]
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }

/// Coerce a reference to have an arbitrary associated lifetime.
#[inline]
pub unsafe fn transmute_lifetime<'a,'b,T>(ptr: &'a T) -> &'b T {
    transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
    transmute(ptr)
}

/// Coerce a mutable reference to have an arbitrary associated lifetime.
#[inline]
pub unsafe fn transmute_mut_lifetime<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
    transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute_lifetime(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
    transmute_mut_lifetime(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
    transmute_lifetime(ptr)
}

/****************************************************************************
 * Tests
 ****************************************************************************/

#[cfg(test)]
mod tests {
    use cast::transmute;
    use raw;
    use realstd::str::StrAllocating;

    #[test]
    fn test_transmute_copy() {
        assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
    }

    #[test]
    fn test_transmute() {
        unsafe {
            let x = @100u8;
            let x: *raw::Box<u8> = transmute(x);
            assert!((*x).data == 100);
            let _x: @int = transmute(x);
        }
    }

    #[test]
    fn test_transmute2() {
        unsafe {
            assert_eq!(box [76u8], transmute("L".to_owned()));
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

/*! The Clone trait for types that cannot be "implicitly copied"

In Rust, some simple types are "implicitly copyable" and when you
assign them or pass them as arguments, the receiver will get a copy,
leaving the original value in place. These types do not require
allocation to copy and do not have finalizers (i.e. they do not
contain owned boxes or implement `Drop`), so the compiler considers
them cheap and safe to copy and automatically implements the `Copy`
trait for them. For other types copies must be made explicitly,
by convention implementing the `Clone` trait and calling the
`clone` method.

*/

use core::kinds::Const;

/// A common trait for cloning an object.
pub trait Clone {
    /// Returns a copy of the value. The contents of owned pointers
    /// are copied to maintain uniqueness, while the contents of
    /// managed pointers are not copied.
    fn clone(&self) -> Self;
}

impl<T: Clone> Clone for ~T {
    /// Return a deep copy of the owned box.
    #[inline(always)]
    fn clone(&self) -> ~T { ~(**self).clone() }
}

impl<T> Clone for @T {
    /// Return a shallow copy of the managed box.
    #[inline(always)]
    fn clone(&self) -> @T { *self }
}

impl<T> Clone for @mut T {
    /// Return a shallow copy of the managed box.
    #[inline(always)]
    fn clone(&self) -> @mut T { *self }
}

impl<'self, T> Clone for &'self T {
    /// Return a shallow copy of the borrowed pointer.
    #[inline(always)]
    fn clone(&self) -> &'self T { *self }
}

macro_rules! clone_impl(
    ($t:ty) => {
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline(always)]
            fn clone(&self) -> $t { *self }
        }
    }
)

clone_impl!(int)
clone_impl!(i8)
clone_impl!(i16)
clone_impl!(i32)
clone_impl!(i64)

clone_impl!(uint)
clone_impl!(u8)
clone_impl!(u16)
clone_impl!(u32)
clone_impl!(u64)

clone_impl!(float)
clone_impl!(f32)
clone_impl!(f64)

clone_impl!(())
clone_impl!(bool)
clone_impl!(char)

/// A trait distinct from `Clone` which represents "deep copies" of things like
/// managed boxes which would otherwise not be copied.
pub trait DeepClone {
    /// Return a deep copy of the value. Unlike `Clone`, the contents of shared pointer types
    /// *are* copied. Note that this is currently unimplemented for managed boxes, as
    /// it would need to handle cycles, but it is implemented for other smart-pointer types.
    fn deep_clone(&self) -> Self;
}

impl<T: DeepClone> DeepClone for ~T {
    /// Return a deep copy of the owned box.
    #[inline(always)]
    fn deep_clone(&self) -> ~T { ~(**self).deep_clone() }
}

// FIXME: #6525: should also be implemented for `T: Owned + DeepClone`
impl<T: Const + DeepClone> DeepClone for @T {
    /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
    /// a deep clone of a potentially cyclical type.
    #[inline(always)]
    fn deep_clone(&self) -> @T { @(**self).deep_clone() }
}

// FIXME: #6525: should also be implemented for `T: Owned + DeepClone`
impl<T: Const + DeepClone> DeepClone for @mut T {
    /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
    /// a deep clone of a potentially cyclical type.
    #[inline(always)]
    fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() }
}

macro_rules! deep_clone_impl(
    ($t:ty) => {
        impl DeepClone for $t {
            /// Return a deep copy of the value.
            #[inline(always)]
            fn deep_clone(&self) -> $t { *self }
        }
    }
)

deep_clone_impl!(int)
deep_clone_impl!(i8)
deep_clone_impl!(i16)
deep_clone_impl!(i32)
deep_clone_impl!(i64)

deep_clone_impl!(uint)
deep_clone_impl!(u8)
deep_clone_impl!(u16)
deep_clone_impl!(u32)
deep_clone_impl!(u64)

deep_clone_impl!(float)
deep_clone_impl!(f32)
deep_clone_impl!(f64)

deep_clone_impl!(())
deep_clone_impl!(bool)
deep_clone_impl!(char)

#[test]
fn test_owned_clone() {
    let a = ~5i;
    let b: ~int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_clone() {
    let a = @5i;
    let b: @int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_mut_deep_clone() {
    let x = @mut 5i;
    let y: @mut int = x.deep_clone();
    *x = 20;
    assert_eq!(*y, 5);
}

#[test]
fn test_managed_mut_clone() {
    let a = @mut 5i;
    let b: @mut int = a.clone();
    assert_eq!(a, b);
    *b = 10;
    assert_eq!(a, b);
}

#[test]
fn test_borrowed_clone() {
    let x = 5i;
    let y: &int = &x;
    let z: &int = (&y).clone();
    assert_eq!(*z, 5);
}
<commit_msg>auto merge of #6939 : thestinger/rust/clone, r=catamorphism<commit_after>// Copyright 2012-2013 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.

/*! The Clone trait for types that cannot be "implicitly copied"

In Rust, some simple types are "implicitly copyable" and when you
assign them or pass them as arguments, the receiver will get a copy,
leaving the original value in place. These types do not require
allocation to copy and do not have finalizers (i.e. they do not
contain owned boxes or implement `Drop`), so the compiler considers
them cheap and safe to copy and automatically implements the `Copy`
trait for them. For other types copies must be made explicitly,
by convention implementing the `Clone` trait and calling the
`clone` method.

*/

use core::kinds::Const;

/// A common trait for cloning an object.
pub trait Clone {
    /// Returns a copy of the value. The contents of owned pointers
    /// are copied to maintain uniqueness, while the contents of
    /// managed pointers are not copied.
    fn clone(&self) -> Self;
}

impl<T: Clone> Clone for ~T {
    /// Return a deep copy of the owned box.
    #[inline(always)]
    fn clone(&self) -> ~T { ~(**self).clone() }
}

impl<T> Clone for @T {
    /// Return a shallow copy of the managed box.
    #[inline(always)]
    fn clone(&self) -> @T { *self }
}

impl<T> Clone for @mut T {
    /// Return a shallow copy of the managed box.
    #[inline(always)]
    fn clone(&self) -> @mut T { *self }
}

impl<'self, T> Clone for &'self T {
    /// Return a shallow copy of the borrowed pointer.
    #[inline(always)]
    fn clone(&self) -> &'self T { *self }
}

macro_rules! clone_impl(
    ($t:ty) => {
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline(always)]
            fn clone(&self) -> $t { *self }
        }
    }
)

clone_impl!(int)
clone_impl!(i8)
clone_impl!(i16)
clone_impl!(i32)
clone_impl!(i64)

clone_impl!(uint)
clone_impl!(u8)
clone_impl!(u16)
clone_impl!(u32)
clone_impl!(u64)

clone_impl!(float)
clone_impl!(f32)
clone_impl!(f64)

clone_impl!(())
clone_impl!(bool)
clone_impl!(char)

/// A trait distinct from `Clone` which represents "deep copies" of things like
/// managed boxes which would otherwise not be copied.
pub trait DeepClone {
    /// Return a deep copy of the value. Unlike `Clone`, the contents of shared pointer types
    /// *are* copied.
    fn deep_clone(&self) -> Self;
}

impl<T: DeepClone> DeepClone for ~T {
    /// Return a deep copy of the owned box.
    #[inline(always)]
    fn deep_clone(&self) -> ~T { ~(**self).deep_clone() }
}

// FIXME: #6525: should also be implemented for `T: Owned + DeepClone`
impl<T: Const + DeepClone> DeepClone for @T {
    /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
    /// a deep clone of a potentially cyclical type.
    #[inline(always)]
    fn deep_clone(&self) -> @T { @(**self).deep_clone() }
}

// FIXME: #6525: should also be implemented for `T: Owned + DeepClone`
impl<T: Const + DeepClone> DeepClone for @mut T {
    /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
    /// a deep clone of a potentially cyclical type.
    #[inline(always)]
    fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() }
}

macro_rules! deep_clone_impl(
    ($t:ty) => {
        impl DeepClone for $t {
            /// Return a deep copy of the value.
            #[inline(always)]
            fn deep_clone(&self) -> $t { *self }
        }
    }
)

deep_clone_impl!(int)
deep_clone_impl!(i8)
deep_clone_impl!(i16)
deep_clone_impl!(i32)
deep_clone_impl!(i64)

deep_clone_impl!(uint)
deep_clone_impl!(u8)
deep_clone_impl!(u16)
deep_clone_impl!(u32)
deep_clone_impl!(u64)

deep_clone_impl!(float)
deep_clone_impl!(f32)
deep_clone_impl!(f64)

deep_clone_impl!(())
deep_clone_impl!(bool)
deep_clone_impl!(char)

#[test]
fn test_owned_clone() {
    let a = ~5i;
    let b: ~int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_clone() {
    let a = @5i;
    let b: @int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_mut_deep_clone() {
    let x = @mut 5i;
    let y: @mut int = x.deep_clone();
    *x = 20;
    assert_eq!(*y, 5);
}

#[test]
fn test_managed_mut_clone() {
    let a = @mut 5i;
    let b: @mut int = a.clone();
    assert_eq!(a, b);
    *b = 10;
    assert_eq!(a, b);
}

#[test]
fn test_borrowed_clone() {
    let x = 5i;
    let y: &int = &x;
    let z: &int = (&y).clone();
    assert_eq!(*z, 5);
}
<|endoftext|>


<commit_before>// This example uses get_sock() to find out which file descriptors c-ares
// wants us to listen on, and uses epoll() to satisfy those requirements.
extern crate c_ares;
extern crate nix;

use nix::sys::epoll::{
    epoll_create,
    epoll_ctl,
    epoll_wait,
    EpollEvent,
    EpollEventKind,
    EpollOp,
    EPOLLIN,
    EPOLLOUT,
};
use std::collections::HashSet;
use std::os::unix::io;

fn print_a_results(result: Result<c_ares::AResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("A lookup failed with error '{}'", err_string);
        }
        Ok(a_results) => {
            println!("Successful A lookup...");
            println!("Hostname: {}", a_results.hostname());
            for a_result in &a_results {
                println!("{:}", a_result.ipv4_addr());
            }
        }
    }
}

fn print_aaaa_results(result: Result<c_ares::AAAAResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("AAAA lookup failed with error '{}'", err_string);
        }
        Ok(aaaa_results) => {
            println!("Successful AAAA lookup...");
            println!("Hostname: {}", aaaa_results.hostname());
            for aaaa_result in &aaaa_results {
                println!("{:}", aaaa_result.ipv6_addr());
            }
        }
    }
}

fn print_srv_results(result: Result<c_ares::SRVResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("SRV lookup failed with error '{}'", err_string);
        }
        Ok(srv_results) => {
            println!("Successful SRV lookup...");
            for srv_result in &srv_results {
                println!("host: {} (port: {}), priority: {} weight: {}",
                         srv_result.host(),
                         srv_result.port(),
                         srv_result.weight(),
                         srv_result.priority());
            }
        }
    }
}

fn main() {
    // Create the c_ares::Channel.
    let mut options = c_ares::Options::new();
    options
        .set_flags(c_ares::flags::STAYOPEN)
        .set_timeout(500)
        .set_tries(3);
    let mut ares_channel = c_ares::Channel::new(options)
        .ok()
        .expect("Failed to create channel");

    // Set up some queries.
    ares_channel.query_a("apple.com", move |results| {
        print_a_results(results);
    });

    ares_channel.query_aaaa("google.com", move |results| {
        print_aaaa_results(results);
    });

    ares_channel.query_srv("_xmpp-server._tcp.gmail.com", move |result| {
        print_srv_results(result);
    });

    // Create an epoll file descriptor so that we can listen for events.
    let epoll = epoll_create().ok().expect("Failed to create epoll");
    let mut tracked_fds = HashSet::<io::RawFd>::new();
    loop {
        // Ask c-ares what file descriptors we should be listening on, and map
        // those requests onto the epoll file descriptor.
        let mut active = false;
        for (fd, readable, writable) in ares_channel.get_sock().sockets() {
            let mut interest = EpollEventKind::empty();
            if readable { interest = interest | EPOLLIN; }
            if writable { interest = interest | EPOLLOUT; }
            let event = EpollEvent { events: interest, data: fd as u64 };
            let op = if tracked_fds.insert(fd) {
                EpollOp::EpollCtlAdd
            } else {
                EpollOp::EpollCtlMod
            };
            epoll_ctl(epoll, op, fd, &event).ok().expect("epoll_ctl failed");
            active = true;
        }
        if !active { break }

        // Wait for something to happen.
        let empty_event = EpollEvent {
            events: EpollEventKind::empty(),
            data: 0
        };
        let mut events = [empty_event; 2];
        let results = epoll_wait(epoll, &mut events, 500)
            .ok()
            .expect("epoll_wait failed");

        // Process whatever happened.
        match results {
            0 => {
                // No events - must be a timeout.  Tell c-ares about it.
                ares_channel.process_fd(c_ares::INVALID_FD, c_ares::INVALID_FD);
            },
            n => {
                // Sockets became readable or writable.  Tell c-ares about it.
                for i in 0..n {
                    let event = events[i];
                    let active_fd = event.data as io::RawFd;
                    let readable_fd = if (event.events & EPOLLIN).is_empty() {
                        c_ares::INVALID_FD
                    } else {
                        active_fd
                    };
                    let writable_fd = if (event.events & EPOLLOUT).is_empty() {
                        c_ares::INVALID_FD
                    } else {
                        active_fd
                    };
                    ares_channel.process_fd(readable_fd, writable_fd);
                }
            }
        }
    }
}
<commit_msg>Consistent style<commit_after>// This example uses get_sock() to find out which file descriptors c-ares
// wants us to listen on, and uses epoll() to satisfy those requirements.
extern crate c_ares;
extern crate nix;

use nix::sys::epoll::{
    epoll_create,
    epoll_ctl,
    epoll_wait,
    EpollEvent,
    EpollEventKind,
    EpollOp,
    EPOLLIN,
    EPOLLOUT,
};
use std::collections::HashSet;
use std::os::unix::io;

fn print_a_results(result: Result<c_ares::AResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("A lookup failed with error '{}'", err_string);
        }
        Ok(a_results) => {
            println!("Successful A lookup...");
            println!("Hostname: {}", a_results.hostname());
            for a_result in &a_results {
                println!("{:}", a_result.ipv4_addr());
            }
        }
    }
}

fn print_aaaa_results(result: Result<c_ares::AAAAResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("AAAA lookup failed with error '{}'", err_string);
        }
        Ok(aaaa_results) => {
            println!("Successful AAAA lookup...");
            println!("Hostname: {}", aaaa_results.hostname());
            for aaaa_result in &aaaa_results {
                println!("{:}", aaaa_result.ipv6_addr());
            }
        }
    }
}

fn print_srv_results(result: Result<c_ares::SRVResults, c_ares::AresError>) {
    println!("");
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("SRV lookup failed with error '{}'", err_string);
        }
        Ok(srv_results) => {
            println!("Successful SRV lookup...");
            for srv_result in &srv_results {
                println!("host: {} (port: {}), priority: {} weight: {}",
                         srv_result.host(),
                         srv_result.port(),
                         srv_result.weight(),
                         srv_result.priority());
            }
        }
    }
}

fn main() {
    // Create the c_ares::Channel.
    let mut options = c_ares::Options::new();
    options
        .set_flags(c_ares::flags::STAYOPEN)
        .set_timeout(500)
        .set_tries(3);
    let mut ares_channel = c_ares::Channel::new(options)
        .ok()
        .expect("Failed to create channel");

    // Set up some queries.
    ares_channel.query_a("apple.com", move |results| {
        print_a_results(results);
    });

    ares_channel.query_aaaa("google.com", move |results| {
        print_aaaa_results(results);
    });

    ares_channel.query_srv("_xmpp-server._tcp.gmail.com", move |result| {
        print_srv_results(result);
    });

    // Create an epoll file descriptor so that we can listen for events.
    let epoll = epoll_create().ok().expect("Failed to create epoll");
    let mut tracked_fds = HashSet::<io::RawFd>::new();
    loop {
        // Ask c-ares what file descriptors we should be listening on, and map
        // those requests onto the epoll file descriptor.
        let mut active = false;
        for (fd, readable, writable) in ares_channel.get_sock().sockets() {
            let mut interest = EpollEventKind::empty();
            if readable { interest = interest | EPOLLIN; }
            if writable { interest = interest | EPOLLOUT; }
            let event = EpollEvent {
                events: interest,
                data: fd as u64,
            };
            let op = if tracked_fds.insert(fd) {
                EpollOp::EpollCtlAdd
            } else {
                EpollOp::EpollCtlMod
            };
            epoll_ctl(epoll, op, fd, &event).ok().expect("epoll_ctl failed");
            active = true;
        }
        if !active { break }

        // Wait for something to happen.
        let empty_event = EpollEvent {
            events: EpollEventKind::empty(),
            data: 0,
        };
        let mut events = [empty_event; 2];
        let results = epoll_wait(epoll, &mut events, 500)
            .ok()
            .expect("epoll_wait failed");

        // Process whatever happened.
        match results {
            0 => {
                // No events - must be a timeout.  Tell c-ares about it.
                ares_channel.process_fd(c_ares::INVALID_FD, c_ares::INVALID_FD);
            },
            n => {
                // Sockets became readable or writable.  Tell c-ares about it.
                for i in 0..n {
                    let event = events[i];
                    let active_fd = event.data as io::RawFd;
                    let readable_fd = if (event.events & EPOLLIN).is_empty() {
                        c_ares::INVALID_FD
                    } else {
                        active_fd
                    };
                    let writable_fd = if (event.events & EPOLLOUT).is_empty() {
                        c_ares::INVALID_FD
                    } else {
                        active_fd
                    };
                    ares_channel.process_fd(readable_fd, writable_fd);
                }
            }
        }
    }
}
<|endoftext|>


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

//! Implementation for WASM via stdweb
extern crate std;
#[macro_use] extern crate stdweb;

use core::cell::RefCell;
use core::mem;
use core::num::NonZeroU32;
use std::thread_local;

use stdweb::unstable::TryInto;
use stdweb::web::error::Error as WebError;

use crate::Error;
use crate::utils::use_init;

#[derive(Clone, Debug)]
enum RngSource {
    Browser,
    Node
}

thread_local!(
    static RNG_SOURCE: RefCell<Option<RngSource>> = RefCell::new(None);
);

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    assert_eq!(mem::size_of::<usize>(), 4);

    RNG_SOURCE.with(|f| {
        use_init(f, getrandom_init, |source| getrandom_fill(source, dest))
    })

}

fn getrandom_init() -> Result<RngSource, Error> {
    let result = js! {
        try {
            if (
                typeof self === "object" &&
                typeof self.crypto === "object" &&
                typeof self.crypto.getRandomValues === "function"
            ) {
                return { success: true, ty: 1 };
            }

            if (typeof require("crypto").randomBytes === "function") {
                return { success: true, ty: 2 };
            }

            return { success: false, error: new Error("not supported") };
        } catch(err) {
            return { success: false, error: err };
        }
    };

    if js!{ return @{ result.as_ref() }.success } == true {
        let ty = js!{ return @{ result }.ty };

        if ty == 1 { Ok(RngSource::Browser) }
        else if ty == 2 { Ok(RngSource::Node) }
        else { unreachable!() }
    } else {
        let err: WebError = js!{ return @{ result }.error }.try_into().unwrap();
        error!("getrandom unavailable: {}", err);
        Err(Error::UNAVAILABLE)
    }
}

fn getrandom_fill(source: &mut RngSource, dest: &mut [u8]) -> Result<(), Error> {
    for chunk in dest.chunks_mut(65536) {
        let len = chunk.len() as u32;
        let ptr = chunk.as_mut_ptr() as i32;

        let result = match source {
            RngSource::Browser => js! {
                try {
                    let array = new Uint8Array(@{ len });
                    self.crypto.getRandomValues(array);
                    HEAPU8.set(array, @{ ptr });

                    return { success: true };
                } catch(err) {
                    return { success: false, error: err };
                }
            },
            RngSource::Node => js! {
                try {
                    let bytes = require("crypto").randomBytes(@{ len });
                    HEAPU8.set(new Uint8Array(bytes), @{ ptr });

                    return { success: true };
                } catch(err) {
                    return { success: false, error: err };
                }
            }
        };

        if js!{ return @{ result.as_ref() }.success } != true {
            let err: WebError = js!{ return @{ result }.error }.try_into().unwrap();
            error!("getrandom failed: {}", err);
            return Err(Error::UNKNOWN)
        }
    }
    Ok(())
}

#[inline(always)]
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }
<commit_msg>import js macro<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for WASM via stdweb
extern crate std;

use core::cell::RefCell;
use core::mem;
use core::num::NonZeroU32;
use std::thread_local;

use stdweb::js;
use stdweb::unstable::TryInto;
use stdweb::web::error::Error as WebError;

use crate::Error;
use crate::utils::use_init;

#[derive(Clone, Debug)]
enum RngSource {
    Browser,
    Node
}

thread_local!(
    static RNG_SOURCE: RefCell<Option<RngSource>> = RefCell::new(None);
);

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    assert_eq!(mem::size_of::<usize>(), 4);

    RNG_SOURCE.with(|f| {
        use_init(f, getrandom_init, |source| getrandom_fill(source, dest))
    })

}

fn getrandom_init() -> Result<RngSource, Error> {
    let result = js! {
        try {
            if (
                typeof self === "object" &&
                typeof self.crypto === "object" &&
                typeof self.crypto.getRandomValues === "function"
            ) {
                return { success: true, ty: 1 };
            }

            if (typeof require("crypto").randomBytes === "function") {
                return { success: true, ty: 2 };
            }

            return { success: false, error: new Error("not supported") };
        } catch(err) {
            return { success: false, error: err };
        }
    };

    if js!{ return @{ result.as_ref() }.success } == true {
        let ty = js!{ return @{ result }.ty };

        if ty == 1 { Ok(RngSource::Browser) }
        else if ty == 2 { Ok(RngSource::Node) }
        else { unreachable!() }
    } else {
        let err: WebError = js!{ return @{ result }.error }.try_into().unwrap();
        error!("getrandom unavailable: {}", err);
        Err(Error::UNAVAILABLE)
    }
}

fn getrandom_fill(source: &mut RngSource, dest: &mut [u8]) -> Result<(), Error> {
    for chunk in dest.chunks_mut(65536) {
        let len = chunk.len() as u32;
        let ptr = chunk.as_mut_ptr() as i32;

        let result = match source {
            RngSource::Browser => js! {
                try {
                    let array = new Uint8Array(@{ len });
                    self.crypto.getRandomValues(array);
                    HEAPU8.set(array, @{ ptr });

                    return { success: true };
                } catch(err) {
                    return { success: false, error: err };
                }
            },
            RngSource::Node => js! {
                try {
                    let bytes = require("crypto").randomBytes(@{ len });
                    HEAPU8.set(new Uint8Array(bytes), @{ ptr });

                    return { success: true };
                } catch(err) {
                    return { success: false, error: err };
                }
            }
        };

        if js!{ return @{ result.as_ref() }.success } != true {
            let err: WebError = js!{ return @{ result }.error }.try_into().unwrap();
            error!("getrandom failed: {}", err);
            return Err(Error::UNKNOWN)
        }
    }
    Ok(())
}

#[inline(always)]
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }
<|endoftext|>


<commit_before>fn main() {
    example::main();
}

#[cfg(feature = "security")]
mod example {
    extern crate openssl;
    extern crate kafka;
    extern crate getopts;
    extern crate env_logger;

    use std::env;
    use std::process;

    use self::kafka::client::{KafkaClient, SecurityConfig};

    use self::openssl::ssl::{SslContext, SslMethod, SSL_VERIFY_PEER};
    use self::openssl::x509::X509FileType;

    pub fn main() {
        env_logger::init().unwrap();

        // ~ parse the command line arguments
        let cfg = match Config::from_cmdline() {
            Ok(cfg) => cfg,
            Err(e) => {
                println!("{}", e);
                process::exit(1);
            }
        };

        // ~ OpenSSL offers a variety of complex configurations. Here is an example:
        let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
        ctx.set_cipher_list("DEFAULT").unwrap();
        ctx.set_verify(SSL_VERIFY_PEER);
        if let Some(ccert) = cfg.client_cert {
            ctx.set_certificate_file(ccert, X509FileType::PEM).unwrap();
        }
        if let Some(ckey) = cfg.client_key {
            ctx.set_private_key_file(ckey, X509FileType::PEM).unwrap();
        }
        if let Some(ca_cert) = cfg.ca_cert {
            ctx.set_CA_file(ca_cert).unwrap();
        } else {
            // ~ allow client specify the CAs through the default paths:
            // "These locations are read from the SSL_CERT_FILE and
            // SSL_CERT_DIR environment variables if present, or defaults
            // specified at OpenSSL build time otherwise."
            ctx.set_default_verify_paths().unwrap();
        }

        // ~ instantiate KafkaClient with the previous OpenSSL setup
        let mut client = KafkaClient::new_secure(cfg.brokers, SecurityConfig::new(ctx));

        // ~ communicate with the brokers
        match client.load_metadata_all() {
            Err(e) => {
                println!("{:?}", e);
                drop(client);
                process::exit(1);
            }
            Ok(_) => {
                let topics = client.topics();
                if topics.len() == 0 {
                    println!("No topics available!");
                } else {
                    println!("Available topic(s):");
                    for topic in client.topics().names() {
                        println!("\t{}", topic);
                    }
                }
            }
        }
    }

    struct Config {
        brokers: Vec<String>,
        client_cert: Option<String>,
        client_key: Option<String>,
        ca_cert: Option<String>,
    }

    impl Config {
        fn from_cmdline() -> Result<Config, String> {
            let mut opts = getopts::Options::new();
            opts.optflag("h", "help", "Print this help screen");
            opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
            opts.optopt("", "ca-cert", "Specify the trusted CA certificates", "FILE");
            opts.optopt("", "client-cert", "Specify the client certificate", "FILE");
            opts.optopt("", "client-key", "Specify key for the client certificate", "FILE");

            let args: Vec<_> = env::args().collect();
            let m = match opts.parse(&args[1..]) {
                Ok(m) => m,
                Err(e) => return Err(format!("{}", e)),
            };

            if m.opt_present("help") {
                let brief = format!("{} [options]", args[0]);
                return Err(opts.usage(&brief));
            };

            let brokers = m.opt_str("brokers")
                .map(|s| {
                    s.split(',')
                        .map(|s| s.trim().to_owned())
                        .filter(|s| !s.is_empty())
                        .collect()
                })
                .unwrap_or_else(|| vec!["localhost:9092".into()]);
            if brokers.is_empty() {
                return Err("Invalid --brokers specified!".to_owned());
            }

            Ok(Config {
                brokers: brokers,
                client_cert: m.opt_str("client-cert"),
                client_key: m.opt_str("client-key"),
                ca_cert: m.opt_str("ca-cert"),
            })
        }
    }
}

#[cfg(not(feature = "security"))]
mod example {
    use std::process;

    pub fn main() {
        println!("example relevant only with the \"security\" feature enabled!");
        process::exit(1);
    }
}
<commit_msg>Contact all brokers through example/example-ssl.rs<commit_after>fn main() {
    example::main();
}

#[cfg(feature = "security")]
mod example {
    extern crate openssl;
    extern crate kafka;
    extern crate getopts;
    extern crate env_logger;

    use std::env;
    use std::process;

    use self::kafka::client::{FetchOffset, KafkaClient, SecurityConfig};

    use self::openssl::ssl::{SslContext, SslMethod, SSL_VERIFY_PEER};
    use self::openssl::x509::X509FileType;

    pub fn main() {
        env_logger::init().unwrap();

        // ~ parse the command line arguments
        let cfg = match Config::from_cmdline() {
            Ok(cfg) => cfg,
            Err(e) => {
                println!("{}", e);
                process::exit(1);
            }
        };

        // ~ OpenSSL offers a variety of complex configurations. Here is an example:
        let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
        ctx.set_cipher_list("DEFAULT").unwrap();
        ctx.set_verify(SSL_VERIFY_PEER);
        if let Some(ccert) = cfg.client_cert {
            ctx.set_certificate_file(ccert, X509FileType::PEM).unwrap();
        }
        if let Some(ckey) = cfg.client_key {
            ctx.set_private_key_file(ckey, X509FileType::PEM).unwrap();
        }
        if let Some(ca_cert) = cfg.ca_cert {
            ctx.set_CA_file(ca_cert).unwrap();
        } else {
            // ~ allow client specify the CAs through the default paths:
            // "These locations are read from the SSL_CERT_FILE and
            // SSL_CERT_DIR environment variables if present, or defaults
            // specified at OpenSSL build time otherwise."
            ctx.set_default_verify_paths().unwrap();
        }

        // ~ instantiate KafkaClient with the previous OpenSSL setup
        let mut client = KafkaClient::new_secure(cfg.brokers, SecurityConfig::new(ctx));

        // ~ communicate with the brokers
        match client.load_metadata_all() {
            Err(e) => {
                println!("{:?}", e);
                drop(client);
                process::exit(1);
            }
            Ok(_) => {
                // ~ at this point we have successfully loaded
                // metadata via a secured connection to one of the
                // specified brokers

                if client.topics().len() == 0 {
                    println!("No topics available!");
                } else {
                    // ~ now let's communicate with all the brokers in
                    // the cluster our topics are spread over

                    let topics: Vec<String> = client.topics().names().map(Into::into).collect();
                    match client.fetch_offsets(topics.as_slice(), FetchOffset::Latest) {
                        Err(e) => {
                            println!("{:?}", e);
                            drop(client);
                            process::exit(1);
                        }
                        Ok(toffsets) => {
                            println!("Topic offsets:");
                            for (topic, mut offs) in toffsets {
                                offs.sort_by_key(|x| x.partition);
                                println!("{}", topic);
                                for off in offs {
                                    println!("\t{}: {:?}", off.partition, off.offset);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    struct Config {
        brokers: Vec<String>,
        client_cert: Option<String>,
        client_key: Option<String>,
        ca_cert: Option<String>,
    }

    impl Config {
        fn from_cmdline() -> Result<Config, String> {
            let mut opts = getopts::Options::new();
            opts.optflag("h", "help", "Print this help screen");
            opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
            opts.optopt("", "ca-cert", "Specify the trusted CA certificates", "FILE");
            opts.optopt("", "client-cert", "Specify the client certificate", "FILE");
            opts.optopt("", "client-key", "Specify key for the client certificate", "FILE");

            let args: Vec<_> = env::args().collect();
            let m = match opts.parse(&args[1..]) {
                Ok(m) => m,
                Err(e) => return Err(format!("{}", e)),
            };

            if m.opt_present("help") {
                let brief = format!("{} [options]", args[0]);
                return Err(opts.usage(&brief));
            };

            let brokers = m.opt_str("brokers")
                .map(|s| {
                    s.split(',')
                        .map(|s| s.trim().to_owned())
                        .filter(|s| !s.is_empty())
                        .collect()
                })
                .unwrap_or_else(|| vec!["localhost:9092".into()]);
            if brokers.is_empty() {
                return Err("Invalid --brokers specified!".to_owned());
            }

            Ok(Config {
                brokers: brokers,
                client_cert: m.opt_str("client-cert"),
                client_key: m.opt_str("client-key"),
                ca_cert: m.opt_str("ca-cert"),
            })
        }
    }
}

#[cfg(not(feature = "security"))]
mod example {
    use std::process;

    pub fn main() {
        println!("example relevant only with the \"security\" feature enabled!");
        process::exit(1);
    }
}
<|endoftext|>