<commit_before>// Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2019 Alibaba Cloud Computing. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

#[macro_use]
extern crate log;

use std::io;
use std::result;
use std::sync::{Arc, Mutex};
use std::thread;

use vhost::vhost_user::message::VhostUserSingleMemoryRegion;
use vhost::vhost_user::{
    Error as VhostUserError, Listener, SlaveListener, VhostUserSlaveReqHandlerMut,
};
use virtio_queue::Queue;
use vm_memory::{
    GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap, GuestRegionMmap, MmapRegion,
};
use vmm_sys_util::eventfd::EventFd;

use self::handler::VhostUserHandler;

mod backend;
pub use self::backend::{VhostUserBackend, VhostUserBackendMut};

mod event_loop;
pub use self::event_loop::{VringEpollError, VringEpollHandler, VringEpollResult};

mod handler;
pub use self::handler::VhostUserHandlerError;

#[derive(Debug)]
/// Errors related to vhost-user daemon.
pub enum Error {
    /// Failed to create a new vhost-user handler.
    NewVhostUserHandler(VhostUserHandlerError),
    /// Failed creating vhost-user slave listener.
    CreateSlaveListener(VhostUserError),
    /// Failed creating vhost-user slave handler.
    CreateSlaveReqHandler(VhostUserError),
    /// Failed starting daemon thread.
    StartDaemon(io::Error),
    /// Failed waiting for daemon thread.
    WaitDaemon(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
    /// Failed handling a vhost-user request.
    HandleRequest(VhostUserError),
    /// Failed to process queue.
    ProcessQueue(VringEpollError),
    /// Failed to register listener.
    RegisterListener(io::Error),
    /// Failed to unregister listener.
    UnregisterListener(io::Error),
}

/// Result of vhost-user daemon operations.
pub type Result<T> = result::Result<T, Error>;

/// This structure is the public API the backend is allowed to interact with
/// in order to run a fully functional vhost-user daemon.
pub struct VhostUserDaemon<S: VhostUserBackend> {
    name: String,
    handler: Arc<Mutex<VhostUserHandler<S>>>,
    main_thread: Option<thread::JoinHandle<Result<()>>>,
}

impl<S: VhostUserBackend + Clone> VhostUserDaemon<S> {
    /// Create the daemon instance, providing the backend implementation of
    /// VhostUserBackend.
    /// Under the hood, this will start a dedicated thread responsible for
    /// listening onto registered event. Those events can be vring events or
    /// custom events from the backend, but they get to be registered later
    /// during the sequence.
    pub fn new(name: String, backend: S) -> Result<Self> {
        let handler = Arc::new(Mutex::new(
            VhostUserHandler::new(backend).map_err(Error::NewVhostUserHandler)?,
        ));

        Ok(VhostUserDaemon {
            name,
            handler,
            main_thread: None,
        })
    }

    /// Connect to the vhost-user socket and run a dedicated thread handling
    /// all requests coming through this socket. This runs in an infinite loop
    /// that should be terminating once the other end of the socket (the VMM)
    /// disconnects.
    pub fn start(&mut self, listener: Listener) -> Result<()> {
        let mut slave_listener = SlaveListener::new(listener, self.handler.clone())
            .map_err(Error::CreateSlaveListener)?;
        let mut slave_handler = slave_listener
            .accept()
            .map_err(Error::CreateSlaveReqHandler)?
            .unwrap();
        let handle = thread::Builder::new()
            .name(self.name.clone())
            .spawn(move || loop {
                slave_handler
                    .handle_request()
                    .map_err(Error::HandleRequest)?;
            })
            .map_err(Error::StartDaemon)?;

        self.main_thread = Some(handle);

        Ok(())
    }

    /// Wait for the thread handling the vhost-user socket connection to
    /// terminate.
    pub fn wait(&mut self) -> Result<()> {
        if let Some(handle) = self.main_thread.take() {
            match handle.join().map_err(Error::WaitDaemon)? {
                Ok(()) => Ok(()),
                Err(Error::HandleRequest(VhostUserError::SocketBroken(_))) => Ok(()),
                Err(e) => Err(e),
            }
        } else {
            Ok(())
        }
    }

    /// Retrieve the vring worker. This is necessary to perform further
    /// actions like registering and unregistering some extra event file
    /// descriptors.
    pub fn get_epoll_handlers(&self) -> Vec<Arc<VringEpollHandler<S>>> {
        self.handler.lock().unwrap().get_epoll_handlers()
    }
}

pub struct Vring {
    queue: Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
    kick: Option<EventFd>,
    call: Option<EventFd>,
    err: Option<EventFd>,
    enabled: bool,
}

impl Vring {
    fn new(atomic_mem: GuestMemoryAtomic<GuestMemoryMmap>, max_queue_size: u16) -> Self {
        Vring {
            queue: Queue::new(atomic_mem, max_queue_size),
            kick: None,
            call: None,
            err: None,
            enabled: false,
        }
    }

    pub fn mut_queue(&mut self) -> &mut Queue<GuestMemoryAtomic<GuestMemoryMmap>> {
        &mut self.queue
    }

    pub fn signal_used_queue(&mut self) -> result::Result<(), io::Error> {
        if let Some(call) = self.call.as_ref() {
            call.write(1)
        } else {
            Ok(())
        }
    }
}
<commit_msg>Refine documentation and remove unused code<commit_after>// Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2019 Alibaba Cloud Computing. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! A simple framework to run a vhost-user backend service.

#[macro_use]
extern crate log;

use std::io;
use std::result;
use std::sync::{Arc, Mutex};
use std::thread;

use vhost::vhost_user::message::VhostUserSingleMemoryRegion;
use vhost::vhost_user::{
    Error as VhostUserError, Listener, SlaveListener, VhostUserSlaveReqHandlerMut,
};
use virtio_queue::Queue;
use vm_memory::{
    GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap, GuestRegionMmap, MmapRegion,
};
use vmm_sys_util::eventfd::EventFd;

use self::handler::VhostUserHandler;

mod backend;
pub use self::backend::{VhostUserBackend, VhostUserBackendMut};

mod event_loop;
pub use self::event_loop::{VringEpollError, VringEpollHandler, VringEpollResult};

mod handler;
pub use self::handler::VhostUserHandlerError;

#[derive(Debug)]
/// Errors related to vhost-user daemon.
pub enum Error {
    /// Failed to create a new vhost-user handler.
    NewVhostUserHandler(VhostUserHandlerError),
    /// Failed creating vhost-user slave listener.
    CreateSlaveListener(VhostUserError),
    /// Failed creating vhost-user slave handler.
    CreateSlaveReqHandler(VhostUserError),
    /// Failed starting daemon thread.
    StartDaemon(io::Error),
    /// Failed waiting for daemon thread.
    WaitDaemon(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
    /// Failed handling a vhost-user request.
    HandleRequest(VhostUserError),
}

/// Result of vhost-user daemon operations.
pub type Result<T> = result::Result<T, Error>;

/// Implement a simple framework to run a vhost user service daemon.
///
/// This structure is the public API the backend is allowed to interact with in order to run
/// a fully functional vhost-user daemon.
pub struct VhostUserDaemon<S: VhostUserBackend> {
    name: String,
    handler: Arc<Mutex<VhostUserHandler<S>>>,
    main_thread: Option<thread::JoinHandle<Result<()>>>,
}

impl<S: VhostUserBackend + Clone> VhostUserDaemon<S> {
    /// Create the daemon instance, providing the backend implementation of `VhostUserBackend`.
    ///
    /// Under the hood, this will start a dedicated thread responsible for listening onto
    /// registered event. Those events can be vring events or custom events from the backend,
    /// but they get to be registered later during the sequence.
    pub fn new(name: String, backend: S) -> Result<Self> {
        let handler = Arc::new(Mutex::new(
            VhostUserHandler::new(backend).map_err(Error::NewVhostUserHandler)?,
        ));

        Ok(VhostUserDaemon {
            name,
            handler,
            main_thread: None,
        })
    }

    /// Connect to the vhost-user socket and run a dedicated thread handling all requests coming
    /// through this socket.
    ///
    /// This runs in an infinite loop that should be terminating once the other end of the socket
    /// (the VMM) disconnects.
    pub fn start(&mut self, listener: Listener) -> Result<()> {
        let mut slave_listener = SlaveListener::new(listener, self.handler.clone())
            .map_err(Error::CreateSlaveListener)?;
        let mut slave_handler = slave_listener
            .accept()
            .map_err(Error::CreateSlaveReqHandler)?
            .unwrap();
        let handle = thread::Builder::new()
            .name(self.name.clone())
            .spawn(move || loop {
                slave_handler
                    .handle_request()
                    .map_err(Error::HandleRequest)?;
            })
            .map_err(Error::StartDaemon)?;

        self.main_thread = Some(handle);

        Ok(())
    }

    /// Wait for the thread handling the vhost-user socket connection to terminate.
    pub fn wait(&mut self) -> Result<()> {
        if let Some(handle) = self.main_thread.take() {
            match handle.join().map_err(Error::WaitDaemon)? {
                Ok(()) => Ok(()),
                Err(Error::HandleRequest(VhostUserError::SocketBroken(_))) => Ok(()),
                Err(e) => Err(e),
            }
        } else {
            Ok(())
        }
    }

    /// Retrieve the vring epoll handler.
    ///
    /// This is necessary to perform further actions like registering and unregistering some extra
    /// event file descriptors.
    pub fn get_epoll_handlers(&self) -> Vec<Arc<VringEpollHandler<S>>> {
        self.handler.lock().unwrap().get_epoll_handlers()
    }
}

pub struct Vring {
    queue: Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
    kick: Option<EventFd>,
    call: Option<EventFd>,
    err: Option<EventFd>,
    enabled: bool,
}

impl Vring {
    fn new(atomic_mem: GuestMemoryAtomic<GuestMemoryMmap>, max_queue_size: u16) -> Self {
        Vring {
            queue: Queue::new(atomic_mem, max_queue_size),
            kick: None,
            call: None,
            err: None,
            enabled: false,
        }
    }

    pub fn mut_queue(&mut self) -> &mut Queue<GuestMemoryAtomic<GuestMemoryMmap>> {
        &mut self.queue
    }

    pub fn signal_used_queue(&mut self) -> result::Result<(), io::Error> {
        if let Some(call) = self.call.as_ref() {
            call.write(1)
        } else {
            Ok(())
        }
    }
}
<|endoftext|>


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
<commit_msg>Better state machine.<commit_after>#![crate_name = "raft"]
#![crate_type="lib"]

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

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

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

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

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

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

/// The implementation of the RaftNode. In most use cases, creating a `RaftNode` should just be
/// done via `::new()`.
///
/// ```
/// use raft::RaftNode;
/// use std::io::net::ip::SocketAddr;
/// use std::io::net::ip::IpAddr::Ipv4Addr;
///
/// let my_node = RaftNode::<String>::new(
///     // This node's address.
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 },
///     // The list of nodes.
///     vec![
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 },
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11113 }
///     ]);
/// ```
impl<T: Encodable + Decodable + Send + Clone> RaftNode<T> {
    /// Creates a new RaftNode with the neighbors specified.
    pub fn new(own_socket: SocketAddr, node_list: Vec<SocketAddr>) -> RaftNode<T> {
        // I'd rather not have to create these, but c'este la vie
        let mut rng = thread_rng();
        let mut timer = Timer::new().unwrap();
        RaftNode {
            state: NodeState::Follower,
            persistent_state: PersistentState {
                current_term: 0, // TODO: Double Check.
                voted_for: 0,    // TODO: Better type?
                log: Vec::<T>::new(),
            },
            volatile_state: VolatileState {
                commit_index: 0,
                last_applied: 0,
            },
            known_nodes: node_list,
            leader_node: None,
            own_socket: own_socket,
            // Blank timer for now.
            heartbeat: timer.oneshot(Duration::milliseconds(rng.gen_range::<i64>(HEARTBEAT_MIN, HEARTBEAT_MAX))), // If this fails we're in trouble.
        }
    }
    /// Spins up a thread that listens and handles RPCs.
    pub fn spinup(mut self) -> (Sender<T>, Receiver<T>) {
        let (client_in, node_out) = channel::<T>();
        let (node_in, client_out) = channel::<T>();
        // Need to clone the SocketAddr for lifetime reasons.
        Thread::spawn(move || {
            // Setup the socket, make it not block.
            let mut socket = UdpSocket::bind(self.own_socket)
                .unwrap(); // TODO: Can we do better?
            socket.set_read_timeout(Some(0));
            // Start up a RNG and Timer
            let mut rng = thread_rng();
            let mut timer = Timer::new().unwrap();
            // We need a read buffer.
            let mut read_buffer = [0; BUFFER_SIZE];
            loop {
                match &self.state {
                    &Leader(ref leader_state) => {
                        // If socket has data.
                        match socket.recv_from(&mut read_buffer) {
                            Ok((num_read, source)) => { // Something on the socket.
                                // TODO
                            },
                            Err(_) => (),               // Nothing on the socket.
                        }
                        // If channel has data.
                        match node_out.try_recv() {
                            Ok(entry) => {              // Something in channel.

                            },
                            Err(_) => (),               // Nothing in channel.
                        }
                        // If timer has fired.
                        match self.heartbeat.try_recv() {
                            Ok(_) => {                  // Timer has fired.

                            },
                            Err(_) => (),               // Timer hasn't fired.
                        }
                    },
                    &Follower => {
                        // If socket has data.
                        match socket.recv_from(&mut read_buffer) {
                            Ok((num_read, source)) => { // Something on the socket.
                                // TODO
                                println!("Got something from socket");
                                let string_slice = str::from_utf8(read_buffer.slice_to_mut(num_read))
                                    .unwrap(); // TODO: Can we do better?
                                let mut rpc = json::decode::<RemoteProcedureCall<T>>(string_slice)
                                    .unwrap(); // TODO: Can we do better?
                                match rpc {
                                    AppendEntries { entries: mut entries, .. } => {
                                        // TODO: Log data properly.
                                        for entry in entries.iter_mut() {
                                            node_in.send(entry.clone());
                                        }
                                    },
                                    RequestVote { .. } => {
                                        // TODO: Do something.
                                    },
                                }
                            },
                            Err(_) => (),               // Nothing on the socket.
                        }
                        // If channel has data.
                        match node_out.try_recv() {
                            Ok(entry) => {              // Something in channel.
                                println!("Sending things!");
                                let rpc = AppendEntries {
                                    term: 0,
                                    leader_id: 0,
                                    prev_log_index: 0,
                                    entries: vec![entry],
                                    leader_commit: 0,
                                };
                                let encoded = json::encode::<RemoteProcedureCall<T>>(&rpc);
                                for node in self.known_nodes.iter() {
                                    socket.send_to(encoded.as_bytes(), *node)
                                        .unwrap(); // TODO: Can we do better?
                                }
                            },
                            Err(_) => (),               // Nothing in channel.
                        }
                        // If timer has fired.
                        match self.heartbeat.try_recv() {
                            Ok(_) => {                  // Timer has fired.

                            },
                            Err(_) => (),               // Timer hasn't fired.
                        }
                    },
                    &Candidate => {
                        // If socket has data.
                        match socket.recv_from(&mut read_buffer) {
                            Ok((num_read, source)) => { // Something on the socket.
                                // TODO
                            },
                            Err(_) => (),               // Nothing on the socket.
                        }
                        // If channel has data.
                        match node_out.try_recv() {
                            Ok(entry) => {              // Something in channel.

                            },
                            Err(_) => (),               // Nothing in channel.
                        }
                        // If timer has fired.
                        match self.heartbeat.try_recv() {
                            Ok(_) => {                  // Timer has fired.

                            },
                            Err(_) => (),               // Timer hasn't fired.
                        }
                    },
                }
            }
        });
        (client_in, client_out)
    }
}

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

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

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

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

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

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

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

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

}
<|endoftext|>


<commit_before>/**
 * This module is part of twig-rs.
 *
 * (c) 2015 Rust Twig Team
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate regex;

mod token;
mod lexer;
mod error;
mod environment;
mod extension;
mod parser;
mod node;

pub use extension::Extension;
pub use lexer::{ Lexer };
pub use environment::{ CompiledEnvironment, Environment };
pub use environment::operators::{ UnaryOperator, BinaryOperator, Associativity };
pub use node::Module;

pub struct Container<T>(Vec<T>);

impl<T: Clone, I: Into<T>, C: IntoIterator<Item=I>> From<C> for Container<T> {
    fn from(source: C) -> Container<T> {
        Container(
            source.into_iter()
                .map(|i| i.into().clone())
                .collect()
        )
    }
}
<commit_msg>Fork me on github.<commit_after>/*!

*/

/**
 * This module is part of twig-rs.
 *
 * (c) 2015 Rust Twig Team
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate regex;

mod token;
mod lexer;
mod error;
mod environment;
mod extension;
mod parser;
mod node;

pub use extension::Extension;
pub use lexer::{ Lexer };
pub use environment::{ CompiledEnvironment, Environment };
pub use environment::operators::{ UnaryOperator, BinaryOperator, Associativity };
pub use node::Module;

pub struct Container<T>(Vec<T>);

impl<T: Clone, I: Into<T>, C: IntoIterator<Item=I>> From<C> for Container<T> {
    fn from(source: C) -> Container<T> {
        Container(
            source.into_iter()
                .map(|i| i.into().clone())
                .collect()
        )
    }
}
<|endoftext|>


<commit_before>//! A crate that re-exports various types defined in both `libc` and `winapi`.
//!
//! Stop having to write code like this:
//!
//! ```ignore
//! #[cfg(unix)]
//! use libc::some_type;
//!
//! #[cfg(windows)]
//! use winapi::some_type;
//! ```
//!
//! Instead, write code like this:
//!
//! ```ignore
//! use c_types::some_type;
//! ```
#![allow(non_camel_case_types)]

#[cfg(unix)]
mod unix {
  extern crate libc;

  pub type fd_set = libc::fd_set;
  pub type hostent = libc::hostent;
  pub type in_addr = libc::in_addr;
  pub type in6_addr = libc::in6_addr;
  pub type iovec = libc::iovec;
  pub type sa_family_t = libc::sa_family_t;
  pub type sockaddr = libc::sockaddr;
  pub type sockaddr_in = libc::sockaddr_in;
  pub type sockaddr_in6 = libc::sockaddr_in6;
  pub type socklen_t = libc::socklen_t;

  pub const AF_INET: i32 = libc::AF_INET;
  pub const AF_INET6: i32 = libc::AF_INET6;
}

#[cfg(windows)]
mod windows {
  extern crate libc;
  extern crate winapi;

  pub type fd_set = winapi::fd_set;
  pub type hostent = winapi::winsock2::hostent;
  pub type in_addr = winapi::in_addr;
  pub type in6_addr = winapi::in6_addr;
  #[repr(C)]
  pub struct iovec {
      pub iov_base: *mut libc::c_void,
      pub iov_len: libc::size_t,
  }
  pub type sa_family_t = winapi::ws2def::ADDRESS_FAMILY;
  pub type sockaddr = winapi::SOCKADDR;
  pub type sockaddr_in = winapi::ws2def::SOCKADDR_IN;
  pub type sockaddr_in6 = winapi::ws2ipdef::sockaddr_in6;
  pub type socklen_t = winapi::socklen_t;

  pub const AF_INET: i32 = winapi::ws2def::AF_INET;
  pub const AF_INET6: i32 = winapi::ws2def::AF_INET6;
}

#[cfg(unix)]
pub use self::unix::*;

#[cfg(windows)]
pub use self::windows::*;
<commit_msg>add AF_UNSPEC<commit_after>//! A crate that re-exports various types defined in both `libc` and `winapi`.
//!
//! Stop having to write code like this:
//!
//! ```ignore
//! #[cfg(unix)]
//! use libc::some_type;
//!
//! #[cfg(windows)]
//! use winapi::some_type;
//! ```
//!
//! Instead, write code like this:
//!
//! ```ignore
//! use c_types::some_type;
//! ```
#![allow(non_camel_case_types)]

#[cfg(unix)]
mod unix {
  extern crate libc;

  pub type fd_set = libc::fd_set;
  pub type hostent = libc::hostent;
  pub type in_addr = libc::in_addr;
  pub type in6_addr = libc::in6_addr;
  pub type iovec = libc::iovec;
  pub type sa_family_t = libc::sa_family_t;
  pub type sockaddr = libc::sockaddr;
  pub type sockaddr_in = libc::sockaddr_in;
  pub type sockaddr_in6 = libc::sockaddr_in6;
  pub type socklen_t = libc::socklen_t;

  pub const AF_UNSPEC: i32 = libc::AF_UNSPEC;
  pub const AF_INET: i32 = libc::AF_INET;
  pub const AF_INET6: i32 = libc::AF_INET6;
}

#[cfg(windows)]
mod windows {
  extern crate libc;
  extern crate winapi;

  pub type fd_set = winapi::fd_set;
  pub type hostent = winapi::winsock2::hostent;
  pub type in_addr = winapi::in_addr;
  pub type in6_addr = winapi::in6_addr;
  #[repr(C)]
  pub struct iovec {
      pub iov_base: *mut libc::c_void,
      pub iov_len: libc::size_t,
  }
  pub type sa_family_t = winapi::ws2def::ADDRESS_FAMILY;
  pub type sockaddr = winapi::SOCKADDR;
  pub type sockaddr_in = winapi::ws2def::SOCKADDR_IN;
  pub type sockaddr_in6 = winapi::ws2ipdef::sockaddr_in6;
  pub type socklen_t = winapi::socklen_t;

  pub const AF_UNSPEC: i32 = winapi::ws2def::AF_UNSPEC;
  pub const AF_INET: i32 = winapi::ws2def::AF_INET;
  pub const AF_INET6: i32 = winapi::ws2def::AF_INET6;
}

#[cfg(unix)]
pub use self::unix::*;

#[cfg(windows)]
pub use self::windows::*;
<|endoftext|>


<commit_before>#![no_std]

//! The `array-vec` crate allows you to initialize arrays
//! with an initializer closure that will be called
//! once for each element until the array is filled.
//!
//! This way you do not need to default-fill an array
//! before running initializers. Rust currently only
//! lets you either specify all initializers at once,
//! individually (`[a(), b(), c(), ...]`), or specify
//! one initializer for a `Copy` type (`[a(); N]`),
//! which will be called once with the result copied over.
//!
//! # Examples:
//! ```rust
//! # #![allow(unused)]
//! # extern crate array_init;
//!
//! // Initialize an array of length 10 containing
//! // successive squares
//!
//! let arr: [u32; 50] = array_init::array_init(|i| (i*i) as u32);
//!
//! // Initialize an array from an iterator
//! // producing an array of [1,2,3,4] repeated
//!
//! let four = [1u32,2,3,4];
//! let mut iter = four.iter().cloned().cycle();
//! let arr: [u32; 50] = array_init::from_iter(iter).unwrap();
//!
//! // Closures can also mutate state. We guarantee that they will be called
//! // in order from lower to higher indices.
//!
//! let mut last = 1u64;
//! let mut secondlast = 0;
//! let fibonacci: [u64; 50] = array_init::array_init(|_| {
//!     let this = last + secondlast;
//!     secondlast = last;
//!     last = this;
//!     this
//! });
//! ```
//!
//! Currently, using `from_iter` and `array_init` will incur additional
//! memcpys, which may be undesirable for a large array. This can be eliminated
//! by using the nightly feature of this crate, which uses unions to provide
//! panic-safety. Alternatively, if your array only contains `Copy` types,
//! you can use `array_init_copy` and `from_iter_copy`.
//!
//! Sadly, cannot guarantee right now that any of these solutions will completely
//! eliminate a memcpy.
//!

extern crate nodrop;

use nodrop::NoDrop;
use core::mem;

/// Trait for things which are actually arrays
///
/// Probably shouldn't implement this yourself,
/// but you can
pub unsafe trait IsArray {
    type Item;
    /// Must assume self is uninitialized.
    fn set(&mut self, idx: usize, value: Self::Item);
    fn len() -> usize;
}

#[inline]
/// Initialize an array given an initializer expression
///
/// The initializer is given the index of the element. It is allowed
/// to mutate external state; we will always initialize the elements in order.
///
/// Without the nightly feature it is very likely that this will cause memcpys.
/// For panic safety, we internally use NoDrop, which will ensure that panics
/// in the initializer will not cause the array to be prematurely dropped.
/// If you are using a Copy type, prefer using `array_init_copy` since
/// it does not need the panic safety stuff and is more likely to have no
/// memcpys.
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array of length 10 containing
/// // successive squares
///
/// let arr: [u32; 50] = array_init::array_init(|i| (i*i) as u32);
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter(iter).unwrap();
///
/// ```
///
pub fn array_init<Array, F>(mut initializer: F) -> Array where Array: IsArray,
                                                               F: FnMut(usize) -> Array::Item {
    // NoDrop makes this panic-safe
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: NoDrop<Array> = NoDrop::new(unsafe { mem::uninitialized() });
    for i in 0..Array::len() {
        Array::set(&mut ret, i, initializer(i));
    }
    ret.into_inner()
}

#[inline]
/// Initialize an array given an iterator
///
/// We will iterate until the array is full or the iterator is exhausted. Returns
/// None if the iterator is exhausted before we can fill the array.
///
/// Without the nightly feature it is very likely that this will cause memcpys.
/// For panic safety, we internally use NoDrop, which will ensure that panics
/// in the initializer will not cause the array to be prematurely dropped.
/// If you are using a Copy type, prefer using `from_iter_copy` since
/// it does not need the panic safety stuff and is more likely to have no
/// memcpys.
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter_copy(iter).unwrap();
/// ```
///
pub fn from_iter<Array, I>(iter: I) -> Option<Array>
    where I: IntoIterator<Item = Array::Item>,
          Array: IsArray {
    // NoDrop makes this panic-safe
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: NoDrop<Array> = NoDrop::new(unsafe { mem::uninitialized() });
    let mut count = 0;
    for item in iter.into_iter().take(Array::len()) {
        Array::set(&mut ret, count, item);
        count += 1;
    }
    // crucial for safety!
    if count == Array::len() {
        Some(ret.into_inner())
    } else {
        None
    }
}

#[inline]
/// Initialize an array of `Copy` elements given an initializer expression
///
/// The initializer is given the index of the element. It is allowed
/// to mutate external state; we will always initialize the elements in order.
///
/// This is preferred over `array_init` if you have a `Copy` type
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array of length 10 containing
/// // successive squares
///
/// let arr: [u32; 50] = array_init::array_init_copy(|i| (i*i) as u32);
///
///
/// // Closures can also mutate state. We guarantee that they will be called
/// // in order from lower to higher indices.
///
/// let mut last = 1u64;
/// let mut secondlast = 0;
/// let fibonacci: [u64; 50] = array_init::array_init_copy(|_| {
///     let this = last + secondlast;
///     secondlast = last;
///     last = this;
///     this
/// });
/// ```
///
pub fn array_init_copy<Array, F>(mut initializer: F) -> Array where Array: IsArray,
                                                                    F: FnMut(usize) -> Array::Item,
                                                                    Array::Item : Copy {
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: Array = unsafe { mem::uninitialized() };
    for i in 0..Array::len() {
        Array::set(&mut ret, i, initializer(i));
    }
    ret
}

#[inline]
/// Initialize an array given an iterator
///
/// We will iterate until the array is full or the iterator is exhausted. Returns
/// None if the iterator is exhausted before we can fill the array.
///
/// This is preferred over `from_iter_copy` if you have a `Copy` type
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter_copy(iter).unwrap();
/// ```
pub fn from_iter_copy<Array, I>(iter: I) -> Option<Array>
    where I: IntoIterator<Item = Array::Item>,
          Array: IsArray,
          Array::Item : Copy {
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: Array = unsafe { mem::uninitialized() };
    let mut count = 0;
    for item in iter.into_iter().take(Array::len()) {
        Array::set(&mut ret, count, item);
        count += 1;
    }
    // crucial for safety!
    if count == Array::len() {
        Some(ret)
    } else {
        None
    }
}

macro_rules! impl_is_array {
    ($size:expr) => (
        unsafe impl<T> IsArray for [T; $size] {
            type Item = T;
            #[inline]
            fn set(&mut self, idx: usize, value: Self::Item) {
                mem::forget(mem::replace(&mut self[idx], value));
            }

            #[inline]
            fn len() -> usize {
                $size
            }
        }
    )
}

// lol

impl_is_array!(0);
impl_is_array!(1);
impl_is_array!(2);
impl_is_array!(3);
impl_is_array!(4);
impl_is_array!(5);
impl_is_array!(6);
impl_is_array!(7);
impl_is_array!(8);
impl_is_array!(9);
impl_is_array!(10);
impl_is_array!(11);
impl_is_array!(12);
impl_is_array!(13);
impl_is_array!(14);
impl_is_array!(15);
impl_is_array!(16);
impl_is_array!(17);
impl_is_array!(18);
impl_is_array!(19);
impl_is_array!(20);
impl_is_array!(21);
impl_is_array!(22);
impl_is_array!(23);
impl_is_array!(24);
impl_is_array!(25);
impl_is_array!(26);
impl_is_array!(27);
impl_is_array!(28);
impl_is_array!(29);
impl_is_array!(30);
impl_is_array!(31);
impl_is_array!(32);
impl_is_array!(33);
impl_is_array!(34);
impl_is_array!(35);
impl_is_array!(36);
impl_is_array!(37);
impl_is_array!(38);
impl_is_array!(39);
impl_is_array!(40);
impl_is_array!(41);
impl_is_array!(42);
impl_is_array!(43);
impl_is_array!(44);
impl_is_array!(45);
impl_is_array!(46);
impl_is_array!(47);
impl_is_array!(48);
impl_is_array!(49);
impl_is_array!(50);
impl_is_array!(51);
impl_is_array!(52);
impl_is_array!(53);
impl_is_array!(54);
impl_is_array!(55);
impl_is_array!(56);
impl_is_array!(57);
impl_is_array!(58);
impl_is_array!(59);
impl_is_array!(60);
impl_is_array!(61);
impl_is_array!(62);
impl_is_array!(63);
impl_is_array!(64);
<commit_msg>Simplify use of impl_is_array macro<commit_after>#![no_std]

//! The `array-vec` crate allows you to initialize arrays
//! with an initializer closure that will be called
//! once for each element until the array is filled.
//!
//! This way you do not need to default-fill an array
//! before running initializers. Rust currently only
//! lets you either specify all initializers at once,
//! individually (`[a(), b(), c(), ...]`), or specify
//! one initializer for a `Copy` type (`[a(); N]`),
//! which will be called once with the result copied over.
//!
//! # Examples:
//! ```rust
//! # #![allow(unused)]
//! # extern crate array_init;
//!
//! // Initialize an array of length 10 containing
//! // successive squares
//!
//! let arr: [u32; 50] = array_init::array_init(|i| (i*i) as u32);
//!
//! // Initialize an array from an iterator
//! // producing an array of [1,2,3,4] repeated
//!
//! let four = [1u32,2,3,4];
//! let mut iter = four.iter().cloned().cycle();
//! let arr: [u32; 50] = array_init::from_iter(iter).unwrap();
//!
//! // Closures can also mutate state. We guarantee that they will be called
//! // in order from lower to higher indices.
//!
//! let mut last = 1u64;
//! let mut secondlast = 0;
//! let fibonacci: [u64; 50] = array_init::array_init(|_| {
//!     let this = last + secondlast;
//!     secondlast = last;
//!     last = this;
//!     this
//! });
//! ```
//!
//! Currently, using `from_iter` and `array_init` will incur additional
//! memcpys, which may be undesirable for a large array. This can be eliminated
//! by using the nightly feature of this crate, which uses unions to provide
//! panic-safety. Alternatively, if your array only contains `Copy` types,
//! you can use `array_init_copy` and `from_iter_copy`.
//!
//! Sadly, cannot guarantee right now that any of these solutions will completely
//! eliminate a memcpy.
//!

extern crate nodrop;

use nodrop::NoDrop;
use core::mem;

/// Trait for things which are actually arrays
///
/// Probably shouldn't implement this yourself,
/// but you can
pub unsafe trait IsArray {
    type Item;
    /// Must assume self is uninitialized.
    fn set(&mut self, idx: usize, value: Self::Item);
    fn len() -> usize;
}

#[inline]
/// Initialize an array given an initializer expression
///
/// The initializer is given the index of the element. It is allowed
/// to mutate external state; we will always initialize the elements in order.
///
/// Without the nightly feature it is very likely that this will cause memcpys.
/// For panic safety, we internally use NoDrop, which will ensure that panics
/// in the initializer will not cause the array to be prematurely dropped.
/// If you are using a Copy type, prefer using `array_init_copy` since
/// it does not need the panic safety stuff and is more likely to have no
/// memcpys.
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array of length 10 containing
/// // successive squares
///
/// let arr: [u32; 50] = array_init::array_init(|i| (i*i) as u32);
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter(iter).unwrap();
///
/// ```
///
pub fn array_init<Array, F>(mut initializer: F) -> Array where Array: IsArray,
                                                               F: FnMut(usize) -> Array::Item {
    // NoDrop makes this panic-safe
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: NoDrop<Array> = NoDrop::new(unsafe { mem::uninitialized() });
    for i in 0..Array::len() {
        Array::set(&mut ret, i, initializer(i));
    }
    ret.into_inner()
}

#[inline]
/// Initialize an array given an iterator
///
/// We will iterate until the array is full or the iterator is exhausted. Returns
/// None if the iterator is exhausted before we can fill the array.
///
/// Without the nightly feature it is very likely that this will cause memcpys.
/// For panic safety, we internally use NoDrop, which will ensure that panics
/// in the initializer will not cause the array to be prematurely dropped.
/// If you are using a Copy type, prefer using `from_iter_copy` since
/// it does not need the panic safety stuff and is more likely to have no
/// memcpys.
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter_copy(iter).unwrap();
/// ```
///
pub fn from_iter<Array, I>(iter: I) -> Option<Array>
    where I: IntoIterator<Item = Array::Item>,
          Array: IsArray {
    // NoDrop makes this panic-safe
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: NoDrop<Array> = NoDrop::new(unsafe { mem::uninitialized() });
    let mut count = 0;
    for item in iter.into_iter().take(Array::len()) {
        Array::set(&mut ret, count, item);
        count += 1;
    }
    // crucial for safety!
    if count == Array::len() {
        Some(ret.into_inner())
    } else {
        None
    }
}

#[inline]
/// Initialize an array of `Copy` elements given an initializer expression
///
/// The initializer is given the index of the element. It is allowed
/// to mutate external state; we will always initialize the elements in order.
///
/// This is preferred over `array_init` if you have a `Copy` type
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array of length 10 containing
/// // successive squares
///
/// let arr: [u32; 50] = array_init::array_init_copy(|i| (i*i) as u32);
///
///
/// // Closures can also mutate state. We guarantee that they will be called
/// // in order from lower to higher indices.
///
/// let mut last = 1u64;
/// let mut secondlast = 0;
/// let fibonacci: [u64; 50] = array_init::array_init_copy(|_| {
///     let this = last + secondlast;
///     secondlast = last;
///     last = this;
///     this
/// });
/// ```
///
pub fn array_init_copy<Array, F>(mut initializer: F) -> Array where Array: IsArray,
                                                                    F: FnMut(usize) -> Array::Item,
                                                                    Array::Item : Copy {
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: Array = unsafe { mem::uninitialized() };
    for i in 0..Array::len() {
        Array::set(&mut ret, i, initializer(i));
    }
    ret
}

#[inline]
/// Initialize an array given an iterator
///
/// We will iterate until the array is full or the iterator is exhausted. Returns
/// None if the iterator is exhausted before we can fill the array.
///
/// This is preferred over `from_iter_copy` if you have a `Copy` type
///
/// # Examples
///
/// ```rust
/// # #![allow(unused)]
/// # extern crate array_init;
///
/// // Initialize an array from an iterator
/// // producing an array of [1,2,3,4] repeated
///
/// let four = [1u32,2,3,4];
/// let mut iter = four.iter().cloned().cycle();
/// let arr: [u32; 50] = array_init::from_iter_copy(iter).unwrap();
/// ```
pub fn from_iter_copy<Array, I>(iter: I) -> Option<Array>
    where I: IntoIterator<Item = Array::Item>,
          Array: IsArray,
          Array::Item : Copy {
    // We are sure to initialize the whole array here,
    // and we do not read from the array till then, so this is safe.
    let mut ret: Array = unsafe { mem::uninitialized() };
    let mut count = 0;
    for item in iter.into_iter().take(Array::len()) {
        Array::set(&mut ret, count, item);
        count += 1;
    }
    // crucial for safety!
    if count == Array::len() {
        Some(ret)
    } else {
        None
    }
}

macro_rules! impl_is_array {
    ($($size:expr)+) => ($(
        unsafe impl<T> IsArray for [T; $size] {
            type Item = T;
            #[inline]
            fn set(&mut self, idx: usize, value: Self::Item) {
                mem::forget(mem::replace(&mut self[idx], value));
            }

            #[inline]
            fn len() -> usize {
                $size
            }
        }
    )+)
}

// lol

impl_is_array! {
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
    48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    64
}
<|endoftext|>


<commit_before>extern crate glium;

pub fn print_hello() {
    println!("hello");
}

<commit_msg>setting up wrapper struct<commit_after>extern crate glium;

pub struct BhMhd<'a> {
    facade: &'a glium::backend::Facade,
    layers: Vec<glium::texture::Texture2d>,
    sim_prog: glium::Program,
}

impl<'a> BhMhd<'a> {
    pub fn new<F>(f: &'a F) -> Self where F: glium::backend::Facade {
        BhMhd {
            facade: f,
            layers: BhMhd::init_layers(f),
            sim_prog: glium::Program::from_source(f, "", "", None).unwrap(),
        }
    }

    fn init_layers<F>(f: &'a F) -> Vec<glium::texture::Texture2d>
        where F: glium::backend::Facade {
        let ang_num = 100u32;
        let height_num = 100u32;
        let rad_num = 100u32;

        (0..height_num)
            .into_iter()
            .map(|x| { glium::texture::Texture2d::empty(f, ang_num, rad_num).unwrap() })
            .collect()
    }
}

pub fn print_hello() {
    println!("hello");
}

<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[macro_use]
extern crate error_chain;
extern crate chrono;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod api;
mod errors;
mod krate;

pub use api::CratesIO;
pub use errors::Error;
pub use krate::{Crate, Version};
<commit_msg>Export missing types<commit_after>#![recursion_limit = "1024"]
#[macro_use]
extern crate error_chain;
extern crate chrono;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod api;
mod errors;
mod krate;

pub use api::{CratesIO, ErrorResponse};
pub use errors::{Error, ErrorKind};
pub use krate::{Crate, Version};
<|endoftext|>


<commit_before>use std::io::{IoResult, IoError, IoErrorKind, Reader};
use std::io::fs::File;

struct Frame;

// TODO: there should be a way to signal IO error.
// This will be handled by the error reform RFCs, I think.
// For now, use IO error to indicate any failure.
type Error = IoError;

fn mk_err() -> Error {
    IoError {
        kind: IoErrorKind::OtherIoError,
        desc: "FLAC decoding error",
        detail: None
    }
}

struct FlacStream {
    metadata_blocks: Vec<MetadataBlock>
}

#[cfg(test)]
fn get_foo_file() -> File {
    File::open(&Path::new("foo.flac")).unwrap()
}

fn read_stream_header(input: &mut Reader) -> Result<(), Error> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const HEADER: u32 = 0x66_4c_61_43;
    let header = try!(input.read_be_u32());
    if header != HEADER { return Err(mk_err()); } // TODO: provide more error info.
    Ok(())
}

#[test]
fn test_read_stream_header() {
    let mut input = get_foo_file();
    read_stream_header(&mut input).unwrap();
}

struct StreamInfo {
    pub min_block_size: u16,
    pub max_block_size: u16,
    pub min_frame_size: Option<u32>,
    pub max_frame_size: Option<u32>,
    pub sample_rate: u32,
    pub n_channels: u8,
    pub bits_per_sample: u8,
    pub n_samples: Option<u64>,
    pub md5_signature: [u8, ..16]
}

struct Seekpoint {
    pub sample: u64,
    pub offset: u64,
    pub n_samples: u16
}

struct SeekTable {
    seekpoints: Vec<Seekpoint>
}

enum MetadataBlock {
    StreamInfoBlock(StreamInfo),
    PaddingBlock(u32),
    ApplicationBlock(u32, Vec<u8>),
    SeekTableBlock(SeekTable),
    VorbisCommentBlock, // TODO
    CuesheetBlock, // TODO
    PictureBlock // TODO
}

struct MetadataBlockHeader {
    is_last: bool,
    block_type: u8,
    length: u32
}

fn read_metadata_block_header(input: &mut Reader) -> Result<MetadataBlockHeader, Error> {
    let byte = try!(input.read_u8());

    // The first bit specifies whether this is the last block, the next 7 bits
    // specify the type of the metadata block to follow.
    let is_last = (byte & 1) == 1;
    let block_type = byte >> 1;

    if block_type == 127 { return Err(mk_err()); } // TODO: "invalid, to avoid confusion with a frame sync code"
    if block_type > 6 { return Err(mk_err()); } // TODO: "reserved"

    // The length field is 24 bits, or 3 bytes.
    let length = try!(input.read_be_uint_n(3)) as u32;

    let header = MetadataBlockHeader {
        is_last: is_last,
        block_type: block_type,
        length: length
    };
    Ok(header)
}

fn read_streaminfo_block(input: &mut Reader) -> Result<StreamInfo, Error> {
    let min_block_size = try!(input.read_be_u16());
    let max_block_size = try!(input.read_be_u16());
    // The frame size fields are 24 bits, or 3 bytes.
    let min_frame_size = try!(input.read_be_uint_n(3)) as u32;
    let max_frame_size = try!(input.read_be_uint_n(3)) as u32;

    // Sample data is packed as 20 bits sample rate, 3 bits #channels - 1,
    // 5 bits #bits per sample - 1, 36 bits #samples in stream.
    let sample_rate_msb = try!(input.read_be_u16());
    let sample_rate_lsb = try!(input.read_byte());
    // Stitch together the value from the first 16 bits,
    // and then 4 bits of the next byte.
    let sample_rate = sample_rate_msb as u32 << 4 | sample_rate_lsb as u32 >> 4;
    // Next three bits are the number of channels - 1; mask out and add 1.
    let n_channels = ((sample_rate_lsb >> 1) & 0x7) + 1;
    // The final bit is the most significant of bits per sample - 1
    let bps_msb = sample_rate_lsb & 1;
    let bps_lsb = try!(input.read_byte());
    // Stitch together these values, add 1 because # - 1 is stored.
    let bits_per_sample = (bps_msb << 5 | (bps_lsb >> 4)) + 1;
    // Number of samples in 36 bits, we have 4, 32 to go.
    let n_samples_lsb = try!(input.read_be_u32());
    let n_samples = (bps_lsb & 0xf) as u64 << 32 | n_samples_lsb as u64;

    let md5_signature = try!(input.read_exact(16));
}

impl FlacStream {
    pub fn new(input: &mut Reader) -> Result<FlacStream, Error> {
        try!(read_stream_header(input));

        let hdr = try!(read_metadata_block_header(input));
        println!("type: {}, length: {}, last: {}",
                 hdr.block_type, hdr.length, hdr.is_last);
        // Read the STREAMINFO block
        // Read any metadata
        // Read frames

        let flac_stream = FlacStream {
            metadata_blocks: Vec::new()
        };

        Ok(flac_stream)
    }
}

#[test]
fn test_open_stream() {
    let mut input = get_foo_file();
    let flac_stream = FlacStream::new(&mut input).unwrap();
}
<commit_msg>implement streaminfo parsing<commit_after>use std::io::{IoResult, IoError, IoErrorKind, Reader};
use std::io::fs::File;

struct Frame;

// TODO: there should be a way to signal IO error.
// This will be handled by the error reform RFCs, I think.
// For now, use IO error to indicate any failure.
type Error = IoError;

fn mk_err() -> Error {
    IoError {
        kind: IoErrorKind::OtherIoError,
        desc: "FLAC decoding error",
        detail: None
    }
}

struct FlacStream {
    metadata_blocks: Vec<MetadataBlock>
}

#[cfg(test)]
fn get_foo_file() -> File {
    File::open(&Path::new("foo.flac")).unwrap()
}

fn read_stream_header(input: &mut Reader) -> Result<(), Error> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const HEADER: u32 = 0x66_4c_61_43;
    let header = try!(input.read_be_u32());
    if header != HEADER { return Err(mk_err()); } // TODO: provide more error info.
    Ok(())
}

#[test]
fn test_read_stream_header() {
    let mut input = get_foo_file();
    read_stream_header(&mut input).unwrap();
}

struct StreamInfo {
    pub min_block_size: u16,
    pub max_block_size: u16,
    pub min_frame_size: Option<u32>,
    pub max_frame_size: Option<u32>,
    pub sample_rate: u32,
    pub n_channels: u8,
    pub bits_per_sample: u8,
    pub n_samples: Option<u64>,
    pub md5sum: [u8, ..16]
}

struct Seekpoint {
    pub sample: u64,
    pub offset: u64,
    pub n_samples: u16
}

struct SeekTable {
    seekpoints: Vec<Seekpoint>
}

enum MetadataBlock {
    StreamInfoBlock(StreamInfo),
    PaddingBlock(u32),
    ApplicationBlock(u32, Vec<u8>),
    SeekTableBlock(SeekTable),
    VorbisCommentBlock, // TODO
    CuesheetBlock, // TODO
    PictureBlock // TODO
}

struct MetadataBlockHeader {
    is_last: bool,
    block_type: u8,
    length: u32
}

fn read_metadata_block_header(input: &mut Reader) -> Result<MetadataBlockHeader, Error> {
    let byte = try!(input.read_u8());

    // The first bit specifies whether this is the last block, the next 7 bits
    // specify the type of the metadata block to follow.
    let is_last = (byte & 1) == 1;
    let block_type = byte >> 1;

    if block_type == 127 { return Err(mk_err()); } // TODO: "invalid, to avoid confusion with a frame sync code"
    if block_type > 6 { return Err(mk_err()); } // TODO: "reserved"

    // The length field is 24 bits, or 3 bytes.
    let length = try!(input.read_be_uint_n(3)) as u32;

    let header = MetadataBlockHeader {
        is_last: is_last,
        block_type: block_type,
        length: length
    };
    Ok(header)
}

fn read_streaminfo_block(input: &mut Reader) -> Result<StreamInfo, Error> {
    let min_block_size = try!(input.read_be_u16());
    let max_block_size = try!(input.read_be_u16());

    // The frame size fields are 24 bits, or 3 bytes.
    let min_frame_size = try!(input.read_be_uint_n(3)) as u32;
    let max_frame_size = try!(input.read_be_uint_n(3)) as u32;

    // Next up are 20 bits that determine the sample rate.
    let sample_rate_msb = try!(input.read_be_u16());
    let sample_rate_lsb = try!(input.read_byte());

    // Stitch together the value from the first 16 bits,
    // and then the 4 most significant bits of the next byte.
    let sample_rate = sample_rate_msb as u32 << 4 | sample_rate_lsb as u32 >> 4;

    // Next three bits are the number of channels - 1. Mask them out and add 1.
    let n_channels_bps = sample_rate_lsb;
    let n_channels = ((n_channels_bps >> 1) & 0x7) + 1;

    // The final bit is the most significant of bits per sample - 1. Bits per
    // sample - 1 is 5 bits in total.
    let bps_msb = n_channels_bps & 1;
    let bps_lsb_n_samples = try!(input.read_byte());

    // Stitch together these values, add 1 because # - 1 is stored.
    let bits_per_sample = (bps_msb << 5 | (bps_lsb_n_samples >> 4)) + 1;

    // Number of samples in 36 bits, we have 4 already, 32 to go.
    let n_samples_msb = bps_lsb_n_samples & 0xf;
    let n_samples_lsb = try!(input.read_be_u32());
    let n_samples = n_samples_msb as u64 << 32 | n_samples_lsb as u64;

    let mut md5sum = [0u8, ..16];
    try!(input.read_at_least(16, &mut md5sum));

    let stream_info = StreamInfo {
        min_block_size: min_block_size,
        max_block_size: max_block_size,
        min_frame_size: if min_frame_size == 0 { None } else { Some(min_frame_size) },
        max_frame_size: if max_frame_size == 0 { None } else { Some(max_frame_size) },
        sample_rate: sample_rate,
        n_channels: n_channels,
        bits_per_sample: bits_per_sample,
        n_samples: if n_samples == 0 { None } else { Some(n_samples) },
        md5sum: md5sum
    };

    Ok(stream_info)
}

impl FlacStream {
    pub fn new(input: &mut Reader) -> Result<FlacStream, Error> {
        try!(read_stream_header(input));

        let hdr = try!(read_metadata_block_header(input));
        println!("type: {}, length: {}, last: {}",
                 hdr.block_type, hdr.length, hdr.is_last);
        // Read the STREAMINFO block
        // Read any metadata
        // Read frames

        let flac_stream = FlacStream {
            metadata_blocks: Vec::new()
        };

        Ok(flac_stream)
    }
}

#[test]
fn test_open_stream() {
    let mut input = get_foo_file();
    let flac_stream = FlacStream::new(&mut input).unwrap();
}
<|endoftext|>


<commit_before>//! *Carboxyl* provides primitives for functional reactive programming in Rust.
//! It draws inspiration from the [Sodium][sodium] libraries and Push-Pull FRP,
//! as described by [Elliott (2009)][elliott_push_pull].
//!
//! [sodium]: https://github.com/SodiumFRP/sodium/
//! [elliott_push_pull]: http://conal.net/papers/push-pull-frp/push-pull-frp.pdf
//!
//!
//! # Overview
//!
//! Functional reactive programming (FRP) is a composable and modular
//! abstraction for creating dynamic and reactive systems. In its most general
//! form it models these systems as a composition of two basic primitives:
//! *streams* are a series of singular events and *signals* are continuously
//! changing values.
//!
//! *Carboxyl* is an imperative, hybrid push- and pull-based implementation of
//! FRP. Streams and the discrete components of signals are data-driven, i.e.
//! whenever an event occurs the resulting changes are propagated to everything
//! that depends on it.
//!
//! However, the continuous components of signals are demand-driven. Internally,
//! *Carboxyl* stores the state of a signal as a function. This function has to
//! be evaluated by consumers of a signal to obtain a concrete value.
//!
//! Nonetheless, *Carboxyl* has no explicit notion of time. Its signals are
//! functions that can be evaluated at any time, but they do not carry any
//! inherent notion of time. Synchronization and atomicity is achieved by a
//! transaction system.
//!
//!
//! # Functional reactive primitives
//!
//! This library provides two basic types: `Stream` and `Signal`. A stream is a
//! discrete sequence of events, a signal is a container for values that change
//! (discretely) over time.
//!
//! The FRP primitives are mostly implemented as methods of the basic types to
//! ease method chaining, except for the various lifting functions, as they do
//! not really belong to any type in particular.
//!
//! In addition, the `Sink` type allows one to create a stream of events by
//! sending values into it. It is the only way to create a stream from scratch,
//! i.e. without using any of the other primitives.
//!
//!
//! # Usage example
//!
//! Here is a simple example of how you can use the primitives provided by
//! *Carboxyl*. First of all, events can be sent into a *sink*. From a sink one
//! can create a *stream* of events. Streams can also be filtered, mapped and
//! merged. One can e.g. hold the last event from a stream as a signal.
//!
//! ```
//! use carboxyl::Sink;
//!
//! let sink = Sink::new();
//! let stream = sink.stream();
//! let signal = stream.hold(3);
//!
//! // The current value of the signal is initially 3
//! assert_eq!(signal.sample(), 3);
//!
//! // When we fire an event, the signal get updated accordingly
//! sink.send(5);
//! assert_eq!(signal.sample(), 5);
//! ```
//!
//! One can also directly iterate over the stream instead of holding it in a
//! signal:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink = Sink::new();
//! # let stream = sink.stream();
//! let mut events = stream.events();
//! sink.send(4);
//! assert_eq!(events.next(), Some(4));
//! ```
//!
//! Streams and signals can be combined using various primitives. We can map a
//! stream to another stream using a function:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink: Sink<i32> = Sink::new();
//! # let stream = sink.stream();
//! let squares = stream.map(|x| x * x).hold(0);
//! sink.send(4);
//! assert_eq!(squares.sample(), 16);
//! ```
//!
//! Or we can filter a stream to create a new one that only contains events that
//! satisfy a certain predicate:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink: Sink<i32> = Sink::new();
//! # let stream = sink.stream();
//! let negatives = stream.filter(|&x| x < 0).hold(0);
//!
//! // This won't arrive at the signal.
//! sink.send(4);
//! assert_eq!(negatives.sample(), 0);
//!
//! // But this will!
//! sink.send(-3);
//! assert_eq!(negatives.sample(), -3);
//! ```
//!
//! There are some other methods on streams and signals, that you can find in
//! their respective APIs.
//!
//! Note that all these objects are `Send + Sync + Clone`. This means you can
//! easily pass them around in your code, make clones, give them to another
//! thread, and they will still be updated correctly.
//!
//! You may have noticed that certain primitives take a function as an argument.
//! There is a limitation on what kind of functions can and should be used here.
//! In general, as FRP provides an abstraction around mutable state, they should
//! be pure functions (i.e. free of side effects).
//!
//! For the most part this is guaranteed by Rust's type system. A static
//! function with a matching signature always works. A closure though is very
//! restricted: it must not borrow its environment, as it is impossible to
//! satisfy the lifetime requirements for that. So you can only move stuff into
//! it from the environment. However, the moved contents of the closure may also
//! not be altered, which is guaranteed by the `Fn(…) -> …)` trait bound.
//!
//! However, both closures and functions could still have side effects such as
//! I/O, changing mutable state via `Mutex` or `RefCell`, etc. While Rust's type
//! system cannot prevent this, you should generally not pass such functions to
//! the FRP primitives, as they break the benefits you get from using FRP.
//! (An exception here is debugging output.)

#![cfg_attr(test, feature(test))]
#![warn(missing_docs)]

#[cfg(test)]
extern crate test;
#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate quickcheck;
#[macro_use(lazy_static)]
extern crate lazy_static;

pub use stream::{ Sink, Stream };
pub use signal::{ Signal, SignalMut };

mod transaction;
mod source;
mod pending;
mod readonly;
mod stream;
mod signal;
mod fnbox;
#[macro_use]
pub mod lift;
#[cfg(test)]
mod testing;
<commit_msg>Remove unused test feature from main tree<commit_after>//! *Carboxyl* provides primitives for functional reactive programming in Rust.
//! It draws inspiration from the [Sodium][sodium] libraries and Push-Pull FRP,
//! as described by [Elliott (2009)][elliott_push_pull].
//!
//! [sodium]: https://github.com/SodiumFRP/sodium/
//! [elliott_push_pull]: http://conal.net/papers/push-pull-frp/push-pull-frp.pdf
//!
//!
//! # Overview
//!
//! Functional reactive programming (FRP) is a composable and modular
//! abstraction for creating dynamic and reactive systems. In its most general
//! form it models these systems as a composition of two basic primitives:
//! *streams* are a series of singular events and *signals* are continuously
//! changing values.
//!
//! *Carboxyl* is an imperative, hybrid push- and pull-based implementation of
//! FRP. Streams and the discrete components of signals are data-driven, i.e.
//! whenever an event occurs the resulting changes are propagated to everything
//! that depends on it.
//!
//! However, the continuous components of signals are demand-driven. Internally,
//! *Carboxyl* stores the state of a signal as a function. This function has to
//! be evaluated by consumers of a signal to obtain a concrete value.
//!
//! Nonetheless, *Carboxyl* has no explicit notion of time. Its signals are
//! functions that can be evaluated at any time, but they do not carry any
//! inherent notion of time. Synchronization and atomicity is achieved by a
//! transaction system.
//!
//!
//! # Functional reactive primitives
//!
//! This library provides two basic types: `Stream` and `Signal`. A stream is a
//! discrete sequence of events, a signal is a container for values that change
//! (discretely) over time.
//!
//! The FRP primitives are mostly implemented as methods of the basic types to
//! ease method chaining, except for the various lifting functions, as they do
//! not really belong to any type in particular.
//!
//! In addition, the `Sink` type allows one to create a stream of events by
//! sending values into it. It is the only way to create a stream from scratch,
//! i.e. without using any of the other primitives.
//!
//!
//! # Usage example
//!
//! Here is a simple example of how you can use the primitives provided by
//! *Carboxyl*. First of all, events can be sent into a *sink*. From a sink one
//! can create a *stream* of events. Streams can also be filtered, mapped and
//! merged. One can e.g. hold the last event from a stream as a signal.
//!
//! ```
//! use carboxyl::Sink;
//!
//! let sink = Sink::new();
//! let stream = sink.stream();
//! let signal = stream.hold(3);
//!
//! // The current value of the signal is initially 3
//! assert_eq!(signal.sample(), 3);
//!
//! // When we fire an event, the signal get updated accordingly
//! sink.send(5);
//! assert_eq!(signal.sample(), 5);
//! ```
//!
//! One can also directly iterate over the stream instead of holding it in a
//! signal:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink = Sink::new();
//! # let stream = sink.stream();
//! let mut events = stream.events();
//! sink.send(4);
//! assert_eq!(events.next(), Some(4));
//! ```
//!
//! Streams and signals can be combined using various primitives. We can map a
//! stream to another stream using a function:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink: Sink<i32> = Sink::new();
//! # let stream = sink.stream();
//! let squares = stream.map(|x| x * x).hold(0);
//! sink.send(4);
//! assert_eq!(squares.sample(), 16);
//! ```
//!
//! Or we can filter a stream to create a new one that only contains events that
//! satisfy a certain predicate:
//!
//! ```
//! # use carboxyl::Sink;
//! # let sink: Sink<i32> = Sink::new();
//! # let stream = sink.stream();
//! let negatives = stream.filter(|&x| x < 0).hold(0);
//!
//! // This won't arrive at the signal.
//! sink.send(4);
//! assert_eq!(negatives.sample(), 0);
//!
//! // But this will!
//! sink.send(-3);
//! assert_eq!(negatives.sample(), -3);
//! ```
//!
//! There are some other methods on streams and signals, that you can find in
//! their respective APIs.
//!
//! Note that all these objects are `Send + Sync + Clone`. This means you can
//! easily pass them around in your code, make clones, give them to another
//! thread, and they will still be updated correctly.
//!
//! You may have noticed that certain primitives take a function as an argument.
//! There is a limitation on what kind of functions can and should be used here.
//! In general, as FRP provides an abstraction around mutable state, they should
//! be pure functions (i.e. free of side effects).
//!
//! For the most part this is guaranteed by Rust's type system. A static
//! function with a matching signature always works. A closure though is very
//! restricted: it must not borrow its environment, as it is impossible to
//! satisfy the lifetime requirements for that. So you can only move stuff into
//! it from the environment. However, the moved contents of the closure may also
//! not be altered, which is guaranteed by the `Fn(…) -> …)` trait bound.
//!
//! However, both closures and functions could still have side effects such as
//! I/O, changing mutable state via `Mutex` or `RefCell`, etc. While Rust's type
//! system cannot prevent this, you should generally not pass such functions to
//! the FRP primitives, as they break the benefits you get from using FRP.
//! (An exception here is debugging output.)

#![warn(missing_docs)]

#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate quickcheck;
#[macro_use(lazy_static)]
extern crate lazy_static;

pub use stream::{ Sink, Stream };
pub use signal::{ Signal, SignalMut };

mod transaction;
mod source;
mod pending;
mod readonly;
mod stream;
mod signal;
mod fnbox;
#[macro_use]
pub mod lift;
#[cfg(test)]
mod testing;
<|endoftext|>