<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use bincode;
use errors::WireError;
use futures::{self, Async, Future, Stream, future};
use net2;
use protocol::Proto;
use serde::{Deserialize, Serialize};
use std::io;
use std::net::SocketAddr;
use tokio_core::net::TcpListener;
use tokio_core::reactor::{self, Handle};
use tokio_proto::BindServer;
use tokio_service::NewService;

cfg_if! {
    if #[cfg(feature = "tls")] {
        use native_tls::TlsAcceptor;
        use tokio_tls::TlsAcceptorExt;
        use errors::native_to_io;
        use stream_type::StreamType;
    } else {}
}

enum Acceptor {
    Tcp,
    #[cfg(feature = "tls")]
    Tls(TlsAcceptor),
}

/// Additional options to configure how the server operates.
#[derive(Default)]
pub struct Options {
    #[cfg(feature = "tls")]
    tls_acceptor: Option<TlsAcceptor>,
}

impl Options {
    /// Set the `TlsAcceptor`
    #[cfg(feature = "tls")]
    pub fn tls(mut self, tls_acceptor: TlsAcceptor) -> Self {
        self.tls_acceptor = Some(tls_acceptor);
        self
    }
}

/// A message from server to client.
#[doc(hidden)]
pub type Response<T, E> = Result<T, WireError<E>>;

#[doc(hidden)]
pub fn listen<S, Req, Resp, E>(new_service: S,
                               addr: SocketAddr,
                               handle: &reactor::Handle,
                               _options: Options)
                               -> io::Result<SocketAddr>
    where S: NewService<Request = Result<Req, bincode::Error>,
                        Response = Response<Resp, E>,
                        Error = io::Error> + 'static,
          Req: Deserialize + 'static,
          Resp: Serialize + 'static,
          E: Serialize + 'static
{
    // Similar to the client, since `Options` is not `Send`, we take the `TlsAcceptor` when it is
    // available.
    #[cfg(feature = "tls")]
    let acceptor = match _options.tls_acceptor {
        Some(tls_acceptor) => Acceptor::Tls(tls_acceptor),
        None => Acceptor::Tcp,
    };
    #[cfg(not(feature = "tls"))]
    let acceptor = Acceptor::Tcp;

    listen_with(new_service, addr, handle, acceptor)
}

/// Spawns a service that binds to the given address using the given handle.
fn listen_with<S, Req, Resp, E>(new_service: S,
                                addr: SocketAddr,
                                handle: &Handle,
                                _acceptor: Acceptor)
                                -> io::Result<SocketAddr>
    where S: NewService<Request = Result<Req, bincode::Error>,
                        Response = Response<Resp, E>,
                        Error = io::Error> + 'static,
          Req: Deserialize + 'static,
          Resp: Serialize + 'static,
          E: Serialize + 'static
{
    let listener = listener(&addr, handle)?;
    let addr = listener.local_addr()?;

    let handle2 = handle.clone();

    let server = listener.incoming()
        .and_then(move |(socket, _)| {
            #[cfg(feature = "tls")]
            match _acceptor {
                Acceptor::Tls(ref tls_acceptor) => {
                    future::Either::A(tls_acceptor.accept_async(socket)
                        .map(StreamType::Tls)
                        .map_err(native_to_io))
                }
                Acceptor::Tcp => future::Either::B(future::ok(StreamType::Tcp(socket))),
            }
            #[cfg(not(feature = "tls"))]
            future::ok(socket)
        })
        .for_each(move |socket| {
            Proto::new().bind_server(&handle2, socket, new_service.new_service()?);

            Ok(())
        })
        .map_err(|e| error!("While processing incoming connections: {}", e));
    handle.spawn(server);
    Ok(addr)
}

fn listener(addr: &SocketAddr, handle: &Handle) -> io::Result<TcpListener> {
    const PENDING_CONNECTION_BACKLOG: i32 = 1024;
    #[cfg(unix)]
    use net2::unix::UnixTcpBuilderExt;

    let builder = match *addr {
        SocketAddr::V4(_) => net2::TcpBuilder::new_v4(),
        SocketAddr::V6(_) => net2::TcpBuilder::new_v6(),
    }?;

    builder.reuse_address(true)?;

    #[cfg(unix)]
    builder.reuse_port(true)?;

    builder.bind(addr)?
        .listen(PENDING_CONNECTION_BACKLOG)
        .and_then(|l| TcpListener::from_listener(l, addr, handle))
}
<commit_msg>Unused imports<commit_after>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use bincode;
use errors::WireError;
use futures::{Future, Stream, future};
use net2;
use protocol::Proto;
use serde::{Deserialize, Serialize};
use std::io;
use std::net::SocketAddr;
use tokio_core::net::TcpListener;
use tokio_core::reactor::{self, Handle};
use tokio_proto::BindServer;
use tokio_service::NewService;

cfg_if! {
    if #[cfg(feature = "tls")] {
        use native_tls::TlsAcceptor;
        use tokio_tls::TlsAcceptorExt;
        use errors::native_to_io;
        use stream_type::StreamType;
    } else {}
}

enum Acceptor {
    Tcp,
    #[cfg(feature = "tls")]
    Tls(TlsAcceptor),
}

/// Additional options to configure how the server operates.
#[derive(Default)]
pub struct Options {
    #[cfg(feature = "tls")]
    tls_acceptor: Option<TlsAcceptor>,
}

impl Options {
    /// Set the `TlsAcceptor`
    #[cfg(feature = "tls")]
    pub fn tls(mut self, tls_acceptor: TlsAcceptor) -> Self {
        self.tls_acceptor = Some(tls_acceptor);
        self
    }
}

/// A message from server to client.
#[doc(hidden)]
pub type Response<T, E> = Result<T, WireError<E>>;

#[doc(hidden)]
pub fn listen<S, Req, Resp, E>(new_service: S,
                               addr: SocketAddr,
                               handle: &reactor::Handle,
                               _options: Options)
                               -> io::Result<SocketAddr>
    where S: NewService<Request = Result<Req, bincode::Error>,
                        Response = Response<Resp, E>,
                        Error = io::Error> + 'static,
          Req: Deserialize + 'static,
          Resp: Serialize + 'static,
          E: Serialize + 'static
{
    // Similar to the client, since `Options` is not `Send`, we take the `TlsAcceptor` when it is
    // available.
    #[cfg(feature = "tls")]
    let acceptor = match _options.tls_acceptor {
        Some(tls_acceptor) => Acceptor::Tls(tls_acceptor),
        None => Acceptor::Tcp,
    };
    #[cfg(not(feature = "tls"))]
    let acceptor = Acceptor::Tcp;

    listen_with(new_service, addr, handle, acceptor)
}

/// Spawns a service that binds to the given address using the given handle.
fn listen_with<S, Req, Resp, E>(new_service: S,
                                addr: SocketAddr,
                                handle: &Handle,
                                _acceptor: Acceptor)
                                -> io::Result<SocketAddr>
    where S: NewService<Request = Result<Req, bincode::Error>,
                        Response = Response<Resp, E>,
                        Error = io::Error> + 'static,
          Req: Deserialize + 'static,
          Resp: Serialize + 'static,
          E: Serialize + 'static
{
    let listener = listener(&addr, handle)?;
    let addr = listener.local_addr()?;

    let handle2 = handle.clone();

    let server = listener.incoming()
        .and_then(move |(socket, _)| {
            #[cfg(feature = "tls")]
            match _acceptor {
                Acceptor::Tls(ref tls_acceptor) => {
                    future::Either::A(tls_acceptor.accept_async(socket)
                        .map(StreamType::Tls)
                        .map_err(native_to_io))
                }
                Acceptor::Tcp => future::Either::B(future::ok(StreamType::Tcp(socket))),
            }
            #[cfg(not(feature = "tls"))]
            future::ok(socket)
        })
        .for_each(move |socket| {
            Proto::new().bind_server(&handle2, socket, new_service.new_service()?);

            Ok(())
        })
        .map_err(|e| error!("While processing incoming connections: {}", e));
    handle.spawn(server);
    Ok(addr)
}

fn listener(addr: &SocketAddr, handle: &Handle) -> io::Result<TcpListener> {
    const PENDING_CONNECTION_BACKLOG: i32 = 1024;
    #[cfg(unix)]
    use net2::unix::UnixTcpBuilderExt;

    let builder = match *addr {
        SocketAddr::V4(_) => net2::TcpBuilder::new_v4(),
        SocketAddr::V6(_) => net2::TcpBuilder::new_v6(),
    }?;

    builder.reuse_address(true)?;

    #[cfg(unix)]
    builder.reuse_port(true)?;

    builder.bind(addr)?
        .listen(PENDING_CONNECTION_BACKLOG)
        .and_then(|l| TcpListener::from_listener(l, addr, handle))
}
<|endoftext|>


<commit_before>// なくてもよいモジュールだけれども、モジュール設計や実装方法などを理解するためにいったん書いてみる。

pub fn make_string() -> String {
    String::new()
}
// fn realloc_body() {} // なくてもいいかな?

pub fn string_append() {}
pub fn string_appendf() {}
<commit_msg>Add modules<commit_after>// なくてもよいモジュールだけれども、モジュール設計や実装方法などを理解するためにいったん書いてみる。

pub fn make_string() -> String {
    String::new()
}
// fn realloc_body() {} // なくてもいいかな?

pub fn string_append() {}
pub fn string_appendf() {}
<|endoftext|>


<commit_before>//! Contains the basic structures of an atomic system.
//!
//! A final system consists of a set of `Component`s. Each `Component`
//! in turn consists of a collection of `Residue`s, which
//! can be moved around and translated with ease. Each `Residue`
//! consists of some `Atom`s. These atoms have positions
//! relative to their parent.
//!
//! This somewhat convoluted structure is inherited from molecular
//! simulation packages in which atoms are commonly grouped as such.
//! A proper physical way to look at is that atoms can be
//! similarly grouped into molecules.

#[derive(Clone, Debug)]
/// A system component which consists of a list of residues,
/// each of which contains some atoms.
pub struct Component {
    /// Component origin position. All residue positions are relative to this.
    pub origin: Coord,
    /// Component boundary box size.
    pub box_size: Coord,
    /// Residue base of component.
    pub residue_base: ResidueBase,
    /// List of residue positions.
    pub residue_coords: Vec<Coord>,
}

impl Component {
    /// Count and return the number of atoms in the component.
    pub fn num_atoms(&self) -> usize {
        self.residue_base.atoms.len() * self.residue_coords.len()
    }

    /// Translate all residues within the component.
    /// TODO: Use relative coordinates.
    pub fn translate(mut self, add: &Coord) -> Component {
        self.origin = self.origin + *add;
        self
    }
}

/// Components (eg. `Sheet`, `Cylinder`) use this trait to define
/// common behaviour and conversion into a proper `Component` object.
pub trait IntoComponent {
    /// Copy residues to create a `Component` from the sub-component.
    fn to_component(&self) -> Component;

    /// Transform the sub-component into a `Component`.
    fn into_component(self) -> Component;

    /// Return the number of atoms of component.
    fn num_atoms(&self) -> usize;
}

/// Trait denoting the ability to `Translate` an object with a `Coord`.
pub trait Translate {
    fn translate(self, &Coord) -> Self;
}

/// Join a list of `Component`s into a single `Component`. The output `Component` box
/// is the maximum for all individual `Component`s along all axes. `Residue`s are
/// added in order to the list.
/*
pub fn merge_components<'a>(components: &[Component<'a>]) -> Component<'a> {
    components.into_iter()
        .fold(Component { origin: Coord::new(0.0, 0.0, 0.0), box_size: Coord::new(0.0, 0.0, 0.0), residues: vec![] },
            |acc, add_comp| {
                let (x0, y0, z0) = acc.box_size.to_tuple();
                let (x1, y1, z1) = add_comp.box_size.to_tuple();

                let box_size = Coord::new(x0.max(x1), y0.max(y1), z0.max(z1));

                let mut residues = acc.residues;
                residues.extend_from_slice(&add_comp.residues);

                Component { origin: Coord::new(0.0, 0.0, 0.0), box_size, residues }
            }
        )
}
*/

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
/// Every atom in a residue has their own code and relative
/// position some base coordinate.
pub struct Atom {
    /// Atom code.
    pub code: String,
    /// Relative position.
    pub position: Coord,
}

/// A base for generating atoms belonging to a residue.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct ResidueBase {
    pub code: String,
    pub atoms: Vec<Atom>,
}

#[macro_export]
/// Construct a ResidueBase with a code and atoms.
///
/// At least one atom has to be present in the base. This is not a limitation
/// when explicitly constructing a residue, but it makes no sense to allow
/// it when invoking a constructor like this.
///
/// # Examples
/// ```
/// # #[macro_use] extern crate grafen;
/// # use grafen::system::{Atom, Coord, ResidueBase};
/// # fn main() {
/// let expect = ResidueBase {
///     code: "RES".to_string(),
///     atoms: vec![
///         Atom { code: "A".to_string(), position: Coord::new(0.0, 0.0, 0.0) },
///         Atom { code: "B".to_string(), position: Coord::new(1.0, 2.0, 3.0) }
///     ],
/// };
///
/// let residue = resbase![
///     "RES",
///     ("A", 0.0, 0.0, 0.0),
///     ("B", 1.0, 2.0, 3.0)
/// ];
///
/// assert_eq!(expect, residue);
/// # }
/// ```
macro_rules! resbase {
    (
        $rescode:expr,
        $(($atname:expr, $x:expr, $y:expr, $z:expr)),+
    ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push(
                    Atom {
                        code: $atname.to_string(),
                        position: Coord::new($x, $y, $z),
                    }
                );
            )*

            ResidueBase {
                code: $rescode.to_string(),
                atoms: temp_vec,
            }
        }
    }
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
/// A three-dimensional coordinate.
///
/// # Examples
/// ```
/// # use grafen::system::Coord;
/// let coord1 = Coord::new(1.0, 0.0, 1.0);
/// let coord2 = Coord::new(0.5, 0.5, 0.5);
///
/// assert_eq!(Coord::new(1.5, 0.5, 1.5), coord1 + coord2);
/// assert_eq!(Coord::new(0.5, -0.5, 0.5), coord1 - coord2);
/// ```
pub struct Coord {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

use std::ops::{Add, Sub};

impl Coord {
    /// Construct a new coordinate.
    pub fn new(x: f64, y: f64, z: f64) -> Coord {
        Coord { x: x, y: y, z: z }
    }

    /// Unpack the coordinate into a tuple.
    pub fn to_tuple(&self) -> (f64, f64, f64) {
        (self.x, self.y, self.z)
    }

    /// Calculate the absolute distance between two coordinates.
    pub fn distance(self, other: Coord) -> f64 {
        let dx = self - other;

        (dx.x * dx.x + dx.y * dx.y + dx.z * dx.z).sqrt()
    }
}

impl Add for Coord {
    type Output = Coord;

    fn add(self, other: Coord) -> Coord {
        Coord::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }

}

impl Sub for Coord {
    type Output = Coord;

    fn sub(self, other: Coord) -> Coord {
        Coord::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }

}

impl PartialEq for Coord {
    fn eq(&self, other: &Coord) -> bool {
        let atol = 1e-9;
        (self.x - other.x).abs() < atol
            && (self.y - other.y).abs() < atol
            && (self.z - other.z).abs() < atol
    }
}

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

    #[test]
    fn coord_addition_and_subtraction() {
        let coord = Coord::new(0.0, 1.0, 2.0);
        assert_eq!(Coord::new(0.0, 2.0, 4.0), coord + coord);
        assert_eq!(Coord::new(0.0, 0.0, 0.0), coord - coord);

    }

    #[test]
    fn coord_eq_tolerance_small_deviation_passes() {
        // Allow for some deviation when testing for equality, since floating point
        // numbers are stupid.
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-10, 2e-10, 3e-10));
    }

    #[test]
    #[should_panic]
    fn coord_eq_tolerance_larger_deviation_does_not() {
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-9, 2e-9, 3e-9));
    }

    #[test]
    fn coord_distance_calc() {
        let coord1 = Coord::new(1.0, 1.0, 1.0);
        let coord2 = Coord::new(3.0, 3.0, 2.0);

        assert_eq!(3.0, Coord::distance(coord1, coord2));
        assert_eq!(3.0, coord1.distance(coord2));
    }

    #[test]
    fn coord_to_tuple() {
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!((1.0, 2.0, 3.0), coord.to_tuple());
    }

    // A simple component with two different residues and five atoms
    fn setup_component(base: &ResidueBase, num: usize) -> Component {
        Component {
            origin: Coord::new(0.0, 0.0, 0.0),
            box_size: Coord::new(0.0, 0.0, 0.0),
            residue_base: base.clone(),
            residue_coords: vec![Coord::new(0.0, 0.0, 0.0); num],
        }
    }

    #[test]
    fn count_atoms_in_component() {
        // A residue with three atoms duplicated twice
        let coord0 = Coord::new(0.0, 1.0, 2.0);
        let residue_base = ResidueBase {
            code: "R1".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: coord0, },
                Atom { code: "A2".to_string(), position: coord0, },
                Atom { code: "A3".to_string(), position: coord0, },
            ]
        };
        let component = setup_component(&residue_base, 2);

        assert_eq!(3 * 2, component.num_atoms());
    }

    #[test]
    fn translate_a_component() {
        let coord0 = Coord::new(0.0, 1.0, 2.0);
        let residue_base = ResidueBase {
            code: "R1".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: coord0, },
                Atom { code: "A2".to_string(), position: coord0, },
                Atom { code: "A3".to_string(), position: coord0, },
            ]
        };

        let component = setup_component(&residue_base, 1);
        let shift = Coord::new(0.0, 1.0, 2.0);

        let trans_component = component.clone().translate(&shift);
        for (orig, updated) in component.residue_coords.iter().zip(trans_component.residue_coords.iter()) {
            assert_eq!(orig, updated);
        }
        assert_eq!(component.origin + shift, trans_component.origin);
    }

    #[test]
    fn create_residue_base_macro() {
        let expect = ResidueBase {
            code: "RES".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: Coord::new(0.0, 0.0, 0.0) },
                Atom { code: "A2".to_string(), position: Coord::new(0.0, 1.0, 2.0) }
            ],
        };
        let result = resbase![
            "RES",
            ("A1", 0.0, 0.0, 0.0),
            ("A2", 0.0, 1.0, 2.0)
        ];

        assert_eq!(expect, result);
    }
}
<commit_msg>Add counter-clockwise rotation methods to `Component`<commit_after>//! Contains the basic structures of an atomic system.
//!
//! A final system consists of a set of `Component`s. Each `Component`
//! in turn consists of a collection of `Residue`s, which
//! can be moved around and translated with ease. Each `Residue`
//! consists of some `Atom`s. These atoms have positions
//! relative to their parent.
//!
//! This somewhat convoluted structure is inherited from molecular
//! simulation packages in which atoms are commonly grouped as such.
//! A proper physical way to look at is that atoms can be
//! similarly grouped into molecules.

#[derive(Clone, Debug)]
/// A system component which consists of a list of residues,
/// each of which contains some atoms.
pub struct Component {
    /// Component origin position. All residue positions are relative to this.
    pub origin: Coord,
    /// Component boundary box size.
    pub box_size: Coord,
    /// Residue base of component.
    pub residue_base: ResidueBase,
    /// List of residue positions.
    pub residue_coords: Vec<Coord>,
}

impl Component {
    /// Count and return the number of atoms in the component.
    pub fn num_atoms(&self) -> usize {
        self.residue_base.atoms.len() * self.residue_coords.len()
    }

    /// Translate all residues within the component.
    pub fn translate(mut self, add: &Coord) -> Self {
        self.origin = self.origin + *add;
        self
    }

    /// Rotate all coordinates along the x axis by 90 degrees, counter-clockwise.
    fn rotate_x(mut self) -> Self {
        for coord in self.residue_coords.iter_mut() {
            let y = coord.y;
            coord.y = -coord.z;
            coord.z = y;
        }

        let box_y = self.box_size.y;
        self.box_size.y = self.box_size.z;
        self.box_size.z = box_y;

        self
    }

    /// Rotate all coordinates along the y axis by 90 degrees, counter-clockwise.
    pub fn rotate_y(mut self) -> Self {
        for coord in self.residue_coords.iter_mut() {
            let x = coord.x;
            coord.x = -coord.z;
            coord.z = x;
        }

        let box_x = self.box_size.x;
        self.box_size.x = self.box_size.z;
        self.box_size.z = box_x;

        self
    }

    /// Rotate all coordinates along the z axis by 90 degrees, counter-clockwise.
    fn rotate_z(mut self) -> Self {
        for coord in self.residue_coords.iter_mut() {
            let x = coord.x;
            coord.x = -coord.y;
            coord.y = x;
        }

        let box_x = self.box_size.x;
        self.box_size.x = self.box_size.y;
        self.box_size.y = box_x;

        self
    }
}

/// Components (eg. `Sheet`, `Cylinder`) use this trait to define
/// common behaviour and conversion into a proper `Component` object.
pub trait IntoComponent {
    /// Copy residues to create a `Component` from the sub-component.
    fn to_component(&self) -> Component;

    /// Transform the sub-component into a `Component`.
    fn into_component(self) -> Component;

    /// Return the number of atoms of component.
    fn num_atoms(&self) -> usize;
}

/// Trait denoting the ability to `Translate` an object with a `Coord`.
pub trait Translate {
    fn translate(self, &Coord) -> Self;
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
/// Every atom in a residue has their own code and relative
/// position some base coordinate.
pub struct Atom {
    /// Atom code.
    pub code: String,
    /// Relative position.
    pub position: Coord,
}

/// A base for generating atoms belonging to a residue.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct ResidueBase {
    pub code: String,
    pub atoms: Vec<Atom>,
}

#[macro_export]
/// Construct a ResidueBase with a code and atoms.
///
/// At least one atom has to be present in the base. This is not a limitation
/// when explicitly constructing a residue, but it makes no sense to allow
/// it when invoking a constructor like this.
///
/// # Examples
/// ```
/// # #[macro_use] extern crate grafen;
/// # use grafen::system::{Atom, Coord, ResidueBase};
/// # fn main() {
/// let expect = ResidueBase {
///     code: "RES".to_string(),
///     atoms: vec![
///         Atom { code: "A".to_string(), position: Coord::new(0.0, 0.0, 0.0) },
///         Atom { code: "B".to_string(), position: Coord::new(1.0, 2.0, 3.0) }
///     ],
/// };
///
/// let residue = resbase![
///     "RES",
///     ("A", 0.0, 0.0, 0.0),
///     ("B", 1.0, 2.0, 3.0)
/// ];
///
/// assert_eq!(expect, residue);
/// # }
/// ```
macro_rules! resbase {
    (
        $rescode:expr,
        $(($atname:expr, $x:expr, $y:expr, $z:expr)),+
    ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push(
                    Atom {
                        code: $atname.to_string(),
                        position: Coord::new($x, $y, $z),
                    }
                );
            )*

            ResidueBase {
                code: $rescode.to_string(),
                atoms: temp_vec,
            }
        }
    }
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
/// A three-dimensional coordinate.
///
/// # Examples
/// ```
/// # use grafen::system::Coord;
/// let coord1 = Coord::new(1.0, 0.0, 1.0);
/// let coord2 = Coord::new(0.5, 0.5, 0.5);
///
/// assert_eq!(Coord::new(1.5, 0.5, 1.5), coord1 + coord2);
/// assert_eq!(Coord::new(0.5, -0.5, 0.5), coord1 - coord2);
/// ```
pub struct Coord {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

use std::ops::{Add, Sub};

impl Coord {
    /// Construct a new coordinate.
    pub fn new(x: f64, y: f64, z: f64) -> Coord {
        Coord { x: x, y: y, z: z }
    }

    /// Unpack the coordinate into a tuple.
    pub fn to_tuple(&self) -> (f64, f64, f64) {
        (self.x, self.y, self.z)
    }

    /// Calculate the absolute distance between two coordinates.
    pub fn distance(self, other: Coord) -> f64 {
        let dx = self - other;

        (dx.x * dx.x + dx.y * dx.y + dx.z * dx.z).sqrt()
    }
}

impl Add for Coord {
    type Output = Coord;

    fn add(self, other: Coord) -> Coord {
        Coord::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }

}

impl Sub for Coord {
    type Output = Coord;

    fn sub(self, other: Coord) -> Coord {
        Coord::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }

}

impl PartialEq for Coord {
    fn eq(&self, other: &Coord) -> bool {
        let atol = 1e-9;
        (self.x - other.x).abs() < atol
            && (self.y - other.y).abs() < atol
            && (self.z - other.z).abs() < atol
    }
}

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

    #[test]
    fn coord_addition_and_subtraction() {
        let coord = Coord::new(0.0, 1.0, 2.0);
        assert_eq!(Coord::new(0.0, 2.0, 4.0), coord + coord);
        assert_eq!(Coord::new(0.0, 0.0, 0.0), coord - coord);

    }

    #[test]
    fn coord_eq_tolerance_small_deviation_passes() {
        // Allow for some deviation when testing for equality, since floating point
        // numbers are stupid.
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-10, 2e-10, 3e-10));
    }

    #[test]
    #[should_panic]
    fn coord_eq_tolerance_larger_deviation_does_not() {
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-9, 2e-9, 3e-9));
    }

    #[test]
    fn coord_distance_calc() {
        let coord1 = Coord::new(1.0, 1.0, 1.0);
        let coord2 = Coord::new(3.0, 3.0, 2.0);

        assert_eq!(3.0, Coord::distance(coord1, coord2));
        assert_eq!(3.0, coord1.distance(coord2));
    }

    #[test]
    fn coord_to_tuple() {
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!((1.0, 2.0, 3.0), coord.to_tuple());
    }

    // A simple component with two different residues and five atoms
    fn setup_component(base: &ResidueBase, num: usize) -> Component {
        Component {
            origin: Coord::new(0.0, 0.0, 0.0),
            box_size: Coord::new(0.0, 0.0, 0.0),
            residue_base: base.clone(),
            residue_coords: vec![Coord::new(0.0, 0.0, 0.0); num],
        }
    }

    #[test]
    fn count_atoms_in_component() {
        // A residue with three atoms duplicated twice
        let coord0 = Coord::new(0.0, 1.0, 2.0);
        let residue_base = ResidueBase {
            code: "R1".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: coord0, },
                Atom { code: "A2".to_string(), position: coord0, },
                Atom { code: "A3".to_string(), position: coord0, },
            ]
        };
        let component = setup_component(&residue_base, 2);

        assert_eq!(3 * 2, component.num_atoms());
    }

    #[test]
    fn translate_a_component() {
        let coord0 = Coord::new(0.0, 1.0, 2.0);
        let residue_base = ResidueBase {
            code: "R1".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: coord0, },
                Atom { code: "A2".to_string(), position: coord0, },
                Atom { code: "A3".to_string(), position: coord0, },
            ]
        };

        let component = setup_component(&residue_base, 1);
        let shift = Coord::new(0.0, 1.0, 2.0);

        let trans_component = component.clone().translate(&shift);
        for (orig, updated) in component.residue_coords.iter().zip(trans_component.residue_coords.iter()) {
            assert_eq!(orig, updated);
        }
        assert_eq!(component.origin + shift, trans_component.origin);
    }

    #[test]
    fn create_residue_base_macro() {
        let expect = ResidueBase {
            code: "RES".to_string(),
            atoms: vec![
                Atom { code: "A1".to_string(), position: Coord::new(0.0, 0.0, 0.0) },
                Atom { code: "A2".to_string(), position: Coord::new(0.0, 1.0, 2.0) }
            ],
        };
        let result = resbase![
            "RES",
            ("A1", 0.0, 0.0, 0.0),
            ("A2", 0.0, 1.0, 2.0)
        ];

        assert_eq!(expect, result);
    }

    #[test]
    fn rotate_component_around_yxz() {
        let residue = resbase![
            "RES",
            ("A", 0.0, 0.0, 0.0)
        ];

        let origin = Coord::new(1.0, 1.0, 1.0);

        let component = Component {
            origin,
            box_size: Coord::new(2.0, 5.0, 8.0),
            residue_base: residue,
            residue_coords: vec![
                Coord::new(0.0, 3.0, 6.0),
                Coord::new(1.0, 4.0, 7.0),
                Coord::new(2.0, 5.0, 8.0),
            ],
        };

        let rotated_y = component.rotate_y();

        {
            assert_eq!(origin, rotated_y.origin);
            assert_eq!(Coord::new(8.0, 5.0, 2.0), rotated_y.box_size);

            // Our 90 degree rotation is counter-clockwise.
            let mut iter = rotated_y.residue_coords.iter();
            assert_eq!(&Coord::new(-6.0, 3.0, 0.0), iter.next().unwrap());
            assert_eq!(&Coord::new(-7.0, 4.0, 1.0), iter.next().unwrap());
            assert_eq!(&Coord::new(-8.0, 5.0, 2.0), iter.next().unwrap());
            assert_eq!(None, iter.next());
        }

        let rotated_yx = rotated_y.rotate_x();
        {
            assert_eq!(origin, rotated_yx.origin);
            assert_eq!(Coord::new(8.0, 2.0, 5.0), rotated_yx.box_size);
            let mut iter = rotated_yx.residue_coords.iter();
            assert_eq!(&Coord::new(-6.0, 0.0, 3.0), iter.next().unwrap());
            assert_eq!(&Coord::new(-7.0, -1.0, 4.0), iter.next().unwrap());
            assert_eq!(&Coord::new(-8.0, -2.0, 5.0), iter.next().unwrap());
            assert_eq!(None, iter.next());
        }

        let rotated_yxz = rotated_yx.rotate_z();
        {
            assert_eq!(origin, rotated_yxz.origin);
            assert_eq!(Coord::new(2.0, 8.0, 5.0), rotated_yxz.box_size);
            let mut iter = rotated_yxz.residue_coords.iter();
            assert_eq!(&Coord::new(0.0, -6.0, 3.0), iter.next().unwrap());
            assert_eq!(&Coord::new(1.0, -7.0, 4.0), iter.next().unwrap());
            assert_eq!(&Coord::new(2.0, -8.0, 5.0), iter.next().unwrap());
            assert_eq!(None, iter.next());
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use {Word, Result};
use private::layout::{CapTable, StructReader, StructBuilder, StructSize, PointerBuilder, PointerReader};

pub trait FromStructReader<'a> {
    fn new(reader : StructReader<'a>) -> Self;
}

pub trait HasStructSize {
    fn struct_size() -> StructSize;
}

pub trait FromStructBuilder<'a> {
    fn new(structBuilder: StructBuilder<'a>) -> Self;
}

pub trait FromPointerReader<'a> : Sized {
    fn get_from_pointer(reader: &PointerReader<'a>) -> Result<Self>;
}

/// Associated types hackery that allows us to reason about Cap'n Proto types
/// without needing to give them a lifetime `'a`.
///
/// If `Foo` is a Cap'n Proto struct and `Bar` is a Rust-native struct, then
/// `foo::Reader<'a>` is to `foo::Owned` as `&'a Bar` is to `Bar`, and
/// `foo::Builder<'a>` is to `foo::Owned` as `&'a mut Bar` is to `Bar`.
/// The relationship is formalized by an `impl <'a> capnp::traits::Owned<'a> for foo::Owned`.
/// Because Cap'n Proto struct layout differs from Rust struct layout,
/// `foo::Owned` cannot be an inhabited type; it is useful nonetheless
/// as a type parameter, e.g. for a generic container that owns a Cap'n Proto message
/// of type `T: for<'a> capnp::traits::Owned<'a>`.
pub trait Owned<'a> {
    type Reader: FromPointerReader<'a> + SetPointerBuilder<Self::Builder>;
    type Builder: FromPointerBuilder<'a>;
}

pub trait OwnedStruct<'a> {
    type Reader: FromStructReader<'a> + SetPointerBuilder<Self::Builder>;
    type Builder: FromStructBuilder<'a> + HasStructSize;
}

pub trait Pipelined {
    type Pipeline;
}

pub trait FromPointerReaderRefDefault<'a> {
    fn get_from_pointer(reader: &PointerReader<'a>, default_value : *const Word) -> Self;
}

pub trait FromPointerBuilder<'a> : Sized {
    fn init_pointer(PointerBuilder<'a>, u32) -> Self;
    fn get_from_pointer(builder: PointerBuilder<'a>) -> Result<Self>;
}

pub trait FromPointerBuilderRefDefault<'a> {
    fn get_from_pointer(builder: PointerBuilder<'a>, default_value: *const Word) -> Self;
}

pub trait SetPointerBuilder<To> {
    fn set_pointer_builder<'a>(PointerBuilder<'a>, Self) -> Result<()>;
}

pub trait Imbue<'a> {
    fn imbue(&mut self, &'a CapTable);
}

pub trait ImbueMut<'a> {
    fn imbue_mut(&mut self, &'a mut CapTable);
}

pub trait HasTypeId {
    fn type_id() -> u64;
}

pub trait ToU16 {
    fn to_u16(self) -> u16;
}

pub trait FromU16 : Sized {
    fn from_u16(value: u16) -> ::std::result::Result<Self, ::NotInSchema>;
}

pub trait IndexMove<I, T> {
    fn index_move(&self, index: I) -> T;
}

pub struct ListIter<T, U> {
    marker : ::std::marker::PhantomData<U>,
    list : T,
    index : u32,
    size : u32,
}

impl <T, U> ListIter<T, U>{
    pub fn new(list : T, size : u32) -> ListIter<T, U> {
        ListIter { list : list, index : 0, size : size, marker : ::std::marker::PhantomData }
    }
}

impl <U, T : IndexMove<u32, U>> ::std::iter::Iterator for ListIter<T, U> {
    type Item = U;
    fn next(&mut self) -> ::std::option::Option<U> {
        if self.index < self.size {
            let result = self.list.index_move(self.index);
            self.index += 1;
            return Some(result);
        } else {
            return None;
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>){
        (self.size as usize, Some(self.size as usize))
    }

    fn nth(&mut self, p: usize) -> Option<U>{
        if p < self.size as usize {
            self.index = p as u32;
            let result = self.list.index_move(self.index);
            return Some(result)
        } else {
            None
        }
    }
}

impl <U, T: IndexMove<u32, U>> ::std::iter::ExactSizeIterator for ListIter<T, U>{
    fn len(&self) -> usize{
        self.size as usize
    }
}
<commit_msg>Implement DoubleEndedIter for ListIter<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use {Word, Result};
use private::layout::{CapTable, StructReader, StructBuilder, StructSize, PointerBuilder, PointerReader};

pub trait FromStructReader<'a> {
    fn new(reader : StructReader<'a>) -> Self;
}

pub trait HasStructSize {
    fn struct_size() -> StructSize;
}

pub trait FromStructBuilder<'a> {
    fn new(structBuilder: StructBuilder<'a>) -> Self;
}

pub trait FromPointerReader<'a> : Sized {
    fn get_from_pointer(reader: &PointerReader<'a>) -> Result<Self>;
}

/// Associated types hackery that allows us to reason about Cap'n Proto types
/// without needing to give them a lifetime `'a`.
///
/// If `Foo` is a Cap'n Proto struct and `Bar` is a Rust-native struct, then
/// `foo::Reader<'a>` is to `foo::Owned` as `&'a Bar` is to `Bar`, and
/// `foo::Builder<'a>` is to `foo::Owned` as `&'a mut Bar` is to `Bar`.
/// The relationship is formalized by an `impl <'a> capnp::traits::Owned<'a> for foo::Owned`.
/// Because Cap'n Proto struct layout differs from Rust struct layout,
/// `foo::Owned` cannot be an inhabited type; it is useful nonetheless
/// as a type parameter, e.g. for a generic container that owns a Cap'n Proto message
/// of type `T: for<'a> capnp::traits::Owned<'a>`.
pub trait Owned<'a> {
    type Reader: FromPointerReader<'a> + SetPointerBuilder<Self::Builder>;
    type Builder: FromPointerBuilder<'a>;
}

pub trait OwnedStruct<'a> {
    type Reader: FromStructReader<'a> + SetPointerBuilder<Self::Builder>;
    type Builder: FromStructBuilder<'a> + HasStructSize;
}

pub trait Pipelined {
    type Pipeline;
}

pub trait FromPointerReaderRefDefault<'a> {
    fn get_from_pointer(reader: &PointerReader<'a>, default_value : *const Word) -> Self;
}

pub trait FromPointerBuilder<'a> : Sized {
    fn init_pointer(PointerBuilder<'a>, u32) -> Self;
    fn get_from_pointer(builder: PointerBuilder<'a>) -> Result<Self>;
}

pub trait FromPointerBuilderRefDefault<'a> {
    fn get_from_pointer(builder: PointerBuilder<'a>, default_value: *const Word) -> Self;
}

pub trait SetPointerBuilder<To> {
    fn set_pointer_builder<'a>(PointerBuilder<'a>, Self) -> Result<()>;
}

pub trait Imbue<'a> {
    fn imbue(&mut self, &'a CapTable);
}

pub trait ImbueMut<'a> {
    fn imbue_mut(&mut self, &'a mut CapTable);
}

pub trait HasTypeId {
    fn type_id() -> u64;
}

pub trait ToU16 {
    fn to_u16(self) -> u16;
}

pub trait FromU16 : Sized {
    fn from_u16(value: u16) -> ::std::result::Result<Self, ::NotInSchema>;
}

pub trait IndexMove<I, T> {
    fn index_move(&self, index: I) -> T;
}

pub struct ListIter<T, U> {
    marker : ::std::marker::PhantomData<U>,
    list : T,
    index : u32,
    size : u32,
}

impl <T, U> ListIter<T, U>{
    pub fn new(list : T, size : u32) -> ListIter<T, U> {
        ListIter { list : list, index : 0, size : size, marker : ::std::marker::PhantomData }
    }
}

impl <U, T : IndexMove<u32, U>> ::std::iter::Iterator for ListIter<T, U> {
    type Item = U;
    fn next(&mut self) -> ::std::option::Option<U> {
        if self.index < self.size {
            let result = self.list.index_move(self.index);
            self.index += 1;
            return Some(result);
        } else {
            return None;
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>){
        (self.size as usize, Some(self.size as usize))
    }

    fn nth(&mut self, p: usize) -> Option<U>{
        if p < self.size as usize {
            self.index = p as u32;
            let result = self.list.index_move(self.index);
            return Some(result)
        } else {
            None
        }
    }
}

impl <U, T: IndexMove<u32, U>> ::std::iter::ExactSizeIterator for ListIter<T, U>{
    fn len(&self) -> usize{
        self.size as usize
    }
}

impl <U, T: IndexMove<u32, U>> ::std::iter::DoubleEndedIterator for ListIter<T, U>{
    fn next_back(&mut self) -> ::std::option::Option<U> {
        if self.size > self.index {
            self.size -= 1;
            Some(self.list.index_move(self.size))
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;

pub use self::screen::Screen;

mod screen;

/// Abstract object that can be created to initialize and access the UI
pub struct UI;

impl UI {
	/// Create an abstract UI object (initializes SDL2 until dropped)
	pub fn new () -> UI {
		match sdl2::init([sdl2::InitVideo]) {
			false => fail!("ui: Failed to initialize SDL2: {}", sdl2::get_error()),
			true => UI,
		}
	}

	/// Runs the UI loop and the given closure. Must be called from
	/// the main thread (SDL2 requirement)
	pub fn run (&mut self, f: ||) {
		loop {
			match sdl2::event::poll_event() {
				sdl2::event::QuitEvent(..) => break,
				sdl2::event::KeyDownEvent(_, _, sdl2::keycode::EscapeKey, _, _) => break,
				_ => { },
			}
			f()
		}
	}
}

impl Drop for UI {
	fn drop (&mut self) {
		sdl2::quit();
	}
}

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

	#[test]
	fn smoke () {
		let mut ui = UI::new();
		ui.run(|| { });
	}
}
<commit_msg>Allow closure for UI loop to return false to break the loop<commit_after>extern crate sdl2;

pub use self::screen::Screen;

mod screen;

/// Abstract object that can be created to initialize and access the UI
pub struct UI;

impl UI {
	/// Create an abstract UI object (initializes SDL2 until dropped)
	pub fn new () -> UI {
		match sdl2::init([sdl2::InitVideo]) {
			false => fail!("ui: Failed to initialize SDL2: {}", sdl2::get_error()),
			true => UI,
		}
	}

	/// Runs the UI loop and the given closure. Must be called from
	/// the main thread (SDL2 requirement)
	pub fn run (&mut self, f: || -> bool) {
		loop {
			match sdl2::event::poll_event() {
				sdl2::event::QuitEvent(..) => break,
				sdl2::event::KeyDownEvent(_, _, sdl2::keycode::EscapeKey, _, _) => break,
				_ => { },
			}
			if !f() { break; }
		}
	}
}

impl Drop for UI {
	fn drop (&mut self) {
		sdl2::quit();
	}
}

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

	#[test]
	fn smoke () {
		let mut ui = UI::new();
		ui.run(|| { false });
	}
}
<|endoftext|>


<commit_before>use std::ops::{
    Add,
    Sub,
    Mul,
    Div,
};

use num::{
    Zero,
};

macro_rules! vec_self_binop_impl {
    ($imp:ident, $method:ident for $vec:ident, $($field:ident),+) => {
        impl $imp for $vec {
            type Output = Self;

            #[inline]
            fn $method(self, other: Self) -> Self::Output {
                $vec { $($field: self.$field.$method(other.$field)),+ }
            }
        }
        binop_ref_impl! { $imp, $method for $vec, $vec }
    }
}

macro_rules! vec_float_binop_impl {
    ($imp:ident, $method:ident for $vec:ident, $($field:ident),+) => {
        impl $imp<f32> for $vec {
            type Output = Self;

            #[inline]
            fn $method(self, other: f32) -> Self::Output {
                $vec { $($field: self.$field.$method(other)),+ }
            }
        }
        binop_ref_impl! { $imp, $method for $vec, f32 }
    }
}

macro_rules! vec_zero_impl {
    ($vec:ident, $($field:ident),+) => {
        impl Zero for $vec {
            fn zero() -> Self {
                $vec { $($field: f32::zero()),+ }
            }

            fn is_zero(&self) -> bool {
                *self == Self::zero()
            }
        }
    }
}

macro_rules! vec_new_impl {
    ($vec:ident, $($field:ident),+) => {
        impl $vec {
            fn new($($field: f32),+) -> $vec {
                $vec { $($field: $field),+ }
            }
        }
    }
}

macro_rules! vec_impl {
    ($vec:ident, $($field:ident),+) => {
        vec_new_impl!{ $vec, $($field),+ }
        vec_zero_impl!{ $vec, $($field),+ }

        vec_self_binop_impl!{ Add, add for $vec, $($field),+ }
        vec_self_binop_impl!{ Sub, sub for $vec, $($field),+ }

        vec_float_binop_impl!{ Add, add for $vec, $($field),+ }
        vec_float_binop_impl!{ Sub, sub for $vec, $($field),+ }
        vec_float_binop_impl!{ Mul, mul for $vec, $($field),+ }
        vec_float_binop_impl!{ Div, div for $vec, $($field),+ }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}
vec_impl!(Vec2, x, y);

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}
vec_impl!(Vec3, x, y, z);

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec4 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}
vec_impl!(Vec4, x, y, z, w);
<commit_msg>as array impl<commit_after>use std::ops::{
    Add,
    Sub,
    Mul,
    Div,
};

use std::mem;

use num::{
    Zero,
};

macro_rules! vec_self_binop_impl {
    ($imp:ident, $method:ident for $vec:ident, $($field:ident),+) => {
        impl $imp for $vec {
            type Output = Self;

            #[inline]
            fn $method(self, other: Self) -> Self::Output {
                $vec { $($field: self.$field.$method(other.$field)),+ }
            }
        }
        binop_ref_impl! { $imp, $method for $vec, $vec }
    }
}

macro_rules! vec_float_binop_impl {
    ($imp:ident, $method:ident for $vec:ident, $($field:ident),+) => {
        impl $imp<f32> for $vec {
            type Output = Self;

            #[inline]
            fn $method(self, other: f32) -> Self::Output {
                $vec { $($field: self.$field.$method(other)),+ }
            }
        }
        binop_ref_impl! { $imp, $method for $vec, f32 }
    }
}

macro_rules! vec_zero_impl {
    ($vec:ident, $($field:ident),+) => {
        impl Zero for $vec {
            fn zero() -> Self {
                $vec { $($field: f32::zero()),+ }
            }

            fn is_zero(&self) -> bool {
                *self == Self::zero()
            }
        }
    }
}

macro_rules! vec_new_impl {
    ($vec:ident, $($field:ident),+) => {
        impl $vec {
            fn new($($field: f32),+) -> $vec {
                $vec { $($field: $field),+ }
            }
        }
    }
}

macro_rules! vec_as_array_impl {
    ($vec:ident, $n:expr) => {
        impl $vec {
            pub fn as_array(&self) -> &[f32; $n] {
                unsafe {
                    mem::transmute(self)
                }
            }

            pub fn as_array_mut(&mut self) -> &mut [f32; $n] {
                unsafe {
                    mem::transmute(self)
                }
            }
        }
    }
}

macro_rules! vec_impl {
    ($vec:ident, $n:expr, $($field:ident),+) => {
        vec_new_impl!{ $vec, $($field),+ }
        vec_zero_impl!{ $vec, $($field),+ }

        vec_self_binop_impl!{ Add, add for $vec, $($field),+ }
        vec_self_binop_impl!{ Sub, sub for $vec, $($field),+ }

        vec_float_binop_impl!{ Add, add for $vec, $($field),+ }
        vec_float_binop_impl!{ Sub, sub for $vec, $($field),+ }
        vec_float_binop_impl!{ Mul, mul for $vec, $($field),+ }
        vec_float_binop_impl!{ Div, div for $vec, $($field),+ }

        vec_as_array_impl!{ $vec, $n }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}
vec_impl!(Vec2, 2, x, y);

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}
vec_impl!(Vec3, 3, x, y, z);

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec4 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}
vec_impl!(Vec4, 4, x, y, z, w);
<|endoftext|>


<commit_before>use fixpoint::{Fix, fix, fix_result};

use super::term::Term;

#[derive (Debug, PartialEq, Eq)]
pub enum Ctx<T> {
    Top,
    Abs(Box<Ctx<T>>),
    AppL(Box<Ctx<T>>, Term<T>),
    AppR(Term<T>, Box<Ctx<T>>),
    Let(Box<Ctx<T>>),
}

#[derive (Debug, PartialEq, Eq)]
enum Bind<T> {
    Var(String, T),
    Let(String, Option<(T, Box<Term<T>>)>)
}

impl<T> Bind<T> {

    fn is_identified_by(&self, id: &str) -> bool {
        match self {
            &Bind::Var(ref s, _) => id == s,
            &Bind::Let(ref s, _) => id == s
        }
    }

    fn take(&mut self) -> Option<(T, Box<Term<T>>)> where T: Clone {
        match self {
            &mut Bind::Var(ref s, ref y) => Some((y.clone(), Box::new(Term::Var(s.clone())))),
            &mut Bind::Let(_, ref mut o) => o.take()
        }
    }

}

#[derive (Debug, PartialEq, Eq)]
pub struct Env<T>(Vec<Bind<T>>);

impl<T> Env<T> {

    pub fn new() -> Env<T> {
        Env(Vec::new())
    }

    pub fn push_var(&mut self, s: String, y: T) {
        self.0.push(Bind::Var(s, y))
    }

    pub fn push_let(&mut self, s: String, o: Option<(T, Box<Term<T>>)>) {
        self.0.push(Bind::Let(s, o))
    }

    pub fn pop_var(&mut self) -> (String, T) {
        self.0.pop().map(|bind| {
            match bind {
                Bind::Let(_, _) => panic!("tried to pop a let"),
                Bind::Var(s, y) => (s, y)
            }
        }).unwrap()
    }

    pub fn pop_let(&mut self) -> (String, Option<(T, Box<Term<T>>)>) {
        self.0.pop().map(|bind| {
            match bind {
                Bind::Let(s, o) => (s, o),
                Bind::Var(_, _) => panic!("tried to pop a var")
            }
        }).unwrap()
    }

    pub fn take(&mut self, s: &str) -> Option<(T, Box<Term<T>>)> where T: Clone {
        self.0.iter_mut().rev().find(|&&mut ref bind| {
            bind.is_identified_by(s)
        }).and_then(|&mut ref mut bind| bind.take())
    }

}

#[derive (Debug, PartialEq, Eq)]
pub struct Loc<T>(pub Term<T>, pub Ctx<T>, pub Env<T>);

impl<T> Loc<T> {

    pub fn get(self) -> Term<T> {
        self.0
    }

    pub fn set(self, term: Term<T>) -> Loc<T> {
        Loc(term, self.1, self.2)
    }

    pub fn down(self) -> Fix<Loc<T>> {
        match self {
            Loc(Term::Abs(s, y, t1), c, mut e) => {
                e.push_var(s, y);
                Fix::Pro(Loc(*t1, Ctx::Abs(Box::new(c)), e))
            },
            Loc(Term::App(t1, t2), c, e) => Fix::Pro(Loc(*t1, Ctx::AppL(Box::new(c), *t2), e)),
            Loc(Term::Let(s, o, t1), c, mut e) => {
                e.push_let(s, o);
                Fix::Pro(Loc(*t1, Ctx::Let(Box::new(c)), e))
            },
            _ => Fix::Fix(self)
        }
    }

    pub fn up(self) -> Fix<Loc<T>> {
        match self {
            Loc(t1, Ctx::Abs(c), mut e) => {
                let (s, y) = e.pop_var();
                Fix::Pro(Loc(Term::abs(s, y, t1), *c, e))
            },
            Loc(t1, Ctx::AppL(c, t2), e) => Fix::Pro(Loc(Term::app(t1, t2), *c, e)),
            Loc(t2, Ctx::AppR(t1, c), e) => Fix::Pro(Loc(Term::app(t1, t2), *c, e)),
            Loc(t1, Ctx::Let(c), mut e) => {
                let (s, o) = e.pop_let();
                Fix::Pro(Loc(Term::Let(s, o, Box::new(t1)), *c, e))
            },
            _ => Fix::Fix(self)
        }
    }

    pub fn left(self) -> Fix<Loc<T>> {
        match self {
            Loc(t2, Ctx::AppR(t1, c), e) => Fix::Pro(Loc(t1, Ctx::AppL(c, t2), e)),
            _ => Fix::Fix(self)
        }
    }

    pub fn right(self) -> Fix<Loc<T>> {
        match self {
            Loc(t1, Ctx::AppL(c, t2), e) => Fix::Pro(Loc(t2, Ctx::AppR(t1, c), e)),
            _ => Fix::Fix(self)
        }
    }

    pub fn top(term: Term<T>) -> Loc<T> {
        Loc(term, Ctx::Top, Env::new())
    }

    pub fn fix<F: FnMut(Loc<T>) -> Fix<Loc<T>>>(self, mut f: F) -> Term<T> {
        fix(self, |loc| {
            match f(loc) {
                Fix::Fix(loc) => loc.up(),
                fix => fix
            }
        }).get()
    }

    pub fn fix_result<E, F: FnMut(Loc<T>) -> Result<Fix<Loc<T>>, E>>(self, mut f: F) -> Result<Term<T>, E> {
        fix_result(self, |loc| {
            f(loc).map(|fix| match fix {
                Fix::Fix(loc) => loc.up(),
                _ => fix
            })
        }).map(Loc::get)
    }

}
<commit_msg>make fragile zipper functions private<commit_after>use fixpoint::{Fix, fix, fix_result};

use super::term::Term;

#[derive (Debug, PartialEq, Eq)]
pub enum Ctx<T> {
    Top,
    Abs(Box<Ctx<T>>),
    AppL(Box<Ctx<T>>, Term<T>),
    AppR(Term<T>, Box<Ctx<T>>),
    Let(Box<Ctx<T>>),
}

#[derive (Debug, PartialEq, Eq)]
enum Bind<T> {
    Var(String, T),
    Let(String, Option<(T, Box<Term<T>>)>)
}

impl<T> Bind<T> {

    fn is_identified_by(&self, id: &str) -> bool {
        match self {
            &Bind::Var(ref s, _) => id == s,
            &Bind::Let(ref s, _) => id == s
        }
    }

    fn take(&mut self) -> Option<(T, Box<Term<T>>)> where T: Clone {
        match self {
            &mut Bind::Var(ref s, ref y) => Some((y.clone(), Box::new(Term::Var(s.clone())))),
            &mut Bind::Let(_, ref mut o) => o.take()
        }
    }

}

#[derive (Debug, PartialEq, Eq)]
pub struct Env<T>(Vec<Bind<T>>);

impl<T> Env<T> {

    fn new() -> Env<T> {
        Env(Vec::new())
    }

    fn push_var(&mut self, s: String, y: T) {
        self.0.push(Bind::Var(s, y))
    }

    fn push_let(&mut self, s: String, o: Option<(T, Box<Term<T>>)>) {
        self.0.push(Bind::Let(s, o))
    }

    fn pop_var(&mut self) -> (String, T) {
        self.0.pop().map(|bind| {
            match bind {
                Bind::Let(_, _) => panic!("tried to pop a let"),
                Bind::Var(s, y) => (s, y)
            }
        }).unwrap()
    }

    fn pop_let(&mut self) -> (String, Option<(T, Box<Term<T>>)>) {
        self.0.pop().map(|bind| {
            match bind {
                Bind::Let(s, o) => (s, o),
                Bind::Var(_, _) => panic!("tried to pop a var")
            }
        }).unwrap()
    }

    pub fn take(&mut self, s: &str) -> Option<(T, Box<Term<T>>)> where T: Clone {
        self.0.iter_mut().rev().find(|&&mut ref bind| {
            bind.is_identified_by(s)
        }).and_then(|&mut ref mut bind| bind.take())
    }

}

#[derive (Debug, PartialEq, Eq)]
pub struct Loc<T>(pub Term<T>, pub Ctx<T>, pub Env<T>);

impl<T> Loc<T> {

    pub fn get(self) -> Term<T> {
        self.0
    }

    pub fn set(self, term: Term<T>) -> Loc<T> {
        Loc(term, self.1, self.2)
    }

    pub fn down(self) -> Fix<Loc<T>> {
        match self {
            Loc(Term::Abs(s, y, t1), c, mut e) => {
                e.push_var(s, y);
                Fix::Pro(Loc(*t1, Ctx::Abs(Box::new(c)), e))
            },
            Loc(Term::App(t1, t2), c, e) => Fix::Pro(Loc(*t1, Ctx::AppL(Box::new(c), *t2), e)),
            Loc(Term::Let(s, o, t1), c, mut e) => {
                e.push_let(s, o);
                Fix::Pro(Loc(*t1, Ctx::Let(Box::new(c)), e))
            },
            _ => Fix::Fix(self)
        }
    }

    pub fn up(self) -> Fix<Loc<T>> {
        match self {
            Loc(t1, Ctx::Abs(c), mut e) => {
                let (s, y) = e.pop_var();
                Fix::Pro(Loc(Term::abs(s, y, t1), *c, e))
            },
            Loc(t1, Ctx::AppL(c, t2), e) => Fix::Pro(Loc(Term::app(t1, t2), *c, e)),
            Loc(t2, Ctx::AppR(t1, c), e) => Fix::Pro(Loc(Term::app(t1, t2), *c, e)),
            Loc(t1, Ctx::Let(c), mut e) => {
                let (s, o) = e.pop_let();
                Fix::Pro(Loc(Term::Let(s, o, Box::new(t1)), *c, e))
            },
            _ => Fix::Fix(self)
        }
    }

    pub fn left(self) -> Fix<Loc<T>> {
        match self {
            Loc(t2, Ctx::AppR(t1, c), e) => Fix::Pro(Loc(t1, Ctx::AppL(c, t2), e)),
            _ => Fix::Fix(self)
        }
    }

    pub fn right(self) -> Fix<Loc<T>> {
        match self {
            Loc(t1, Ctx::AppL(c, t2), e) => Fix::Pro(Loc(t2, Ctx::AppR(t1, c), e)),
            _ => Fix::Fix(self)
        }
    }

    pub fn top(term: Term<T>) -> Loc<T> {
        Loc(term, Ctx::Top, Env::new())
    }

    pub fn fix<F: FnMut(Loc<T>) -> Fix<Loc<T>>>(self, mut f: F) -> Term<T> {
        fix(self, |loc| {
            match f(loc) {
                Fix::Fix(loc) => loc.up(),
                fix => fix
            }
        }).get()
    }

    pub fn fix_result<E, F: FnMut(Loc<T>) -> Result<Fix<Loc<T>>, E>>(self, mut f: F) -> Result<Term<T>, E> {
        fix_result(self, |loc| {
            f(loc).map(|fix| match fix {
                Fix::Fix(loc) => loc.up(),
                _ => fix
            })
        }).map(Loc::get)
    }

}
<|endoftext|>


<commit_before>extern crate rs6502;
extern crate sdl2;

mod ship;
mod timer;

use std::io::{self, BufRead, Write};
use std::path::Path;
use std::sync::mpsc::channel;
use std::thread;
use std::time::Duration;

use rs6502::{Assembler, Cpu, Disassembler};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::image::LoadTexture;
use sdl2::Sdl;

use ::timer::FrameTimer;

fn main() {
    let (tx, rx) = channel();

    thread::spawn(move || {
        loop {
            std::io::stdout().write(b"HAKKA> ");
            std::io::stdout().flush();

            let mut line = String::new();
            let stdin = io::stdin();
            stdin.lock().read_line(&mut line).expect("Could not read line");
            tx.send(line).unwrap();
        }
    });

    let mut cpu = Cpu::new();
    let mut assembler = Assembler::new();
    let bytecode = assembler.assemble_file("level.asm").unwrap();
    cpu.load(&bytecode[..], None);
    cpu.flags.interrupt_disabled = false;

    cpu.memory[0x02] = 0x80;
    cpu.memory[0x03] = 0x00;
    cpu.memory[0x05] = 0x19;
    cpu.memory[0x06] = 0x00;

    let mut timer = FrameTimer::new(1000 / 120, 0, 0, 0);

    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();

    let window = video_subsystem.window("Hakka", 1280, 400)
        .position_centered()
        .build()
        .unwrap();

    let mut renderer = window.renderer()
        .accelerated()
        .build()
        .unwrap();

    let ship_texture = renderer.load_texture(Path::new("ship.png")).unwrap();

    let mut events = sdl_context.event_pump().unwrap();

    let mut ship = ship::Ship::new(ship_texture);

    'running: loop {

        cpu.step_n(4);
        if let Ok(input) = rx.try_recv() {
            let input = input.trim();
            if input == "exit" {
                break 'running;
            }

            if input == "list" {
                std::io::stdout().write(b"\n");
                std::io::stdout().write(b"-- Disassembly --\n");

                let mut disassembler = Disassembler::new();
                let asm = disassembler.disassemble(&bytecode[..]);

                std::io::stdout().write(asm.as_bytes());
                std::io::stdout().write(b"\nHAKKA> ");
                std::io::stdout().flush();
            }
        }

        for event in events.poll_iter() {
            match event {
                Event::Quit { .. } => break 'running,
                Event::KeyDown { keycode: Option::Some(Keycode::Right), .. } => {
                    cpu.memory[0x04] = 39
                }
                Event::KeyDown { keycode: Option::Some(Keycode::Left), .. } => {
                    cpu.memory[0x04] = 37
                }
                Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => cpu.memory[0x04] = 0,
                Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => cpu.memory[0x04] = 0,
                Event::KeyDown { keycode: Option::Some(Keycode::Escape), .. } => break 'running,
                _ => (),
            }
        }

        if frame_cap(&sdl_context, &mut timer) {
            ship.process(&cpu.memory[..]);

            if !cpu.flags.interrupt_disabled {
                // Render stuff here
                renderer.clear();
                ship.render(&mut renderer);
                renderer.present();
            }

        }

        if cpu.finished() {
            cpu.reset();
        }

        // thread::sleep(Duration::from_millis(10));
    }
}

fn frame_cap(sdl_context: &Sdl, timer: &mut FrameTimer) -> bool {
    let now = sdl_context.timer().unwrap().ticks();
    let delta = now - timer.prev;
    let elapsed = delta as f64 / 1000.0;

    timer.ticks = now;

    // Wait until 1/60th of a second has passed since we last called this
    if delta < timer.interval {
        sdl_context.timer().unwrap().delay(timer.interval - delta);
        return false;
    }

    timer.prev = now;
    timer.fps += 1;

    timer.elapsed = elapsed;

    if now - timer.last_second > 1000 {
        // Store our current FPS
        timer.last_fps = timer.fps;
        timer.last_second = now;
        timer.fps = 0;
    }

    true
}<commit_msg>Set code offset in Disassembler<commit_after>extern crate rs6502;
extern crate sdl2;

mod ship;
mod timer;

use std::io::{self, BufRead, Write};
use std::path::Path;
use std::sync::mpsc::channel;
use std::thread;
use std::time::Duration;

use rs6502::{Assembler, Cpu, Disassembler};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::image::LoadTexture;
use sdl2::Sdl;

use ::timer::FrameTimer;

fn main() {
    let (tx, rx) = channel();

    thread::spawn(move || {
        loop {
            std::io::stdout().write(b"HAKKA> ");
            std::io::stdout().flush();

            let mut line = String::new();
            let stdin = io::stdin();
            stdin.lock().read_line(&mut line).expect("Could not read line");
            tx.send(line).unwrap();
        }
    });

    let mut cpu = Cpu::new();
    let mut assembler = Assembler::new();
    let bytecode = assembler.assemble_file("level.asm").unwrap();
    cpu.load(&bytecode[..], None);
    cpu.flags.interrupt_disabled = false;

    cpu.memory[0x02] = 0x80;
    cpu.memory[0x03] = 0x00;
    cpu.memory[0x05] = 0x19;
    cpu.memory[0x06] = 0x00;

    let mut timer = FrameTimer::new(1000 / 120, 0, 0, 0);

    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();

    let window = video_subsystem.window("Hakka", 1280, 400)
        .position_centered()
        .build()
        .unwrap();

    let mut renderer = window.renderer()
        .accelerated()
        .build()
        .unwrap();

    let ship_texture = renderer.load_texture(Path::new("ship.png")).unwrap();

    let mut events = sdl_context.event_pump().unwrap();

    let mut ship = ship::Ship::new(ship_texture);

    'running: loop {

        cpu.step_n(4);
        if let Ok(input) = rx.try_recv() {
            let input = input.trim();
            if input == "exit" {
                break 'running;
            }

            if input == "list" {
                std::io::stdout().write(b"\n");
                std::io::stdout().write(b"-- Disassembly --\n");

                let mut disassembler = Disassembler::with_offset(0xC000);
                let asm = disassembler.disassemble(&bytecode[..]);

                std::io::stdout().write(asm.as_bytes());
                std::io::stdout().write(b"\nHAKKA> ");
                std::io::stdout().flush();
            }
        }

        for event in events.poll_iter() {
            match event {
                Event::Quit { .. } => break 'running,
                Event::KeyDown { keycode: Option::Some(Keycode::Right), .. } => {
                    cpu.memory[0x04] = 39
                }
                Event::KeyDown { keycode: Option::Some(Keycode::Left), .. } => {
                    cpu.memory[0x04] = 37
                }
                Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => cpu.memory[0x04] = 0,
                Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => cpu.memory[0x04] = 0,
                Event::KeyDown { keycode: Option::Some(Keycode::Escape), .. } => break 'running,
                _ => (),
            }
        }

        if frame_cap(&sdl_context, &mut timer) {
            ship.process(&cpu.memory[..]);

            if !cpu.flags.interrupt_disabled {
                // Render stuff here
                renderer.clear();
                ship.render(&mut renderer);
                renderer.present();
            }

        }

        if cpu.finished() {
            cpu.reset();
        }

        // thread::sleep(Duration::from_millis(10));
    }
}

fn frame_cap(sdl_context: &Sdl, timer: &mut FrameTimer) -> bool {
    let now = sdl_context.timer().unwrap().ticks();
    let delta = now - timer.prev;
    let elapsed = delta as f64 / 1000.0;

    timer.ticks = now;

    // Wait until 1/60th of a second has passed since we last called this
    if delta < timer.interval {
        sdl_context.timer().unwrap().delay(timer.interval - delta);
        return false;
    }

    timer.prev = now;
    timer.fps += 1;

    timer.elapsed = elapsed;

    if now - timer.last_second > 1000 {
        // Store our current FPS
        timer.last_fps = timer.fps;
        timer.last_second = now;
        timer.fps = 0;
    }

    true
}<|endoftext|>


<commit_before>pub mod bldr;
pub mod cli;
pub mod config;
pub mod file;
pub mod license;
pub mod origin;
pub mod pkg;
pub mod plan;
pub mod ring;
pub mod studio;
pub mod sup;
pub mod svc;
#[cfg(test)]
mod tests;
pub mod user;
pub mod util;

use self::{bldr::{ConfigOptChannelCreate,
                  ConfigOptChannelDemote,
                  ConfigOptChannelDestroy,
                  ConfigOptChannelList,
                  ConfigOptChannelPromote,
                  ConfigOptJobCancel,
                  ConfigOptJobDemote,
                  ConfigOptJobPromote,
                  ConfigOptJobStart,
                  ConfigOptJobStatus,
                  ChannelCreate,
                  ChannelDemote,
                  ChannelDestroy,
                  ChannelList,
                  ChannelPromote,
                  JobCancel,
                  JobDemote,
                  JobPromote,
                  JobStart,
                  JobStatus},
           cli::{CliCompleters,
                 ConfigOptCliCompleters,
                 CliSetup,
                 ConfigOptCliSetup},
           config::{ConfigOptServiceConfig,
                    ConfigOptServiceConfigApply,
                    ServiceConfig,
                    ServiceConfigApply},
           file::{ConfigOptFile,
                  File},
           license::{ConfigOptLicense,
                     License},
           origin::{ConfigOptOrigin,
                    Origin},
           pkg::{ConfigOptPkg,
                 ConfigOptPkgInstall,
                 Pkg,
                 PkgInstall},
           plan::{ConfigOptPlan,
                  Plan},
           ring::{ConfigOptRing,
                  Ring},
           studio::{ConfigOptStudio,
                    Studio},
           sup::{ConfigOptHabSup,
                 ConfigOptSupRun,
                 HabSup,
                 SupRun},
           svc::{ConfigOptSvc,
                 ConfigOptSvcStart,
                 ConfigOptSvcStop,
                 Svc,
                 SvcStart,
                 SvcStop},
           user::{ConfigOptUserKeyGenerate,
                  UserKeyGenerate},
           util::{CacheKeyPath,
                  ConfigOptCacheKeyPath}};
use crate::{cli::AFTER_HELP,
            VERSION};
use configopt::ConfigOpt;
use structopt::{clap::AppSettings,
                StructOpt};

#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "hab",
            version = VERSION,
            about = "Patents: https://chef.io/patents\n\"A Habitat is the natural environment for your services\" - Alan Turing",
            author = "\nThe Habitat Maintainers <humans@habitat.sh>\n",
            settings = &[AppSettings::GlobalVersion],
            after_help = AFTER_HELP
        )]
#[allow(clippy::large_enum_variant)]
pub enum Hab {
    #[structopt(no_version)]
    Bldr(Bldr),
    #[structopt(no_version)]
    Cli(Cli),
    #[structopt(no_version)]
    Config(ServiceConfig),
    #[structopt(no_version)]
    File(File),
    #[structopt(no_version, settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
    License(License),
    #[structopt(no_version)]
    Origin(Origin),
    #[structopt(no_version)]
    Pkg(Pkg),
    #[structopt(no_version)]
    Plan(Plan),
    #[structopt(no_version)]
    Ring(Ring),
    #[structopt(no_version, aliases = &["stu", "stud", "studi"])]
    Studio(Studio),
    #[structopt(no_version)]
    Sup(HabSup),
    /// Create a tarball of Habitat Supervisor data to send to support
    #[structopt(no_version)]
    Supportbundle,
    #[structopt(no_version)]
    Svc(Svc),
    #[structopt(no_version)]
    User(User),

    /// Alias for 'config apply'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Apply(ServiceConfigApply),
    /// Alias for 'pkg install'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["i", "in", "ins", "inst", "insta", "instal"])]
    Install(PkgInstall),
    #[cfg(not(target_os = "macos"))]
    /// Alias for 'sup run'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Run(SupRun),
    /// Alias for 'cli setup'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["set", "setu"])]
    Setup(CacheKeyPath),
    /// Alias for 'svc start'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["sta", "star"])]
    Start(SvcStart),
    /// Alias for 'svc stop'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["sto"])]
    Stop(SvcStop),
    #[cfg(not(target_os = "macos"))]
    /// Alias for 'sup term'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Term,
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["b", "bl", "bld"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder
pub enum Bldr {
    #[structopt(no_version)]
    Channel(Channel),
    #[structopt(no_version)]
    Job(Job),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["c", "ch", "cha", "chan", "chann", "channe"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder channels
pub enum Channel {
    #[structopt(no_version, aliases = &["c", "cr", "cre", "crea", "creat"])]
    Create(ChannelCreate),
    Demote(ChannelDemote),
    #[structopt(no_version, aliases = &["d", "de", "des", "dest", "destr", "destro"])]
    Destroy(ChannelDestroy),
    #[structopt(no_version, aliases = &["l", "li", "lis"])]
    List(ChannelList),
    Promote(ChannelPromote),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["j", "jo"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder jobs
pub enum Job {
    #[structopt(no_version, aliases = &["c", "ca", "can", "cance", "cancel"])]
    Cancel(JobCancel),
    #[structopt(no_version, aliases = &["d", "de", "dem", "demo", "demot"])]
    Demote(JobDemote),
    #[structopt(no_version, aliases = &["p", "pr", "pro", "prom", "promo", "promot"])]
    Promote(JobPromote),
    #[structopt(no_version, aliases = &["s", "st", "sta", "star"])]
    Start(JobStart),
    #[structopt(no_version, aliases = &["stat", "statu"])]
    Status(JobStatus),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["cl"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat runtime config
pub enum Cli {
    #[structopt(no_version, aliases = &["s", "se", "set", "setu"])]
    /// Sets up the CLI with reasonable defaults
    Setup(CliSetup),
    #[structopt(no_version, aliases = &["c", "co", "com", "comp"])]
    /// Creates command-line completers for your shell
    Completers(CliCompleters),
}

/// Commands relating to Habitat users
#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "user", no_version, aliases = &["u", "us", "use"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
pub enum User {
    Key(UserKey),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "key", no_version, aliases = &["k", "ke"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat user keys
pub enum UserKey {
    #[structopt(no_version, aliases = &["g", "ge", "gen", "gene", "gener", "genera", "generat"])]
    Generate(UserKeyGenerate),
}<commit_msg>[Refactor] added service config wrapper to hab<commit_after>pub mod bldr;
pub mod cli;
pub mod config;
pub mod file;
pub mod license;
pub mod origin;
pub mod pkg;
pub mod plan;
pub mod ring;
pub mod studio;
pub mod sup;
pub mod svc;
#[cfg(test)]
mod tests;
pub mod user;
pub mod util;

use self::{bldr::{ConfigOptChannelCreate,
                  ConfigOptChannelDemote,
                  ConfigOptChannelDestroy,
                  ConfigOptChannelList,
                  ConfigOptChannelPromote,
                  ConfigOptJobCancel,
                  ConfigOptJobDemote,
                  ConfigOptJobPromote,
                  ConfigOptJobStart,
                  ConfigOptJobStatus,
                  ChannelCreate,
                  ChannelDemote,
                  ChannelDestroy,
                  ChannelList,
                  ChannelPromote,
                  JobCancel,
                  JobDemote,
                  JobPromote,
                  JobStart,
                  JobStatus},
           cli::{CliCompleters,
                 ConfigOptCliCompleters,
                 CliSetup,
                 ConfigOptCliSetup},
           config::{ConfigOptServiceConfigApply,
                    ConfigOptServiceConfigShow,
                    ServiceConfigApply,
                    ServiceConfigShow},
           file::{ConfigOptFile,
                  File},
           license::{ConfigOptLicense,
                     License},
           origin::{ConfigOptOrigin,
                    Origin},
           pkg::{ConfigOptPkg,
                 ConfigOptPkgInstall,
                 Pkg,
                 PkgInstall},
           plan::{ConfigOptPlan,
                  Plan},
           ring::{ConfigOptRing,
                  Ring},
           studio::{ConfigOptStudio,
                    Studio},
           sup::{ConfigOptHabSup,
                 ConfigOptSupRun,
                 HabSup,
                 SupRun},
           svc::{ConfigOptSvc,
                 ConfigOptSvcStart,
                 ConfigOptSvcStop,
                 Svc,
                 SvcStart,
                 SvcStop},
           user::{ConfigOptUserKeyGenerate,
                  UserKeyGenerate},
           util::{CacheKeyPath,
                  ConfigOptCacheKeyPath}};
use crate::{cli::AFTER_HELP,
            VERSION};
use configopt::ConfigOpt;
use structopt::{clap::AppSettings,
                StructOpt};

#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "hab",
            version = VERSION,
            about = "Patents: https://chef.io/patents\n\"A Habitat is the natural environment for your services\" - Alan Turing",
            author = "\nThe Habitat Maintainers <humans@habitat.sh>\n",
            settings = &[AppSettings::GlobalVersion],
            after_help = AFTER_HELP
        )]
#[allow(clippy::large_enum_variant)]
pub enum Hab {
    #[structopt(no_version)]
    Bldr(Bldr),
    #[structopt(no_version)]
    Cli(Cli),
    #[structopt(no_version)]
    Config(ServiceConfig),
    #[structopt(no_version)]
    File(File),
    #[structopt(no_version, settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
    License(License),
    #[structopt(no_version)]
    Origin(Origin),
    #[structopt(no_version)]
    Pkg(Pkg),
    #[structopt(no_version)]
    Plan(Plan),
    #[structopt(no_version)]
    Ring(Ring),
    #[structopt(no_version, aliases = &["stu", "stud", "studi"])]
    Studio(Studio),
    #[structopt(no_version)]
    Sup(HabSup),
    /// Create a tarball of Habitat Supervisor data to send to support
    #[structopt(no_version)]
    Supportbundle,
    #[structopt(no_version)]
    Svc(Svc),
    #[structopt(no_version)]
    User(User),

    /// Alias for 'config apply'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Apply(ServiceConfigApply),
    /// Alias for 'pkg install'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["i", "in", "ins", "inst", "insta", "instal"])]
    Install(PkgInstall),
    #[cfg(not(target_os = "macos"))]
    /// Alias for 'sup run'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Run(SupRun),
    /// Alias for 'cli setup'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["set", "setu"])]
    Setup(CacheKeyPath),
    /// Alias for 'svc start'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["sta", "star"])]
    Start(SvcStart),
    /// Alias for 'svc stop'
    #[structopt(no_version, settings = &[AppSettings::Hidden], aliases = &["sto"])]
    Stop(SvcStop),
    #[cfg(not(target_os = "macos"))]
    /// Alias for 'sup term'
    #[structopt(no_version, settings = &[AppSettings::Hidden])]
    Term,
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["b", "bl", "bld"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder
pub enum Bldr {
    #[structopt(no_version)]
    Channel(Channel),
    #[structopt(no_version)]
    Job(Job),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["c", "ch", "cha", "chan", "chann", "channe"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder channels
pub enum Channel {
    #[structopt(no_version, aliases = &["c", "cr", "cre", "crea", "creat"])]
    Create(ChannelCreate),
    Demote(ChannelDemote),
    #[structopt(no_version, aliases = &["d", "de", "des", "dest", "destr", "destro"])]
    Destroy(ChannelDestroy),
    #[structopt(no_version, aliases = &["l", "li", "lis"])]
    List(ChannelList),
    Promote(ChannelPromote),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["j", "jo"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat Builder jobs
pub enum Job {
    #[structopt(no_version, aliases = &["c", "ca", "can", "cance", "cancel"])]
    Cancel(JobCancel),
    #[structopt(no_version, aliases = &["d", "de", "dem", "demo", "demot"])]
    Demote(JobDemote),
    #[structopt(no_version, aliases = &["p", "pr", "pro", "prom", "promo", "promot"])]
    Promote(JobPromote),
    #[structopt(no_version, aliases = &["s", "st", "sta", "star"])]
    Start(JobStart),
    #[structopt(no_version, aliases = &["stat", "statu"])]
    Status(JobStatus),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["cl"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat runtime config
pub enum Cli {
    #[structopt(no_version, aliases = &["s", "se", "set", "setu"])]
    /// Sets up the CLI with reasonable defaults
    Setup(CliSetup),
    #[structopt(no_version, aliases = &["c", "co", "com", "comp"])]
    /// Creates command-line completers for your shell
    Completers(CliCompleters),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(no_version, aliases = &["co", "con", "conf", "confi"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to a Service's runtime config
pub enum ServiceConfig {
    #[structopt(no_version, aliases = &["ap", "app", "appl"])]
    Apply(ServiceConfigApply),
    #[structopt(no_version, aliases = &["sh", "sho"])]
    Show(ServiceConfigShow),
}

/// Commands relating to Habitat users
#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "user", no_version, aliases = &["u", "us", "use"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
pub enum User {
    Key(UserKey),
}

#[derive(ConfigOpt, StructOpt)]
#[structopt(name = "key", no_version, aliases = &["k", "ke"], settings = &[AppSettings::ArgRequiredElseHelp, AppSettings::SubcommandRequiredElseHelp])]
/// Commands relating to Habitat user keys
pub enum UserKey {
    #[structopt(no_version, aliases = &["g", "ge", "gen", "gene", "gener", "genera", "generat"])]
    Generate(UserKeyGenerate),
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method %>

// CSS Basic User Interface Module Level 1
// https://drafts.csswg.org/css-ui-3/
<% data.new_style_struct("UI", inherited=False, gecko_name="UIReset") %>

// TODO spec says that UAs should not support this
// we should probably remove from gecko (https://bugzilla.mozilla.org/show_bug.cgi?id=1328331)
${helpers.single_keyword("ime-mode", "auto normal active disabled inactive",
                         products="gecko", gecko_ffi_name="mIMEMode",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-ui/#input-method-editor")}

${helpers.single_keyword("-moz-user-select", "auto text none all element elements" +
                            " toggle tri-state -moz-all -moz-text",
                         products="gecko",
                         alias="-webkit-user-select",
                         gecko_ffi_name="mUserSelect",
                         gecko_enum_prefix="StyleUserSelect",
                         gecko_strip_moz_prefix=False,
                         aliases="-moz-none=none",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select")}

${helpers.single_keyword("-moz-window-dragging", "default drag no-drag", products="gecko",
                         gecko_ffi_name="mWindowDragging",
                         gecko_enum_prefix="StyleWindowDragging",
                         animation_value_type="discrete",
                         spec="None (Nonstandard Firefox-only property)")}

${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet", products="gecko",
                         gecko_ffi_name="mWindowShadow",
                         gecko_constant_prefix="NS_STYLE_WINDOW_SHADOW",
                         animation_value_type="discrete",
                         internal=True,
                         spec="None (Nonstandard internal property)")}

<%helpers:longhand name="-moz-force-broken-image-icon"
                   products="gecko"
                   animation_value_type="discrete"
                   spec="None (Nonstandard Firefox-only property)">
    use std::fmt;
    use style_traits::ToCss;

    pub mod computed_value {
        #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
        pub struct T(pub bool);
    }

    pub use self::computed_value::T as SpecifiedValue;

    impl ToCss for computed_value::T {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            dest.write_str(if self.0 { "1" } else { "0" })
        }
    }

    #[inline]
    pub fn get_initial_value() -> computed_value::T {
        computed_value::T(false)
    }

    #[inline]
    pub fn get_initial_specified_value() -> SpecifiedValue {
        computed_value::T(false)
    }

    pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
                         -> Result<SpecifiedValue, ParseError<'i>> {
        match input.expect_integer()? {
            0 => Ok(computed_value::T(false)),
            1 => Ok(computed_value::T(true)),
            _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
        }
    }

    impl From<u8> for SpecifiedValue {
        fn from(bits: u8) -> SpecifiedValue {
            SpecifiedValue(bits == 1)
        }
    }

    impl From<SpecifiedValue> for u8 {
        fn from(v: SpecifiedValue) -> u8 {
            match v.0 {
                true => 1u8,
                false => 0u8,
            }
        }
    }
</%helpers:longhand>
<commit_msg>Add support for -moz-window-opacity to stylo<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method %>

// CSS Basic User Interface Module Level 1
// https://drafts.csswg.org/css-ui-3/
<% data.new_style_struct("UI", inherited=False, gecko_name="UIReset") %>

// TODO spec says that UAs should not support this
// we should probably remove from gecko (https://bugzilla.mozilla.org/show_bug.cgi?id=1328331)
${helpers.single_keyword("ime-mode", "auto normal active disabled inactive",
                         products="gecko", gecko_ffi_name="mIMEMode",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-ui/#input-method-editor")}

${helpers.single_keyword("-moz-user-select", "auto text none all element elements" +
                            " toggle tri-state -moz-all -moz-text",
                         products="gecko",
                         alias="-webkit-user-select",
                         gecko_ffi_name="mUserSelect",
                         gecko_enum_prefix="StyleUserSelect",
                         gecko_strip_moz_prefix=False,
                         aliases="-moz-none=none",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select")}

${helpers.single_keyword("-moz-window-dragging", "default drag no-drag", products="gecko",
                         gecko_ffi_name="mWindowDragging",
                         gecko_enum_prefix="StyleWindowDragging",
                         animation_value_type="discrete",
                         spec="None (Nonstandard Firefox-only property)")}

${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet", products="gecko",
                         gecko_ffi_name="mWindowShadow",
                         gecko_constant_prefix="NS_STYLE_WINDOW_SHADOW",
                         animation_value_type="discrete",
                         internal=True,
                         spec="None (Nonstandard internal property)")}

${helpers.predefined_type("-moz-window-opacity", "Opacity", "1.0", products="gecko",
                          gecko_ffi_name="mWindowOpacity",
                          animation_value_type="ComputedValue",
                          internal=True,
                          spec="None (Nonstandard internal property)")}

<%helpers:longhand name="-moz-force-broken-image-icon"
                   products="gecko"
                   animation_value_type="discrete"
                   spec="None (Nonstandard Firefox-only property)">
    use std::fmt;
    use style_traits::ToCss;

    pub mod computed_value {
        #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
        pub struct T(pub bool);
    }

    pub use self::computed_value::T as SpecifiedValue;

    impl ToCss for computed_value::T {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            dest.write_str(if self.0 { "1" } else { "0" })
        }
    }

    #[inline]
    pub fn get_initial_value() -> computed_value::T {
        computed_value::T(false)
    }

    #[inline]
    pub fn get_initial_specified_value() -> SpecifiedValue {
        computed_value::T(false)
    }

    pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
                         -> Result<SpecifiedValue, ParseError<'i>> {
        match input.expect_integer()? {
            0 => Ok(computed_value::T(false)),
            1 => Ok(computed_value::T(true)),
            _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
        }
    }

    impl From<u8> for SpecifiedValue {
        fn from(bits: u8) -> SpecifiedValue {
            SpecifiedValue(bits == 1)
        }
    }

    impl From<SpecifiedValue> for u8 {
        fn from(v: SpecifiedValue) -> u8 {
            match v.0 {
                true => 1u8,
                false => 0u8,
            }
        }
    }
</%helpers:longhand>
<|endoftext|>