<commit_before>use crate::api::raii::{Publisher, Service, Subscriber};
use crate::api::resolve::get_unused_args;
use crate::api::{Delay, Parameter, Rate, Ros, SystemState, Topic};
use crate::error::{ErrorKind, Result};
use crate::rosxmlrpc::Response;
use crate::tcpros::{Client, Message, ServicePair, ServiceResult};
use crate::time::{Duration, Time};
use crate::util::FAILED_TO_LOCK;
use crate::RawMessageDescription;
use crossbeam::sync::ShardedLock;
use ctrlc;
use error_chain::bail;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::time;

lazy_static! {
    static ref ROS: ShardedLock<Option<Ros>> = ShardedLock::new(None);
}

#[inline]
pub fn init(name: &str) {
    try_init(name).expect("ROS init failed!");
}

#[inline]
pub fn try_init(name: &str) -> Result<()> {
    try_init_with_options(name, true)
}

pub fn try_init_with_options(name: &str, capture_sigint: bool) -> Result<()> {
    let mut ros = ROS.write().expect(FAILED_TO_LOCK);
    if ros.is_some() {
        bail!(ErrorKind::MultipleInitialization);
    }
    let client = Ros::new(name)?;
    if capture_sigint {
        let shutdown_sender = client.shutdown_sender();
        ctrlc::set_handler(move || {
            shutdown_sender.shutdown();
        })?;
    }
    *ros = Some(client);
    Ok(())
}

pub fn is_initialized() -> bool {
    ROS.read().expect(FAILED_TO_LOCK).is_some()
}

macro_rules! ros {
    () => {
        ROS.read()
            .expect(FAILED_TO_LOCK)
            .as_ref()
            .expect(UNINITIALIZED)
    };
}

#[inline]
pub fn args() -> Vec<String> {
    get_unused_args()
}

#[inline]
pub fn uri() -> String {
    ros!().uri().into()
}

#[inline]
pub fn name() -> String {
    ros!().name().into()
}

#[inline]
pub fn hostname() -> String {
    ros!().hostname().into()
}

#[inline]
pub fn now() -> Time {
    ros!().now()
}

#[inline]
pub fn delay(d: Duration) -> Delay {
    ros!().delay(d)
}

#[inline]
pub fn sleep(d: Duration) {
    delay(d).sleep();
}

#[inline]
pub fn rate(rate: f64) -> Rate {
    ros!().rate(rate)
}

#[inline]
pub fn is_ok() -> bool {
    ros!().is_ok()
}

#[inline]
pub fn spin() {
    // Spinner drop locks the thread until a kill request is received
    let _spinner = { ros!().spin() };
}

#[inline]
pub fn shutdown() {
    ros!().shutdown_sender().shutdown()
}

#[inline]
pub fn param(name: &str) -> Option<Parameter> {
    ros!().param(name)
}

#[inline]
pub fn parameters() -> Response<Vec<String>> {
    ros!().parameters()
}

#[inline]
pub fn state() -> Response<SystemState> {
    ros!().state()
}

#[inline]
pub fn topics() -> Response<Vec<Topic>> {
    ros!().topics()
}

#[inline]
pub fn client<T: ServicePair>(service: &str) -> Result<Client<T>> {
    ros!().client::<T>(service)
}

#[inline]
pub fn wait_for_service(service: &str, timeout: Option<time::Duration>) -> Result<()> {
    ros!().wait_for_service(service, timeout)
}

#[inline]
pub fn service<T, F>(service: &str, handler: F) -> Result<Service>
where
    T: ServicePair,
    F: Fn(T::Request) -> ServiceResult<T::Response> + Send + Sync + 'static,
{
    ros!().service::<T, F>(service, handler)
}

#[inline]
pub fn subscribe<T, F>(topic: &str, queue_size: usize, callback: F) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T) + Send + 'static,
{
    ros!().subscribe::<T, F>(topic, queue_size, callback)
}

#[inline]
pub fn subscribe_with_ids<T, F>(topic: &str, queue_size: usize, callback: F) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T, &str) + Send + 'static,
{
    ros!().subscribe_with_ids::<T, F>(topic, queue_size, callback)
}

#[inline]
pub fn subscribe_with_ids_and_headers<T, F, G>(
    topic: &str,
    queue_size: usize,
    on_message: F,
    on_connect: G,
) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T, &str) + Send + 'static,
    G: Fn(HashMap<String, String>) + Send + 'static,
{
    ros!().subscribe_with_ids_and_headers::<T, F, G>(topic, queue_size, on_message, on_connect)
}

#[inline]
pub fn publish<T>(topic: &str, queue_size: usize) -> Result<Publisher<T>>
where
    T: Message,
{
    ros!().publish::<T>(topic, queue_size)
}

#[inline]
pub fn publish_with_description<T>(
    topic: &str,
    queue_size: usize,
    message_description: RawMessageDescription,
) -> Result<Publisher<T>>
where
    T: Message,
{
    ros!().publish_with_description::<T>(topic, queue_size, message_description)
}

#[inline]
pub fn log(level: i8, msg: String, file: &str, line: u32) {
    ros!().log(level, msg, file, line)
}

static UNINITIALIZED: &str = "ROS uninitialized. Please run ros::init(name) first!";
<commit_msg>Added a loop init function to handle a non-running roscore<commit_after>use crate::api::raii::{Publisher, Service, Subscriber};
use crate::api::resolve::get_unused_args;
use crate::api::{Delay, Parameter, Rate, Ros, SystemState, Topic};
use crate::error::{ErrorKind, Result};
use crate::rosxmlrpc::Response;
use crate::tcpros::{Client, Message, ServicePair, ServiceResult};
use crate::time::{Duration, Time};
use crate::util::FAILED_TO_LOCK;
use crate::RawMessageDescription;
use crossbeam::sync::ShardedLock;
use ctrlc;
use error_chain::bail;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::time;
use std::thread;

lazy_static! {
    static ref ROS: ShardedLock<Option<Ros>> = ShardedLock::new(None);
}

#[inline]
pub fn init(name: &str) {
    try_init(name).expect("ROS init failed!");
}

#[inline]
pub fn loop_init(name: &str, wait_millis: u64) {
    loop {
        if try_init(name).is_ok() {
            break;
        }
        println!("roscore not found. Will retry until it becomes available...");
        thread::sleep(std::time::Duration::from_millis(wait_millis));
    }
    println!("Connected to roscore");
}

#[inline]
pub fn try_init(name: &str) -> Result<()> {
    try_init_with_options(name, true)
}

pub fn try_init_with_options(name: &str, capture_sigint: bool) -> Result<()> {
    let mut ros = ROS.write().expect(FAILED_TO_LOCK);
    if ros.is_some() {
        bail!(ErrorKind::MultipleInitialization);
    }
    let client = Ros::new(name)?;
    if capture_sigint {
        let shutdown_sender = client.shutdown_sender();
        ctrlc::set_handler(move || {
            shutdown_sender.shutdown();
        })?;
    }
    *ros = Some(client);
    Ok(())
}

pub fn is_initialized() -> bool {
    ROS.read().expect(FAILED_TO_LOCK).is_some()
}

macro_rules! ros {
    () => {
        ROS.read()
            .expect(FAILED_TO_LOCK)
            .as_ref()
            .expect(UNINITIALIZED)
    };
}

#[inline]
pub fn args() -> Vec<String> {
    get_unused_args()
}

#[inline]
pub fn uri() -> String {
    ros!().uri().into()
}

#[inline]
pub fn name() -> String {
    ros!().name().into()
}

#[inline]
pub fn hostname() -> String {
    ros!().hostname().into()
}

#[inline]
pub fn now() -> Time {
    ros!().now()
}

#[inline]
pub fn delay(d: Duration) -> Delay {
    ros!().delay(d)
}

#[inline]
pub fn sleep(d: Duration) {
    delay(d).sleep();
}

#[inline]
pub fn rate(rate: f64) -> Rate {
    ros!().rate(rate)
}

#[inline]
pub fn is_ok() -> bool {
    ros!().is_ok()
}

#[inline]
pub fn spin() {
    // Spinner drop locks the thread until a kill request is received
    let _spinner = { ros!().spin() };
}

#[inline]
pub fn shutdown() {
    ros!().shutdown_sender().shutdown()
}

#[inline]
pub fn param(name: &str) -> Option<Parameter> {
    ros!().param(name)
}

#[inline]
pub fn parameters() -> Response<Vec<String>> {
    ros!().parameters()
}

#[inline]
pub fn state() -> Response<SystemState> {
    ros!().state()
}

#[inline]
pub fn topics() -> Response<Vec<Topic>> {
    ros!().topics()
}

#[inline]
pub fn client<T: ServicePair>(service: &str) -> Result<Client<T>> {
    ros!().client::<T>(service)
}

#[inline]
pub fn wait_for_service(service: &str, timeout: Option<time::Duration>) -> Result<()> {
    ros!().wait_for_service(service, timeout)
}

#[inline]
pub fn service<T, F>(service: &str, handler: F) -> Result<Service>
where
    T: ServicePair,
    F: Fn(T::Request) -> ServiceResult<T::Response> + Send + Sync + 'static,
{
    ros!().service::<T, F>(service, handler)
}

#[inline]
pub fn subscribe<T, F>(topic: &str, queue_size: usize, callback: F) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T) + Send + 'static,
{
    ros!().subscribe::<T, F>(topic, queue_size, callback)
}

#[inline]
pub fn subscribe_with_ids<T, F>(topic: &str, queue_size: usize, callback: F) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T, &str) + Send + 'static,
{
    ros!().subscribe_with_ids::<T, F>(topic, queue_size, callback)
}

#[inline]
pub fn subscribe_with_ids_and_headers<T, F, G>(
    topic: &str,
    queue_size: usize,
    on_message: F,
    on_connect: G,
) -> Result<Subscriber>
where
    T: Message,
    F: Fn(T, &str) + Send + 'static,
    G: Fn(HashMap<String, String>) + Send + 'static,
{
    ros!().subscribe_with_ids_and_headers::<T, F, G>(topic, queue_size, on_message, on_connect)
}

#[inline]
pub fn publish<T>(topic: &str, queue_size: usize) -> Result<Publisher<T>>
where
    T: Message,
{
    ros!().publish::<T>(topic, queue_size)
}

#[inline]
pub fn publish_with_description<T>(
    topic: &str,
    queue_size: usize,
    message_description: RawMessageDescription,
) -> Result<Publisher<T>>
where
    T: Message,
{
    ros!().publish_with_description::<T>(topic, queue_size, message_description)
}

#[inline]
pub fn log(level: i8, msg: String, file: &str, line: u32) {
    ros!().log(level, msg, file, line)
}

static UNINITIALIZED: &str = "ROS uninitialized. Please run ros::init(name) first!";
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A definition of `StorageKey` trait and implementations for common types.

use std::mem;

use byteorder::{ByteOrder, BigEndian};

use crypto::{Hash, PublicKey, HASH_SIZE, PUBLIC_KEY_LENGTH};

/// A trait that defines serialization of corresponding types as storage keys.
///
/// Since internally the keys are sorted in a serialized form, the big-endian encoding is used.
///
/// # Examples
///
/// Implementing `StorageKey` for the type:
///
/// ```
/// # extern crate exonum;
/// # extern crate byteorder;
///
/// use std::mem;
///
/// use exonum::storage::StorageKey;
/// use byteorder::{LittleEndian, ByteOrder};
///
/// #[Derive(Clone)]
/// struct Key {
///     a: i16,
///     b: u32,
/// }
///
/// impl StorageKey for Key {
///     fn size(&self) -> usize {
///         mem::size_of_val(&self.a) + mem::size_of_val(&self.b)
///     }
///
///     fn write(&self, buffer: &mut [u8]) {
///         LittleEndian::write_i16(&mut buffer[0..2], self.a);
///         LittleEndian::write_u32(&mut buffer[2..6], self.b);
///     }
///
///     fn read(buffer: &[u8]) -> Self {
///         let a = LittleEndian::read_i16(&buffer[0..2]);
///         let b = LittleEndian::read_u32(&buffer[2..6]);
///         Key { a, b }
///     }
/// }
/// # fn main() {}
/// ```
pub trait StorageKey: ToOwned {
    /// Returns the size of the serialized key in bytes.
    fn size(&self) -> usize;

    /// Serialize a key into the specified buffer of bytes.
    ///
    /// The caller must guarantee that the size of the buffer is equal to the precalculated size
    /// of the serialized key.
    // TODO: should be unsafe (ECR-174)?
    fn write(&self, buffer: &mut [u8]);

    /// Deserialize a key from the specified buffer of bytes.
    // TODO: should be unsafe (ECR-174)?
    fn read(buffer: &[u8]) -> Self::Owned;
}

impl StorageKey for () {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, _buffer: &mut [u8]) {
        // no-op
    }

    fn read(_buffer: &[u8]) -> Self::Owned {
        ()
    }
}

impl StorageKey for u8 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer[0]
    }
}

impl StorageKey for u16 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u16(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u16(buffer)
    }
}

impl StorageKey for u32 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u32(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u32(buffer)
    }
}

impl StorageKey for u64 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u64(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u64(buffer)
    }
}

impl StorageKey for i8 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self as u8
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer[0] as i8
    }
}

impl StorageKey for i16 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i16(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i16(buffer)
    }
}

impl StorageKey for i32 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i32(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i32(buffer)
    }
}

impl StorageKey for i64 {
    fn size(&self) -> usize {
        mem::size_of::<Self>()
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i64(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i64(buffer)
    }
}

impl StorageKey for Hash {
    fn size(&self) -> usize {
        HASH_SIZE
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        Hash::from_slice(buffer).unwrap()
    }
}

impl StorageKey for PublicKey {
    fn size(&self) -> usize {
        PUBLIC_KEY_LENGTH
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        PublicKey::from_slice(buffer).unwrap()
    }
}

impl StorageKey for Vec<u8> {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer.to_vec()
    }
}

impl StorageKey for [u8] {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer.to_vec()
    }
}

impl StorageKey for String {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}

impl StorageKey for str {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}

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

    #[test]
    fn str_key() {
        let values = ["eee", "hello world", ""];
        for val in values.iter() {
            let mut buffer = get_buffer(*val);
            val.write(&mut buffer);
            let new_val = str::read(&buffer);
            assert_eq!(new_val, *val);
        }
    }

    #[test]
    fn u8_slice_key() {
        let values: &[&[u8]] = &[&[1, 2, 3], &[255], &[]];
        for val in values.iter() {
            let mut buffer = get_buffer(*val);
            val.write(&mut buffer);
            let new_val = <[u8] as StorageKey>::read(&buffer);
            assert_eq!(new_val, *val);
        }
    }

    fn get_buffer<T: StorageKey + ?Sized>(key: &T) -> Vec<u8> {
        vec![0; key.size()]
    }
}
<commit_msg>Revert mem::size_of usage<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A definition of `StorageKey` trait and implementations for common types.

use byteorder::{ByteOrder, BigEndian};

use crypto::{Hash, PublicKey, HASH_SIZE, PUBLIC_KEY_LENGTH};

/// A trait that defines serialization of corresponding types as storage keys.
///
/// Since internally the keys are sorted in a serialized form, the big-endian encoding is used.
///
/// # Examples
///
/// Implementing `StorageKey` for the type:
///
/// ```
/// # extern crate exonum;
/// # extern crate byteorder;
///
/// use std::mem;
///
/// use exonum::storage::StorageKey;
/// use byteorder::{LittleEndian, ByteOrder};
///
/// #[Derive(Clone)]
/// struct Key {
///     a: i16,
///     b: u32,
/// }
///
/// impl StorageKey for Key {
///     fn size(&self) -> usize {
///         mem::size_of_val(&self.a) + mem::size_of_val(&self.b)
///     }
///
///     fn write(&self, buffer: &mut [u8]) {
///         LittleEndian::write_i16(&mut buffer[0..2], self.a);
///         LittleEndian::write_u32(&mut buffer[2..6], self.b);
///     }
///
///     fn read(buffer: &[u8]) -> Self {
///         let a = LittleEndian::read_i16(&buffer[0..2]);
///         let b = LittleEndian::read_u32(&buffer[2..6]);
///         Key { a, b }
///     }
/// }
/// # fn main() {}
/// ```
pub trait StorageKey: ToOwned {
    /// Returns the size of the serialized key in bytes.
    fn size(&self) -> usize;

    /// Serialize a key into the specified buffer of bytes.
    ///
    /// The caller must guarantee that the size of the buffer is equal to the precalculated size
    /// of the serialized key.
    // TODO: should be unsafe (ECR-174)?
    fn write(&self, buffer: &mut [u8]);

    /// Deserialize a key from the specified buffer of bytes.
    // TODO: should be unsafe (ECR-174)?
    fn read(buffer: &[u8]) -> Self::Owned;
}

impl StorageKey for () {
    fn size(&self) -> usize {
        0
    }

    fn write(&self, _buffer: &mut [u8]) {
        // no-op
    }

    fn read(_buffer: &[u8]) -> Self::Owned {
        ()
    }
}

impl StorageKey for u8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer[0]
    }
}

impl StorageKey for u16 {
    fn size(&self) -> usize {
        2
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u16(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u16(buffer)
    }
}

impl StorageKey for u32 {
    fn size(&self) -> usize {
        4
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u32(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u32(buffer)
    }
}

impl StorageKey for u64 {
    fn size(&self) -> usize {
        8
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_u64(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_u64(buffer)
    }
}

impl StorageKey for i8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self as u8
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer[0] as i8
    }
}

impl StorageKey for i16 {
    fn size(&self) -> usize {
        2
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i16(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i16(buffer)
    }
}

impl StorageKey for i32 {
    fn size(&self) -> usize {
        4
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i32(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i32(buffer)
    }
}

impl StorageKey for i64 {
    fn size(&self) -> usize {
        8
    }

    fn write(&self, buffer: &mut [u8]) {
        BigEndian::write_i64(buffer, *self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        BigEndian::read_i64(buffer)
    }
}

impl StorageKey for Hash {
    fn size(&self) -> usize {
        HASH_SIZE
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        Hash::from_slice(buffer).unwrap()
    }
}

impl StorageKey for PublicKey {
    fn size(&self) -> usize {
        PUBLIC_KEY_LENGTH
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        PublicKey::from_slice(buffer).unwrap()
    }
}

impl StorageKey for Vec<u8> {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer.to_vec()
    }
}

impl StorageKey for [u8] {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        buffer.to_vec()
    }
}

impl StorageKey for String {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}

impl StorageKey for str {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self::Owned {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}

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

    #[test]
    fn str_key() {
        let values = ["eee", "hello world", ""];
        for val in values.iter() {
            let mut buffer = get_buffer(*val);
            val.write(&mut buffer);
            let new_val = str::read(&buffer);
            assert_eq!(new_val, *val);
        }
    }

    #[test]
    fn u8_slice_key() {
        let values: &[&[u8]] = &[&[1, 2, 3], &[255], &[]];
        for val in values.iter() {
            let mut buffer = get_buffer(*val);
            val.write(&mut buffer);
            let new_val = <[u8] as StorageKey>::read(&buffer);
            assert_eq!(new_val, *val);
        }
    }

    fn get_buffer<T: StorageKey + ?Sized>(key: &T) -> Vec<u8> {
        vec![0; key.size()]
    }
}
<|endoftext|>


<commit_before>//! Module defining all sensor related structures.

use std::collections::BTreeMap;
use rustc_serialize::json::{Json, ToJson};
use optional::Optional;

//--- Templates ---//

/// A trait for all possible sensor templates.
///
/// A sensor template is like a sensor struct, but without the actual data in it.
/// A `SensorTemplate` is capable of registering itself in a `Sensors` struct.
pub trait SensorTemplate : Send+Sync {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors);
}

#[derive(Debug, Clone)]
pub struct PeopleNowPresentSensorTemplate {
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

impl SensorTemplate for PeopleNowPresentSensorTemplate {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors) {
        if value_str.parse::<i64>().map(|value|{
            let sensor = PeopleNowPresentSensor {
                location: self.location.clone(),
                name: self.name.clone(),
                names: self.names.clone(),
                description: self.description.clone(),
                value: value,
            };

            match sensors.people_now_present {
                Optional::Value(ref mut vec_sensors) => {
                    vec_sensors.push(sensor)
                }
                Optional::Absent => {
                    sensors.people_now_present = Optional::Value(vec![sensor])
                }
            }
        }).is_err() {
            warn!("Could not parse value '{}', omiting PeopleNowPresentSensor", value_str);
        }
    }
}

#[derive(Debug, Clone)]
pub struct TemperatureSensorTemplate {
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

impl SensorTemplate for TemperatureSensorTemplate {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors) {
        if value_str.parse::<f64>().map(|value|{
            let sensor = TemperatureSensor {
                unit: self.unit.clone(),
                location: self.location.clone(),
                name: self.name.clone(),
                description: self.description.clone(),
                value: value,
            };
            match sensors.temperature {
                Optional::Value(ref mut vec_sensors) => {
                    vec_sensors.push(sensor)
                }
                Optional::Absent => {
                    sensors.temperature = Optional::Value(vec![sensor])
                }
            }
        }).is_err() {
            warn!("Could not parse value '{}', omiting TemperatureSensor", value_str);
        }
    }
}

//--- Structures ---//

#[derive(Debug, Clone)]
pub struct PeopleNowPresentSensor {
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
    pub value: i64,
}

#[derive(Debug, Clone)]
pub struct TemperatureSensor {
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
    pub value: f64,
}

#[derive(Debug, Clone)]
pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

//--- Serialization ---//

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        self.people_now_present.as_ref().map_or((), |v| { d.insert("people_now_present".to_string(), v.to_json()); });
        self.temperature.as_ref().map_or((), |v| { d.insert("temperature".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        self.location.as_ref().map_or((), |v| { d.insert("location".to_string(), v.to_json()); });
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.names.as_ref().map_or((), |v| { d.insert("names".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}
<commit_msg>People present sensor should always contain positive values<commit_after>//! Module defining all sensor related structures.

use std::collections::BTreeMap;
use rustc_serialize::json::{Json, ToJson};
use optional::Optional;

//--- Templates ---//

/// A trait for all possible sensor templates.
///
/// A sensor template is like a sensor struct, but without the actual data in it.
/// A `SensorTemplate` is capable of registering itself in a `Sensors` struct.
pub trait SensorTemplate : Send+Sync {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors);
}

#[derive(Debug, Clone)]
pub struct PeopleNowPresentSensorTemplate {
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

impl SensorTemplate for PeopleNowPresentSensorTemplate {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors) {
        if value_str.parse::<u64>().map(|value|{
            let sensor = PeopleNowPresentSensor {
                location: self.location.clone(),
                name: self.name.clone(),
                names: self.names.clone(),
                description: self.description.clone(),
                value: value,
            };

            match sensors.people_now_present {
                Optional::Value(ref mut vec_sensors) => {
                    vec_sensors.push(sensor)
                }
                Optional::Absent => {
                    sensors.people_now_present = Optional::Value(vec![sensor])
                }
            }
        }).is_err() {
            warn!("Could not parse value '{}', omiting PeopleNowPresentSensor", value_str);
        }
    }
}

#[derive(Debug, Clone)]
pub struct TemperatureSensorTemplate {
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

impl SensorTemplate for TemperatureSensorTemplate {
    fn to_sensor(&self, value_str: &str, sensors: &mut Sensors) {
        if value_str.parse::<f64>().map(|value|{
            let sensor = TemperatureSensor {
                unit: self.unit.clone(),
                location: self.location.clone(),
                name: self.name.clone(),
                description: self.description.clone(),
                value: value,
            };
            match sensors.temperature {
                Optional::Value(ref mut vec_sensors) => {
                    vec_sensors.push(sensor)
                }
                Optional::Absent => {
                    sensors.temperature = Optional::Value(vec![sensor])
                }
            }
        }).is_err() {
            warn!("Could not parse value '{}', omiting TemperatureSensor", value_str);
        }
    }
}

//--- Structures ---//

#[derive(Debug, Clone)]
pub struct PeopleNowPresentSensor {
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
    pub value: u64,
}

#[derive(Debug, Clone)]
pub struct TemperatureSensor {
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
    pub value: f64,
}

#[derive(Debug, Clone)]
pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

//--- Serialization ---//

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        self.people_now_present.as_ref().map_or((), |v| { d.insert("people_now_present".to_string(), v.to_json()); });
        self.temperature.as_ref().map_or((), |v| { d.insert("temperature".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        self.location.as_ref().map_or((), |v| { d.insert("location".to_string(), v.to_json()); });
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.names.as_ref().map_or((), |v| { d.insert("names".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use rustc::ty::subst::Subst;
use rustc::ty::TypeVariants;
use rustc::ty;
use rustc::hir::*;
use syntax::ast::{Attribute, MetaItemKind};
use syntax::codemap::Span;
use utils::paths;
use utils::{match_path, span_lint_and_then};

/// **What it does:** This lint warns about deriving `Hash` but implementing `PartialEq`
/// explicitly.
///
/// **Why is this bad?** The implementation of these traits must agree (for example for use with
/// `HashMap`) so it’s probably a bad idea to use a default-generated `Hash` implementation  with
/// an explicitly defined `PartialEq`. In particular, the following must hold for any type:
///
/// ```rust
/// k1 == k2 ⇒ hash(k1) == hash(k2)
/// ```
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// #[derive(Hash)]
/// struct Foo;
///
/// impl PartialEq for Foo {
///     ..
/// }
/// ```
declare_lint! {
    pub DERIVE_HASH_XOR_EQ,
    Warn,
    "deriving `Hash` but implementing `PartialEq` explicitly"
}

/// **What it does:** This lint warns about explicit `Clone` implementation for `Copy` types.
///
/// **Why is this bad?** To avoid surprising behaviour, these traits should agree and the behaviour
/// of `Copy` cannot be overridden. In almost all situations a `Copy` type should have a `Clone`
/// implementation that does nothing more than copy the object, which is what
/// `#[derive(Copy, Clone)]` gets you.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// #[derive(Copy)]
/// struct Foo;
///
/// impl Clone for Foo {
///     ..
/// }
/// ```
declare_lint! {
    pub EXPL_IMPL_CLONE_ON_COPY,
    Warn,
    "implementing `Clone` explicitly on `Copy` types"
}

pub struct Derive;

impl LintPass for Derive {
    fn get_lints(&self) -> LintArray {
        lint_array!(EXPL_IMPL_CLONE_ON_COPY, DERIVE_HASH_XOR_EQ)
    }
}

impl LateLintPass for Derive {
    fn check_item(&mut self, cx: &LateContext, item: &Item) {
        if_let_chain! {[
            let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node
        ], {
            let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
            let is_automatically_derived = item.attrs.iter().any(is_automatically_derived);

            check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);

            if !is_automatically_derived {
                check_copy_clone(cx, item, trait_ref, ty);
            }
        }}
    }
}

/// Implementation of the `DERIVE_HASH_XOR_EQ` lint.
fn check_hash_peq<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: &TraitRef, ty: ty::Ty<'tcx>, hash_is_automatically_derived: bool) {
    if_let_chain! {[
        match_path(&trait_ref.path, &paths::HASH),
        let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait()
    ], {
        let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id);

        // Look for the PartialEq implementations for `ty`
        peq_trait_def.for_each_relevant_impl(cx.tcx, ty, |impl_id| {
            let peq_is_automatically_derived = cx.tcx.get_attrs(impl_id).iter().any(is_automatically_derived);

            if peq_is_automatically_derived == hash_is_automatically_derived {
                return;
            }

            let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");

            // Only care about `impl PartialEq<Foo> for Foo`
            if trait_ref.input_types()[0] == ty {
                let mess = if peq_is_automatically_derived {
                    "you are implementing `Hash` explicitly but have derived `PartialEq`"
                } else {
                    "you are deriving `Hash` but have implemented `PartialEq` explicitly"
                };

                span_lint_and_then(
                    cx, DERIVE_HASH_XOR_EQ, span,
                    mess,
                    |db| {
                    if let Some(node_id) = cx.tcx.map.as_local_node_id(impl_id) {
                        db.span_note(
                            cx.tcx.map.span(node_id),
                            "`PartialEq` implemented here"
                        );
                    }
                });
            }
        });
    }}
}

/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) {
    if match_path(&trait_ref.path, &paths::CLONE_TRAIT) {
        let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
        let subst_ty = ty.subst(cx.tcx, parameter_environment.free_substs);

        if subst_ty.moves_by_default(cx.tcx.global_tcx(), &parameter_environment, item.span) {
            return; // ty is not Copy
        }

        // Some types are not Clone by default but could be cloned `by hand` if necessary
        match ty.sty {
            TypeVariants::TyEnum(def, substs) | TypeVariants::TyStruct(def, substs) => {
                for variant in &def.variants {
                    for field in &variant.fields {
                        match field.ty(cx.tcx, substs).sty {
                            TypeVariants::TyArray(_, size) if size > 32 => {
                                return;
                            }
                            TypeVariants::TyFnPtr(..) => {
                                return;
                            }
                            TypeVariants::TyTuple(ref tys) if tys.len() > 12 => {
                                return;
                            }
                            _ => (),
                        }
                    }
                }
            }
            _ => (),
        }

        span_lint_and_then(cx,
                           EXPL_IMPL_CLONE_ON_COPY,
                           item.span,
                           "you are implementing `Clone` explicitly on a `Copy` type",
                           |db| {
                               db.span_note(item.span, "consider deriving `Clone` or removing `Copy`");
                           });
    }
}

/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d implementations have.
fn is_automatically_derived(attr: &Attribute) -> bool {
    if let MetaItemKind::Word(ref word) = attr.node.value.node {
        word == &"automatically_derived"
    } else {
        false
    }
}
<commit_msg>Remove useless `if_let_chain`<commit_after>use rustc::lint::*;
use rustc::ty::subst::Subst;
use rustc::ty::TypeVariants;
use rustc::ty;
use rustc::hir::*;
use syntax::ast::{Attribute, MetaItemKind};
use syntax::codemap::Span;
use utils::paths;
use utils::{match_path, span_lint_and_then};

/// **What it does:** This lint warns about deriving `Hash` but implementing `PartialEq`
/// explicitly.
///
/// **Why is this bad?** The implementation of these traits must agree (for example for use with
/// `HashMap`) so it’s probably a bad idea to use a default-generated `Hash` implementation  with
/// an explicitly defined `PartialEq`. In particular, the following must hold for any type:
///
/// ```rust
/// k1 == k2 ⇒ hash(k1) == hash(k2)
/// ```
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// #[derive(Hash)]
/// struct Foo;
///
/// impl PartialEq for Foo {
///     ..
/// }
/// ```
declare_lint! {
    pub DERIVE_HASH_XOR_EQ,
    Warn,
    "deriving `Hash` but implementing `PartialEq` explicitly"
}

/// **What it does:** This lint warns about explicit `Clone` implementation for `Copy` types.
///
/// **Why is this bad?** To avoid surprising behaviour, these traits should agree and the behaviour
/// of `Copy` cannot be overridden. In almost all situations a `Copy` type should have a `Clone`
/// implementation that does nothing more than copy the object, which is what
/// `#[derive(Copy, Clone)]` gets you.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// #[derive(Copy)]
/// struct Foo;
///
/// impl Clone for Foo {
///     ..
/// }
/// ```
declare_lint! {
    pub EXPL_IMPL_CLONE_ON_COPY,
    Warn,
    "implementing `Clone` explicitly on `Copy` types"
}

pub struct Derive;

impl LintPass for Derive {
    fn get_lints(&self) -> LintArray {
        lint_array!(EXPL_IMPL_CLONE_ON_COPY, DERIVE_HASH_XOR_EQ)
    }
}

impl LateLintPass for Derive {
    fn check_item(&mut self, cx: &LateContext, item: &Item) {
        if let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
            let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
            let is_automatically_derived = item.attrs.iter().any(is_automatically_derived);

            check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);

            if !is_automatically_derived {
                check_copy_clone(cx, item, trait_ref, ty);
            }
        }
    }
}

/// Implementation of the `DERIVE_HASH_XOR_EQ` lint.
fn check_hash_peq<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: &TraitRef, ty: ty::Ty<'tcx>, hash_is_automatically_derived: bool) {
    if_let_chain! {[
        match_path(&trait_ref.path, &paths::HASH),
        let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait()
    ], {
        let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id);

        // Look for the PartialEq implementations for `ty`
        peq_trait_def.for_each_relevant_impl(cx.tcx, ty, |impl_id| {
            let peq_is_automatically_derived = cx.tcx.get_attrs(impl_id).iter().any(is_automatically_derived);

            if peq_is_automatically_derived == hash_is_automatically_derived {
                return;
            }

            let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");

            // Only care about `impl PartialEq<Foo> for Foo`
            if trait_ref.input_types()[0] == ty {
                let mess = if peq_is_automatically_derived {
                    "you are implementing `Hash` explicitly but have derived `PartialEq`"
                } else {
                    "you are deriving `Hash` but have implemented `PartialEq` explicitly"
                };

                span_lint_and_then(
                    cx, DERIVE_HASH_XOR_EQ, span,
                    mess,
                    |db| {
                    if let Some(node_id) = cx.tcx.map.as_local_node_id(impl_id) {
                        db.span_note(
                            cx.tcx.map.span(node_id),
                            "`PartialEq` implemented here"
                        );
                    }
                });
            }
        });
    }}
}

/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) {
    if match_path(&trait_ref.path, &paths::CLONE_TRAIT) {
        let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
        let subst_ty = ty.subst(cx.tcx, parameter_environment.free_substs);

        if subst_ty.moves_by_default(cx.tcx.global_tcx(), &parameter_environment, item.span) {
            return; // ty is not Copy
        }

        // Some types are not Clone by default but could be cloned `by hand` if necessary
        match ty.sty {
            TypeVariants::TyEnum(def, substs) | TypeVariants::TyStruct(def, substs) => {
                for variant in &def.variants {
                    for field in &variant.fields {
                        match field.ty(cx.tcx, substs).sty {
                            TypeVariants::TyArray(_, size) if size > 32 => {
                                return;
                            }
                            TypeVariants::TyFnPtr(..) => {
                                return;
                            }
                            TypeVariants::TyTuple(ref tys) if tys.len() > 12 => {
                                return;
                            }
                            _ => (),
                        }
                    }
                }
            }
            _ => (),
        }

        span_lint_and_then(cx,
                           EXPL_IMPL_CLONE_ON_COPY,
                           item.span,
                           "you are implementing `Clone` explicitly on a `Copy` type",
                           |db| {
                               db.span_note(item.span, "consider deriving `Clone` or removing `Copy`");
                           });
    }
}

/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d implementations have.
fn is_automatically_derived(attr: &Attribute) -> bool {
    if let MetaItemKind::Word(ref word) = attr.node.value.node {
        word == &"automatically_derived"
    } else {
        false
    }
}
<|endoftext|>


<commit_before>extern crate ggez;
extern crate clap;
use clap::{Arg, App};
use ggez::*;
use ggez::graphics::{DrawMode, Point2};
use std::time::Duration;

struct MainState {
    pos_x: f32,
}

impl MainState {
    fn new(_ctx: &mut Context) -> GameResult<MainState> {
        let s = MainState { pos_x: 0.0 };
        Ok(s)
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        self.pos_x = self.pos_x % 800.0 + 1.0;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        graphics::circle(ctx, DrawMode::Line(3.0), Point2::new(400.0, 300.0), 100.0, 4.0)?;
        graphics::present(ctx);
        Ok(())
    }
}

pub fn main() {
    let matches = App::new("graphics settings example")
        .arg(Arg::with_name("msaa")
            .short("m")
            .value_name("N")
            .help("Number of MSAA samples to do (powers of 2 from 1 to 16)")
            .takes_value(true))
        .get_matches();

    let msaa: u32 = matches.value_of("msaa")
        .unwrap_or("1")
        .parse()
        .expect("Option msaa needs to be a number!");
    let mut c = conf::Conf::new();
    c.window_mode.samples = conf::NumSamples::from_u32(msaa)
        .expect("Option msaa needs to be 1, 2, 4, 8 or 16!");
    let ctx = &mut Context::load_from_conf("super_simple", "ggez", c).unwrap();
    let state = &mut MainState::new(ctx).unwrap();
    event::run(ctx, state).unwrap();
}
<commit_msg>Circle slowly rotates<commit_after>extern crate ggez;
extern crate clap;
use clap::{Arg, App};
use ggez::*;
use ggez::graphics::{DrawMode, Point2, Drawable};
use std::time::Duration;

struct MainState {
    pos_x: f32,
    angle: f32, // in radians
}

impl MainState {
    fn new(_ctx: &mut Context) -> GameResult<MainState> {
        let s = MainState { pos_x: 0.0, angle: 0.0 };
        Ok(s)
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        self.pos_x = self.pos_x % 800.0 + 1.0;
        self.angle = self.angle + 0.01;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);

        let rot_circle = graphics::Mesh::new_circle(ctx, DrawMode::Line(3.0), Point2::new(0.0, 0.0), 100.0, 4.0)?;

        rot_circle.draw(ctx, Point2::new(400.0, 300.0), self.angle)?;
        graphics::present(ctx);
        Ok(())
    }
}

pub fn main() {
    let matches = App::new("graphics settings example")
        .arg(Arg::with_name("msaa")
            .short("m")
            .value_name("N")
            .help("Number of MSAA samples to do (powers of 2 from 1 to 16)")
            .takes_value(true))
        .get_matches();

    let msaa: u32 = matches.value_of("msaa")
        .unwrap_or("1")
        .parse()
        .expect("Option msaa needs to be a number!");
    let mut c = conf::Conf::new();
    c.window_mode.samples = conf::NumSamples::from_u32(msaa)
        .expect("Option msaa needs to be 1, 2, 4, 8 or 16!");
    let ctx = &mut Context::load_from_conf("super_simple", "ggez", c).unwrap();
    let state = &mut MainState::new(ctx).unwrap();
    event::run(ctx, state).unwrap();
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::env;
use std::ffi::{OsStr, OsString};
use std::iter::FromIterator;
use std::path::PathBuf;

use indexmap::IndexSet;

pub struct PathVec {
    vec: VecDeque<PathBuf>,
}

impl PathVec {
    pub fn make(&self) -> OsString {
        return env::join_paths(self.unique()).expect("join path error");
    }

    pub fn iter(&self) -> impl Iterator<Item=&PathBuf> {
        self.vec.iter()
    }

    pub fn unique(&self) -> Self {
        self.vec.iter()
            .collect::<IndexSet<_>>()
            .into_iter()
            .cloned()
            .collect()
    }

    pub fn no_version_managers(&self) -> Self {
        self.vec.iter().filter(|x| {
            !x.ends_with(".pyenv/shims") && !x.ends_with(".rbenv/shims")
        }).cloned().collect()
    }

    pub fn push_front<T: Into<PathBuf>>(&mut self, path: T) {
        self.vec.push_front(path.into())
    }

    #[allow(dead_code)]
    pub fn push_back<T: Into<PathBuf>>(&mut self, path: T) {
        self.vec.push_back(path.into())
    }

    pub fn parse<T: AsRef<OsStr>>(input: T) -> Self {
        let unparsed = input.as_ref();
        if !unparsed.is_empty() {
            env::split_paths(unparsed).collect()
        } else {
            Self::new()
        }
    }

    pub fn new() -> Self {
        Self {
            vec: VecDeque::new(),
        }
    }
}

impl FromIterator<PathBuf> for PathVec {
    fn from_iter<T: IntoIterator<Item=PathBuf>>(iter: T) -> Self {
        Self {
            vec: iter.into_iter().collect()
        }
    }
}

impl IntoIterator for PathVec {
    type Item = PathBuf;
    type IntoIter = std::collections::vec_deque::IntoIter<PathBuf>;

    fn into_iter(self) -> Self::IntoIter {
        self.vec.into_iter()
    }
}

#[cfg(test)]
mod tests {
    // Note this useful idiom: importing names from outer (for mod tests) scope.
    use super::*;

    const FOO: &str = "/foo";
    const BAR: &str = "/bar";

    #[test]
    fn test() {
        // no item
        let ps = PathVec::parse(OsString::new());
        let actual = ps.make();
        assert_eq!(actual, "");

        // no item add one to front
        let mut ps = PathVec::parse(OsString::new());
        ps.push_front(FOO.to_string());
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // no item add one to back
        let mut ps = PathVec::parse(OsString::new());
        ps.push_back(FOO.to_string());
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // no item add two items to back
        let mut ps = PathVec::parse(OsString::new());
        ps.push_back(FOO.to_string());
        ps.push_back(BAR.to_string());
        let actual = ps.make();
        let expected = OsString::from(format!("{}:{}", FOO, BAR));
        assert_eq!(actual, expected);

        // one item
        let ps = PathVec::parse(OsString::from(FOO));
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // two items
        let input = OsString::from(format!("{}:{}", FOO, BAR));
        let ps = PathVec::parse(&input);
        let actual = ps.make();
        assert_eq!(actual, input);

        // move order correctly
        let input = OsString::from("/a:/b:/c");
        let mut ps = PathVec::parse(&input);
        ps.push_front("/c".to_string());
        let actual = ps.make();
        let expect = OsString::from("/c:/a:/b");
        assert_eq!(actual, expect);

        // remove pyenv, rbenv, and node path
        let input = OsString::from("/a:/home/.pyenv/shims:/home/.rbenv/shims");
        let ps = PathVec::parse(&input).no_version_managers();
        let actual = ps.make();
        assert_eq!(actual, OsString::from("/a"))
    }

    #[test]
    fn test_unique() {
        let input = OsString::from("/a:/b:/a");
        let ps = PathVec::parse(&input);
        let actual = ps.make();
        assert_eq!(actual, OsString::from("/a:/b"))
    }
}
<commit_msg>fix some wierd LD_LIBRARY_PATH<commit_after>use std::collections::VecDeque;
use std::env;
use std::ffi::{OsStr, OsString};
use std::iter::FromIterator;
use std::path::PathBuf;

use indexmap::IndexSet;
use nix::NixPath;

pub struct PathVec {
    vec: VecDeque<PathBuf>,
}

impl PathVec {
    pub fn make(&self) -> OsString {
        return env::join_paths(self.unique()).expect("join path error");
    }

    pub fn iter(&self) -> impl Iterator<Item=&PathBuf> {
        self.vec.iter()
    }

    pub fn unique(&self) -> Self {
        self.vec.iter()
            .collect::<IndexSet<_>>()
            .into_iter()
            .cloned()
            .collect()
    }

    pub fn no_version_managers(&self) -> Self {
        self.vec.iter().filter(|x| {
            !x.ends_with(".pyenv/shims") && !x.ends_with(".rbenv/shims")
        }).cloned().collect()
    }

    pub fn push_front<T: Into<PathBuf>>(&mut self, path: T) {
        self.vec.push_front(path.into())
    }

    #[allow(dead_code)]
    pub fn push_back<T: Into<PathBuf>>(&mut self, path: T) {
        self.vec.push_back(path.into())
    }

    pub fn parse<T: AsRef<OsStr>>(input: T) -> Self {
        let unparsed = input.as_ref();
        if !unparsed.is_empty() {
            env::split_paths(unparsed).filter(|p| p.len() > 0).collect()
        } else {
            Self::new()
        }
    }

    pub fn new() -> Self {
        Self {
            vec: VecDeque::new(),
        }
    }
}

impl FromIterator<PathBuf> for PathVec {
    fn from_iter<T: IntoIterator<Item=PathBuf>>(iter: T) -> Self {
        Self {
            vec: iter.into_iter().collect()
        }
    }
}

impl IntoIterator for PathVec {
    type Item = PathBuf;
    type IntoIter = std::collections::vec_deque::IntoIter<PathBuf>;

    fn into_iter(self) -> Self::IntoIter {
        self.vec.into_iter()
    }
}

#[cfg(test)]
mod tests {
    // Note this useful idiom: importing names from outer (for mod tests) scope.
    use super::*;

    const FOO: &str = "/foo";
    const BAR: &str = "/bar";

    #[test]
    fn test() {
        // no item
        let ps = PathVec::parse(OsString::new());
        let actual = ps.make();
        assert_eq!(actual, "");

        // no item add one to front
        let mut ps = PathVec::parse(OsString::new());
        ps.push_front(FOO.to_string());
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // no item add one to back
        let mut ps = PathVec::parse(OsString::new());
        ps.push_back(FOO.to_string());
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // no item add two items to back
        let mut ps = PathVec::parse(OsString::new());
        ps.push_back(FOO.to_string());
        ps.push_back(BAR.to_string());
        let actual = ps.make();
        let expected = OsString::from(format!("{}:{}", FOO, BAR));
        assert_eq!(actual, expected);

        // one item
        let ps = PathVec::parse(OsString::from(FOO));
        let actual = ps.make();
        assert_eq!(actual, FOO);

        // should fix following cases
        let ps = PathVec::parse(OsString::from(":/foo"));
        let actual = ps.make();
        assert_eq!(actual, "/foo");
        let ps = PathVec::parse(OsString::from("/foo:"));
        let actual = ps.make();
        assert_eq!(actual, "/foo");

        // two items
        let input = OsString::from(format!("{}:{}", FOO, BAR));
        let ps = PathVec::parse(&input);
        let actual = ps.make();
        assert_eq!(actual, input);

        // move order correctly
        let input = OsString::from("/a:/b:/c");
        let mut ps = PathVec::parse(&input);
        ps.push_front("/c".to_string());
        let actual = ps.make();
        let expect = OsString::from("/c:/a:/b");
        assert_eq!(actual, expect);

        // remove pyenv, rbenv, and node path
        let input = OsString::from("/a:/home/.pyenv/shims:/home/.rbenv/shims");
        let ps = PathVec::parse(&input).no_version_managers();
        let actual = ps.make();
        assert_eq!(actual, OsString::from("/a"))
    }

    #[test]
    fn test_unique() {
        let input = OsString::from("/a:/b:/a");
        let ps = PathVec::parse(&input);
        let actual = ps.make();
        assert_eq!(actual, OsString::from("/a:/b"))
    }
}
<|endoftext|>


<commit_before>use raft::raftpb::*;
use std;
use std::{io, fmt, ops};

pub type Result<T> = std::result::Result<T, std::error::Error>;

pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state() -> Result<RaftState>;
    fn entries(low: u64, high: u64, max_size: u64) -> Vec<Entry>;
    fn term(idx: u64) -> Result<u64>;
    fn first_index() -> Result<u64>;
    fn last_index() -> Result<u64>;
    fn snapshot() -> Box<Snapshot>;
}
<commit_msg>Tiny clean up<commit_after>use raft::raftpb::*;
use std::{result, error};
use std::{io, fmt, ops};

pub type Result<T> = result::Result<T, error::Error>;

pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state() -> Result<RaftState>;
    fn entries(low: u64, high: u64, max_size: u64) -> Vec<Entry>;
    fn term(idx: u64) -> Result<u64>;
    fn first_index() -> Result<u64>;
    fn last_index() -> Result<u64>;
    fn snapshot() -> Box<Snapshot>;
}
<|endoftext|>


<commit_before>use libc::{c_int, c_uint, c_uchar};

#[cfg(not(target_os = "macos"))]
pub const TIOCGWINSZ: usize = 0x00005413;

#[cfg(target_os = "macos")]
pub const TIOCGWINSZ: usize = 0x40087468;

extern {
    pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
    pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *mut Termios) -> c_int;
    pub fn cfmakeraw(termptr: *mut Termios);
}

#[derive(Clone)]
#[repr(C)]
pub struct Termios {
    c_iflag: c_uint,
    c_oflag: c_uint,
    c_cflag: c_uint,
    c_lflag: c_uint,
    c_line: c_uchar,
    c_cc: [c_uchar; 32],
    c_ispeed: c_uint,
    c_ospeed: c_uint,
}

pub fn get_terminal_attr() -> (Termios, c_int) {
    unsafe {
        let mut ios = Termios {
            c_iflag: 0,
            c_oflag: 0,
            c_cflag: 0,
            c_lflag: 0,
            c_line: 0,
            c_cc: [0; 32],
            c_ispeed: 0,
            c_ospeed: 0
        };

        let attr = tcgetattr(0, &mut ios);
        (ios, attr)
    }
}

pub fn set_terminal_attr(ios: *mut Termios) -> c_int {
    unsafe {
        tcsetattr(0, 0, ios)
    }
}

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

    #[test]
    fn test_get_terminal_attr() {
        get_terminal_attr();
        get_terminal_attr();
        get_terminal_attr();
    }
    #[test]
    fn test_set_terminal_attr() {
        let mut ios = get_terminal_attr().0;
        set_terminal_attr(&mut ios as *mut _);
    }
}
<commit_msg>Use libc termios struct<commit_after>use libc::c_int;
use std::mem;

pub use libc::termios as Termios;

#[cfg(not(target_os = "macos"))]
pub const TIOCGWINSZ: usize = 0x00005413;

#[cfg(target_os = "macos")]
pub const TIOCGWINSZ: usize = 0x40087468;

extern {
    pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
    pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *mut Termios) -> c_int;
    pub fn cfmakeraw(termptr: *mut Termios);
}

pub fn get_terminal_attr() -> (Termios, c_int) {
    unsafe {
        let mut ios = mem::zeroed();
        let attr = tcgetattr(0, &mut ios);
        (ios, attr)
    }
}

pub fn set_terminal_attr(ios: *mut Termios) -> c_int {
    unsafe {
        tcsetattr(0, 0, ios)
    }
}

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

    #[test]
    fn test_get_terminal_attr() {
        get_terminal_attr();
        get_terminal_attr();
        get_terminal_attr();
    }
    #[test]
    fn test_set_terminal_attr() {
        let mut ios = get_terminal_attr().0;
        set_terminal_attr(&mut ios as *mut _);
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::marker::PhantomData;
use gl;
use gl::types::*;
use context::Context;
use image_data::{Image2d, TextelFormat, ImageFormat};
use types::GLError;

pub struct Texture<T: TextureType> {
    gl_id: GLuint,
    phantom: PhantomData<*mut T>
}
pub type Texture2d = Texture<Tx2d>;
pub type TextureCubeMap = Texture<TxCubeMap>;

impl<T: TextureType> Texture<T> {
    pub fn gl_id(&self) -> GLuint {
        self.gl_id
    }
}

impl<T: TextureType> Drop for Texture<T> {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteTextures(1, &self.gl_id as *const GLuint);
        }
    }
}

impl Context {
    pub unsafe fn gen_texture<T: TextureType>(&self) -> Texture<T> {
        let mut id : GLuint =  0;

        gl::GenTextures(1, &mut id as *mut GLuint);
        dbg_gl_sanity_check! {
            GLError::InvalidValue => "`n` is negative",
            _ => "Unknown error"
        }

        Texture {
            gl_id: id,
            phantom: PhantomData
        }
    }
}

pub trait ImageTargetType {
    fn gl_enum(&self) -> GLenum;
}

pub trait TextureType {
    type ImageTargetType: ImageTargetType;

    fn target() -> TextureBindingTarget;
}

pub struct Tx2d;

gl_enum! {
    pub gl_enum Tx2dImageTarget {
        Texture2d as TEXTURE_2D_TARGET = gl::TEXTURE_2D
    }
}

impl ImageTargetType for Tx2dImageTarget {
    fn gl_enum(&self) -> GLenum {
        self.gl_enum()
    }
}

impl TextureType for Tx2d {
    type ImageTargetType = Tx2dImageTarget;

    fn target() -> TextureBindingTarget {
        TextureBindingTarget::Texture2d
    }
}

pub struct TxCubeMap;

gl_enum! {
    pub gl_enum TxCubeMapImageTarget {
        CubeMapPositiveX as TEXTURE_CUBE_MAP_POSITIVE_X =
            gl::TEXTURE_CUBE_MAP_POSITIVE_X,
        CubeMapNegativeX as TEXTURE_CUBE_MAP_NEGATIVE_X =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_X,
        CubeMapPositiveY as TEXTURE_CUBE_MAP_POSITIVE_Y =
            gl::TEXTURE_CUBE_MAP_POSITIVE_Y,
        CubeMapNegativeY as TEXTURE_CUBE_MAP_NEGATIVE_Y =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_Y,
        CubeMapPositiveZ as TEXTURE_CUBE_MAP_POSITIVE_Z =
            gl::TEXTURE_CUBE_MAP_POSITIVE_Z,
        CubeMapNegativeZ as TEXTURE_CUBE_MAP_NEGATIVE_Z =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_Z
    }
}

impl ImageTargetType for TxCubeMapImageTarget {
    fn gl_enum(&self) -> GLenum {
        self.gl_enum()
    }
}

impl TextureType for TxCubeMap {
    type ImageTargetType = TxCubeMapImageTarget;

    fn target() -> TextureBindingTarget {
        TextureBindingTarget::TextureCubeMap
    }
}

gl_enum! {
    pub gl_enum TextureBindingTarget {
        Texture2d as TEXTURE_2D = gl::TEXTURE_2D,
        TextureCubeMap as TEXTURE_CUBE_MAP = gl::TEXTURE_CUBE_MAP
    }
}

// TODO: Use type refinements someday...
#[derive(Debug, Clone, Copy)]
pub enum TextureFilter {
    Nearest,
    Linear
}

#[derive(Debug, Clone, Copy)]
pub enum TextureMipmapFilter {
    Filter(TextureFilter),
    MipmapFilter { criterion: TextureFilter, mipmap: TextureFilter }
}

pub const NEAREST : TextureFilter = TextureFilter::Nearest;
pub const LINEAR : TextureFilter = TextureFilter::Linear;
pub const NEAREST_MIPMAP_NEAREST : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Nearest,
        mipmap: TextureFilter::Nearest
    };
pub const LINEAR_MIPMAP_NEAREST : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Linear,
        mipmap: TextureFilter::Nearest
    };
pub const NEAREST_MIPMAP_LINEAR : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Nearest,
        mipmap: TextureFilter::Linear
    };
pub const LINEAR_MIPMAP_LINEAR : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Linear,
        mipmap: TextureFilter::Linear
    };

#[allow(dead_code)]
impl TextureFilter {
    fn from_gl(gl_enum: GLenum) -> Result<Self, ()> {
        match gl_enum {
            gl::NEAREST => { Ok(self::NEAREST) },
            gl::LINEAR => { Ok(self::LINEAR) },
            _ => { Err(()) }
        }
    }

    fn gl_enum(&self) -> GLenum {
        match *self {
            self::NEAREST => gl::NEAREST,
            self::LINEAR => gl::LINEAR
        }
    }
}

#[allow(dead_code)]
impl TextureMipmapFilter {
    fn from_gl(gl_enum: GLenum) -> Result<Self, ()> {
        match gl_enum {
            gl::NEAREST => { Ok(TextureMipmapFilter::Filter(self::NEAREST)) },
            gl::LINEAR => { Ok(TextureMipmapFilter::Filter(self::LINEAR)) },
            gl::NEAREST_MIPMAP_NEAREST => { Ok(self::NEAREST_MIPMAP_NEAREST) },
            gl::LINEAR_MIPMAP_NEAREST => { Ok(self::LINEAR_MIPMAP_NEAREST) },
            gl::NEAREST_MIPMAP_LINEAR => { Ok(self::NEAREST_MIPMAP_LINEAR) },
            gl::LINEAR_MIPMAP_LINEAR => { Ok(self::LINEAR_MIPMAP_LINEAR) },
            _ => { Err(()) }
        }
    }

    fn gl_enum(&self) -> GLenum {
        match *self {
            TextureMipmapFilter::Filter(self::LINEAR) => { gl::LINEAR },
            TextureMipmapFilter::Filter(self::NEAREST) => { gl::NEAREST },
            self::NEAREST_MIPMAP_NEAREST => { gl::NEAREST_MIPMAP_NEAREST },
            self::LINEAR_MIPMAP_NEAREST => { gl::LINEAR_MIPMAP_NEAREST },
            self::NEAREST_MIPMAP_LINEAR => { gl::NEAREST_MIPMAP_LINEAR },
            self::LINEAR_MIPMAP_LINEAR => { gl::LINEAR_MIPMAP_LINEAR }
        }
    }
}

impl From<TextureFilter> for TextureMipmapFilter {
    fn from(filter: TextureFilter) -> TextureMipmapFilter {
        TextureMipmapFilter::Filter(filter)
    }
}

gl_enum! {
    pub gl_enum TextureWrapMode {
        ClampToEdge as CLAMP_TO_EDGE = gl::CLAMP_TO_EDGE,
        MirroredRepeat as MIRRORED_REPEAT = gl::MIRRORED_REPEAT,
        Repeat as REPEAT = gl::REPEAT
    }
}

unsafe fn _tex_parameter_iv(target: TextureBindingTarget,
                            pname: GLenum,
                            params: *const GLint)
{
    gl::TexParameteriv(target.gl_enum(), pname, params);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`target` or `pname` is not an accepted defined value, or `params` should have defined a symbolic constant and does not",
        _ => "Unknown error"
    }
}

unsafe fn _tex_image_2d<T: ImageTargetType>(target: T,
                                            level: u32,
                                            internal_format: TextelFormat,
                                            width: u32,
                                            height: u32,
                                            border: u32,
                                            format: ImageFormat,
                                            image_ptr: *const u8) {
    debug_assert!(internal_format == format.textel_format);
    gl::TexImage2D(target.gl_enum(),
                   level as GLint,
                   internal_format.gl_enum() as GLint,
                   width as GLint,
                   height as GLint,
                   border as GLint,
                   format.textel_format.gl_enum(),
                   format.textel_type.gl_enum(),
                   image_ptr as *const GLvoid);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`target`, `format`, or `type` is not an accepted value",
        GLError::InvalidValue => "`target`, `level`, `internalformat`, `width`, `height`, or `border` is an invalid value",
        GLError::InvalidOperation => "`format` conflicts with either `internalformat` or `type`",
        _ => "Unknown error"
    }
}

pub trait TextureBinding {
    type TextureType: TextureType;

    fn target() -> TextureBindingTarget {
        Self::TextureType::target()
    }

    fn set_min_filter<F: Into<TextureMipmapFilter>>(&mut self, filter: F) {
        let gl_int = filter.into().gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_MIN_FILTER,
                              &gl_int as *const GLint);
        }
    }

    fn set_mag_filter(&mut self, filter: TextureFilter) {
        let gl_int = filter.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_MAG_FILTER,
                              &gl_int as *const GLint);
        }
    }

    fn set_wrap_s(&mut self, wrap_mode: TextureWrapMode) {
        let gl_int = wrap_mode.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_WRAP_S,
                              &gl_int as *const GLint);
        }
    }

    fn set_wrap_t(&mut self, wrap_mode: TextureWrapMode) {
        let gl_int = wrap_mode.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_WRAP_T,
                              &gl_int as *const GLint);
        }
    }

    fn image_2d<I>(&mut self,
                   target: <Self::TextureType as TextureType>::ImageTargetType,
                   level: u32,
                   img: &I)
        where I: Image2d
    {
        unsafe {
            _tex_image_2d(target,
                          level,
                          img.format().textel_format,
                          img.width() as u32,
                          img.height() as u32,
                          0,
                          img.format(),
                          img.textel_bytes().as_ptr());
        }
    }

    fn image_2d_empty<T: ImageTargetType>(&mut self,
                                          target: T,
                                          level: u32,
                                          format: ImageFormat,
                                          width: u32,
                                          height: u32)
    {
        unsafe {
            _tex_image_2d(target,
                          level,
                          format.textel_format,
                          width,
                          height,
                          0,
                          format,
                          ptr::null());
        }
    }
}

pub struct Texture2dBinding<'a> {
    phantom: PhantomData<&'a mut Texture2d>
}

impl<'a> TextureBinding for Texture2dBinding<'a> {
    type TextureType = Tx2d;
}

pub struct TextureCubeMapBinding<'a> {
    phantom: PhantomData<&'a mut TextureCubeMap>
}

impl<'a> TextureBinding for TextureCubeMapBinding<'a> {
    type TextureType = TxCubeMap;
}

unsafe fn _bind_texture<T: TextureType>(texture: &mut Texture<T>) {
    gl::BindTexture(T::target().gl_enum(), texture.gl_id());
    dbg_gl_error! {
        GLError::InvalidEnum => "`target` is not one of the allowed values",
        GLError::InvalidOperation => "`texture` was created with a target that doesn't match `target`",
        _ => "Unknown error"
    }
}

pub struct Texture2dBinder;
impl Texture2dBinder {
    pub fn bind(&mut self, texture: &mut Texture2d) -> Texture2dBinding {
        unsafe {
            _bind_texture(texture);
        }
        Texture2dBinding { phantom: PhantomData }
    }
}

pub struct TextureCubeMapBinder;
impl TextureCubeMapBinder {
    pub fn bind(&mut self, texture: &mut TextureCubeMap)
        -> TextureCubeMapBinding
    {
        unsafe {
            _bind_texture(texture);
        }
        TextureCubeMapBinding { phantom: PhantomData }
    }
}
<commit_msg>Don't use `gl_enum!` for `Tx2dImageTarget`<commit_after>use std::ptr;
use std::marker::PhantomData;
use gl;
use gl::types::*;
use context::Context;
use image_data::{Image2d, TextelFormat, ImageFormat};
use types::GLError;

pub struct Texture<T: TextureType> {
    gl_id: GLuint,
    phantom: PhantomData<*mut T>
}
pub type Texture2d = Texture<Tx2d>;
pub type TextureCubeMap = Texture<TxCubeMap>;

impl<T: TextureType> Texture<T> {
    pub fn gl_id(&self) -> GLuint {
        self.gl_id
    }
}

impl<T: TextureType> Drop for Texture<T> {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteTextures(1, &self.gl_id as *const GLuint);
        }
    }
}

impl Context {
    pub unsafe fn gen_texture<T: TextureType>(&self) -> Texture<T> {
        let mut id : GLuint =  0;

        gl::GenTextures(1, &mut id as *mut GLuint);
        dbg_gl_sanity_check! {
            GLError::InvalidValue => "`n` is negative",
            _ => "Unknown error"
        }

        Texture {
            gl_id: id,
            phantom: PhantomData
        }
    }
}

pub trait ImageTargetType {
    fn gl_enum(&self) -> GLenum;
}

pub trait TextureType {
    type ImageTargetType: ImageTargetType;

    fn target() -> TextureBindingTarget;
}

pub struct Tx2d;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Tx2dImageTarget {
    Texture2d = gl::TEXTURE_2D as isize
}

impl ImageTargetType for Tx2dImageTarget {
    fn gl_enum(&self) -> GLenum {
        *self as GLenum
    }
}

impl TextureType for Tx2d {
    type ImageTargetType = Tx2dImageTarget;

    fn target() -> TextureBindingTarget {
        TextureBindingTarget::Texture2d
    }
}

pub struct TxCubeMap;

gl_enum! {
    pub gl_enum TxCubeMapImageTarget {
        CubeMapPositiveX as TEXTURE_CUBE_MAP_POSITIVE_X =
            gl::TEXTURE_CUBE_MAP_POSITIVE_X,
        CubeMapNegativeX as TEXTURE_CUBE_MAP_NEGATIVE_X =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_X,
        CubeMapPositiveY as TEXTURE_CUBE_MAP_POSITIVE_Y =
            gl::TEXTURE_CUBE_MAP_POSITIVE_Y,
        CubeMapNegativeY as TEXTURE_CUBE_MAP_NEGATIVE_Y =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_Y,
        CubeMapPositiveZ as TEXTURE_CUBE_MAP_POSITIVE_Z =
            gl::TEXTURE_CUBE_MAP_POSITIVE_Z,
        CubeMapNegativeZ as TEXTURE_CUBE_MAP_NEGATIVE_Z =
            gl::TEXTURE_CUBE_MAP_NEGATIVE_Z
    }
}

impl ImageTargetType for TxCubeMapImageTarget {
    fn gl_enum(&self) -> GLenum {
        self.gl_enum()
    }
}

impl TextureType for TxCubeMap {
    type ImageTargetType = TxCubeMapImageTarget;

    fn target() -> TextureBindingTarget {
        TextureBindingTarget::TextureCubeMap
    }
}

gl_enum! {
    pub gl_enum TextureBindingTarget {
        Texture2d as TEXTURE_2D = gl::TEXTURE_2D,
        TextureCubeMap as TEXTURE_CUBE_MAP = gl::TEXTURE_CUBE_MAP
    }
}

// TODO: Use type refinements someday...
#[derive(Debug, Clone, Copy)]
pub enum TextureFilter {
    Nearest,
    Linear
}

#[derive(Debug, Clone, Copy)]
pub enum TextureMipmapFilter {
    Filter(TextureFilter),
    MipmapFilter { criterion: TextureFilter, mipmap: TextureFilter }
}

pub const NEAREST : TextureFilter = TextureFilter::Nearest;
pub const LINEAR : TextureFilter = TextureFilter::Linear;
pub const NEAREST_MIPMAP_NEAREST : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Nearest,
        mipmap: TextureFilter::Nearest
    };
pub const LINEAR_MIPMAP_NEAREST : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Linear,
        mipmap: TextureFilter::Nearest
    };
pub const NEAREST_MIPMAP_LINEAR : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Nearest,
        mipmap: TextureFilter::Linear
    };
pub const LINEAR_MIPMAP_LINEAR : TextureMipmapFilter =
    TextureMipmapFilter::MipmapFilter {
        criterion: TextureFilter::Linear,
        mipmap: TextureFilter::Linear
    };

#[allow(dead_code)]
impl TextureFilter {
    fn from_gl(gl_enum: GLenum) -> Result<Self, ()> {
        match gl_enum {
            gl::NEAREST => { Ok(self::NEAREST) },
            gl::LINEAR => { Ok(self::LINEAR) },
            _ => { Err(()) }
        }
    }

    fn gl_enum(&self) -> GLenum {
        match *self {
            self::NEAREST => gl::NEAREST,
            self::LINEAR => gl::LINEAR
        }
    }
}

#[allow(dead_code)]
impl TextureMipmapFilter {
    fn from_gl(gl_enum: GLenum) -> Result<Self, ()> {
        match gl_enum {
            gl::NEAREST => { Ok(TextureMipmapFilter::Filter(self::NEAREST)) },
            gl::LINEAR => { Ok(TextureMipmapFilter::Filter(self::LINEAR)) },
            gl::NEAREST_MIPMAP_NEAREST => { Ok(self::NEAREST_MIPMAP_NEAREST) },
            gl::LINEAR_MIPMAP_NEAREST => { Ok(self::LINEAR_MIPMAP_NEAREST) },
            gl::NEAREST_MIPMAP_LINEAR => { Ok(self::NEAREST_MIPMAP_LINEAR) },
            gl::LINEAR_MIPMAP_LINEAR => { Ok(self::LINEAR_MIPMAP_LINEAR) },
            _ => { Err(()) }
        }
    }

    fn gl_enum(&self) -> GLenum {
        match *self {
            TextureMipmapFilter::Filter(self::LINEAR) => { gl::LINEAR },
            TextureMipmapFilter::Filter(self::NEAREST) => { gl::NEAREST },
            self::NEAREST_MIPMAP_NEAREST => { gl::NEAREST_MIPMAP_NEAREST },
            self::LINEAR_MIPMAP_NEAREST => { gl::LINEAR_MIPMAP_NEAREST },
            self::NEAREST_MIPMAP_LINEAR => { gl::NEAREST_MIPMAP_LINEAR },
            self::LINEAR_MIPMAP_LINEAR => { gl::LINEAR_MIPMAP_LINEAR }
        }
    }
}

impl From<TextureFilter> for TextureMipmapFilter {
    fn from(filter: TextureFilter) -> TextureMipmapFilter {
        TextureMipmapFilter::Filter(filter)
    }
}

gl_enum! {
    pub gl_enum TextureWrapMode {
        ClampToEdge as CLAMP_TO_EDGE = gl::CLAMP_TO_EDGE,
        MirroredRepeat as MIRRORED_REPEAT = gl::MIRRORED_REPEAT,
        Repeat as REPEAT = gl::REPEAT
    }
}

unsafe fn _tex_parameter_iv(target: TextureBindingTarget,
                            pname: GLenum,
                            params: *const GLint)
{
    gl::TexParameteriv(target.gl_enum(), pname, params);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`target` or `pname` is not an accepted defined value, or `params` should have defined a symbolic constant and does not",
        _ => "Unknown error"
    }
}

unsafe fn _tex_image_2d<T: ImageTargetType>(target: T,
                                            level: u32,
                                            internal_format: TextelFormat,
                                            width: u32,
                                            height: u32,
                                            border: u32,
                                            format: ImageFormat,
                                            image_ptr: *const u8) {
    debug_assert!(internal_format == format.textel_format);
    gl::TexImage2D(target.gl_enum(),
                   level as GLint,
                   internal_format.gl_enum() as GLint,
                   width as GLint,
                   height as GLint,
                   border as GLint,
                   format.textel_format.gl_enum(),
                   format.textel_type.gl_enum(),
                   image_ptr as *const GLvoid);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`target`, `format`, or `type` is not an accepted value",
        GLError::InvalidValue => "`target`, `level`, `internalformat`, `width`, `height`, or `border` is an invalid value",
        GLError::InvalidOperation => "`format` conflicts with either `internalformat` or `type`",
        _ => "Unknown error"
    }
}

pub trait TextureBinding {
    type TextureType: TextureType;

    fn target() -> TextureBindingTarget {
        Self::TextureType::target()
    }

    fn set_min_filter<F: Into<TextureMipmapFilter>>(&mut self, filter: F) {
        let gl_int = filter.into().gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_MIN_FILTER,
                              &gl_int as *const GLint);
        }
    }

    fn set_mag_filter(&mut self, filter: TextureFilter) {
        let gl_int = filter.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_MAG_FILTER,
                              &gl_int as *const GLint);
        }
    }

    fn set_wrap_s(&mut self, wrap_mode: TextureWrapMode) {
        let gl_int = wrap_mode.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_WRAP_S,
                              &gl_int as *const GLint);
        }
    }

    fn set_wrap_t(&mut self, wrap_mode: TextureWrapMode) {
        let gl_int = wrap_mode.gl_enum() as GLint;
        unsafe {
            _tex_parameter_iv(Self::target(),
                              gl::TEXTURE_WRAP_T,
                              &gl_int as *const GLint);
        }
    }

    fn image_2d<I>(&mut self,
                   target: <Self::TextureType as TextureType>::ImageTargetType,
                   level: u32,
                   img: &I)
        where I: Image2d
    {
        unsafe {
            _tex_image_2d(target,
                          level,
                          img.format().textel_format,
                          img.width() as u32,
                          img.height() as u32,
                          0,
                          img.format(),
                          img.textel_bytes().as_ptr());
        }
    }

    fn image_2d_empty<T: ImageTargetType>(&mut self,
                                          target: T,
                                          level: u32,
                                          format: ImageFormat,
                                          width: u32,
                                          height: u32)
    {
        unsafe {
            _tex_image_2d(target,
                          level,
                          format.textel_format,
                          width,
                          height,
                          0,
                          format,
                          ptr::null());
        }
    }
}

pub struct Texture2dBinding<'a> {
    phantom: PhantomData<&'a mut Texture2d>
}

impl<'a> TextureBinding for Texture2dBinding<'a> {
    type TextureType = Tx2d;
}

pub struct TextureCubeMapBinding<'a> {
    phantom: PhantomData<&'a mut TextureCubeMap>
}

impl<'a> TextureBinding for TextureCubeMapBinding<'a> {
    type TextureType = TxCubeMap;
}

unsafe fn _bind_texture<T: TextureType>(texture: &mut Texture<T>) {
    gl::BindTexture(T::target().gl_enum(), texture.gl_id());
    dbg_gl_error! {
        GLError::InvalidEnum => "`target` is not one of the allowed values",
        GLError::InvalidOperation => "`texture` was created with a target that doesn't match `target`",
        _ => "Unknown error"
    }
}

pub struct Texture2dBinder;
impl Texture2dBinder {
    pub fn bind(&mut self, texture: &mut Texture2d) -> Texture2dBinding {
        unsafe {
            _bind_texture(texture);
        }
        Texture2dBinding { phantom: PhantomData }
    }
}

pub struct TextureCubeMapBinder;
impl TextureCubeMapBinder {
    pub fn bind(&mut self, texture: &mut TextureCubeMap)
        -> TextureCubeMapBinding
    {
        unsafe {
            _bind_texture(texture);
        }
        TextureCubeMapBinding { phantom: PhantomData }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io;
use std::io::{Write, Seek, SeekFrom};
use std::mem;
use std::ptr;
use std::cmp::min;
use std::os::windows::fs::FileExt;

use super::{ReadAt, WriteAt};

use std::os::windows::io::AsRawHandle;

extern crate winapi;
use self::winapi::shared::basetsd::SIZE_T;
use self::winapi::shared::minwindef::{BOOL, DWORD};
use self::winapi::um::handleapi::CloseHandle;
use self::winapi::um::sysinfoapi::GetSystemInfo;
use self::winapi::um::winnt::{HANDLE, PAGE_READONLY};
use self::winapi::um::memoryapi::{CreateFileMappingW, MapViewOfFile, UnmapViewOfFile, FILE_MAP_READ};

fn result(e: BOOL) -> io::Result<()> {
    if e == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

fn allocation_granularity() -> usize {
    unsafe {
        let mut info = mem::zeroed();
        GetSystemInfo(&mut info);
        info.dwAllocationGranularity as usize
    }
}

impl ReadAt for File {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> io::Result<usize> {
        let file_len = self.metadata()?.len();

        if buf.is_empty() || pos >= file_len {
            return Ok(0);
        }

        // cast is safe because only relevant if less than buf.len()
        let len = min((file_len - pos) as usize, buf.len());

        unsafe {
            let alignment = pos % allocation_granularity() as u64;
            let aligned_pos = pos - alignment;
            let aligned_len = len + alignment as usize;

            let mapping = CreateFileMappingW(
                self.as_raw_handle() as HANDLE,
                ptr::null_mut(),
                PAGE_READONLY,
                0,
                0,
                ptr::null(),
            );

            if mapping.is_null() {
                return Err(io::Error::last_os_error());
            }

            let aligned_ptr = MapViewOfFile(
                mapping,
                FILE_MAP_READ,
                (aligned_pos >> 32) as DWORD,
                (aligned_pos & 0xffff_ffff) as DWORD,
                aligned_len as SIZE_T,
            );

            CloseHandle(mapping);

            if aligned_ptr.is_null() {
                return Err(io::Error::last_os_error());
            }

            let ptr = (aligned_ptr as *const u8).offset(alignment as isize);
            ptr::copy_nonoverlapping(ptr, buf.as_mut_ptr(), len);

            result(UnmapViewOfFile(aligned_ptr))?;
        }

        Ok(len)
    }
}

impl WriteAt for File {
    fn write_at(&mut self, pos: u64, buf: &[u8]) -> io::Result<usize> {
        let cursor = self.seek(SeekFrom::Current(0))?;
        let result = self.seek_write(buf, pos)?;
        self.seek(SeekFrom::Start(cursor))?;
        Ok(result)
    }

    fn flush(&mut self) -> io::Result<()> {
        Write::flush(self)
    }
}
<commit_msg>win32: fix len computation with very large files<commit_after>use std::fs::File;
use std::io;
use std::io::{Write, Seek, SeekFrom};
use std::mem;
use std::ptr;
use std::cmp::min;
use std::os::windows::fs::FileExt;

use super::{ReadAt, WriteAt};

use std::os::windows::io::AsRawHandle;

extern crate winapi;
use self::winapi::shared::basetsd::SIZE_T;
use self::winapi::shared::minwindef::{BOOL, DWORD};
use self::winapi::um::handleapi::CloseHandle;
use self::winapi::um::sysinfoapi::GetSystemInfo;
use self::winapi::um::winnt::{HANDLE, PAGE_READONLY};
use self::winapi::um::memoryapi::{CreateFileMappingW, MapViewOfFile, UnmapViewOfFile, FILE_MAP_READ};

fn result(e: BOOL) -> io::Result<()> {
    if e == 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

fn allocation_granularity() -> usize {
    unsafe {
        let mut info = mem::zeroed();
        GetSystemInfo(&mut info);
        info.dwAllocationGranularity as usize
    }
}

impl ReadAt for File {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> io::Result<usize> {
        let file_len = self.metadata()?.len();

        if buf.is_empty() || pos >= file_len {
            return Ok(0);
        }

        let len = min(file_len - pos, buf.len() as u64) as usize;

        unsafe {
            let alignment = pos % allocation_granularity() as u64;
            let aligned_pos = pos - alignment;
            let aligned_len = len + alignment as usize;

            let mapping = CreateFileMappingW(
                self.as_raw_handle() as HANDLE,
                ptr::null_mut(),
                PAGE_READONLY,
                0,
                0,
                ptr::null(),
            );

            if mapping.is_null() {
                return Err(io::Error::last_os_error());
            }

            let aligned_ptr = MapViewOfFile(
                mapping,
                FILE_MAP_READ,
                (aligned_pos >> 32) as DWORD,
                (aligned_pos & 0xffff_ffff) as DWORD,
                aligned_len as SIZE_T,
            );

            CloseHandle(mapping);

            if aligned_ptr.is_null() {
                return Err(io::Error::last_os_error());
            }

            let ptr = (aligned_ptr as *const u8).offset(alignment as isize);
            ptr::copy_nonoverlapping(ptr, buf.as_mut_ptr(), len);

            result(UnmapViewOfFile(aligned_ptr))?;
        }

        Ok(len)
    }
}

impl WriteAt for File {
    fn write_at(&mut self, pos: u64, buf: &[u8]) -> io::Result<usize> {
        let cursor = self.seek(SeekFrom::Current(0))?;
        let result = self.seek_write(buf, pos)?;
        self.seek(SeekFrom::Start(cursor))?;
        Ok(result)
    }

    fn flush(&mut self) -> io::Result<()> {
        Write::flush(self)
    }
}
<|endoftext|>