<commit_before>extern crate libc;
extern crate heartbeats_sys;

pub mod poet;

/*
use heartbeats::energy_reader::EnergyReader;
use heartbeats::heartbeat::Heartbeat;
use poet::POET;
use poet::POETStates;

fn main() {
    let mut er = EnergyReader::new().ok().expect("Failed to get energy reader");
    let mut hb = Heartbeat::new(None, 20, 20, "heartbeat.log", &mut er).ok().expect("Failed to get heartbeat");
    let mut poet_states = POETStates::new().ok().expect("Failed to load POET states");
    let mut poet = POET::new(&mut hb, 100.0, &mut poet_states, None, None, 20u32, "poet.log").ok().expect("Failed to initialize POET");
    for i in 0..100 {
        hb.heartbeat(i, 1, 0.0, None);
        poet.apply_control();
        std::thread::sleep_ms(100);
    }
    println!("Hello, world!");
    // using Drop trait automatically cleans up
}
*/
<commit_msg>Remove commented out code<commit_after>extern crate libc;
extern crate heartbeats_sys;

pub mod poet;
<|endoftext|>


<commit_before>#![feature(zero_one)]
#![feature(const_fn)]
#![no_std]

#[cfg(test)]
mod tests;

use core::mem::size_of;

#[derive(Debug, Clone, Copy)]
pub struct BitField<T: Number>(T);

impl<T> BitField<T>
    where T: Number
{
    pub const fn new(value: T) -> BitField<T> {
        BitField(value)
    }

    pub fn get_bit(&self, bit: u8) -> bool {
        assert!(bit < self.length());
        self.get_range(bit..(bit + 1)) == T::one()
    }

    pub fn get_range(&self, range: Range<u8>) -> T {
        assert!(range.start < self.length());
        assert!(range.end <= self.length());
        assert!(range.start < range.end);

        // shift away high bits
        let bits = self.0 << (self.length() - range.end) >> (self.length() - range.end);

        // shift away low bits
        bits >> range.start
    }

    pub fn set_bit(&mut self, bit: u8, value: bool) -> &mut Self {
        assert!(bit < self.length());
        if value {
            self.0 |= T::one() << bit;
        } else {
            self.0 &= !(T::one() << bit);
        }
        self
    }

    pub fn set_range(&mut self, range: Range<u8>, value: T) -> &mut Self {
        assert!(range.start < self.length());
        assert!(range.end <= self.length());
        assert!(range.start < range.end);
        assert!(value << (self.length() - (range.end - range.start)) >>
                (self.length() - (range.end - range.start)) == value,
                "value too big");

        let bitmask: T = !(!T::zero() << (self.length() - range.end) >>
                           (self.length() - range.end) >>
                           range.start << range.start);

        let bits = self.0 & bitmask;
        // set bits
        self.0 = bits | (value << range.start);

        self
    }

    fn length(&self) -> u8 {
        size_of::<T>() as u8 * 8
    }
}

use core::ops::{Range, Shl, Shr, BitAnd, BitOr, BitOrAssign, BitAndAssign, Not};
use core::num::{Zero, One};
use core::fmt::Debug;

pub trait Number: Debug + Copy + Eq + Zero + One +
    Not<Output=Self> + Shl<u8, Output=Self> + Shr<u8, Output=Self> +
    BitAnd<Self, Output=Self> + BitOr<Self, Output=Self>  + BitAndAssign + BitOrAssign {}

impl Number for u8 {}
impl Number for u16 {}
impl Number for u32 {}
impl Number for u64 {}
impl Number for usize {}
<commit_msg>Add method to retrieve bits<commit_after>#![feature(zero_one)]
#![feature(const_fn)]
#![no_std]

#[cfg(test)]
mod tests;

use core::mem::size_of;

#[derive(Debug, Clone, Copy)]
pub struct BitField<T: Number>(T);

impl<T> BitField<T>
    where T: Number
{
    pub const fn new(value: T) -> BitField<T> {
        BitField(value)
    }

    pub fn bits(&self) -> T {
        self.0
    }

    pub fn get_bit(&self, bit: u8) -> bool {
        assert!(bit < self.length());
        self.get_range(bit..(bit + 1)) == T::one()
    }

    pub fn get_range(&self, range: Range<u8>) -> T {
        assert!(range.start < self.length());
        assert!(range.end <= self.length());
        assert!(range.start < range.end);

        // shift away high bits
        let bits = self.0 << (self.length() - range.end) >> (self.length() - range.end);

        // shift away low bits
        bits >> range.start
    }

    pub fn set_bit(&mut self, bit: u8, value: bool) -> &mut Self {
        assert!(bit < self.length());
        if value {
            self.0 |= T::one() << bit;
        } else {
            self.0 &= !(T::one() << bit);
        }
        self
    }

    pub fn set_range(&mut self, range: Range<u8>, value: T) -> &mut Self {
        assert!(range.start < self.length());
        assert!(range.end <= self.length());
        assert!(range.start < range.end);
        assert!(value << (self.length() - (range.end - range.start)) >>
                (self.length() - (range.end - range.start)) == value,
                "value too big");

        let bitmask: T = !(!T::zero() << (self.length() - range.end) >>
                           (self.length() - range.end) >>
                           range.start << range.start);

        let bits = self.0 & bitmask;
        // set bits
        self.0 = bits | (value << range.start);

        self
    }

    fn length(&self) -> u8 {
        size_of::<T>() as u8 * 8
    }
}

use core::ops::{Range, Shl, Shr, BitAnd, BitOr, BitOrAssign, BitAndAssign, Not};
use core::num::{Zero, One};
use core::fmt::Debug;

pub trait Number: Debug + Copy + Eq + Zero + One +
    Not<Output=Self> + Shl<u8, Output=Self> + Shr<u8, Output=Self> +
    BitAnd<Self, Output=Self> + BitOr<Self, Output=Self>  + BitAndAssign + BitOrAssign {}

impl Number for u8 {}
impl Number for u16 {}
impl Number for u32 {}
impl Number for u64 {}
impl Number for usize {}
<|endoftext|>


<commit_before>//!
//! # Desync
//!
//!
//! This is a library for Rust that provides a model of concurrency based around the idea of
//! scheduling operations on data. This is in contrast to the traditional model where operations
//! are scheduled on threads with ownership of the data being passed between them.
//!
//! This approach has several advantages over the traditional method:
//!
//!  * It's simpler: almost the  entire set of thread methods and synchronisation primitives can
//!    be replaced with the two fundamental scheduling functions, `sync()` and `desync()`.
//!  * It's easier to reason about: scheduled operations are always performed in the order they're
//!    queued so race conditions and similar issues due to out-of-order execution are both much rarer
//!    and easier to debug.
//!  * It makes it easier to write highly concurrent code: desync makes moving between performing
//!    operations synchronously and asynchronously trivial, with no need to deal with adding code to
//!    start threads or communicate between them.
//!
//! In addition to the two fundamental methods, desync provides methods for generating futures and
//! processing streams.
//!
//! # Quick start
//!
//! There is a single new synchronisation object: `Desync`. You create one like this:
//!
//! ```
//! use desync::Desync;
//! let number = Desync::new(0);
//! ```
//!
//! It supports two main operations. `desync` will schedule a new job for the object that will run
//! in a background thread. It's useful for deferring long-running operations and moving updates
//! so they can run in parallel.
//!
//! ```
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! let number = Desync::new(0);
//! number.desync(|val| {
//!     // Long update here
//!     thread::sleep(Duration::from_millis(100));
//!     *val = 42;
//! });
//!
//! // We can carry on what we're doing with the update now running in the background
//! ```
//!
//! The other operation is `sync`, which schedules a job to run synchronously on the data structure.
//! This is useful for retrieving values from a `Desync`.
//!
//! ```
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! # let number = Desync::new(0);
//! # number.desync(|val| {
//! #     // Long update here
//! #     thread::sleep(Duration::from_millis(100));
//! #     *val = 42;
//! # });
//! let new_number = number.sync(|val| *val);           // = 42
//! # assert!(new_number == 42);
//! ```
//!
//! `Desync` objects always run operations in the order that is provided, so all operations are
//! serialized from the point of view of the data that they contain. When combined with the ability
//! to perform operations asynchronously, this provides a useful way to immediately parallelize
//! long-running operations.
//!
//! The `future()` action returns a boxed Future that can be used with other libraries that use them. It's
//! conceptually the same as `sync`, except that it doesn't wait for the operation to complete:
//!
//! ```
//! # extern crate futures;
//! # extern crate desync;
//! # fn main() {
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! # use futures::executor;
//! # use futures::future;
//! # let number = Desync::new(0);
//! # number.desync(|val| {
//! #     // Long update here
//! #     thread::sleep(Duration::from_millis(100));
//! #     *val = 42;
//! # });
//! let future_number = number.future(|val| future::ready(*val));
//! assert!(executor::block_on(async { future_number.await.unwrap() }) == 42 );
//! # }
//!
//! Note that this is the equivalent of just `number.sync(|val| *val)`, so this is mainly useful for
//! interacting with other code that's already using futures. The `after()` function is also provided
//! for using the results of futures to update the contents of `Desync` data: these all preserve the
//! strict order-of-operations semantics, so operations scheduled after an `after` won't start until
//! that operation has completed.
//!
//! ```
//!

#![warn(bare_trait_objects)]

#[macro_use]
extern crate lazy_static;
extern crate futures;

#[cfg(not(target_arch = "wasm32"))]
extern crate num_cpus;

pub mod scheduler;
pub mod desync;
pub mod pipe;

mod job;
mod future_job;
mod unsafe_job;
mod scheduler_thread;

pub use self::desync::*;
pub use self::pipe::*;
<commit_msg>Add a note about pipes/streams to the library docs<commit_after>//!
//! # Desync
//!
//!
//! This is a library for Rust that provides a model of concurrency based around the idea of
//! scheduling operations on data. This is in contrast to the traditional model where operations
//! are scheduled on threads with ownership of the data being passed between them.
//!
//! This approach has several advantages over the traditional method:
//!
//!  * It's simpler: almost the  entire set of thread methods and synchronisation primitives can
//!    be replaced with the two fundamental scheduling functions, `sync()` and `desync()`.
//!  * It's easier to reason about: scheduled operations are always performed in the order they're
//!    queued so race conditions and similar issues due to out-of-order execution are both much rarer
//!    and easier to debug.
//!  * It makes it easier to write highly concurrent code: desync makes moving between performing
//!    operations synchronously and asynchronously trivial, with no need to deal with adding code to
//!    start threads or communicate between them.
//!
//! In addition to the two fundamental methods, desync provides methods for generating futures and
//! processing streams.
//!
//! # Quick start
//!
//! There is a single new synchronisation object: `Desync`. You create one like this:
//!
//! ```
//! use desync::Desync;
//! let number = Desync::new(0);
//! ```
//!
//! It supports two main operations. `desync` will schedule a new job for the object that will run
//! in a background thread. It's useful for deferring long-running operations and moving updates
//! so they can run in parallel.
//!
//! ```
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! let number = Desync::new(0);
//! number.desync(|val| {
//!     // Long update here
//!     thread::sleep(Duration::from_millis(100));
//!     *val = 42;
//! });
//!
//! // We can carry on what we're doing with the update now running in the background
//! ```
//!
//! The other operation is `sync`, which schedules a job to run synchronously on the data structure.
//! This is useful for retrieving values from a `Desync`.
//!
//! ```
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! # let number = Desync::new(0);
//! # number.desync(|val| {
//! #     // Long update here
//! #     thread::sleep(Duration::from_millis(100));
//! #     *val = 42;
//! # });
//! let new_number = number.sync(|val| *val);           // = 42
//! # assert!(new_number == 42);
//! ```
//!
//! `Desync` objects always run operations in the order that is provided, so all operations are
//! serialized from the point of view of the data that they contain. When combined with the ability
//! to perform operations asynchronously, this provides a useful way to immediately parallelize
//! long-running operations.
//!
//! The `future()` action returns a boxed Future that can be used with other libraries that use them. It's
//! conceptually the same as `sync`, except that it doesn't wait for the operation to complete:
//!
//! ```
//! # extern crate futures;
//! # extern crate desync;
//! # fn main() {
//! # use desync::Desync;
//! # use std::thread;
//! # use std::time::*;
//! # use futures::executor;
//! # use futures::future;
//! # let number = Desync::new(0);
//! # number.desync(|val| {
//! #     // Long update here
//! #     thread::sleep(Duration::from_millis(100));
//! #     *val = 42;
//! # });
//! let future_number = number.future(|val| future::ready(*val));
//! assert!(executor::block_on(async { future_number.await.unwrap() }) == 42 );
//! # }
//!
//! Note that this is the equivalent of just `number.sync(|val| *val)`, so this is mainly useful for
//! interacting with other code that's already using futures. The `after()` function is also provided
//! for using the results of futures to update the contents of `Desync` data: these all preserve the
//! strict order-of-operations semantics, so operations scheduled after an `after` won't start until
//! that operation has completed.
//!
//! # Pipes and streams
//!
//! As well as support for futures, Desync provides supports for streams. The `pipe_in()` and `pipe()`
//! functions provide a way to process stream data in a desync object as it arrives. `pipe_in()` just
//! processes stream data as it arrives, and `pipe()` provides an output stream of data.
//!
//! `pipe()` is quite useful as a way to provide asynchronous access to synchronous code: it can be used
//! to create a channel to send requests to an asynchronous target and retrieve results back via its
//! output. (Unlike this 'traditional' method, the actual scheduling and channel maintenance does not
//! need to be explicitly implemented)
//!
//! ```
//!

#![warn(bare_trait_objects)]

#[macro_use]
extern crate lazy_static;
extern crate futures;

#[cfg(not(target_arch = "wasm32"))]
extern crate num_cpus;

pub mod scheduler;
pub mod desync;
pub mod pipe;

mod job;
mod future_job;
mod unsafe_job;
mod scheduler_thread;

pub use self::desync::*;
pub use self::pipe::*;
<|endoftext|>


<commit_before>//! Lightweight, event-driven WebSockets for Rust.
#![allow(deprecated)]
#![deny(
    missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unstable_features,
    unused_import_braces)]

extern crate httparse;
extern crate mio;
extern crate sha1;
extern crate rand;
extern crate url;
extern crate slab;
extern crate bytes;
extern crate byteorder;
#[cfg(feature="ssl")] extern crate openssl;
#[macro_use] extern crate log;

mod result;
mod connection;
mod handler;
mod factory;
mod frame;
mod message;
mod handshake;
mod protocol;
mod communication;
mod io;
mod stream;

#[cfg(feature="permessage-deflate")]
pub mod deflate;

pub mod util;

pub use factory::Factory;
pub use handler::Handler;

pub use result::{Result, Error};
pub use result::Kind as ErrorKind;
pub use message::Message;
pub use communication::Sender;
pub use frame::Frame;
pub use protocol::{CloseCode, OpCode};
pub use handshake::{Handshake, Request, Response};

use std::fmt;
use std::default::Default;
use std::net::{SocketAddr, ToSocketAddrs};
use std::borrow::Borrow;

use mio::Poll;

/// A utility function for setting up a WebSocket server.
///
/// # Safety
///
/// This function blocks until the event loop finishes running. Avoid calling this method within
/// another WebSocket handler.
///
/// # Examples
///
/// ```no_run
/// use ws::listen;
///
/// listen("127.0.0.1:3012", |out| {
///     move |msg| {
///        out.send(msg)
///    }
/// }).unwrap()
/// ```
///
pub fn listen<A, F, H>(addr: A, factory: F) -> Result<()>
    where
        A: ToSocketAddrs + fmt::Debug,
        F: FnMut(Sender) -> H,
        H: Handler,
{
    let ws = try!(WebSocket::new(factory));
    try!(ws.listen(addr));
    Ok(())
}

/// A utility function for setting up a WebSocket client.
///
/// # Safety
///
/// This function blocks until the event loop finishes running. Avoid calling this method within
/// another WebSocket handler. If you need to establish a connection from inside of a handler,
/// use the `connect` method on the Sender.
///
/// # Examples
///
/// ```no_run
/// use ws::{connect, CloseCode};
///
/// connect("ws://127.0.0.1:3012", |out| {
///     out.send("Hello WebSocket").unwrap();
///
///     move |msg| {
///         println!("Got message: {}", msg);
///         out.close(CloseCode::Normal)
///     }
/// }).unwrap()
/// ```
///
pub fn connect<U, F, H>(url: U, factory: F) -> Result<()>
    where
        U: Borrow<str>,
        F: FnMut(Sender) -> H,
        H: Handler
{
    let mut ws = try!(WebSocket::new(factory));
    let parsed = try!(
        url::Url::parse(url.borrow())
            .map_err(|err| Error::new(
                ErrorKind::Internal,
                format!("Unable to parse {} as url due to {:?}", url.borrow(), err))));
    try!(ws.connect(parsed));
    try!(ws.run());
    Ok(())
}

/// WebSocket settings
#[derive(Debug, Clone, Copy)]
pub struct Settings {
    /// The maximum number of connections that this WebSocket will support.
    /// The default setting is low and should be increased when expecting more
    /// connections because this is a hard limit and no new connections beyond
    /// this limit can be made until an old connection is dropped.
    /// Default: 100
    pub max_connections: usize,
    /// The number of events anticipated per connection. The event loop queue size will
    /// be `queue_size` * `max_connections`. In order to avoid an overflow error,
    /// `queue_size` * `max_connections` must be less than or equal to `usize::max_value()`.
    /// The queue is shared between connections, which means that a connection may schedule
    /// more events than `queue_size` provided that another connection is using less than
    /// `queue_size`. However, if the queue is maxed out a Queue error will occur.
    /// Default: 5
    pub queue_size: usize,
    /// Whether to panic when unable to establish a new TCP connection.
    /// Default: false
    pub panic_on_new_connection: bool,
    /// Whether to panic when a shutdown of the WebSocket is requested.
    /// Default: false
    pub panic_on_shutdown: bool,
    /// The maximum number of fragments the connection can handle without reallocating.
    /// Default: 10
    pub fragments_capacity: usize,
    /// Whether to reallocate when `fragments_capacity` is reached. If this is false,
    /// a Capacity error will be triggered instead.
    /// Default: true
    pub fragments_grow: bool,
    /// The maximum length of outgoing frames. Messages longer than this will be fragmented.
    /// Default: 65,535
    pub fragment_size: usize,
    /// The size of the incoming buffer. A larger buffer uses more memory but will allow for fewer
    /// reallocations.
    /// Default: 2048
    pub in_buffer_capacity: usize,
    /// Whether to reallocate the incoming buffer when `in_buffer_capacity` is reached. If this is
    /// false, a Capacity error will be triggered instead.
    /// Default: true
    pub in_buffer_grow: bool,
    /// The size of the outgoing buffer. A larger buffer uses more memory but will allow for fewer
    /// reallocations.
    /// Default: 2048
    pub out_buffer_capacity: usize,
    /// Whether to reallocate the incoming buffer when `out_buffer_capacity` is reached. If this is
    /// false, a Capacity error will be triggered instead.
    /// Default: true
    pub out_buffer_grow: bool,
    /// Whether to panic when an Internal error is encountered. Internal errors should generally
    /// not occur, so this setting defaults to true as a debug measure, whereas production
    /// applications should consider setting it to false.
    /// Default: true
    pub panic_on_internal: bool,
    /// Whether to panic when a Capacity error is encountered.
    /// Default: false
    pub panic_on_capacity: bool,
    /// Whether to panic when a Protocol error is encountered.
    /// Default: false
    pub panic_on_protocol: bool,
    /// Whether to panic when an Encoding error is encountered.
    /// Default: false
    pub panic_on_encoding: bool,
    /// Whether to panic when a Queue error is encountered.
    /// Default: false
    pub panic_on_queue: bool,
    /// Whether to panic when an Io error is encountered.
    /// Default: false
    pub panic_on_io: bool,
    /// Whether to panic when a Timer error is encountered.
    /// Default: false
    pub panic_on_timeout: bool,
    /// Whether to shutdown the eventloop when an interrupt is received.
    /// Default: true
    pub shutdown_on_interrupt: bool,
    /// The WebSocket protocol requires frames sent from client endpoints to be masked as a
    /// security and sanity precaution. Enforcing this requirement, which may be removed at some
    /// point may cause incompatibilities. If you need the extra security, set this to true.
    /// Default: false
    pub masking_strict: bool,
    /// The WebSocket protocol requires clients to verify the key returned by a server to ensure
    /// that the server and all intermediaries can perform the protocol. Verifying the key will
    /// consume processing time and other resources with the benifit that we can fail the
    /// connection early. The default in WS-RS is to accept any key from the server and instead
    /// fail late if a protocol error occurs. Change this setting to enable key verification.
    /// Default: false
    pub key_strict: bool,
    /// The WebSocket protocol requires clients to perform an opening handshake using the HTTP
    /// GET method for the request. However, since only WebSockets are supported on the connection,
    /// verifying the method of handshake requests is not always necessary. To enforce the
    /// requirement that handshakes begin with a GET method, set this to true.
    /// Default: false
    pub method_strict: bool,
    /// Indicate whether server connections should use ssl encryption when accepting connections.
    /// Setting this to true means that clients should use the `wss` scheme to connect to this
    /// server. Note that using this flag will in general necessitate overriding the
    /// `Handler::upgrade_ssl_server` method in order to provide the details of the ssl context. It may be
    /// simpler for most users to use a reverse proxy such as nginx to provide server side
    /// encryption.
    ///
    /// Default: false
    pub encrypt_server: bool,
    /// Disables Nagle's algorithm.
    /// Usually tcp socket tries to accumulate packets to send them all together (every 200ms).
    /// When enabled socket will try to send packet as fast as possible.
    ///
    /// Default: false
    pub tcp_nodelay: bool
}

impl Default for Settings {

    fn default() -> Settings {
        Settings {
            max_connections: 100,
            queue_size: 5,
            panic_on_new_connection: false,
            panic_on_shutdown: false,
            fragments_capacity: 10,
            fragments_grow: true,
            fragment_size: u16::max_value() as usize,
            in_buffer_capacity: 2048,
            in_buffer_grow: true,
            out_buffer_capacity: 2048,
            out_buffer_grow: true,
            panic_on_internal: true,
            panic_on_capacity: false,
            panic_on_protocol: false,
            panic_on_encoding: false,
            panic_on_queue: false,
            panic_on_io: false,
            panic_on_timeout: false,
            shutdown_on_interrupt: true,
            masking_strict: false,
            key_strict: false,
            method_strict: false,
            encrypt_server: false,
            tcp_nodelay: false
        }
    }
}

/// The WebSocket struct. A WebSocket can support multiple incoming and outgoing connections.
pub struct WebSocket<F>
    where F: Factory
{
    poll: Poll,
    handler: io::Handler<F>,
}

impl<F> WebSocket<F>
    where F: Factory
{
    /// Create a new WebSocket using the given Factory to create handlers.
    pub fn new(factory: F) -> Result<WebSocket<F>> {
        Builder::new().build(factory)
    }

    /// Consume the WebSocket and bind to the specified address.
    /// If the `addr_spec` yields multiple addresses this will return after the
    /// first successful bind. `local_addr` can be called to determine which
    /// address it ended up binding to.
    /// After the server is succesfully bound you should start it using `run`.
    pub fn bind<A>(mut self, addr_spec: A) -> Result<WebSocket<F>>
        where A: ToSocketAddrs
    {
        let mut last_error = Error::new(ErrorKind::Internal, "No address given");

        for addr in try!(addr_spec.to_socket_addrs()) {
            if let Err(e) = self.handler.listen(&mut self.poll, &addr) {
                error!("Unable to listen on {}", addr);
                last_error = e;
            } else {
                let actual_addr = self.handler.local_addr().unwrap_or(addr);
                info!("Listening for new connections on {}.", actual_addr);
                return Ok(self);
            }
        }

        Err(last_error)
    }

    /// Consume the WebSocket and listen for new connections on the specified address.
    ///
    /// # Safety
    ///
    /// This method will block until the event loop finishes running.
    pub fn listen<A>(self, addr_spec: A) -> Result<WebSocket<F>>
        where A: ToSocketAddrs
    {
        self.bind(addr_spec).and_then(|server| server.run())
    }

    /// Queue an outgoing connection on this WebSocket. This method may be called multiple times,
    /// but the actual connections will not be established until after `run` is called.
    pub fn connect(&mut self, url: url::Url) -> Result<&mut WebSocket<F>> {
        let sender = self.handler.sender();
        info!("Queuing connection to {}", url);
        try!(sender.connect(url));
        Ok(self)
    }

    /// Run the WebSocket. This will run the encapsulated event loop blocking until the WebSocket
    /// is shutdown.
    pub fn run(mut self) -> Result<WebSocket<F>> {
        try!(self.handler.run(&mut self.poll));
        Ok(self)
    }

    /// Get a Sender that can be used to send messages on all connections.
    /// Calling `send` on this Sender is equivalent to calling `broadcast`.
    /// Calling `shutdown` on this Sender will shudown the WebSocket even if no connections have
    /// been established.
    #[inline]
    pub fn broadcaster(&self) -> Sender {
        self.handler.sender()
    }

    /// Get the local socket address this socket is bound to. Will return an error
    /// if the backend returns an error. Will return a `NotFound` error if
    /// this WebSocket is not a listening socket.
    pub fn local_addr(&self) -> ::std::io::Result<SocketAddr> {
        self.handler.local_addr()
    }
}

/// Utility for constructing a WebSocket from various settings.
#[derive(Debug, Clone, Copy)]
pub struct Builder {
    settings: Settings,
}

// TODO: add convenience methods for each setting
impl Builder {
    /// Create a new Builder with default settings.
    pub fn new() -> Builder {
        Builder {
            settings: Settings::default(),
        }
    }

    /// Build a WebSocket using this builder and a factory.
    /// It is possible to use the same builder to create multiple WebSockets.
    pub fn build<F>(&self, factory: F) -> Result<WebSocket<F>>
        where F: Factory
    {
        Ok(WebSocket {
            poll: try!(Poll::new()),
            handler: io::Handler::new(factory, self.settings),
        })
    }

    /// Set the WebSocket settings to use.
    pub fn with_settings(&mut self, settings: Settings) -> &mut Builder {
        self.settings = settings;
        self
    }
}
<commit_msg>doc enhancement<commit_after>//! Lightweight, event-driven WebSockets for Rust.
#![allow(deprecated)]
#![deny(
    missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unstable_features,
    unused_import_braces)]

extern crate httparse;
extern crate mio;
extern crate sha1;
extern crate rand;
extern crate url;
extern crate slab;
extern crate bytes;
extern crate byteorder;
#[cfg(feature="ssl")] extern crate openssl;
#[macro_use] extern crate log;

mod result;
mod connection;
mod handler;
mod factory;
mod frame;
mod message;
mod handshake;
mod protocol;
mod communication;
mod io;
mod stream;

#[cfg(feature="permessage-deflate")]
pub mod deflate;

pub mod util;

pub use factory::Factory;
pub use handler::Handler;

pub use result::{Result, Error};
pub use result::Kind as ErrorKind;
pub use message::Message;
pub use communication::Sender;
pub use frame::Frame;
pub use protocol::{CloseCode, OpCode};
pub use handshake::{Handshake, Request, Response};

use std::fmt;
use std::default::Default;
use std::net::{SocketAddr, ToSocketAddrs};
use std::borrow::Borrow;

use mio::Poll;

/// A utility function for setting up a WebSocket server.
///
/// # Safety
///
/// This function blocks until the event loop finishes running. Avoid calling this method within
/// another WebSocket handler.
///
/// # Examples
///
/// ```no_run
/// use ws::listen;
///
/// listen("127.0.0.1:3012", |out| {
///     move |msg| {
///        out.send(msg)
///    }
/// }).unwrap()
/// ```
///
pub fn listen<A, F, H>(addr: A, factory: F) -> Result<()>
    where
        A: ToSocketAddrs + fmt::Debug,
        F: FnMut(Sender) -> H,
        H: Handler,
{
    let ws = try!(WebSocket::new(factory));
    try!(ws.listen(addr));
    Ok(())
}

/// A utility function for setting up a WebSocket client.
///
/// # Safety
///
/// This function blocks until the event loop finishes running. Avoid calling this method within
/// another WebSocket handler. If you need to establish a connection from inside of a handler,
/// use the `connect` method on the Sender.
///
/// # Examples
///
/// ```no_run
/// use ws::{connect, CloseCode};
///
/// connect("ws://127.0.0.1:3012", |out| {
///     out.send("Hello WebSocket").unwrap();
///
///     move |msg| {
///         println!("Got message: {}", msg);
///         out.close(CloseCode::Normal)
///     }
/// }).unwrap()
/// ```
///
pub fn connect<U, F, H>(url: U, factory: F) -> Result<()>
    where
        U: Borrow<str>,
        F: FnMut(Sender) -> H,
        H: Handler
{
    let mut ws = try!(WebSocket::new(factory));
    let parsed = try!(
        url::Url::parse(url.borrow())
            .map_err(|err| Error::new(
                ErrorKind::Internal,
                format!("Unable to parse {} as url due to {:?}", url.borrow(), err))));
    try!(ws.connect(parsed));
    try!(ws.run());
    Ok(())
}

/// WebSocket settings
#[derive(Debug, Clone, Copy)]
pub struct Settings {
    /// The maximum number of connections that this WebSocket will support.
    /// The default setting is low and should be increased when expecting more
    /// connections because this is a hard limit and no new connections beyond
    /// this limit can be made until an old connection is dropped.
    /// Default: 100
    pub max_connections: usize,
    /// The number of events anticipated per connection. The event loop queue size will
    /// be `queue_size` * `max_connections`. In order to avoid an overflow error,
    /// `queue_size` * `max_connections` must be less than or equal to `usize::max_value()`.
    /// The queue is shared between connections, which means that a connection may schedule
    /// more events than `queue_size` provided that another connection is using less than
    /// `queue_size`. However, if the queue is maxed out a Queue error will occur.
    /// Default: 5
    pub queue_size: usize,
    /// Whether to panic when unable to establish a new TCP connection.
    /// Default: false
    pub panic_on_new_connection: bool,
    /// Whether to panic when a shutdown of the WebSocket is requested.
    /// Default: false
    pub panic_on_shutdown: bool,
    /// The maximum number of fragments the connection can handle without reallocating.
    /// Default: 10
    pub fragments_capacity: usize,
    /// Whether to reallocate when `fragments_capacity` is reached. If this is false,
    /// a Capacity error will be triggered instead.
    /// Default: true
    pub fragments_grow: bool,
    /// The maximum length of outgoing frames. Messages longer than this will be fragmented.
    /// Default: 65,535
    pub fragment_size: usize,
    /// The size of the incoming buffer. A larger buffer uses more memory but will allow for fewer
    /// reallocations.
    /// Default: 2048
    pub in_buffer_capacity: usize,
    /// Whether to reallocate the incoming buffer when `in_buffer_capacity` is reached. If this is
    /// false, a Capacity error will be triggered instead.
    /// Default: true
    pub in_buffer_grow: bool,
    /// The size of the outgoing buffer. A larger buffer uses more memory but will allow for fewer
    /// reallocations.
    /// Default: 2048
    pub out_buffer_capacity: usize,
    /// Whether to reallocate the incoming buffer when `out_buffer_capacity` is reached. If this is
    /// false, a Capacity error will be triggered instead.
    /// Default: true
    pub out_buffer_grow: bool,
    /// Whether to panic when an Internal error is encountered. Internal errors should generally
    /// not occur, so this setting defaults to true as a debug measure, whereas production
    /// applications should consider setting it to false.
    /// Default: true
    pub panic_on_internal: bool,
    /// Whether to panic when a Capacity error is encountered.
    /// Default: false
    pub panic_on_capacity: bool,
    /// Whether to panic when a Protocol error is encountered.
    /// Default: false
    pub panic_on_protocol: bool,
    /// Whether to panic when an Encoding error is encountered.
    /// Default: false
    pub panic_on_encoding: bool,
    /// Whether to panic when a Queue error is encountered.
    /// Default: false
    pub panic_on_queue: bool,
    /// Whether to panic when an Io error is encountered.
    /// Default: false
    pub panic_on_io: bool,
    /// Whether to panic when a Timer error is encountered.
    /// Default: false
    pub panic_on_timeout: bool,
    /// Whether to shutdown the eventloop when an interrupt is received.
    /// Default: true
    pub shutdown_on_interrupt: bool,
    /// The WebSocket protocol requires frames sent from client endpoints to be masked as a
    /// security and sanity precaution. Enforcing this requirement, which may be removed at some
    /// point may cause incompatibilities. If you need the extra security, set this to true.
    /// Default: false
    pub masking_strict: bool,
    /// The WebSocket protocol requires clients to verify the key returned by a server to ensure
    /// that the server and all intermediaries can perform the protocol. Verifying the key will
    /// consume processing time and other resources with the benifit that we can fail the
    /// connection early. The default in WS-RS is to accept any key from the server and instead
    /// fail late if a protocol error occurs. Change this setting to enable key verification.
    /// Default: false
    pub key_strict: bool,
    /// The WebSocket protocol requires clients to perform an opening handshake using the HTTP
    /// GET method for the request. However, since only WebSockets are supported on the connection,
    /// verifying the method of handshake requests is not always necessary. To enforce the
    /// requirement that handshakes begin with a GET method, set this to true.
    /// Default: false
    pub method_strict: bool,
    /// Indicate whether server connections should use ssl encryption when accepting connections.
    /// Setting this to true means that clients should use the `wss` scheme to connect to this
    /// server. Note that using this flag will in general necessitate overriding the
    /// `Handler::upgrade_ssl_server` method in order to provide the details of the ssl context. It may be
    /// simpler for most users to use a reverse proxy such as nginx to provide server side
    /// encryption.
    ///
    /// Default: false
    pub encrypt_server: bool,
    /// Disables Nagle's algorithm.
    /// Usually tcp socket tries to accumulate packets to send them all together (every 200ms).
    /// When enabled socket will try to send packet as fast as possible.
    ///
    /// Default: false
    pub tcp_nodelay: bool
}

impl Default for Settings {

    fn default() -> Settings {
        Settings {
            max_connections: 100,
            queue_size: 5,
            panic_on_new_connection: false,
            panic_on_shutdown: false,
            fragments_capacity: 10,
            fragments_grow: true,
            fragment_size: u16::max_value() as usize,
            in_buffer_capacity: 2048,
            in_buffer_grow: true,
            out_buffer_capacity: 2048,
            out_buffer_grow: true,
            panic_on_internal: true,
            panic_on_capacity: false,
            panic_on_protocol: false,
            panic_on_encoding: false,
            panic_on_queue: false,
            panic_on_io: false,
            panic_on_timeout: false,
            shutdown_on_interrupt: true,
            masking_strict: false,
            key_strict: false,
            method_strict: false,
            encrypt_server: false,
            tcp_nodelay: false
        }
    }
}

/// The WebSocket struct. A WebSocket can support multiple incoming and outgoing connections.
pub struct WebSocket<F>
    where F: Factory
{
    poll: Poll,
    handler: io::Handler<F>,
}

impl<F> WebSocket<F>
    where F: Factory
{
    /// Create a new WebSocket using the given Factory to create handlers.
    pub fn new(factory: F) -> Result<WebSocket<F>> {
        Builder::new().build(factory)
    }

    /// Consume the WebSocket and bind to the specified address.
    /// If the `addr_spec` yields multiple addresses this will return after the
    /// first successful bind. `local_addr` can be called to determine which
    /// address it ended up binding to.
    /// After the server is succesfully bound you should start it using `run`.
    pub fn bind<A>(mut self, addr_spec: A) -> Result<WebSocket<F>>
        where A: ToSocketAddrs
    {
        let mut last_error = Error::new(ErrorKind::Internal, "No address given");

        for addr in try!(addr_spec.to_socket_addrs()) {
            if let Err(e) = self.handler.listen(&mut self.poll, &addr) {
                error!("Unable to listen on {}", addr);
                last_error = e;
            } else {
                let actual_addr = self.handler.local_addr().unwrap_or(addr);
                info!("Listening for new connections on {}.", actual_addr);
                return Ok(self);
            }
        }

        Err(last_error)
    }

    /// Consume the WebSocket and listen for new connections on the specified address.
    ///
    /// # Safety
    ///
    /// This method will block until the event loop finishes running.
    pub fn listen<A>(self, addr_spec: A) -> Result<WebSocket<F>>
        where A: ToSocketAddrs
    {
        self.bind(addr_spec).and_then(|server| server.run())
    }

    /// Queue an outgoing connection on this WebSocket. This method may be called multiple times,
    /// but the actual connections will not be established until `run` is called.
    pub fn connect(&mut self, url: url::Url) -> Result<&mut WebSocket<F>> {
        let sender = self.handler.sender();
        info!("Queuing connection to {}", url);
        try!(sender.connect(url));
        Ok(self)
    }

    /// Run the WebSocket. This will run the encapsulated event loop blocking the calling thread until
    /// the WebSocket is shutdown.
    pub fn run(mut self) -> Result<WebSocket<F>> {
        try!(self.handler.run(&mut self.poll));
        Ok(self)
    }

    /// Get a Sender that can be used to send messages on all connections.
    /// Calling `send` on this Sender is equivalent to calling `broadcast`.
    /// Calling `shutdown` on this Sender will shudown the WebSocket even if no connections have
    /// been established.
    #[inline]
    pub fn broadcaster(&self) -> Sender {
        self.handler.sender()
    }

    /// Get the local socket address this socket is bound to. Will return an error
    /// if the backend returns an error. Will return a `NotFound` error if
    /// this WebSocket is not a listening socket.
    pub fn local_addr(&self) -> ::std::io::Result<SocketAddr> {
        self.handler.local_addr()
    }
}

/// Utility for constructing a WebSocket from various settings.
#[derive(Debug, Clone, Copy)]
pub struct Builder {
    settings: Settings,
}

// TODO: add convenience methods for each setting
impl Builder {
    /// Create a new Builder with default settings.
    pub fn new() -> Builder {
        Builder {
            settings: Settings::default(),
        }
    }

    /// Build a WebSocket using this builder and a factory.
    /// It is possible to use the same builder to create multiple WebSockets.
    pub fn build<F>(&self, factory: F) -> Result<WebSocket<F>>
        where F: Factory
    {
        Ok(WebSocket {
            poll: try!(Poll::new()),
            handler: io::Handler::new(factory, self.settings),
        })
    }

    /// Set the WebSocket settings to use.
    pub fn with_settings(&mut self, settings: Settings) -> &mut Builder {
        self.settings = settings;
        self
    }
}
<|endoftext|>


<commit_before>use std::ops::Index;
use std::fmt;
use std::fmt::Write;

#[derive(Clone)]
pub struct StrStack {
    data: String,
    ends: Vec<usize>,
}

impl Index<usize> for StrStack {
    type Output = str;
    #[inline]
    fn index(&self, index: usize) -> &str {
        let start = if index == 0 {
            0
        } else {
            self.ends[index-1]
        };
        let end = self.ends[index];
        &self.data[start..end]
    }
}

#[derive(Clone, Copy)]
pub struct Iter<'a> {
    stack: &'a StrStack,
    start: usize,
    end: usize,
}

impl fmt::Debug for StrStack {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.iter()).finish()
    }
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a str;
    #[inline]
    fn next(&mut self) -> Option<&'a str> {
        if self.start == self.end {
            None
        } else {
            let s = &self.stack[self.start];
            self.start += 1;
            Some(s)
        }
    }

    fn count(self) -> usize {
        self.end - self.start
    }

    fn nth(&mut self, n: usize) -> Option<&'a str> {
        match self.start.checked_add(n) {
            Some(n) if n < self.end => {
                self.start = n;
                self.next()
            },
            _ => {
                self.start = self.end;
                None
            }
        }
    }

    fn last(mut self) -> Option<&'a str> {
        self.next_back()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.end - self.start;
        (len, Some(len))
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {}

impl<'a> DoubleEndedIterator for Iter<'a> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a str> {
        if self.start == self.end {
            None
        } else {
            self.end -= 1;
            Some(&self.stack[self.end])
        }
    }
}

impl<'a> IntoIterator for &'a StrStack {
    type IntoIter = Iter<'a>;
    type Item = &'a str;
    #[inline]
    fn into_iter(self) -> Iter<'a> {
        self.iter()
    }
}

impl StrStack {
    /// Create a new StrStack.
    #[inline]
    pub fn new() -> StrStack {
        StrStack {
            data: String::new(),
            ends: Vec::new(),
        }
    }

    /// Create a new StrStack with the given capacity.
    #[inline]
    pub fn with_capacity(bytes: usize, strings: usize) -> StrStack {
        StrStack {
            data: String::with_capacity(bytes),
            ends: Vec::with_capacity(strings)
        }
    }

    #[inline]
    pub fn push(&mut self, s: &str) -> usize {
        self.data.push_str(s);
        self.ends.push(self.data.len());
        self.len() - 1
    }

    #[inline]
    pub fn iter(&self) -> Iter {
        Iter {
            stack: self,
            start: 0,
            end: self.len(),
        }
    }

    #[inline]
    pub fn pop(&mut self) -> bool {
        let popped = self.ends.pop().is_some();
        if let Some(&offset) = self.ends.last() {
            self.data.truncate(offset);
        }
        popped
    }

    #[inline]
    pub fn clear(&mut self) {
        self.ends.clear();
        self.data.clear();
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.ends.len()
    }

    #[inline]
    pub fn truncate(&mut self, len: usize) {
        self.ends.truncate(len);
        self.data.truncate(*self.ends.last().unwrap_or(&0));
    }

    #[inline]
    pub fn writer(&mut self) -> Writer {
        Writer(self)
    }

    #[inline]
    pub fn write_fmt(&mut self, args: fmt::Arguments) -> usize {
        let mut writer = self.writer();
        let _ = writer.write_fmt(args);
        writer.finish()
    }
}

pub struct Writer<'a>(&'a mut StrStack);
impl<'a> Writer<'a> {
    #[inline]
    pub fn finish(self) -> usize {
        // We push on drop.
        self.0.len()
    }
}
impl<'a> fmt::Write for Writer<'a> {
    #[inline]
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.0.data.push_str(s);
        Ok(())
    }
    #[inline]
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.0.data.push(c);
        Ok(())
    }
}

impl<'a> Drop for Writer<'a> {
    fn drop(&mut self) {
        self.0.ends.push(self.0.data.len());
    }
}

#[test]
fn test_basic() {
    let mut stack = StrStack::new();
    let first = stack.push("one");
    let second = stack.push("two");
    let third = stack.push("three");

    assert_eq!(&stack[first], "one");
    assert_eq!(&stack[second], "two");
    assert_eq!(&stack[third], "three");

    assert_eq!(stack.len(), 3);

    assert!(stack.pop());

    assert_eq!(stack.len(), 2);

    assert_eq!(&stack[first], "one");
    assert_eq!(&stack[second], "two");

    assert!(stack.pop());
    assert!(stack.pop());

    assert_eq!(stack.len(), 0);
    assert!(!stack.pop());
}

#[test]
fn test_writer() {
    let mut stack = StrStack::new();
    let first = {
        let mut w = stack.writer();
        write!(w, "{}", "first ").unwrap();
        write!(w, "{}", "second").unwrap();
        w.finish()
    };

    let second = {
        let mut w = stack.writer();
        write!(w, "{}", "third ").unwrap();
        write!(w, "{}", "fourth").unwrap();
        w.finish()
    };
    assert_eq!(&stack[first], "first second");
    assert_eq!(&stack[second], "third fourth");
}
<commit_msg>Document and add consume method.<commit_after>use std::ops::Index;
use std::fmt::{self, Write};
use std::io::{self, Read};

#[derive(Clone)]
pub struct StrStack {
    data: String,
    ends: Vec<usize>,
}

impl Index<usize> for StrStack {
    type Output = str;
    #[inline]
    fn index(&self, index: usize) -> &str {
        let start = if index == 0 {
            0
        } else {
            self.ends[index-1]
        };
        let end = self.ends[index];
        &self.data[start..end]
    }
}

#[derive(Clone, Copy)]
pub struct Iter<'a> {
    stack: &'a StrStack,
    start: usize,
    end: usize,
}

impl fmt::Debug for StrStack {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.iter()).finish()
    }
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a str;
    #[inline]
    fn next(&mut self) -> Option<&'a str> {
        if self.start == self.end {
            None
        } else {
            let s = &self.stack[self.start];
            self.start += 1;
            Some(s)
        }
    }

    fn count(self) -> usize {
        self.end - self.start
    }

    fn nth(&mut self, n: usize) -> Option<&'a str> {
        match self.start.checked_add(n) {
            Some(n) if n < self.end => {
                self.start = n;
                self.next()
            },
            _ => {
                self.start = self.end;
                None
            }
        }
    }

    fn last(mut self) -> Option<&'a str> {
        self.next_back()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.end - self.start;
        (len, Some(len))
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {}

impl<'a> DoubleEndedIterator for Iter<'a> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a str> {
        if self.start == self.end {
            None
        } else {
            self.end -= 1;
            Some(&self.stack[self.end])
        }
    }
}

impl<'a> IntoIterator for &'a StrStack {
    type IntoIter = Iter<'a>;
    type Item = &'a str;
    #[inline]
    fn into_iter(self) -> Iter<'a> {
        self.iter()
    }
}

impl StrStack {
    /// Create a new StrStack.
    #[inline]
    pub fn new() -> StrStack {
        StrStack {
            data: String::new(),
            ends: Vec::new(),
        }
    }

    /// Create a new StrStack with the given capacity.
    ///
    /// You will be able to push `bytes` bytes and create `strings` strings before reallocating.
    #[inline]
    pub fn with_capacity(bytes: usize, strings: usize) -> StrStack {
        StrStack {
            data: String::with_capacity(bytes),
            ends: Vec::with_capacity(strings)
        }
    }

    /// Push a string onto the string stack.
    ///
    /// This returns the index of the string on the stack.
    #[inline]
    pub fn push(&mut self, s: &str) -> usize {
        self.data.push_str(s);
        self.ends.push(self.data.len());
        self.len() - 1
    }

    /// Iterate over the strings on the stack.
    #[inline]
    pub fn iter(&self) -> Iter {
        Iter {
            stack: self,
            start: 0,
            end: self.len(),
        }
    }

    /// Remove the top string from the stack.
    ///
    /// Returns true iff a string was removed.
    #[inline]
    pub fn pop(&mut self) -> bool {
        let popped = self.ends.pop().is_some();
        if let Some(&offset) = self.ends.last() {
            self.data.truncate(offset);
        }
        popped
    }

    /// Clear the stack.
    #[inline]
    pub fn clear(&mut self) {
        self.ends.clear();
        self.data.clear();
    }

    /// Returns the number of strings on the stack.
    #[inline]
    pub fn len(&self) -> usize {
        self.ends.len()
    }

    /// Truncate the stack to `len` strings.
    #[inline]
    pub fn truncate(&mut self, len: usize) {
        self.ends.truncate(len);
        self.data.truncate(*self.ends.last().unwrap_or(&0));
    }

    /// Read from `source` into the string stack.
    ///
    /// Returns the index of the new string or an IO Error.
    pub fn consume<R: io::Read>(&mut self, mut source: R) -> io::Result<usize> {
        match source.read_to_string(&mut self.data) {
            Ok(_) => {
                let idx = self.len();
                self.ends.push(self.data.len());
                Ok(idx)
            },
            Err(e) => Err(e),
        }
    }

    /// Returns a writer helper for this string stack.
    ///
    /// This is useful for building a string in-place on the string-stack.
    ///
    /// Example:
    ///
    /// ```
    /// use std::fmt::Write;
    /// use str_stack::StrStack;
    ///
    /// let mut s = StrStack::new();
    /// let index = {
    ///     let mut writer = s.writer();
    ///     writer.write_str("Hello");
    ///     writer.write_char(' ');
    ///     writer.write_str("World");
    ///     writer.write_char('!');
    ///     writer.finish()
    /// };
    /// assert_eq!(&s[index], "Hello World!");
    /// ```
    #[inline]
    pub fn writer(&mut self) -> Writer {
        Writer(self)
    }

    /// Allows calling the write! macro directly on the string stack:
    ///
    /// Example:
    ///
    /// ```
    /// use std::fmt::Write;
    /// use str_stack::StrStack;
    ///
    /// let mut s = StrStack::new();
    /// let index = write!(&mut s, "Hello {}!", "World");
    /// assert_eq!(&s[index], "Hello World!");
    /// ```
    #[inline]
    pub fn write_fmt(&mut self, args: fmt::Arguments) -> usize {
        let mut writer = self.writer();
        let _ = writer.write_fmt(args);
        writer.finish()
    }
}

pub struct Writer<'a>(&'a mut StrStack);

impl<'a> Writer<'a> {
    /// Finish pushing the string onto the stack and return its index.
    #[inline]
    pub fn finish(self) -> usize {
        // We push on drop.
        self.0.len()
    }
}
impl<'a> fmt::Write for Writer<'a> {
    #[inline]
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.0.data.push_str(s);
        Ok(())
    }
    #[inline]
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.0.data.push(c);
        Ok(())
    }
}

impl<'a> Drop for Writer<'a> {
    fn drop(&mut self) {
        self.0.ends.push(self.0.data.len());
    }
}

#[test]
fn test_basic() {
    let mut stack = StrStack::new();
    let first = stack.push("one");
    let second = stack.push("two");
    let third = stack.push("three");

    assert_eq!(&stack[first], "one");
    assert_eq!(&stack[second], "two");
    assert_eq!(&stack[third], "three");

    assert_eq!(stack.len(), 3);

    assert!(stack.pop());

    assert_eq!(stack.len(), 2);

    assert_eq!(&stack[first], "one");
    assert_eq!(&stack[second], "two");

    assert!(stack.pop());
    assert!(stack.pop());

    assert_eq!(stack.len(), 0);
    assert!(!stack.pop());
}

#[test]
fn test_consume() {
    let mut stack = StrStack::new();
    let idx = stack.consume("testing".as_bytes()).unwrap();
    assert_eq!(&stack[idx], "testing");
}

#[test]
fn test_writer() {
    let mut stack = StrStack::new();
    let first = {
        let mut w = stack.writer();
        write!(w, "{}", "first ").unwrap();
        write!(w, "{}", "second").unwrap();
        w.finish()
    };

    let second = {
        let mut w = stack.writer();
        write!(w, "{}", "third ").unwrap();
        write!(w, "{}", "fourth").unwrap();
        w.finish()
    };
    assert_eq!(&stack[first], "first second");
    assert_eq!(&stack[second], "third fourth");
}
<|endoftext|>


<commit_before>extern crate pencil;
#[macro_use] extern crate hyper;
extern crate crypto;

use std::io::Read;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use crypto::mac::{Mac, MacResult};
use hyper::header::Headers;
use pencil::Request;

header! { (XGitHubEvent, "X-GitHub-Event") => [String] }
header! { (XGitHubDelivery, "X-GitHub-Delivery") => [String] }
header! { (XHubSignature, "X-Hub-Signature") => [String] }

pub type DeployResult<T> = Result<T, String>;

pub fn check_signature(request: &mut Request, signature: &XHubSignature, secret: &str) -> DeployResult<bool> {
  let (method, hash) = {
    let mut split = signature.split('=');
    let method = match split.next() {
      Some(x) => x,
      None => return Err("invalid signature".into())
    };
    let hash = match split.next() {
      Some(x) => x,
      None => return Err("invalid signature".into())
    };
    (method, hash)
  };
  if method != "sha1" {
    return Err("invalid signature method (non-sha1)".into());
  }
  let hash = try!(hex_string_to_bytes(hash));
  let mut bytes: Vec<u8> = Vec::new();
  request.read_to_end(&mut bytes);
  let result = build_sha1_hmac(secret, &bytes).result();
  let check_against = MacResult::new(&hash);
  Ok(result == check_against)
}

fn build_sha1_hmac(secret: &str, input: &[u8]) -> Hmac<Sha1> {
  let mut hmac = Hmac::new(Sha1::new(), secret.as_bytes());
  hmac.input(input);
  hmac
}

pub fn hex_string_to_bytes(hex_string: &str) -> DeployResult<Vec<u8>> {
  let char_vec = hex_string.chars().collect::<Vec<_>>();
  let chunks = char_vec.chunks(2);
  let parsed: Vec<_> = chunks
    .map(|x| u8::from_str_radix(
        x.into_iter().cloned().collect::<String>().as_str(),
        16
      )
    )
    .collect();
  if parsed.iter().any(|x| x.is_err()) {
    return Err("could not parse hex string".into());
  }
  Ok(parsed.into_iter().flat_map(|x| x).collect())
}
<commit_msg>fix: check for an error while reading request<commit_after>extern crate pencil;
#[macro_use] extern crate hyper;
extern crate crypto;

use std::io::Read;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use crypto::mac::{Mac, MacResult};
use hyper::header::Headers;
use pencil::Request;

header! { (XGitHubEvent, "X-GitHub-Event") => [String] }
header! { (XGitHubDelivery, "X-GitHub-Delivery") => [String] }
header! { (XHubSignature, "X-Hub-Signature") => [String] }

pub type DeployResult<T> = Result<T, String>;

pub fn check_signature(request: &mut Request, signature: &XHubSignature, secret: &str) -> DeployResult<bool> {
  let (method, hash) = {
    let mut split = signature.split('=');
    let method = match split.next() {
      Some(x) => x,
      None => return Err("invalid signature".into())
    };
    let hash = match split.next() {
      Some(x) => x,
      None => return Err("invalid signature".into())
    };
    (method, hash)
  };
  if method != "sha1" {
    return Err("invalid signature method (non-sha1)".into());
  }
  let hash = try!(hex_string_to_bytes(hash));
  let mut bytes: Vec<u8> = Vec::new();
  match request.read_to_end(&mut bytes) {
    Ok(_) => {},
    Err(e) => {
      return Err(format!("could not read request: {}", e));
    }
  }
  let result = build_sha1_hmac(secret, &bytes).result();
  let check_against = MacResult::new(&hash);
  Ok(result == check_against)
}

fn build_sha1_hmac(secret: &str, input: &[u8]) -> Hmac<Sha1> {
  let mut hmac = Hmac::new(Sha1::new(), secret.as_bytes());
  hmac.input(input);
  hmac
}

pub fn hex_string_to_bytes(hex_string: &str) -> DeployResult<Vec<u8>> {
  let char_vec = hex_string.chars().collect::<Vec<_>>();
  let chunks = char_vec.chunks(2);
  let parsed: Vec<_> = chunks
    .map(|x| u8::from_str_radix(
        x.into_iter().cloned().collect::<String>().as_str(),
        16
      )
    )
    .collect();
  if parsed.iter().any(|x| x.is_err()) {
    return Err("could not parse hex string".into());
  }
  Ok(parsed.into_iter().flat_map(|x| x).collect())
}
<|endoftext|>


<commit_before>mod request;
mod service;
mod application;
mod user;
mod apicall;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>lib: make modules public<commit_after>pub mod request;
pub mod service;
pub mod application;
pub mod user;
pub mod apicall;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>extern crate bit_vec;
extern crate num;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate nock;

use std::rc::Rc;
use std::collections::HashMap;
use bit_vec::BitVec;
use num::bigint::BigUint;
use num::traits::{One, ToPrimitive};
use nock::Noun;

pub use ream::ream;
pub use twig::Twig;

mod twig;
mod ream;

/// Unpack the data of an Urbit pillfile into a Nock noun.
pub fn unpack_pill(mut buf: Vec<u8>) -> Result<nock::Noun, &'static str> {
    // Guarantee that the buffer is made of 32-bit chunks.
    while buf.len() % 4 != 0 {
        buf.push(0);
    }

    // Reverse bits of each byte to be little-endian all the way.
    for i in 0..buf.len() {
        let b = &mut buf[i];
        *b = (*b & 0xF0) >> 4 | (*b & 0x0F) << 4;
        *b = (*b & 0xCC) >> 2 | (*b & 0x33) << 2;
        *b = (*b & 0xAA) >> 1 | (*b & 0x55) << 1;
    }

    let bits = BitVec::from_bytes(&buf);

    let (noun, _size) = try!(cue(&bits));
    Ok(noun)
}

/// Decode a lenght-encoded atom from a bit stream.
fn rub(bits: &BitVec, pos: usize) -> (usize, BigUint) {
    // Length of the prefix in bits is the count of initial zeroes before
    // the separator 1.

    let mut p = 0;

    // Assume the first bit is zero even if it isn't.
    let mut k = 1;
    p += 1;

    while !bits[pos + p] {
        k += 1;
        p += 1;
    }
    p += 1;

    // Read the prefix.
    let mut b = 0;
    if k > 1 {
        for i in 0..(k - 2) {
            if bits[pos + p] {
                b += 1 << i;
            }
            p += 1;
        }
        // Add the implicit top 1 to the prefix.
        b += 1 << (k - 2);
    }

    let mut q: BigUint = Default::default();
    for i in 0..b {
        if bits[pos + p] {
            q = q + (BigUint::one() << i);
        }
        p += 1;
    }
    (p, q)
}

/// Decode an encoded cell from a bit stream.
///
/// Return the Nock noun and the count of atoms in it.
fn cue(bits: &BitVec) -> Result<(Noun, u64), &'static str> {
    let (_, noun, size) = try!(parse(0, bits, &mut HashMap::new()));
    return Ok(((*noun.clone()).clone(), size));

    fn parse(mut pos: usize,
             bits: &BitVec,
             dict: &mut HashMap<usize, (Rc<Noun>, u64)>)
             -> Result<(usize, Rc<Noun>, u64), &'static str> {
        let key = pos;
        if bits[pos] {
            pos += 1;
            if !bits[pos] {
                // 10: encode a pair.
                pos += 1;
                let (p, left, s1) = try!(parse(pos, bits, dict));
                pos = p;
                let (p, right, s2) = try!(parse(pos, bits, dict));
                pos = p;

                let ret = Rc::new(Noun::Cell(left, right));
                let size = s1 + s2;
                dict.insert(key, (ret.clone(), size));
                Ok((pos, ret, size))
            } else {
                // 11: Repeat element
                // Read the index in bitstream where the value was first
                // encountered.
                let (p, q) = rub(&bits, pos);
                pos += p;
                let key = q.to_usize().unwrap();
                if let Some(ref x) = dict.get(&key) {
                    let (noun, size) = (x.0.clone(), x.1);
                    Ok((pos, noun, size))
                } else {
                    Err("Bad cell index")
                }
            }
        } else {
            // Atom.
            let (p, q) = rub(&bits, pos);
            pos += p;
            let ret = Rc::new(Noun::from_biguint(q));
            dict.insert(key, (ret.clone(), 1));
            Ok((pos, ret, 1))
        }
    }
}

#[cfg(test)]
mod test {
    use nock::Noun;
    use super::unpack_pill;

    #[test]
    fn test_read_pill() {
        let noun: Noun = "[18.446.744.073.709.551.616 8 [1 0] 8 [1 6 [5 [0 7] 4 0 6] [0 6] 9 2 [0 \
                          2] [4 0 6] 0 7] 9 2 0 1]"
                             .parse()
                             .expect("Nock parse error");
        let pill: &[u8] = &[0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
                            0xc1, 0x62, 0x83, 0x60, 0x71, 0xd8, 0x85, 0x5b, 0xe2, 0x87, 0x99,
                            0xd8, 0x0d, 0xc1, 0x1a, 0x24, 0x43, 0x96, 0xc8, 0x86, 0x10, 0x1d,
                            0xc2, 0x32, 0x48, 0x86, 0x4c, 0x06];
        let unpacked = unpack_pill(pill.to_vec()).expect("Pill unpack failed");
        assert_eq!(noun, unpacked);
    }
}
<commit_msg>Don't count pill atoms, overflows even u64<commit_after>extern crate bit_vec;
extern crate num;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate nock;

use std::rc::Rc;
use std::collections::HashMap;
use bit_vec::BitVec;
use num::bigint::BigUint;
use num::traits::{One, ToPrimitive};
use nock::Noun;

pub use ream::ream;
pub use twig::Twig;

mod twig;
mod ream;

/// Unpack the data of an Urbit pillfile into a Nock noun.
pub fn unpack_pill(mut buf: Vec<u8>) -> Result<Noun, &'static str> {
    // Guarantee that the buffer is made of 32-bit chunks.
    while buf.len() % 4 != 0 {
        buf.push(0);
    }

    // Reverse bits of each byte to be little-endian all the way.
    for i in 0..buf.len() {
        let b = &mut buf[i];
        *b = (*b & 0xF0) >> 4 | (*b & 0x0F) << 4;
        *b = (*b & 0xCC) >> 2 | (*b & 0x33) << 2;
        *b = (*b & 0xAA) >> 1 | (*b & 0x55) << 1;
    }

    let bits = BitVec::from_bytes(&buf);

    cue(&bits)
}

/// Decode a lenght-encoded atom from a bit stream.
fn rub(bits: &BitVec, pos: usize) -> (usize, BigUint) {
    // Length of the prefix in bits is the count of initial zeroes before
    // the separator 1.

    let mut p = 0;

    // Assume the first bit is zero even if it isn't.
    let mut k = 1;
    p += 1;

    while !bits[pos + p] {
        k += 1;
        p += 1;
    }
    p += 1;

    // Read the prefix.
    let mut b = 0;
    if k > 1 {
        for i in 0..(k - 2) {
            if bits[pos + p] {
                b += 1 << i;
            }
            p += 1;
        }
        // Add the implicit top 1 to the prefix.
        b += 1 << (k - 2);
    }

    let mut q: BigUint = Default::default();
    for i in 0..b {
        if bits[pos + p] {
            q = q + (BigUint::one() << i);
        }
        p += 1;
    }
    (p, q)
}

/// Decode an encoded cell from a bit stream.
///
/// Return the Nock noun.
fn cue(bits: &BitVec) -> Result<Noun, &'static str> {
    let (_, noun) = try!(parse(0, bits, &mut HashMap::new()));
    return Ok((*noun.clone()).clone());

    fn parse(mut pos: usize,
             bits: &BitVec,
             dict: &mut HashMap<usize, Rc<Noun>>)
             -> Result<(usize, Rc<Noun>), &'static str> {
        let key = pos;
        if bits[pos] {
            pos += 1;
            if !bits[pos] {
                // 10: encode a pair.
                pos += 1;
                let (p, left) = try!(parse(pos, bits, dict));
                pos = p;
                let (p, right) = try!(parse(pos, bits, dict));
                pos = p;

                let ret = Rc::new(Noun::Cell(left, right));
                dict.insert(key, ret.clone());
                Ok((pos, ret))
            } else {
                // 11: Repeat element
                // Read the index in bitstream where the value was first
                // encountered.
                let (p, q) = rub(&bits, pos);
                pos += p;
                let key = q.to_usize().unwrap();
                if let Some(x) = dict.get(&key) {
                    Ok((pos, x.clone()))
                } else {
                    Err("Bad cell index")
                }
            }
        } else {
            // Atom.
            let (p, q) = rub(&bits, pos);
            pos += p;
            let ret = Rc::new(Noun::from_biguint(q));
            dict.insert(key, ret.clone());
            Ok((pos, ret))
        }
    }
}

#[cfg(test)]
mod test {
    use nock::Noun;
    use super::unpack_pill;

    #[test]
    fn test_read_pill() {
        let noun: Noun = "[18.446.744.073.709.551.616 8 [1 0] 8 [1 6 [5 [0 7] 4 0 6] [0 6] 9 2 [0 \
                          2] [4 0 6] 0 7] 9 2 0 1]"
                             .parse()
                             .expect("Nock parse error");
        let pill: &[u8] = &[0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
                            0xc1, 0x62, 0x83, 0x60, 0x71, 0xd8, 0x85, 0x5b, 0xe2, 0x87, 0x99,
                            0xd8, 0x0d, 0xc1, 0x1a, 0x24, 0x43, 0x96, 0xc8, 0x86, 0x10, 0x1d,
                            0xc2, 0x32, 0x48, 0x86, 0x4c, 0x06];
        let unpacked = unpack_pill(pill.to_vec()).expect("Pill unpack failed");
        assert_eq!(noun, unpacked);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! # GTK+ 3 bindings
//!
//! This library contains safe Rust bindings for [GTK+ 3](http://www.gtk.org), a
//! multi-platform GUI toolkit. It's a part of [Gtk-rs](http://gtk-rs.org/).
//!
//! The library is a work in progress: expect missing bindings and breaking
//! changes. A steadily increasing share of the code is machine-generated from
//! GObject introspection metadata. The API docs were converted from the
//! upstream ones so until they've all been reviewed there will be incongruities
//! with actual Rust APIs.
//!
//! See also:
//!
//! - [Gtk-rs documentation overview](http://gtk-rs.org/docs/)
//!
//! - [General GLib family types and object system overview](../glib/index.html)
//!
//! - [GTK+ documentation](http://www.gtk.org/documentation.php)
//!
//! # Hello World
//!
//! ```no_run
//! extern crate gtk;
//! use gtk::prelude::*;
//! use gtk::{ButtonsType, DialogFlags, MessageType, MessageDialog, Window};
//!
//! fn main() {
//!     if gtk::init().is_err() {
//!         println!("Failed to initialize GTK.");
//!         return;
//!     }
//!     MessageDialog::new(None::<&Window>,
//!                        DialogFlags::empty(),
//!                        MessageType::Info,
//!                        ButtonsType::Ok,
//!                        "Hello World").run();
//! }
//! ```
//!
//! # Initialization
//!
//! GTK+ needs to be initialized before use by calling [`init`](fn.init.html) or
//! [`Application::new`](struct.Application.html#method.new). You only need to
//! do it once and there is no 'finalize'.
//!
//! # The main loop
//!
//! In a typical GTK+ application you set up the UI, assign signal handlers
//! and run the main event loop:
//!
//! ```no_run
//! # extern crate gtk;
//! # use gtk::prelude::*;
//! # use gtk::{Window, WindowType};
//! fn main() {
//!     gtk::init().unwrap();
//!     // Create the main window.
//!     let window = Window::new(WindowType::Toplevel);
//!     // UI initialization.
//!     // ...
//!     // Don't forget to make all widgets visible.
//!     window.show_all();
//!     // Handle closing of the window.
//!     window.connect_delete_event(|_, _| {
//!         // Stop the main loop.
//!         gtk::main_quit();
//!         // Let the default handler destroy the window.
//!         Inhibit(false)
//!     });
//!     // Run the main loop.
//!     gtk::main();
//! }
//! ```
//!
//! # Threads
//!
//! GTK+ is not thread-safe. Accordingly, none of this crate's structs implement
//! `Send` or `Sync`.
//!
//! The thread where `init` was called is considered the main thread. OS X has
//! its own notion of the main thread and `init` must be called on that thread.
//! After successful initialization, calling any `gtk` or `gdk` functions
//! (including `init`) from other threads will `panic`.
//!
//! Any thread can schedule a closure to be run by the main loop on the main
//! thread via [`glib::idle_add`](../glib/source/fn.idle_add.html) or
//! [`glib::timeout_add`](../glib/source/fn.timeout_add.html). This crate has
//! versions of those functions without the `Send` bound, which may only be
//! called from the main thread: [`idle_add`](fn.idle_add.html),
//! [`timeout_add`](fn.timeout_add.html).
//!
//! # Panics
//!
//! This and the `gdk` crate have some run-time safety and contract checks:
//!
//! - Any constructor or free function will panic if called before `init` or on
//! a non-main thread.
//!
//! - Any `&str` or `&Path` parameter with an interior null (`\0`) character will
//! cause a panic.
//!
//! - Some functions will panic if supplied out-of-range integer parameters. All
//! such cases will be documented individually but they're not yet.
//!
//! **A panic in a closure will abort the process.**
//!
//! # Crate features
//!
//! ## Library versions
//!
//! By default this crate provides only GTK+ 3.4 APIs. You can access more
//! modern APIs by selecting one of the following features: `v3_6`, `v3_8`,
//! `v3_10`, `v3_12`, `v3_14`, `v3_16`.
//!
//! `Cargo.toml` example:
//!
//! ```toml
//! [dependencies.gtk]
//! version = "0.x.y"
//! features = ["v3_16"]
//! ```
//!
//! **Take care when choosing the version to target: some of your users might
//! not have easy access to the latest ones.** The higher the version, the fewer
//! users will have it installed.
//!
//! ## Lgpl-docs
//!
//! The Gtk-rs crates come with API docs missing because of licensing
//! incompatibilty. You can embed those docs locally via the `embed-lgpl-docs`
//! feature, e.g.
//!
//! ```shell
//! > cargo doc --features embed-lgpl-docs
//! ```
//!
//! Its counterpart `purge-lgpl-docs` removes those docs regardless of edits.
//!
//! These features **rewrite the crate sources** so it's sufficient to enable
//! them once. **Omitting them in the following cargo invocations will not undo
//! their effects!**

extern crate libc;
#[macro_use]
extern crate bitflags;

extern crate glib_sys as glib_ffi;
extern crate gio_sys as gio_ffi;
extern crate gdk_sys as gdk_ffi;
extern crate gdk_pixbuf_sys as gdk_pixbuf_ffi;
extern crate gobject_sys as gobject_ffi;
extern crate gtk_sys as ffi;
extern crate cairo_sys as cairo_ffi;
#[macro_use]
extern crate glib;
extern crate gio;
extern crate gdk;
extern crate gdk_pixbuf;
extern crate cairo;
extern crate pango;

pub use glib::{
    Cast,
    Continue,
    Error,
    IsA,
    Object,
    StaticType,
    ToValue,
    Type,
    TypedValue,
    Value,
};

pub const STYLE_PROVIDER_PRIORITY_FALLBACK: i32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_FALLBACK;
pub const STYLE_PROVIDER_PRIORITY_THEME: i32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_THEME;
pub const STYLE_PROVIDER_PRIORITY_SETTINGS: i32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_SETTINGS;
pub const STYLE_PROVIDER_PRIORITY_APPLICATION: i32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_APPLICATION;
pub const STYLE_PROVIDER_PRIORITY_USER: i32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_USER;

#[macro_use]
mod rt;

mod auto;

mod app_chooser;
mod application;
mod builder;
mod clipboard;
mod color_button;
mod color_chooser;
mod dialog;
mod entry_buffer;
mod enums;
mod file_chooser_dialog;
mod list_store;
mod message_dialog;
mod notebook;
mod recent_chooser_dialog;
mod recent_data;
mod recent_info;
mod rectangle;
mod requisition;
mod signal;
#[cfg(target_os = "linux")]
mod socket;
mod text_attributes;
mod text_buffer;
mod text_iter;
mod tree_model_filter;
mod tree_sortable;
mod tree_path;
mod tree_store;
mod widget;

pub mod prelude;

pub use auto::*;
pub use rt::*;
pub use signal::*;

pub use rectangle::Rectangle as Allocation;
pub use app_chooser::AppChooser;
pub use builder::Builder;
pub use color_chooser::ColorChooser;
pub use entry_buffer::EntryBuffer;
pub use recent_data::RecentData;
pub use recent_info::RecentInfo;
pub use rectangle::Rectangle;
pub use requisition::Requisition;
#[cfg(target_os = "linux")]
pub use socket::Socket;
pub use text_attributes::TextAttributes;
pub use tree_sortable::SortColumn;
<commit_msg>Make STYLE_PROVIDER_PRIORITY_* values u32.<commit_after>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! # GTK+ 3 bindings
//!
//! This library contains safe Rust bindings for [GTK+ 3](http://www.gtk.org), a
//! multi-platform GUI toolkit. It's a part of [Gtk-rs](http://gtk-rs.org/).
//!
//! The library is a work in progress: expect missing bindings and breaking
//! changes. A steadily increasing share of the code is machine-generated from
//! GObject introspection metadata. The API docs were converted from the
//! upstream ones so until they've all been reviewed there will be incongruities
//! with actual Rust APIs.
//!
//! See also:
//!
//! - [Gtk-rs documentation overview](http://gtk-rs.org/docs/)
//!
//! - [General GLib family types and object system overview](../glib/index.html)
//!
//! - [GTK+ documentation](http://www.gtk.org/documentation.php)
//!
//! # Hello World
//!
//! ```no_run
//! extern crate gtk;
//! use gtk::prelude::*;
//! use gtk::{ButtonsType, DialogFlags, MessageType, MessageDialog, Window};
//!
//! fn main() {
//!     if gtk::init().is_err() {
//!         println!("Failed to initialize GTK.");
//!         return;
//!     }
//!     MessageDialog::new(None::<&Window>,
//!                        DialogFlags::empty(),
//!                        MessageType::Info,
//!                        ButtonsType::Ok,
//!                        "Hello World").run();
//! }
//! ```
//!
//! # Initialization
//!
//! GTK+ needs to be initialized before use by calling [`init`](fn.init.html) or
//! [`Application::new`](struct.Application.html#method.new). You only need to
//! do it once and there is no 'finalize'.
//!
//! # The main loop
//!
//! In a typical GTK+ application you set up the UI, assign signal handlers
//! and run the main event loop:
//!
//! ```no_run
//! # extern crate gtk;
//! # use gtk::prelude::*;
//! # use gtk::{Window, WindowType};
//! fn main() {
//!     gtk::init().unwrap();
//!     // Create the main window.
//!     let window = Window::new(WindowType::Toplevel);
//!     // UI initialization.
//!     // ...
//!     // Don't forget to make all widgets visible.
//!     window.show_all();
//!     // Handle closing of the window.
//!     window.connect_delete_event(|_, _| {
//!         // Stop the main loop.
//!         gtk::main_quit();
//!         // Let the default handler destroy the window.
//!         Inhibit(false)
//!     });
//!     // Run the main loop.
//!     gtk::main();
//! }
//! ```
//!
//! # Threads
//!
//! GTK+ is not thread-safe. Accordingly, none of this crate's structs implement
//! `Send` or `Sync`.
//!
//! The thread where `init` was called is considered the main thread. OS X has
//! its own notion of the main thread and `init` must be called on that thread.
//! After successful initialization, calling any `gtk` or `gdk` functions
//! (including `init`) from other threads will `panic`.
//!
//! Any thread can schedule a closure to be run by the main loop on the main
//! thread via [`glib::idle_add`](../glib/source/fn.idle_add.html) or
//! [`glib::timeout_add`](../glib/source/fn.timeout_add.html). This crate has
//! versions of those functions without the `Send` bound, which may only be
//! called from the main thread: [`idle_add`](fn.idle_add.html),
//! [`timeout_add`](fn.timeout_add.html).
//!
//! # Panics
//!
//! This and the `gdk` crate have some run-time safety and contract checks:
//!
//! - Any constructor or free function will panic if called before `init` or on
//! a non-main thread.
//!
//! - Any `&str` or `&Path` parameter with an interior null (`\0`) character will
//! cause a panic.
//!
//! - Some functions will panic if supplied out-of-range integer parameters. All
//! such cases will be documented individually but they're not yet.
//!
//! **A panic in a closure will abort the process.**
//!
//! # Crate features
//!
//! ## Library versions
//!
//! By default this crate provides only GTK+ 3.4 APIs. You can access more
//! modern APIs by selecting one of the following features: `v3_6`, `v3_8`,
//! `v3_10`, `v3_12`, `v3_14`, `v3_16`.
//!
//! `Cargo.toml` example:
//!
//! ```toml
//! [dependencies.gtk]
//! version = "0.x.y"
//! features = ["v3_16"]
//! ```
//!
//! **Take care when choosing the version to target: some of your users might
//! not have easy access to the latest ones.** The higher the version, the fewer
//! users will have it installed.
//!
//! ## Lgpl-docs
//!
//! The Gtk-rs crates come with API docs missing because of licensing
//! incompatibilty. You can embed those docs locally via the `embed-lgpl-docs`
//! feature, e.g.
//!
//! ```shell
//! > cargo doc --features embed-lgpl-docs
//! ```
//!
//! Its counterpart `purge-lgpl-docs` removes those docs regardless of edits.
//!
//! These features **rewrite the crate sources** so it's sufficient to enable
//! them once. **Omitting them in the following cargo invocations will not undo
//! their effects!**

extern crate libc;
#[macro_use]
extern crate bitflags;

extern crate glib_sys as glib_ffi;
extern crate gio_sys as gio_ffi;
extern crate gdk_sys as gdk_ffi;
extern crate gdk_pixbuf_sys as gdk_pixbuf_ffi;
extern crate gobject_sys as gobject_ffi;
extern crate gtk_sys as ffi;
extern crate cairo_sys as cairo_ffi;
#[macro_use]
extern crate glib;
extern crate gio;
extern crate gdk;
extern crate gdk_pixbuf;
extern crate cairo;
extern crate pango;

pub use glib::{
    Cast,
    Continue,
    Error,
    IsA,
    Object,
    StaticType,
    ToValue,
    Type,
    TypedValue,
    Value,
};

pub const STYLE_PROVIDER_PRIORITY_FALLBACK: u32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_FALLBACK as u32;
pub const STYLE_PROVIDER_PRIORITY_THEME: u32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_THEME as u32;
pub const STYLE_PROVIDER_PRIORITY_SETTINGS: u32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_SETTINGS as u32;
pub const STYLE_PROVIDER_PRIORITY_APPLICATION: u32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_APPLICATION as u32;
pub const STYLE_PROVIDER_PRIORITY_USER: u32 = ffi::GTK_STYLE_PROVIDER_PRIORITY_USER as u32;

#[macro_use]
mod rt;

mod auto;

mod app_chooser;
mod application;
mod builder;
mod clipboard;
mod color_button;
mod color_chooser;
mod dialog;
mod entry_buffer;
mod enums;
mod file_chooser_dialog;
mod list_store;
mod message_dialog;
mod notebook;
mod recent_chooser_dialog;
mod recent_data;
mod recent_info;
mod rectangle;
mod requisition;
mod signal;
#[cfg(target_os = "linux")]
mod socket;
mod text_attributes;
mod text_buffer;
mod text_iter;
mod tree_model_filter;
mod tree_sortable;
mod tree_path;
mod tree_store;
mod widget;

pub mod prelude;

pub use auto::*;
pub use rt::*;
pub use signal::*;

pub use rectangle::Rectangle as Allocation;
pub use app_chooser::AppChooser;
pub use builder::Builder;
pub use color_chooser::ColorChooser;
pub use entry_buffer::EntryBuffer;
pub use recent_data::RecentData;
pub use recent_info::RecentInfo;
pub use rectangle::Rectangle;
pub use requisition::Requisition;
#[cfg(target_os = "linux")]
pub use socket::Socket;
pub use text_attributes::TextAttributes;
pub use tree_sortable::SortColumn;
<|endoftext|>