<commit_before>//   Copyright 2015 Colin Sherratt
//
//   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.

use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::ptr;
use std::sync::atomic::AtomicPtr;
use std::sync::atomic::Ordering;
use std::sync::Arc;

/// An Atom wraps an AtomicPtr, it allows for safe mutation of an atomic
/// into common Rust Types.
pub struct Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    inner: AtomicPtr<()>,
    data: PhantomData
,
}

impl
 Debug for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "atom({:?})", self.inner.load(Ordering::Relaxed))
    }
}

impl
 Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    /// Create a empty Atom
    pub fn empty() -> Atom
 {
        Atom {
            inner: AtomicPtr::new(ptr::null_mut()),
            data: PhantomData,
        }
    }

    /// Create a new Atomic from Pointer P
    pub fn new(value: P) -> Atom
 {
        Atom {
            inner: AtomicPtr::new(unsafe { value.into_raw() }),
            data: PhantomData,
        }
    }

    /// Swap a new value into the Atom, This will try multiple
    /// times until it succeeds. The old value will be returned.
    pub fn swap(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.swap(new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// Take the value of the Atom replacing it with null pointer
    /// Returning the contents. If the contents was a `null` pointer the
    /// result will be `None`.
    pub fn take(&self, order: Ordering) -> Option
 {
        let old = self.inner.swap(ptr::null_mut(), order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `None` if the value was written,
    /// otherwise a `Some(v)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.compare_and_swap(ptr::null_mut(), new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(new) })
        } else {
            None
        }
    }

    /// Take the current content, write it into P then do a CAS to extent this
    /// Atom with the previous contents. This can be used to create a LIFO
    ///
    /// Returns true if this set this migrated the Atom from null.
    pub fn replace_and_set_next(
        &self,
        mut value: P,
        load_order: Ordering,
        cas_order: Ordering,
    ) -> bool
    where
        P: GetNextMut<NextPtr = Option
>,
    {
        unsafe {
            let next = value.get_next() as *mut Option
;
            let raw = value.into_raw();
            // Iff next was set to Some(P) we want to
            // assert that it was droppeds
            drop(ptr::read(next));
            loop {
                let pcurrent = self.inner.load(load_order);
                let current = if pcurrent.is_null() {
                    None
                } else {
                    Some(FromRawPtr::from_raw(pcurrent))
                };
                ptr::write(next, current);
                let last = self.inner.compare_and_swap(pcurrent, raw, cas_order);
                if last == pcurrent {
                    return last.is_null();
                }
            }
        }
    }

    /// Check to see if an atom is None
    ///
    /// This only means that the contents was None when it was measured
    pub fn is_none(&self, order: Ordering) -> bool {
        self.inner.load(order).is_null()
    }
}

impl
 Drop for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    fn drop(&mut self) {
        unsafe {
            let ptr = self.inner.load(Ordering::Relaxed);
            if !ptr.is_null() {
                let _: P = FromRawPtr::from_raw(ptr);
            }
        }
    }
}

unsafe impl
 Send for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
}
unsafe impl
 Sync for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
}

/// Convert from into a raw pointer
pub trait IntoRawPtr {
    unsafe fn into_raw(self) -> *mut ();
}

/// Convert from a raw ptr into a pointer
pub trait FromRawPtr {
    unsafe fn from_raw(ptr: *mut ()) -> Self;
}

impl<T> IntoRawPtr for Box<T> {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        Box::into_raw(self) as *mut ()
    }
}

impl<T> FromRawPtr for Box<T> {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> Box<T> {
        Box::from_raw(ptr as *mut T)
    }
}

impl<T> IntoRawPtr for Arc<T> {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        Arc::into_raw(self) as *mut T as *mut ()
    }
}

impl<T> FromRawPtr for Arc<T> {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> Arc<T> {
        Arc::from_raw(ptr as *const () as *const T)
    }
}

// This impl can be useful for stack-allocated and 'static values.
impl<'a, T> IntoRawPtr for &'a T {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        self as *const _ as *mut ()
    }
}

impl<'a, T> FromRawPtr for &'a T {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> &'a T {
        &*(ptr as *mut T)
    }
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, ptr: &T) -> &'a T {
    mem::transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, ptr: &mut T) -> &'a mut T {
    mem::transmute(ptr)
}

/// This is a restricted version of the Atom. It allows for only
/// `set_if_none` to be called.
///
/// `swap` and `take` can be used only with a mutable reference. Meaning
/// that AtomSetOnce is not usable as a
#[derive(Debug)]
pub struct AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr,
{
    inner: Atom
,
}

impl
 AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr,
{
    /// Create an empty `AtomSetOnce`
    pub fn empty() -> AtomSetOnce
 {
        AtomSetOnce {
            inner: Atom::empty(),
        }
    }

    /// Create a new `AtomSetOnce` from Pointer P
    pub fn new(value: P) -> AtomSetOnce
 {
        AtomSetOnce {
            inner: Atom::new(value),
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `OK(())` if the value was written,
    /// otherwise a `Err(P)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        self.inner.set_if_none(v, order)
    }

    /// Convert an `AtomSetOnce` into an `Atom`
    pub fn into_atom(self) -> Atom
 {
        self.inner
    }

    /// Allow access to the atom if exclusive access is granted
    pub fn atom(&mut self) -> &mut Atom
 {
        &mut self.inner
    }

    /// Check to see if an atom is None
    ///
    /// This only means that the contents was None when it was measured
    pub fn is_none(&self, order: Ordering) -> bool {
        self.inner.is_none(order)
    }
}

impl<T, P> AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr + Deref<Target = T>,
{
    /// If the Atom is set, get the value
    pub fn get<'a>(&'a self, order: Ordering) -> Option<&'a T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: P = FromRawPtr::from_raw(ptr);
                let out = copy_lifetime(self, &*v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<Box<T>> {
    /// If the Atom is set, get the value
    pub fn get_mut<'a>(&'a mut self, order: Ordering) -> Option<&'a mut T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let mut v: Box<T> = FromRawPtr::from_raw(ptr);
                let out = copy_mut_lifetime(self, &mut *v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<T>
where
    T: Clone + IntoRawPtr + FromRawPtr,
{
    /// Duplicate the inner pointer if it is set
    pub fn dup<'a>(&self, order: Ordering) -> Option<T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: T = FromRawPtr::from_raw(ptr);
                let out = v.clone();
                mem::forget(v);
                Some(out)
            }
        }
    }
}

/// This is a utility Trait that fetches the next ptr from
/// an object.
pub trait GetNextMut {
    type NextPtr;
    fn get_next(&mut self) -> &mut Self::NextPtr;
}
<commit_msg>Invariant over lifetimes in Atom<commit_after>//   Copyright 2015 Colin Sherratt
//
//   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.

use std::cell::UnsafeCell;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::ptr;
use std::sync::atomic::AtomicPtr;
use std::sync::atomic::Ordering;
use std::sync::Arc;

/// An Atom wraps an AtomicPtr, it allows for safe mutation of an atomic
/// into common Rust Types.
pub struct Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    inner: AtomicPtr<()>,
    data: PhantomData<UnsafeCell
>,
}

impl
 Debug for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "atom({:?})", self.inner.load(Ordering::Relaxed))
    }
}

impl
 Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    /// Create a empty Atom
    pub fn empty() -> Atom
 {
        Atom {
            inner: AtomicPtr::new(ptr::null_mut()),
            data: PhantomData,
        }
    }

    /// Create a new Atomic from Pointer P
    pub fn new(value: P) -> Atom
 {
        Atom {
            inner: AtomicPtr::new(unsafe { value.into_raw() }),
            data: PhantomData,
        }
    }

    /// Swap a new value into the Atom, This will try multiple
    /// times until it succeeds. The old value will be returned.
    pub fn swap(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.swap(new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// Take the value of the Atom replacing it with null pointer
    /// Returning the contents. If the contents was a `null` pointer the
    /// result will be `None`.
    pub fn take(&self, order: Ordering) -> Option
 {
        let old = self.inner.swap(ptr::null_mut(), order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `None` if the value was written,
    /// otherwise a `Some(v)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.compare_and_swap(ptr::null_mut(), new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(new) })
        } else {
            None
        }
    }

    /// Take the current content, write it into P then do a CAS to extent this
    /// Atom with the previous contents. This can be used to create a LIFO
    ///
    /// Returns true if this set this migrated the Atom from null.
    pub fn replace_and_set_next(
        &self,
        mut value: P,
        load_order: Ordering,
        cas_order: Ordering,
    ) -> bool
    where
        P: GetNextMut<NextPtr = Option
>,
    {
        unsafe {
            let next = value.get_next() as *mut Option
;
            let raw = value.into_raw();
            // Iff next was set to Some(P) we want to
            // assert that it was droppeds
            drop(ptr::read(next));
            loop {
                let pcurrent = self.inner.load(load_order);
                let current = if pcurrent.is_null() {
                    None
                } else {
                    Some(FromRawPtr::from_raw(pcurrent))
                };
                ptr::write(next, current);
                let last = self.inner.compare_and_swap(pcurrent, raw, cas_order);
                if last == pcurrent {
                    return last.is_null();
                }
            }
        }
    }

    /// Check to see if an atom is None
    ///
    /// This only means that the contents was None when it was measured
    pub fn is_none(&self, order: Ordering) -> bool {
        self.inner.load(order).is_null()
    }
}

impl
 Drop for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
    fn drop(&mut self) {
        unsafe {
            let ptr = self.inner.load(Ordering::Relaxed);
            if !ptr.is_null() {
                let _: P = FromRawPtr::from_raw(ptr);
            }
        }
    }
}

unsafe impl
 Send for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
}
unsafe impl
 Sync for Atom

where
    P: IntoRawPtr + FromRawPtr,
{
}

/// Convert from into a raw pointer
pub trait IntoRawPtr {
    unsafe fn into_raw(self) -> *mut ();
}

/// Convert from a raw ptr into a pointer
pub trait FromRawPtr {
    unsafe fn from_raw(ptr: *mut ()) -> Self;
}

impl<T> IntoRawPtr for Box<T> {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        Box::into_raw(self) as *mut ()
    }
}

impl<T> FromRawPtr for Box<T> {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> Box<T> {
        Box::from_raw(ptr as *mut T)
    }
}

impl<T> IntoRawPtr for Arc<T> {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        Arc::into_raw(self) as *mut T as *mut ()
    }
}

impl<T> FromRawPtr for Arc<T> {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> Arc<T> {
        Arc::from_raw(ptr as *const () as *const T)
    }
}

// This impl can be useful for stack-allocated and 'static values.
impl<'a, T> IntoRawPtr for &'a T {
    #[inline]
    unsafe fn into_raw(self) -> *mut () {
        self as *const _ as *mut ()
    }
}

impl<'a, T> FromRawPtr for &'a T {
    #[inline]
    unsafe fn from_raw(ptr: *mut ()) -> &'a T {
        &*(ptr as *mut T)
    }
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, ptr: &T) -> &'a T {
    mem::transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S, ptr: &mut T) -> &'a mut T {
    mem::transmute(ptr)
}

/// This is a restricted version of the Atom. It allows for only
/// `set_if_none` to be called.
///
/// `swap` and `take` can be used only with a mutable reference. Meaning
/// that AtomSetOnce is not usable as a
#[derive(Debug)]
pub struct AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr,
{
    inner: Atom
,
}

impl
 AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr,
{
    /// Create an empty `AtomSetOnce`
    pub fn empty() -> AtomSetOnce
 {
        AtomSetOnce {
            inner: Atom::empty(),
        }
    }

    /// Create a new `AtomSetOnce` from Pointer P
    pub fn new(value: P) -> AtomSetOnce
 {
        AtomSetOnce {
            inner: Atom::new(value),
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `OK(())` if the value was written,
    /// otherwise a `Err(P)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        self.inner.set_if_none(v, order)
    }

    /// Convert an `AtomSetOnce` into an `Atom`
    pub fn into_atom(self) -> Atom
 {
        self.inner
    }

    /// Allow access to the atom if exclusive access is granted
    pub fn atom(&mut self) -> &mut Atom
 {
        &mut self.inner
    }

    /// Check to see if an atom is None
    ///
    /// This only means that the contents was None when it was measured
    pub fn is_none(&self, order: Ordering) -> bool {
        self.inner.is_none(order)
    }
}

impl<T, P> AtomSetOnce

where
    P: IntoRawPtr + FromRawPtr + Deref<Target = T>,
{
    /// If the Atom is set, get the value
    pub fn get<'a>(&'a self, order: Ordering) -> Option<&'a T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: P = FromRawPtr::from_raw(ptr);
                let out = copy_lifetime(self, &*v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<Box<T>> {
    /// If the Atom is set, get the value
    pub fn get_mut<'a>(&'a mut self, order: Ordering) -> Option<&'a mut T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let mut v: Box<T> = FromRawPtr::from_raw(ptr);
                let out = copy_mut_lifetime(self, &mut *v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<T>
where
    T: Clone + IntoRawPtr + FromRawPtr,
{
    /// Duplicate the inner pointer if it is set
    pub fn dup<'a>(&self, order: Ordering) -> Option<T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: T = FromRawPtr::from_raw(ptr);
                let out = v.clone();
                mem::forget(v);
                Some(out)
            }
        }
    }
}

/// This is a utility Trait that fetches the next ptr from
/// an object.
pub trait GetNextMut {
    type NextPtr;
    fn get_next(&mut self) -> &mut Self::NextPtr;
}
<|endoftext|>


<commit_before>#![crate_id = "typedopts"]
#![crate_type = "lib"];

extern crate getopts;
extern crate serialize;
use getopts::Matches;
use std::from_str::FromStr;
use std::str::StrSlice;
use serialize::Decodable;
use std::task;
use std::any::AnyOwnExt;

#[deriving(Eq, Show)]
pub enum ErrorType {
  UnimplementedDecoder,
  MissingField(~str),
  ExpectedType(~str, ~str, ~str)
}

#[deriving(Eq, Show)]
pub struct Error {
  e: ErrorType
}

pub type DecoderResult<T> =  Result<T, ErrorType>;

pub struct Decoder {
  priv matches: Matches,
  priv cur: ~str,
  priv current_type: ~str
}

impl Decoder {
  pub fn new(matches: Matches) -> Decoder {
    Decoder {
      matches: matches,
      cur: ~"",
      current_type: ~""
    }
  }

  fn unimplemented(&self) -> ! {
    fail!(Error { e: UnimplementedDecoder });
  }

  fn missing_field(&self, field: &str) -> ! {
    fail!(Error { e: MissingField(field.to_owned()) });
  }

  fn expected(&self, expected: &str, field: &str) -> ! {
    fail!(Error { e: ExpectedType(field.to_owned(),
                       expected.to_owned(),
                       self.matches.opt_str(self.cur).unwrap()) });
  }

}

pub fn decode<T:Send+Decodable<Decoder>>(matches: Matches) -> DecoderResult<T> {
  let result = task::try(proc() {
    let mut decoder = Decoder::new(matches);
    let a:T = Decodable::decode(&mut decoder);
    a
  });

  match result {
    Ok(data) => Ok(data),
    Err(e)   => {
      let err = e.move::<Error>().unwrap();
      Err(err.e)
    }
  }
}

impl ErrorType {
  pub fn to_err_msg(self) -> ~str {
    match self {
      UnimplementedDecoder => format!("this function is not implemented"),
      MissingField(ref s)  => format!("the required field '{}' is not present", s),
      ExpectedType(ref field, ref expected, ref value) => {
        format!("Expected type '{}' for field '{}' but got value '{}'", expected, field, value)
      }
    }
  }
}
impl<T:FromStr> Decoder {
  fn get_field<T:FromStr>(&self, field: &str) -> Option<T> {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => FromStr::from_str(s)
    }
  }
}

impl serialize::Decoder for Decoder {

  fn read_nil(&mut self) {

  }

  fn read_u64(&mut self)  -> u64  {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("u64", self.cur),
        Some(nb) => nb
      }
    }
  }
  fn read_u32(&mut self)  -> u32  { self.read_u64() as u32 }
  fn read_u16(&mut self)  -> u16  { self.read_u64() as u16 }
  fn read_u8 (&mut self)  -> u8   { self.read_u64() as u8 }
  fn read_uint(&mut self) -> uint { self.read_u64() as uint }

  fn read_i64(&mut self) -> i64 {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("i64", self.cur),
        Some(nb) => nb
      }
    }
  }
  fn read_i32(&mut self) -> i32 { self.read_i64() as i32 }
  fn read_i16(&mut self) -> i16 { self.read_i64() as i16 }
  fn read_i8 (&mut self) -> i8  { self.read_i64() as i8 }
  fn read_int(&mut self) -> int { self.read_i64() as int }

  fn read_f32(&mut self) -> f32 { self.read_f64() as f32 }
  fn read_f64(&mut self) -> f64 {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("f64", self.cur),
        Some(nb) => nb
      }
    }
  }

  fn read_bool(&mut self) -> bool {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("boolean", self.cur),
        Some(b) => b
      }
    }
  }

  fn read_char(&mut self) -> char {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => if s.char_len() == 1 { s.char_at(0) } else { self.expected("char", self.cur) }
    }
  }

  fn read_str(&mut self) -> ~str {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => s
    }
  }

  fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum: {}", name);
    self.current_type = name.to_owned();
    f(self)
  }

  fn read_enum_variant<T>(&mut self, names: &[&str], f: |&mut Decoder, uint| -> T) -> T {
    //println!("reading enum variant({}): {}", self.cur, names);
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match names.iter().position(|&e| e == s) {
        None    => self.expected(self.current_type + " enum", self.cur),
        Some(i) => f(self, i)
      }
    }
    //f(self, 0)
  }

  fn read_enum_variant_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum variant_arg: {}", a_idx);
    f(self);
    self.unimplemented()
  }

  fn read_enum_struct_variant<T>(&mut self, names: &[&str], f: |&mut Decoder, uint| -> T) -> T {
    //println!("reading enum struct variant: {}", names);
    f(self, 0);
    self.unimplemented()
  }

  fn read_enum_struct_variant_field<T>(&mut self, f_name: &str, f_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum struct variant field: {}, {}", f_name, f_idx);
    f(self);
    self.unimplemented()
  }

  fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading struct: {} | len = {}", s_name, len);
    self.cur = s_name.to_owned();
    f(self)
  }

  fn read_struct_field<T>(&mut self, f_name: &str, f_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading struct field: {} | idx = {}", f_name, f_idx);
    self.cur = f_name.to_owned();
    let data = f(self);
    //println!("got struct field data: {}", data);
    data
  }

  fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> T) -> T {
    //println!("read_option");
    match self.matches.opt_str(self.cur) {
      None    => {
        //println!("option not there");
        f(self, false)
      },
      Some(s) => {
        //println!("option is there");
        f(self, true)
      }
    }
    //f(self, true);
    //self.unimplemented()
  }

  fn read_tuple<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_tuple_struct<T>(&mut self, s_name: &str, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_tuple_struct_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

}
<commit_msg>try to fix compilation remotely<commit_after>#![crate_id = "typedopts"]
#![crate_type = "lib"]

extern crate getopts;
extern crate serialize;
use getopts::Matches;
use std::from_str::FromStr;
use std::str::StrSlice;
use serialize::Decodable;
use std::task;
use std::any::AnyOwnExt;

#[deriving(Eq, Show)]
pub enum ErrorType {
  UnimplementedDecoder,
  MissingField(~str),
  ExpectedType(~str, ~str, ~str)
}

#[deriving(Eq, Show)]
pub struct Error {
  e: ErrorType
}

pub type DecoderResult<T> =  Result<T, ErrorType>;

pub struct Decoder {
  priv matches: Matches,
  priv cur: ~str,
  priv current_type: ~str
}

impl Decoder {
  pub fn new(matches: Matches) -> Decoder {
    Decoder {
      matches: matches,
      cur: ~"",
      current_type: ~""
    }
  }

  fn unimplemented(&self) -> ! {
    fail!(Error { e: UnimplementedDecoder });
  }

  fn missing_field(&self, field: &str) -> ! {
    fail!(Error { e: MissingField(field.to_owned()) });
  }

  fn expected(&self, expected: &str, field: &str) -> ! {
    fail!(Error { e: ExpectedType(field.to_owned(),
                       expected.to_owned(),
                       self.matches.opt_str(self.cur).unwrap()) });
  }

}

pub fn decode<T:Send+Decodable<Decoder, T>>(matches: Matches) -> DecoderResult<T> {
  let result = task::try(proc() {
    let mut decoder = Decoder::new(matches);
    let a:T = Decodable::decode(&mut decoder);
    a
  });

  match result {
    Ok(data) => Ok(data),
    Err(e)   => {
      let err = e.move::<Error>().unwrap();
      Err(err.e)
    }
  }
}

impl ErrorType {
  pub fn to_err_msg(self) -> ~str {
    match self {
      UnimplementedDecoder => format!("this function is not implemented"),
      MissingField(ref s)  => format!("the required field '{}' is not present", s),
      ExpectedType(ref field, ref expected, ref value) => {
        format!("Expected type '{}' for field '{}' but got value '{}'", expected, field, value)
      }
    }
  }
}
impl<T:FromStr> Decoder {
  fn get_field<T:FromStr>(&self, field: &str) -> Option<T> {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => FromStr::from_str(s)
    }
  }
}

impl serialize::Decoder for Decoder {

  fn read_nil(&mut self) {

  }

  fn read_u64(&mut self)  -> u64  {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("u64", self.cur),
        Some(nb) => nb
      }
    }
  }
  fn read_u32(&mut self)  -> u32  { self.read_u64() as u32 }
  fn read_u16(&mut self)  -> u16  { self.read_u64() as u16 }
  fn read_u8 (&mut self)  -> u8   { self.read_u64() as u8 }
  fn read_uint(&mut self) -> uint { self.read_u64() as uint }

  fn read_i64(&mut self) -> i64 {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("i64", self.cur),
        Some(nb) => nb
      }
    }
  }
  fn read_i32(&mut self) -> i32 { self.read_i64() as i32 }
  fn read_i16(&mut self) -> i16 { self.read_i64() as i16 }
  fn read_i8 (&mut self) -> i8  { self.read_i64() as i8 }
  fn read_int(&mut self) -> int { self.read_i64() as int }

  fn read_f32(&mut self) -> f32 { self.read_f64() as f32 }
  fn read_f64(&mut self) -> f64 {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("f64", self.cur),
        Some(nb) => nb
      }
    }
  }

  fn read_bool(&mut self) -> bool {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match FromStr::from_str(s) {
        None     => self.expected("boolean", self.cur),
        Some(b) => b
      }
    }
  }

  fn read_char(&mut self) -> char {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => if s.char_len() == 1 { s.char_at(0) } else { self.expected("char", self.cur) }
    }
  }

  fn read_str(&mut self) -> ~str {
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => s
    }
  }

  fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum: {}", name);
    self.current_type = name.to_owned();
    f(self)
  }

  fn read_enum_variant<T>(&mut self, names: &[&str], f: |&mut Decoder, uint| -> T) -> T {
    //println!("reading enum variant({}): {}", self.cur, names);
    match self.matches.opt_str(self.cur) {
      None    => self.missing_field(self.cur),
      Some(s) => match names.iter().position(|&e| e == s) {
        None    => self.expected(self.current_type + " enum", self.cur),
        Some(i) => f(self, i)
      }
    }
    //f(self, 0)
  }

  fn read_enum_variant_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum variant_arg: {}", a_idx);
    f(self);
    self.unimplemented()
  }

  fn read_enum_struct_variant<T>(&mut self, names: &[&str], f: |&mut Decoder, uint| -> T) -> T {
    //println!("reading enum struct variant: {}", names);
    f(self, 0);
    self.unimplemented()
  }

  fn read_enum_struct_variant_field<T>(&mut self, f_name: &str, f_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading enum struct variant field: {}, {}", f_name, f_idx);
    f(self);
    self.unimplemented()
  }

  fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading struct: {} | len = {}", s_name, len);
    self.cur = s_name.to_owned();
    f(self)
  }

  fn read_struct_field<T>(&mut self, f_name: &str, f_idx: uint, f: |&mut Decoder| -> T) -> T {
    //println!("reading struct field: {} | idx = {}", f_name, f_idx);
    self.cur = f_name.to_owned();
    let data = f(self);
    //println!("got struct field data: {}", data);
    data
  }

  fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> T) -> T {
    //println!("read_option");
    match self.matches.opt_str(self.cur) {
      None    => {
        //println!("option not there");
        f(self, false)
      },
      Some(s) => {
        //println!("option is there");
        f(self, true)
      }
    }
    //f(self, true);
    //self.unimplemented()
  }

  fn read_tuple<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_tuple_struct<T>(&mut self, s_name: &str, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_tuple_struct_arg<T>(&mut self, a_idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
    f(self, 0);
    self.unimplemented()
  }

  fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

  fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
    f(self);
    self.unimplemented()
  }

}
<|endoftext|>


<commit_before>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};

pub use current::{
    Get,
    Set,
    Modifier,
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = WindowBackEnd::new(
        opengl,
        window_settings,
    );

    let mut gl = Gl::new(opengl);
    let mut fps_counter = FPSCounter::new();

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx(f: ||) {
    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let mut g2d = G2D::new(&mut device);
    let mut renderer = device.create_renderer();
    let event::window::Size([w, h]) = window.get();
    let mut frame = gfx::Frame::new(w as u16, h as u16);

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx(f: ||) {
    f();
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub unsafe fn current_window() -> Current<WindowBackEnd> { Current::new() }
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub unsafe fn current_gfx_device() -> Current<gfx::GlDevice> { Current::new() }
/// The current opengl_graphics back-end
pub unsafe fn current_gl() -> Current<Gl> { Current::new() }
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub unsafe fn current_g2d() -> Current<G2D> { Current::new() }
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub unsafe fn current_renderer() -> Current<gfx::Renderer<gfx::GlCommandBuffer>> { Current::new() }
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub unsafe fn current_frame() -> Current<gfx::Frame> { Current::new() }
/// The current FPS counter
pub unsafe fn current_fps_counter() -> Current<FPSCounter> { Current::new() }

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Current<WindowBackEnd>> {
    unsafe {
        Events::new(current_window())
    }
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    unsafe {
        current_fps_counter().tick()
    }
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    unsafe {
        current_window().set_mut(window::Title(text));
    }
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;

    unsafe {
        let ShouldClose(val) = current_window().get();
        val
    }
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    bg_color: Option<[f32, ..4]>,
    f: |graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    unsafe {
        current_g2d().draw(
            &mut *current_renderer(),
            &*current_frame(),
            |c, g| {
                if let Some(bg_color) = bg_color {
                    graphics::clear(bg_color, g);
                }
                f(c, g);
            });
        current_gfx_device().submit(current_renderer().as_buffer());
        current_renderer().reset();
    }
}

/// Renders 2D graphics using OpenGL.
pub fn render_2d_opengl(
    bg_color: Option<[f32, ..4]>,
    f: |graphics::Context,
        &mut opengl_graphics::Gl|
) {
    unsafe {
        let gl = &mut *current_gl();
        let window::Size([w, h]) = current_window().get();
        gl.draw([0, 0, w as i32, h as i32], |c, g| {
            use graphics::*;
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    }
}

<commit_msg>Added `DANGER` to `render_2d_opengl` and `render_2d_gfx`<commit_after>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};

pub use current::{
    Get,
    Set,
    Modifier,
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = WindowBackEnd::new(
        opengl,
        window_settings,
    );

    let mut gl = Gl::new(opengl);
    let mut fps_counter = FPSCounter::new();

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx(f: ||) {
    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let mut g2d = G2D::new(&mut device);
    let mut renderer = device.create_renderer();
    let event::window::Size([w, h]) = window.get();
    let mut frame = gfx::Frame::new(w as u16, h as u16);

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx(f: ||) {
    f();
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub unsafe fn current_window() -> Current<WindowBackEnd> { Current::new() }
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub unsafe fn current_gfx_device() -> Current<gfx::GlDevice> { Current::new() }
/// The current opengl_graphics back-end
pub unsafe fn current_gl() -> Current<Gl> { Current::new() }
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub unsafe fn current_g2d() -> Current<G2D> { Current::new() }
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub unsafe fn current_renderer() -> Current<gfx::Renderer<gfx::GlCommandBuffer>> { Current::new() }
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub unsafe fn current_frame() -> Current<gfx::Frame> { Current::new() }
/// The current FPS counter
pub unsafe fn current_fps_counter() -> Current<FPSCounter> { Current::new() }

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Current<WindowBackEnd>> {
    unsafe {
        Events::new(current_window())
    }
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    unsafe {
        current_fps_counter().tick()
    }
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    unsafe {
        current_window().set_mut(window::Title(text));
    }
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;

    unsafe {
        let ShouldClose(val) = current_window().get();
        val
    }
}

/// Renders 2D graphics using Gfx.
///
/// ### DANGER
///
/// This function should not be called nested within the closure.
/// Doing so will lead to mutable aliased references to the graphics back-end.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    _: current::DANGER,
    bg_color: Option<[f32, ..4]>,
    f: |graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    unsafe {
        current_g2d().draw(
            &mut *current_renderer(),
            &*current_frame(),
            |c, g| {
                if let Some(bg_color) = bg_color {
                    graphics::clear(bg_color, g);
                }
                f(c, g);
            });
        current_gfx_device().submit(current_renderer().as_buffer());
        current_renderer().reset();
    }
}

/// Renders 2D graphics using OpenGL.
///
/// ### DANGER
///
/// This function should not be called nested within the closure.
/// Doing so will lead to mutable aliased references to the graphics back-end.
pub fn render_2d_opengl(
    _: current::DANGER,
    bg_color: Option<[f32, ..4]>,
    f: |graphics::Context,
        &mut opengl_graphics::Gl|
) {
    unsafe {
        let gl = &mut *current_gl();
        let window::Size([w, h]) = current_window().get();
        gl.draw([0, 0, w as i32, h as i32], |c, g| {
            use graphics::*;
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    }
}

<|endoftext|>


<commit_before>//! A crate that provides the `IpAddr` type, which can represent either an IPv4
//! or an IPv6 address.

use std::fmt;
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::str::FromStr;

/// An IP address, either an IPv4 or IPv6 address.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpAddr {
    /// Representation of an IPv4 address.
    V4(Ipv4Addr),
    /// Representation of an IPv6 address.
    V6(Ipv6Addr),
}

impl fmt::Display for IpAddr {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpAddr::V4(ref a) => a.fmt(fmt),
            IpAddr::V6(ref a) => a.fmt(fmt),
        }
    }
}

impl FromStr for IpAddr {
    type Err = AddrParseError;

    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Ipv4Addr::from_str(s).map(|v4| IpAddr::V4(v4))
            .or_else(|_| {
                Ipv6Addr::from_str(s).map(|v6| IpAddr::V6(v6))
            })
    }
}

/// Methods to convert between `IpAddr` and `std::net::SocketAddr`
pub trait SocketAddrExt {
    /// Creates a new socket address from the (ip, port) pair.
    fn new(ip: IpAddr, port: u16) -> SocketAddr;
    /// Returns the IP address associated with this socket address.
    fn ip(&self) -> IpAddr;
}

impl SocketAddrExt for SocketAddr {
    fn new(ip: IpAddr, port: u16) -> SocketAddr {
        match ip {
            IpAddr::V4(ipv4_addr) => SocketAddr::V4(SocketAddrV4::new(ipv4_addr, port)),
            IpAddr::V6(ipv6_addr) => SocketAddr::V6(SocketAddrV6::new(ipv6_addr, port, 0, 0)),
        }
    }

    fn ip(&self) -> IpAddr {
        match *self {
            SocketAddr::V4(socket_addr_v4) => IpAddr::V4(*socket_addr_v4.ip()),
            SocketAddr::V6(socket_addr_v6) => IpAddr::V6(*socket_addr_v6.ip()),
        }
    }
}

#[test]
fn parse_ipv4() {
    let parsed = IpAddr::from_str("192.168.0.1").unwrap();
    let ipv4 = Ipv4Addr::from_str("192.168.0.1").unwrap();
    assert_eq!(IpAddr::V4(ipv4), parsed);
}

#[test]
fn parse_ipv6() {
    let parsed = IpAddr::from_str("2001:0db8::0001").unwrap();
    let ipv6 = Ipv6Addr::from_str("2001:0db8::0001").unwrap();
    assert_eq!(IpAddr::V6(ipv6), parsed);
}

#[test]
fn parse_fails() {
    let parsed = IpAddr::from_str("nonsense");
    assert!(parsed.is_err());
}

#[test]
fn to_from_socket_addr() {
    let set_ip = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
    let set_port = 45666;
    let socket_addr = <SocketAddr as SocketAddrExt>::new(set_ip, set_port);
    let get_ip = <SocketAddr as SocketAddrExt>::ip(&socket_addr);
    let get_port = socket_addr.port();
    assert_eq!(set_ip, get_ip);
    assert_eq!(set_port, get_port);
}

<commit_msg>Testcases for display<commit_after>//! A crate that provides the `IpAddr` type, which can represent either an IPv4
//! or an IPv6 address.

use std::fmt;
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::str::FromStr;

/// An IP address, either an IPv4 or IPv6 address.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpAddr {
    /// Representation of an IPv4 address.
    V4(Ipv4Addr),
    /// Representation of an IPv6 address.
    V6(Ipv6Addr),
}

impl fmt::Display for IpAddr {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpAddr::V4(ref a) => a.fmt(fmt),
            IpAddr::V6(ref a) => a.fmt(fmt),
        }
    }
}

impl FromStr for IpAddr {
    type Err = AddrParseError;

    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Ipv4Addr::from_str(s).map(|v4| IpAddr::V4(v4))
            .or_else(|_| {
                Ipv6Addr::from_str(s).map(|v6| IpAddr::V6(v6))
            })
    }
}

/// Methods to convert between `IpAddr` and `std::net::SocketAddr`
pub trait SocketAddrExt {
    /// Creates a new socket address from the (ip, port) pair.
    fn new(ip: IpAddr, port: u16) -> SocketAddr;
    /// Returns the IP address associated with this socket address.
    fn ip(&self) -> IpAddr;
}

impl SocketAddrExt for SocketAddr {
    fn new(ip: IpAddr, port: u16) -> SocketAddr {
        match ip {
            IpAddr::V4(ipv4_addr) => SocketAddr::V4(SocketAddrV4::new(ipv4_addr, port)),
            IpAddr::V6(ipv6_addr) => SocketAddr::V6(SocketAddrV6::new(ipv6_addr, port, 0, 0)),
        }
    }

    fn ip(&self) -> IpAddr {
        match *self {
            SocketAddr::V4(socket_addr_v4) => IpAddr::V4(*socket_addr_v4.ip()),
            SocketAddr::V6(socket_addr_v6) => IpAddr::V6(*socket_addr_v6.ip()),
        }
    }
}

#[test]
fn display_ipv4() {
    let ipv4 = Ipv4Addr::new(192, 168, 0, 1);
    let ip = IpAddr::V4(ipv4);
    assert_eq!(format!("{}", ip), format!("{}", ipv4));
}

#[test]
fn display_ipv6() {
    let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1);
    let ip = IpAddr::V6(ipv6);
    assert_eq!(format!("{}", ip), format!("{}", ipv6));
}

#[test]
fn parse_ipv4() {
    let ipv4 = Ipv4Addr::from_str("192.168.0.1").unwrap();
    let ip = IpAddr::from_str("192.168.0.1").unwrap();
    assert_eq!(IpAddr::V4(ipv4), ip);
}

#[test]
fn parse_ipv6() {
    let ipv6 = Ipv6Addr::from_str("2001:0db8::0001").unwrap();
    let ip = IpAddr::from_str("2001:0db8::0001").unwrap();
    assert_eq!(IpAddr::V6(ipv6), ip);
}

#[test]
fn parse_fails() {
    let error = IpAddr::from_str("nonsense");
    assert!(error.is_err());
}

#[test]
fn to_from_socket_addr() {
    let set_ip = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1));
    let set_port = 45666;
    let socket_addr = <SocketAddr as SocketAddrExt>::new(set_ip, set_port);
    let get_ip = <SocketAddr as SocketAddrExt>::ip(&socket_addr);
    let get_port = socket_addr.port();
    assert_eq!(set_ip, get_ip);
    assert_eq!(set_port, get_port);
}
<|endoftext|>


<commit_before>// Copyright 2015 Dawid Ciężarkiewicz
// See LICENSE-MPL
//
//! Non-thread-shareable, simple and efficient Circular Buffer
//! implementation that can store N elements when full (typical circular
//! buffer implementations store N-1) without using separate flags.
//!
//! Uses only `core` so can be used in `#[no_std]` projects by using
//! `no_std` feature.
//!
#![no_std]
#![feature(const_fn)]
#![feature(test)]

use core::option::Option::{self, Some, None};
use core::marker::PhantomData;

extern crate test as test;

const CBUF_DATA_BIT: usize = !((usize::max_value() << 1) >> 1);

pub trait CopyOrClone {
    fn clone(&self) -> Self;
}

#[cfg(feature = "no_std")]
impl<T : Copy> CopyOrClone for T {
    fn clone(&self) -> T {
        *self
    }
}

#[cfg(not(feature = "no_std"))]
impl<T : Clone> CopyOrClone for T {
    fn clone(&self) -> T {
        self.clone()
    }
}

/// Circular Buffer
///
/// Turns a slice into a Circular buffer with head and tail indexes.
#[derive(Debug)]
pub struct CBuf<'a, T: 'a> {
    buf: &'a mut [T],
    ctrl: CBufControl<T>,
}

/// Circular Buffer Control
///
/// Implements the actual logic of Circular Buffer, but requires passing &[T]
/// to `get` and `put`.
#[derive(Debug)]
pub struct CBufControl<T> {
    head : usize,
    tail : usize,
    phantom : PhantomData<T>
}

#[cfg(not(feature = "no_std"))]
impl<'a, T: CopyOrClone> CBuf<'a, T>
        where T: Clone {

    /// Create new CBuf
    ///
    /// Length (not capacity) will be used to store elements
    /// in the circular buffer.
    pub fn new(buf: &'a mut [T]) -> CBuf<T> {
        debug_assert!(buf.len() < CBUF_DATA_BIT);

        CBuf {
            buf: buf,
            ctrl: CBufControl::new(),
        }
    }

    /// Is buffer full?
    #[inline]
    pub fn is_full(&self) -> bool {
        let CBuf {
            ref ctrl,
            ..
        } = *self;

        ctrl.is_full()
    }

    /// Is buffer empty?
    #[inline]
    pub fn is_empty(&self) -> bool {
        let CBuf {
            ref ctrl,
            ..
        } = *self;

        ctrl.is_empty()
    }

    /// Peek next element from the CBuf without removing it
    ///
    /// Returns `None` if buffer is empty.
    #[inline]
    pub fn peek(&mut self) -> Option<T> {
        let CBuf {
            ref mut ctrl,
            ref buf,
        } = *self;

        ctrl.get(buf)
    }

    /// Peek next element from the CBuf without removing it
    ///
    /// Makes the buffer misbehave if it's empty.
    #[inline]
    pub fn peek_unchecked(&mut self) -> T {
        let CBuf {
            ref mut ctrl,
            ref buf,
        } = *self;

        ctrl.peek_unchecked(buf)
    }

    /// Remove one element from the CBuf
    ///
    /// Returns `None` if buffer is empty.
    #[inline]
    pub fn get(&mut self) -> Option<T> {
        let CBuf {
            ref mut ctrl,
            ref buf,
        } = *self;

        ctrl.get(buf)
    }

    /// Remove one element from the CBuf
    ///
    /// Makes the buffer misbehave if it's empty.
    #[inline]
    pub fn get_unchecked(&mut self) -> T {
        let CBuf {
            ref mut ctrl,
            ref buf,
        } = *self;

        ctrl.get_unchecked(buf)
    }

    /// Add element the buffer
    ///
    /// Ignores the write if buffer is full.
    #[inline]
    pub fn put(&mut self, val : T) {
        let CBuf {
            ref mut ctrl,
            ref mut buf,
        } = *self;

        ctrl.put(buf, val)
    }

    /// Add element the buffer
    ///
    /// Makes the buffer misbehave if it's full.
    #[inline]
    pub fn put_unchecked(&mut self, val : T) {
        let CBuf {
            ref mut ctrl,
            ref mut buf,
        } = *self;

        ctrl.put_unchecked(buf, val)
    }
}

impl<T : CopyOrClone> CBufControl<T> {

    pub fn new() -> CBufControl<T> {
        CBufControl {
            tail: 0,
            head: 0,
            phantom: PhantomData,
        }
    }

    /// See corresponding method of CBuf
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    /// See corresponding method of CBuf
    #[inline]
    pub fn is_full(&self) -> bool {
        (self.head ^ self.tail) == CBUF_DATA_BIT
    }

    /// See corresponding method of CBuf
    pub fn get(&mut self, buf : &[T]) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        Some(self.get_unchecked(buf))
    }

    /// See corresponding method of CBuf
    pub fn get_unchecked(&mut self, buf : &[T]) -> T {
        let val = buf[self.tail & !CBUF_DATA_BIT].clone();

        self.tail += 1;

        if (self.tail & !CBUF_DATA_BIT) >= buf.len() {
            self.tail = (self.tail - buf.len()) ^ CBUF_DATA_BIT;
        }

        val
    }

    /// See corresponding method of CBuf
    pub fn peek(&mut self, buf : &[T]) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        Some(self.peek_unchecked(buf))
    }

    /// See corresponding method of CBuf
    pub fn peek_unchecked(&mut self, buf : &[T]) -> T {
        buf[self.tail & !CBUF_DATA_BIT].clone()
    }

    /// See corresponding method of CBuf
    pub fn put(&mut self, buf : &mut [T], val : T) {
        if self.is_full() {
            return;
        }
        self.put_unchecked(buf, val)
    }

    /// See corresponding method of CBuf
    pub fn put_unchecked(&mut self, buf : &mut [T], val : T) {
        buf[self.head & !CBUF_DATA_BIT] = val;

        self.head += 1;

        if (self.head & !CBUF_DATA_BIT) >= buf.len() {
            self.head = (self.head - buf.len()) ^ CBUF_DATA_BIT;
        }
    }
}

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

    #[test]
    fn basic_ctl() {
        let mut buf = [0u8, 2];
        let mut cbuf = CBufControl::<u8>::new();

        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());

        cbuf.put(&mut buf, 0);
        cbuf.put(&mut buf, 0);
        assert!(!cbuf.is_empty());
        assert!(cbuf.is_full());

        cbuf.get(&buf);
        cbuf.get(&buf);
        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());
    }

    #[test]
    fn basic_cbuf() {
        let mut buf = &mut [0u8, 0u8];
        let mut cbuf = CBuf::new(buf);

        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());

        cbuf.put(0);
        cbuf.put(0);
        assert!(!cbuf.is_empty());
        assert!(cbuf.is_full());

        cbuf.get();
        cbuf.get();
        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());
    }

    #[test]
    fn patterns() {
        let mut buf = [0u8, 7];
        let mut cbuf = CBufControl::<u8>::new();

        let mut cur_len = 0;
        let mut put_val = 0;
        let mut get_val = 0;

        for pattern in 0..256 {
            if cur_len == 0 {
                assert!(cbuf.is_empty());
            }
            if cur_len == buf.len() {
                assert!(cbuf.is_full());
            }

            for bit_i in 0..8 {
                match pattern & (1 << bit_i) == 0 {
                    true => if cbuf.is_empty() {
                        assert!(cbuf.peek(&buf).is_none());
                        assert!(cbuf.get(&buf).is_none());
                    } else {
                        assert!(cbuf.peek(&buf).unwrap() == get_val);
                        let val = cbuf.get(&buf).unwrap();
                        assert!(val == get_val);
                        get_val = get_val.wrapping_add(1);
                        cur_len -= 1;
                    },
                    false => if cbuf.is_full() {
                        cbuf.put(&mut buf, put_val);
                        assert!(cbuf.is_full());
                    } else {
                        cbuf.put(&mut buf, put_val);
                        put_val = put_val.wrapping_add(1);
                        cur_len += 1;
                    },
                }
            }
        }
    }

    #[bench]
    pub fn put_and_get(b : &mut Bencher) {
        let buf = &mut [0u8; 256];
        let mut cbuf = CBuf::new(buf);

        b.iter(|| {
            cbuf.put(0u8);
            cbuf.get();
        });

        test::black_box(cbuf.get());
    }

    #[bench]
    pub fn put_unchecked_and_get(b : &mut Bencher) {
        let buf = &mut [0u8; 256];
        let mut cbuf = CBuf::new(buf);

        b.iter(|| {
            cbuf.put_unchecked(0u8);
            cbuf.get_unchecked();
        });

        test::black_box(cbuf.get());
    }
}
<commit_msg>run rustfmt, remove CopyOrClone<commit_after>// Copyright 2015 Dawid Ciężarkiewicz
// See LICENSE-MPL
//
// Non-thread-shareable, simple and efficient Circular Buffer
// implementation that can store N elements when full (typical circular
// buffer implementations store N-1) without using separate flags.
//
// Uses only `core` so can be used in `#[no_std]` projects by using
// `no_std` feature.
//
#![no_std]
#![feature(const_fn)]
#![feature(test)]

use core::option::Option::{self, Some, None};
use core::marker::PhantomData;

extern crate test as test;

const CBUF_DATA_BIT: usize = !((usize::max_value() << 1) >> 1);

/// Circular Buffer
///
/// Turns a slice into a Circular buffer with head and tail indexes.
#[derive(Debug)]
pub struct CBuf<'a, T: 'a> {
    buf: &'a mut [T],
    ctrl: CBufControl<T>,
}

/// Circular Buffer Control
///
/// Implements the actual logic of Circular Buffer, but requires passing &[T]
/// to `get` and `put`.
#[derive(Debug)]
pub struct CBufControl<T> {
    head: usize,
    tail: usize,
    phantom: PhantomData<T>,
}

#[cfg(not(feature = "no_std"))]
impl<'a, T: Clone> CBuf<'a, T>
    where T: Clone
{
    /// Create new CBuf
    ///
    /// Length (not capacity) will be used to store elements
    /// in the circular buffer.
    pub fn new(buf: &'a mut [T]) -> CBuf<T> {
        debug_assert!(buf.len() < CBUF_DATA_BIT);

        CBuf {
            buf: buf,
            ctrl: CBufControl::new(),
        }
    }

    /// Is buffer full?
    #[inline]
    pub fn is_full(&self) -> bool {
        let CBuf { ref ctrl, .. } = *self;

        ctrl.is_full()
    }

    /// Is buffer empty?
    #[inline]
    pub fn is_empty(&self) -> bool {
        let CBuf { ref ctrl, .. } = *self;

        ctrl.is_empty()
    }

    /// Peek next element from the CBuf without removing it
    ///
    /// Returns `None` if buffer is empty.
    #[inline]
    pub fn peek(&mut self) -> Option<T> {
        let CBuf { ref mut ctrl, ref buf } = *self;

        ctrl.get(buf)
    }

    /// Peek next element from the CBuf without removing it
    ///
    /// Makes the buffer misbehave if it's empty.
    #[inline]
    pub fn peek_unchecked(&mut self) -> T {
        let CBuf { ref mut ctrl, ref buf } = *self;

        ctrl.peek_unchecked(buf)
    }

    /// Remove one element from the CBuf
    ///
    /// Returns `None` if buffer is empty.
    #[inline]
    pub fn get(&mut self) -> Option<T> {
        let CBuf { ref mut ctrl, ref buf } = *self;

        ctrl.get(buf)
    }

    /// Remove one element from the CBuf
    ///
    /// Makes the buffer misbehave if it's empty.
    #[inline]
    pub fn get_unchecked(&mut self) -> T {
        let CBuf { ref mut ctrl, ref buf } = *self;

        ctrl.get_unchecked(buf)
    }

    /// Add element the buffer
    ///
    /// Ignores the write if buffer is full.
    #[inline]
    pub fn put(&mut self, val: T) {
        let CBuf { ref mut ctrl, ref mut buf } = *self;

        ctrl.put(buf, val)
    }

    /// Add element the buffer
    ///
    /// Makes the buffer misbehave if it's full.
    #[inline]
    pub fn put_unchecked(&mut self, val: T) {
        let CBuf { ref mut ctrl, ref mut buf } = *self;

        ctrl.put_unchecked(buf, val)
    }
}

impl<T: Clone> CBufControl<T> {
    pub fn new() -> CBufControl<T> {
        CBufControl {
            tail: 0,
            head: 0,
            phantom: PhantomData,
        }
    }

    /// See corresponding method of CBuf
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    /// See corresponding method of CBuf
    #[inline]
    pub fn is_full(&self) -> bool {
        (self.head ^ self.tail) == CBUF_DATA_BIT
    }

    /// See corresponding method of CBuf
    pub fn get(&mut self, buf: &[T]) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        Some(self.get_unchecked(buf))
    }

    /// See corresponding method of CBuf
    pub fn get_unchecked(&mut self, buf: &[T]) -> T {
        let val = buf[self.tail & !CBUF_DATA_BIT].clone();

        self.tail += 1;

        if (self.tail & !CBUF_DATA_BIT) >= buf.len() {
            self.tail = (self.tail - buf.len()) ^ CBUF_DATA_BIT;
        }

        val
    }

    /// See corresponding method of CBuf
    pub fn peek(&mut self, buf: &[T]) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        Some(self.peek_unchecked(buf))
    }

    /// See corresponding method of CBuf
    pub fn peek_unchecked(&mut self, buf: &[T]) -> T {
        buf[self.tail & !CBUF_DATA_BIT].clone()
    }

    /// See corresponding method of CBuf
    pub fn put(&mut self, buf: &mut [T], val: T) {
        if self.is_full() {
            return;
        }
        self.put_unchecked(buf, val)
    }

    /// See corresponding method of CBuf
    pub fn put_unchecked(&mut self, buf: &mut [T], val: T) {
        buf[self.head & !CBUF_DATA_BIT] = val;

        self.head += 1;

        if (self.head & !CBUF_DATA_BIT) >= buf.len() {
            self.head = (self.head - buf.len()) ^ CBUF_DATA_BIT;
        }
    }
}

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

    #[test]
    fn basic_ctl() {
        let mut buf = [0u8, 2];
        let mut cbuf = CBufControl::<u8>::new();

        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());

        cbuf.put(&mut buf, 0);
        cbuf.put(&mut buf, 0);
        assert!(!cbuf.is_empty());
        assert!(cbuf.is_full());

        cbuf.get(&buf);
        cbuf.get(&buf);
        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());
    }

    #[test]
    fn basic_cbuf() {
        let mut buf = &mut [0u8, 0u8];
        let mut cbuf = CBuf::new(buf);

        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());

        cbuf.put(0);
        cbuf.put(0);
        assert!(!cbuf.is_empty());
        assert!(cbuf.is_full());

        cbuf.get();
        cbuf.get();
        assert!(cbuf.is_empty());
        assert!(!cbuf.is_full());
    }

    #[test]
    fn patterns() {
        let mut buf = [0u8, 7];
        let mut cbuf = CBufControl::<u8>::new();

        let mut cur_len = 0;
        let mut put_val = 0;
        let mut get_val = 0;

        for pattern in 0..256 {
            if cur_len == 0 {
                assert!(cbuf.is_empty());
            }
            if cur_len == buf.len() {
                assert!(cbuf.is_full());
            }

            for bit_i in 0..8 {
                match pattern & (1 << bit_i) == 0 {
                    true => {
                        if cbuf.is_empty() {
                            assert!(cbuf.peek(&buf).is_none());
                            assert!(cbuf.get(&buf).is_none());
                        } else {
                            assert!(cbuf.peek(&buf).unwrap() == get_val);
                            let val = cbuf.get(&buf).unwrap();
                            assert!(val == get_val);
                            get_val = get_val.wrapping_add(1);
                            cur_len -= 1;
                        }
                    }
                    false => {
                        if cbuf.is_full() {
                            cbuf.put(&mut buf, put_val);
                            assert!(cbuf.is_full());
                        } else {
                            cbuf.put(&mut buf, put_val);
                            put_val = put_val.wrapping_add(1);
                            cur_len += 1;
                        }
                    }
                }
            }
        }
    }

    #[bench]
    pub fn put_and_get(b: &mut Bencher) {
        let buf = &mut [0u8; 256];
        let mut cbuf = CBuf::new(buf);

        b.iter(|| {
            cbuf.put(0u8);
            cbuf.get();
        });

        test::black_box(cbuf.get());
    }

    #[bench]
    pub fn put_unchecked_and_get(b: &mut Bencher) {
        let buf = &mut [0u8; 256];
        let mut cbuf = CBuf::new(buf);

        b.iter(|| {
            cbuf.put_unchecked(0u8);
            cbuf.get_unchecked();
        });

        test::black_box(cbuf.get());
    }
}
<|endoftext|>


<commit_before>//! Linkify finds links such as URLs and email addresses in plain text.
//! It's smart about where a link ends, such as with trailing punctuation.
//!
//! Your reaction might be: "Do I need a library for this? Why not a regex?".
//! Let's look at a few cases:
//!
//! * In `http://example.com/.` the link should not include the trailing dot
//! * `http://example.com/,` should not include the trailing comma
//! * `(http://example.com/)` should not include the parens
//!
//! Seems simple enough. But then we also have these cases:
//!
//! * `https://en.wikipedia.org/wiki/Link_(The_Legend_of_Zelda)` should include the trailing paren
//! * `http://üñîçøðé.com/ä` should also work for Unicode (including Emoji and Punycode)
//! * `<http://example.com/>` should not include angle brackets
//!
//! This library behaves as you'd expect in the above cases and many more.
//! It uses a simple scan with linear runtime.
//!
//! In addition to URLs, it can also find emails.
//!
//! ### Usage
//!
//! Basic usage:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//!
//! assert_eq!("http://example.com", link.as_str());
//! assert_eq!(14, link.start());
//! assert_eq!(32, link.end());
//! assert_eq!(&LinkKind::Url, link.kind());
//! ```
//!
//! Option to allow URLs without schemes:
//!
//! ```
//! use linkify::LinkFinder;
//!
//! let input = "Look, no scheme: example.org/foo";
//! let mut finder = LinkFinder::new();
//!
//! // true by default
//! finder.url_must_have_scheme(false);
//!
//! let links: Vec<_> = finder.links(input).collect();
//! assert_eq!(links[0].as_str(), "example.org/foo");
//! ```
//!
//! Restrict the kinds of links:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "http://example.com and foo@example.com";
//! let mut finder = LinkFinder::new();
//! finder.kinds(&[LinkKind::Email]);
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//! assert_eq!("foo@example.com", link.as_str());
//! assert_eq!(&LinkKind::Email, link.kind());
//! ```
//!
//! Split the text into consecutive spans (mixed links and plain text).
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let spans: Vec<_> = finder.spans(input).collect();
//!
//! assert_eq!(3, spans.len());
//!
//! assert_eq!("Have you seen ", spans[0].as_str());
//! assert_eq!(0, spans[0].start());
//! assert_eq!(14, spans[0].end());
//! assert_eq!(None, spans[0].kind());
//!
//! assert_eq!("http://example.com", spans[1].as_str());
//! assert_eq!(14, spans[1].start());
//! assert_eq!(32, spans[1].end());
//! assert_eq!(Some(&LinkKind::Url), spans[1].kind());
//!
//! assert_eq!("?", spans[2].as_str());
//! assert_eq!(32, spans[2].start());
//! assert_eq!(33, spans[2].end());
//! assert_eq!(None, spans[2].kind());
//! ```
//!
//! ### Conformance
//!
//! This crates makes an effort to respect the various standards, namely:
//!
//! * [RFC 3986] and [RFC 3987] for URLs
//! * [RFC 5321] and [RFC 6531] for emails (except IP addresses and quoting)
//!
//! At the same time, it does not guarantee that the returned links are valid.
//! If in doubt, it rather returns a link than skipping it.
//!
//! If you need to validate URLs, e.g. for checking TLDs, use another library on
//! the returned links.
//!
//! [RFC 3986]: https://datatracker.ietf.org/doc/html/rfc3986
//! [RFC 3987]: https://datatracker.ietf.org/doc/html/rfc3987
//! [RFC 5321]: https://datatracker.ietf.org/doc/html/rfc5321
//! [RFC 6531]: https://datatracker.ietf.org/doc/html/rfc6531

#![doc(html_root_url = "https://docs.rs/linkify/0.8.1")]
// #![deny(warnings)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

mod domains;
mod email;
mod finder;
mod scanner;
mod url;

pub use crate::finder::Link;
pub use crate::finder::LinkFinder;
pub use crate::finder::LinkKind;
pub use crate::finder::Links;
pub use crate::finder::{Span, Spans};

#[cfg(doctest)]
doc_comment::doctest!("../README.md");
<commit_msg>Re-enable deny warnings<commit_after>//! Linkify finds links such as URLs and email addresses in plain text.
//! It's smart about where a link ends, such as with trailing punctuation.
//!
//! Your reaction might be: "Do I need a library for this? Why not a regex?".
//! Let's look at a few cases:
//!
//! * In `http://example.com/.` the link should not include the trailing dot
//! * `http://example.com/,` should not include the trailing comma
//! * `(http://example.com/)` should not include the parens
//!
//! Seems simple enough. But then we also have these cases:
//!
//! * `https://en.wikipedia.org/wiki/Link_(The_Legend_of_Zelda)` should include the trailing paren
//! * `http://üñîçøðé.com/ä` should also work for Unicode (including Emoji and Punycode)
//! * `<http://example.com/>` should not include angle brackets
//!
//! This library behaves as you'd expect in the above cases and many more.
//! It uses a simple scan with linear runtime.
//!
//! In addition to URLs, it can also find emails.
//!
//! ### Usage
//!
//! Basic usage:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//!
//! assert_eq!("http://example.com", link.as_str());
//! assert_eq!(14, link.start());
//! assert_eq!(32, link.end());
//! assert_eq!(&LinkKind::Url, link.kind());
//! ```
//!
//! Option to allow URLs without schemes:
//!
//! ```
//! use linkify::LinkFinder;
//!
//! let input = "Look, no scheme: example.org/foo";
//! let mut finder = LinkFinder::new();
//!
//! // true by default
//! finder.url_must_have_scheme(false);
//!
//! let links: Vec<_> = finder.links(input).collect();
//! assert_eq!(links[0].as_str(), "example.org/foo");
//! ```
//!
//! Restrict the kinds of links:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "http://example.com and foo@example.com";
//! let mut finder = LinkFinder::new();
//! finder.kinds(&[LinkKind::Email]);
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//! assert_eq!("foo@example.com", link.as_str());
//! assert_eq!(&LinkKind::Email, link.kind());
//! ```
//!
//! Split the text into consecutive spans (mixed links and plain text).
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let spans: Vec<_> = finder.spans(input).collect();
//!
//! assert_eq!(3, spans.len());
//!
//! assert_eq!("Have you seen ", spans[0].as_str());
//! assert_eq!(0, spans[0].start());
//! assert_eq!(14, spans[0].end());
//! assert_eq!(None, spans[0].kind());
//!
//! assert_eq!("http://example.com", spans[1].as_str());
//! assert_eq!(14, spans[1].start());
//! assert_eq!(32, spans[1].end());
//! assert_eq!(Some(&LinkKind::Url), spans[1].kind());
//!
//! assert_eq!("?", spans[2].as_str());
//! assert_eq!(32, spans[2].start());
//! assert_eq!(33, spans[2].end());
//! assert_eq!(None, spans[2].kind());
//! ```
//!
//! ### Conformance
//!
//! This crates makes an effort to respect the various standards, namely:
//!
//! * [RFC 3986] and [RFC 3987] for URLs
//! * [RFC 5321] and [RFC 6531] for emails (except IP addresses and quoting)
//!
//! At the same time, it does not guarantee that the returned links are valid.
//! If in doubt, it rather returns a link than skipping it.
//!
//! If you need to validate URLs, e.g. for checking TLDs, use another library on
//! the returned links.
//!
//! [RFC 3986]: https://datatracker.ietf.org/doc/html/rfc3986
//! [RFC 3987]: https://datatracker.ietf.org/doc/html/rfc3987
//! [RFC 5321]: https://datatracker.ietf.org/doc/html/rfc5321
//! [RFC 6531]: https://datatracker.ietf.org/doc/html/rfc6531

#![doc(html_root_url = "https://docs.rs/linkify/0.8.1")]
#![deny(warnings)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

mod domains;
mod email;
mod finder;
mod scanner;
mod url;

pub use crate::finder::Link;
pub use crate::finder::LinkFinder;
pub use crate::finder::LinkKind;
pub use crate::finder::Links;
pub use crate::finder::{Span, Spans};

#[cfg(doctest)]
doc_comment::doctest!("../README.md");
<|endoftext|>


<commit_before>//! nanosleep for rust
//!
//!
//! # Goals
//! * provide nanosleep for linux and macos
//!
//! # Future work
//! * other OS support?
//!
//! # Usage
//!
//! Include the module and call ```shuteye::sleep(Duration::new(seconds, nanoseconds))```
//!
//! # Example
//!
//! Sleep for 1 uS
//!
//! ```
//! use shuteye::sleep;
//! use std::time::Duration;
//!
//! // call sleep
//! sleep(Duration::new(0, 1000));

#![deny(warnings)]

extern crate libc;

use std::ptr;
use std::time::Duration;

/// sleep for a relative time
///
/// # Example
/// ```rust
/// use std::time::Duration;
/// use shuteye::sleep;
///
/// // simple sleep for 1s duration
/// sleep(Duration::new(1, 0));
///
/// // remain captures remaining time
/// match sleep(Duration::new(1, 0)) {
///     Some(remain) => {
///         // woke early - some sleep time remains
///     }
///     None => {
///         // woke on-time or late - no sleep time remains
///     }
/// }
/// ```
pub fn sleep(duration: Duration) -> Option<Duration> {
    let ts = duration_to_timespec(duration);
    let mut remain = libc::timespec {
        tv_sec: 0,
        tv_nsec: 0,
    };

    #[cfg(target_os = "linux")]
    clock_nanosleep(libc::CLOCK_MONOTONIC, 0, &ts, Some(&mut remain));

    #[cfg(target_os = "macos")]
    nanosleep(&ts, Some(&mut remain));

    if remain.tv_nsec == 0 && remain.tv_sec == 0 {
        return None;
    }
    Some(timespec_to_duration(remain))
}

fn duration_to_timespec(duration: Duration) -> libc::timespec {
    libc::timespec {
        tv_sec: duration.as_secs() as i64,
        tv_nsec: duration.subsec_nanos() as i64,
    }
}

fn timespec_to_duration(timespec: libc::timespec) -> Duration {
    Duration::new(timespec.tv_sec as u64, timespec.tv_nsec as u32)
}

#[cfg(target_os = "linux")]
fn clock_nanosleep(clk_id: libc::clockid_t,
                   flags: libc::c_int,
                   req: &libc::timespec,
                   remain: Option<&mut libc::timespec>)
                   -> i32 {
    match remain {
        Some(p) => unsafe { libc::clock_nanosleep(clk_id, flags, req as *const _, p as *mut _) },
        _ => unsafe { libc::clock_nanosleep(clk_id, flags, req as *const _, ptr::null_mut()) },
    }
}

#[cfg(target_os = "macos")]
fn nanosleep(req: &libc::timespec, remain: Option<&mut libc::timespec>) -> i32 {
    match remain {
        Some(p) => unsafe { libc::nanosleep(req as *const _, p as *mut _) },
        _ => unsafe { libc::nanosleep(req as *const _, ptr::null_mut()) },
    }
}
<commit_msg>bugfix: use libc types, fixes 32bit build (#13)<commit_after>//! nanosleep for rust
//!
//!
//! # Goals
//! * provide nanosleep for linux and macos
//!
//! # Future work
//! * other OS support?
//!
//! # Usage
//!
//! Include the module and call ```shuteye::sleep(Duration::new(seconds, nanoseconds))```
//!
//! # Example
//!
//! Sleep for 1 uS
//!
//! ```
//! use shuteye::sleep;
//! use std::time::Duration;
//!
//! // call sleep
//! sleep(Duration::new(0, 1000));

#![deny(warnings)]

extern crate libc;

use std::ptr;
use std::time::Duration;

/// sleep for a relative time
///
/// # Example
/// ```rust
/// use std::time::Duration;
/// use shuteye::sleep;
///
/// // simple sleep for 1s duration
/// sleep(Duration::new(1, 0));
///
/// // remain captures remaining time
/// match sleep(Duration::new(1, 0)) {
///     Some(remain) => {
///         // woke early - some sleep time remains
///     }
///     None => {
///         // woke on-time or late - no sleep time remains
///     }
/// }
/// ```
pub fn sleep(duration: Duration) -> Option<Duration> {
    let ts = duration_to_timespec(duration);
    let mut remain = libc::timespec {
        tv_sec: 0,
        tv_nsec: 0,
    };

    #[cfg(target_os = "linux")]
    clock_nanosleep(libc::CLOCK_MONOTONIC, 0, &ts, Some(&mut remain));

    #[cfg(target_os = "macos")]
    nanosleep(&ts, Some(&mut remain));

    if remain.tv_nsec == 0 && remain.tv_sec == 0 {
        return None;
    }
    Some(timespec_to_duration(remain))
}

fn duration_to_timespec(duration: Duration) -> libc::timespec {
    libc::timespec {
        tv_sec: duration.as_secs() as libc::time_t,
        tv_nsec: duration.subsec_nanos() as libc::c_long,
    }
}

fn timespec_to_duration(timespec: libc::timespec) -> Duration {
    Duration::new(timespec.tv_sec as u64, timespec.tv_nsec as u32)
}

#[cfg(target_os = "linux")]
fn clock_nanosleep(clk_id: libc::clockid_t,
                   flags: libc::c_int,
                   req: &libc::timespec,
                   remain: Option<&mut libc::timespec>)
                   -> i32 {
    match remain {
        Some(p) => unsafe { libc::clock_nanosleep(clk_id, flags, req as *const _, p as *mut _) },
        _ => unsafe { libc::clock_nanosleep(clk_id, flags, req as *const _, ptr::null_mut()) },
    }
}

#[cfg(target_os = "macos")]
fn nanosleep(req: &libc::timespec, remain: Option<&mut libc::timespec>) -> i32 {
    match remain {
        Some(p) => unsafe { libc::nanosleep(req as *const _, p as *mut _) },
        _ => unsafe { libc::nanosleep(req as *const _, ptr::null_mut()) },
    }
}
<|endoftext|>


<commit_before>type Stack<T> = Vec<T>;

pub struct Interpreter<T> {
    data_stack: Stack<T>,
}

impl<T> Interpreter<T> {

    fn new() -> Interpreter<T> {
        Interpreter {
            data_stack: Stack::new(),
        }
    }

    fn push(&mut self, value: T) {
        self.data_stack.push(value)
    }

    fn pop(&mut self) -> Option<T> {
        self.data_stack.pop()
    }
}

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

    #[test]
    fn pops_nothing() {
        let mut interpreter = Interpreter::<i32>::new();
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_as_pushed() {
        let mut interpreter = Interpreter::<i32>::new();
        interpreter.push(42);
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_in_reverse_order() {
        let mut interpreter = Interpreter::<i32>::new();
        interpreter.push(42);
        interpreter.push(51);
        assert_eq!(Some(51), interpreter.pop());
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }
}
<commit_msg>Default initialization for Interpreter<commit_after>type Stack<T> = Vec<T>;

#[derive(Default)]
pub struct Interpreter<T> {
    data_stack: Stack<T>,
}

impl<T> Interpreter<T> {

    fn push(&mut self, value: T) {
        self.data_stack.push(value)
    }

    fn pop(&mut self) -> Option<T> {
        self.data_stack.pop()
    }
}

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

    #[test]
    fn pops_nothing() {
        let mut interpreter = Interpreter::<i32>::default();
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_as_pushed() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_in_reverse_order() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        interpreter.push(51);
        assert_eq!(Some(51), interpreter.pop());
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }
}
<|endoftext|>