<commit_before>#![crate_name = "raft"]
#![crate_type="lib"]

#![allow(unstable)]
extern crate "rustc-serialize" as rustc_serialize;

use std::io::net::ip::SocketAddr;
use std::io::net::udp::UdpSocket;
use std::thread::Thread;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::str;
use rustc_serialize::{json, Encodable, Decodable};
use RemoteProcedureCall::{AppendEntries, RequestVote};

// The maximum size of the read buffer.
const BUFFER_SIZE: usize = 4096;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
pub trait Raft<T: Encodable + Decodable + Send + Clone> {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<T>,
                      leader_commit: usize) -> (usize, bool);

    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool);
}

/// A `RaftNode` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
pub struct RaftNode<T: Encodable + Decodable + Send + Clone> {
    // Raft related.
    state: NodeState,
    persistent_state: PersistentState<T>,
    volatile_state: VolatileState,
    // Auxilary Data.
    // TODO: This should probably be split off.
    // All nodes need to know this otherwise they can't effectively lead or hold elections.
    known_nodes: Vec<SocketAddr>,
    own_socket: SocketAddr,
}

/// The implementation of the RaftNode. In most use cases, creating a `RaftNode` should just be
/// done via `::new()`.
///
/// ```
/// use raft::RaftNode;
/// use std::io::net::ip::SocketAddr;
/// use std::io::net::ip::IpAddr::Ipv4Addr;
///
/// let my_node = RaftNode::<String>::new(
///     // This node's address.
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 },
///     // The list of nodes.
///     vec![
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 },
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11113 }
///     ]);
/// ```
impl<T: Encodable + Decodable + Send + Clone> RaftNode<T> {
    /// Creates a new RaftNode with the neighbors specified.
    pub fn new(own_socket: SocketAddr, node_list: Vec<SocketAddr>) -> RaftNode<T> {
        RaftNode {
            state: NodeState::Follower,
            persistent_state: PersistentState {
                current_term: 0, // TODO: Double Check.
                voted_for: 0,    // TODO: Better type?
                log: Vec::<T>::new(),
            },
            volatile_state: VolatileState {
                commit_index: 0,
                last_applied: 0,
            },
            known_nodes: node_list,
            own_socket: own_socket,
        }
    }
    /// Spins up a thread that listens and handles RPCs.
    pub fn spinup(&self) -> (Sender<(RemoteProcedureCall<T>, SocketAddr)>, Receiver<T>) {
        let (entry_sender, entry_reciever) = channel::<T>();
        let (rpc_sender, rpc_reciever) = channel::<(RemoteProcedureCall<T>, SocketAddr)>();
        // Need to clone the SocketAddr for lifetime reasons.
        let mut socket = UdpSocket::bind(self.own_socket)
            .unwrap(); // TODO: Can we do better?
        socket.set_read_timeout(Some(0));
        Thread::spawn(move || {
            let mut read_buffer = [0; BUFFER_SIZE];
            loop {
                // Read anything from the socket and handle it.
                match socket.recv_from(&mut read_buffer) {
                    Ok((num_read, source)) => {
                        let string_slice = str::from_utf8(read_buffer.slice_to_mut(num_read))
                            .unwrap(); // TODO: Can we do better?
                        let mut rpc = json::decode::<RemoteProcedureCall<T>>(string_slice)
                            .unwrap(); // TODO: Can we do better?
                        match rpc {
                            AppendEntries { entries: mut entries, .. } => {
                                // TODO: Log data properly.
                                for entry in entries.iter_mut() {
                                    entry_sender.send(entry.clone());
                                }
                            },
                            RequestVote { .. } => {
                                // TODO: Do something.
                            },
                        }
                    },
                    // TODO: Maybe need to handle this better.
                    Err(_) => (),
                }
                // Write anything in the channel out to the network.
                match rpc_reciever.try_recv() {
                    Ok((rpc, target)) => {
                        println!("Sending things!");
                        let encoded = json::encode::<RemoteProcedureCall<T>>(&rpc);
                        socket.send_to(encoded.as_bytes(), target)
                            .unwrap(); // TODO: Can we do better?
                    },
                    // TODO: Maybe need to handle this better.
                    Err(_) => (),
                }
            }
        });
        (rpc_sender, entry_reciever)
    }
}

/// The RPC calls required by the Raft protocol.
impl<T: Encodable + Decodable + Send + Clone> Raft<T> for RaftNode<T> {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<T>,
                      leader_commit: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
}

/// Data interchange format for RPC calls.
#[derive(RustcEncodable, RustcDecodable, Show, Clone)]
pub enum RemoteProcedureCall<T> {
    AppendEntries {
        term: usize,
        leader_id: usize,
        prev_log_index: usize,
        entries: Vec<T>,
        leader_commit: usize,
    },
    RequestVote {
        term: usize,
        candidate_id: usize,
        last_log_index: usize,
        last_log_term: usize,
    },
}

/// Nodes can either be:
///
///   * A `Follower`, which replicates AppendEntries requests and votes for it's leader.
///   * A `Leader`, which leads the cluster by serving incoming requests, ensuring data is
///     replicated, and issuing heartbeats..
///   * A `Candidate`, which campaigns in an election and may become a `Leader` (if it gets enough
///     votes) or a `Follower`, if it hears from a `Leader`.
pub enum NodeState {
    Follower,
    Leader(LeaderState),
    Candidate,
}

/// Persistent state
/// **Must be updated to stable storage before RPC response.**
pub struct PersistentState<T: Encodable + Decodable + Send + Clone> {
    current_term: usize,
    voted_for: usize, // Better way? Can we use a IpAddr?
    log: Vec<T>,
}

/// Volatile state
pub struct VolatileState {
    commit_index: usize,
    last_applied: usize
}

/// Leader Only
/// **Reinitialized after election.**
pub struct LeaderState {
    next_index: Vec<usize>,
    match_index: Vec<usize>
}

#[cfg(test)]
mod tests {
    use std::io::net::ip::SocketAddr;
    use std::io::net::udp::UdpSocket;
    use std::io::net::ip::IpAddr::Ipv4Addr;
    use std::thread::Thread;
    use rustc_serialize::json;
    use std::sync::mpsc::{channel, Sender, Receiver};
    use std::str;
    use super::*;

    #[test]
    fn basic_test() {
        let send_addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 };
        let recieve_addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 };
        // Create the node.
        let send_node = RaftNode::<String>::new(
            send_addr, // The node's address.
            vec![
            recieve_addr, // The neighbor.
            ]);
        let recieve_node = RaftNode::<String>::new(
            recieve_addr, // The node's address.
            vec![
            send_addr, // The neighbor.
            ]);
        // Start up the node.
        let (_, log_reciever) = recieve_node.spinup();
        let (rpc_sender, _) = send_node.spinup();
        // Make a test send to that port.
        let test_value = RemoteProcedureCall::AppendEntries {
            term: 0,
            leader_id: 0,
            prev_log_index: 0,
            entries: vec!["foo".to_string()],
            leader_commit: 0,
        };
        rpc_sender.send((test_value.clone(), recieve_addr)).unwrap();
        // Get the result.
        let event = log_reciever.recv().unwrap();
        assert_eq!(event, "foo".to_string());
    }

}
<commit_msg>Better threading and timer setting.<commit_after>#![crate_name = "raft"]
#![crate_type="lib"]

#![allow(unstable)]
extern crate "rustc-serialize" as rustc_serialize;

use std::io::net::ip::SocketAddr;
use std::io::net::udp::UdpSocket;
use std::io::timer::Timer;
use std::time::Duration;
use std::thread::Thread;
use std::rand::{thread_rng, Rng};
use std::sync::mpsc::{channel, Sender, Receiver};
use std::str;
use rustc_serialize::{json, Encodable, Decodable};
use RemoteProcedureCall::{AppendEntries, RequestVote};

// The maximum size of the read buffer.
const BUFFER_SIZE: usize = 4096;
const HEARTBEAT_MIN: i64 = 150;
const HEARTBEAT_MAX: i64 = 300;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
pub trait Raft<T: Encodable + Decodable + Send + Clone> {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<T>,
                      leader_commit: usize) -> (usize, bool);

    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool);
}

/// A `RaftNode` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
pub struct RaftNode<T: Encodable + Decodable + Send + Clone> {
    // Raft related.
    state: NodeState,
    persistent_state: PersistentState<T>,
    volatile_state: VolatileState,
    // Auxilary Data.
    // TODO: This should probably be split off.
    // All nodes need to know this otherwise they can't effectively lead or hold elections.
    known_nodes: Vec<SocketAddr>,
    leader_node: Option<SocketAddr>,
    own_socket: SocketAddr,
    heartbeat: Timer,
}

/// The implementation of the RaftNode. In most use cases, creating a `RaftNode` should just be
/// done via `::new()`.
///
/// ```
/// use raft::RaftNode;
/// use std::io::net::ip::SocketAddr;
/// use std::io::net::ip::IpAddr::Ipv4Addr;
///
/// let my_node = RaftNode::<String>::new(
///     // This node's address.
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 },
///     // The list of nodes.
///     vec![
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 },
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11113 }
///     ]);
/// ```
impl<T: Encodable + Decodable + Send + Clone> RaftNode<T> {
    /// Creates a new RaftNode with the neighbors specified.
    pub fn new(own_socket: SocketAddr, node_list: Vec<SocketAddr>) -> RaftNode<T> {
        RaftNode {
            state: NodeState::Follower,
            persistent_state: PersistentState {
                current_term: 0, // TODO: Double Check.
                voted_for: 0,    // TODO: Better type?
                log: Vec::<T>::new(),
            },
            volatile_state: VolatileState {
                commit_index: 0,
                last_applied: 0,
            },
            known_nodes: node_list,
            leader_node: None,
            own_socket: own_socket,
            // Blank timer for now.
            heartbeat: Timer::new().unwrap(), // If this fails we're in trouble.
        }
    }
    /// Spins up a thread that listens and handles RPCs.
    pub fn spinup(mut self) -> (Sender<T>, Receiver<T>) {
        let (client_in, node_out) = channel::<T>();
        let (node_in, client_out) = channel::<T>();
        // Need to clone the SocketAddr for lifetime reasons.
        Thread::spawn(move || {
            // Setup the socket, make it not block.
            let mut socket = UdpSocket::bind(self.own_socket)
                .unwrap(); // TODO: Can we do better?
            socket.set_read_timeout(Some(0));
            // Start up a RNG.
            let mut rng = thread_rng();
            self.heartbeat.oneshot(Duration::milliseconds(rng.gen_range::<i64>(HEARTBEAT_MIN, HEARTBEAT_MAX)));
            // We need a read buffer.
            let mut read_buffer = [0; BUFFER_SIZE];
            loop {
                // Read anything from the socket and handle it.
                match socket.recv_from(&mut read_buffer) {
                    Ok((num_read, source)) => {
                        println!("Got something from socket");
                        let string_slice = str::from_utf8(read_buffer.slice_to_mut(num_read))
                            .unwrap(); // TODO: Can we do better?
                        let mut rpc = json::decode::<RemoteProcedureCall<T>>(string_slice)
                            .unwrap(); // TODO: Can we do better?
                        match rpc {
                            AppendEntries { entries: mut entries, .. } => {
                                // TODO: Log data properly.
                                for entry in entries.iter_mut() {
                                    node_in.send(entry.clone());
                                }
                            },
                            RequestVote { .. } => {
                                // TODO: Do something.
                            },
                        }
                    },
                    // TODO: Maybe need to handle this better.
                    Err(_) => (),
                }
                // If there is something in the reciever we need to handle it.
                match (node_out.try_recv(), &self.state) {
                    (Ok(entry), &NodeState::Leader(_)) => {
                        println!("Sending things!");
                        let rpc = AppendEntries {
                            term: 0,
                            leader_id: 0,
                            prev_log_index: 0,
                            entries: vec![entry],
                            leader_commit: 0,
                        };
                        let encoded = json::encode::<RemoteProcedureCall<T>>(&rpc);
                        for node in self.known_nodes.iter() {
                            socket.send_to(encoded.as_bytes(), *node)
                                .unwrap(); // TODO: Can we do better?
                        }
                    },
                    // Need to deal with election issues.
                    (Ok(entry), _) => {
                        println!("Got entry, not leader");
                    },
                    // TODO: Maybe need to handle this better.
                    (Err(_), _) => (),
                }
            }
        });
        (client_in, client_out)
    }
}

/// The RPC calls required by the Raft protocol.
impl<T: Encodable + Decodable + Send + Clone> Raft<T> for RaftNode<T> {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<T>,
                      leader_commit: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
}

/// Data interchange format for RPC calls.
#[derive(RustcEncodable, RustcDecodable, Show, Clone)]
pub enum RemoteProcedureCall<T> {
    AppendEntries {
        term: usize,
        leader_id: usize,
        prev_log_index: usize,
        entries: Vec<T>,
        leader_commit: usize,
    },
    RequestVote {
        term: usize,
        candidate_id: usize,
        last_log_index: usize,
        last_log_term: usize,
    },
}

/// Nodes can either be:
///
///   * A `Follower`, which replicates AppendEntries requests and votes for it's leader.
///   * A `Leader`, which leads the cluster by serving incoming requests, ensuring data is
///     replicated, and issuing heartbeats..
///   * A `Candidate`, which campaigns in an election and may become a `Leader` (if it gets enough
///     votes) or a `Follower`, if it hears from a `Leader`.
pub enum NodeState {
    Follower,
    Leader(LeaderState),
    Candidate,
}

/// Persistent state
/// **Must be updated to stable storage before RPC response.**
pub struct PersistentState<T: Encodable + Decodable + Send + Clone> {
    current_term: usize,
    voted_for: usize, // Better way? Can we use a IpAddr?
    log: Vec<T>,
}

/// Volatile state
pub struct VolatileState {
    commit_index: usize,
    last_applied: usize
}

/// Leader Only
/// **Reinitialized after election.**
pub struct LeaderState {
    next_index: Vec<usize>,
    match_index: Vec<usize>
}

#[cfg(test)]
mod tests {
    use std::io::net::ip::SocketAddr;
    use std::io::net::udp::UdpSocket;
    use std::io::net::ip::IpAddr::Ipv4Addr;
    use std::thread::Thread;
    use rustc_serialize::json;
    use std::sync::mpsc::{channel, Sender, Receiver};
    use std::str;
    use super::*;

    #[test]
    fn basic_test() {
        let send_addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 };
        let recieve_addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 };
        // Create the node.
        let send_node = RaftNode::<String>::new(
            send_addr, // The node's address.
            vec![
            recieve_addr, // The neighbor.
            ]);
        let recieve_node = RaftNode::<String>::new(
            recieve_addr, // The node's address.
            vec![
            send_addr, // The neighbor.
            ]);
        // Start up the node.
        let (_, log_reciever) = recieve_node.spinup();
        let (log_sender, _) = send_node.spinup();
        // Make a test send to that port.
        let test_value = "foo".to_string();
        println!("About to send");
        log_sender.send(test_value.clone()).unwrap();
        println!("After send!");
        // Get the result.
        let event = log_reciever.recv().unwrap();
        assert_eq!(event, "foo".to_string());
    }

}
<|endoftext|>


<commit_before>// Copyright 2015-2016 Nikita Pekin and the tcod_window contributors
// See the README.md file at the top-level directory of this distribution.
//
// 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.

#![deny(missing_docs)]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

//! This crate provides a TCOD back-end for the Piston game engine.
//!
//! # Example
//!
//! The following example shows a quick example of the basic functionality of
//! `TcodWindow`.
//!
//! ```
//! extern crate piston;
//! extern crate tcod_window;
//!
//! use piston::window::{Size, WindowSettings};
//! use tcod_window::TcodWindow;
//!
//! fn main() {
//!     let mut window = TcodWindow::new(
//!         WindowSettings::new(
//!             "My Application".to_owned(),
//!             Size {
//!                 width: 100,
//!                 height: 100,
//!             }
//!         )
//!     );
//! }
//! ```

extern crate input;
#[macro_use]
extern crate tcod;
extern crate window;

use std::cell::RefCell;
use std::rc::Rc;

use input::{Input, MouseButton};
use input::keyboard::Key as PistonKey;
use tcod::input::{Key as TcodKey, KeyCode, Mouse};
use tcod::Console;
use tcod::console::Root;
use window::{AdvancedWindow, BuildFromWindowSettings, Size, Window, WindowSettings};

/// A window implemented by a TCOD back-end.
pub struct TcodWindow {
    /// TCOD `Root` window used for rendering.
    pub window: Rc<RefCell<Root>>,
    title: String,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    mouse_state_prev: Mouse,
    exit_on_esc: bool,
}

impl TcodWindow {
    /// Create a new game window from the provided `WindowSettings`.
    ///
    /// Internally, it initializes a new TCOD `Root` with the size and title
    /// specified in the `WindowSettings`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate piston;
    /// # extern crate tcod_window;
    /// #
    /// use piston::window::{Size, WindowSettings};
    /// use tcod_window::TcodWindow;
    ///
    /// # fn main() {
    /// let mut window = TcodWindow::new(
    ///     WindowSettings::new(
    ///         "My Application".to_owned(),
    ///         Size {
    ///             width: 100,
    ///             height: 100,
    ///         }
    ///     )
    /// );
    /// # }
    /// ```
    pub fn new(settings: WindowSettings) -> Self {
        let console = Root::initializer()
                          .size(settings.get_size().width as i32,
                                settings.get_size().height as i32)
                          .title(settings.get_title())
                          .init();
        let console = Rc::new(RefCell::new(console));

        Self::with_console(console, settings)
    }

    /// Create a new game window from an existing TCOD `Root` console wrapped as
    /// an `Rc<RefCell<Root>>`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate piston;
    /// # extern crate tcod;
    /// # extern crate tcod_window;
    /// #
    /// use std::cell::RefCell;
    /// use std::rc::Rc;
    /// #
    /// use piston::window::{Size, WindowSettings};
    /// use tcod::console::Root;
    /// use tcod_window::TcodWindow;
    ///
    /// # fn main() {
    /// let settings =WindowSettings::new(
    ///     "My Application".to_owned(),
    ///     Size {
    ///         width: 100,
    ///         height: 100,
    ///     }
    /// );
    /// let root = Root::initializer()
    ///                 .size(settings.get_size().width as i32,
    ///                       settings.get_size().height as i32)
    ///                 .title(settings.get_title())
    ///                 .init();
    /// let console = Rc::new(RefCell::new(root));
    ///
    /// let mut window = TcodWindow::with_console(console, settings);
    /// # }
    /// ```
    pub fn with_console(console: Rc<RefCell<Root>>, settings: WindowSettings) -> Self {
        TcodWindow {
            window: console,
            title: settings.get_title(),
            should_close: false,
            mouse_relative: None,
            mouse_state_prev: Mouse::default(),
            exit_on_esc: settings.get_exit_on_esc(),
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use input::{Button, Motion};
        use input::Input::{Move, Press, Release};
        use tcod::input::{ANY, KEY_PRESS, KEY_RELEASE, MOUSE_MOVE, MOUSE_PRESS, MOUSE_RELEASE,
                          check_for_event};
        use tcod::input::Event::{Key, Mouse};

        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Move(Motion::MouseRelative(x, y)));
        }

        match check_for_event(ANY) {
            Some((KEY_PRESS, Key(ref key_state))) => {
                if self.exit_on_esc && key_state.code == KeyCode::Escape {
                    self.should_close = true;
                    None
                } else {
                    Some(Press(Button::Keyboard(tcod_map_key(*key_state))))
                }
            },
            Some((KEY_RELEASE, Key(ref key_state))) => {
                Some(Release(Button::Keyboard(tcod_map_key(*key_state))))
            },
            Some((MOUSE_PRESS, Mouse(ref mouse_state))) => {
                let button = tcod_map_mouse(self.mouse_state_prev, mouse_state);
                self.mouse_state_prev = *mouse_state;
                Some(Press(Button::Mouse(button)))
            },
            Some((MOUSE_RELEASE, Mouse(ref mouse_state))) => {
                let button = tcod_map_mouse(self.mouse_state_prev, mouse_state);
                self.mouse_state_prev = *mouse_state;
                Some(Release(Button::Mouse(button)))
            },
            Some((MOUSE_MOVE, Mouse(ref mouse_state))) => {
                self.mouse_relative = Some(((mouse_state.x - self.mouse_state_prev.x) as f64,
                                            (mouse_state.y - self.mouse_state_prev.y) as f64));
                self.mouse_state_prev = *mouse_state;
                Some(Move(Motion::MouseCursor(mouse_state.x as f64, mouse_state.y as f64)))
            },
            _ => None,
        }
    }
}

impl BuildFromWindowSettings for TcodWindow {
    fn build_from_window_settings(settings: WindowSettings) -> Result<Self, String> {
        Ok(TcodWindow::new(settings))
    }
}

impl Window for TcodWindow {
    type Event = Input;

    fn should_close(&self) -> bool {
        self.should_close
    }
    fn set_should_close(&mut self, value: bool) {
        self.should_close = value;
    }
    fn swap_buffers(&mut self) {
        self.window.borrow_mut().flush();
    }
    fn size(&self) -> Size {
        let window = self.window.borrow();
        Size {
            width: window.width() as u32,
            height: window.height() as u32,
        }
    }
    fn poll_event(&mut self) -> Option<Input> {
        self.poll_event()
    }
    fn draw_size(&self) -> Size {
        let window = self.window.borrow();
        Size {
            width: window.width() as u32,
            height: window.height() as u32,
        }
    }
}

impl AdvancedWindow for TcodWindow {
    fn get_title(&self) -> String {
        self.title.clone()
    }
    fn set_title(&mut self, value: String) {
        self.window.borrow_mut().set_window_title(&value);
        self.title = value
    }
    fn get_exit_on_esc(&self) -> bool {
        self.exit_on_esc
    }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value;
    }
    fn set_capture_cursor(&mut self, _value: bool) {}
}

/// Maps a TCOD key to a piston-input key.
///
/// # Examples
///
/// ```
/// # extern crate piston;
/// # extern crate tcod;
/// # extern crate tcod_window;
/// #
/// use piston::input::Key as PistonKey;
/// use tcod::input::{Key, KeyCode};
/// use tcod_window::tcod_map_key;
///
/// # fn main() {
/// let tcod_key = Key {
///     code: KeyCode::Char,
///     printable: 'A',
///     ..Key::default()
/// };
///
/// assert_eq!(tcod_map_key(tcod_key), PistonKey::A);
/// # }
/// ```
pub fn tcod_map_key(key: TcodKey) -> PistonKey {
    match key.code {
        KeyCode::NoKey => PistonKey::Unknown,
        KeyCode::Escape => PistonKey::Escape,
        KeyCode::Backspace => PistonKey::Backspace,
        KeyCode::Tab => PistonKey::Tab,
        KeyCode::Enter => PistonKey::Return,
        KeyCode::Shift => PistonKey::LShift,
        KeyCode::Control => PistonKey::LCtrl,
        KeyCode::Alt => PistonKey::LAlt,
        KeyCode::Pause => PistonKey::Pause,
        KeyCode::CapsLock => PistonKey::CapsLock,
        KeyCode::PageUp => PistonKey::PageUp,
        KeyCode::PageDown => PistonKey::PageDown,
        KeyCode::End => PistonKey::End,
        KeyCode::Home => PistonKey::Home,
        KeyCode::Up => PistonKey::Up,
        KeyCode::Left => PistonKey::Left,
        KeyCode::Right => PistonKey::Right,
        KeyCode::Down => PistonKey::Down,
        KeyCode::PrintScreen => PistonKey::PrintScreen,
        KeyCode::Insert => PistonKey::Insert,
        KeyCode::Delete => PistonKey::Delete,
        KeyCode::LeftWin => PistonKey::LGui,
        KeyCode::RightWin => PistonKey::RGui,
        KeyCode::Apps => PistonKey::Application,
        // The numbers on the numeric keypad
        KeyCode::NumPad0 => PistonKey::NumPad0,
        KeyCode::NumPad1 => PistonKey::NumPad1,
        KeyCode::NumPad2 => PistonKey::NumPad2,
        KeyCode::NumPad3 => PistonKey::NumPad3,
        KeyCode::NumPad4 => PistonKey::NumPad4,
        KeyCode::NumPad5 => PistonKey::NumPad5,
        KeyCode::NumPad6 => PistonKey::NumPad6,
        KeyCode::NumPad7 => PistonKey::NumPad7,
        KeyCode::NumPad8 => PistonKey::NumPad8,
        KeyCode::NumPad9 => PistonKey::NumPad9,
        KeyCode::NumPadAdd => PistonKey::NumPadPlus,
        KeyCode::NumPadSubtract => PistonKey::NumPadMinus,
        KeyCode::NumPadDivide => PistonKey::NumPadDivide,
        KeyCode::NumPadMultiply => PistonKey::NumPadMultiply,
        KeyCode::NumPadDecimal => PistonKey::NumPadDecimal,
        KeyCode::NumPadEnter => PistonKey::NumPadEnter,
        KeyCode::F1 => PistonKey::F1,
        KeyCode::F2 => PistonKey::F2,
        KeyCode::F3 => PistonKey::F3,
        KeyCode::F4 => PistonKey::F4,
        KeyCode::F5 => PistonKey::F5,
        KeyCode::F6 => PistonKey::F6,
        KeyCode::F7 => PistonKey::F7,
        KeyCode::F8 => PistonKey::F8,
        KeyCode::F9 => PistonKey::F9,
        KeyCode::F10 => PistonKey::F10,
        KeyCode::F11 => PistonKey::F11,
        KeyCode::F12 => PistonKey::F12,
        KeyCode::NumLock => PistonKey::NumLockClear,
        KeyCode::ScrollLock => PistonKey::ScrollLock,
        KeyCode::Spacebar => PistonKey::Space,
        // Characters
        _ => {
            let key_as_u32 = match key.printable {
                // We need to convert the uppercase characters to be lowercase.
                key @ 'A' ... 'Z' => key.to_lowercase().next().unwrap() as u32,
                key => key as u32,
            };

            key_as_u32.into()
        },
    }
}

/// Maps a TCOD mouse state change to a piston-input button.
///
/// # Examples
///
/// ```
/// # extern crate piston;
/// # extern crate tcod;
/// # extern crate tcod_window;
/// #
/// use piston::input::mouse::MouseButton;
/// use tcod::input::Mouse;
/// use tcod_window::tcod_map_mouse;
///
/// # fn main() {
/// let prev_state = Mouse {
///     lbutton: false,
///     ..Mouse::default()
/// };
/// let state = Mouse {
///     lbutton: true,
///     ..Mouse::default()
/// };
///
/// assert_eq!(tcod_map_mouse(prev_state, &state), MouseButton::Left);
/// # }
/// ```
#[cfg_attr(feature = "clippy", allow(if_not_else))]
pub fn tcod_map_mouse(prev_state: Mouse, state: &Mouse) -> MouseButton {
    if prev_state.lbutton != state.lbutton {
        MouseButton::Left
    } else if prev_state.rbutton != state.rbutton {
        MouseButton::Right
    } else if prev_state.mbutton != state.mbutton {
        MouseButton::Middle
    } else {
        MouseButton::Unknown
    }
}
<commit_msg>docs: fix typo in doc tests<commit_after>// Copyright 2015-2016 Nikita Pekin and the tcod_window contributors
// See the README.md file at the top-level directory of this distribution.
//
// 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.

#![deny(missing_docs)]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

//! This crate provides a TCOD back-end for the Piston game engine.
//!
//! # Example
//!
//! The following example shows a quick example of the basic functionality of
//! `TcodWindow`.
//!
//! ```
//! extern crate piston;
//! extern crate tcod_window;
//!
//! use piston::window::{Size, WindowSettings};
//! use tcod_window::TcodWindow;
//!
//! fn main() {
//!     let mut window = TcodWindow::new(
//!         WindowSettings::new(
//!             "My Application".to_owned(),
//!             Size {
//!                 width: 100,
//!                 height: 100,
//!             }
//!         )
//!     );
//! }
//! ```

extern crate input;
#[macro_use]
extern crate tcod;
extern crate window;

use std::cell::RefCell;
use std::rc::Rc;

use input::{Input, MouseButton};
use input::keyboard::Key as PistonKey;
use tcod::input::{Key as TcodKey, KeyCode, Mouse};
use tcod::Console;
use tcod::console::Root;
use window::{AdvancedWindow, BuildFromWindowSettings, Size, Window, WindowSettings};

/// A window implemented by a TCOD back-end.
pub struct TcodWindow {
    /// TCOD `Root` window used for rendering.
    pub window: Rc<RefCell<Root>>,
    title: String,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    mouse_state_prev: Mouse,
    exit_on_esc: bool,
}

impl TcodWindow {
    /// Create a new game window from the provided `WindowSettings`.
    ///
    /// Internally, it initializes a new TCOD `Root` with the size and title
    /// specified in the `WindowSettings`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate piston;
    /// # extern crate tcod_window;
    /// #
    /// use piston::window::{Size, WindowSettings};
    /// use tcod_window::TcodWindow;
    ///
    /// # fn main() {
    /// let mut window = TcodWindow::new(
    ///     WindowSettings::new(
    ///         "My Application".to_owned(),
    ///         Size {
    ///             width: 100,
    ///             height: 100,
    ///         }
    ///     )
    /// );
    /// # }
    /// ```
    pub fn new(settings: WindowSettings) -> Self {
        let console = Root::initializer()
                          .size(settings.get_size().width as i32,
                                settings.get_size().height as i32)
                          .title(settings.get_title())
                          .init();
        let console = Rc::new(RefCell::new(console));

        Self::with_console(console, settings)
    }

    /// Create a new game window from an existing TCOD `Root` console wrapped as
    /// an `Rc<RefCell<Root>>`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate piston;
    /// # extern crate tcod;
    /// # extern crate tcod_window;
    /// #
    /// use std::cell::RefCell;
    /// use std::rc::Rc;
    /// #
    /// use piston::window::{Size, WindowSettings};
    /// use tcod::console::Root;
    /// use tcod_window::TcodWindow;
    ///
    /// # fn main() {
    /// let settings = WindowSettings::new(
    ///     "My Application".to_owned(),
    ///     Size {
    ///         width: 100,
    ///         height: 100,
    ///     }
    /// );
    /// let root = Root::initializer()
    ///                 .size(settings.get_size().width as i32,
    ///                       settings.get_size().height as i32)
    ///                 .title(settings.get_title())
    ///                 .init();
    /// let console = Rc::new(RefCell::new(root));
    ///
    /// let mut window = TcodWindow::with_console(console, settings);
    /// # }
    /// ```
    pub fn with_console(console: Rc<RefCell<Root>>, settings: WindowSettings) -> Self {
        TcodWindow {
            window: console,
            title: settings.get_title(),
            should_close: false,
            mouse_relative: None,
            mouse_state_prev: Mouse::default(),
            exit_on_esc: settings.get_exit_on_esc(),
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use input::{Button, Motion};
        use input::Input::{Move, Press, Release};
        use tcod::input::{ANY, KEY_PRESS, KEY_RELEASE, MOUSE_MOVE, MOUSE_PRESS, MOUSE_RELEASE,
                          check_for_event};
        use tcod::input::Event::{Key, Mouse};

        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Move(Motion::MouseRelative(x, y)));
        }

        match check_for_event(ANY) {
            Some((KEY_PRESS, Key(ref key_state))) => {
                if self.exit_on_esc && key_state.code == KeyCode::Escape {
                    self.should_close = true;
                    None
                } else {
                    Some(Press(Button::Keyboard(tcod_map_key(*key_state))))
                }
            },
            Some((KEY_RELEASE, Key(ref key_state))) => {
                Some(Release(Button::Keyboard(tcod_map_key(*key_state))))
            },
            Some((MOUSE_PRESS, Mouse(ref mouse_state))) => {
                let button = tcod_map_mouse(self.mouse_state_prev, mouse_state);
                self.mouse_state_prev = *mouse_state;
                Some(Press(Button::Mouse(button)))
            },
            Some((MOUSE_RELEASE, Mouse(ref mouse_state))) => {
                let button = tcod_map_mouse(self.mouse_state_prev, mouse_state);
                self.mouse_state_prev = *mouse_state;
                Some(Release(Button::Mouse(button)))
            },
            Some((MOUSE_MOVE, Mouse(ref mouse_state))) => {
                self.mouse_relative = Some(((mouse_state.x - self.mouse_state_prev.x) as f64,
                                            (mouse_state.y - self.mouse_state_prev.y) as f64));
                self.mouse_state_prev = *mouse_state;
                Some(Move(Motion::MouseCursor(mouse_state.x as f64, mouse_state.y as f64)))
            },
            _ => None,
        }
    }
}

impl BuildFromWindowSettings for TcodWindow {
    fn build_from_window_settings(settings: WindowSettings) -> Result<Self, String> {
        Ok(TcodWindow::new(settings))
    }
}

impl Window for TcodWindow {
    type Event = Input;

    fn should_close(&self) -> bool {
        self.should_close
    }
    fn set_should_close(&mut self, value: bool) {
        self.should_close = value;
    }
    fn swap_buffers(&mut self) {
        self.window.borrow_mut().flush();
    }
    fn size(&self) -> Size {
        let window = self.window.borrow();
        Size {
            width: window.width() as u32,
            height: window.height() as u32,
        }
    }
    fn poll_event(&mut self) -> Option<Input> {
        self.poll_event()
    }
    fn draw_size(&self) -> Size {
        let window = self.window.borrow();
        Size {
            width: window.width() as u32,
            height: window.height() as u32,
        }
    }
}

impl AdvancedWindow for TcodWindow {
    fn get_title(&self) -> String {
        self.title.clone()
    }
    fn set_title(&mut self, value: String) {
        self.window.borrow_mut().set_window_title(&value);
        self.title = value
    }
    fn get_exit_on_esc(&self) -> bool {
        self.exit_on_esc
    }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value;
    }
    fn set_capture_cursor(&mut self, _value: bool) {}
}

/// Maps a TCOD key to a piston-input key.
///
/// # Examples
///
/// ```
/// # extern crate piston;
/// # extern crate tcod;
/// # extern crate tcod_window;
/// #
/// use piston::input::Key as PistonKey;
/// use tcod::input::{Key, KeyCode};
/// use tcod_window::tcod_map_key;
///
/// # fn main() {
/// let tcod_key = Key {
///     code: KeyCode::Char,
///     printable: 'A',
///     ..Key::default()
/// };
///
/// assert_eq!(tcod_map_key(tcod_key), PistonKey::A);
/// # }
/// ```
pub fn tcod_map_key(key: TcodKey) -> PistonKey {
    match key.code {
        KeyCode::NoKey => PistonKey::Unknown,
        KeyCode::Escape => PistonKey::Escape,
        KeyCode::Backspace => PistonKey::Backspace,
        KeyCode::Tab => PistonKey::Tab,
        KeyCode::Enter => PistonKey::Return,
        KeyCode::Shift => PistonKey::LShift,
        KeyCode::Control => PistonKey::LCtrl,
        KeyCode::Alt => PistonKey::LAlt,
        KeyCode::Pause => PistonKey::Pause,
        KeyCode::CapsLock => PistonKey::CapsLock,
        KeyCode::PageUp => PistonKey::PageUp,
        KeyCode::PageDown => PistonKey::PageDown,
        KeyCode::End => PistonKey::End,
        KeyCode::Home => PistonKey::Home,
        KeyCode::Up => PistonKey::Up,
        KeyCode::Left => PistonKey::Left,
        KeyCode::Right => PistonKey::Right,
        KeyCode::Down => PistonKey::Down,
        KeyCode::PrintScreen => PistonKey::PrintScreen,
        KeyCode::Insert => PistonKey::Insert,
        KeyCode::Delete => PistonKey::Delete,
        KeyCode::LeftWin => PistonKey::LGui,
        KeyCode::RightWin => PistonKey::RGui,
        KeyCode::Apps => PistonKey::Application,
        // The numbers on the numeric keypad
        KeyCode::NumPad0 => PistonKey::NumPad0,
        KeyCode::NumPad1 => PistonKey::NumPad1,
        KeyCode::NumPad2 => PistonKey::NumPad2,
        KeyCode::NumPad3 => PistonKey::NumPad3,
        KeyCode::NumPad4 => PistonKey::NumPad4,
        KeyCode::NumPad5 => PistonKey::NumPad5,
        KeyCode::NumPad6 => PistonKey::NumPad6,
        KeyCode::NumPad7 => PistonKey::NumPad7,
        KeyCode::NumPad8 => PistonKey::NumPad8,
        KeyCode::NumPad9 => PistonKey::NumPad9,
        KeyCode::NumPadAdd => PistonKey::NumPadPlus,
        KeyCode::NumPadSubtract => PistonKey::NumPadMinus,
        KeyCode::NumPadDivide => PistonKey::NumPadDivide,
        KeyCode::NumPadMultiply => PistonKey::NumPadMultiply,
        KeyCode::NumPadDecimal => PistonKey::NumPadDecimal,
        KeyCode::NumPadEnter => PistonKey::NumPadEnter,
        KeyCode::F1 => PistonKey::F1,
        KeyCode::F2 => PistonKey::F2,
        KeyCode::F3 => PistonKey::F3,
        KeyCode::F4 => PistonKey::F4,
        KeyCode::F5 => PistonKey::F5,
        KeyCode::F6 => PistonKey::F6,
        KeyCode::F7 => PistonKey::F7,
        KeyCode::F8 => PistonKey::F8,
        KeyCode::F9 => PistonKey::F9,
        KeyCode::F10 => PistonKey::F10,
        KeyCode::F11 => PistonKey::F11,
        KeyCode::F12 => PistonKey::F12,
        KeyCode::NumLock => PistonKey::NumLockClear,
        KeyCode::ScrollLock => PistonKey::ScrollLock,
        KeyCode::Spacebar => PistonKey::Space,
        // Characters
        _ => {
            let key_as_u32 = match key.printable {
                // We need to convert the uppercase characters to be lowercase.
                key @ 'A' ... 'Z' => key.to_lowercase().next().unwrap() as u32,
                key => key as u32,
            };

            key_as_u32.into()
        },
    }
}

/// Maps a TCOD mouse state change to a piston-input button.
///
/// # Examples
///
/// ```
/// # extern crate piston;
/// # extern crate tcod;
/// # extern crate tcod_window;
/// #
/// use piston::input::mouse::MouseButton;
/// use tcod::input::Mouse;
/// use tcod_window::tcod_map_mouse;
///
/// # fn main() {
/// let prev_state = Mouse {
///     lbutton: false,
///     ..Mouse::default()
/// };
/// let state = Mouse {
///     lbutton: true,
///     ..Mouse::default()
/// };
///
/// assert_eq!(tcod_map_mouse(prev_state, &state), MouseButton::Left);
/// # }
/// ```
#[cfg_attr(feature = "clippy", allow(if_not_else))]
pub fn tcod_map_mouse(prev_state: Mouse, state: &Mouse) -> MouseButton {
    if prev_state.lbutton != state.lbutton {
        MouseButton::Left
    } else if prev_state.rbutton != state.rbutton {
        MouseButton::Right
    } else if prev_state.mbutton != state.mbutton {
        MouseButton::Middle
    } else {
        MouseButton::Unknown
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Itoa Developers
//
// 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.

#![doc(html_root_url = "https://docs.rs/itoa/0.4.0")]

#![cfg_attr(not(feature = "std"), no_std)]

#![cfg_attr(feature = "i128", feature(i128_type, i128))]

#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, unreadable_literal))]

#[cfg(feature = "i128")]
mod udiv128;

#[cfg(feature = "std")]
use std::{fmt, io, mem, ptr, slice, str};

#[cfg(not(feature = "std"))]
use core::{fmt, mem, ptr, slice, str};

/// Write integer to an `io::Write`.
#[cfg(feature = "std")]
#[inline]
pub fn write<W: io::Write, V: Integer>(wr: W, value: V) -> io::Result<usize> {
    value.write(wr)
}

/// Write integer to an `fmt::Write`.
#[inline]
pub fn fmt<W: fmt::Write, V: Integer>(wr: W, value: V) -> fmt::Result {
    value.fmt(wr)
}

// Seal to prevent downstream implementations of the Integer trait.
mod private {
    pub trait Sealed {}
}

/// An integer that can be formatted by `itoa::write` and `itoa::fmt`.
///
/// This trait is sealed and cannot be implemented for types outside of itoa.
pub trait Integer: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    #[cfg(feature = "std")]
    fn write<W: io::Write>(self, W) -> io::Result<usize>;

    // Not public API.
    #[doc(hidden)]
    fn fmt<W: fmt::Write>(self, W) -> fmt::Result;
}

trait IntegerPrivate<B> {
    fn write_to(self, buf: &mut B) -> &[u8];
}

const DEC_DIGITS_LUT: &'static[u8] =
    b"0001020304050607080910111213141516171819\
      2021222324252627282930313233343536373839\
      4041424344454647484950515253545556575859\
      6061626364656667686970717273747576777879\
      8081828384858687888990919293949596979899";

// Adaptation of the original implementation at
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
macro_rules! impl_IntegerCommon {
    ($max_len:expr, $t:ident) => {
        impl Integer for $t {
            #[cfg(feature = "std")]
            #[inline]
            fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
                let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
                let bytes = self.write_to(&mut buf);
                try!(wr.write_all(bytes));
                Ok(bytes.len())
            }

            #[inline]
            fn fmt<W: fmt::Write>(self, mut wr: W) -> fmt::Result {
                let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
                let bytes = self.write_to(&mut buf);
                wr.write_str(unsafe { str::from_utf8_unchecked(bytes) })
            }
        }

        impl private::Sealed for $t {}
    };
}

macro_rules! impl_Integer {
    (private $($max_len:expr => $t:ident),* as $conv_fn:ident) => {$(

        impl IntegerPrivate<[u8; $max_len]> for $t {
            #[allow(unused_comparisons)]
            #[inline]
            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
                let is_nonnegative = self >= 0;
                let mut n = if is_nonnegative {
                    self as $conv_fn
                } else {
                    // convert the negative num to positive by summing 1 to it's 2 complement
                    (!(self as $conv_fn)).wrapping_add(1)
                };
                let mut curr = buf.len() as isize;
                let buf_ptr = buf.as_mut_ptr();
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();

                unsafe {
                    // need at least 16 bits for the 4-characters-at-a-time to work.
                    if mem::size_of::<$t>() >= 2 {
                        // eagerly decode 4 characters at a time
                        while n >= 10000 {
                            let rem = (n % 10000) as isize;
                            n /= 10000;

                            let d1 = (rem / 100) << 1;
                            let d2 = (rem % 100) << 1;
                            curr -= 4;
                            ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                            ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
                        }
                    }

                    // if we reach here numbers are <= 9999, so at most 4 chars long
                    let mut n = n as isize; // possibly reduce 64bit math

                    // decode 2 more chars, if > 2 chars
                    if n >= 100 {
                        let d1 = (n % 100) << 1;
                        n /= 100;
                        curr -= 2;
                        ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                    }

                    // decode last 1 or 2 chars
                    if n < 10 {
                        curr -= 1;
                        *buf_ptr.offset(curr) = (n as u8) + b'0';
                    } else {
                        let d1 = n << 1;
                        curr -= 2;
                        ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                    }

                    if !is_nonnegative {
                        curr -= 1;
                        *buf_ptr.offset(curr) = b'-';
                    }
                }

                let len = buf.len() - curr as usize;
                unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }
            }
        }
    )*};

    ($($max_len:expr => $t:ident),* as $conv_fn:ident) => {
        $(impl_IntegerCommon!($max_len, $t);)*
        impl_Integer!(private $($max_len => $t),* as $conv_fn);
    };
}

const I8_MAX_LEN: usize = 4;
const U8_MAX_LEN: usize = 3;
const I16_MAX_LEN: usize = 6;
const U16_MAX_LEN: usize = 5;
const I32_MAX_LEN: usize = 11;
const U32_MAX_LEN: usize = 10;
const I64_MAX_LEN: usize = 20;
const U64_MAX_LEN: usize = 20;

impl_Integer!(
    I8_MAX_LEN => i8,
    U8_MAX_LEN => u8,
    I16_MAX_LEN => i16,
    U16_MAX_LEN => u16,
    I32_MAX_LEN => i32,
    U32_MAX_LEN => u32
    as u32);

impl_Integer!(I64_MAX_LEN => i64, U64_MAX_LEN => u64 as u64);

#[cfg(target_pointer_width = "16")]
impl_Integer!(I16_MAX_LEN => isize, U16_MAX_LEN => usize as u16);

#[cfg(target_pointer_width = "32")]
impl_Integer!(I32_MAX_LEN => isize, U32_MAX_LEN => usize as u32);

#[cfg(target_pointer_width = "64")]
impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64);

#[cfg(all(feature = "i128"))]
macro_rules! impl_Integer128 {
    ($($max_len:expr => $t:ident),*) => {$(
        impl_IntegerCommon!($max_len, $t);

        impl IntegerPrivate<[u8; $max_len]> for $t {
            #[allow(unused_comparisons)]
            #[inline]
            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
                let is_nonnegative = self >= 0;
                let n = if is_nonnegative {
                    self as u128
                } else {
                    // convert the negative num to positive by summing 1 to it's 2 complement
                    (!(self as u128)).wrapping_add(1)
                };
                let mut curr = buf.len() as isize;
                let buf_ptr = buf.as_mut_ptr();

                unsafe {
                    // Divide by 10^19 which is the highest power less than 2^64.
                    let (n, rem) = udiv128::udivmod_1e19(n);
                    curr -= rem.write_to(buf).len() as isize;

                    if n != 0 {
                        // Memset the base10 leading zeros of rem.
                        let target = buf.len() as isize - 19;
                        ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
                        curr = target;

                        // Divide by 10^19 again.
                        let (n, rem) = udiv128::udivmod_1e19(n);
                        let buf2 = buf_ptr.offset(curr - buf.len() as isize) as *mut [u8; $max_len];
                        curr -= rem.write_to(&mut *buf2).len() as isize;

                        if n != 0 {
                            // Memset the leading zeros.
                            let target = buf.len() as isize - 38;
                            ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
                            curr = target;

                            // There is at most one digit left
                            // because u128::max / 10^19 / 10^19 is 3.
                            curr -= 1;
                            *buf_ptr.offset(curr) = (n as u8) + b'0';
                        }
                    }

                    if !is_nonnegative {
                        curr -= 1;
                        *buf_ptr.offset(curr) = b'-';
                    }

                    let len = buf.len() - curr as usize;
                    slice::from_raw_parts(buf_ptr.offset(curr), len)
                }
            }
        }
    )*};
}

#[cfg(all(feature = "i128"))]
const U128_MAX_LEN: usize = 39;
#[cfg(all(feature = "i128"))]
const I128_MAX_LEN: usize = 40;

#[cfg(all(feature = "i128"))]
impl_Integer!(private U128_MAX_LEN => u64, I128_MAX_LEN => u64 as u64);

#[cfg(all(feature = "i128"))]
impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128);
<commit_msg>use one u64 impl<commit_after>// Copyright 2016 Itoa Developers
//
// 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.

#![doc(html_root_url = "https://docs.rs/itoa/0.4.0")]

#![cfg_attr(not(feature = "std"), no_std)]

#![cfg_attr(feature = "i128", feature(i128_type, i128))]

#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, unreadable_literal))]

#[cfg(feature = "i128")]
mod udiv128;

#[cfg(feature = "std")]
use std::{fmt, io, mem, ptr, slice, str};

#[cfg(not(feature = "std"))]
use core::{fmt, mem, ptr, slice, str};

/// Write integer to an `io::Write`.
#[cfg(feature = "std")]
#[inline]
pub fn write<W: io::Write, V: Integer>(wr: W, value: V) -> io::Result<usize> {
    value.write(wr)
}

/// Write integer to an `fmt::Write`.
#[inline]
pub fn fmt<W: fmt::Write, V: Integer>(wr: W, value: V) -> fmt::Result {
    value.fmt(wr)
}

// Seal to prevent downstream implementations of the Integer trait.
mod private {
    pub trait Sealed {}
}

/// An integer that can be formatted by `itoa::write` and `itoa::fmt`.
///
/// This trait is sealed and cannot be implemented for types outside of itoa.
pub trait Integer: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    #[cfg(feature = "std")]
    fn write<W: io::Write>(self, W) -> io::Result<usize>;

    // Not public API.
    #[doc(hidden)]
    fn fmt<W: fmt::Write>(self, W) -> fmt::Result;
}

trait IntegerPrivate<B> {
    fn write_to(self, buf: &mut B) -> &[u8];
}

const DEC_DIGITS_LUT: &'static[u8] =
    b"0001020304050607080910111213141516171819\
      2021222324252627282930313233343536373839\
      4041424344454647484950515253545556575859\
      6061626364656667686970717273747576777879\
      8081828384858687888990919293949596979899";

// Adaptation of the original implementation at
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
macro_rules! impl_IntegerCommon {
    ($max_len:expr, $t:ident) => {
        impl Integer for $t {
            #[cfg(feature = "std")]
            #[inline]
            fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
                let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
                let bytes = self.write_to(&mut buf);
                try!(wr.write_all(bytes));
                Ok(bytes.len())
            }

            #[inline]
            fn fmt<W: fmt::Write>(self, mut wr: W) -> fmt::Result {
                let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
                let bytes = self.write_to(&mut buf);
                wr.write_str(unsafe { str::from_utf8_unchecked(bytes) })
            }
        }

        impl private::Sealed for $t {}
    };
}

macro_rules! impl_Integer {
    ($($max_len:expr => $t:ident),* as $conv_fn:ident) => {$(
        impl_IntegerCommon!($max_len, $t);

        impl IntegerPrivate<[u8; $max_len]> for $t {
            #[allow(unused_comparisons)]
            #[inline]
            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
                let is_nonnegative = self >= 0;
                let mut n = if is_nonnegative {
                    self as $conv_fn
                } else {
                    // convert the negative num to positive by summing 1 to it's 2 complement
                    (!(self as $conv_fn)).wrapping_add(1)
                };
                let mut curr = buf.len() as isize;
                let buf_ptr = buf.as_mut_ptr();
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();

                unsafe {
                    // need at least 16 bits for the 4-characters-at-a-time to work.
                    if mem::size_of::<$t>() >= 2 {
                        // eagerly decode 4 characters at a time
                        while n >= 10000 {
                            let rem = (n % 10000) as isize;
                            n /= 10000;

                            let d1 = (rem / 100) << 1;
                            let d2 = (rem % 100) << 1;
                            curr -= 4;
                            ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                            ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
                        }
                    }

                    // if we reach here numbers are <= 9999, so at most 4 chars long
                    let mut n = n as isize; // possibly reduce 64bit math

                    // decode 2 more chars, if > 2 chars
                    if n >= 100 {
                        let d1 = (n % 100) << 1;
                        n /= 100;
                        curr -= 2;
                        ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                    }

                    // decode last 1 or 2 chars
                    if n < 10 {
                        curr -= 1;
                        *buf_ptr.offset(curr) = (n as u8) + b'0';
                    } else {
                        let d1 = n << 1;
                        curr -= 2;
                        ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
                    }

                    if !is_nonnegative {
                        curr -= 1;
                        *buf_ptr.offset(curr) = b'-';
                    }
                }

                let len = buf.len() - curr as usize;
                unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }
            }
        }
    )*};
}

const I8_MAX_LEN: usize = 4;
const U8_MAX_LEN: usize = 3;
const I16_MAX_LEN: usize = 6;
const U16_MAX_LEN: usize = 5;
const I32_MAX_LEN: usize = 11;
const U32_MAX_LEN: usize = 10;
const I64_MAX_LEN: usize = 20;
const U64_MAX_LEN: usize = 20;

impl_Integer!(
    I8_MAX_LEN => i8,
    U8_MAX_LEN => u8,
    I16_MAX_LEN => i16,
    U16_MAX_LEN => u16,
    I32_MAX_LEN => i32,
    U32_MAX_LEN => u32
    as u32);

impl_Integer!(I64_MAX_LEN => i64, U64_MAX_LEN => u64 as u64);

#[cfg(target_pointer_width = "16")]
impl_Integer!(I16_MAX_LEN => isize, U16_MAX_LEN => usize as u16);

#[cfg(target_pointer_width = "32")]
impl_Integer!(I32_MAX_LEN => isize, U32_MAX_LEN => usize as u32);

#[cfg(target_pointer_width = "64")]
impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64);

#[cfg(all(feature = "i128"))]
macro_rules! impl_Integer128 {
    ($($max_len:expr => $t:ident),*) => {$(
        impl_IntegerCommon!($max_len, $t);

        impl IntegerPrivate<[u8; $max_len]> for $t {
            #[allow(unused_comparisons)]
            #[inline]
            fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
                let is_nonnegative = self >= 0;
                let n = if is_nonnegative {
                    self as u128
                } else {
                    // convert the negative num to positive by summing 1 to it's 2 complement
                    (!(self as u128)).wrapping_add(1)
                };
                let mut curr = buf.len() as isize;
                let buf_ptr = buf.as_mut_ptr();

                unsafe {
                    // Divide by 10^19 which is the highest power less than 2^64.
                    let (n, rem) = udiv128::udivmod_1e19(n);
                    let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
                    curr -= rem.write_to(&mut *buf1).len() as isize;

                    if n != 0 {
                        // Memset the base10 leading zeros of rem.
                        let target = buf.len() as isize - 19;
                        ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
                        curr = target;

                        // Divide by 10^19 again.
                        let (n, rem) = udiv128::udivmod_1e19(n);
                        let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
                        curr -= rem.write_to(&mut *buf2).len() as isize;

                        if n != 0 {
                            // Memset the leading zeros.
                            let target = buf.len() as isize - 38;
                            ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
                            curr = target;

                            // There is at most one digit left
                            // because u128::max / 10^19 / 10^19 is 3.
                            curr -= 1;
                            *buf_ptr.offset(curr) = (n as u8) + b'0';
                        }
                    }

                    if !is_nonnegative {
                        curr -= 1;
                        *buf_ptr.offset(curr) = b'-';
                    }

                    let len = buf.len() - curr as usize;
                    slice::from_raw_parts(buf_ptr.offset(curr), len)
                }
            }
        }
    )*};
}

#[cfg(all(feature = "i128"))]
const U128_MAX_LEN: usize = 39;
#[cfg(all(feature = "i128"))]
const I128_MAX_LEN: usize = 40;

#[cfg(all(feature = "i128"))]
impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128);
<|endoftext|>


<commit_before>#![feature(proc_macro, custom_derive, custom_attribute)]
#![feature(box_syntax)]
#[macro_use] extern crate serde_derive;
extern crate serde_json;
extern crate hyper;
pub mod dictionaries;
pub mod thesaureses;
pub use dictionaries::{Definition, Dictionary};
pub use thesaureses::Thesaurus;
mod error {
    use std::error;
    use std::error::Error as ErrorT;
    use std::fmt;
    #[derive(Debug)]
    pub enum Error {
        Hyper(::hyper::Error),
        Serde(::serde_json::Error),
        Error(Box<error::Error>)
    }
    impl error::Error for Error {
        fn description(&self) -> &str {
            match *self {
                Error::Hyper(ref hyper) => hyper.description(),
                Error::Serde(ref serde) => serde.description(),
                Error::Error(ref err) => err.description()
            }
        }
        fn cause(&self) -> Option<&::std::error::Error> { None }
    }
    impl fmt::Display for Error {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
            fmt.write_str(self.description())?;
            Ok(())
        }
    }
    impl From<::hyper::Error> for Error {
        fn from(val: ::hyper::Error) -> Self {
            Error::Hyper(val)
        }
    }
    impl From<::serde_json::Error> for Error {
        fn from(val: ::serde_json::Error) -> Self {
            Error::Serde(val)
        }
    }
}

pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
<commit_msg>Add implementation for I/O Errors<commit_after>#![feature(proc_macro, custom_derive, custom_attribute)]
#![feature(box_syntax)]
#[macro_use] extern crate serde_derive;
extern crate serde_json;
extern crate hyper;
pub mod dictionaries;
pub mod thesaureses;
pub use dictionaries::{Definition, Dictionary};
pub use thesaureses::Thesaurus;
mod error {
    use std::error;
    use std::error::Error as ErrorT;
    use std::fmt;
    #[derive(Debug)]
    pub enum Error {
        Hyper(::hyper::Error),
        Serde(::serde_json::Error),
        Error(Box<error::Error>)
    }
    impl error::Error for Error {
        fn description(&self) -> &str {
            match *self {
                Error::Hyper(ref hyper) => hyper.description(),
                Error::Serde(ref serde) => serde.description(),
                Error::Error(ref err) => err.description()
            }
        }
        fn cause(&self) -> Option<&::std::error::Error> { None }
    }
    impl fmt::Display for Error {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
            fmt.write_str(self.description())?;
            Ok(())
        }
    }
    impl From<::hyper::Error> for Error {
        fn from(val: ::hyper::Error) -> Self {
            Error::Hyper(val)
        }
    }
    impl From<::serde_json::Error> for Error {
        fn from(val: ::serde_json::Error) -> Self {
            Error::Serde(val)
        }
    }
    impl From<::std::io::Error> for Error {
        fn from(val: ::std::io::Error) -> Self {
            Error::Error(Box::new(val))
        }
    }
}

pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
<|endoftext|>


<commit_before>// Copyright 2016 Jason Lingle
//
// 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.

use std::convert::From;
use std::cmp;
use std::fmt;
use std::mem;
use std::hash::{Hash, Hasher};
use std::ops::Deref;

/// Miscelaneous things used to integrate other code with Supercow, but which
/// is not of interest to end users.
pub mod aux {
    use std::rc::Rc;
    use std::sync::Arc;

    /// Marker trait indicating a `Deref`-like which always returns the same
    /// reference.
    ///
    /// This is not indended for general use outside Supercow. Notably, `Box`
    /// and mundane references satisfy this trait's requirements, but
    /// deliberately do not implement it. It is also not a subtrait of `Deref`
    /// due to some additional special logic around boxes.
    ///
    /// ## Unsafety
    ///
    /// Behaviour is undefined if the implementation does not always return the
    /// same reference from `deref()` for any particular implementing value
    /// (including if that value is moved).
    pub unsafe trait ConstDeref {
        type Target : ?Sized;
        fn const_deref(&self) -> &Self::Target;
    }

    unsafe impl<T : ?Sized> ConstDeref for Rc<T> {
        type Target = T;
        fn const_deref(&self) -> &T { self }
    }

    unsafe impl<T : ?Sized> ConstDeref for Arc<T> {
        type Target = T;
        fn const_deref(&self) -> &T { self }
    }

    unsafe impl<T : ConstDeref + ?Sized> ConstDeref for Box<T> {
        type Target = T::Target;
        fn const_deref(&self) -> &T::Target {
            (**self).const_deref()
        }
    }
}

use self::aux::*;

/// Defines a "feature set" for a custom `Supercow` type.
///
/// ## Syntax
///
/// ```
/// #[macro_use] extern crate supercow;
///
/// # pub trait SomeTrait { }
/// # pub trait AnotherTrait { }
///
/// supercow_features!(
///   /// Some documentation, etc, if desired.
///   pub trait FeatureName: SomeTrait, AnotherTrait);
/// supercow_features!(
///   pub trait FeatureName2: Clone, SomeTrait, AnotherTrait);
///
/// # fn main() { }
/// ```
///
/// ## Semantics
///
/// A public trait named `FeatureName` is defined which extends all the listed
/// traits, other than `Clone`, and in addition to `ConstDeref`. If listed,
/// `Clone` *must* come first. If `Clone` is listed, the trait gains a
/// `clone_boxed()` method and `Box<FeatureName>` is `Clone`. All types which
/// implement all the listed traits (including `Clone`) and `ConstDeref`
/// implement `FeatureName`.
#[macro_export]
macro_rules! supercow_features {
    // It's unclear why $req:path doesn't work, but apparently constraints
    // allow neither `path` nor `ty`.
    ($(#[$meta:meta])* pub trait $feature_name:ident: Clone $(, $req:ident)*) => {
        $(#[$meta])*
        pub trait $feature_name<'a>: $($req +)* $crate::aux::ConstDeref + 'a {
            fn clone_boxed
                (&self)
                 -> Box<$feature_name<'a, Target = Self::Target> + 'a>;
        }
        impl<'a, T : 'a + $($req +)* Clone + $crate::aux::ConstDeref>
        $feature_name<'a> for T {
            fn clone_boxed
                (&self)
                 -> Box<$feature_name<'a, Target = Self::Target> + 'a>
            {
                let cloned: T = self.clone();
                Box::new(cloned)
            }
        }
        impl<'a, S : 'a> Clone for Box<$feature_name<'a, Target = S> + 'a> {
            fn clone(&self) -> Self {
                $feature_name::clone_boxed(&**self)
            }
        }
    };

    ($(#[$meta:meta])* pub trait $feature_name:ident: $($req:ident),*) => {
        $(#[$meta])*
        pub trait $feature_name<'a>: $($req +)* $crate::aux::ConstDeref + 'a {
        }
        impl<'a, T : 'a + $($req +)* Clone + $crate::aux::ConstDeref>
        $feature_name<'a> for T {
        }
    };
}

supercow_features!(
    /// The default feature set for special `Supercow` references.
    pub trait DefaultFeatures: Clone);
supercow_features!(
    /// The feature set used for `ASupercow` references.
    pub trait SyncFeatures: Clone, Send, Sync);

pub struct Supercow<'a, OWNED,
                    SPECIAL = Box<DefaultFeatures<'a, Target = OWNED>>>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    // In order to implement `Deref` in a branch-free fashion that isn't
    // sensitive to the Supercow being moved, we set `ptr_mask` and
    // `ptr_displacement` such that
    // `target = &*((&self & ptr_mask) + ptr_displacement)`
    // (arithmetic in terms of bytes, obviously).
    //
    // So for the three cases:
    //
    // Owned => ptr_mask = ~0u, ptr_displacement = offsetof(self, Owned.0)
    // Borrowed, Special => ptr_mask = 0u, ptr_displacement = address
    ptr_mask: usize,
    ptr_displacement: usize,
    state: SupercowData<'a, OWNED, SPECIAL>,
}

enum SupercowData<'a, OWNED : 'a, SPECIAL> {
    Owned(OWNED),
    Borrowed(&'a OWNED),
    Special(SPECIAL),
}
use self::SupercowData::*;

impl<'a, OWNED, SPECIAL> Deref
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    type Target = OWNED;
    #[inline]
    fn deref(&self) -> &OWNED {
        unsafe {
            let self_address: usize = mem::transmute(self);
            mem::transmute((self_address & self.ptr_mask) +
                           self.ptr_displacement)
        }
    }
}

impl<'a, OWNED, SPECIAL>
Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    pub fn owned(inner: OWNED) -> Self {
        Self::from_data(Owned(inner))
    }

    pub fn borrowed(inner: &'a OWNED) -> Self {
        Self::from_data(Borrowed(inner))
    }

    pub fn special<T : Into<SPECIAL>>(inner: T) -> Self {
        Self::from_data(Special(inner.into()))
    }

    fn from_data(data: SupercowData<'a, OWNED, SPECIAL>) -> Self {
        let mut this = Supercow {
            ptr_mask: 0,
            ptr_displacement: 0,
            state: data,
        };

        let ptr = match this.state {
            Owned(ref r) => r as *const OWNED,
            Borrowed(r) => r as *const OWNED,
            Special(ref s) => s.const_deref() as *const OWNED,
        };
        this.set_ptr(ptr);

        this
    }

    fn set_ptr(&mut self, ptr: *const OWNED) {
        // Use relative addressing if `ptr` is inside `self` and absolute
        // addressing otherwise.
        //
        // Ordinarily, `ptr` will always be inside `self` if the state is
        // `Owned`, and outside otherwise. However, it is possible to create
        // `Borrow` implementations that return arbitrary pointers, so we
        // handle the two cases like this instead.
        let self_start = self as *const Self as usize;
        let self_end = self_start + mem::size_of::<Self>();
        let addr = ptr as usize;

        if addr >= self_start && addr < self_end {
            self.ptr_mask = !0;
            self.ptr_displacement = addr - self_start;
        } else {
            self.ptr_mask = 0;
            self.ptr_displacement = addr;
        }
    }
}

impl<'a, OWNED, SPECIAL> From<OWNED>
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn from(inner: OWNED) -> Self {
        Self::from_data(SupercowData::Owned(inner))
    }
}

impl<'a, OWNED, SPECIAL> From<&'a OWNED>
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn from(inner: &'a OWNED) -> Self {
        Self::from_data(SupercowData::Borrowed(inner))
    }
}

impl<'a, OWNED, SPECIAL>
Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a + Clone,
      SPECIAL : ConstDeref<Target = OWNED> {
    pub fn to_mut(&mut self) -> &mut OWNED {
        let new = match self.state {
            Owned(ref mut r) => return r,
            Borrowed(r) => Self::from(r.clone()),
            Special(ref s) => Self::from(s.const_deref().clone()),
        };
        *self = new;
        match self.state {
            Owned(ref mut r) => r,
            _ => unreachable!(),
        }
    }
}

impl<'a, OWNED, SPECIAL> Clone
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Clone + 'a,
      SPECIAL : Clone + ConstDeref<Target = OWNED> {
    fn clone(&self) -> Self {
        Supercow {
            ptr_mask: self.ptr_mask,
            ptr_displacement: self.ptr_displacement,
            state: match self.state {
                Owned(ref o) => Owned(o.clone()),
                Borrowed(r) => Borrowed(r),
                Special(ref s) => Special(s.clone()),
            }
        }
    }
}

macro_rules! deleg_fmt {
    ($tr:ident) => {
        impl<'a, OWNED, SPECIAL> fmt::$tr
        for Supercow<'a, OWNED, SPECIAL>
        where OWNED : fmt::$tr + 'a,
              SPECIAL : ConstDeref<Target = OWNED> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                (**self).fmt(f)
            }
        }
    }
}
deleg_fmt!(Binary);
deleg_fmt!(Debug);
deleg_fmt!(Display);
deleg_fmt!(LowerExp);
deleg_fmt!(LowerHex);
deleg_fmt!(Octal);
deleg_fmt!(Pointer);
deleg_fmt!(UpperExp);
deleg_fmt!(UpperHex);

impl<'a, OWNED, SPECIAL, T> cmp::PartialEq<T>
for Supercow<'a, OWNED, SPECIAL>
where T : Deref<Target = OWNED>,
      OWNED : PartialEq<OWNED> + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn eq(&self, other: &T) -> bool {
        **self == **other
    }

    fn ne(&self, other: &T) -> bool {
        **self != **other
    }
}

impl<'a, OWNED, SPECIAL> cmp::Eq
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Eq + 'a,
      SPECIAL : ConstDeref<Target = OWNED> { }

impl<'a, OWNED, SPECIAL, T> cmp::PartialOrd<T>
for Supercow<'a, OWNED, SPECIAL>
where T : Deref<Target = OWNED>,
      OWNED : PartialOrd<OWNED> + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
        (**self).partial_cmp(other)
    }

    fn lt(&self, other: &T) -> bool {
        **self < **other
    }

    fn le(&self, other: &T) -> bool {
        **self <= **other
    }

    fn gt(&self, other: &T) -> bool {
        **self > **other
    }

    fn ge(&self, other: &T) -> bool {
        **self >= **other
    }
}

impl<'a, OWNED, SPECIAL> cmp::Ord
for Supercow<'a, OWNED, SPECIAL>
where OWNED : cmp::Ord + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        (**self).cmp(other)
    }
}

impl<'a, OWNED, SPECIAL> Hash
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Hash + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn hash<H : Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

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

    #[test]
    fn ref_to_owned() {
        let x = 42u32;
        let a: Supercow<u32> = Supercow::borrowed(&x);
        assert_eq!(x, *a);
        assert_eq!(&x as *const u32 as usize,
                   (&*a) as *const u32 as usize);

        let mut b = a.clone();
        assert_eq!(x, *b);
        assert_eq!(&x as *const u32 as usize,
                   (&*b) as *const u32 as usize);

        *b.to_mut() = 56;
        assert_eq!(42, *a);
        assert_eq!(x, *a);
        assert_eq!(&x as *const u32 as usize,
                   (&*a) as *const u32 as usize);
        assert_eq!(56, *b);
    }
}
<commit_msg>Shrink `ptr_mask`.<commit_after>// Copyright 2016 Jason Lingle
//
// 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.

use std::convert::From;
use std::cmp;
use std::fmt;
use std::mem;
use std::hash::{Hash, Hasher};
use std::ops::Deref;

/// Miscelaneous things used to integrate other code with Supercow, but which
/// is not of interest to end users.
pub mod aux {
    use std::rc::Rc;
    use std::sync::Arc;

    /// Marker trait indicating a `Deref`-like which always returns the same
    /// reference.
    ///
    /// This is not indended for general use outside Supercow. Notably, `Box`
    /// and mundane references satisfy this trait's requirements, but
    /// deliberately do not implement it. It is also not a subtrait of `Deref`
    /// due to some additional special logic around boxes.
    ///
    /// ## Unsafety
    ///
    /// Behaviour is undefined if the implementation does not always return the
    /// same reference from `deref()` for any particular implementing value
    /// (including if that value is moved).
    pub unsafe trait ConstDeref {
        type Target : ?Sized;
        fn const_deref(&self) -> &Self::Target;
    }

    unsafe impl<T : ?Sized> ConstDeref for Rc<T> {
        type Target = T;
        fn const_deref(&self) -> &T { self }
    }

    unsafe impl<T : ?Sized> ConstDeref for Arc<T> {
        type Target = T;
        fn const_deref(&self) -> &T { self }
    }

    unsafe impl<T : ConstDeref + ?Sized> ConstDeref for Box<T> {
        type Target = T::Target;
        fn const_deref(&self) -> &T::Target {
            (**self).const_deref()
        }
    }
}

use self::aux::*;

/// Defines a "feature set" for a custom `Supercow` type.
///
/// ## Syntax
///
/// ```
/// #[macro_use] extern crate supercow;
///
/// # pub trait SomeTrait { }
/// # pub trait AnotherTrait { }
///
/// supercow_features!(
///   /// Some documentation, etc, if desired.
///   pub trait FeatureName: SomeTrait, AnotherTrait);
/// supercow_features!(
///   pub trait FeatureName2: Clone, SomeTrait, AnotherTrait);
///
/// # fn main() { }
/// ```
///
/// ## Semantics
///
/// A public trait named `FeatureName` is defined which extends all the listed
/// traits, other than `Clone`, and in addition to `ConstDeref`. If listed,
/// `Clone` *must* come first. If `Clone` is listed, the trait gains a
/// `clone_boxed()` method and `Box<FeatureName>` is `Clone`. All types which
/// implement all the listed traits (including `Clone`) and `ConstDeref`
/// implement `FeatureName`.
#[macro_export]
macro_rules! supercow_features {
    // It's unclear why $req:path doesn't work, but apparently constraints
    // allow neither `path` nor `ty`.
    ($(#[$meta:meta])* pub trait $feature_name:ident: Clone $(, $req:ident)*) => {
        $(#[$meta])*
        pub trait $feature_name<'a>: $($req +)* $crate::aux::ConstDeref + 'a {
            fn clone_boxed
                (&self)
                 -> Box<$feature_name<'a, Target = Self::Target> + 'a>;
        }
        impl<'a, T : 'a + $($req +)* Clone + $crate::aux::ConstDeref>
        $feature_name<'a> for T {
            fn clone_boxed
                (&self)
                 -> Box<$feature_name<'a, Target = Self::Target> + 'a>
            {
                let cloned: T = self.clone();
                Box::new(cloned)
            }
        }
        impl<'a, S : 'a> Clone for Box<$feature_name<'a, Target = S> + 'a> {
            fn clone(&self) -> Self {
                $feature_name::clone_boxed(&**self)
            }
        }
    };

    ($(#[$meta:meta])* pub trait $feature_name:ident: $($req:ident),*) => {
        $(#[$meta])*
        pub trait $feature_name<'a>: $($req +)* $crate::aux::ConstDeref + 'a {
        }
        impl<'a, T : 'a + $($req +)* Clone + $crate::aux::ConstDeref>
        $feature_name<'a> for T {
        }
    };
}

supercow_features!(
    /// The default feature set for special `Supercow` references.
    pub trait DefaultFeatures: Clone);
supercow_features!(
    /// The feature set used for `ASupercow` references.
    pub trait SyncFeatures: Clone, Send, Sync);

pub struct Supercow<'a, OWNED,
                    SPECIAL = Box<DefaultFeatures<'a, Target = OWNED>>>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    // In order to implement `Deref` in a branch-free fashion that isn't
    // sensitive to the Supercow being moved, we set `ptr_mask` and
    // `ptr_displacement` such that
    // `target = &*((&self & sext(ptr_mask)) + ptr_displacement)`
    // (arithmetic in terms of bytes, obviously).
    //
    // So for the three cases:
    //
    // Owned => ptr_mask = ~0u, ptr_displacement = offsetof(self, Owned.0)
    // Borrowed, Special => ptr_mask = 0u, ptr_displacement = address
    //
    // `ptr_mask` is an i8 since that may allow better struct layout in the
    // future (since `SupercowData` has a decent amount of padding).
    ptr_displacement: usize,
    ptr_mask: i8,
    state: SupercowData<'a, OWNED, SPECIAL>,
}

enum SupercowData<'a, OWNED : 'a, SPECIAL> {
    Owned(OWNED),
    Borrowed(&'a OWNED),
    Special(SPECIAL),
}
use self::SupercowData::*;

impl<'a, OWNED, SPECIAL> Deref
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    type Target = OWNED;
    #[inline]
    fn deref(&self) -> &OWNED {
        let mask = self.ptr_mask as isize as usize;
        unsafe {
            let self_address: usize = mem::transmute(self);
            mem::transmute((self_address & mask) +
                           self.ptr_displacement)
        }
    }
}

impl<'a, OWNED, SPECIAL>
Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    pub fn owned(inner: OWNED) -> Self {
        Self::from_data(Owned(inner))
    }

    pub fn borrowed(inner: &'a OWNED) -> Self {
        Self::from_data(Borrowed(inner))
    }

    pub fn special<T : Into<SPECIAL>>(inner: T) -> Self {
        Self::from_data(Special(inner.into()))
    }

    fn from_data(data: SupercowData<'a, OWNED, SPECIAL>) -> Self {
        let mut this = Supercow {
            ptr_mask: 0,
            ptr_displacement: 0,
            state: data,
        };

        let ptr = match this.state {
            Owned(ref r) => r as *const OWNED,
            Borrowed(r) => r as *const OWNED,
            Special(ref s) => s.const_deref() as *const OWNED,
        };
        this.set_ptr(ptr);

        this
    }

    fn set_ptr(&mut self, ptr: *const OWNED) {
        // Use relative addressing if `ptr` is inside `self` and absolute
        // addressing otherwise.
        //
        // Ordinarily, `ptr` will always be inside `self` if the state is
        // `Owned`, and outside otherwise. However, it is possible to create
        // `Borrow` implementations that return arbitrary pointers, so we
        // handle the two cases like this instead.
        let self_start = self as *const Self as usize;
        let self_end = self_start + mem::size_of::<Self>();
        let addr = ptr as usize;

        if addr >= self_start && addr < self_end {
            self.ptr_mask = !0;
            self.ptr_displacement = addr - self_start;
        } else {
            self.ptr_mask = 0;
            self.ptr_displacement = addr;
        }
    }
}

impl<'a, OWNED, SPECIAL> From<OWNED>
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn from(inner: OWNED) -> Self {
        Self::from_data(SupercowData::Owned(inner))
    }
}

impl<'a, OWNED, SPECIAL> From<&'a OWNED>
for Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn from(inner: &'a OWNED) -> Self {
        Self::from_data(SupercowData::Borrowed(inner))
    }
}

impl<'a, OWNED, SPECIAL>
Supercow<'a, OWNED, SPECIAL>
where OWNED : 'a + Clone,
      SPECIAL : ConstDeref<Target = OWNED> {
    pub fn to_mut(&mut self) -> &mut OWNED {
        let new = match self.state {
            Owned(ref mut r) => return r,
            Borrowed(r) => Self::from(r.clone()),
            Special(ref s) => Self::from(s.const_deref().clone()),
        };
        *self = new;
        match self.state {
            Owned(ref mut r) => r,
            _ => unreachable!(),
        }
    }
}

impl<'a, OWNED, SPECIAL> Clone
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Clone + 'a,
      SPECIAL : Clone + ConstDeref<Target = OWNED> {
    fn clone(&self) -> Self {
        Supercow {
            ptr_mask: self.ptr_mask,
            ptr_displacement: self.ptr_displacement,
            state: match self.state {
                Owned(ref o) => Owned(o.clone()),
                Borrowed(r) => Borrowed(r),
                Special(ref s) => Special(s.clone()),
            }
        }
    }
}

macro_rules! deleg_fmt {
    ($tr:ident) => {
        impl<'a, OWNED, SPECIAL> fmt::$tr
        for Supercow<'a, OWNED, SPECIAL>
        where OWNED : fmt::$tr + 'a,
              SPECIAL : ConstDeref<Target = OWNED> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                (**self).fmt(f)
            }
        }
    }
}
deleg_fmt!(Binary);
deleg_fmt!(Debug);
deleg_fmt!(Display);
deleg_fmt!(LowerExp);
deleg_fmt!(LowerHex);
deleg_fmt!(Octal);
deleg_fmt!(Pointer);
deleg_fmt!(UpperExp);
deleg_fmt!(UpperHex);

impl<'a, OWNED, SPECIAL, T> cmp::PartialEq<T>
for Supercow<'a, OWNED, SPECIAL>
where T : Deref<Target = OWNED>,
      OWNED : PartialEq<OWNED> + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn eq(&self, other: &T) -> bool {
        **self == **other
    }

    fn ne(&self, other: &T) -> bool {
        **self != **other
    }
}

impl<'a, OWNED, SPECIAL> cmp::Eq
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Eq + 'a,
      SPECIAL : ConstDeref<Target = OWNED> { }

impl<'a, OWNED, SPECIAL, T> cmp::PartialOrd<T>
for Supercow<'a, OWNED, SPECIAL>
where T : Deref<Target = OWNED>,
      OWNED : PartialOrd<OWNED> + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
        (**self).partial_cmp(other)
    }

    fn lt(&self, other: &T) -> bool {
        **self < **other
    }

    fn le(&self, other: &T) -> bool {
        **self <= **other
    }

    fn gt(&self, other: &T) -> bool {
        **self > **other
    }

    fn ge(&self, other: &T) -> bool {
        **self >= **other
    }
}

impl<'a, OWNED, SPECIAL> cmp::Ord
for Supercow<'a, OWNED, SPECIAL>
where OWNED : cmp::Ord + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        (**self).cmp(other)
    }
}

impl<'a, OWNED, SPECIAL> Hash
for Supercow<'a, OWNED, SPECIAL>
where OWNED : Hash + 'a,
      SPECIAL : ConstDeref<Target = OWNED> {
    fn hash<H : Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

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

    #[test]
    fn ref_to_owned() {
        let x = 42u32;
        let a: Supercow<u32> = Supercow::borrowed(&x);
        assert_eq!(x, *a);
        assert_eq!(&x as *const u32 as usize,
                   (&*a) as *const u32 as usize);

        let mut b = a.clone();
        assert_eq!(x, *b);
        assert_eq!(&x as *const u32 as usize,
                   (&*b) as *const u32 as usize);

        *b.to_mut() = 56;
        assert_eq!(42, *a);
        assert_eq!(x, *a);
        assert_eq!(&x as *const u32 as usize,
                   (&*a) as *const u32 as usize);
        assert_eq!(56, *b);
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::hash::{sip, Hash};
use libc;

use {raw, Error};

/// Unique identity of any object (commit, tree, blob, tag).
pub struct Oid {
    raw: raw::git_oid,
}

impl Oid {
    /// Create a new Oid from a raw libgit2 oid structure.
    ///
    /// This function is unsafe as it does not know if the memory pointed to by
    /// `oid` is valid or not.
    pub unsafe fn from_raw(oid: *const raw::git_oid) -> Oid {
        ::init();
        Oid { raw: *oid }
    }

    /// Parse a hex-formatted object id into an Oid structure.
    ///
    /// If the string is not a valid 40-character hex string, an error is
    /// returned.
    pub fn from_str(s: &str) -> Result<Oid, Error> {
        ::init();
        let mut raw = raw::git_oid { id: [0, ..raw::GIT_OID_RAWSZ] };
        try!(::doit(|| unsafe {
            raw::git_oid_fromstrn(&mut raw,
                                  s.as_bytes().as_ptr() as *const libc::c_char,
                                  s.len() as libc::size_t)
        }));
        Ok(Oid { raw: raw })
    }

    /// Parse a raw object id into an Oid structure.
    ///
    /// If the array given is not 20 bytes in length, an error is returned.
    pub fn from_bytes(bytes: &[u8]) -> Result<Oid, Error> {
        ::init();
        let mut raw = raw::git_oid { id: [0, ..raw::GIT_OID_RAWSZ] };
        if bytes.len() != raw::GIT_OID_RAWSZ {
            Err(Error::from_str("raw byte array must be 20 bytes"))
        } else {
            unsafe { raw::git_oid_fromraw(&mut raw, bytes.as_ptr()) }
            Ok(Oid { raw: raw })
        }
    }

    /// Gain access to the underlying raw oid pointer
    pub fn raw(&self) -> *const raw::git_oid { &self.raw as *const _ }
}

impl fmt::Show for Oid {
    /// Hex-encode this Oid into a formatter.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut dst = [0u8, ..raw::GIT_OID_HEXSZ + 1];
        unsafe {
            raw::git_oid_tostr(dst.as_mut_ptr() as *mut libc::c_char,
                               dst.len() as libc::size_t, &self.raw);
        }
        f.write(dst.slice_to(dst.iter().position(|&a| a == 0).unwrap()))
    }
}

impl PartialEq for Oid {
    fn eq(&self, other: &Oid) -> bool {
        unsafe { raw::git_oid_equal(&self.raw, &other.raw) != 0 }
    }
}
impl Eq for Oid {}

impl PartialOrd for Oid {
    fn partial_cmp(&self, other: &Oid) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Oid {
    fn cmp(&self, other: &Oid) -> Ordering {
        match unsafe { raw::git_oid_cmp(&self.raw, &other.raw) } {
            0 => Equal,
            n if n < 0 => Less,
            _ => Greater,
        }
    }
}

impl Clone for Oid {
    fn clone(&self) -> Oid { *self }
}

impl Hash for Oid {
    fn hash(&self, into: &mut sip::SipState) {
        self.raw.id.as_slice().hash(into)
    }
}

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

    #[test]
    fn conversions() {
        assert!(Oid::from_str("foo").is_err());
        assert!(Oid::from_str("decbf2be529ab6557d5429922251e5ee36519817").is_ok());
        assert!(Oid::from_bytes(b"foo").is_err());
        assert!(Oid::from_bytes(b"00000000000000000000").is_ok());
    }
}
<commit_msg>Add Oid::as_bytes<commit_after>use std::fmt;
use std::hash::{sip, Hash};
use libc;

use {raw, Error};

/// Unique identity of any object (commit, tree, blob, tag).
pub struct Oid {
    raw: raw::git_oid,
}

impl Oid {
    /// Create a new Oid from a raw libgit2 oid structure.
    ///
    /// This function is unsafe as it does not know if the memory pointed to by
    /// `oid` is valid or not.
    pub unsafe fn from_raw(oid: *const raw::git_oid) -> Oid {
        ::init();
        Oid { raw: *oid }
    }

    /// Parse a hex-formatted object id into an Oid structure.
    ///
    /// If the string is not a valid 40-character hex string, an error is
    /// returned.
    pub fn from_str(s: &str) -> Result<Oid, Error> {
        ::init();
        let mut raw = raw::git_oid { id: [0, ..raw::GIT_OID_RAWSZ] };
        try!(::doit(|| unsafe {
            raw::git_oid_fromstrn(&mut raw,
                                  s.as_bytes().as_ptr() as *const libc::c_char,
                                  s.len() as libc::size_t)
        }));
        Ok(Oid { raw: raw })
    }

    /// Parse a raw object id into an Oid structure.
    ///
    /// If the array given is not 20 bytes in length, an error is returned.
    pub fn from_bytes(bytes: &[u8]) -> Result<Oid, Error> {
        ::init();
        let mut raw = raw::git_oid { id: [0, ..raw::GIT_OID_RAWSZ] };
        if bytes.len() != raw::GIT_OID_RAWSZ {
            Err(Error::from_str("raw byte array must be 20 bytes"))
        } else {
            unsafe { raw::git_oid_fromraw(&mut raw, bytes.as_ptr()) }
            Ok(Oid { raw: raw })
        }
    }

    /// Gain access to the underlying raw oid pointer
    pub fn raw(&self) -> *const raw::git_oid { &self.raw as *const _ }

    /// View this OID as a byte-slice 20 bytes in length.
    pub fn as_bytes(&self) -> &[u8] { self.raw.id.as_slice() }
}

impl fmt::Show for Oid {
    /// Hex-encode this Oid into a formatter.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut dst = [0u8, ..raw::GIT_OID_HEXSZ + 1];
        unsafe {
            raw::git_oid_tostr(dst.as_mut_ptr() as *mut libc::c_char,
                               dst.len() as libc::size_t, &self.raw);
        }
        f.write(dst.slice_to(dst.iter().position(|&a| a == 0).unwrap()))
    }
}

impl PartialEq for Oid {
    fn eq(&self, other: &Oid) -> bool {
        unsafe { raw::git_oid_equal(&self.raw, &other.raw) != 0 }
    }
}
impl Eq for Oid {}

impl PartialOrd for Oid {
    fn partial_cmp(&self, other: &Oid) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Oid {
    fn cmp(&self, other: &Oid) -> Ordering {
        match unsafe { raw::git_oid_cmp(&self.raw, &other.raw) } {
            0 => Equal,
            n if n < 0 => Less,
            _ => Greater,
        }
    }
}

impl Clone for Oid {
    fn clone(&self) -> Oid { *self }
}

impl Hash for Oid {
    fn hash(&self, into: &mut sip::SipState) {
        self.raw.id.as_slice().hash(into)
    }
}

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

    #[test]
    fn conversions() {
        assert!(Oid::from_str("foo").is_err());
        assert!(Oid::from_str("decbf2be529ab6557d5429922251e5ee36519817").is_ok());
        assert!(Oid::from_bytes(b"foo").is_err());
        assert!(Oid::from_bytes(b"00000000000000000000").is_ok());
    }
}
<|endoftext|>


<commit_before>
<commit_msg>remove unused file<commit_after><|endoftext|>