<commit_before>#![feature(core)]
#![feature(old_io)]
#![feature(std_misc)]
#![feature(collections)]

extern crate "rustc-serialize" as rustc_serialize;
extern crate time;
extern crate uuid;
extern crate rand;

use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::old_io::net::ip::{SocketAddr, ToSocketAddr};
use std::old_io::net::udp::UdpSocket;
use std::old_io::timer::Timer;
use std::str::FromStr;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration;
use std::thread;

use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_serialize::json;
use uuid::Uuid;

mod member;
mod memberlist;

use member::{Member, MemberState, StateChange};
use memberlist::MemberList;

#[derive(Debug)]
pub enum ClusterEvent {
    MemberJoined(Member),
    MemberWentUp(Member),
    MemberSuspectedDown(Member),
    MemberWentDown(Member),
}

pub struct Cluster {
    pub events: Receiver<(Vec<Member>, ClusterEvent)>,
    comm: Sender<InternalRequest>,
}

#[derive(Debug, Clone)]
struct EncSocketAddr(SocketAddr);

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
enum Request {
    Ping,
    Ack,
    PingRequest(EncSocketAddr),
    AckHost(Member),
}

#[derive(Debug, Clone)]
struct TargetedRequest {
    request: Request,
    target: SocketAddr,
}

#[derive(Debug, Clone)]
enum InternalRequest {
    AddSeed(SocketAddr),
    Respond(SocketAddr, Message),
}

struct State {
    host_key: Uuid,
    cluster_key: Vec<u8>,
    members: MemberList,
    seed_queue: Vec<SocketAddr>,
    pending_responses: Vec<(time::Tm, SocketAddr, Vec<StateChange>)>,
    state_changes: Vec<StateChange>,
    wait_list: HashMap<SocketAddr, Vec<SocketAddr>>,
    socket: UdpSocket,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
struct Message {
    sender: Uuid,
    cluster_key: Vec<u8>,
    request: Request,
    state_changes: Vec<StateChange>,
}

pub fn start_cluster<A: ToSocketAddr>(host_key: Uuid, cluster_key: &str, listen_addr: A) -> Cluster {
    let (event_tx, event_rx) = channel();
    let (request_tx, request_rx) = channel();
    let (internal_tx, internal_rx) = channel();
    let socket = UdpSocket::bind(listen_addr).unwrap();
    let cluster_key = cluster_key.as_bytes().to_vec();

    let timeout_tx = request_tx.clone();
    let worker_socket = socket.clone();
    thread::spawn(move || {
        let me = Member::myself(host_key.clone());

        let mut state = State {
            host_key: host_key,
            cluster_key: cluster_key,
            members: MemberList::new(me.clone()),
            seed_queue: Vec::new(),
            pending_responses: Vec::new(),
            state_changes: vec![StateChange::new(me)],
            wait_list: HashMap::new(),
            socket: worker_socket,
        };

        let mut timer = Timer::new().unwrap();
        let periodic = timer.periodic(Duration::seconds(1));

        loop {
            select!(
                _ = periodic.recv() => {
                    enqueue_seed_nodes(&state.seed_queue, &timeout_tx);
                    enqueue_random_ping(&mut state, &timeout_tx);
                },
                request = request_rx.recv() => {
                    prune_timed_out_responses(&mut state, &event_tx, &timeout_tx);
                    process_request(&mut state, request.unwrap());
                },
                internal_message = internal_rx.recv() => {
                    process_internal_request(&mut state, internal_message.unwrap(), &event_tx, &timeout_tx);
                }
            );
        }
    });

    let listener_tx = internal_tx.clone();
    let mut listener_socket = socket.clone();
    thread::spawn(move || {
        loop {
            let mut buf = [0; 512];

            match listener_socket.recv_from(&mut buf) {
                Ok((size, src_addr)) => {
                    let message = json::decode(&*String::from_utf8_lossy(&buf[..size]));
                    listener_tx.send(InternalRequest::Respond(src_addr, message.unwrap())).unwrap();
                },
                Err(e) => {
                    println!("Error while reading: {:?}", e);
                }
            };
        }
    });

    return Cluster { events: event_rx, comm: internal_tx };
}

impl Cluster {
    pub fn add_seed_node<A: ToSocketAddr>(&self, addr: A) {
        self.comm.send(InternalRequest::AddSeed(addr.to_socket_addr().unwrap())).unwrap();
    }
}

fn process_request(state: &mut State, request: TargetedRequest) {
    use Request::*;

    let timeout = time::now_utc() + Duration::seconds(3);
    let should_add_pending = match request.request { Ping => true, _ => false };
    let message = build_message(&state.host_key, &state.cluster_key, request.request, state.state_changes.clone());

    if should_add_pending {
        state.pending_responses.push((timeout, request.target.clone(), message.state_changes.clone()));
    }

    let encoded = json::encode(&message).unwrap();

    assert!(encoded.len() < 512);

    state.socket.send_to(encoded.as_bytes(), request.target).unwrap();
}

fn build_message(sender: &Uuid, cluster_key: &Vec<u8>, request: Request, state_changes: Vec<StateChange>) -> Message {
    let mut message = Message {
        sender: sender.clone(),
        cluster_key: cluster_key.clone(),
        request: request.clone(),
        state_changes: Vec::new(),
    };

    for i in range(0, state_changes.len() + 1) {
        message = Message {
            sender: sender.clone(),
            cluster_key: cluster_key.clone(),
            request: request.clone(),
            state_changes: (&state_changes[..i]).iter().cloned().collect(),
        };

        let encoded = json::encode(&message).unwrap();
        if encoded.len() >= 512 {
            return message;
        }
    }

    return message;
}

fn enqueue_seed_nodes(seed_nodes: &[SocketAddr], tx: &Sender<TargetedRequest>) {
    for seed_node in seed_nodes {
        tx.send(TargetedRequest { request: Request::Ping, target: seed_node.clone() }).unwrap();
    }
}

fn enqueue_random_ping(state: &mut State, tx: &Sender<TargetedRequest>) {
    if let Some(member) = state.members.next_random_member() {
        tx.send(TargetedRequest { request: Request::Ping, target: member.remote_host().unwrap() }).unwrap();
    }
}

fn prune_timed_out_responses(state: &mut State, event_tx: &Sender<(Vec<Member>, ClusterEvent)>, request_tx: &Sender<TargetedRequest>) {
    let now = time::now_utc();

    let (remaining, expired): (Vec<_>, Vec<_>) = state.pending_responses
        .iter()
        .cloned()
        .partition(| &(t, _, _) | t < now);

    let expired_hosts: HashSet<SocketAddr> = expired
        .iter()
        .map(| &(_, a, _) | a)
        .collect();

    state.pending_responses = remaining;

    let (suspect, down) = state.members.time_out_nodes(expired_hosts);

    enqueue_state_change(state, down.as_slice());
    enqueue_state_change(state, suspect.as_slice());

    for member in suspect {
        send_ping_requests(state, &member, request_tx);
        send_cluster_event(&state.members, event_tx, ClusterEvent::MemberSuspectedDown(member.clone()));
    }

    for member in down {
        send_cluster_event(&state.members, event_tx, ClusterEvent::MemberWentDown(member.clone()));
    }
}

fn send_ping_requests(state: &State, target: &Member, request_tx: &Sender<TargetedRequest>) {
    if let Some(target_host) = target.remote_host() {
        for relay in state.members.hosts_for_indirect_ping(&target_host) {
            request_tx.send(TargetedRequest {
                request: Request::PingRequest(EncSocketAddr::from_addr(&target_host)),
                target: relay,
            }).unwrap();
        }
    }
}

fn send_cluster_event(members: &MemberList, event_tx: &Sender<(Vec<Member>, ClusterEvent)>, event: ClusterEvent) {
    use ClusterEvent::*;

    match event {
        MemberJoined(_) => {},
        MemberWentUp(ref m) => assert_eq!(m.state(), MemberState::Alive),
        MemberWentDown(ref m) => assert_eq!(m.state(), MemberState::Down),
        MemberSuspectedDown(ref m) => assert_eq!(m.state(), MemberState::Suspect),
    };

    event_tx.send((members.to_vec(), event)).unwrap();
}

fn process_internal_request(state: &mut State, message: InternalRequest, event_tx: &Sender<(Vec<Member>, ClusterEvent)>, request_tx: &Sender<TargetedRequest>) {
    use InternalRequest::*;
    use Request::*;

    match message {
        AddSeed(addr) => {
            state.seed_queue.push(addr);
        },
        Respond(src_addr, message) => {
            if message.cluster_key != state.cluster_key {
                println!("ERROR: Mismatching cluster keys, ignoring message");
            }
            else {
                apply_state_changes(state, message.state_changes, src_addr, event_tx);
                remove_potential_seed(state, src_addr);

                ensure_node_is_member(state, src_addr, event_tx, message.sender);

                let response = match message.request {
                    Ping => Some(TargetedRequest { request: Ack, target: src_addr }),
                    Ack => {
                        ack_response(state, src_addr);
                        mark_node_alive(state, src_addr, event_tx, request_tx);
                        None
                    },
                    PingRequest(dest_addr) => {
                        let EncSocketAddr(dest_addr) = dest_addr;
                        add_to_wait_list(state, &dest_addr, &src_addr);
                        Some(TargetedRequest { request: Ping, target: dest_addr })
                    },
                    AckHost(member) => {
                        ack_response(state, member.remote_host().unwrap());
                        mark_node_alive(state, member.remote_host().unwrap(), event_tx, request_tx);
                        None
                    }
                };

                match response {
                    Some(response) => request_tx.send(response).unwrap(),
                    None => (),
                };
            }
        },
    };
}

fn add_to_wait_list(state: &mut State, wait_addr: &SocketAddr, notify_addr: &SocketAddr) {
    match state.wait_list.entry(*wait_addr) {
        Entry::Occupied(mut entry) => { entry.get_mut().push(notify_addr.clone()); },
        Entry::Vacant(entry) => { entry.insert(vec![notify_addr.clone()]); }
    };
}

fn remove_potential_seed(state: &mut State, src_addr: SocketAddr) {
    state.seed_queue.retain(|&addr| addr != src_addr)
}

fn ack_response(state: &mut State, src_addr: SocketAddr) {
    let mut to_remove = Vec::new();

    for &(ref t, ref addr, ref state_changes) in state.pending_responses.iter() {
        if src_addr != *addr {
            continue;
        }

        to_remove.push((t.clone(), addr.clone(), state_changes.clone()));

        state.state_changes
            .retain(|os| !state_changes.iter().any(| is | is.member().host_key() == os.member().host_key()))
    }

    state.pending_responses.retain(|op| !to_remove.iter().any(|ip| ip == op));
}

fn ensure_node_is_member(state: &mut State, src_addr: SocketAddr, event_tx: &Sender<(Vec<Member>, ClusterEvent)>, sender: Uuid) {
    if state.members.has_member(&src_addr) {
        return;
    }

    let new_member = Member::new(sender, src_addr, 0, MemberState::Alive);

    state.members.add_member(new_member.clone());
    enqueue_state_change(state, &[new_member.clone()]);
    send_cluster_event(&state.members, event_tx, ClusterEvent::MemberJoined(new_member));
}

fn mark_node_alive(state: &mut State, src_addr: SocketAddr, event_tx: &Sender<(Vec<Member>, ClusterEvent)>, request_tx: &Sender<TargetedRequest>) {
    if let Some(member) = state.members.mark_node_alive(&src_addr) {
        match state.wait_list.get_mut(&src_addr) {
            Some(mut wait_list) => {
                for remote in wait_list.drain() {
                    request_tx.send(TargetedRequest { request: Request::AckHost(member.clone()), target: remote }).unwrap();
                }
            },
            None => ()
        };

        enqueue_state_change(state, &[member.clone()]);
        send_cluster_event(&state.members, event_tx, ClusterEvent::MemberWentUp(member.clone()));
    }
}

fn apply_state_changes(state: &mut State, state_changes: Vec<StateChange>, from: SocketAddr, event_tx: &Sender<(Vec<Member>, ClusterEvent)>) {
    let (new, changed) = state.members.apply_state_changes(state_changes, &from);

    enqueue_state_change(state, new.as_slice());
    enqueue_state_change(state, changed.as_slice());

    for member in new {

        send_cluster_event(&state.members, event_tx, ClusterEvent::MemberJoined(member));
    }

    for member in changed {
        send_cluster_event(&state.members, event_tx, determine_cluster_event(member));
    }
}

fn determine_cluster_event(member: Member) -> ClusterEvent {
    use member::MemberState::*;
    use ClusterEvent::*;

    return match member.state() {
        Alive => MemberWentUp(member),
        Suspect => MemberSuspectedDown(member),
        Down => MemberWentDown(member),
    };
}

fn enqueue_state_change(state: &mut State, members: &[Member]) {
    for member in members {
        for state_change in &mut state.state_changes {
            if state_change.member().host_key() == member.host_key() {
                state_change.update(member.clone());
                return;
            }
        }

        state.state_changes.push(StateChange::new(member.clone()));
    }
}

impl Decodable for EncSocketAddr {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        match d.read_str() {
            Ok(s) => match FromStr::from_str(s.as_slice()) {
                Ok(addr) => Ok(EncSocketAddr(addr)),
                Err(e) => Err(d.error(format!("{:?}", e).as_slice())),
            },
            Err(e) => Err(e),
        }
    }
}

impl Encodable for EncSocketAddr {
    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
        let &EncSocketAddr(addr) = self;
        format!("{}", addr).encode(e)
    }
}

impl EncSocketAddr {
    fn from_addr(addr: &SocketAddr) -> Self {
        EncSocketAddr(addr.clone())
    }
}
<commit_msg>Introduce MemberEvent, replacing ClusterEvent<commit_after>#![feature(core)]
#![feature(old_io)]
#![feature(std_misc)]
#![feature(collections)]

extern crate "rustc-serialize" as rustc_serialize;
extern crate time;
extern crate uuid;
extern crate rand;

use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::old_io::net::ip::{SocketAddr, ToSocketAddr};
use std::old_io::net::udp::UdpSocket;
use std::old_io::timer::Timer;
use std::str::FromStr;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration;
use std::thread;

use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_serialize::json;
use uuid::Uuid;

mod member;
mod memberlist;

use member::{Member, MemberState, StateChange};
use memberlist::MemberList;

pub type ClusterEvent = (Vec<Member>, MemberEvent);

#[derive(Debug)]
pub enum MemberEvent {
    MemberJoined(Member),
    MemberWentUp(Member),
    MemberSuspectedDown(Member),
    MemberWentDown(Member),
}

pub struct Cluster {
    pub events: Receiver<ClusterEvent>,
    comm: Sender<InternalRequest>,
}

#[derive(Debug, Clone)]
struct EncSocketAddr(SocketAddr);

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
enum Request {
    Ping,
    Ack,
    PingRequest(EncSocketAddr),
    AckHost(Member),
}

#[derive(Debug, Clone)]
struct TargetedRequest {
    request: Request,
    target: SocketAddr,
}

#[derive(Debug, Clone)]
enum InternalRequest {
    AddSeed(SocketAddr),
    Respond(SocketAddr, Message),
}

struct State {
    host_key: Uuid,
    cluster_key: Vec<u8>,
    members: MemberList,
    seed_queue: Vec<SocketAddr>,
    pending_responses: Vec<(time::Tm, SocketAddr, Vec<StateChange>)>,
    state_changes: Vec<StateChange>,
    wait_list: HashMap<SocketAddr, Vec<SocketAddr>>,
    socket: UdpSocket,
}

#[derive(RustcEncodable, RustcDecodable, Debug, Clone)]
struct Message {
    sender: Uuid,
    cluster_key: Vec<u8>,
    request: Request,
    state_changes: Vec<StateChange>,
}

pub fn start_cluster<A: ToSocketAddr>(host_key: Uuid, cluster_key: &str, listen_addr: A) -> Cluster {
    let (event_tx, event_rx) = channel();
    let (request_tx, request_rx) = channel();
    let (internal_tx, internal_rx) = channel();
    let socket = UdpSocket::bind(listen_addr).unwrap();
    let cluster_key = cluster_key.as_bytes().to_vec();

    let timeout_tx = request_tx.clone();
    let worker_socket = socket.clone();
    thread::spawn(move || {
        let me = Member::myself(host_key.clone());

        let mut state = State {
            host_key: host_key,
            cluster_key: cluster_key,
            members: MemberList::new(me.clone()),
            seed_queue: Vec::new(),
            pending_responses: Vec::new(),
            state_changes: vec![StateChange::new(me)],
            wait_list: HashMap::new(),
            socket: worker_socket,
        };

        let mut timer = Timer::new().unwrap();
        let periodic = timer.periodic(Duration::seconds(1));

        loop {
            select!(
                _ = periodic.recv() => {
                    enqueue_seed_nodes(&state.seed_queue, &timeout_tx);
                    enqueue_random_ping(&mut state, &timeout_tx);
                },
                request = request_rx.recv() => {
                    prune_timed_out_responses(&mut state, &event_tx, &timeout_tx);
                    process_request(&mut state, request.unwrap());
                },
                internal_message = internal_rx.recv() => {
                    process_internal_request(&mut state, internal_message.unwrap(), &event_tx, &timeout_tx);
                }
            );
        }
    });

    let listener_tx = internal_tx.clone();
    let mut listener_socket = socket.clone();
    thread::spawn(move || {
        loop {
            let mut buf = [0; 512];

            match listener_socket.recv_from(&mut buf) {
                Ok((size, src_addr)) => {
                    let message = json::decode(&*String::from_utf8_lossy(&buf[..size]));
                    listener_tx.send(InternalRequest::Respond(src_addr, message.unwrap())).unwrap();
                },
                Err(e) => {
                    println!("Error while reading: {:?}", e);
                }
            };
        }
    });

    return Cluster { events: event_rx, comm: internal_tx };
}

impl Cluster {
    pub fn add_seed_node<A: ToSocketAddr>(&self, addr: A) {
        self.comm.send(InternalRequest::AddSeed(addr.to_socket_addr().unwrap())).unwrap();
    }
}

fn process_request(state: &mut State, request: TargetedRequest) {
    use Request::*;

    let timeout = time::now_utc() + Duration::seconds(3);
    let should_add_pending = match request.request { Ping => true, _ => false };
    let message = build_message(&state.host_key, &state.cluster_key, request.request, state.state_changes.clone());

    if should_add_pending {
        state.pending_responses.push((timeout, request.target.clone(), message.state_changes.clone()));
    }

    let encoded = json::encode(&message).unwrap();

    assert!(encoded.len() < 512);

    state.socket.send_to(encoded.as_bytes(), request.target).unwrap();
}

fn build_message(sender: &Uuid, cluster_key: &Vec<u8>, request: Request, state_changes: Vec<StateChange>) -> Message {
    let mut message = Message {
        sender: sender.clone(),
        cluster_key: cluster_key.clone(),
        request: request.clone(),
        state_changes: Vec::new(),
    };

    for i in range(0, state_changes.len() + 1) {
        message = Message {
            sender: sender.clone(),
            cluster_key: cluster_key.clone(),
            request: request.clone(),
            state_changes: (&state_changes[..i]).iter().cloned().collect(),
        };

        let encoded = json::encode(&message).unwrap();
        if encoded.len() >= 512 {
            return message;
        }
    }

    return message;
}

fn enqueue_seed_nodes(seed_nodes: &[SocketAddr], tx: &Sender<TargetedRequest>) {
    for seed_node in seed_nodes {
        tx.send(TargetedRequest { request: Request::Ping, target: seed_node.clone() }).unwrap();
    }
}

fn enqueue_random_ping(state: &mut State, tx: &Sender<TargetedRequest>) {
    if let Some(member) = state.members.next_random_member() {
        tx.send(TargetedRequest { request: Request::Ping, target: member.remote_host().unwrap() }).unwrap();
    }
}

fn prune_timed_out_responses(state: &mut State, event_tx: &Sender<ClusterEvent>, request_tx: &Sender<TargetedRequest>) {
    let now = time::now_utc();

    let (remaining, expired): (Vec<_>, Vec<_>) = state.pending_responses
        .iter()
        .cloned()
        .partition(| &(t, _, _) | t < now);

    let expired_hosts: HashSet<SocketAddr> = expired
        .iter()
        .map(| &(_, a, _) | a)
        .collect();

    state.pending_responses = remaining;

    let (suspect, down) = state.members.time_out_nodes(expired_hosts);

    enqueue_state_change(state, down.as_slice());
    enqueue_state_change(state, suspect.as_slice());

    for member in suspect {
        send_ping_requests(state, &member, request_tx);
        send_member_event(&state.members, event_tx, MemberEvent::MemberSuspectedDown(member.clone()));
    }

    for member in down {
        send_member_event(&state.members, event_tx, MemberEvent::MemberWentDown(member.clone()));
    }
}

fn send_ping_requests(state: &State, target: &Member, request_tx: &Sender<TargetedRequest>) {
    if let Some(target_host) = target.remote_host() {
        for relay in state.members.hosts_for_indirect_ping(&target_host) {
            request_tx.send(TargetedRequest {
                request: Request::PingRequest(EncSocketAddr::from_addr(&target_host)),
                target: relay,
            }).unwrap();
        }
    }
}

fn send_member_event(members: &MemberList, event_tx: &Sender<ClusterEvent>, event: MemberEvent) {
    use MemberEvent::*;

    match event {
        MemberJoined(_) => {},
        MemberWentUp(ref m) => assert_eq!(m.state(), MemberState::Alive),
        MemberWentDown(ref m) => assert_eq!(m.state(), MemberState::Down),
        MemberSuspectedDown(ref m) => assert_eq!(m.state(), MemberState::Suspect),
    };

    event_tx.send((members.to_vec(), event)).unwrap();
}

fn process_internal_request(state: &mut State, message: InternalRequest, event_tx: &Sender<ClusterEvent>, request_tx: &Sender<TargetedRequest>) {
    use InternalRequest::*;
    use Request::*;

    match message {
        AddSeed(addr) => {
            state.seed_queue.push(addr);
        },
        Respond(src_addr, message) => {
            if message.cluster_key != state.cluster_key {
                println!("ERROR: Mismatching cluster keys, ignoring message");
            }
            else {
                apply_state_changes(state, message.state_changes, src_addr, event_tx);
                remove_potential_seed(state, src_addr);

                ensure_node_is_member(state, src_addr, event_tx, message.sender);

                let response = match message.request {
                    Ping => Some(TargetedRequest { request: Ack, target: src_addr }),
                    Ack => {
                        ack_response(state, src_addr);
                        mark_node_alive(state, src_addr, event_tx, request_tx);
                        None
                    },
                    PingRequest(dest_addr) => {
                        let EncSocketAddr(dest_addr) = dest_addr;
                        add_to_wait_list(state, &dest_addr, &src_addr);
                        Some(TargetedRequest { request: Ping, target: dest_addr })
                    },
                    AckHost(member) => {
                        ack_response(state, member.remote_host().unwrap());
                        mark_node_alive(state, member.remote_host().unwrap(), event_tx, request_tx);
                        None
                    }
                };

                match response {
                    Some(response) => request_tx.send(response).unwrap(),
                    None => (),
                };
            }
        },
    };
}

fn add_to_wait_list(state: &mut State, wait_addr: &SocketAddr, notify_addr: &SocketAddr) {
    match state.wait_list.entry(*wait_addr) {
        Entry::Occupied(mut entry) => { entry.get_mut().push(notify_addr.clone()); },
        Entry::Vacant(entry) => { entry.insert(vec![notify_addr.clone()]); }
    };
}

fn remove_potential_seed(state: &mut State, src_addr: SocketAddr) {
    state.seed_queue.retain(|&addr| addr != src_addr)
}

fn ack_response(state: &mut State, src_addr: SocketAddr) {
    let mut to_remove = Vec::new();

    for &(ref t, ref addr, ref state_changes) in state.pending_responses.iter() {
        if src_addr != *addr {
            continue;
        }

        to_remove.push((t.clone(), addr.clone(), state_changes.clone()));

        state.state_changes
            .retain(|os| !state_changes.iter().any(| is | is.member().host_key() == os.member().host_key()))
    }

    state.pending_responses.retain(|op| !to_remove.iter().any(|ip| ip == op));
}

fn ensure_node_is_member(state: &mut State, src_addr: SocketAddr, event_tx: &Sender<ClusterEvent>, sender: Uuid) {
    if state.members.has_member(&src_addr) {
        return;
    }

    let new_member = Member::new(sender, src_addr, 0, MemberState::Alive);

    state.members.add_member(new_member.clone());
    enqueue_state_change(state, &[new_member.clone()]);
    send_member_event(&state.members, event_tx, MemberEvent::MemberJoined(new_member));
}

fn mark_node_alive(state: &mut State, src_addr: SocketAddr, event_tx: &Sender<ClusterEvent>, request_tx: &Sender<TargetedRequest>) {
    if let Some(member) = state.members.mark_node_alive(&src_addr) {
        match state.wait_list.get_mut(&src_addr) {
            Some(mut wait_list) => {
                for remote in wait_list.drain() {
                    request_tx.send(TargetedRequest { request: Request::AckHost(member.clone()), target: remote }).unwrap();
                }
            },
            None => ()
        };

        enqueue_state_change(state, &[member.clone()]);
        send_member_event(&state.members, event_tx, MemberEvent::MemberWentUp(member.clone()));
    }
}

fn apply_state_changes(state: &mut State, state_changes: Vec<StateChange>, from: SocketAddr, event_tx: &Sender<ClusterEvent>) {
    let (new, changed) = state.members.apply_state_changes(state_changes, &from);

    enqueue_state_change(state, new.as_slice());
    enqueue_state_change(state, changed.as_slice());

    for member in new {

        send_member_event(&state.members, event_tx, MemberEvent::MemberJoined(member));
    }

    for member in changed {
        send_member_event(&state.members, event_tx, determine_member_event(member));
    }
}

fn determine_member_event(member: Member) -> MemberEvent {
    use member::MemberState::*;
    use MemberEvent::*;

    return match member.state() {
        Alive => MemberWentUp(member),
        Suspect => MemberSuspectedDown(member),
        Down => MemberWentDown(member),
    };
}

fn enqueue_state_change(state: &mut State, members: &[Member]) {
    for member in members {
        for state_change in &mut state.state_changes {
            if state_change.member().host_key() == member.host_key() {
                state_change.update(member.clone());
                return;
            }
        }

        state.state_changes.push(StateChange::new(member.clone()));
    }
}

impl Decodable for EncSocketAddr {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        match d.read_str() {
            Ok(s) => match FromStr::from_str(s.as_slice()) {
                Ok(addr) => Ok(EncSocketAddr(addr)),
                Err(e) => Err(d.error(format!("{:?}", e).as_slice())),
            },
            Err(e) => Err(e),
        }
    }
}

impl Encodable for EncSocketAddr {
    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
        let &EncSocketAddr(addr) = self;
        format!("{}", addr).encode(e)
    }
}

impl EncSocketAddr {
    fn from_addr(addr: &SocketAddr) -> Self {
        EncSocketAddr(addr.clone())
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_term;

extern crate blas;
extern crate openblas_src;

extern crate ndarray;

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_test;

extern crate rand;

pub mod utils;
mod consts;
mod macros;

pub extern crate spaces as geometry;
pub use self::geometry::{Matrix, Vector};

mod parameter;
pub use self::parameter::Parameter;

pub mod agents;
pub mod domains;
pub mod fa;
pub mod logging;
pub mod policies;

mod experiment;
pub use self::experiment::*;
<commit_msg>fix: re-add macro_use annotation to ndarray crate<commit_after>#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_term;

extern crate blas;
extern crate openblas_src;

#[macro_use]
extern crate ndarray;

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_test;

extern crate rand;

pub mod utils;
mod consts;
mod macros;

pub extern crate spaces as geometry;
pub use self::geometry::{Matrix, Vector};

mod parameter;
pub use self::parameter::Parameter;

pub mod agents;
pub mod domains;
pub mod fa;
pub mod logging;
pub mod policies;

mod experiment;
pub use self::experiment::*;
<|endoftext|>


<commit_before>extern crate time;

use std::iter::Iterator;

use time::{now_utc, Tm, Duration};

pub struct ProgressRecord {
    num: usize,
    iterating_for: Duration,
    size_hint: (usize, Option<usize>),

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().num_seconds(), self.num_done(), self.rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        (self.num_done() as f32) / (self.duration_since_start().num_seconds() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_print_every_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_print_every_items(n) {
            print!("{}", msg);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Tm,
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: now_utc() }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now_utc() - self.started_iterating, size_hint: self.iter.size_hint() }
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep_ms;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<commit_msg>docs: Some doccomments<commit_after>extern crate time;

use std::iter::Iterator;

use time::{now_utc, Tm, Duration};

pub struct ProgressRecord {

    /// How many elements before this
    num: usize,
    iterating_for: Duration,
    size_hint: (usize, Option<usize>),

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().num_seconds(), self.num_done(), self.rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        (self.num_done() as f32) / (self.duration_since_start().num_seconds() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_print_every_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_print_every_items(n) {
            print!("{}", msg);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Tm,
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: now_utc() }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now_utc() - self.started_iterating, size_hint: self.iter.size_hint() }
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep_ms;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<|endoftext|>


<commit_before>//! MockMe is a tool used to mock dependencies / function calls when running unit (lib) tests in Rust.
//!
//! ## How to Use
//!
//! Simply use the macro as seen in the example below.
//! When this code is run normally, MockMe will have no effect.
//! However, when the code is run as part of a unit test #[cfg(test)],
//! the mocked token will be used instead.
//!
//! In order to use, we first must mark the functions that we would like to mock.
//! When running tests, we then identify the replacement function that we would like to inject.
//!
//! ```rust,ignore
//!
//! #![feature(proc_macro)]
//! extern crate mock_me;
//! use mock_me::{mock, inject};
//!
//! // Below we will create two mocking identifiers called id_1 and id_2.
//! // We will then provide the name of the two functions we are mocking, as well as
//! // their type signature. In future iterations, hopefully the signature won't be needed.
//! #[mock(id_1="external_db_call: fn(u32) -> String", id_2="other_call: fn() -> String")]
//! fn my_super_cool_function() -> String {
//!     let input = 42u32;
//!     // external_db_call will be replaced with fake_mocked_call during testing
//!     let db_result = external_db_call(input);
//!
//!     // other_call will also be replaced
//!     let other_result = other_call();
//!     format!("I have two results! {} and {}", db_result, other_result)
//! }
//!
//! // Finally, when we run our tests, we simply need to provide the identifier we previously used,
//! // as well as the name of the replacement function
//! #[test]
//! #[inject(id_1="db_fake", id_2="other_fake")]
//! fn actual_test2() {
//!     let result = my_super_cool_function();
//!     assert_eq!(result, "I have two results! Faker! and This is indeed a disturbing universe.");
//! }
//!
//! fn db_fake(_: u32) -> String { "Faker!".to_string() }
//! fn other_fake() -> String { "This is indeed a disturbing universe.".to_string() }
//!
//! ```

#![feature(proc_macro)]
#![feature(insert_str)]
extern crate proc_macro;
use proc_macro::TokenStream;

extern crate mock_me_test_context;

use std::fmt::Write;

mod macro_helper;
use macro_helper::*;

/// The mock macro is used mock a concrete function that is not desired during unit tests.
/// Its signature contains the identifier that is being mocked, with the function that will replace
/// the mocked function within quotes, as well as the mocked function signature.
#[proc_macro_attribute]
pub fn mock(attr: TokenStream, item: TokenStream) -> TokenStream {
    let mock_matches = get_mock_matches(&*attr.to_string());

    let mut source = item.to_string();

    // I should find a more structured way of injecting test context into top of method
    let insertion_point = source.find("{").unwrap() + 1;
    source.insert_str(insertion_point, HEADER);

    let mut modified_source = source.clone();
    for m_match in mock_matches {
        let ctx_getter = format!(r#"
            (unsafe {{
                let _mock_me_test_usize_func = _mock_me_test_context_instance.get("{}");
                let _mock_me_test_transmuted_func: {} = std::mem::transmute(_mock_me_test_usize_func);
                _mock_me_test_transmuted_func
            }})
        "#, m_match.identifier, m_match.function_signature);

        // string replacement should be more controlled ideally than a blind replace
        modified_source = modified_source.replace(&*m_match.function_to_mock, &*ctx_getter);
    }

    let branched_source = format!(
        r#"
        #[cfg(not(test))]
        {}

        #[cfg(test)]
        {}
        "#, source, modified_source
    );

    branched_source.parse().unwrap()
}

/// The inject macro is used to replace a mocked function with an alternative implementation.
/// Its signature contains the identifier that is being mocked, with the function that will replace
/// the mocked function within quotes.
#[proc_macro_attribute]
pub fn inject(attr: TokenStream, item: TokenStream) -> TokenStream {
    let inject_matches = get_inject_matches(&*attr.to_string());

    let mut source = item.to_string();

    let mut context_setter_string = HEADER.to_string();

    for i_match in inject_matches {
        write!(
            context_setter_string,
            "_mock_me_test_context_instance.set(\"{}\".to_string(), {} as usize);\n",
            i_match.identifier, i_match.function_to_mock
        ).unwrap();
    }

    // I should find a more structured way of injecting test context into top of method
    let insertion_point = source.find("{").unwrap() + 1;
    source.insert_str(insertion_point, &*context_setter_string);

    source.parse().unwrap()
}<commit_msg>Removing unneeded code<commit_after>//! MockMe is a tool used to mock dependencies / function calls when running unit (lib) tests in Rust.
//!
//! ## How to Use
//!
//! Simply use the macro as seen in the example below.
//! When this code is run normally, MockMe will have no effect.
//! However, when the code is run as part of a unit test #[cfg(test)],
//! the mocked token will be used instead.
//!
//! In order to use, we first must mark the functions that we would like to mock.
//! When running tests, we then identify the replacement function that we would like to inject.
//!
//! ```rust,ignore
//!
//! #![feature(proc_macro)]
//! extern crate mock_me;
//! use mock_me::{mock, inject};
//!
//! // Below we will create two mocking identifiers called id_1 and id_2.
//! // We will then provide the name of the two functions we are mocking, as well as
//! // their type signature. In future iterations, hopefully the signature won't be needed.
//! #[mock(id_1="external_db_call: fn(u32) -> String", id_2="other_call: fn() -> String")]
//! fn my_super_cool_function() -> String {
//!     let input = 42u32;
//!     // external_db_call will be replaced with fake_mocked_call during testing
//!     let db_result = external_db_call(input);
//!
//!     // other_call will also be replaced
//!     let other_result = other_call();
//!     format!("I have two results! {} and {}", db_result, other_result)
//! }
//!
//! // Finally, when we run our tests, we simply need to provide the identifier we previously used,
//! // as well as the name of the replacement function
//! #[test]
//! #[inject(id_1="db_fake", id_2="other_fake")]
//! fn actual_test2() {
//!     let result = my_super_cool_function();
//!     assert_eq!(result, "I have two results! Faker! and This is indeed a disturbing universe.");
//! }
//!
//! fn db_fake(_: u32) -> String { "Faker!".to_string() }
//! fn other_fake() -> String { "This is indeed a disturbing universe.".to_string() }
//!
//! ```

#![feature(proc_macro)]
extern crate proc_macro;
use proc_macro::TokenStream;

use std::fmt::Write;

mod macro_helper;
use macro_helper::*;

/// The mock macro is used mock a concrete function that is not desired during unit tests.
/// Its signature contains the identifier that is being mocked, with the function that will replace
/// the mocked function within quotes, as well as the mocked function signature.
#[proc_macro_attribute]
pub fn mock(attr: TokenStream, item: TokenStream) -> TokenStream {
    let mock_matches = get_mock_matches(&*attr.to_string());

    let mut source = item.to_string();

    // I should find a more structured way of injecting test context into top of method
    let insertion_point = source.find("{").unwrap() + 1;
    source.insert_str(insertion_point, HEADER);

    let mut modified_source = source.clone();
    for m_match in mock_matches {
        let ctx_getter = format!(r#"
            (unsafe {{
                let _mock_me_test_usize_func = _mock_me_test_context_instance.get("{}");
                let _mock_me_test_transmuted_func: {} = std::mem::transmute(_mock_me_test_usize_func);
                _mock_me_test_transmuted_func
            }})
        "#, m_match.identifier, m_match.function_signature);

        // string replacement should be more controlled ideally than a blind replace
        modified_source = modified_source.replace(&*m_match.function_to_mock, &*ctx_getter);
    }

    let branched_source = format!(
        r#"
        #[cfg(not(test))]
        {}

        #[cfg(test)]
        {}
        "#, source, modified_source
    );

    branched_source.parse().unwrap()
}

/// The inject macro is used to replace a mocked function with an alternative implementation.
/// Its signature contains the identifier that is being mocked, with the function that will replace
/// the mocked function within quotes.
#[proc_macro_attribute]
pub fn inject(attr: TokenStream, item: TokenStream) -> TokenStream {
    let inject_matches = get_inject_matches(&*attr.to_string());

    let mut source = item.to_string();

    let mut context_setter_string = HEADER.to_string();

    for i_match in inject_matches {
        write!(
            context_setter_string,
            "_mock_me_test_context_instance.set(\"{}\".to_string(), {} as usize);\n",
            i_match.identifier, i_match.function_to_mock
        ).unwrap();
    }

    // I should find a more structured way of injecting test context into top of method
    let insertion_point = source.find("{").unwrap() + 1;
    source.insert_str(insertion_point, &*context_setter_string);

    source.parse().unwrap()
}<|endoftext|>


<commit_before>//! This crate provides a Rust implementation of VerbalExpressions in order to build regex
//! strings without knowing the minutiae of regex syntax.
//!
//! It uses the `Regex` crate to compile the created regex strings.
//!
//! # Examples
//!
//! A simple example to show the API.
//!
//! ```rust
//! # extern crate verex;
//! use verex::VerEx;
//! use verex::find;
//!
//! # fn main() {
//!     // You can either use a mutable verex to define different regexes
//!     let mut verex = VerEx::new();
//!     let regex1 = verex.find("a")
//!                       .compile()
//!                       .unwrap();
//!
//!     let regex2 = verex.or_find("b")
//!                       .compile()
//!                       .unwrap();
//!
//!     // Or just use it for building one
//!     let regex3 = VerEx::new().find("a")
//!                              .or_find("b")
//!                              .compile()
//!                              .unwrap();
//!
//!     // Also you can just use the functions directly as constructors
//!     let regex4 = find("a")
//!                  .or_find("b")
//!                  .compile()
//!                  .unwrap();
//!
//!     // Test if the URL is valid
//!     assert!(!regex1.is_match("b"));
//!     assert!(regex2.is_match("b"));
//!     assert!(regex3.is_match("b"));
//!     assert!(regex4.is_match("b"));
//!
//!     // Test the generated regex string
//!     assert_eq!(regex1.as_str(), r"(?:a)");
//!     assert_eq!(regex2.as_str(), r"(?:a)|(?:b)");
//!     assert_eq!(regex3.as_str(), r"(?:a)|(?:b)");
//!     assert_eq!(regex4.as_str(), r"(?:a)|(?:b)");
//! # }
//! ```
//!
//!
//! Here's a URL testing example shamelessly stolen from the python VerEx readme:
//!
//! ```rust
//! # extern crate verex;
//! use verex::VerEx;
//!
//! # fn main() {
//!     // Create an example of how to test for correctly formed URLs
//!     let mut verex = VerEx::new();
//!     let regex = verex
//!                 .start_of_line()
//!                 .find("http")
//!                 .maybe("s")
//!                 .find("://")
//!                 .maybe("www.")
//!                 .anything_but(" ")
//!                 .end_of_line()
//!                 .compile()
//!                 .unwrap();
//!
//!     // Create an example URL
//!     let test_url = r"https://www.google.com";
//!
//!     // Test if the URL is valid
//!     assert!(regex.is_match(test_url));
//!
//!     // Test the generated regex string
//!     assert_eq!(verex.source(), r"^(?:http)(?:s)?(?:://)(?:www.)?(?:[^ ]*)$");
//! # }
//! ```

#![warn(missing_docs)]

extern crate regex;

pub use verex::VerEx;

mod verex;

// standalone functions
/// Any of the given characters
pub fn any(chars: &str) -> VerEx {
    VerEx::new().any(chars).clone()
}

/// See any()
pub fn any_of(chars: &str) -> VerEx {
    any(chars)
}

/// Any character zero or more times
pub fn anything() -> VerEx {
    VerEx::new().anything().clone()
}

/// Any character zero or more times except the provided characters
pub fn anything_but(value: &str) -> VerEx {
    VerEx::new().anything_but(value).clone()
}

/// A line break!
pub fn br() -> VerEx {
    line_break()
}

/// Find a specific string and capture it
pub fn capture(value: &str) -> VerEx {
    VerEx::new().capture(value).clone()
}

/// Add a token for the end of a line
pub fn end_of_line() -> VerEx {
    VerEx::new().end_of_line().clone()
}

/// Find a specific string
pub fn find(value: &str) -> VerEx {
    VerEx::new().find(value).clone()
}

/// A line break!
pub fn line_break() -> VerEx {
    VerEx::new().line_break().clone()
}

/// Any string either one or zero times
pub fn maybe(value: &str) -> VerEx {
    VerEx::new().maybe(value).clone()
}

// TODO: implement variadic macro
// /// Either match the sub-expression before or after this
// pub fn or(&mut self) -> &mut VerEx {
//     self.add(r"|")
// }

/// A range of characters e.g. [A-Z]
/// Usage example: verex.range(vec![('a', 'z'),('A', 'Z')])
pub fn range(range: Vec<(char, char)>) -> VerEx {
    VerEx::new().range(range).clone()
}

/// Any character at least one time
pub fn something() -> VerEx {
    VerEx::new().something().clone()
}

/// Any character at least one time except for these characters
pub fn something_but(value: &str) -> VerEx {
    VerEx::new().something_but(value).clone()
}

/// Add a token for the start of a line
pub fn start_of_line() -> VerEx {
    VerEx::new().start_of_line().clone()
}

/// Add a token for a tab
pub fn tab() -> VerEx {
    VerEx::new().tab().clone()
}

/// Any alphanumeric characters
pub fn word() -> VerEx {
    VerEx::new().word().clone()
}
<commit_msg>implement or! macro and add example<commit_after>//! This crate provides a Rust implementation of VerbalExpressions in order to build regex
//! strings without knowing the minutiae of regex syntax.
//!
//! It uses the `Regex` crate to compile the created regex strings.
//!
//! # Examples
//!
//! A simple example to show the usage:
//!
//! ```rust
//! # extern crate verex;
//! use verex::VerEx;
//! use verex::find;
//!
//! # fn main() {
//!     // You can either use a mutable verex to define different regexes
//!     let mut verex = VerEx::new();
//!     let regex1 = verex.find("a")
//!                       .compile()
//!                       .unwrap();
//!
//!     let regex2 = verex.or_find("b")
//!                       .compile()
//!                       .unwrap();
//!
//!     // Or just use it for building one
//!     let regex3 = VerEx::new().find("a")
//!                              .or_find("b")
//!                              .compile()
//!                              .unwrap();
//!
//!     // Also you can just use the functions directly as constructors
//!     let regex4 = find("a")
//!                  .or_find("b")
//!                  .compile()
//!                  .unwrap();
//!
//!     // Test whether the regexes match correctly
//!     assert!(!regex1.is_match("b"));
//!     assert!(regex2.is_match("b"));
//!     assert!(regex3.is_match("b"));
//!     assert!(regex4.is_match("b"));
//!
//!     // Test the generated regex strings
//!     assert_eq!(regex1.as_str(), r"(?:a)");
//!     assert_eq!(regex2.as_str(), r"(?:a)|(?:b)");
//!     assert_eq!(regex3.as_str(), r"(?:a)|(?:b)");
//!     assert_eq!(regex4.as_str(), r"(?:a)|(?:b)");
//! # }
//! ```
//!
//!
//! Here's a URL testing example shamelessly stolen from the python VerEx readme:
//!
//! ```rust
//! # extern crate verex;
//! use verex::VerEx;
//!
//! # fn main() {
//!     // Create an example of how to test for correctly formed URLs
//!     let mut verex = VerEx::new();
//!     let regex = verex
//!                 .start_of_line()
//!                 .find("http")
//!                 .maybe("s")
//!                 .find("://")
//!                 .maybe("www.")
//!                 .anything_but(" ")
//!                 .end_of_line()
//!                 .compile()
//!                 .unwrap();
//!
//!     // Create an example URL
//!     let test_url = r"https://www.google.com";
//!
//!     // Test if the URL is valid
//!     assert!(regex.is_match(test_url));
//!
//!     // Test the generated regex string
//!     assert_eq!(verex.source(), r"^(?:http)(?:s)?(?:://)(?:www.)?(?:[^ ]*)$");
//! # }
//! ```
//!
//! Example usage of the or! macro:
//!
//! ```rust
//! #[macro_use(or)]
//! extern crate verex;
//!
//! # fn main() {
//!     let regex = or!("foo", "bar", "baz")
//!                 .compile()
//!                 .unwrap();
//!
//!     // Test if the regex matches correctly
//!     assert!(regex.is_match("foo"));
//!     assert!(regex.is_match("bar"));
//!     assert!(regex.is_match("baz"));
//!     assert!(!regex.is_match("bum"));
//!
//!     // Test the generated regex string
//!     assert_eq!(regex.as_str(), r"(?:foo)|(?:bar)|(?:baz)");
//! # }
//! ```

#![warn(missing_docs)]

extern crate regex;

pub use verex::VerEx;

mod verex;

// standalone functions
/// Any of the given characters
pub fn any(chars: &str) -> VerEx {
    VerEx::new().any(chars).clone()
}

/// See any()
pub fn any_of(chars: &str) -> VerEx {
    any(chars)
}

/// Any character zero or more times
pub fn anything() -> VerEx {
    VerEx::new().anything().clone()
}

/// Any character zero or more times except the provided characters
pub fn anything_but(value: &str) -> VerEx {
    VerEx::new().anything_but(value).clone()
}

/// A line break!
pub fn br() -> VerEx {
    line_break()
}

/// Find a specific string and capture it
pub fn capture(value: &str) -> VerEx {
    VerEx::new().capture(value).clone()
}

/// Add a token for the end of a line
pub fn end_of_line() -> VerEx {
    VerEx::new().end_of_line().clone()
}

/// Find a specific string
pub fn find(value: &str) -> VerEx {
    VerEx::new().find(value).clone()
}

/// A line break!
pub fn line_break() -> VerEx {
    VerEx::new().line_break().clone()
}

/// Any string either one or zero times
pub fn maybe(value: &str) -> VerEx {
    VerEx::new().maybe(value).clone()
}

/// Match any of the given sub-expressions
#[macro_export]
macro_rules! or {
    ( $first_string:expr, $( $string:expr ),* ) => {
        {
            let mut verex = $crate::VerEx::new();
            verex.find($first_string);
            $(
                verex.or_find($string);
            )*
            verex
        }
    };
}

/// A range of characters e.g. [A-Z]
/// Usage example: verex.range(vec![('a', 'z'),('A', 'Z')])
pub fn range(range: Vec<(char, char)>) -> VerEx {
    VerEx::new().range(range).clone()
}

/// Any character at least one time
pub fn something() -> VerEx {
    VerEx::new().something().clone()
}

/// Any character at least one time except for these characters
pub fn something_but(value: &str) -> VerEx {
    VerEx::new().something_but(value).clone()
}

/// Add a token for the start of a line
pub fn start_of_line() -> VerEx {
    VerEx::new().start_of_line().clone()
}

/// Add a token for a tab
pub fn tab() -> VerEx {
    VerEx::new().tab().clone()
}

/// Any alphanumeric characters
pub fn word() -> VerEx {
    VerEx::new().word().clone()
}
<|endoftext|>


<commit_before>#![allow(raw_pointer_derive)]

pub mod graph;
pub mod vertex;
pub mod edge;
pub mod traversal;

#[cfg(test)]
mod tests {
    use vertex::{Vertex, GraphProperty};
    use graph::Graph;
    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        let e1 = v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct

        assert_eq!(v1.v, e1.from_vertex);
        assert_eq!(e1.to_vertex, v2.v);

        //assert_eq!(v1.v, *(e1.edge).from_vertex);
    }

    #[test]
    fn test_properties() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let key = "jon".to_string();
        let value = GraphProperty::Int(1);
        v1.set_property(key.clone(), value);

        let result = v1.get_property(key).unwrap();

        match result {
            &GraphProperty::Int(1) =>
                // we're ok
                println!("OK"),
            _ =>
                panic!("wrong graph property")
        }
    }

    #[test]
    fn test_get_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let v = g.get(1).unwrap();
        assert_eq!(v.id, 1);
    }

    #[test]
    fn test_graph_query_off_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let query = g.v(1);
    }

    #[test]
    fn test_traversal_map() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let result = g.v(1).outV();
    }

	#[test]
	fn test_vertex_outv() {
		let mut g = Graph::new();
		let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();

		vertex.add_edge(&mut vertex2);

		let result = vertex.outV();
		assert_eq!(1, result.len());

	}
}
<commit_msg>outV working off a single vertex<commit_after>#![allow(raw_pointer_derive)]

pub mod graph;
pub mod vertex;
pub mod edge;
pub mod traversal;

#[cfg(test)]
mod tests {
    use vertex::{Vertex, GraphProperty};
    use graph::Graph;
    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        let e1 = v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct

        assert_eq!(v1.v, e1.from_vertex);
        assert_eq!(e1.to_vertex, v2.v);

        //assert_eq!(v1.v, *(e1.edge).from_vertex);
    }

    #[test]
    fn test_properties() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let key = "jon".to_string();
        let value = GraphProperty::Int(1);
        v1.set_property(key.clone(), value);

        let result = v1.get_property(key).unwrap();

        match result {
            &GraphProperty::Int(1) =>
                // we're ok
                println!("OK"),
            _ =>
                panic!("wrong graph property")
        }
    }

    #[test]
    fn test_get_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let v = g.get(1).unwrap();
        assert_eq!(v.id, 1);
    }

    #[test]
    fn test_graph_query_off_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let query = g.v(1);
    }

    #[test]
    fn test_traversal_map() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let result = g.v(1).outV();
    }

	#[test]
	fn test_vertex_outv() {
		let mut g = Graph::new();
		let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();

		vertex.add_edge(&mut vertex2);

		let result = vertex.outV();
		assert_eq!(1, result.len());

		// add another edge, check length
		let mut vertex3 = g.add_vertex();
		vertex.add_edge(&mut vertex3);

		let result = vertex.outV();
		assert_eq!(2, result.len());

	}
}
<|endoftext|>


<commit_before>#![feature(trace_macros)]
pub mod signals {
    extern crate libc;
    use std::os;
    use std::mem;

    #[derive(Hash, Eq, PartialEq, Copy, Show, FromPrimitive)]
    pub enum Signal {
        None = 0,
        Hup,
        Int,
        Quit,
        Ill,
        Trap,
        Abrt,
        Bus,
        Fpe,
        Kill,
        Usr1,
        Segv,
        Usr2,
        Pipe,
        Alrm,
        Term,
        StkFlt,
        Chld,
        Cont,
        Stop,
        Tstp,
        Ttin,
    }

    impl Signal {
        pub fn raise(self) -> Result<(), usize> {
            match unsafe { raise(self as libc::c_int) } {
                0 => Result::Ok(()),
                _ => Result::Err(os::errno())
            }
        }

        pub fn kill(self, pid: libc::pid_t) -> Result<(), usize> {
            match unsafe { kill(pid, self as libc::c_int) } {
                0 => Result::Ok(()),
                _ => Result::Err(os::errno())
            }
        }

        pub unsafe fn handle(self, handler: Box<FnMut(Signal)>) -> Result<(), usize> {
            match unsafe { signal (self as libc::c_int, mem::transmute(glue::rust_signal_handler)) } {
                -1 => Result::Err(os::errno()),
                _ => { glue::set_handler(self, handler); Result::Ok(()) }
            }
        }
    }

    mod glue {
        extern crate libc;
        extern crate alloc;
        use super::Signal;
        use std::num::FromPrimitive;
        use self::alloc::arc::Arc;
        use std::rc::Rc;
        use std::mem;
        use std::ptr;

        #[derive(Copy,Show)]
        struct FnPtr {
            foo: usize,
            bar: usize
        }

        static mut handlers: [FnPtr; 18] = [
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
        ];

        pub unsafe fn set_handler (sig: Signal, f: Box<FnMut(Signal)>) {
            handlers[sig as usize] = mem::transmute(f);
        }

        fn null_handler(s: Signal) {}

        pub unsafe extern "C" fn rust_signal_handler(sig: libc::c_int) {
            let f: *mut FnMut(Signal) = mem::transmute(handlers[sig as usize]);
            let p: FnPtr = mem::transmute(f);
            if p.foo != 0 && p.bar != 0 {
                (*f)(FromPrimitive::from_i32(sig).expect("unknown signal"));
            }
        }
    }

    extern "C" {
        fn raise(sig: libc::c_int) -> libc::c_int;
        fn signal(sig: libc::c_int, handler: *const libc::c_void) -> libc::c_int;
        fn kill(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int;
    }
}
<commit_msg>Be more verbose of bad signals<commit_after>#![feature(trace_macros)]
pub mod signals {
    extern crate libc;
    use std::os;
    use std::mem;

    #[derive(Hash, Eq, PartialEq, Copy, Show, FromPrimitive)]
    pub enum Signal {
        None = 0,
        Hup,
        Int,
        Quit,
        Ill,
        Trap,
        Abrt,
        Bus,
        Fpe,
        Kill,
        Usr1,
        Segv,
        Usr2,
        Pipe,
        Alrm,
        Term,
        StkFlt,
        Chld,
        Cont,
        Stop,
        Tstp,
        Ttin,
    }

    impl Signal {
        pub fn raise(self) -> Result<(), usize> {
            match unsafe { raise(self as libc::c_int) } {
                0 => Result::Ok(()),
                _ => Result::Err(os::errno())
            }
        }

        pub fn kill(self, pid: libc::pid_t) -> Result<(), usize> {
            match unsafe { kill(pid, self as libc::c_int) } {
                0 => Result::Ok(()),
                _ => Result::Err(os::errno())
            }
        }

        pub unsafe fn handle(self, handler: Box<FnMut(Signal)>) -> Result<(), usize> {
            match unsafe { signal (self as libc::c_int, mem::transmute(glue::rust_signal_handler)) } {
                -1 => Result::Err(os::errno()),
                _ => { glue::set_handler(self, handler); Result::Ok(()) }
            }
        }
    }

    mod glue {
        extern crate libc;
        extern crate alloc;
        use super::Signal;
        use std::num::FromPrimitive;
        use self::alloc::arc::Arc;
        use std::rc::Rc;
        use std::mem;
        use std::ptr;

        #[derive(Copy,Show)]
        struct FnPtr {
            foo: usize,
            bar: usize
        }

        static mut handlers: [FnPtr; 18] = [
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
            FnPtr {foo: 0, bar: 0},
        ];

        pub unsafe fn set_handler (sig: Signal, f: Box<FnMut(Signal)>) {
            handlers[sig as usize] = mem::transmute(f);
        }

        fn null_handler(s: Signal) {}

        pub unsafe extern "C" fn rust_signal_handler(sig: libc::c_int) {
            let f: *mut FnMut(Signal) = mem::transmute(handlers[sig as usize]);
            let p: FnPtr = mem::transmute(f);
            if p.foo != 0 && p.bar != 0 {
                match FromPrimitive::from_i32(sig) {
                    Some(s) => (*f)(s),
                    None => panic!("Unknown signal {}", sig)
                }
            }
        }
    }

    extern "C" {
        fn raise(sig: libc::c_int) -> libc::c_int;
        fn signal(sig: libc::c_int, handler: *const libc::c_void) -> libc::c_int;
        fn kill(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int;
    }
}
<|endoftext|>


<commit_before>//! # `-lstdc++` or `-lc++`
//!
//! This crate exists for the purpose of passing `-lstdc++` or `-lc++` to the
//! linker, while making it possible for an application to make that choice on
//! behalf of its library dependencies.
//!
//! Without this crate, a library would need to:
//!
//! - pick one or the other to link, with no way for downstream applications to
//!   override the choice;
//! - or link neither and require an explicit link flag provided by downstream
//!   applications even if they would be fine with a default choice;
//!
//! neither of which are good experiences.
//!
//!

//!
//! # Options
//!
//! An application or library that is fine with either of libstdc++ or libc++
//! being linked, whichever is the platform's default, should use:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = "1.0"
//! ```
//!
//! An application that wants a particular one or the other linked should use:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = { version = "1.0", features = ["libstdcxx"] }
//!
//! # or
//!
//! link-cplusplus = { version = "1.0", features = ["libcxx"] }
//! ```
//!
//! An application that wants to handle its own more complicated logic for link
//! flags from its build script can make this crate do nothing by using:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = { version = "1.0", features = ["nothing"] }
//! ```
<commit_msg>Add crosslink icons to top of rustdoc<commit_after>//! [![github]](https://github.com/dtolnay/link-cplusplus) [![crates-io]](https://crates.io/crates/link-cplusplus) [![docs-rs]](https://docs.rs/link-cplusplus)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//!

//!
//! # `-lstdc++` or `-lc++`
//!
//! This crate exists for the purpose of passing `-lstdc++` or `-lc++` to the
//! linker, while making it possible for an application to make that choice on
//! behalf of its library dependencies.
//!
//! Without this crate, a library would need to:
//!
//! - pick one or the other to link, with no way for downstream applications to
//!   override the choice;
//! - or link neither and require an explicit link flag provided by downstream
//!   applications even if they would be fine with a default choice;
//!
//! neither of which are good experiences.
//!
//!

//!
//! # Options
//!
//! An application or library that is fine with either of libstdc++ or libc++
//! being linked, whichever is the platform's default, should use:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = "1.0"
//! ```
//!
//! An application that wants a particular one or the other linked should use:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = { version = "1.0", features = ["libstdcxx"] }
//!
//! # or
//!
//! link-cplusplus = { version = "1.0", features = ["libcxx"] }
//! ```
//!
//! An application that wants to handle its own more complicated logic for link
//! flags from its build script can make this crate do nothing by using:
//!
//! ```toml
//! [dependencies]
//! link-cplusplus = { version = "1.0", features = ["nothing"] }
//! ```
<|endoftext|>