<commit_before>extern crate time;

use std::iter::Iterator;

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

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

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("Have seen {} items and been iterating for {}", self.num_done(), self.iterating_for.num_seconds())
    }

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

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

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

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

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

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

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

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

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

}

pub struct ProgressRecorderIter<I> {
    iter: I,
    count: usize,
    started_iterating: Tm,
}

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

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

}

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

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

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

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

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

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

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

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

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 1 items and been iterating for 0");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 2 items and been iterating for 1");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 3 items and been iterating for 1");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 4 items and been iterating for 2");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
    }

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

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

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

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

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

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

    }
}

<commit_msg>docs: Add docs<commit_after>extern crate time;

use std::iter::Iterator;

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

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

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("Have seen {} items and been iterating for {}", self.num_done(), self.iterating_for.num_seconds())
    }

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

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

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

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

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

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

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

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

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

}

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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 1 items and been iterating for 0");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 2 items and been iterating for 1");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 3 items and been iterating for 1");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "Have seen 4 items and been iterating for 2");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
    }

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

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

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

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

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

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

    }
}

<|endoftext|>


<commit_before>//! This library's goal is to offer a highly available IRC client with an easy to use API.
//! Automatic reconnection is built into the design. It uses a channel-like design, where
//! events are received from a `Reader` and commands are sent from one or many `Writer`.
//!
//! The `Writer` are thread safe and can be cheaply cloned.
//!
//! Here's a canonical example.
//!
//! ```no_run
//! // connect to freenode and use the default reconnection settings.
//! use loirc::{connect, Code, Event};
//!
//! let (writer, reader) = connect("irc.freenode.net:6667", None).unwrap();
//! writer.user("username", "realname");
//! writer.nick("nickname");
//! // Block until something happens.
//! for event in reader.iter() {
//!     match event {
//!         // Handle messages
//!        Event::Message(msg) => {
//!             if msg.code == Code::RplWelcome {
//!                 writer.join("#channel", None);
//!             }
//!         }
//!         // Handle other events, such as disconnects.
//!         _ => {}
//!     }
//! }
//! ```
extern crate time;

mod activity_monitor;
mod code;
mod connection;
mod message;

pub use time::Duration;

pub use activity_monitor::{ActivityMonitor, MonitorSettings};
pub use connection::{connect, Event, Error, Reader, ReconnectionSettings, Writer};
pub use code::Code;
pub use message::{ParseError, Message, Prefix, User};
<commit_msg>Fix documentation example<commit_after>//! This library's goal is to offer a highly available IRC client with an easy to use API.
//! Automatic reconnection is built into the design. It uses a channel-like design, where
//! events are received from a `Reader` and commands are sent from one or many `Writer`.
//!
//! The `Writer` are thread safe and can be cheaply cloned.
//!
//! Here's a canonical example.
//!
//! ```no_run
//! use loirc::{connect, Code, Event};
//!
//! // connect to freenode and use the default reconnection settings.
//! let (writer, reader) = connect("irc.freenode.net:6667", None).unwrap();
//! writer.user("username", "realname");
//! writer.nick("nickname");
//! // Block until something happens.
//! for event in reader.iter() {
//!     match event {
//!         // Handle messages
//!        Event::Message(msg) => {
//!             if msg.code == Code::RplWelcome {
//!                 writer.join("#channel", None);
//!             }
//!         }
//!         // Handle other events, such as disconnects.
//!         _ => {}
//!     }
//! }
//! ```
extern crate time;

mod activity_monitor;
mod code;
mod connection;
mod message;

pub use time::Duration;

pub use activity_monitor::{ActivityMonitor, MonitorSettings};
pub use connection::{connect, Event, Error, Reader, ReconnectionSettings, Writer};
pub use code::Code;
pub use message::{ParseError, Message, Prefix, User};
<|endoftext|>


<commit_before>#[macro_use]
extern crate bitflags;

mod arguments;
mod connection;
mod error;
mod interface;
mod message;
mod object;
mod runner;
mod server;
mod target;
mod value;

pub use connection::Connection;
pub use connection::ReleaseNameReply;
pub use connection::RequestNameFlags;
pub use connection::{ALLOW_REPLACEMENT, REPLACE_EXISTING, DO_NOT_QUEUE};
pub use connection::RequestNameReply;
pub use error::Error;
pub use interface::Annotation;
pub use interface::Argument;
pub use interface::Interface;
pub use interface::Interfaces;
pub use interface::Method;
pub use interface::MethodHandler;
pub use interface::MethodResult;
pub use interface::Property;
pub use interface::PropertyReadHandler;
pub use interface::PropertyReadWriteHandler;
pub use interface::PropertyWriteHandler;
pub use interface::Signal;
pub use message::Message;
pub use message::MessageType;
pub use object::Object;
pub use runner::Runner;
pub use server::Server;
pub use server::SignalHandler;
pub use target::Target;
pub use value::Value;
<commit_msg>lib: export missing types<commit_after>#[macro_use]
extern crate bitflags;

mod arguments;
mod connection;
mod error;
mod interface;
mod message;
mod object;
mod runner;
mod server;
mod target;
mod value;

pub use connection::Connection;
pub use connection::ReleaseNameReply;
pub use connection::RequestNameFlags;
pub use connection::{ALLOW_REPLACEMENT, REPLACE_EXISTING, DO_NOT_QUEUE};
pub use connection::RequestNameReply;
pub use error::Error;
pub use interface::Annotation;
pub use interface::Argument;
pub use interface::ChildrenList;
pub use interface::ErrorMessage;
pub use interface::Interface;
pub use interface::Interfaces;
pub use interface::Method;
pub use interface::MethodHandler;
pub use interface::MethodResult;
pub use interface::Property;
pub use interface::PropertyReadHandler;
pub use interface::PropertyReadWriteHandler;
pub use interface::PropertyWriteHandler;
pub use interface::Signal;
pub use message::Message;
pub use message::MessageType;
pub use object::Object;
pub use runner::Runner;
pub use server::Server;
pub use server::SignalHandler;
pub use target::Target;
pub use value::Value;
<|endoftext|>


<commit_before>//! Bindings for serial port I/O and futures
//!
//! This crate provides bindings between `mio_serial`, a mio crate for
//! serial port I/O, and `futures`.  The API is very similar to the
//! bindings in `mio_serial`
//!
#![deny(missing_docs)]

extern crate bytes;
extern crate futures;
extern crate tokio;

extern crate mio_serial;

// Re-export serialport types and traits from mio_serial
pub use mio_serial::{BaudRate, DataBits, Error, ErrorKind, FlowControl, Parity, SerialPort,
                     SerialPortSettings, StopBits};

/// A type for results generated by interacting with serial ports.
pub type Result<T> = mio_serial::Result<T>;

use futures::{Async, Poll};
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::reactor::PollEvented2;

use std::io::{self, Read, Write};
use std::path::Path;
use std::time::Duration;

/// Serial port I/O struct.
pub struct Serial {
    io: PollEvented2<mio_serial::Serial>,
}

impl Serial {
    /// Open serial port from a provided path.
    pub fn from_path<P>(path: P, settings: &mio_serial::SerialPortSettings) -> io::Result<Serial>
    where
        P: AsRef<Path>,
    {
        let port = mio_serial::Serial::from_path(path.as_ref(), settings)?;
        let io = PollEvented2::new(port);

        Ok(Serial { io })
    }

    /// Test whether this serial port is ready to be read or not.
    ///
    /// If the serial port is *not* readable then the current task is scheduled to
    /// get a notification when the socket does become readable. That is, this
    /// is only suitable for calling in a `Future::poll` method and will
    /// automatically handle ensuring a retry once the socket is readable again.
    pub fn poll_read(&mut self, buf: &mut [u8]) -> ::Result<Async<usize>> {
        Ok(self.io.poll_read(buf)?)
    }

    /// Test whether this socket is ready to be written to or not.
    ///
    /// If the socket is *not* writable then the current task is scheduled to
    /// get a notification when the socket does become writable. That is, this
    /// is only suitable for calling in a `Future::poll` method and will
    /// automatically handle ensuring a retry once the socket is writable again.
    pub fn poll_write(&mut self, buf: &mut [u8]) -> ::Result<Async<usize>> {
        Ok(self.io.poll_write(buf)?)
    }

    /// Create a pair of pseudo serial terminals
    ///
    /// ## Returns
    /// Two connected, unnamed `Serial` objects.
    ///
    /// ## Errors
    /// Attempting any IO or parameter settings on the slave tty after the master
    /// tty is closed will return errors.
    ///
    #[cfg(unix)]
    pub fn pair() -> ::Result<(Self, Self)> {
        let (master, slave) = mio_serial::Serial::pair()?;

        let master = Serial {
            io: PollEvented2::new(master),
        };
        let slave = Serial {
            io: PollEvented2::new(slave),
        };
        Ok((master, slave))
    }

    /// Sets the exclusivity of the port
    ///
    /// If a port is exclusive, then trying to open the same device path again
    /// will fail.
    ///
    /// See the man pages for the tiocexcl and tiocnxcl ioctl's for more details.
    ///
    /// ## Errors
    ///
    /// * `Io` for any error while setting exclusivity for the port.
    #[cfg(unix)]
    pub fn set_exclusive(&mut self, exclusive: bool) -> ::Result<()> {
        self.io.get_mut().set_exclusive(exclusive)
    }

    /// Returns the exclusivity of the port
    ///
    /// If a port is exclusive, then trying to open the same device path again
    /// will fail.
    #[cfg(unix)]
    pub fn exclusive(&self) -> bool {
        self.io.get_ref().exclusive()
    }
}

impl ::SerialPort for Serial {
    fn settings(&self) -> ::SerialPortSettings {
        self.io.get_ref().settings()
    }

    fn port_name(&self) -> Option<String> {
        self.io.get_ref().port_name()
    }

    fn baud_rate(&self) -> Option<::BaudRate> {
        self.io.get_ref().baud_rate()
    }

    fn data_bits(&self) -> Option<::DataBits> {
        self.io.get_ref().data_bits()
    }

    fn flow_control(&self) -> Option<::FlowControl> {
        self.io.get_ref().flow_control()
    }

    fn parity(&self) -> Option<::Parity> {
        self.io.get_ref().parity()
    }

    fn stop_bits(&self) -> Option<::StopBits> {
        self.io.get_ref().stop_bits()
    }

    fn timeout(&self) -> Duration {
        Duration::from_secs(0)
    }

    fn set_all(&mut self, settings: &::SerialPortSettings) -> ::Result<()> {
        self.io.get_mut().set_all(settings)
    }

    fn set_baud_rate(&mut self, baud_rate: ::BaudRate) -> ::Result<()> {
        self.io.get_mut().set_baud_rate(baud_rate)
    }

    fn set_data_bits(&mut self, data_bits: ::DataBits) -> ::Result<()> {
        self.io.get_mut().set_data_bits(data_bits)
    }

    fn set_flow_control(&mut self, flow_control: ::FlowControl) -> ::Result<()> {
        self.io.get_mut().set_flow_control(flow_control)
    }

    fn set_parity(&mut self, parity: ::Parity) -> ::Result<()> {
        self.io.get_mut().set_parity(parity)
    }

    fn set_stop_bits(&mut self, stop_bits: ::StopBits) -> ::Result<()> {
        self.io.get_mut().set_stop_bits(stop_bits)
    }

    fn set_timeout(&mut self, _: Duration) -> ::Result<()> {
        Ok(())
    }

    fn write_request_to_send(&mut self, level: bool) -> ::Result<()> {
        self.io.get_mut().write_request_to_send(level)
    }

    fn write_data_terminal_ready(&mut self, level: bool) -> ::Result<()> {
        self.io.get_mut().write_data_terminal_ready(level)
    }

    fn read_clear_to_send(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_clear_to_send()
    }

    fn read_data_set_ready(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_data_set_ready()
    }

    fn read_ring_indicator(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_ring_indicator()
    }

    fn read_carrier_detect(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_carrier_detect()
    }

    fn try_clone(&self) -> ::Result<Box<::SerialPort>> {
        self.io.get_ref().try_clone()
    }
}

impl Read for Serial {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.get_mut().read(buf)
    }
}

impl Write for Serial {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.get_mut().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.io.get_mut().flush()
    }
}

// impl<'a> Read for &'a Serial {
//     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
//         // (&self.io).read(buf)
//         self.io.get_mut().read(buf)
//     }
// }
//
// impl<'a> Write for &'a Serial {
//     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
//         // (&self.io).write(buf)
//         self.io.get_mut().write(buf)
//     }
//
//     fn flush(&mut self) -> io::Result<()> {
//         // (&self.io).flush()
//         self.io.get_mut().flush()
//     }
// }

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(unix)]
impl AsRawFd for Serial {
    fn as_raw_fd(&self) -> RawFd {
        self.io.get_ref().as_raw_fd()
    }
}

impl AsyncRead for Serial {}

impl AsyncWrite for Serial {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        Ok(Async::Ready(()))
    }
}
<commit_msg>Introduce with_handle variants<commit_after>//! Bindings for serial port I/O and futures
//!
//! This crate provides bindings between `mio_serial`, a mio crate for
//! serial port I/O, and `futures`.  The API is very similar to the
//! bindings in `mio_serial`
//!
#![deny(missing_docs)]

extern crate bytes;
extern crate futures;
extern crate tokio;

extern crate mio_serial;

// Re-export serialport types and traits from mio_serial
pub use mio_serial::{BaudRate, DataBits, Error, ErrorKind, FlowControl, Parity, SerialPort,
                     SerialPortSettings, StopBits};

/// A type for results generated by interacting with serial ports.
pub type Result<T> = mio_serial::Result<T>;

use futures::{Async, Poll};
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::reactor::{Handle, PollEvented2};

use std::io::{self, Read, Write};
use std::path::Path;
use std::time::Duration;

/// Serial port I/O struct.
pub struct Serial {
    io: PollEvented2<mio_serial::Serial>,
}

impl Serial {
    /// Open serial port from a provided path, using the default reactor.
    pub fn from_path<P>(path: P, settings: &mio_serial::SerialPortSettings) -> io::Result<Serial>
    where
        P: AsRef<Path>,
    {
        let port = mio_serial::Serial::from_path(path.as_ref(), settings)?;
        let io = PollEvented2::new(port);

        Ok(Serial { io })
    }

    /// Open serial port from a provided path, using the specified reactor.
    pub fn from_path_with_handle<P>(
        path: P,
        settings: &mio_serial::SerialPortSettings,
        handle: &Handle,
    ) -> io::Result<Serial>
    where
        P: AsRef<Path>,
    {
        let port = mio_serial::Serial::from_path(path.as_ref(), settings)?;
        let io = PollEvented2::new_with_handle(port, handle)?;

        Ok(Serial { io })
    }

    /// Test whether this serial port is ready to be read or not.
    ///
    /// If the serial port is *not* readable then the current task is scheduled to
    /// get a notification when the socket does become readable. That is, this
    /// is only suitable for calling in a `Future::poll` method and will
    /// automatically handle ensuring a retry once the socket is readable again.
    pub fn poll_read(&mut self, buf: &mut [u8]) -> ::Result<Async<usize>> {
        Ok(self.io.poll_read(buf)?)
    }

    /// Test whether this socket is ready to be written to or not.
    ///
    /// If the socket is *not* writable then the current task is scheduled to
    /// get a notification when the socket does become writable. That is, this
    /// is only suitable for calling in a `Future::poll` method and will
    /// automatically handle ensuring a retry once the socket is writable again.
    pub fn poll_write(&mut self, buf: &mut [u8]) -> ::Result<Async<usize>> {
        Ok(self.io.poll_write(buf)?)
    }

    /// Create a pair of pseudo serial terminals using the default reactor
    ///
    /// ## Returns
    /// Two connected, unnamed `Serial` objects.
    ///
    /// ## Errors
    /// Attempting any IO or parameter settings on the slave tty after the master
    /// tty is closed will return errors.
    ///
    #[cfg(unix)]
    pub fn pair() -> ::Result<(Self, Self)> {
        let (master, slave) = mio_serial::Serial::pair()?;

        let master = Serial {
            io: PollEvented2::new(master),
        };
        let slave = Serial {
            io: PollEvented2::new(slave),
        };
        Ok((master, slave))
    }

    /// Create a pair of pseudo serial terminals using the specified reactor.
    ///
    /// ## Returns
    /// Two connected, unnamed `Serial` objects.
    ///
    /// ## Errors
    /// Attempting any IO or parameter settings on the slave tty after the master
    /// tty is closed will return errors.
    ///
    #[cfg(unix)]
    pub fn pair_with_handle(handle: &Handle) -> ::Result<(Self, Self)> {
        let (master, slave) = mio_serial::Serial::pair()?;

        let master = Serial {
            io: PollEvented2::new_with_handle(master, handle)?,
        };
        let slave = Serial {
            io: PollEvented2::new_with_handle(slave, handle)?,
        };
        Ok((master, slave))
    }

    /// Sets the exclusivity of the port
    ///
    /// If a port is exclusive, then trying to open the same device path again
    /// will fail.
    ///
    /// See the man pages for the tiocexcl and tiocnxcl ioctl's for more details.
    ///
    /// ## Errors
    ///
    /// * `Io` for any error while setting exclusivity for the port.
    #[cfg(unix)]
    pub fn set_exclusive(&mut self, exclusive: bool) -> ::Result<()> {
        self.io.get_mut().set_exclusive(exclusive)
    }

    /// Returns the exclusivity of the port
    ///
    /// If a port is exclusive, then trying to open the same device path again
    /// will fail.
    #[cfg(unix)]
    pub fn exclusive(&self) -> bool {
        self.io.get_ref().exclusive()
    }
}

impl ::SerialPort for Serial {
    fn settings(&self) -> ::SerialPortSettings {
        self.io.get_ref().settings()
    }

    fn port_name(&self) -> Option<String> {
        self.io.get_ref().port_name()
    }

    fn baud_rate(&self) -> Option<::BaudRate> {
        self.io.get_ref().baud_rate()
    }

    fn data_bits(&self) -> Option<::DataBits> {
        self.io.get_ref().data_bits()
    }

    fn flow_control(&self) -> Option<::FlowControl> {
        self.io.get_ref().flow_control()
    }

    fn parity(&self) -> Option<::Parity> {
        self.io.get_ref().parity()
    }

    fn stop_bits(&self) -> Option<::StopBits> {
        self.io.get_ref().stop_bits()
    }

    fn timeout(&self) -> Duration {
        Duration::from_secs(0)
    }

    fn set_all(&mut self, settings: &::SerialPortSettings) -> ::Result<()> {
        self.io.get_mut().set_all(settings)
    }

    fn set_baud_rate(&mut self, baud_rate: ::BaudRate) -> ::Result<()> {
        self.io.get_mut().set_baud_rate(baud_rate)
    }

    fn set_data_bits(&mut self, data_bits: ::DataBits) -> ::Result<()> {
        self.io.get_mut().set_data_bits(data_bits)
    }

    fn set_flow_control(&mut self, flow_control: ::FlowControl) -> ::Result<()> {
        self.io.get_mut().set_flow_control(flow_control)
    }

    fn set_parity(&mut self, parity: ::Parity) -> ::Result<()> {
        self.io.get_mut().set_parity(parity)
    }

    fn set_stop_bits(&mut self, stop_bits: ::StopBits) -> ::Result<()> {
        self.io.get_mut().set_stop_bits(stop_bits)
    }

    fn set_timeout(&mut self, _: Duration) -> ::Result<()> {
        Ok(())
    }

    fn write_request_to_send(&mut self, level: bool) -> ::Result<()> {
        self.io.get_mut().write_request_to_send(level)
    }

    fn write_data_terminal_ready(&mut self, level: bool) -> ::Result<()> {
        self.io.get_mut().write_data_terminal_ready(level)
    }

    fn read_clear_to_send(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_clear_to_send()
    }

    fn read_data_set_ready(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_data_set_ready()
    }

    fn read_ring_indicator(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_ring_indicator()
    }

    fn read_carrier_detect(&mut self) -> ::Result<bool> {
        self.io.get_mut().read_carrier_detect()
    }

    fn try_clone(&self) -> ::Result<Box<::SerialPort>> {
        self.io.get_ref().try_clone()
    }
}

impl Read for Serial {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.get_mut().read(buf)
    }
}

impl Write for Serial {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.get_mut().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.io.get_mut().flush()
    }
}

// impl<'a> Read for &'a Serial {
//     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
//         // (&self.io).read(buf)
//         self.io.get_mut().read(buf)
//     }
// }
//
// impl<'a> Write for &'a Serial {
//     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
//         // (&self.io).write(buf)
//         self.io.get_mut().write(buf)
//     }
//
//     fn flush(&mut self) -> io::Result<()> {
//         // (&self.io).flush()
//         self.io.get_mut().flush()
//     }
// }

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(unix)]
impl AsRawFd for Serial {
    fn as_raw_fd(&self) -> RawFd {
        self.io.get_ref().as_raw_fd()
    }
}

impl AsyncRead for Serial {}

impl AsyncWrite for Serial {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        Ok(Async::Ready(()))
    }
}
<|endoftext|>


<commit_before>#![deny(
    missing_docs,
    missing_debug_implementations, missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unsafe_code, unstable_features,
    unused_import_braces, unused_qualifications
)]

//! `merkle_sigs` implements Merkle signatures in Rust.

#![deny(
    // missing_docs,
    missing_debug_implementations, missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unsafe_code, unstable_features,
    unused_import_braces, unused_qualifications
)]

#[doc(no_inline)]
extern crate lamport_sigs;
extern crate merkle;
extern crate ring;

mod signatures;

pub use merkle::Proof;

pub use lamport_sigs::PublicKey;
pub use signatures::{
    MerklePublicKey,
    MerkleSignature,
    MerkleSignedData,
    verify_data_vec_signature,
    sign_data_vec
};

#[cfg(test)]
mod tests;
<commit_msg>Remove duplicated flags.<commit_after>#![deny(
    missing_docs,
    missing_debug_implementations, missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unsafe_code, unstable_features,
    unused_import_braces, unused_qualifications
)]

//! `merkle_sigs` implements Merkle signatures in Rust.

extern crate lamport_sigs;
extern crate merkle;
extern crate ring;

mod signatures;

pub use merkle::Proof;

pub use lamport_sigs::PublicKey;
pub use signatures::{
    MerklePublicKey,
    MerkleSignature,
    MerkleSignedData,
    verify_data_vec_signature,
    sign_data_vec
};

#[cfg(test)]
mod tests;

<|endoftext|>


<commit_before>#![feature(unsafe_destructor, box_syntax)]
#![allow(unstable)]

extern crate "cef-sys" as ffi;
extern crate libc;
extern crate alloc;

use std::mem::{transmute, drop, size_of, zeroed};
use std::ops::{Deref, DerefMut};

mod app;
pub mod string;
mod browser_client;

pub use app::App;
pub use browser_client::BrowserClient;

pub fn shutdown() {
    unsafe { ffi::cef_shutdown() }
}
use string::CefString;

unsafe fn unsafe_downcast_mut<'a, T1, T2 : Is<T1>>(x: &'a mut T1) -> &'a mut T2 {
    transmute(x)
}
fn upcast_mut<'a, T1 : Is<T2>, T2>(x: &'a mut T1) -> &'a mut T2 {
    unsafe{ transmute(x) }
}

fn upcast_ptr<T1 : Is<T2>, T2>(x: CefRc<T1>) -> *mut T2 where T1 : Is<ffi::cef_base_t> {
    unsafe { transmute(x) }
}

#[repr(C)]
#[unsafe_no_drop_flag]
pub struct CefRc<T: Is<ffi::cef_base_t>> {
    inner: *mut T
}

pub trait Is<T> {}

impl Is<ffi::cef_base_t> for ffi::cef_base_t {}
impl<T> Is<T> for () {}
trait CefBase : Is<ffi::cef_base_t> {
    fn add_ref(&mut self);
    fn release(&mut self) -> libc::c_int;
}

impl<T: Is<ffi::cef_base_t>> CefBase for T {
    fn add_ref(&mut self) {
        let base: &mut ffi::cef_base_t = upcast_mut(self);
        base.add_ref.unwrap()(base as *mut _)
    }
    fn release(&mut self) -> libc::c_int {
        let base: &mut ffi::cef_base_t = upcast_mut(self);
        base.release.unwrap()(base as *mut _)
    }
}

impl<T: Is<ffi::cef_base_t>> CefRc<T> {
    fn make<F: FnOnce(ffi::cef_base_t) -> T>(f: F) -> CefRc<T> {
        #[repr(C)]
        struct RefCounted<T> {
            v: T,
            count: libc::c_int
        }
        impl<T> Is<ffi::cef_base_t> for RefCounted<T> {}

        extern fn add_ref<T>(_self: *mut ffi::cef_base_t) {
            let cell: &mut RefCounted<T> = unsafe{ unsafe_downcast_mut(&mut *_self) };
            cell.count += 1;
        }
        extern fn release<T>(_self: *mut ffi::cef_base_t) -> libc::c_int {
            unsafe {
                let cell: *mut RefCounted<T> = transmute(_self);
                (*cell).count -= 1;
                let count = (*cell).count;
                if count == 0 {
                    let cell: Box<RefCounted<T>> = transmute(cell);
                    drop(cell);
                }
                count
            }
        }
        extern fn has_one_ref<T>(_self: *mut ffi::cef_base_t) -> libc::c_int {
            let cell: &mut RefCounted<T> = unsafe{ unsafe_downcast_mut(&mut *_self) };
            if cell.count == 1 { 1 } else { 0 }
        }
        CefRc {
            inner: unsafe { transmute(box RefCounted {
                v: f(ffi::cef_base_t {
                    size: size_of::<RefCounted<T>>() as libc::size_t,
                    add_ref: Some(add_ref::<T>),
                    release: Some(release::<T>),
                    has_one_ref: Some(has_one_ref::<T>)
                }),
                count: 1
            })}
        }
    }
    pub fn from_existing(ptr: *mut T) -> CefRc<T> {
        CefRc { inner: ptr }
    }
}

impl<T: Is<ffi::cef_base_t>> Deref for CefRc<T> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {
        unsafe{ &*self.inner }
    }
}

impl<T: Is<ffi::cef_base_t>> DerefMut for CefRc<T> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe{ &mut *self.inner }
    }
}

pub fn execute_process<T : App>(app: Option<T>) -> libc::c_int {
    use std::ffi::CString;
    let args: Vec<CString> = std::os::args().into_iter().map(|x| CString::from_vec(x.into_bytes())).collect();
    let args: Vec<*mut libc::c_char> = args.iter().map(|x| x.as_slice_with_nul().as_ptr() as *mut _).collect();
    let args = &args[];
    let args = ffi::cef_main_args_t { argc: args.len() as libc::c_int, argv: args[].as_ptr() as *mut _ };
    unsafe{
        ffi::cef_execute_process(
            &args as *const _,
            app.map(|x| upcast_ptr(app::AppWrapper::new(x))).unwrap_or_else(|| zeroed()),
            zeroed())
    }
}

#[repr(C)]
pub struct Settings {
    pub size: ::libc::size_t,
    single_process: ::libc::c_int,
    no_sandbox: ::libc::c_int,
    pub browser_subprocess_path: CefString,
    multi_threaded_message_loop: ::libc::c_int,
    windowless_rendering_enabled: ::libc::c_int,
    command_line_args_disabled: ::libc::c_int,
    pub cache_path: CefString,
    persist_session_cookies: ::libc::c_int,
    pub user_agent: CefString,
    pub product_version: CefString,
    pub locale: CefString,
    pub log_file: CefString,
    pub log_severity: ffi::cef_log_severity_t,
    pub javascript_flags: CefString,
    pub resources_dir_path: CefString,
    pub locales_dir_path: CefString,
    pack_loading_disabled: ::libc::c_int,
    pub remote_debugging_port: ::libc::c_int,
    pub uncaught_exception_stack_size: ::libc::c_int,
    context_safety_implementation: ::libc::c_int,
    ignore_certificate_errors: ::libc::c_int,
    pub background_color: ffi::cef_color_t,
}

impl Settings {
    pub fn new() -> Settings {
        let mut x: Settings = unsafe { zeroed() };
        x.size = size_of::<ffi::cef_settings_t>() as libc::size_t;
        x.no_sandbox = 1;
        x.command_line_args_disabled = 1;
        x
    }
    fn settings<'a>(&'a self) -> &'a ffi::cef_settings_t {
        unsafe{ transmute::<&'a Settings, &'a ffi::cef_settings_t>(self) }
    }

    pub fn set_windowless_rendering(&mut self, enabled: bool) {
        self.windowless_rendering_enabled = enabled as libc::c_int;
    }
}

#[test]
fn settings_size_check() {
    use std::mem::size_of;
    assert!(size_of::<Settings>() == size_of::<ffi::cef_settings_t>());
}

#[repr(C)]
pub struct WindowInfo {
    pub window_name: CefString,
    pub x: ::libc::c_int,
    pub y: ::libc::c_int,
    pub width: ::libc::c_int,
    pub height: ::libc::c_int,
    hidden: ::libc::c_int,
    pub parent_view: *mut ::libc::c_void,
    windowless_rendering_enabled: ::libc::c_int,
    transparent_painting_enabled: ::libc::c_int,
    pub view: *mut ::libc::c_void,
}

#[test]
fn window_size_check() {
    use std::mem::size_of;
    assert!(size_of::<WindowInfo>() == size_of::<ffi::cef_window_info_t>());
}

impl WindowInfo {
    pub fn new() -> WindowInfo {
        let x: WindowInfo = unsafe { zeroed() };
        x
    }
    fn info<'a>(&'a self) -> &'a ffi::cef_window_info_t {
        unsafe{ transmute::<&'a WindowInfo, &'a ffi::cef_window_info_t>(self) }
    }

    pub fn set_windowless_rendering(&mut self, enabled: bool) {
        self.windowless_rendering_enabled = enabled as libc::c_int;
    }

    pub fn set_transparent_painting(&mut self, enabled: bool) {
        self.transparent_painting_enabled = enabled as libc::c_int;
    }

    pub fn set_hidden(&mut self, hidden: bool) {
        self.hidden = hidden as libc::c_int;
    }
}

pub fn initialize<T : App>(settings: &Settings, app: Option<T>) -> bool {
    use std::ffi::CString;
    let args: Vec<CString> = std::os::args().into_iter().map(|x| CString::from_vec(x.into_bytes())).collect();
    let args: Vec<*mut libc::c_char> = args.iter().map(|x| x.as_slice_with_nul().as_ptr() as *mut _).collect();
    let args = &args[];
    let args = ffi::cef_main_args_t { argc: args.len() as libc::c_int, argv: args[].as_ptr() as *mut _ };
    let result = unsafe{
        ffi::cef_initialize(
            &args as *const _,
            settings.settings() as *const _,
            app.map(|x| upcast_ptr(app::AppWrapper::new(x))).unwrap_or_else(|| zeroed()), zeroed()) };
    match result {
        0 => false,
        _ => true
    }
}

#[unsafe_destructor]
impl<T: Is<ffi::cef_base_t>> Drop for CefRc<T> {
    fn drop(&mut self) {
        unsafe{
            if self.inner != std::ptr::null_mut() {
                (*self.inner).release();
                self.inner = std::ptr::null_mut();
            }
        };
    }
}

impl<T: Is<ffi::cef_base_t>> Clone for CefRc<T> {
    fn clone(&self) -> CefRc<T> {
        unsafe{ (*self.inner).add_ref() };
        CefRc { inner: self.inner }
    }
}
<commit_msg>Changed reference counting to be atomic.<commit_after>#![feature(unsafe_destructor, box_syntax)]
#![allow(unstable)]

extern crate "cef-sys" as ffi;
extern crate libc;
extern crate alloc;

use std::mem::{transmute, drop, size_of, zeroed};
use std::ops::{Deref, DerefMut};

mod app;
pub mod string;
mod browser_client;

pub use app::App;
pub use browser_client::BrowserClient;

pub fn shutdown() {
    unsafe { ffi::cef_shutdown() }
}
use string::CefString;

unsafe fn unsafe_downcast_mut<'a, T1, T2 : Is<T1>>(x: &'a mut T1) -> &'a mut T2 {
    transmute(x)
}
fn upcast_mut<'a, T1 : Is<T2>, T2>(x: &'a mut T1) -> &'a mut T2 {
    unsafe{ transmute(x) }
}

fn upcast_ptr<T1 : Is<T2>, T2>(x: CefRc<T1>) -> *mut T2 where T1 : Is<ffi::cef_base_t> {
    unsafe { transmute(x) }
}

#[repr(C)]
#[unsafe_no_drop_flag]
pub struct CefRc<T: Is<ffi::cef_base_t>> {
    inner: *mut T
}

pub trait Is<T> {}

impl Is<ffi::cef_base_t> for ffi::cef_base_t {}
impl<T> Is<T> for () {}
trait CefBase : Is<ffi::cef_base_t> {
    fn add_ref(&mut self);
    fn release(&mut self) -> libc::c_int;
}

impl<T: Is<ffi::cef_base_t>> CefBase for T {
    fn add_ref(&mut self) {
        let base: &mut ffi::cef_base_t = upcast_mut(self);
        base.add_ref.unwrap()(base as *mut _)
    }
    fn release(&mut self) -> libc::c_int {
        let base: &mut ffi::cef_base_t = upcast_mut(self);
        base.release.unwrap()(base as *mut _)
    }
}

impl<T: Is<ffi::cef_base_t>> CefRc<T> {
    fn make<F: FnOnce(ffi::cef_base_t) -> T>(f: F) -> CefRc<T> {
        use std::sync::atomic::AtomicUsize;
        use std::sync::atomic::Ordering;
        use std::sync::atomic;
        #[repr(C)]
        struct RefCounted<T> {
            v: T,
            count: AtomicUsize
        }
        impl<T> Is<ffi::cef_base_t> for RefCounted<T> {}

        extern fn add_ref<T>(_self: *mut ffi::cef_base_t) {
            let cell: &mut RefCounted<T> = unsafe{ unsafe_downcast_mut(&mut *_self) };
            cell.count.fetch_add(1, Ordering::Relaxed);
        }
        extern fn release<T>(_self: *mut ffi::cef_base_t) -> libc::c_int {
            unsafe {
                let cell: *mut RefCounted<T> = transmute(_self);
                let old_count = (*cell).count.fetch_sub(1, Ordering::Release);
                if old_count == 1 {
                    atomic::fence(Ordering::Acquire);
                    let cell: Box<RefCounted<T>> = transmute(cell);
                    drop(cell);
                }
                if old_count == 1 { 1 } else { 0 }
            }
        }
        extern fn has_one_ref<T>(_self: *mut ffi::cef_base_t) -> libc::c_int {
            let cell: &mut RefCounted<T> = unsafe{ unsafe_downcast_mut(&mut *_self) };
            if cell.count.load(Ordering::SeqCst) == 1 { 1 } else { 0 }
        }
        CefRc {
            inner: unsafe { transmute(box RefCounted {
                v: f(ffi::cef_base_t {
                    size: size_of::<RefCounted<T>>() as libc::size_t,
                    add_ref: Some(add_ref::<T>),
                    release: Some(release::<T>),
                    has_one_ref: Some(has_one_ref::<T>)
                }),
                count: AtomicUsize::new(1)
            })}
        }
    }
    pub fn from_existing(ptr: *mut T) -> CefRc<T> {
        CefRc { inner: ptr }
    }
}

impl<T: Is<ffi::cef_base_t>> Deref for CefRc<T> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {
        unsafe{ &*self.inner }
    }
}

impl<T: Is<ffi::cef_base_t>> DerefMut for CefRc<T> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe{ &mut *self.inner }
    }
}

pub fn execute_process<T : App>(app: Option<T>) -> libc::c_int {
    use std::ffi::CString;
    let args: Vec<CString> = std::os::args().into_iter().map(|x| CString::from_vec(x.into_bytes())).collect();
    let args: Vec<*mut libc::c_char> = args.iter().map(|x| x.as_slice_with_nul().as_ptr() as *mut _).collect();
    let args = &args[];
    let args = ffi::cef_main_args_t { argc: args.len() as libc::c_int, argv: args[].as_ptr() as *mut _ };
    unsafe{
        ffi::cef_execute_process(
            &args as *const _,
            app.map(|x| upcast_ptr(app::AppWrapper::new(x))).unwrap_or_else(|| zeroed()),
            zeroed())
    }
}

#[repr(C)]
pub struct Settings {
    pub size: ::libc::size_t,
    single_process: ::libc::c_int,
    no_sandbox: ::libc::c_int,
    pub browser_subprocess_path: CefString,
    multi_threaded_message_loop: ::libc::c_int,
    windowless_rendering_enabled: ::libc::c_int,
    command_line_args_disabled: ::libc::c_int,
    pub cache_path: CefString,
    persist_session_cookies: ::libc::c_int,
    pub user_agent: CefString,
    pub product_version: CefString,
    pub locale: CefString,
    pub log_file: CefString,
    pub log_severity: ffi::cef_log_severity_t,
    pub javascript_flags: CefString,
    pub resources_dir_path: CefString,
    pub locales_dir_path: CefString,
    pack_loading_disabled: ::libc::c_int,
    pub remote_debugging_port: ::libc::c_int,
    pub uncaught_exception_stack_size: ::libc::c_int,
    context_safety_implementation: ::libc::c_int,
    ignore_certificate_errors: ::libc::c_int,
    pub background_color: ffi::cef_color_t,
}

impl Settings {
    pub fn new() -> Settings {
        let mut x: Settings = unsafe { zeroed() };
        x.size = size_of::<ffi::cef_settings_t>() as libc::size_t;
        x.no_sandbox = 1;
        x.command_line_args_disabled = 1;
        x
    }
    fn settings<'a>(&'a self) -> &'a ffi::cef_settings_t {
        unsafe{ transmute::<&'a Settings, &'a ffi::cef_settings_t>(self) }
    }

    pub fn set_windowless_rendering(&mut self, enabled: bool) {
        self.windowless_rendering_enabled = enabled as libc::c_int;
    }
}

#[test]
fn settings_size_check() {
    use std::mem::size_of;
    assert!(size_of::<Settings>() == size_of::<ffi::cef_settings_t>());
}

#[repr(C)]
pub struct WindowInfo {
    pub window_name: CefString,
    pub x: ::libc::c_int,
    pub y: ::libc::c_int,
    pub width: ::libc::c_int,
    pub height: ::libc::c_int,
    hidden: ::libc::c_int,
    pub parent_view: *mut ::libc::c_void,
    windowless_rendering_enabled: ::libc::c_int,
    transparent_painting_enabled: ::libc::c_int,
    pub view: *mut ::libc::c_void,
}

#[test]
fn window_size_check() {
    use std::mem::size_of;
    assert!(size_of::<WindowInfo>() == size_of::<ffi::cef_window_info_t>());
}

impl WindowInfo {
    pub fn new() -> WindowInfo {
        let x: WindowInfo = unsafe { zeroed() };
        x
    }
    fn info<'a>(&'a self) -> &'a ffi::cef_window_info_t {
        unsafe{ transmute::<&'a WindowInfo, &'a ffi::cef_window_info_t>(self) }
    }

    pub fn set_windowless_rendering(&mut self, enabled: bool) {
        self.windowless_rendering_enabled = enabled as libc::c_int;
    }

    pub fn set_transparent_painting(&mut self, enabled: bool) {
        self.transparent_painting_enabled = enabled as libc::c_int;
    }

    pub fn set_hidden(&mut self, hidden: bool) {
        self.hidden = hidden as libc::c_int;
    }
}

pub fn initialize<T : App>(settings: &Settings, app: Option<T>) -> bool {
    use std::ffi::CString;
    let args: Vec<CString> = std::os::args().into_iter().map(|x| CString::from_vec(x.into_bytes())).collect();
    let args: Vec<*mut libc::c_char> = args.iter().map(|x| x.as_slice_with_nul().as_ptr() as *mut _).collect();
    let args = &args[];
    let args = ffi::cef_main_args_t { argc: args.len() as libc::c_int, argv: args[].as_ptr() as *mut _ };
    let result = unsafe{
        ffi::cef_initialize(
            &args as *const _,
            settings.settings() as *const _,
            app.map(|x| upcast_ptr(app::AppWrapper::new(x))).unwrap_or_else(|| zeroed()), zeroed()) };
    match result {
        0 => false,
        _ => true
    }
}

#[unsafe_destructor]
impl<T: Is<ffi::cef_base_t>> Drop for CefRc<T> {
    fn drop(&mut self) {
        unsafe{
            if self.inner != std::ptr::null_mut() {
                (*self.inner).release();
                self.inner = std::ptr::null_mut();
            }
        };
    }
}

impl<T: Is<ffi::cef_base_t>> Clone for CefRc<T> {
    fn clone(&self) -> CefRc<T> {
        unsafe{ (*self.inner).add_ref() };
        CefRc { inner: self.inner }
    }
}
<|endoftext|>


<commit_before>//! Entity Component System Library (ECS)
//!
//! For info about why an ECS may be beneficial, see some of these articles:
//!
//! - http://gameprogrammingpatterns.com/component.html
//! - http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
//! - http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013
//! - http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
//!
//! There is a large variety of ways an ECS may work. This particular one is similar to
//! [Artemis](http://gamadu.com/artemis/).
//! Although this isn't a port to Rust, most functionality should be similar, and the
//! tutorials/manual there should be able to make up for the current lack of documentation [FIXME]
//!
//! Here's the basic structure:
//!
//! - An `Entity` is just an identifier. It contains no data or logic whatsoever.
//! - A `Component` is a piece of data (eg: Position, Velocity, Colour). While containing logic can
//! sometimes be useful, it's best practice to avoid it wherever possible.
//! - A `System` runs all the logic. Most of the time, it filters out entities based on their
//! components, and only runs it's logic on the entities it's interested in. These filters are
//! called `Aspect`s. Some systems ignore entities, and just apply logic to the world itself.
//! - An `Aspect` is a simple helper to filter entities based on their components.
//! - A `Manager` is simply an object that observes when an entity is
//! added/activated/deactivated/removed. They are used to help 'manage' the entities, rather than
//! define data or logic.
//! - The `World` organises all the above items together to make sure everything runs as it should.

#![crate_name = "ecs"]
#![crate_type = "lib"]

#![feature(collections)]
#![feature(collections_drain)]

extern crate bincode;
extern crate rustc_serialize;

pub use aspect::Aspect;
pub use component::{Component, ComponentList};
pub use component::{EntityBuilder, EntityModifier};
pub use entity::{Entity, IndexedEntity, EntityIter};
pub use system::{System, Process};
pub use world::{ComponentManager, ServiceManager, SystemManager, DataHelper, World};

use std::ops::Deref;

pub mod aspect;
pub mod component;
pub mod entity;
pub mod system;
pub mod world;

pub struct BuildData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
pub struct ModifyData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
pub struct EntityData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
impl<'a, T: ComponentManager> Deref for EntityData<'a, T>
{
    type Target = IndexedEntity<T>;
    fn deref(&self) -> &IndexedEntity<T>
    {
        &self.0
    }
}

impl<'a, T: ComponentManager> Copy for BuildData<'a, T> {}
impl<'a, T: ComponentManager> Copy for ModifyData<'a, T> {}
impl<'a, T: ComponentManager> Copy for EntityData<'a, T> {}

impl<'a, T: ComponentManager> Clone for BuildData<'a, T> {fn clone(&self) -> BuildData<'a, T> {*self}}
impl<'a, T: ComponentManager> Clone for ModifyData<'a, T> {fn clone(&self) -> ModifyData<'a, T> {*self}}
impl<'a, T: ComponentManager> Clone for EntityData<'a, T> {fn clone(&self) -> EntityData<'a, T> {*self}}

#[doc(hidden)]
pub unsafe trait EditData<T: ComponentManager> { fn entity(&self) -> &IndexedEntity<T>; }
unsafe impl<'a, T: ComponentManager> EditData<T> for ModifyData<'a, T> { fn entity(&self) -> &IndexedEntity<T> { &self.0 } }
unsafe impl<'a, T: ComponentManager> EditData<T> for EntityData<'a, T> { fn entity(&self) -> &IndexedEntity<T> { &self.0 } }

#[macro_use]
mod macros
{
    #[macro_export]
    macro_rules! process {
        {
            $world:expr, $system:ident
        } => {
            $crate::Process::process(&mut $world.systems.$system, &mut $world.data)
        };
    }

    #[macro_export]
    macro_rules! components {
        {
            $Name:ident;
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name;

            unsafe impl $crate::ComponentManager for $Name
            {
                unsafe fn new() -> $Name
                {
                    $Name
                }

                unsafe fn remove_all(&mut self, _: &$crate::IndexedEntity<$Name>)
                {

                }
            }
        };
        {
            $Name:ident {
                $(#[$kind:ident] $field_name:ident : $field_ty:ty),+
            }
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name {
                $(
                    pub $field_name : $crate::ComponentList<$Name, $field_ty>,
                )+
            }

            unsafe impl $crate::ComponentManager for $Name
            {
                unsafe fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $crate::ComponentList::$kind(),
                        )+
                    }
                }

                unsafe fn remove_all(&mut self, entity: &$crate::IndexedEntity<$Name>)
                {
                    $(
                        self.$field_name.clear(entity);
                    )+
                }
            }
        };
        {
            $Name:ident {
                $(#[$kind:ident] $field_name:ident : $field_ty:ty),+,
            }
        } => {
            components! { $Name { $(#[$kind] $field_name : $field_ty),+ } }
        };
    }

    #[macro_export]
    macro_rules! services {
        {
            $Name:ident {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+
            }
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name {
                $(
                    pub $field_name : $field_ty,
                )+
            }

            impl $crate::ServiceManager for $Name
            {
                fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                }
            }
        };
        {
            $Name:ident {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+,
            }
        } => {
            services! { $Name { $($field_name : $field_ty = $field_init),+ } }
        }
    }

    #[macro_export]
    macro_rules! systems {
        {
            $Name:ident<$components:ty, $services:ty>;
        } => {
            pub struct $Name;

            impl Encodable for $Name
            {
                fn encode<S:Encoder>(&self,_: &mut S)-> Result<(),S::Error>
                {
                    Ok(())
                }
            }

            impl Decodable for $Name
            {
                fn decode<D: Decoder>(_: &mut D)->Result<$Name,D::Error>
                {
                    Ok(
                    $Name
                    {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                    )
                }
            }

            unsafe impl $crate::SystemManager for $Name
            {
                type Components = $components;
                type Services = $services;
                #[allow(unused_unsafe)] // The aspect macro is probably going to be used here and it also expands to an unsafe block.
                unsafe fn new() -> $Name
                {
                    $Name
                }

                unsafe fn activated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn reactivated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn deactivated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn update(&mut self, _: &mut $crate::DataHelper<$components, $services>)
                {

                }
            }
        };
        {
            $Name:ident<$components:ty, $services:ty> {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+
            }
        } => {
            pub struct $Name {
                $(
                    pub $field_name : $field_ty,
                )+
            }

            impl Encodable for $Name
            {
                fn encode<S:Encoder>(&self,_: &mut S)-> Result<(),S::Error>
                {
                    Ok(())
                }
            }

            impl Decodable for $Name
            {
                fn decode<D: Decoder>(_: &mut D)->Result<$Name,D::Error>
                {
                    Ok(
                    $Name
                    {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                    )
                }
            }

            unsafe impl $crate::SystemManager for $Name
            {
                type Components = $components;
                type Services = $services;
                #[allow(unused_unsafe)] // The aspect macro is probably going to be used here and it also expands to an unsafe block.
                unsafe fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                }

                unsafe fn activated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.activated(&en, co);
                    )+
                }

                unsafe fn reactivated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.reactivated(&en, co);
                    )+
                }

                unsafe fn deactivated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.deactivated(&en, co);
                    )+
                }

                unsafe fn update(&mut self, co: &mut $crate::DataHelper<$components, $services>)
                {
                    $(
                        if self.$field_name.is_active() {
                            $crate::Process::process(&mut self.$field_name, co);
                        }
                    )+
                }
            }
        };
        {
            $Name:ident<$components:ty, $services:ty> {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+,
            }
        } => {
            systems! { $Name<$components, $services> { $($field_name : $field_ty = $field_init),+ } }
        }
    }

    #[macro_export]
    macro_rules! aspect {
        {
            <$components:ty>
            all: [$($all_field:ident),*]
            none: [$($none_field:ident),*]
        } => {
            unsafe {
                $crate::Aspect::new(Box::new(|_en: &$crate::EntityData<$components>, _co: &$components| {
                    ($(_co.$all_field.has(_en) &&)* true) &&
                    !($(_co.$none_field.has(_en) ||)* false)
                }))
            }
        };
        {
            <$components:ty>
            all: [$($field:ident),*]
        } => {
            aspect!(
                <$components>
                all: [$($field),*]
                none: []
            )
        };
        {
            <$components:ty>
            none: [$($field:ident),*]
        } => {
            aspect!(
                <$components>
                all: []
                none: [$($field),*]
            )
        };
    }
}
<commit_msg>Works with rust nightly now<commit_after>//! Entity Component System Library (ECS)
//!
//! For info about why an ECS may be beneficial, see some of these articles:
//!
//! - http://gameprogrammingpatterns.com/component.html
//! - http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
//! - http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013
//! - http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
//!
//! There is a large variety of ways an ECS may work. This particular one is similar to
//! [Artemis](http://gamadu.com/artemis/).
//! Although this isn't a port to Rust, most functionality should be similar, and the
//! tutorials/manual there should be able to make up for the current lack of documentation [FIXME]
//!
//! Here's the basic structure:
//!
//! - An `Entity` is just an identifier. It contains no data or logic whatsoever.
//! - A `Component` is a piece of data (eg: Position, Velocity, Colour). While containing logic can
//! sometimes be useful, it's best practice to avoid it wherever possible.
//! - A `System` runs all the logic. Most of the time, it filters out entities based on their
//! components, and only runs it's logic on the entities it's interested in. These filters are
//! called `Aspect`s. Some systems ignore entities, and just apply logic to the world itself.
//! - An `Aspect` is a simple helper to filter entities based on their components.
//! - A `Manager` is simply an object that observes when an entity is
//! added/activated/deactivated/removed. They are used to help 'manage' the entities, rather than
//! define data or logic.
//! - The `World` organises all the above items together to make sure everything runs as it should.

#![crate_name = "ecs"]
#![crate_type = "lib"]

#![feature(collections)]
#![feature(collections_drain)]
#![feature(vecmap)]
#![feature(drain)]
extern crate bincode;
extern crate rustc_serialize;

pub use aspect::Aspect;
pub use component::{Component, ComponentList};
pub use component::{EntityBuilder, EntityModifier};
pub use entity::{Entity, IndexedEntity, EntityIter};
pub use system::{System, Process};
pub use world::{ComponentManager, ServiceManager, SystemManager, DataHelper, World};

use std::ops::Deref;

pub mod aspect;
pub mod component;
pub mod entity;
pub mod system;
pub mod world;

pub struct BuildData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
pub struct ModifyData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
pub struct EntityData<'a, T: ComponentManager>(&'a IndexedEntity<T>);
impl<'a, T: ComponentManager> Deref for EntityData<'a, T>
{
    type Target = IndexedEntity<T>;
    fn deref(&self) -> &IndexedEntity<T>
    {
        &self.0
    }
}

impl<'a, T: ComponentManager> Copy for BuildData<'a, T> {}
impl<'a, T: ComponentManager> Copy for ModifyData<'a, T> {}
impl<'a, T: ComponentManager> Copy for EntityData<'a, T> {}

impl<'a, T: ComponentManager> Clone for BuildData<'a, T> {fn clone(&self) -> BuildData<'a, T> {*self}}
impl<'a, T: ComponentManager> Clone for ModifyData<'a, T> {fn clone(&self) -> ModifyData<'a, T> {*self}}
impl<'a, T: ComponentManager> Clone for EntityData<'a, T> {fn clone(&self) -> EntityData<'a, T> {*self}}

#[doc(hidden)]
pub unsafe trait EditData<T: ComponentManager> { fn entity(&self) -> &IndexedEntity<T>; }
unsafe impl<'a, T: ComponentManager> EditData<T> for ModifyData<'a, T> { fn entity(&self) -> &IndexedEntity<T> { &self.0 } }
unsafe impl<'a, T: ComponentManager> EditData<T> for EntityData<'a, T> { fn entity(&self) -> &IndexedEntity<T> { &self.0 } }

#[macro_use]
mod macros
{
    #[macro_export]
    macro_rules! process {
        {
            $world:expr, $system:ident
        } => {
            $crate::Process::process(&mut $world.systems.$system, &mut $world.data)
        };
    }

    #[macro_export]
    macro_rules! components {
        {
            $Name:ident;
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name;

            unsafe impl $crate::ComponentManager for $Name
            {
                unsafe fn new() -> $Name
                {
                    $Name
                }

                unsafe fn remove_all(&mut self, _: &$crate::IndexedEntity<$Name>)
                {

                }
            }
        };
        {
            $Name:ident {
                $(#[$kind:ident] $field_name:ident : $field_ty:ty),+
            }
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name {
                $(
                    pub $field_name : $crate::ComponentList<$Name, $field_ty>,
                )+
            }

            unsafe impl $crate::ComponentManager for $Name
            {
                unsafe fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $crate::ComponentList::$kind(),
                        )+
                    }
                }

                unsafe fn remove_all(&mut self, entity: &$crate::IndexedEntity<$Name>)
                {
                    $(
                        self.$field_name.clear(entity);
                    )+
                }
            }
        };
        {
            $Name:ident {
                $(#[$kind:ident] $field_name:ident : $field_ty:ty),+,
            }
        } => {
            components! { $Name { $(#[$kind] $field_name : $field_ty),+ } }
        };
    }

    #[macro_export]
    macro_rules! services {
        {
            $Name:ident {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+
            }
        } => {
            #[derive(RustcEncodable,RustcDecodable)]
            pub struct $Name {
                $(
                    pub $field_name : $field_ty,
                )+
            }

            impl $crate::ServiceManager for $Name
            {
                fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                }
            }
        };
        {
            $Name:ident {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+,
            }
        } => {
            services! { $Name { $($field_name : $field_ty = $field_init),+ } }
        }
    }

    #[macro_export]
    macro_rules! systems {
        {
            $Name:ident<$components:ty, $services:ty>;
        } => {
            pub struct $Name;

            impl Encodable for $Name
            {
                fn encode<S:Encoder>(&self,_: &mut S)-> Result<(),S::Error>
                {
                    Ok(())
                }
            }

            impl Decodable for $Name
            {
                fn decode<D: Decoder>(_: &mut D)->Result<$Name,D::Error>
                {
                    Ok(
                    $Name
                    {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                    )
                }
            }

            unsafe impl $crate::SystemManager for $Name
            {
                type Components = $components;
                type Services = $services;
                #[allow(unused_unsafe)] // The aspect macro is probably going to be used here and it also expands to an unsafe block.
                unsafe fn new() -> $Name
                {
                    $Name
                }

                unsafe fn activated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn reactivated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn deactivated(&mut self, _: $crate::EntityData<$components>, _: &$components)
                {

                }

                unsafe fn update(&mut self, _: &mut $crate::DataHelper<$components, $services>)
                {

                }
            }
        };
        {
            $Name:ident<$components:ty, $services:ty> {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+
            }
        } => {
            pub struct $Name {
                $(
                    pub $field_name : $field_ty,
                )+
            }

            impl Encodable for $Name
            {
                fn encode<S:Encoder>(&self,_: &mut S)-> Result<(),S::Error>
                {
                    Ok(())
                }
            }

            impl Decodable for $Name
            {
                fn decode<D: Decoder>(_: &mut D)->Result<$Name,D::Error>
                {
                    Ok(
                    $Name
                    {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                    )
                }
            }

            unsafe impl $crate::SystemManager for $Name
            {
                type Components = $components;
                type Services = $services;
                #[allow(unused_unsafe)] // The aspect macro is probably going to be used here and it also expands to an unsafe block.
                unsafe fn new() -> $Name
                {
                    $Name {
                        $(
                            $field_name : $field_init,
                        )+
                    }
                }

                unsafe fn activated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.activated(&en, co);
                    )+
                }

                unsafe fn reactivated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.reactivated(&en, co);
                    )+
                }

                unsafe fn deactivated(&mut self, en: $crate::EntityData<$components>, co: &$components)
                {
                    $(
                        self.$field_name.deactivated(&en, co);
                    )+
                }

                unsafe fn update(&mut self, co: &mut $crate::DataHelper<$components, $services>)
                {
                    $(
                        if self.$field_name.is_active() {
                            $crate::Process::process(&mut self.$field_name, co);
                        }
                    )+
                }
            }
        };
        {
            $Name:ident<$components:ty, $services:ty> {
                $($field_name:ident : $field_ty:ty = $field_init:expr),+,
            }
        } => {
            systems! { $Name<$components, $services> { $($field_name : $field_ty = $field_init),+ } }
        }
    }

    #[macro_export]
    macro_rules! aspect {
        {
            <$components:ty>
            all: [$($all_field:ident),*]
            none: [$($none_field:ident),*]
        } => {
            unsafe {
                $crate::Aspect::new(Box::new(|_en: &$crate::EntityData<$components>, _co: &$components| {
                    ($(_co.$all_field.has(_en) &&)* true) &&
                    !($(_co.$none_field.has(_en) ||)* false)
                }))
            }
        };
        {
            <$components:ty>
            all: [$($field:ident),*]
        } => {
            aspect!(
                <$components>
                all: [$($field),*]
                none: []
            )
        };
        {
            <$components:ty>
            none: [$($field:ident),*]
        } => {
            aspect!(
                <$components>
                all: []
                none: [$($field),*]
            )
        };
    }
}
<|endoftext|>