<commit_before>//!Available RPC methods types and ids.

use ssz::{impl_decode_via_from, impl_encode_via_from};
use ssz_derive::{Decode, Encode};
use types::{Epoch, Hash256, Slot};

/* Request/Response data structures for RPC methods */

/* Requests */

pub type RequestId = usize;

/// The HELLO request/response handshake message.
#[derive(Encode, Decode, Clone, Debug)]
pub struct HelloMessage {
    /// The fork version of the chain we are broadcasting.
    pub fork_version: [u8; 4],

    /// Latest finalized root.
    pub finalized_root: Hash256,

    /// Latest finalized epoch.
    pub finalized_epoch: Epoch,

    /// The latest block root.
    pub head_root: Hash256,

    /// The slot associated with the latest block root.
    pub head_slot: Slot,
}

/// The reason given for a `Goodbye` message.
///
/// Note: any unknown `u64::into(n)` will resolve to `Goodbye::Unknown` for any unknown `n`,
/// however `GoodbyeReason::Unknown.into()` will go into `0_u64`. Therefore de-serializing then
/// re-serializing may not return the same bytes.
#[derive(Debug, Clone)]
pub enum GoodbyeReason {
    /// This node has shutdown.
    ClientShutdown = 1,

    /// Incompatible networks.
    IrrelevantNetwork = 2,

    /// Error/fault in the RPC.
    Fault = 3,

    /// Unknown reason.
    Unknown = 0,
}

impl From<u64> for GoodbyeReason {
    fn from(id: u64) -> GoodbyeReason {
        match id {
            1 => GoodbyeReason::ClientShutdown,
            2 => GoodbyeReason::IrrelevantNetwork,
            3 => GoodbyeReason::Fault,
            _ => GoodbyeReason::Unknown,
        }
    }
}

impl Into<u64> for GoodbyeReason {
    fn into(self) -> u64 {
        self as u64
    }
}

impl_encode_via_from!(GoodbyeReason, u64);
impl_decode_via_from!(GoodbyeReason, u64);

/// Request a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct BeaconBlocksRequest {
    /// The hash tree root of a block on the requested chain.
    pub head_block_root: Hash256,

    /// The starting slot to request blocks.
    pub start_slot: u64,

    /// The number of blocks from the start slot.
    pub count: u64,

    /// The step increment to receive blocks.
    ///
    /// A value of 1 returns every block.
    /// A value of 2 returns every second block.
    /// A value of 3 returns every third block and so on.
    pub step: u64,
}

// TODO: Currently handle encoding/decoding of blocks in the message handler. Leave this struct
// here in case encoding/decoding of ssz requires an object.
/*
/// Response containing a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct BeaconBlocksResponse {
    /// List of requested blocks and associated slots.
    pub beacon_blocks: Vec<u8>,
}
*/

/// Request a number of beacon block bodies from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct RecentBeaconBlocksRequest {
    /// The list of beacon block bodies being requested.
    pub block_roots: Vec<Hash256>,
}

/* RPC Handling and Grouping */
// Collection of enums and structs used by the Codecs to encode/decode RPC messages

#[derive(Debug, Clone)]
pub enum RPCResponse {
    /// A HELLO message.
    Hello(HelloMessage),
    /// A response to a get BEACON_BLOCKS request.
    BeaconBlocks(Vec<u8>),
    /// A response to a get RECENT_BEACON_BLOCKS request.
    RecentBeaconBlocks(Vec<u8>),
}

#[derive(Debug)]
pub enum RPCErrorResponse {
    Success(RPCResponse),
    InvalidRequest(ErrorMessage),
    ServerError(ErrorMessage),
    Unknown(ErrorMessage),
}

impl RPCErrorResponse {
    /// Used to encode the response.
    pub fn as_u8(&self) -> u8 {
        match self {
            RPCErrorResponse::Success(_) => 0,
            RPCErrorResponse::InvalidRequest(_) => 1,
            RPCErrorResponse::ServerError(_) => 2,
            RPCErrorResponse::Unknown(_) => 255,
        }
    }

    /// Tells the codec whether to decode as an RPCResponse or an error.
    pub fn is_response(response_code: u8) -> bool {
        match response_code {
            0 => true,
            _ => false,
        }
    }

    /// Builds an RPCErrorResponse from a response code and an ErrorMessage
    pub fn from_error(response_code: u8, err: ErrorMessage) -> Self {
        match response_code {
            1 => RPCErrorResponse::InvalidRequest(err),
            2 => RPCErrorResponse::ServerError(err),
            _ => RPCErrorResponse::Unknown(err),
        }
    }
}

#[derive(Encode, Decode, Debug)]
pub struct ErrorMessage {
    /// The UTF-8 encoded Error message string.
    pub error_message: Vec<u8>,
}

impl ErrorMessage {
    pub fn as_string(&self) -> String {
        String::from_utf8(self.error_message.clone()).unwrap_or_else(|_| "".into())
    }
}
<commit_msg>Remove redundant code<commit_after>//!Available RPC methods types and ids.

use ssz::{impl_decode_via_from, impl_encode_via_from};
use ssz_derive::{Decode, Encode};
use types::{Epoch, Hash256, Slot};

/* Request/Response data structures for RPC methods */

/* Requests */

pub type RequestId = usize;

/// The HELLO request/response handshake message.
#[derive(Encode, Decode, Clone, Debug)]
pub struct HelloMessage {
    /// The fork version of the chain we are broadcasting.
    pub fork_version: [u8; 4],

    /// Latest finalized root.
    pub finalized_root: Hash256,

    /// Latest finalized epoch.
    pub finalized_epoch: Epoch,

    /// The latest block root.
    pub head_root: Hash256,

    /// The slot associated with the latest block root.
    pub head_slot: Slot,
}

/// The reason given for a `Goodbye` message.
///
/// Note: any unknown `u64::into(n)` will resolve to `Goodbye::Unknown` for any unknown `n`,
/// however `GoodbyeReason::Unknown.into()` will go into `0_u64`. Therefore de-serializing then
/// re-serializing may not return the same bytes.
#[derive(Debug, Clone)]
pub enum GoodbyeReason {
    /// This node has shutdown.
    ClientShutdown = 1,

    /// Incompatible networks.
    IrrelevantNetwork = 2,

    /// Error/fault in the RPC.
    Fault = 3,

    /// Unknown reason.
    Unknown = 0,
}

impl From<u64> for GoodbyeReason {
    fn from(id: u64) -> GoodbyeReason {
        match id {
            1 => GoodbyeReason::ClientShutdown,
            2 => GoodbyeReason::IrrelevantNetwork,
            3 => GoodbyeReason::Fault,
            _ => GoodbyeReason::Unknown,
        }
    }
}

impl Into<u64> for GoodbyeReason {
    fn into(self) -> u64 {
        self as u64
    }
}

impl_encode_via_from!(GoodbyeReason, u64);
impl_decode_via_from!(GoodbyeReason, u64);

/// Request a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct BeaconBlocksRequest {
    /// The hash tree root of a block on the requested chain.
    pub head_block_root: Hash256,

    /// The starting slot to request blocks.
    pub start_slot: u64,

    /// The number of blocks from the start slot.
    pub count: u64,

    /// The step increment to receive blocks.
    ///
    /// A value of 1 returns every block.
    /// A value of 2 returns every second block.
    /// A value of 3 returns every third block and so on.
    pub step: u64,
}

/// Request a number of beacon block bodies from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct RecentBeaconBlocksRequest {
    /// The list of beacon block bodies being requested.
    pub block_roots: Vec<Hash256>,
}

/* RPC Handling and Grouping */
// Collection of enums and structs used by the Codecs to encode/decode RPC messages

#[derive(Debug, Clone)]
pub enum RPCResponse {
    /// A HELLO message.
    Hello(HelloMessage),
    /// A response to a get BEACON_BLOCKS request.
    BeaconBlocks(Vec<u8>),
    /// A response to a get RECENT_BEACON_BLOCKS request.
    RecentBeaconBlocks(Vec<u8>),
}

#[derive(Debug)]
pub enum RPCErrorResponse {
    Success(RPCResponse),
    InvalidRequest(ErrorMessage),
    ServerError(ErrorMessage),
    Unknown(ErrorMessage),
}

impl RPCErrorResponse {
    /// Used to encode the response.
    pub fn as_u8(&self) -> u8 {
        match self {
            RPCErrorResponse::Success(_) => 0,
            RPCErrorResponse::InvalidRequest(_) => 1,
            RPCErrorResponse::ServerError(_) => 2,
            RPCErrorResponse::Unknown(_) => 255,
        }
    }

    /// Tells the codec whether to decode as an RPCResponse or an error.
    pub fn is_response(response_code: u8) -> bool {
        match response_code {
            0 => true,
            _ => false,
        }
    }

    /// Builds an RPCErrorResponse from a response code and an ErrorMessage
    pub fn from_error(response_code: u8, err: ErrorMessage) -> Self {
        match response_code {
            1 => RPCErrorResponse::InvalidRequest(err),
            2 => RPCErrorResponse::ServerError(err),
            _ => RPCErrorResponse::Unknown(err),
        }
    }
}

#[derive(Encode, Decode, Debug)]
pub struct ErrorMessage {
    /// The UTF-8 encoded Error message string.
    pub error_message: Vec<u8>,
}

impl ErrorMessage {
    pub fn as_string(&self) -> String {
        String::from_utf8(self.error_message.clone()).unwrap_or_else(|_| "".into())
    }
}
<|endoftext|>


<commit_before>use crate::beacon_chain::BeaconChain;
use crate::error;
use crate::messages::NodeMessage;
use crate::service::{NetworkMessage, OutgoingMessage};
use crate::sync::SimpleSync;
use crossbeam_channel::{unbounded as channel, Sender};
use futures::future;
use futures::prelude::*;
use libp2p::{
    rpc::{RPCMethod, RPCRequest, RPCResponse},
    PeerId, RPCEvent,
};
use slog::warn;
use slog::{debug, trace};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use types::Hash256;

/// Timeout for RPC requests.
const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);

/// Handles messages received from the network and client and organises syncing.
pub struct MessageHandler {
    /// Currently loaded and initialised beacon chain.
    chain: Arc<BeaconChain>,
    /// The syncing framework.
    sync: SimpleSync,
    /// The network channel to relay messages to the Network service.
    network_send: crossbeam_channel::Sender<NetworkMessage>,
    /// A mapping of peers we have sent an RPC request to.
    requests: HashMap<PeerId, Vec<RPCRequestInfo>>,
    /// A counter of request id for each peer.
    request_ids: HashMap<PeerId, u64>,
    /// The `MessageHandler` logger.
    log: slog::Logger,
}

/// RPC request information
pub struct RPCRequestInfo {
    /// The id of the request
    id: u64,
    /// The time the request was sent, to check ttl.
    request_time: Instant,
}

/// Types of messages the handler can receive.
#[derive(Debug, Clone)]
pub enum HandlerMessage {
    /// We have initiated a connection to a new peer.
    PeerDialed(PeerId),
    /// Peer has disconnected,
    PeerDisconnected(PeerId),
    /// A Node message has been received.
    Message(PeerId, NodeMessage),
    /// An RPC response/request has been received.
    RPC(PeerId, RPCEvent),
}

impl MessageHandler {
    /// Initializes and runs the MessageHandler.
    pub fn new(
        beacon_chain: Arc<BeaconChain>,
        network_send: crossbeam_channel::Sender<NetworkMessage>,
        executor: &tokio::runtime::TaskExecutor,
        log: slog::Logger,
    ) -> error::Result<Sender<HandlerMessage>> {
        debug!(log, "Service starting");

        let (handler_send, handler_recv) = channel();

        // Initialise sync and begin processing in thread
        // generate the Message handler
        let sync = SimpleSync::new(beacon_chain.clone());

        let mut handler = MessageHandler {
            // TODO: The handler may not need a chain, perhaps only sync?
            chain: beacon_chain.clone(),
            sync,
            network_send,
            requests: HashMap::new(),
            request_ids: HashMap::new(),
            log: log.clone(),
        };

        // spawn handler task
        // TODO: Handle manual termination of thread
        executor.spawn(future::poll_fn(move || -> Result<_, _> {
            loop {
                handler.handle_message(handler_recv.recv().map_err(|_| {
                    debug!(log, "Network message handler terminated.");
                })?);
            }
        }));

        Ok(handler_send)
    }

    fn handle_message(&mut self, message: HandlerMessage) {
        match message {
            // we have initiated a connection to a peer
            HandlerMessage::PeerDialed(peer_id) => {
                self.send_hello_request(peer_id);
            }
            // we have received an RPC message request/response
            HandlerMessage::RPC(peer_id, rpc_event) => {
                self.handle_rpc_message(peer_id, rpc_event);
            }
            //TODO: Handle all messages
            _ => {}
        }
    }

    fn handle_rpc_message(&mut self, peer_id: PeerId, rpc_message: RPCEvent) {
        match rpc_message {
            RPCEvent::Request {
                id,
                method_id: _,
                body,
            } => self.handle_rpc_request(peer_id, id, body),
            RPCEvent::Response {
                id,
                method_id: _,
                result,
            } => self.handle_rpc_response(peer_id, id, result),
        }
    }

    fn handle_rpc_request(&mut self, peer_id: PeerId, id: u64, request: RPCRequest) {}

    // we match on id and ignore responses past the timeout.
    fn handle_rpc_response(&mut self, peer_id: PeerId, id: u64, response: RPCResponse) {}

    /// Sends a HELLO RPC request to a newly connected peer.
    fn send_hello_request(&mut self, peer_id: PeerId) {
        // generate a unique id for the peer
        let id = {
            let borrowed_id = self.request_ids.entry(peer_id.clone()).or_insert_with(|| 0);
            let id = borrowed_id.clone();
            //increment the counter
            *borrowed_id += 1;
            id
        };
        // register RPC request
        {
            let requests = self
                .requests
                .entry(peer_id.clone())
                .or_insert_with(|| vec![]);
            requests.push(RPCRequestInfo {
                id: id.clone(),
                request_time: Instant::now(),
            });
        }

        // build the rpc request
        let rpc_event = RPCEvent::Request {
            id,
            method_id: RPCMethod::Hello.into(),
            body: RPCRequest::Hello(self.sync.generate_hello()),
        };

        // send the hello request to the network
        trace!(self.log, "Sending HELLO message to peer {:?}", peer_id);
        self.send_rpc(peer_id, rpc_event);
    }

    /// Sends an RPC request/response to the network server.
    fn send_rpc(&self, peer_id: PeerId, rpc_event: RPCEvent) {
        self.network_send
            .send(NetworkMessage::Send(
                peer_id,
                OutgoingMessage::RPC(rpc_event),
            ))
            .unwrap_or_else(|_| {
                warn!(
                    self.log,
                    "Could not send RPC message to the network service"
                )
            });
    }
}
<commit_msg>Initial handling RPC responses<commit_after>use crate::beacon_chain::BeaconChain;
use crate::error;
use crate::messages::NodeMessage;
use crate::service::{NetworkMessage, OutgoingMessage};
use crate::sync::SimpleSync;
use crossbeam_channel::{unbounded as channel, Sender};
use futures::future;
use futures::prelude::*;
use libp2p::{
    rpc::{RPCMethod, RPCRequest, RPCResponse},
    HelloMessage, PeerId, RPCEvent,
};
use slog::warn;
use slog::{debug, trace};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use types::Hash256;

/// Timeout for RPC requests.
const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);

/// Handles messages received from the network and client and organises syncing.
pub struct MessageHandler {
    /// Currently loaded and initialised beacon chain.
    chain: Arc<BeaconChain>,
    /// The syncing framework.
    sync: SimpleSync,
    /// The network channel to relay messages to the Network service.
    network_send: crossbeam_channel::Sender<NetworkMessage>,
    /// A mapping of peers we have sent an RPC request to.
    requests: HashMap<PeerId, Vec<RPCRequestInfo>>,
    /// A counter of request id for each peer.
    request_ids: HashMap<PeerId, u64>,
    /// The `MessageHandler` logger.
    log: slog::Logger,
}

/// RPC request information
pub struct RPCRequestInfo {
    /// The id of the request
    id: u64,
    /// The time the request was sent, to check ttl.
    request_time: Instant,
}

/// Types of messages the handler can receive.
#[derive(Debug, Clone)]
pub enum HandlerMessage {
    /// We have initiated a connection to a new peer.
    PeerDialed(PeerId),
    /// Peer has disconnected,
    PeerDisconnected(PeerId),
    /// A Node message has been received.
    Message(PeerId, NodeMessage),
    /// An RPC response/request has been received.
    RPC(PeerId, RPCEvent),
}

impl MessageHandler {
    /// Initializes and runs the MessageHandler.
    pub fn new(
        beacon_chain: Arc<BeaconChain>,
        network_send: crossbeam_channel::Sender<NetworkMessage>,
        executor: &tokio::runtime::TaskExecutor,
        log: slog::Logger,
    ) -> error::Result<Sender<HandlerMessage>> {
        debug!(log, "Service starting");

        let (handler_send, handler_recv) = channel();

        // Initialise sync and begin processing in thread
        // generate the Message handler
        let sync = SimpleSync::new(beacon_chain.clone());

        let mut handler = MessageHandler {
            // TODO: The handler may not need a chain, perhaps only sync?
            chain: beacon_chain.clone(),
            sync,
            network_send,
            requests: HashMap::new(),
            request_ids: HashMap::new(),
            log: log.clone(),
        };

        // spawn handler task
        // TODO: Handle manual termination of thread
        executor.spawn(future::poll_fn(move || -> Result<_, _> {
            loop {
                handler.handle_message(handler_recv.recv().map_err(|_| {
                    debug!(log, "Network message handler terminated.");
                })?);
            }
        }));

        Ok(handler_send)
    }

    fn handle_message(&mut self, message: HandlerMessage) {
        match message {
            // we have initiated a connection to a peer
            HandlerMessage::PeerDialed(peer_id) => {
                self.send_hello_request(peer_id);
            }
            // we have received an RPC message request/response
            HandlerMessage::RPC(peer_id, rpc_event) => {
                self.handle_rpc_message(peer_id, rpc_event);
            }
            //TODO: Handle all messages
            _ => {}
        }
    }

    fn handle_rpc_message(&mut self, peer_id: PeerId, rpc_message: RPCEvent) {
        match rpc_message {
            RPCEvent::Request {
                id,
                method_id: _, // TODO: Clean up RPC Message types, have a cleaner type by this point.
                body,
            } => self.handle_rpc_request(peer_id, id, body),
            RPCEvent::Response {
                id,
                method_id: _,
                result,
            } => self.handle_rpc_response(peer_id, id, result),
        }
    }

    /// A new RPC request has been received from the network.
    fn handle_rpc_request(&mut self, peer_id: PeerId, id: u64, request: RPCRequest) {
        match request {
            RPCRequest::Hello(hello_message) => {
                self.handle_hello_response(peer_id, id, hello_message)
            }
        }
    }

    /// An RPC response has been received from the network.
    // we match on id and ignore responses past the timeout.
    fn handle_rpc_response(&mut self, peer_id: PeerId, id: u64, response: RPCResponse) {}

    fn handle_hello_response(&mut self, peer_id: PeerId, id: u64, response: HelloMessage) {
        /*
                // if response id is not in our list, ignore (likely RPC timeout)
                match self.requests.get(peer_id) {
                    None => return;
                    Some(rpc_info) => {
                        if rpc_info.con

        */

    }

    /// Sends a HELLO RPC request to a newly connected peer.
    fn send_hello_request(&mut self, peer_id: PeerId) {
        // generate a unique id for the peer
        let id = {
            let borrowed_id = self.request_ids.entry(peer_id.clone()).or_insert_with(|| 0);
            let id = borrowed_id.clone();
            //increment the counter
            *borrowed_id += 1;
            id
        };
        // register RPC request
        {
            let requests = self
                .requests
                .entry(peer_id.clone())
                .or_insert_with(|| vec![]);
            requests.push(RPCRequestInfo {
                id: id.clone(),
                request_time: Instant::now(),
            });
        }

        // build the rpc request
        let rpc_event = RPCEvent::Request {
            id,
            method_id: RPCMethod::Hello.into(),
            body: RPCRequest::Hello(self.sync.generate_hello()),
        };

        // send the hello request to the network
        trace!(self.log, "Sending HELLO message to peer {:?}", peer_id);
        self.send_rpc(peer_id, rpc_event);
    }

    /// Sends an RPC request/response to the network server.
    fn send_rpc(&self, peer_id: PeerId, rpc_event: RPCEvent) {
        self.network_send
            .send(NetworkMessage::Send(
                peer_id,
                OutgoingMessage::RPC(rpc_event),
            ))
            .unwrap_or_else(|_| {
                warn!(
                    self.log,
                    "Could not send RPC message to the network service"
                )
            });
    }
}
<|endoftext|>


<commit_before>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 7;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = canvas_size.width.min(canvas_size.height) as f64 - 2.0 * BORDER_MARGIN;
    let start_point_coord = -auto_size / 2.0;

    turtle.pen_up();
    turn_and_go_to(turtle, [start_point_coord, start_point_coord].into());
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());

    turtle.hide();
}
<commit_msg>Draw less levels on Sierpinski Triangle example<commit_after>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 6;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = canvas_size.width.min(canvas_size.height) as f64 - 2.0 * BORDER_MARGIN;
    let start_point_coord = -auto_size / 2.0;

    turtle.pen_up();
    turn_and_go_to(turtle, [start_point_coord, start_point_coord].into());
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());

    turtle.hide();
}
<|endoftext|>


<commit_before>use crate::common::util::*;

#[test]
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
fn test_groups() {
    if !is_ci() {
        new_ucmd!().succeeds().stdout_is(expected_result(&[]));
    } else {
        // TODO: investigate how this could be tested in CI
        // stderr = groups: cannot find name for group ID 116
        println!("test skipped:");
    }
}

#[test]
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
#[ignore = "fixme: 'groups USERNAME' needs more debugging"]
fn test_groups_username() {
    let scene = TestScenario::new(util_name!());
    let whoami_result = scene.cmd("whoami").run();

    let username = if whoami_result.succeeded() {
        whoami_result.stdout_move_str()
    } else if is_ci() {
        String::from("docker")
    } else {
        println!("test skipped:");
        return;
    };

    // TODO: stdout should be in the form: "username : group1 group2 group3"

    scene
        .ucmd()
        .arg(&username)
        .succeeds()
        .stdout_is(expected_result(&[&username]));
}

#[cfg(any(target_vendor = "apple", target_os = "linux"))]
fn expected_result(args: &[&str]) -> String {
    let util_name = "id";

    TestScenario::new(&util_name)
        .cmd_keepenv(util_name)
        .env("LANGUAGE", "C")
        .args(args)
        .args(&["-Gn"])
        .succeeds()
        .stdout_move_str()
}
<commit_msg>Revert "groups: fix test for arch"<commit_after>use crate::common::util::*;

#[test]
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
fn test_groups() {
    if !is_ci() {
        new_ucmd!().succeeds().stdout_is(expected_result(&[]));
    } else {
        // TODO: investigate how this could be tested in CI
        // stderr = groups: cannot find name for group ID 116
        println!("test skipped:");
    }
}

#[test]
#[cfg(any(target_os = "linux"))]
#[ignore = "fixme: 'groups USERNAME' needs more debugging"]
fn test_groups_username() {
    let scene = TestScenario::new(util_name!());
    let whoami_result = scene.cmd("whoami").run();

    let username = if whoami_result.succeeded() {
        whoami_result.stdout_move_str()
    } else if is_ci() {
        String::from("docker")
    } else {
        println!("test skipped:");
        return;
    };

    // TODO: stdout should be in the form: "username : group1 group2 group3"

    scene
        .ucmd()
        .arg(&username)
        .succeeds()
        .stdout_is(expected_result(&[&username]));
}

#[cfg(any(target_vendor = "apple", target_os = "linux"))]
fn expected_result(args: &[&str]) -> String {
    #[cfg(target_os = "linux")]
    let util_name = util_name!();
    #[cfg(target_vendor = "apple")]
    let util_name = format!("g{}", util_name!());

    TestScenario::new(&util_name)
        .cmd_keepenv(util_name)
        .env("LANGUAGE", "C")
        .args(args)
        .succeeds()
        .stdout_move_str()
}
<|endoftext|>


<commit_before>use crate::common::util::*;

// Apparently some CI environments have configuration issues, e.g. with 'whoami' and 'id'.
// If we are running inside the CI and "needle" is in "stderr" skipping this test is
// considered okay. If we are not inside the CI this calls assert!(result.success).
//
// From the Logs: "Build (ubuntu-18.04, x86_64-unknown-linux-gnu, feat_os_unix, use-cross)"
// stderr: "whoami: failed to get username"
// Maybe: "adduser --uid 1001 username" can put things right?
fn skipping_test_is_okay(result: &CmdResult, needle: &str) -> bool {
    if !result.succeeded() {
        println!("result.stdout = {}", result.stdout_str());
        println!("result.stderr = {}", result.stderr_str());
        if is_ci() && result.stderr_str().contains(needle) {
            println!("test skipped:");
            return true;
        } else {
            result.success();
        }
    }
    false
}

#[test]
fn test_normal() {
    let (_, mut ucmd) = at_and_ucmd!();

    let result = ucmd.run();

    // use std::env;
    // println!("env::var(CI).is_ok() = {}", env::var("CI").is_ok());
    // for (key, value) in env::vars() {
    //     println!("{}: {}", key, value);
    // }

    if skipping_test_is_okay(&result, "failed to get username") {
        return;
    }

    result.no_stderr();
    assert!(!result.stdout_str().trim().is_empty());
}

#[test]
#[cfg(not(windows))]
fn test_normal_compare_id() {
    let scene = TestScenario::new(util_name!());

    let result_ucmd = scene.ucmd().run();
    if skipping_test_is_okay(&result_ucmd, "failed to get username") {
        return;
    }

    let result_cmd = scene.cmd("id").arg("-un").run();
    if skipping_test_is_okay(&result_cmd, "cannot find name for user ID") {
        return;
    }

    assert_eq!(
        result_ucmd.stdout_str().trim(),
        result_cmd.stdout_str().trim()
    );
}
<commit_msg>test_whoami: refactor use expected_result and whoami from common/util.rs<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

use crate::common::util::*;

#[test]
#[cfg(unix)]
fn test_normal() {
    let ts = TestScenario::new(util_name!());
    let result = ts.ucmd().run();
    let exp_result = unwrap_or_return!(expected_result(&ts, &[]));

    result
        .stdout_is(exp_result.stdout_str())
        .stderr_is(exp_result.stderr_str())
        .code_is(exp_result.code());
}

#[test]
#[cfg(unix)]
fn test_normal_compare_id() {
    let ts = TestScenario::new("id");
    let id_un = unwrap_or_return!(expected_result(&ts, &["-un"]));
    if id_un.succeeded() {
        new_ucmd!().succeeds().stdout_is(id_un.stdout_str());
    } else if is_ci() && id_un.stderr_str().contains("cannot find name for user ID") {
        println!("test skipped:");
    } else {
        id_un.success();
    }
}

#[test]
#[cfg(unix)]
fn test_normal_compare_env() {
    let whoami = whoami();
    if whoami == "nobody" {
        println!("test skipped:");
        return;
    } else {
        new_ucmd!().succeeds().stdout_is(format!("{}\n", whoami));
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::collections::hash_map::Entry;

fn lowercase(word: &str) -> String {
    let mut lower = String::with_capacity(word.len());
    for c in word.chars() {
        for low in c.to_lowercase() {
            lower.push(low);
        }
    }
    lower
}

pub fn word_count(input: &str) -> HashMap<String, u32> {
    let mut map: HashMap<String, u32> = HashMap::new();
    let lower = lowercase(input);
    let slice: &str = lower.as_ref();
    for word in slice.split(|c: char| !c.is_alphanumeric()).filter(|s| !s.is_empty()) {
        match map.entry(word.to_string()) {
            Entry::Vacant(entry) => { entry.insert(1); },
            Entry::Occupied(mut entry) => {
                *entry.get_mut() += 1;
            }
        };
    }
    map
}
<commit_msg>word-count: Use `Entry#or_insert` in `word_count`<commit_after>use std::collections::HashMap;

fn lowercase(word: &str) -> String {
    let mut lower = String::with_capacity(word.len());
    for c in word.chars() {
        for low in c.to_lowercase() {
            lower.push(low);
        }
    }
    lower
}

pub fn word_count(input: &str) -> HashMap<String, u32> {
    let mut map: HashMap<String, u32> = HashMap::new();
    let lower = lowercase(input);
    let slice: &str = lower.as_ref();
    for word in slice.split(|c: char| !c.is_alphanumeric()).filter(|s| !s.is_empty()) {
        *map.entry(word.to_string()).or_insert(0) += 1;
    }
    map
}
<|endoftext|>


<commit_before>use clap::{App, Arg};

fn main() {
    // Once all App settings (including all arguments) have been set, you call get_matches() which
    // parses the string provided by the user, and returns all the valid matches to the ones you
    // specified.
    //
    // You can then query the matches struct to get information about how the user ran the program
    // at startup.
    //
    // For this example, let's assume you created an App which accepts three arguments (plus two
    // generated by clap), a flag to display debugging information triggered with "-d" or
    // "--debug" as well as an option argument which specifies a custom configuration file to use
    // triggered with "-c file" or "--config file" or "--config=file" and finally a positional
    // argument which is the input file we want to work with, this will be the only required
    // argument.
    let matches = App::new("MyApp")
        .about("Parses an input file to do awesome things")
        .version("1.0")
        .author("Kevin K. <kbknapp@gmail.com>")
        .arg(
            Arg::with_name("debug")
                .about("turn on debugging information")
                .short('d')
                .long("debug"),
        )
        .arg(
            Arg::with_name("config")
                .about("sets the config file to use")
                .short('c')
                .long("config")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("input")
                .about("the input file to use")
                .index(1)
                .required(true),
        )
        .get_matches();

    // We can find out whether or not debugging was turned on
    if matches.is_present("debug") {
        println!("Debugging is turned on");
    }

    // If we wanted to some custom initialization based off some configuration file provided
    // by the user, we could get the file (A string of the file)
    if let Some(ref file) = matches.value_of("config") {
        println!("Using config file: {}", file);
    }

    // Because "input" is required we can safely call unwrap() because had the user NOT
    // specified a value, clap would have explained the error the user, and exited.
    println!(
        "Doing real work with file: {}",
        matches.value_of("input").unwrap()
    );

    // Continued program logic goes here...
}
<commit_msg>fix typo in example 04_using_matches.rs<commit_after>use clap::{App, Arg};

fn main() {
    // Once all App settings (including all arguments) have been set, you call get_matches() which
    // parses the string provided by the user, and returns all the valid matches to the ones you
    // specified.
    //
    // You can then query the matches struct to get information about how the user ran the program
    // at startup.
    //
    // For this example, let's assume you created an App which accepts three arguments (plus two
    // generated by clap), a flag to display debugging information triggered with "-d" or
    // "--debug" as well as an option argument which specifies a custom configuration file to use
    // triggered with "-c file" or "--config file" or "--config=file" and finally a positional
    // argument which is the input file we want to work with, this will be the only required
    // argument.
    let matches = App::new("MyApp")
        .about("Parses an input file to do awesome things")
        .version("1.0")
        .author("Kevin K. <kbknapp@gmail.com>")
        .arg(
            Arg::with_name("debug")
                .about("turn on debugging information")
                .short('d')
                .long("debug"),
        )
        .arg(
            Arg::with_name("config")
                .about("sets the config file to use")
                .short('c')
                .long("config")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("input")
                .about("the input file to use")
                .index(1)
                .required(true),
        )
        .get_matches();

    // We can find out whether or not debugging was turned on
    if matches.is_present("debug") {
        println!("Debugging is turned on");
    }

    // If we wanted to do some custom initialization based off some configuration file
    // provided by the user, we could get the file (A string of the file)
    if let Some(ref file) = matches.value_of("config") {
        println!("Using config file: {}", file);
    }

    // Because "input" is required we can safely call unwrap() because had the user NOT
    // specified a value, clap would have explained the error the user, and exited.
    println!(
        "Doing real work with file: {}",
        matches.value_of("input").unwrap()
    );

    // Continued program logic goes here...
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::slice;

use gc::{Gc, Traverseable};

/// Abstract array type which have their length store inline with the elements.
/// Fills the same role as Box<[T]> but takes only 8 bytes on the stack instead of 16
#[repr(C)]
pub struct Array<T: Copy> {
    len: usize,
    array_start: [T; 0],
}

impl<T: Copy> AsRef<[T]> for Array<T> {
    fn as_ref(&self) -> &[T] {
        self
    }
}

impl<T: Copy> AsMut<[T]> for Array<T> {
    fn as_mut(&mut self) -> &mut [T] {
        self
    }
}

impl<T: Copy + PartialEq> PartialEq for Array<T> {
    fn eq(&self, other: &Array<T>) -> bool {
        &**self == other.as_ref()
    }
}

impl<T: Copy + Eq> Eq for Array<T> {}

impl<T: Copy + PartialOrd> PartialOrd for Array<T> {
    fn partial_cmp(&self, other: &Array<T>) -> Option<Ordering> {
        (&**self).partial_cmp(other.as_ref())
    }
}

impl<T: Copy + Ord> Ord for Array<T> {
    fn cmp(&self, other: &Array<T>) -> Ordering {
        (&**self).cmp(other)
    }
}

impl<T: Copy + Hash> Hash for Array<T> {
    fn hash<H>(&self, hasher: &mut H)
    where
        H: Hasher,
    {
        (&**self).hash(hasher)
    }
}

impl<T: Copy + fmt::Debug> fmt::Debug for Array<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", &**self)
    }
}

impl<T: Copy + Traverseable> Traverseable for Array<T> {
    fn traverse(&self, gc: &mut Gc) {
        (**self).traverse(gc)
    }
}

impl<T: Copy> Array<T> {
    pub fn size_of(len: usize) -> usize {
        mem::size_of::<usize>() + mem::size_of::<T>() * len
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        self.len = len;
    }

    /// Initializes an Array.
    /// To be safe it is required that the iterators length is known and exactly the same as the
    /// length of the allocated array.
    pub unsafe fn initialize<I>(&mut self, iterable: I)
    where
        I: IntoIterator<Item = T>,
    {
        let iter = iterable.into_iter();
        self.len = iter.size_hint()
            .1
            .expect("initialize expected a known length");
        for (field, value) in self.iter_mut().zip(iter) {
            *field = value;
        }
    }
}

impl<T: Copy> Deref for Array<T> {
    type Target = [T];
    fn deref(&self) -> &[T] {
        unsafe { slice::from_raw_parts(self.array_start.as_ptr(), self.len) }
    }
}

impl<T: Copy> DerefMut for Array<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe { slice::from_raw_parts_mut(self.array_start.as_mut_ptr(), self.len) }
    }
}

impl<'a, T: Copy + 'a> IntoIterator for &'a Array<T> {
    type Item = &'a T;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&**self).into_iter()
    }
}

impl<'a, T: Copy + 'a> IntoIterator for &'a mut Array<T> {
    type Item = &'a mut T;
    type IntoIter = <&'a mut [T] as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&mut **self).into_iter()
    }
}

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

    #[test]
    fn array_values_offset() {
        use std::mem;
        use std::ptr;

        unsafe {
            let p: *const Array<i32> = ptr::null();
            assert_eq!(p as *const u8, &(*p).len as *const _ as *const u8);
            assert_eq!(
                (p as *const u8).offset(mem::size_of::<usize>() as isize),
                &(*p).array_start as *const _ as *const u8
            );
        }
    }
}
<commit_msg>refactor: Disable  from being constructed<commit_after>use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::slice;

use gc::{Gc, Traverseable};

mod internal {
    pub struct CantConstruct(());
}

/// Abstract array type which have their length store inline with the elements.
/// Fills the same role as Box<[T]> but takes only 8 bytes on the stack instead of 16
#[repr(C)]
pub struct Array<T: Copy> {
    len: usize,
    array_start: [T; 0],
    _marker: self::internal::CantConstruct,
}

impl<T: Copy> AsRef<[T]> for Array<T> {
    fn as_ref(&self) -> &[T] {
        self
    }
}

impl<T: Copy> AsMut<[T]> for Array<T> {
    fn as_mut(&mut self) -> &mut [T] {
        self
    }
}

impl<T: Copy + PartialEq> PartialEq for Array<T> {
    fn eq(&self, other: &Array<T>) -> bool {
        &**self == other.as_ref()
    }
}

impl<T: Copy + Eq> Eq for Array<T> {}

impl<T: Copy + PartialOrd> PartialOrd for Array<T> {
    fn partial_cmp(&self, other: &Array<T>) -> Option<Ordering> {
        (&**self).partial_cmp(other.as_ref())
    }
}

impl<T: Copy + Ord> Ord for Array<T> {
    fn cmp(&self, other: &Array<T>) -> Ordering {
        (&**self).cmp(other)
    }
}

impl<T: Copy + Hash> Hash for Array<T> {
    fn hash<H>(&self, hasher: &mut H)
    where
        H: Hasher,
    {
        (&**self).hash(hasher)
    }
}

impl<T: Copy + fmt::Debug> fmt::Debug for Array<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", &**self)
    }
}

impl<T: Copy + Traverseable> Traverseable for Array<T> {
    fn traverse(&self, gc: &mut Gc) {
        (**self).traverse(gc)
    }
}

impl<T: Copy> Array<T> {
    pub fn size_of(len: usize) -> usize {
        mem::size_of::<usize>() + mem::size_of::<T>() * len
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        self.len = len;
    }

    /// Initializes an Array.
    /// To be safe it is required that the iterators length is known and exactly the same as the
    /// length of the allocated array.
    pub unsafe fn initialize<I>(&mut self, iterable: I)
    where
        I: IntoIterator<Item = T>,
    {
        let iter = iterable.into_iter();
        self.len = iter.size_hint()
            .1
            .expect("initialize expected a known length");
        for (field, value) in self.iter_mut().zip(iter) {
            *field = value;
        }
    }
}

impl<T: Copy> Deref for Array<T> {
    type Target = [T];
    fn deref(&self) -> &[T] {
        unsafe { slice::from_raw_parts(self.array_start.as_ptr(), self.len) }
    }
}

impl<T: Copy> DerefMut for Array<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe { slice::from_raw_parts_mut(self.array_start.as_mut_ptr(), self.len) }
    }
}

impl<'a, T: Copy + 'a> IntoIterator for &'a Array<T> {
    type Item = &'a T;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&**self).into_iter()
    }
}

impl<'a, T: Copy + 'a> IntoIterator for &'a mut Array<T> {
    type Item = &'a mut T;
    type IntoIter = <&'a mut [T] as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        (&mut **self).into_iter()
    }
}

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

    #[test]
    fn array_values_offset() {
        use std::mem;
        use std::ptr;

        unsafe {
            let p: *const Array<i32> = ptr::null();
            assert_eq!(p as *const u8, &(*p).len as *const _ as *const u8);
            assert_eq!(
                (p as *const u8).offset(mem::size_of::<usize>() as isize),
                &(*p).array_start as *const _ as *const u8
            );
        }
    }
}
<|endoftext|>


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

use std::fmt::{Display, Formatter};

/// A simplification of Clojure's Symbol.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct PlainSymbol(pub String);

#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct NamespacedSymbol {
    // We derive PartialOrd, which implements a lexicographic based
    // on the order of members, so put namespace first.
    pub namespace: String,
    pub name: String,
}

/// A keyword is a symbol, optionally with a namespace, that prints with a leading colon.
/// This concept is imported from Clojure, as it features in EDN and the query
/// syntax that we use.
///
/// Clojure's constraints are looser than ours, allowing empty namespaces or
/// names:
///
/// ```clojure
/// user=> (keyword "" "")
/// :/
/// user=> (keyword "foo" "")
/// :foo/
/// user=> (keyword "" "bar")
/// :/bar
/// ```
///
/// We think that's nonsense, so we only allow keywords like `:bar` and `:foo/bar`,
/// with both namespace and main parts containing no whitespace and no colon or slash:
///
/// ```rust
/// # use edn::symbols::Keyword;
/// # use edn::symbols::NamespacedKeyword;
/// let bar     = Keyword::new("bar");                         // :bar
/// let foo_bar = NamespacedKeyword::new("foo", "bar");        // :foo/bar
/// assert_eq!("bar", bar.0);
/// assert_eq!("bar", foo_bar.name);
/// assert_eq!("foo", foo_bar.namespace);
/// ```
///
/// If you're not sure whether your input is well-formed, you should use a
/// parser or a reader function first to validate. TODO: implement `read`.
///
/// Callers are expected to follow these rules:
/// http://www.clojure.org/reference/reader#_symbols
///
/// Future: fast equality (interning?) for keywords.
///
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct Keyword(pub String);

#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct NamespacedKeyword {
    // We derive PartialOrd, which implements a lexicographic based
    // on the order of members, so put namespace first.
    pub namespace: String,
    pub name: String,
}

impl PlainSymbol {
    pub fn new<T>(name: T) -> Self where T: Into<String> {
        let n = name.into();
        assert!(!n.is_empty(), "Symbols cannot be unnamed.");

        PlainSymbol(n)
    }
}

impl NamespacedSymbol {
    pub fn new(namespace: &str, name: &str) -> Self {
        assert!(!name.is_empty(), "Symbols cannot be unnamed.");
        assert!(!namespace.is_empty(), "Symbols cannot have an empty non-null namespace.");

        NamespacedSymbol { name: name.to_string(), namespace: namespace.to_string() }
    }
}

impl Keyword {
    pub fn new<T>(name: T) -> Self where T: Into<String>{
        let n = name.into();
        assert!(!n.is_empty(), "Keywords cannot be unnamed.");

        Keyword(n)
    }
}

impl NamespacedKeyword {
    pub fn new(namespace: &str, name: &str) -> Self {
        assert!(!name.is_empty(), "Keywords cannot be unnamed.");
        assert!(!namespace.is_empty(), "Keywords cannot have an empty non-null namespace.");

        // TODO: debug asserts to ensure that neither field matches [ :/].
        NamespacedKeyword { name: name.to_string(), namespace: namespace.to_string() }
    }
}

//
// Note that we don't currently do any escaping.
//

impl Display for PlainSymbol {
    /// Print the symbol in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::PlainSymbol;
    /// assert_eq!("baz", PlainSymbol::new("baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl Display for NamespacedSymbol {
    /// Print the symbol in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::NamespacedSymbol;
    /// assert_eq!("bar/baz", NamespacedSymbol::new("bar", "baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, "{}/{}", self.namespace, self.name)
    }
}

impl Display for Keyword {
    /// Print the keyword in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::Keyword;
    /// assert_eq!(":baz", Keyword::new("baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, ":{}", self.0)
    }
}

impl Display for NamespacedKeyword {
    /// Print the keyword in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::NamespacedKeyword;
    /// assert_eq!(":bar/baz", NamespacedKeyword::new("bar", "baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, ":{}/{}", self.namespace, self.name)
    }
}
<commit_msg>Add Into<String> to symbol::* constructors. Fixes #199<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

use std::fmt::{Display, Formatter};

/// A simplification of Clojure's Symbol.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct PlainSymbol(pub String);

#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct NamespacedSymbol {
    // We derive PartialOrd, which implements a lexicographic based
    // on the order of members, so put namespace first.
    pub namespace: String,
    pub name: String,
}

/// A keyword is a symbol, optionally with a namespace, that prints with a leading colon.
/// This concept is imported from Clojure, as it features in EDN and the query
/// syntax that we use.
///
/// Clojure's constraints are looser than ours, allowing empty namespaces or
/// names:
///
/// ```clojure
/// user=> (keyword "" "")
/// :/
/// user=> (keyword "foo" "")
/// :foo/
/// user=> (keyword "" "bar")
/// :/bar
/// ```
///
/// We think that's nonsense, so we only allow keywords like `:bar` and `:foo/bar`,
/// with both namespace and main parts containing no whitespace and no colon or slash:
///
/// ```rust
/// # use edn::symbols::Keyword;
/// # use edn::symbols::NamespacedKeyword;
/// let bar     = Keyword::new("bar");                         // :bar
/// let foo_bar = NamespacedKeyword::new("foo", "bar");        // :foo/bar
/// assert_eq!("bar", bar.0);
/// assert_eq!("bar", foo_bar.name);
/// assert_eq!("foo", foo_bar.namespace);
/// ```
///
/// If you're not sure whether your input is well-formed, you should use a
/// parser or a reader function first to validate. TODO: implement `read`.
///
/// Callers are expected to follow these rules:
/// http://www.clojure.org/reference/reader#_symbols
///
/// Future: fast equality (interning?) for keywords.
///
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct Keyword(pub String);

#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct NamespacedKeyword {
    // We derive PartialOrd, which implements a lexicographic based
    // on the order of members, so put namespace first.
    pub namespace: String,
    pub name: String,
}

impl PlainSymbol {
    pub fn new<T>(name: T) -> Self where T: Into<String> {
        let n = name.into();
        assert!(!n.is_empty(), "Symbols cannot be unnamed.");

        PlainSymbol(n)
    }
}

impl NamespacedSymbol {
    pub fn new<T>(namespace: T, name: T) -> Self where T: Into<String> {
        let n = name.into();
        let ns = namespace.into();

        assert!(!n.is_empty(), "Symbols cannot be unnamed.");
        assert!(!ns.is_empty(), "Symbols cannot have an empty non-null namespace.");

        NamespacedSymbol { name: n, namespace: ns }
    }
}

impl Keyword {
    pub fn new<T>(name: T) -> Self where T: Into<String> {
        let n = name.into();
        assert!(!n.is_empty(), "Keywords cannot be unnamed.");

        Keyword(n)
    }
}

impl NamespacedKeyword {
    pub fn new<T>(namespace: T, name: T) -> Self where T: Into<String> {
        let n = name.into();
        let ns = namespace.into();
        assert!(!n.is_empty(), "Keywords cannot be unnamed.");
        assert!(!ns.is_empty(), "Keywords cannot have an empty non-null namespace.");

        // TODO: debug asserts to ensure that neither field matches [ :/].
        NamespacedKeyword { name: n, namespace: ns }
    }
}

//
// Note that we don't currently do any escaping.
//

impl Display for PlainSymbol {
    /// Print the symbol in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::PlainSymbol;
    /// assert_eq!("baz", PlainSymbol::new("baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl Display for NamespacedSymbol {
    /// Print the symbol in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::NamespacedSymbol;
    /// assert_eq!("bar/baz", NamespacedSymbol::new("bar", "baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, "{}/{}", self.namespace, self.name)
    }
}

impl Display for Keyword {
    /// Print the keyword in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::Keyword;
    /// assert_eq!(":baz", Keyword::new("baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, ":{}", self.0)
    }
}

impl Display for NamespacedKeyword {
    /// Print the keyword in EDN format.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use edn::symbols::NamespacedKeyword;
    /// assert_eq!(":bar/baz", NamespacedKeyword::new("bar", "baz").to_string());
    /// ```
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        write!(f, ":{}/{}", self.namespace, self.name)
    }
}
<|endoftext|>


<commit_before>use ui::ncurses::*;
use ui::{RIGHT_PANEL_WIDTH, CMD_ENTRY_HEIGHT, Position, Size};
use ui::window::BorderWindow;

pub struct Chat {
    window: BorderWindow,
}

// glibc will panic if a message containing a C-style format string is entered
fn sanitize(string: &str) -> String {
    string.replace('%', "%%")
}

impl Chat {
    pub fn new(size: Size) -> Chat {
        let window = BorderWindow::new(
                        Position::new(0, 0),
                        Size::new(size.width - RIGHT_PANEL_WIDTH, size.height - CMD_ENTRY_HEIGHT),
                        Size::new(1, 1));

        scrollok(window.inner.id, true);

        Chat { window: window }
    }

    pub fn add_message(&self, msg: &str) {
        wprintw(self.window.inner.id, &format!("{}\n", sanitize(msg)));
        wrefresh(self.window.inner.id);
    }
}<commit_msg>Replace wprintw call with waddstr to bypass message sanitization<commit_after>use ui::ncurses::*;
use ui::{RIGHT_PANEL_WIDTH, CMD_ENTRY_HEIGHT, Position, Size};
use ui::window::BorderWindow;

pub struct Chat {
    window: BorderWindow,
}

impl Chat {
    pub fn new(size: Size) -> Chat {
        let window = BorderWindow::new(
                        Position::new(0, 0),
                        Size::new(size.width - RIGHT_PANEL_WIDTH, size.height - CMD_ENTRY_HEIGHT),
                        Size::new(1, 1));

        scrollok(window.inner.id, true);

        Chat { window: window }
    }

    pub fn add_message(&self, msg: &str) {
        waddstr(self.window.inner.id, &format!("{}\n", msg));
        wrefresh(self.window.inner.id);
    }
}<|endoftext|>


<commit_before>use board::std_board;
use board::std_board::{ChessBoard, Piece, PieceType, Square};
use board::sjadam_move::{SjadamMove, SjadamUndoMove};
use board::sjadam_move_gen;
use board::std_move_gen::move_gen;

use search_algorithms::board::EvalBoard;
use search_algorithms::board::Color;
use search_algorithms::board::Color::*;
use search_algorithms::board::GameResult;

use rand;
use uci::UciBoard;

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct SjadamBoard {
    pub base_board: std_board::ChessBoard,
}

impl EvalBoard for SjadamBoard {
    type Move = SjadamMove;
    type UndoMove = SjadamUndoMove;

    fn to_move(&self) -> Color {
        self.base_board.to_move()
    }

    fn do_move(&mut self, mv: Self::Move) -> Self::UndoMove {
        let start_color = self.to_move();
        debug_assert!(mv.from != mv.sjadam_square || mv.sjadam_square != mv.to);

        let undo_move = SjadamUndoMove {
            from: mv.from, sjadam_square: mv.sjadam_square,
            capture: self.base_board[mv.to].piece_type(),
            to: mv.to, piece_moved: self.base_board[mv.from].piece_type(),
            old_castling_en_passant: self.base_board.castling_en_passant,
            old_half_move_clock: self.base_board.half_move_clock };

        // Do sjadam move. Has no effect if there is no sjadam jump
        self.base_board[mv.sjadam_square] = self.base_board[mv.from];
        if mv.from != mv.sjadam_square {
            self.base_board[mv.from] = Piece::empty();
        }

        // Remove castling priviledges on king moves
        if undo_move.piece_moved == PieceType::King {
            let color = self.to_move();
            self.base_board.disable_castling(color);
        }

        // Remove castling priviledges if anything moves from or to a corner

        let a1 = Square::from_alg("a1").unwrap();
        let h1 = Square::from_alg("h1").unwrap();
        let a8 = Square::from_alg("a8").unwrap();
        let h8 = Square::from_alg("h8").unwrap();
        match mv.from {
            square if square == a1 =>
                self.base_board.disable_castling_queenside(White),
            square if square == h1 =>
                self.base_board.disable_castling_kingside(White),
            square if square == a8 =>
                self.base_board.disable_castling_queenside(Black),
            square if square == h8 =>
                self.base_board.disable_castling_kingside(Black),
            _ => (),
        }

        match mv.to {
            square if square == a1 =>
                self.base_board.disable_castling_queenside(White),
            square if square == h1 =>
                self.base_board.disable_castling_kingside(White),
            square if square == a8 =>
                self.base_board.disable_castling_queenside(Black),
            square if square == h8 =>
                self.base_board.disable_castling_kingside(Black),
            _ => (),
        }

        let chess_move = mv.chess_move(self);

        match chess_move {
            None => {
                if undo_move.piece_moved != PieceType::Pawn {
                    self.base_board.half_move_clock += 1; // Pure sjadam moves are never captures
                }
                else {
                    self.base_board.half_move_clock = 0;
                }

                // Sjadam moves never create en passant
                self.base_board.set_en_passant_square(None);
                self.base_board.to_move = !self.base_board.to_move;

            }, // TODO: Figure out if anything else needs to be done here
            Some(chess_move) => {
                self.base_board.do_move(chess_move);
            },
        }
        if (start_color == White && mv.to.rank() == 0)
            || (start_color == Black && mv.to.rank() == 7) {
                debug_assert!(!self.base_board[mv.to].is_empty());
                if self.base_board[mv.to].piece_type() != PieceType::King {
                    self.base_board[mv.to] = Piece::new(PieceType::Queen, start_color);
                }
            }
        debug_assert_ne!(start_color, self.to_move());
        debug_assert!(self.base_board.castling_en_passant & 15 <= undo_move.old_castling_en_passant & 15);
        undo_move
    }

    fn undo_move(&mut self, mv: Self::UndoMove) {
        let start_color = self.to_move();
        match mv.chess_move(self) {
            None => {
                self.base_board.to_move = !self.base_board.to_move;
            },
            Some(chess_move) => self.base_board.undo_move(chess_move),
        }
        self.base_board.half_move_clock = mv.old_half_move_clock;
        self.base_board.castling_en_passant = mv.old_castling_en_passant;

        let color = self.base_board[mv.sjadam_square].color().unwrap();
        self.base_board[mv.from] = Piece::new(mv.piece_moved, color);
        // Undo sjadam move
        if mv.from != mv.sjadam_square {
            self.base_board[mv.sjadam_square] = Piece::empty();
        }
        debug_assert_ne!(start_color, self.to_move());

    }

    fn start_board() -> Self {
        SjadamBoard {
            base_board: std_board::ChessBoard::start_board(),
        }
    }

    fn all_legal_moves(&self) -> Vec<Self::Move> {
        let mut cloned_board = self.clone();
        sjadam_move_gen::all_legal_moves(&mut cloned_board)
    }

    fn game_result(&self) -> Option<GameResult> {
        // In sjadam, king may be actually captured.
        // Check if the king is gone
        match self.king_on_board() {
            (true, false) => Some(GameResult::WhiteWin),
            (false, true) => Some(GameResult::BlackWin),
            (false, false) => panic!("Neither side has a king on the board:\n{:?}", self),
            (true, true) => {
                // First check if it is attacked by regular moves
                if !sjadam_move_gen::any_legal_moves(&mut self.clone()) {
                    if move_gen::is_attacked(&self.base_board, move_gen::king_pos(&self.base_board)) {
                        match self.to_move() {
                            Black => Some(GameResult::WhiteWin),
                            White => Some(GameResult::BlackWin),
                        }
                    }
                    else {
                        Some(GameResult::Draw)
                    }
                }
                // The king might still be directly captured by a sjadam move next move,
                // but that is fine
                else {
                    if self.base_board.half_move_clock > 50 {
                        Some(GameResult::Draw)
                    }
                    else { None }
                }
            },
        }
    }
    fn do_random_move<R: rand::Rng>(&mut self, rng: &mut R) {
        let moves = self.all_legal_moves();
        assert!(!moves.is_empty(),
                "Tried to do a random move, but there were no legal moves on {:?}",
                self);
        self.do_move(moves[rng.gen_range(0, moves.len())].clone());
    }
    fn eval_board(&self) -> f32 {
        self.base_board.eval_board()
    }
}

impl UciBoard for SjadamBoard {
    fn from_fen(input: &str) -> Result<Self, String> {
        Ok(SjadamBoard { base_board: try!(ChessBoard::from_fen(input)) })
    }

    fn to_fen(&self) -> String {
        self.base_board.to_fen()
    }
}

impl SjadamBoard {
    fn king_on_board(&self) -> (bool, bool) {
        let mut white_king = false;
        let mut black_king = false;
        let board = &self.base_board;
        for square in std_board::BoardIter::new() {
            if board[square].piece_type() == PieceType::King {
                match board[square].color().unwrap() {
                    White => white_king = true,
                    Black => black_king = true,
                }
            }
        }
        (white_king, black_king)
    }
}
<commit_msg>Added branch factor to sjadam_board<commit_after>use board::std_board;
use board::std_board::{ChessBoard, Piece, PieceType, Square};
use board::sjadam_move::{SjadamMove, SjadamUndoMove};
use board::sjadam_move_gen;
use board::std_move_gen::move_gen;

use search_algorithms::board::EvalBoard;
use search_algorithms::board::Color;
use search_algorithms::board::Color::*;
use search_algorithms::board::GameResult;

use rand;
use uci::UciBoard;

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct SjadamBoard {
    pub base_board: std_board::ChessBoard,
}

impl EvalBoard for SjadamBoard {
    type Move = SjadamMove;
    type UndoMove = SjadamUndoMove;

    fn to_move(&self) -> Color {
        self.base_board.to_move()
    }

    fn do_move(&mut self, mv: Self::Move) -> Self::UndoMove {
        let start_color = self.to_move();
        debug_assert!(mv.from != mv.sjadam_square || mv.sjadam_square != mv.to);

        let undo_move = SjadamUndoMove {
            from: mv.from, sjadam_square: mv.sjadam_square,
            capture: self.base_board[mv.to].piece_type(),
            to: mv.to, piece_moved: self.base_board[mv.from].piece_type(),
            old_castling_en_passant: self.base_board.castling_en_passant,
            old_half_move_clock: self.base_board.half_move_clock };

        // Do sjadam move. Has no effect if there is no sjadam jump
        self.base_board[mv.sjadam_square] = self.base_board[mv.from];
        if mv.from != mv.sjadam_square {
            self.base_board[mv.from] = Piece::empty();
        }

        // Remove castling priviledges on king moves
        if undo_move.piece_moved == PieceType::King {
            let color = self.to_move();
            self.base_board.disable_castling(color);
        }

        // Remove castling priviledges if anything moves from or to a corner

        let a1 = Square::from_alg("a1").unwrap();
        let h1 = Square::from_alg("h1").unwrap();
        let a8 = Square::from_alg("a8").unwrap();
        let h8 = Square::from_alg("h8").unwrap();
        match mv.from {
            square if square == a1 =>
                self.base_board.disable_castling_queenside(White),
            square if square == h1 =>
                self.base_board.disable_castling_kingside(White),
            square if square == a8 =>
                self.base_board.disable_castling_queenside(Black),
            square if square == h8 =>
                self.base_board.disable_castling_kingside(Black),
            _ => (),
        }

        match mv.to {
            square if square == a1 =>
                self.base_board.disable_castling_queenside(White),
            square if square == h1 =>
                self.base_board.disable_castling_kingside(White),
            square if square == a8 =>
                self.base_board.disable_castling_queenside(Black),
            square if square == h8 =>
                self.base_board.disable_castling_kingside(Black),
            _ => (),
        }

        let chess_move = mv.chess_move(self);

        match chess_move {
            None => {
                if undo_move.piece_moved != PieceType::Pawn {
                    self.base_board.half_move_clock += 1; // Pure sjadam moves are never captures
                }
                else {
                    self.base_board.half_move_clock = 0;
                }

                // Sjadam moves never create en passant
                self.base_board.set_en_passant_square(None);
                self.base_board.to_move = !self.base_board.to_move;

            }, // TODO: Figure out if anything else needs to be done here
            Some(chess_move) => {
                self.base_board.do_move(chess_move);
            },
        }
        if (start_color == White && mv.to.rank() == 0)
            || (start_color == Black && mv.to.rank() == 7) {
                debug_assert!(!self.base_board[mv.to].is_empty());
                if self.base_board[mv.to].piece_type() != PieceType::King {
                    self.base_board[mv.to] = Piece::new(PieceType::Queen, start_color);
                }
            }
        debug_assert_ne!(start_color, self.to_move());
        debug_assert!(self.base_board.castling_en_passant & 15 <= undo_move.old_castling_en_passant & 15);
        undo_move
    }

    fn undo_move(&mut self, mv: Self::UndoMove) {
        let start_color = self.to_move();
        match mv.chess_move(self) {
            None => {
                self.base_board.to_move = !self.base_board.to_move;
            },
            Some(chess_move) => self.base_board.undo_move(chess_move),
        }
        self.base_board.half_move_clock = mv.old_half_move_clock;
        self.base_board.castling_en_passant = mv.old_castling_en_passant;

        let color = self.base_board[mv.sjadam_square].color().unwrap();
        self.base_board[mv.from] = Piece::new(mv.piece_moved, color);
        // Undo sjadam move
        if mv.from != mv.sjadam_square {
            self.base_board[mv.sjadam_square] = Piece::empty();
        }
        debug_assert_ne!(start_color, self.to_move());

    }

    fn start_board() -> Self {
        SjadamBoard {
            base_board: std_board::ChessBoard::start_board(),
        }
    }

    fn all_legal_moves(&self) -> Vec<Self::Move> {
        let mut cloned_board = self.clone();
        sjadam_move_gen::all_legal_moves(&mut cloned_board)
    }

    fn game_result(&self) -> Option<GameResult> {
        // In sjadam, king may be actually captured.
        // Check if the king is gone
        match self.king_on_board() {
            (true, false) => Some(GameResult::WhiteWin),
            (false, true) => Some(GameResult::BlackWin),
            (false, false) => panic!("Neither side has a king on the board:\n{:?}", self),
            (true, true) => {
                // First check if it is attacked by regular moves
                if !sjadam_move_gen::any_legal_moves(&mut self.clone()) {
                    if move_gen::is_attacked(&self.base_board, move_gen::king_pos(&self.base_board)) {
                        match self.to_move() {
                            Black => Some(GameResult::WhiteWin),
                            White => Some(GameResult::BlackWin),
                        }
                    }
                    else {
                        Some(GameResult::Draw)
                    }
                }
                // The king might still be directly captured by a sjadam move next move,
                // but that is fine
                else {
                    if self.base_board.half_move_clock > 50 {
                        Some(GameResult::Draw)
                    }
                    else { None }
                }
            },
        }
    }
    fn do_random_move<R: rand::Rng>(&mut self, rng: &mut R) {
        let moves = self.all_legal_moves();
        assert!(!moves.is_empty(),
                "Tried to do a random move, but there were no legal moves on {:?}",
                self);
        self.do_move(moves[rng.gen_range(0, moves.len())].clone());
    }
    fn eval_board(&self) -> f32 {
        self.base_board.eval_board()
    }

    fn branch_factor() -> u64 {
        80
    }
}

impl UciBoard for SjadamBoard {
    fn from_fen(input: &str) -> Result<Self, String> {
        Ok(SjadamBoard { base_board: try!(ChessBoard::from_fen(input)) })
    }

    fn to_fen(&self) -> String {
        self.base_board.to_fen()
    }
}

impl SjadamBoard {
    fn king_on_board(&self) -> (bool, bool) {
        let mut white_king = false;
        let mut black_king = false;
        let board = &self.base_board;
        for square in std_board::BoardIter::new() {
            if board[square].piece_type() == PieceType::King {
                match board[square].color().unwrap() {
                    White => white_king = true,
                    Black => black_king = true,
                }
            }
        }
        (white_king, black_king)
    }
}
<|endoftext|>