<commit_before>use std::collections::TreeMap;

///////////////////////////////////////////////////////////////////////////////

pub trait Serialize<S, R> {
    fn serialize(&self, state: &mut S) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Serializer<S, R> {
    fn serialize<T: Serialize<S, R>>(&mut self, value: &T) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Visitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait VisitorState<R> {
    fn visit_null(&mut self) -> R;

    fn visit_bool(&mut self, v: bool) -> R;

    #[inline]
    fn visit_int(&mut self, v: int) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i8(&mut self, v: i8) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i16(&mut self, v: i16) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i32(&mut self, v: i32) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i64(&mut self, v: i64) -> R;

    #[inline]
    fn visit_uint(&mut self, v: uint) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u8(&mut self, v: u8) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u16(&mut self, v: u16) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u32(&mut self, v: u32) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u64(&mut self, v: u64) -> R;

    #[inline]
    fn visit_f32(&mut self, v: f32) -> R {
        self.visit_f64(v as f64)
    }

    fn visit_f64(&mut self, v: f64) -> R;

    fn visit_char(&mut self, value: char) -> R;

    fn visit_str(&mut self, value: &str) -> R;

    fn visit_seq<
        V: Visitor<Self, R>
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_seq<
        V: Visitor<Self, R>
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    #[inline]
    fn visit_enum<
        V: Visitor<Self, R>
    >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    fn visit_seq_elt<
        T: Serialize<Self, R>
    >(&mut self, first: bool, value: T) -> R;

    fn visit_map<
        V: Visitor<Self, R>
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_map<
        V: Visitor<Self, R>
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_map(visitor)
    }

    fn visit_map_elt<
        K: Serialize<Self, R>,
        V: Serialize<Self, R>
    >(&mut self, first: bool, key: K, value: V) -> R;
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! impl_serialize {
    ($ty:ty, $method:ident) => {
        impl<S: VisitorState<R>, R> Serialize<S, R> for $ty {
            #[inline]
            fn serialize(&self, state: &mut S) -> R {
                state.$method(*self)
            }
        }
    }
}

impl_serialize!(bool, visit_bool)
impl_serialize!(int, visit_int)
impl_serialize!(i8, visit_i8)
impl_serialize!(i16, visit_i16)
impl_serialize!(i32, visit_i32)
impl_serialize!(i64, visit_i64)
impl_serialize!(uint, visit_uint)
impl_serialize!(u8, visit_u8)
impl_serialize!(u16, visit_u16)
impl_serialize!(u32, visit_u32)
impl_serialize!(u64, visit_u64)
impl_serialize!(f32, visit_f32)
impl_serialize!(f64, visit_f64)
impl_serialize!(char, visit_char)

///////////////////////////////////////////////////////////////////////////////

impl<'a, S: VisitorState<R>, R> Serialize<S, R> for &'a str {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(*self)
    }
}

impl<S: VisitorState<R>, R> Serialize<S, R> for String {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(self.as_slice())
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct SeqIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<T, Iter: Iterator<T>> SeqIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
        SeqIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    T: Serialize<S, R>,
    Iter: Iterator<T>,
    S: VisitorState<R>,
    R
> Visitor<S, R> for SeqIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some(value) => Some(state.visit_seq_elt(first, value)),
            None => None
        }
    }

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

///////////////////////////////////////////////////////////////////////////////

impl<
    S: VisitorState<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for Vec<T> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(SeqIteratorVisitor::new(self.iter()))
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct MapIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<K, V, Iter: Iterator<(K, V)>> MapIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
        MapIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    K: Serialize<S, R>,
    V: Serialize<S, R>,
    Iter: Iterator<(K, V)>,
    S: VisitorState<R>,
    R
> Visitor<S, R> for MapIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some((key, value)) => Some(state.visit_map_elt(first, key, value)),
            None => None
        }
    }

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

///////////////////////////////////////////////////////////////////////////////

impl<
    S: VisitorState<R>,
    R,
    K: Serialize<S, R> + Ord,
    V: Serialize<S, R>
> Serialize<S, R> for TreeMap<K, V> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_map(MapIteratorVisitor::new(self.iter()))
    }
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Serialize<S, R> for (T0, T1) {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(Tuple2Serialize { value: self, state: 0 })
    }
}

struct Tuple2Serialize<'a, T0: 'a, T1: 'a> {
    value: &'a (T0, T1),
    state: uint,
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Visitor<S, R> for Tuple2Serialize<'a, T0, T1> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        match self.state {
            0 => {
                self.state += 1;
                let (ref value, _) = *self.value;
                Some(state.visit_seq_elt(true, value))
            }
            1 => {
                self.state += 1;
                let (_, ref value) = *self.value;
                Some(state.visit_seq_elt(false, value))
            }
            _ => {
                None
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        let size = 2 - self.state;
        (size, Some(size))
    }
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for &'a T {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        (**self).serialize(state)
    }
}

///////////////////////////////////////////////////////////////////////////////

#[deriving(Show)]
pub enum Token<'a> {
    Null,
    Bool(bool),
    Int(int),
    I64(i64),
    U64(u64),
    F64(f64),
    Char(char),
    Str(&'a str),
    String(String),
    SeqStart(uint),
    MapStart(uint),
    StructStart(&'static str, uint),
    End,
}

pub trait TokenState<'a, R>: VisitorState<R> {
    fn serialize(&mut self, token: Token<'a>) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub struct GatherTokens<'a> {
    tokens: Vec<Token<'a>>,
}

impl<'a> GatherTokens<'a> {
    pub fn new() -> GatherTokens<'a> {
        GatherTokens {
            tokens: Vec::new(),
        }
    }

    pub fn unwrap(self) -> Vec<Token<'a>> {
        self.tokens
    }
}

impl<'a> TokenState<'a, ()> for GatherTokens<'a> {
    fn serialize(&mut self, token: Token<'a>) -> () {
        self.tokens.push(token);
    }
}

impl<'a> VisitorState<()> for GatherTokens<'a> {
    fn visit_null(&mut self) -> () {
        self.serialize(Null)
    }

    fn visit_bool(&mut self, value: bool) -> () {
        self.serialize(Bool(value))
    }

    fn visit_i64(&mut self, value: i64) -> () {
        self.serialize(I64(value))
    }

    fn visit_u64(&mut self, value: u64) -> () {
        self.serialize(U64(value))
    }

    fn visit_f64(&mut self, value: f64) -> () {
        self.serialize(F64(value))
    }

    fn visit_char(&mut self, value: char) -> () {
        self.serialize(Char(value))
    }

    fn visit_str(&mut self, value: &str) -> () {
        self.serialize(String(value.to_string()))
    }

    fn visit_seq<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.tokens.push(SeqStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.tokens.push(End)
    }

    fn visit_seq_elt<
        T: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, value: T) -> () {
        value.serialize(self)
    }

    fn visit_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(MapStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_named_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, name: &'static str, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(StructStart(name, len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_map_elt<
        K: Serialize<GatherTokens<'a>, ()>,
        V: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, key: K, value: V) -> () {
        key.serialize(self);
        value.serialize(self)
    }
}
<commit_msg>whitespace cleanup<commit_after>use std::collections::TreeMap;

///////////////////////////////////////////////////////////////////////////////

pub trait Serialize<S, R> {
    fn serialize(&self, state: &mut S) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Serializer<S, R> {
    fn serialize<T: Serialize<S, R>>(&mut self, value: &T) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub trait Visitor<S, R> {
    fn visit(&mut self, state: &mut S) -> Option<R>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait VisitorState<R> {
    fn visit_null(&mut self) -> R;

    fn visit_bool(&mut self, v: bool) -> R;

    #[inline]
    fn visit_int(&mut self, v: int) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i8(&mut self, v: i8) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i16(&mut self, v: i16) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i32(&mut self, v: i32) -> R {
        self.visit_i64(v as i64)
    }

    #[inline]
    fn visit_i64(&mut self, v: i64) -> R;

    #[inline]
    fn visit_uint(&mut self, v: uint) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u8(&mut self, v: u8) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u16(&mut self, v: u16) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u32(&mut self, v: u32) -> R {
        self.visit_u64(v as u64)
    }

    #[inline]
    fn visit_u64(&mut self, v: u64) -> R;

    #[inline]
    fn visit_f32(&mut self, v: f32) -> R {
        self.visit_f64(v as f64)
    }

    fn visit_f64(&mut self, v: f64) -> R;

    fn visit_char(&mut self, value: char) -> R;

    fn visit_str(&mut self, value: &str) -> R;

    fn visit_seq<
        V: Visitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_seq<
        V: Visitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    #[inline]
    fn visit_enum<
        V: Visitor<Self, R>,
    >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> R {
        self.visit_seq(visitor)
    }

    fn visit_seq_elt<
        T: Serialize<Self, R>,
    >(&mut self, first: bool, value: T) -> R;

    fn visit_map<
        V: Visitor<Self, R>,
    >(&mut self, visitor: V) -> R;

    #[inline]
    fn visit_named_map<
        V: Visitor<Self, R>,
    >(&mut self, _name: &'static str, visitor: V) -> R {
        self.visit_map(visitor)
    }

    fn visit_map_elt<
        K: Serialize<Self, R>,
        V: Serialize<Self, R>,
    >(&mut self, first: bool, key: K, value: V) -> R;
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! impl_serialize {
    ($ty:ty, $method:ident) => {
        impl<S: VisitorState<R>, R> Serialize<S, R> for $ty {
            #[inline]
            fn serialize(&self, state: &mut S) -> R {
                state.$method(*self)
            }
        }
    }
}

impl_serialize!(bool, visit_bool)
impl_serialize!(int, visit_int)
impl_serialize!(i8, visit_i8)
impl_serialize!(i16, visit_i16)
impl_serialize!(i32, visit_i32)
impl_serialize!(i64, visit_i64)
impl_serialize!(uint, visit_uint)
impl_serialize!(u8, visit_u8)
impl_serialize!(u16, visit_u16)
impl_serialize!(u32, visit_u32)
impl_serialize!(u64, visit_u64)
impl_serialize!(f32, visit_f32)
impl_serialize!(f64, visit_f64)
impl_serialize!(char, visit_char)

///////////////////////////////////////////////////////////////////////////////

impl<'a, S: VisitorState<R>, R> Serialize<S, R> for &'a str {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(*self)
    }
}

impl<S: VisitorState<R>, R> Serialize<S, R> for String {
    #[inline]
    fn serialize(&self, s: &mut S) -> R {
        s.visit_str(self.as_slice())
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct SeqIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<T, Iter: Iterator<T>> SeqIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
        SeqIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    T: Serialize<S, R>,
    Iter: Iterator<T>,
    S: VisitorState<R>,
    R
> Visitor<S, R> for SeqIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some(value) => Some(state.visit_seq_elt(first, value)),
            None => None
        }
    }

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

///////////////////////////////////////////////////////////////////////////////

impl<
    S: VisitorState<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for Vec<T> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(SeqIteratorVisitor::new(self.iter()))
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct MapIteratorVisitor<Iter> {
    iter: Iter,
    first: bool,
}

impl<K, V, Iter: Iterator<(K, V)>> MapIteratorVisitor<Iter> {
    #[inline]
    pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
        MapIteratorVisitor {
            iter: iter,
            first: true,
        }
    }
}

impl<
    K: Serialize<S, R>,
    V: Serialize<S, R>,
    Iter: Iterator<(K, V)>,
    S: VisitorState<R>,
    R
> Visitor<S, R> for MapIteratorVisitor<Iter> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        let first = self.first;
        self.first = false;

        match self.iter.next() {
            Some((key, value)) => Some(state.visit_map_elt(first, key, value)),
            None => None
        }
    }

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

///////////////////////////////////////////////////////////////////////////////

impl<
    S: VisitorState<R>,
    R,
    K: Serialize<S, R> + Ord,
    V: Serialize<S, R>
> Serialize<S, R> for TreeMap<K, V> {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_map(MapIteratorVisitor::new(self.iter()))
    }
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Serialize<S, R> for (T0, T1) {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        state.visit_seq(Tuple2Serialize { value: self, state: 0 })
    }
}

struct Tuple2Serialize<'a, T0: 'a, T1: 'a> {
    value: &'a (T0, T1),
    state: uint,
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T0: Serialize<S, R>,
    T1: Serialize<S, R>
> Visitor<S, R> for Tuple2Serialize<'a, T0, T1> {
    #[inline]
    fn visit(&mut self, state: &mut S) -> Option<R> {
        match self.state {
            0 => {
                self.state += 1;
                let (ref value, _) = *self.value;
                Some(state.visit_seq_elt(true, value))
            }
            1 => {
                self.state += 1;
                let (_, ref value) = *self.value;
                Some(state.visit_seq_elt(false, value))
            }
            _ => {
                None
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        let size = 2 - self.state;
        (size, Some(size))
    }
}

impl<
    'a,
    S: VisitorState<R>,
    R,
    T: Serialize<S, R>
> Serialize<S, R> for &'a T {
    #[inline]
    fn serialize(&self, state: &mut S) -> R {
        (**self).serialize(state)
    }
}

///////////////////////////////////////////////////////////////////////////////

#[deriving(Show)]
pub enum Token<'a> {
    Null,
    Bool(bool),
    Int(int),
    I64(i64),
    U64(u64),
    F64(f64),
    Char(char),
    Str(&'a str),
    String(String),
    SeqStart(uint),
    MapStart(uint),
    StructStart(&'static str, uint),
    End,
}

pub trait TokenState<'a, R>: VisitorState<R> {
    fn serialize(&mut self, token: Token<'a>) -> R;
}

///////////////////////////////////////////////////////////////////////////////

pub struct GatherTokens<'a> {
    tokens: Vec<Token<'a>>,
}

impl<'a> GatherTokens<'a> {
    pub fn new() -> GatherTokens<'a> {
        GatherTokens {
            tokens: Vec::new(),
        }
    }

    pub fn unwrap(self) -> Vec<Token<'a>> {
        self.tokens
    }
}

impl<'a> TokenState<'a, ()> for GatherTokens<'a> {
    fn serialize(&mut self, token: Token<'a>) -> () {
        self.tokens.push(token);
    }
}

impl<'a> VisitorState<()> for GatherTokens<'a> {
    fn visit_null(&mut self) -> () {
        self.serialize(Null)
    }

    fn visit_bool(&mut self, value: bool) -> () {
        self.serialize(Bool(value))
    }

    fn visit_i64(&mut self, value: i64) -> () {
        self.serialize(I64(value))
    }

    fn visit_u64(&mut self, value: u64) -> () {
        self.serialize(U64(value))
    }

    fn visit_f64(&mut self, value: f64) -> () {
        self.serialize(F64(value))
    }

    fn visit_char(&mut self, value: char) -> () {
        self.serialize(Char(value))
    }

    fn visit_str(&mut self, value: &str) -> () {
        self.serialize(String(value.to_string()))
    }

    fn visit_seq<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.tokens.push(SeqStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.tokens.push(End)
    }

    fn visit_seq_elt<
        T: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, value: T) -> () {
        value.serialize(self)
    }

    fn visit_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(MapStart(len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_named_map<
        V: Visitor<GatherTokens<'a>, ()>
    >(&mut self, name: &'static str, mut visitor: V) -> () {
        let (len, _) = visitor.size_hint();
        self.serialize(StructStart(name, len));
        loop {
            match visitor.visit(self) {
                Some(()) => { }
                None => { break; }
            }
        }
        self.serialize(End)
    }

    fn visit_map_elt<
        K: Serialize<GatherTokens<'a>, ()>,
        V: Serialize<GatherTokens<'a>, ()>
    >(&mut self, _first: bool, key: K, value: V) -> () {
        key.serialize(self);
        value.serialize(self)
    }
}
<|endoftext|>


<commit_before>extern crate gcc;
extern crate bindgen;

use std::env;
use std::path::PathBuf;
use std::fs::File;
use std::time::{SystemTime, Duration};
use std::cmp;

pub fn main() {
/*
    #[cfg(not(target_os = "windows"))]
    {
        println!("cargo:rustc-link-search=native=../c/windows");
        println!("cargo:rustc-link-lib=static=sodium-release");
    }
*/
    gcc::Config::new()
        .file("../c/netcode.c")
        .include("../c")
        .include("../c/windows")
        .define("NETCODE_ENABLE_TESTS", Some("0"))
        .define("NDEBUG", Some("0"))
        .compile("libnetcode.a");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    let pub_path = out_path.join("pub_bindings.rs");
    let private_path = out_path.join("private_bindings.rs");

    //Do some basic dependecy management
    let targets = vec!(&pub_path, &private_path);
    let source = vec!("build.rs", "../c/netcode.c", "../c/netcode.h").iter()
        .map(|v| PathBuf::from(v))
        .collect::<Vec<_>>();

    let newest_source = source.iter()
        .map(|v| {
            File::open(v)
                .and_then(|f| f.metadata())
                .and_then(|m| m.modified())
                .expect(format!("Source file {:?} not found", v).as_str())
        })
        .max()
        .unwrap();

    let oldest_target = targets.iter()
        .filter_map(|v| {
            File::open(v)
                .and_then(|f| f.metadata())
                .and_then(|m| m.modified())
                .ok()
        })
        .min()
        .unwrap_or(newest_source - Duration::from_secs(1));

    if newest_source > oldest_target {
        //Export symbols for netcode
        let pub_bindings = bindgen::Builder::default()
            .no_unstable_rust()
            .header("../c/netcode.h")
            .generate()
            .expect("Unable to generate bindings");

        pub_bindings.write_to_file(&pub_path)
            .expect("Couldn't write bindings!");

        let include = env::var("INCLUDE").unwrap_or("".to_string());
        let sodium_include = env::var("SODIUM_LIB_DIR")
                                 .unwrap_or("../c/windows/sodium".to_string());

        let private_bindings = bindgen::Builder::default()
            .no_unstable_rust()
            .header("../c/netcode.c")
            .clang_arg("-I../c")
            .clang_arg(format!("-I{}", include))
            .clang_arg(format!("-I{}", sodium_include))
            .whitelisted_function("netcode_write_packet")
            .whitelisted_function("netcode_read_packet")
            .whitelisted_function("netcode_read_connect_token")
            .whitelisted_function("netcode_decrypt_challenge_token")
            .whitelisted_function("netcode_read_challenge_token")
            .whitelisted_function("netcode_replay_protection_reset")
            .whitelisted_function("free")
            .whitelisted_var("NETCODE_CONNECTION_NUM_PACKETS")
            .generate()
            .expect("Unable to generate bindings");

        private_bindings.write_to_file(&private_path)
            .expect("Couldn't write bindings!");
    }
}
<commit_msg>Fixing windows build.<commit_after>extern crate gcc;
extern crate bindgen;

use std::env;
use std::path::PathBuf;
use std::fs::File;
use std::time::{SystemTime, Duration};
use std::cmp;

pub fn main() {

    #[cfg(target_os = "windows")]
    {
        println!("cargo:rustc-link-search=native=../c/windows");
        println!("cargo:rustc-link-lib=static=sodium-release");
    }

    gcc::Config::new()
        .file("../c/netcode.c")
        .include("../c")
        .include("../c/windows")
        .define("NETCODE_ENABLE_TESTS", Some("0"))
        .define("NDEBUG", Some("0"))
        .compile("libnetcode.a");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    let pub_path = out_path.join("pub_bindings.rs");
    let private_path = out_path.join("private_bindings.rs");

    //Do some basic dependecy management
    let targets = vec!(&pub_path, &private_path);
    let source = vec!("build.rs", "../c/netcode.c", "../c/netcode.h").iter()
        .map(|v| PathBuf::from(v))
        .collect::<Vec<_>>();

    let newest_source = source.iter()
        .map(|v| {
            File::open(v)
                .and_then(|f| f.metadata())
                .and_then(|m| m.modified())
                .expect(format!("Source file {:?} not found", v).as_str())
        })
        .max()
        .unwrap();

    let oldest_target = targets.iter()
        .filter_map(|v| {
            File::open(v)
                .and_then(|f| f.metadata())
                .and_then(|m| m.modified())
                .ok()
        })
        .min()
        .unwrap_or(newest_source - Duration::from_secs(1));

    if newest_source > oldest_target {
        //Export symbols for netcode
        let pub_bindings = bindgen::Builder::default()
            .no_unstable_rust()
            .header("../c/netcode.h")
            .generate()
            .expect("Unable to generate bindings");

        pub_bindings.write_to_file(&pub_path)
            .expect("Couldn't write bindings!");

        let include = env::var("INCLUDE").unwrap_or("".to_string());
        let sodium_include = env::var("SODIUM_LIB_DIR")
                                 .unwrap_or("../c/windows/sodium".to_string());

        let private_bindings = bindgen::Builder::default()
            .no_unstable_rust()
            .header("../c/netcode.c")
            .clang_arg("-I../c")
            .clang_arg(format!("-I{}", include))
            .clang_arg(format!("-I{}", sodium_include))
            .whitelisted_function("netcode_write_packet")
            .whitelisted_function("netcode_read_packet")
            .whitelisted_function("netcode_read_connect_token")
            .whitelisted_function("netcode_decrypt_challenge_token")
            .whitelisted_function("netcode_read_challenge_token")
            .whitelisted_function("netcode_replay_protection_reset")
            .whitelisted_function("free")
            .whitelisted_var("NETCODE_CONNECTION_NUM_PACKETS")
            .generate()
            .expect("Unable to generate bindings");

        private_bindings.write_to_file(&private_path)
            .expect("Couldn't write bindings!");
    }
}
<|endoftext|>


<commit_before>use std::{collections::VecDeque, rc::Rc};

use crate::{
    api::prelude::*, proc_macros::*, shell::prelude::WindowRequest, themes::theme_orbtk::*,
};

// --- KEYS --
pub static STYLE_WINDOW: &str = "window";
// --- KEYS --

// internal type to handle dirty widgets.
type DirtyWidgets = Vec<Entity>;

#[derive(Clone)]
enum Action {
    WindowEvent(WindowEvent),
    FocusEvent(FocusEvent),
}

// The `WindowState` handles the window events.
#[derive(Default, AsAny)]
struct WindowState {
    actions: VecDeque<Action>,
    background: Brush,
    title: String,
}

impl WindowState {
    fn push_action(&mut self, action: Action) {
        self.actions.push_front(action);
    }

    fn resize(&self, width: f64, height: f64, ctx: &mut Context) {
        Window::bounds_mut(&mut ctx.window()).set_size(width, height);
        Window::constraint_mut(&mut ctx.window()).set_size(width, height);
    }

    fn active_changed(&self, active: bool, ctx: &mut Context) {
        Window::active_set(&mut ctx.widget(), active);

        // if !active {
        //     // remove focus if the window is not active
        //     if let Some(focused_widget) = ctx.window().get::<Global>("global").focused_widget {
        //         ctx.window().get_mut::<Global>("global").focused_widget = None;
        //         if ctx.get_widget(focused_widget).has::<bool>("focused") {
        //             ctx.get_widget(focused_widget).set("focused", false);
        //             ctx.get_widget(focused_widget).update_theme_by_state(false);
        //         }
        //     }
        // }
    }

    fn request_focus(&self, entity: Entity, ctx: &mut Context) {
        let mut focus_state: FocusState = Window::focus_state_clone(&ctx.widget());
        focus_state.request_focus(entity, ctx);
        Window::focus_state_set(&mut ctx.widget(), focus_state);
    }

    fn remove_focus(&self, entity: Entity, ctx: &mut Context) {
        let mut focus_state: FocusState = Window::focus_state_clone(&ctx.widget());
        focus_state.remove_focus(entity, ctx);
        Window::focus_state_set(&mut ctx.widget(), focus_state);
    }

    fn set_background(&mut self, ctx: &mut Context) {
        let background: Brush = ctx.widget().clone("background");
        if let Brush::SolidColor(color) = background {
            ctx.render_context_2_d().set_background(color);
        };
        self.background = background;
    }
}

impl State for WindowState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.set_background(ctx);
        self.title = ctx.widget().clone("title");
    }

    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if self.background != *Window::background_ref(&ctx.widget()) {
            self.set_background(ctx);
        }

        let window = ctx.widget();

        if !self.title.eq(Window::title_ref(&window)) {
            self.title = Window::title_clone(&window);
            ctx.send_window_request(WindowRequest::ChangeTitle(self.title.clone()));
        }

        if let Some(action) = self.actions.pop_front() {
            match action {
                Action::WindowEvent(window_event) => match window_event {
                    WindowEvent::Resize { width, height } => {
                        self.resize(width, height, ctx);
                    }
                    WindowEvent::ActiveChanged(active) => {
                        self.active_changed(active, ctx);
                    }
                    _ => {}
                },
                Action::FocusEvent(focus_event) => match focus_event {
                    FocusEvent::RequestFocus(entity) => {
                        self.request_focus(entity, ctx);
                    }
                    FocusEvent::RemoveFocus(entity) => {
                        self.remove_focus(entity, ctx);
                    }
                },
            }
        }
    }
}

widget!(
    /// The `Window` widget provides access to the properties of an application window.
    /// It also contains global properties like keyboard modifier and focused widget.
    ///
    /// **style:** `window`
    Window<WindowState>: ActivateHandler {
        /// Sets or shares the background property.
        background: Brush,

        /// Sets or shares the title property.
        title: String,

        /// Sets or shares the resizable property.
        resizable: bool,

        /// Sets or shares the property if this window should always be on top.
        always_on_top: bool,

        /// Sets or shares the flag if the window is borderless.
        borderless: bool,

        /// Sets or shares a value that describes if the current window is active.
        active: bool,

        /// Access the current keyboard state e.g. to check modifiers.
        keyboard_state: KeyboardState,

        /// Access the current window theme.
        theme: Theme,

        /// Access the current focus state.
        focus_state: FocusState,

        /// Internal property to handle dirty widgets.
        dirty_widgets: DirtyWidgets
    }
);

impl Window {
    fn on_window_event<H: Fn(&mut StatesContext, WindowEvent) -> bool + 'static>(
        self,
        handler: H,
    ) -> Self {
        self.insert_handler(WindowEventHandler {
            handler: Rc::new(handler),
        })
    }

    fn on_focus_event<H: Fn(&mut StatesContext, FocusEvent) -> bool + 'static>(
        self,
        handler: H,
    ) -> Self {
        self.insert_handler(FocusEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Sets or shares the resizable property.
    #[inline(always)]
    #[deprecated = "Use resizable instead"]
    pub fn resizeable<P: IntoPropertySource<bool>>(self, resizeable: P) -> Self {
        self.resizable(resizeable)
    }
}

impl Template for Window {
    fn template(self, id: Entity, _: &mut BuildContext) -> Self {
        self.name("Window")
            .background(colors::BRIGHT_GRAY_COLOR)
            .size(100.0, 100.0)
            .style(STYLE_WINDOW)
            .title("Window")
            .resizable(false)
            .always_on_top(false)
            .on_window_event(move |ctx, event| {
                ctx.get_mut::<WindowState>(id)
                    .push_action(Action::WindowEvent(event));
                true
            })
            .on_focus_event(move |ctx, event| {
                ctx.get_mut::<WindowState>(id)
                    .push_action(Action::FocusEvent(event));
                true
            })
    }

    fn render_object(&self) -> Box<dyn RenderObject> {
        RectangleRenderObject.into()
    }

    fn layout(&self) -> Box<dyn Layout> {
        GridLayout::new().into()
    }
}
<commit_msg>✨ Backwards compatibility for resizeable<commit_after>use std::{collections::VecDeque, rc::Rc};

use crate::{
    api::prelude::*, proc_macros::*, shell::prelude::WindowRequest, themes::theme_orbtk::*,
};

// --- KEYS --
pub static STYLE_WINDOW: &str = "window";
// --- KEYS --

// internal type to handle dirty widgets.
type DirtyWidgets = Vec<Entity>;

#[derive(Clone)]
enum Action {
    WindowEvent(WindowEvent),
    FocusEvent(FocusEvent),
}

// The `WindowState` handles the window events.
#[derive(Default, AsAny)]
struct WindowState {
    actions: VecDeque<Action>,
    background: Brush,
    title: String,
}

impl WindowState {
    fn push_action(&mut self, action: Action) {
        self.actions.push_front(action);
    }

    fn resize(&self, width: f64, height: f64, ctx: &mut Context) {
        Window::bounds_mut(&mut ctx.window()).set_size(width, height);
        Window::constraint_mut(&mut ctx.window()).set_size(width, height);
    }

    fn active_changed(&self, active: bool, ctx: &mut Context) {
        Window::active_set(&mut ctx.widget(), active);

        // if !active {
        //     // remove focus if the window is not active
        //     if let Some(focused_widget) = ctx.window().get::<Global>("global").focused_widget {
        //         ctx.window().get_mut::<Global>("global").focused_widget = None;
        //         if ctx.get_widget(focused_widget).has::<bool>("focused") {
        //             ctx.get_widget(focused_widget).set("focused", false);
        //             ctx.get_widget(focused_widget).update_theme_by_state(false);
        //         }
        //     }
        // }
    }

    fn request_focus(&self, entity: Entity, ctx: &mut Context) {
        let mut focus_state: FocusState = Window::focus_state_clone(&ctx.widget());
        focus_state.request_focus(entity, ctx);
        Window::focus_state_set(&mut ctx.widget(), focus_state);
    }

    fn remove_focus(&self, entity: Entity, ctx: &mut Context) {
        let mut focus_state: FocusState = Window::focus_state_clone(&ctx.widget());
        focus_state.remove_focus(entity, ctx);
        Window::focus_state_set(&mut ctx.widget(), focus_state);
    }

    fn set_background(&mut self, ctx: &mut Context) {
        let background: Brush = ctx.widget().clone("background");
        if let Brush::SolidColor(color) = background {
            ctx.render_context_2_d().set_background(color);
        };
        self.background = background;
    }
}

impl State for WindowState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.set_background(ctx);
        self.title = ctx.widget().clone("title");
    }

    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if self.background != *Window::background_ref(&ctx.widget()) {
            self.set_background(ctx);
        }

        let window = ctx.widget();

        if !self.title.eq(Window::title_ref(&window)) {
            self.title = Window::title_clone(&window);
            ctx.send_window_request(WindowRequest::ChangeTitle(self.title.clone()));
        }

        if let Some(action) = self.actions.pop_front() {
            match action {
                Action::WindowEvent(window_event) => match window_event {
                    WindowEvent::Resize { width, height } => {
                        self.resize(width, height, ctx);
                    }
                    WindowEvent::ActiveChanged(active) => {
                        self.active_changed(active, ctx);
                    }
                    _ => {}
                },
                Action::FocusEvent(focus_event) => match focus_event {
                    FocusEvent::RequestFocus(entity) => {
                        self.request_focus(entity, ctx);
                    }
                    FocusEvent::RemoveFocus(entity) => {
                        self.remove_focus(entity, ctx);
                    }
                },
            }
        }
    }
}

widget!(
    /// The `Window` widget provides access to the properties of an application window.
    /// It also contains global properties like keyboard modifier and focused widget.
    ///
    /// **style:** `window`
    Window<WindowState>: ActivateHandler {
        /// Sets or shares the background property.
        background: Brush,

        /// Sets or shares the title property.
        title: String,

        /// Sets or shares the resizable property.
        resizable: bool,

        /// Sets or shares the property if this window should always be on top.
        always_on_top: bool,

        /// Sets or shares the flag if the window is borderless.
        borderless: bool,

        /// Sets or shares a value that describes if the current window is active.
        active: bool,

        /// Access the current keyboard state e.g. to check modifiers.
        keyboard_state: KeyboardState,

        /// Access the current window theme.
        theme: Theme,

        /// Access the current focus state.
        focus_state: FocusState,

        /// Internal property to handle dirty widgets.
        dirty_widgets: DirtyWidgets
    }
);

impl Window {
    fn on_window_event<H: Fn(&mut StatesContext, WindowEvent) -> bool + 'static>(
        self,
        handler: H,
    ) -> Self {
        self.insert_handler(WindowEventHandler {
            handler: Rc::new(handler),
        })
    }

    fn on_focus_event<H: Fn(&mut StatesContext, FocusEvent) -> bool + 'static>(
        self,
        handler: H,
    ) -> Self {
        self.insert_handler(FocusEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Sets or shares the resizable property.
    #[inline(always)]
    #[deprecated = "Use resizable instead"]
    pub fn resizeable<P: IntoPropertySource<bool>>(self, resizeable: P) -> Self {
        self.resizable(resizeable)
    }

    /// Clones the property value. Panics if it is the wrong widget type.
    #[inline(always)]
    #[deprecated = "Use resizable_clone instead"]
    pub fn resizeable_clone(widget: &WidgetContainer<'_>) -> bool {
        Window::resizable_clone(widget)
    }

    /// Sets the property value. Panics if it is the wrong widget type.
    #[inline(always)]
    #[deprecated = "Use resizable_set instead"]
    pub fn resizeable_set(widget: &mut WidgetContainer<'_>, value: impl Into<bool>) {
        Window::resizable_set(widget, value)
    }

    /// Gets a mutable reference of the property value. Panics if it is the wrong widget type.
    #[inline(always)]
    #[deprecated = "Use resizable_mut instead"]
    pub fn resizeable_mut<'a>(widget: &'a mut WidgetContainer<'a>) -> &'a mut bool {
        Window::resizable_mut(widget)
    }

    /// Gets a reference of the property value. Panics if it is the wrong widget type.
    #[inline(always)]
    #[deprecated = "Use resizable_ref instead"]
    pub fn resizeable_ref<'a>(widget: &'a WidgetContainer<'a>) -> &'a bool {
        Window::resizable_ref(widget)
    }
}

impl Template for Window {
    fn template(self, id: Entity, _: &mut BuildContext) -> Self {
        self.name("Window")
            .background(colors::BRIGHT_GRAY_COLOR)
            .size(100.0, 100.0)
            .style(STYLE_WINDOW)
            .title("Window")
            .resizable(false)
            .always_on_top(false)
            .on_window_event(move |ctx, event| {
                ctx.get_mut::<WindowState>(id)
                    .push_action(Action::WindowEvent(event));
                true
            })
            .on_focus_event(move |ctx, event| {
                ctx.get_mut::<WindowState>(id)
                    .push_action(Action::FocusEvent(event));
                true
            })
    }

    fn render_object(&self) -> Box<dyn RenderObject> {
        RectangleRenderObject.into()
    }

    fn layout(&self) -> Box<dyn Layout> {
        GridLayout::new().into()
    }
}
<|endoftext|>


<commit_before>#[derive(Eq, PartialEq)]
enum Direction {
    North,
    East,
    South,
    West,
    Empty,
}

struct Table {
    w: i32,
    h: i32,
}

struct Robot {
    x: i32,
    y: i32,
    d: Direction,
    t: Table,
}

impl Default for Robot {
    fn default() -> Robot {
        let table = Table{w: 5, h: 5};

        Robot{x: 0, y: 0, d: Direction::Empty, t: table}
    }
}

impl Table {
    fn valid_pos(&self, x: i32, y: i32) -> bool {
        x >= 0 && x < self.w && y >= 0 && y < self.h
    }
}

impl Robot {
    fn is_placed(&self) -> bool {
        self.d == Direction::Empty
    }

    fn place(&mut self, x: i32, y: i32, d: Direction) {
        if self.t.valid_pos(x, y) {
            self.x = x;
            self.y = y;
            self.d = d;
        }
    }

    fn right(&mut self) {
        let d = match self.d {
            Direction::North => Direction::East,
            Direction::East => Direction::South,
            Direction::South => Direction::West,
            Direction::West => Direction::North,
            _ => Direction::Empty,
        };

        self.d = d;
    }

    fn left(&mut self) {
        let d = match self.d {
            Direction::North => Direction::West,
            Direction::West => Direction::South,
            Direction::South => Direction::East,
            Direction::East => Direction::North,
            _ => Direction::Empty,
        };

        self.d = d;
    }

    fn step(&mut self) {
    }

    fn report(&self) {
    }
}

fn main() {
    let mut robot: Robot = Default::default();

    robot.place(1, 2, Direction::North);
    robot.left();
}
<commit_msg>Added step and report<commit_after>#[derive(Eq, PartialEq)]
enum Direction {
    North,
    East,
    South,
    West,
    Empty,
}

struct Table {
    w: i32,
    h: i32,
}

struct Robot {
    x: i32,
    y: i32,
    d: Direction,
    t: Table,
}

impl Direction {
    fn string(&self) -> String {
        let s = match *self {
            Direction::North => "North",
            Direction::East => "East",
            Direction::South => "South",
            Direction::West => "West",
            _ => "Empty",
        };

        s.to_string()
    }
}

impl Default for Robot {
    fn default() -> Robot {
        let table = Table{w: 5, h: 5};

        Robot{x: 0, y: 0, d: Direction::Empty, t: table}
    }
}

impl Table {
    fn valid_pos(&self, x: i32, y: i32) -> bool {
        x >= 0 && x < self.w && y >= 0 && y < self.h
    }
}

impl Robot {
    fn place(&mut self, x: i32, y: i32, d: Direction) {
        if self.t.valid_pos(x, y) {
            self.x = x;
            self.y = y;
            self.d = d;
        }
    }

    fn right(&mut self) {
        let d = match self.d {
            Direction::North => Direction::East,
            Direction::East => Direction::South,
            Direction::South => Direction::West,
            Direction::West => Direction::North,
            _ => Direction::Empty,
        };

        self.d = d;
    }

    fn left(&mut self) {
        let d = match self.d {
            Direction::North => Direction::West,
            Direction::West => Direction::South,
            Direction::South => Direction::East,
            Direction::East => Direction::North,
            _ => Direction::Empty,
        };

        self.d = d;
    }

    fn step(&mut self) {
        match self.d {
            Direction::North => if self.t.valid_pos(self.x, self.y - 1) {self.y -= 1;},
            Direction::East => if self.t.valid_pos(self.x + 1, self.y) {self.x += 1;},
            Direction::South => if self.t.valid_pos(self.x, self.y + 1) {self.y += 1;},
            Direction::West => if self.t.valid_pos(self.x - 1, self.y) {self.y -= 1;},
            _ => (),
        }
    }

    fn report(&self) {
        println!("{}, {}, {}", self.x, self.y, self.d.string());
    }
}

fn main() {
    let mut robot: Robot = Default::default();

    robot.place(1, 2, Direction::North);
    robot.left();
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc::TryRecvError;
use std::sync::{Arc, Mutex};
use std::old_io::timer;
use std::time::Duration;

use messages::{MarketMessages, MarketHistory, ActorMessages, TransactionRequest};
use messages::ActorMessages::{StockRequest, MoneyRequest, CommitTransaction, AbortTransaction, History, Time, ReceiveActivityCount, Stop};
use messages::MarketMessages::{BuyRequest, Commit, Cancel, RegisterActor, SellRequest, RevokeRequest};
use actor::Actor;
use actor::{add_stock, remove_stock, status};

pub fn start_dummy_actor_2(actor_id: usize, existing_markets: HashMap<usize, Sender<MarketMessages>>, actor_tx: Sender<ActorMessages>, actor_rx: Receiver<ActorMessages>) {
  println!("Starting Dummy_Actor_2 {}", actor_id);
  let mut actor = Actor { id: actor_id,
                          money: 100,
                          stocks: HashMap::new(),
                          pending_money: 0,
                          pending_stock: (0, 0),
                          markets: existing_markets,
                          history: Arc::new(Mutex::new(MarketHistory {history: HashMap::new(), stocks: vec![]}))};

  //Register the actor with every market
  for (_, market_tx) in actor.markets.iter() {
    market_tx.send(RegisterActor(actor.id, actor_tx.clone())).unwrap();
  }

  let mut current_time: usize = 0;
  let mut max_time: usize = 0;

  //Number of stocks available to buy
  let mut init_history = false;
  let mut stop_flag = false;
  let mut to_sell_prices = HashMap::new();
  let mut stock_id_incr = 0;
  let mut active_buy_requests = HashMap::new();
  let mut active_sell_requests = HashMap::new();
  let mut backup_sell_requests = HashMap::new();

  loop {
    if stop_flag {
      timer::sleep(Duration::milliseconds(1000));
      continue;
    }

    //Logic
    let mark_clone = actor.markets.clone();
    let stock_clone = actor.stocks.clone();

    //buying and selling decisions
    ////////////////////////////////////////////////////////////////////

    if init_history {
      //Get variables for the actor's stocks
      let local_stocks;
      {
        local_stocks = actor.history.lock().unwrap().stocks.clone();
      }

      //Iterate through the actor's stocks
      for stock in local_stocks.iter() {
        match actor.stocks.get(stock) {
          //If the actor has some of a stock
          Some(_) => {

            //And he has not yet sent out a sell request
            if to_sell_prices.contains_key(stock) {
              //Get the price he should sell it at (remove from HashMap)
              let sell_price = to_sell_prices.remove(stock);
              match sell_price {
                Some(price) => {
                  for (_, market_tx) in actor.markets.iter() {
                    //Send out a sell request to sell it
                    let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: price, quantity: 1};
                    market_tx.send(SellRequest(t)).unwrap();
                    active_sell_requests.insert(stock_id_incr, *stock);
                    backup_sell_requests.insert(*stock, stock_id_incr);
                    stock_id_incr = stock_id_incr + 1;
                  }
                },
                None => {}
              }
            }

            if current_time > 3 * (max_time / 4) {
              match backup_sell_requests.remove(stock) {
                Some(transaction_id) => {
                  for (_, market_tx) in actor.markets.iter() {
                    //println!("()()()()()Sending backup request");
                    //market_tx.send(RevokeRequest(*stock, actor.id, transaction_id));

                    let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: 1, quantity: 1};
                    market_tx.send(SellRequest(t)).unwrap();
                    stock_id_incr = stock_id_incr + 1;
                  }
                },
                None => {}
              }
            }
          }
          //If the actor has none of a stock
          None => {
            if current_time < 3 * (max_time / 4) {
              if !to_sell_prices.contains_key(stock) {
                //Make the price he should buy it at the most recently bought price
                let buy_price = actor.history.lock().unwrap().last_sold_price(*stock);
                match buy_price {
                  //If the stock was last bought at a price
                  Some(price) => {
                    //If the actor can afford to buy it
                    if actor.money > price {
                      for (_, market_tx) in actor.markets.iter() {
                        let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: price, quantity: 1};
                        market_tx.send(BuyRequest(t)).unwrap();
                        active_buy_requests.insert(stock_id_incr, *stock);
                        stock_id_incr = stock_id_incr + 1;
                        to_sell_prices.insert(*stock, price * 2);
                      }
                    }
                  },
                  //If the stock has not been bought yet
                  None => {}
                }
              }
            }
          }
        }
      }

    }
    /////////////////////////////////////////////////////////////////////

    match actor_rx.try_recv() {
      Ok(message) => {
          match message {
            StockRequest(stock_request) => {
              let market_tx;
              let tx_text = mark_clone.get(&stock_request.market_id);
              match tx_text {
                Some(tx) => {
                  market_tx = tx;
                },
                None => {
                  return; //HOW DID WE GET A MISSING MARKET?
                }
              }
              if has_pending_transaction(&actor) {
                market_tx.send(Cancel(actor.id)).unwrap();
              }
              else {
                //if we have the stock. set it aside.
                let stock_id = stock_request.stock_id;
                let quantity = stock_request.quantity;
                let stock = stock_clone.get(&stock_id);
                match stock {
                  Some(owned_quantity) => {
                    if *owned_quantity >= quantity {
                      remove_stock(&mut actor, (stock_id, quantity));
                      actor.pending_stock = (stock_id, quantity);
                      market_tx.send(Commit(actor.id)).unwrap();
                    }
                    else {
                      market_tx.send(Cancel(actor.id)).unwrap();
                    }
                  },
                  None => {
                    market_tx.send(Cancel(actor.id)).unwrap();
                  }
                }
              }
              //print_status(&actor);
              },
            MoneyRequest(money_request) => {
              let market_tx;
              let tx_text = actor.markets.get(&money_request.market_id);
              match tx_text {
                Some(tx) => {
                  market_tx = tx;
                },
                None => {
                  return; //HOW DID WE GET A MISSING MARKET?
                }
              }
              if has_pending_transaction(&actor) {
                market_tx.send(Cancel(actor.id)).unwrap();
              }
              else {
                //if we have the money. set it aside.
                if actor.money >= money_request.amount {
                  actor.money = actor.money - money_request.amount;
                  actor.pending_money = money_request.amount;
                  market_tx.send(Commit(actor.id)).unwrap();
                }
                else {
                  market_tx.send(Cancel(actor.id)).unwrap();
                }
              }
              //print_status(&actor);
              },
            CommitTransaction(commit_transaction_request) => {
              //if we have money pending, then look up the stock id and add that quantity purchased.
              //remove the pending money
              if actor.pending_money > 0 {
                let units = commit_transaction_request.quantity;
                let leftover_money = actor.pending_money - commit_transaction_request.price;

                //make a function for adding stock.
                add_stock(&mut actor, (commit_transaction_request.stock_id, units));
                actor.money = actor.money + leftover_money;

                actor.pending_money = 0;

                //Remove this stock from the active buy requests
                active_buy_requests.remove(&(commit_transaction_request.transaction_id));
              }

              //if we have stock pending, look up the quantity purchased and add the money.
              //remove the pending stock
              if actor.pending_stock.1 > 0 {
                let money = commit_transaction_request.price;
                let restore_stock = (commit_transaction_request.stock_id, actor.pending_stock.1 - commit_transaction_request.quantity);
                if restore_stock.1 > 0 {
                  add_stock(&mut actor, restore_stock);
                }
                actor.money = actor.money + money;
                actor.pending_stock = (0,0);

                active_sell_requests.remove(&(commit_transaction_request.transaction_id));
                backup_sell_requests.remove(&(commit_transaction_request.stock_id));
              }
              //println!("After a committed transaction in actor {} ", actor.id);
              //print_status(&actor);
            },
            AbortTransaction => {
              //move pending stock back into stocks.
              if actor.pending_stock.1 != 0 {
                let pending_stock_clone = actor.pending_stock.clone();
                add_stock(&mut actor, pending_stock_clone);
                //now that we have moved it. Clear out the pending stock.
                actor.pending_stock = (0,0); //setting the quantity to zero clears it.
              }
              //move pending money back into money.
              if actor.pending_money > 0 {
                actor.money = actor.money + actor.pending_money;
                actor.pending_money = 0;
              }
            },
            History(history) => {
              actor.history = history;
              init_history = true},
            Time(current, max) => {
                current_time = current;
                max_time = max;
            },
            ReceiveActivityCount(_,_,_) => {},
            Stop(main_channel) => {
              main_channel.send((actor.id, "(Dumb Actor 2) ".to_string() + status(&actor).as_slice())).unwrap();
              stop_flag = true;
            }
          }
        },
      Err(TryRecvError::Empty) => {timer::sleep(Duration::milliseconds(1));},
      Err(TryRecvError::Disconnected) => {println!("ERROR: Actor {} disconnected", actor.id);}
    }
  }
}

fn print_status(actor: &Actor) {
  for (stock_id, quantity) in (*actor).stocks.iter() {
    println!("Dummy Actor_2 {} now has StockId: {} Quantity: {}", (*actor).id, *stock_id, *quantity);
  }
  println!("Dummy Actor_2 {} has {} money.", (*actor).id, (*actor).money);
}

fn has_pending_transaction(actor: &Actor) -> bool {
  (*actor).pending_money > 0 || (*actor).pending_stock.1 > 0
}
<commit_msg>Removed warnings<commit_after>use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc::TryRecvError;
use std::sync::{Arc, Mutex};
use std::old_io::timer;
use std::time::Duration;

use messages::{MarketMessages, MarketHistory, ActorMessages, TransactionRequest};
use messages::ActorMessages::{StockRequest, MoneyRequest, CommitTransaction, AbortTransaction, History, Time, ReceiveActivityCount, Stop};
use messages::MarketMessages::{BuyRequest, Commit, Cancel, RegisterActor, SellRequest};
use actor::Actor;
use actor::{add_stock, remove_stock, status};

pub fn start_dummy_actor_2(actor_id: usize, existing_markets: HashMap<usize, Sender<MarketMessages>>, actor_tx: Sender<ActorMessages>, actor_rx: Receiver<ActorMessages>) {
  println!("Starting Dummy_Actor_2 {}", actor_id);
  let mut actor = Actor { id: actor_id,
                          money: 100,
                          stocks: HashMap::new(),
                          pending_money: 0,
                          pending_stock: (0, 0),
                          markets: existing_markets,
                          history: Arc::new(Mutex::new(MarketHistory {history: HashMap::new(), stocks: vec![]}))};

  //Register the actor with every market
  for (_, market_tx) in actor.markets.iter() {
    market_tx.send(RegisterActor(actor.id, actor_tx.clone())).unwrap();
  }

  let mut current_time: usize = 0;
  let mut max_time: usize = 0;

  //Number of stocks available to buy
  let mut init_history = false;
  let mut stop_flag = false;
  let mut to_sell_prices = HashMap::new();
  let mut stock_id_incr = 0;
  let mut active_buy_requests = HashMap::new();
  let mut active_sell_requests = HashMap::new();
  let mut backup_sell_requests = HashMap::new();

  loop {
    if stop_flag {
      timer::sleep(Duration::milliseconds(1000));
      continue;
    }

    //Logic
    let mark_clone = actor.markets.clone();
    let stock_clone = actor.stocks.clone();

    //buying and selling decisions
    ////////////////////////////////////////////////////////////////////

    if init_history {
      //Get variables for the actor's stocks
      let local_stocks;
      {
        local_stocks = actor.history.lock().unwrap().stocks.clone();
      }

      //Iterate through the actor's stocks
      for stock in local_stocks.iter() {
        match actor.stocks.get(stock) {
          //If the actor has some of a stock
          Some(_) => {

            //And he has not yet sent out a sell request
            if to_sell_prices.contains_key(stock) {
              //Get the price he should sell it at (remove from HashMap)
              let sell_price = to_sell_prices.remove(stock);
              match sell_price {
                Some(price) => {
                  for (_, market_tx) in actor.markets.iter() {
                    //Send out a sell request to sell it
                    let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: price, quantity: 1};
                    market_tx.send(SellRequest(t)).unwrap();
                    active_sell_requests.insert(stock_id_incr, *stock);
                    backup_sell_requests.insert(*stock, stock_id_incr);
                    stock_id_incr = stock_id_incr + 1;
                  }
                },
                None => {}
              }
            }

            if current_time > 3 * (max_time / 4) {
              match backup_sell_requests.remove(stock) {
                Some(_) => {
                  for (_, market_tx) in actor.markets.iter() {
                    //println!("()()()()()Sending backup request");
                    //market_tx.send(RevokeRequest(*stock, actor.id, transaction_id));

                    let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: 1, quantity: 1};
                    market_tx.send(SellRequest(t)).unwrap();
                    stock_id_incr = stock_id_incr + 1;
                  }
                },
                None => {}
              }
            }
          }
          //If the actor has none of a stock
          None => {
            if current_time < 3 * (max_time / 4) {
              if !to_sell_prices.contains_key(stock) {
                //Make the price he should buy it at the most recently bought price
                let buy_price = actor.history.lock().unwrap().last_sold_price(*stock);
                match buy_price {
                  //If the stock was last bought at a price
                  Some(price) => {
                    //If the actor can afford to buy it
                    if actor.money > price {
                      for (_, market_tx) in actor.markets.iter() {
                        let t = TransactionRequest{actor_id: actor.id, transaction_id: stock_id_incr, stock_id: *stock, price: price, quantity: 1};
                        market_tx.send(BuyRequest(t)).unwrap();
                        active_buy_requests.insert(stock_id_incr, *stock);
                        stock_id_incr = stock_id_incr + 1;
                        to_sell_prices.insert(*stock, price * 2);
                      }
                    }
                  },
                  //If the stock has not been bought yet
                  None => {}
                }
              }
            }
          }
        }
      }

    }
    /////////////////////////////////////////////////////////////////////

    match actor_rx.try_recv() {
      Ok(message) => {
          match message {
            StockRequest(stock_request) => {
              let market_tx;
              let tx_text = mark_clone.get(&stock_request.market_id);
              match tx_text {
                Some(tx) => {
                  market_tx = tx;
                },
                None => {
                  return; //HOW DID WE GET A MISSING MARKET?
                }
              }
              if has_pending_transaction(&actor) {
                market_tx.send(Cancel(actor.id)).unwrap();
              }
              else {
                //if we have the stock. set it aside.
                let stock_id = stock_request.stock_id;
                let quantity = stock_request.quantity;
                let stock = stock_clone.get(&stock_id);
                match stock {
                  Some(owned_quantity) => {
                    if *owned_quantity >= quantity {
                      remove_stock(&mut actor, (stock_id, quantity));
                      actor.pending_stock = (stock_id, quantity);
                      market_tx.send(Commit(actor.id)).unwrap();
                    }
                    else {
                      market_tx.send(Cancel(actor.id)).unwrap();
                    }
                  },
                  None => {
                    market_tx.send(Cancel(actor.id)).unwrap();
                  }
                }
              }
              //print_status(&actor);
              },
            MoneyRequest(money_request) => {
              let market_tx;
              let tx_text = actor.markets.get(&money_request.market_id);
              match tx_text {
                Some(tx) => {
                  market_tx = tx;
                },
                None => {
                  return; //HOW DID WE GET A MISSING MARKET?
                }
              }
              if has_pending_transaction(&actor) {
                market_tx.send(Cancel(actor.id)).unwrap();
              }
              else {
                //if we have the money. set it aside.
                if actor.money >= money_request.amount {
                  actor.money = actor.money - money_request.amount;
                  actor.pending_money = money_request.amount;
                  market_tx.send(Commit(actor.id)).unwrap();
                }
                else {
                  market_tx.send(Cancel(actor.id)).unwrap();
                }
              }
              //print_status(&actor);
              },
            CommitTransaction(commit_transaction_request) => {
              //if we have money pending, then look up the stock id and add that quantity purchased.
              //remove the pending money
              if actor.pending_money > 0 {
                let units = commit_transaction_request.quantity;
                let leftover_money = actor.pending_money - commit_transaction_request.price;

                //make a function for adding stock.
                add_stock(&mut actor, (commit_transaction_request.stock_id, units));
                actor.money = actor.money + leftover_money;

                actor.pending_money = 0;

                //Remove this stock from the active buy requests
                active_buy_requests.remove(&(commit_transaction_request.transaction_id));
              }

              //if we have stock pending, look up the quantity purchased and add the money.
              //remove the pending stock
              if actor.pending_stock.1 > 0 {
                let money = commit_transaction_request.price;
                let restore_stock = (commit_transaction_request.stock_id, actor.pending_stock.1 - commit_transaction_request.quantity);
                if restore_stock.1 > 0 {
                  add_stock(&mut actor, restore_stock);
                }
                actor.money = actor.money + money;
                actor.pending_stock = (0,0);

                active_sell_requests.remove(&(commit_transaction_request.transaction_id));
                backup_sell_requests.remove(&(commit_transaction_request.stock_id));
              }
              //println!("After a committed transaction in actor {} ", actor.id);
              //print_status(&actor);
            },
            AbortTransaction => {
              //move pending stock back into stocks.
              if actor.pending_stock.1 != 0 {
                let pending_stock_clone = actor.pending_stock.clone();
                add_stock(&mut actor, pending_stock_clone);
                //now that we have moved it. Clear out the pending stock.
                actor.pending_stock = (0,0); //setting the quantity to zero clears it.
              }
              //move pending money back into money.
              if actor.pending_money > 0 {
                actor.money = actor.money + actor.pending_money;
                actor.pending_money = 0;
              }
            },
            History(history) => {
              actor.history = history;
              init_history = true},
            Time(current, max) => {
                current_time = current;
                max_time = max;
            },
            ReceiveActivityCount(_,_,_) => {},
            Stop(main_channel) => {
              main_channel.send((actor.id, "(Dumb Actor 2) ".to_string() + status(&actor).as_slice())).unwrap();
              stop_flag = true;
            }
          }
        },
      Err(TryRecvError::Empty) => {timer::sleep(Duration::milliseconds(1));},
      Err(TryRecvError::Disconnected) => {println!("ERROR: Actor {} disconnected", actor.id);}
    }
  }
}

fn has_pending_transaction(actor: &Actor) -> bool {
  (*actor).pending_money > 0 || (*actor).pending_stock.1 > 0
}
<|endoftext|>


<commit_before>#![feature(proc_macro_quote, proc_macro_hygiene)]
#![deny(rust_2018_idioms)]
extern crate proc_macro;

use proc_macro::{quote, TokenStream};

#[proc_macro_derive(ClippyMiniMacroTest)]
pub fn mini_macro(_: TokenStream) -> TokenStream {
    quote!(
        #[allow(unused)]
        fn needless_take_by_value(s: String) {
            println!("{}", s.len());
        }
        #[allow(unused)]
        fn needless_loop(items: &[u8]) {
            for i in 0..items.len() {
                println!("{}", items[i]);
            }
        }
        fn line_wrapper() {
            println!("{}", line!());
        }
    )
}
<commit_msg>Allow unused_extern_crates for now<commit_after>#![feature(proc_macro_quote, proc_macro_hygiene)]
#![deny(rust_2018_idioms)]
// FIXME: Remove this attribute once the weird failure is gone.
#![allow(unused_extern_crates)]
extern crate proc_macro;

use proc_macro::{quote, TokenStream};

#[proc_macro_derive(ClippyMiniMacroTest)]
pub fn mini_macro(_: TokenStream) -> TokenStream {
    quote!(
        #[allow(unused)]
        fn needless_take_by_value(s: String) {
            println!("{}", s.len());
        }
        #[allow(unused)]
        fn needless_loop(items: &[u8]) {
            for i in 0..items.len() {
                println!("{}", items[i]);
            }
        }
        fn line_wrapper() {
            println!("{}", line!());
        }
    )
}
<|endoftext|>


<commit_before>//! Module that contains a crawler function that crawls through the vulkan xml and returns a
//! Registry struct
use xml::reader::{Events, XmlEvent};
use xml::name::OwnedName;
use xml::attribute::OwnedAttribute;
use std::io::Read;
use std::ffi::CStr;
use {VkRegistry, VkType, VkMember};
use VkVariant;

pub fn crawl<R: Read>(xml_events: Events<R>, mut registry: VkRegistry) -> VkRegistry {
    use self::XmlElement::*;

    let mut type_buffer = VkType::Unhandled;
    let mut cur_block = VkBlock::None;
    // A variable that contains what the index of the element in vk_elements that vk_elements was
    // popped to. Used to prevent the element iterator from going over elements that have already
    // been checked.
    let mut popped_to = 0;

    // A stack of the relevant elements in the vulkan xml
    let mut vk_elements = Vec::with_capacity(10);

    for event in xml_events {

        let event = event.unwrap();
        match event {
            XmlEvent::StartElement{ name, attributes, .. } => {
                vk_elements.push(XmlElement::new_tag(name, attributes));
            }

            XmlEvent::EndElement{ name } => {
                for el in &vk_elements[popped_to..] {
                    match *el {
                        Tag{name: ref tag_name, attributes: ref tag_attrs} =>
                            match &tag_name[..] {
                                "types"      => cur_block = VkBlock::Types,
                                "enums"      => cur_block = VkBlock::Enums,
                                "commands"   => cur_block = VkBlock::Commands,
                                "extensions" => cur_block = VkBlock::Extensions,

                                "type"  =>
                                    if VkBlock::Types == cur_block {
                                        if let Some(category) = find_attribute(tag_attrs, "category") {
                                            registry.push_type(type_buffer).ok();
                                            match category {
                                                "basetype"      => type_buffer = VkType::Unhandled,
                                                "bitmask"       => type_buffer = VkType::Unhandled,
                                                "define"        => type_buffer = VkType::Unhandled,
                                                "enum"          => type_buffer = VkType::Unhandled,
                                                "funcpointer"   => type_buffer = VkType::Unhandled,
                                                "group"         => type_buffer = VkType::Unhandled,
                                                "handle"        => type_buffer = VkType::Unhandled,
                                                "include"       => type_buffer = VkType::Unhandled,
                                                "struct"        =>
                                                    type_buffer = VkType::Struct{name: registry.append_str(find_attribute(tag_attrs, "name").unwrap()), fields: Vec::with_capacity(8)},
                                                "union"         =>
                                                    type_buffer = VkType::Union{name: registry.append_str(find_attribute(tag_attrs, "name").unwrap()), variants: Vec::with_capacity(8)},
                                                _               => panic!("Unexpected category")
                                            }
                                        }
                                    } else {/*panic!("\"type\" tag found outside of \"types\" block")*/}, //TODO: implement fully so panic can be used

                                "member" =>
                                    if VkBlock::Types == cur_block {
                                        match type_buffer {
                                            VkType::Struct{ref mut fields, ..} => fields.push(VkMember::empty()),
                                            VkType::Union{ref mut variants, ..} => variants.push(VkMember::empty()),
                                            _ =>
                                                panic!("Unexpected \"member\" tag found")
                                        }
                                    } else {panic!("\"member\" tag found outside of \"types\" block")},

                                _ => ()
                            },

                        Characters{ref chars, tag} =>
                            match tag {
                                "member" =>
                                    if VkBlock::Types == cur_block {
                                        match type_buffer {
                                            VkType::Struct{fields: ref mut members, ..} |
                                            VkType::Union{variants: ref mut members, ..} =>
                                                match chars.trim() {
                                                    "const" => members.last_mut().unwrap().change_type_const(),
                                                    "*"     => members.last_mut().unwrap().change_type_ptr(),
                                                    _       => ()
                                                },
                                            _ => ()
                                        }
                                    },
                                "type" =>
                                    if VkBlock::Types == cur_block {
                                        match type_buffer {
                                            VkType::Struct{fields: ref mut members, ..} |
                                            VkType::Union{variants: ref mut members, ..} => members.last_mut().unwrap().set_type(registry.append_str(&chars[..])),
                                            _ => ()
                                        }
                                    },
                                "name" =>
                                    if VkBlock::Types == cur_block {
                                        match type_buffer {
                                            VkType::Struct{fields: ref mut members, ..} |
                                            VkType::Union{variants: ref mut members, ..} => members.last_mut().unwrap().set_name(registry.append_str(&chars[..])),
                                            _ => ()
                                        }
                                    },
                                _ => ()
                            }
                    }
                }

                pop_element_stack(&mut vk_elements);
                popped_to = vk_elements.len();
            }

            XmlEvent::Characters(chars) => {
                let tag_ptr =
                    match *vk_elements.last().unwrap() {
                        XmlElement::Tag{name: ref tag, ..} => &tag[..] as *const str,
                        // In circumstances where the xml reads something like <foo>foostart<bar>bar</bar>fooend</foo>, the
                        // "fooend" string will appear in vk_elements after the "foostart" event, instead of after <foo>.
                        // Because of that, we must pull the tag from the other Characters event.
                        XmlElement::Characters{tag, ..} => tag as *const str
                    };

                unsafe{ vk_elements.push(XmlElement::new_chars(chars, &*tag_ptr)) }
            }

            _ => ()
        }
    }

    for t in &registry.types {
        unsafe {
            match *t {
                VkType::Struct{name, ref fields} => {
                    println!("Struct {:?}", CStr::from_ptr(name));

                    for f in fields {
                        println!("{:#?}", f);
                    }
                }
                VkType::Union{name, ref variants} => {
                    println!("Union {:?}", CStr::from_ptr(name));

                    for v in variants {
                        println!("{:#?}", v);
                    }
                }
                _ => ()
            }
        }
    }

    registry
}

fn find_attribute<'v>(source: &'v Vec<OwnedAttribute>, query: &str) -> Option<&'v str> {
    source.into_iter().skip_while(|attr| &attr.name.local_name != query).next().map(|res| &*res.value)
}

/// Takes a mutable reference to a XmlElement stack, popping the stack of Character elements until
/// it pops a Tag
fn pop_element_stack(vk_elements: &mut Vec<XmlElement>) {
    match vk_elements.pop() {
        Some(el) =>
            if let XmlElement::Characters{..} = el {
                pop_element_stack(vk_elements)
            },

        None => panic!("Invalid xml; Unexpected closing tag")
    }
}

#[derive(Debug)]
enum XmlElement<'a> {
    Tag {
        /// The name of the tag e.g. "hello" in <hello>
        name: String,
        /// The attributes contained within the specification xml.
        attributes: Vec<OwnedAttribute>
    },
    Characters{
        chars: String,
        tag: &'a str
    }
}

impl<'a> XmlElement<'a> {
    fn new_tag(name: OwnedName, attributes: Vec<OwnedAttribute>) -> XmlElement<'a> {
        XmlElement::Tag {
            name: name.local_name,
            attributes: attributes
        }
    }

    fn new_chars(chars: String, tag: &'a str) -> XmlElement<'a> {
        XmlElement::Characters {
            chars: chars,
            tag: tag
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
enum VkBlock {
    Types,
    Enums,
    Commands,
    Extensions,
    None
}<commit_msg>Performed distributive property magic on nested match statement.<commit_after>//! Module that contains a crawler function that crawls through the vulkan xml and returns a
//! Registry struct
use xml::reader::{Events, XmlEvent};
use xml::name::OwnedName;
use xml::attribute::OwnedAttribute;
use std::io::Read;
use std::ffi::CStr;
use {VkRegistry, VkType, VkMember};
use VkVariant;

pub fn crawl<R: Read>(xml_events: Events<R>, mut registry: VkRegistry) -> VkRegistry {
    use self::XmlElement::*;

    let mut type_buffer = VkType::Unhandled;
    let mut cur_block = VkBlock::None;
    // A variable that contains what the index of the element in vk_elements that vk_elements was
    // popped to. Used to prevent the element iterator from going over elements that have already
    // been checked.
    let mut popped_to = 0;

    // A stack of the relevant elements in the vulkan xml
    let mut vk_elements = Vec::with_capacity(10);

    for event in xml_events {

        let event = event.unwrap();
        match event {
            XmlEvent::StartElement{ name, attributes, .. } => {
                vk_elements.push(XmlElement::new_tag(name, attributes));
            }

            XmlEvent::EndElement{ name } => {
                for el in &vk_elements[popped_to..] {
                    match *el {
                        Tag{name: ref tag_name, attributes: ref tag_attrs} =>
                            match &tag_name[..] {
                                "types"      => cur_block = VkBlock::Types,
                                "enums"      => cur_block = VkBlock::Enums,
                                "commands"   => cur_block = VkBlock::Commands,
                                "extensions" => cur_block = VkBlock::Extensions,

                                "type"  =>
                                    if VkBlock::Types == cur_block {
                                        if let Some(category) = find_attribute(tag_attrs, "category") {
                                            registry.push_type(type_buffer).ok();
                                            match category {
                                                "basetype"      => type_buffer = VkType::Unhandled,
                                                "bitmask"       => type_buffer = VkType::Unhandled,
                                                "define"        => type_buffer = VkType::Unhandled,
                                                "enum"          => type_buffer = VkType::Unhandled,
                                                "funcpointer"   => type_buffer = VkType::Unhandled,
                                                "group"         => type_buffer = VkType::Unhandled,
                                                "handle"        => type_buffer = VkType::Unhandled,
                                                "include"       => type_buffer = VkType::Unhandled,
                                                "struct"        =>
                                                    type_buffer = VkType::Struct{name: registry.append_str(find_attribute(tag_attrs, "name").unwrap()), fields: Vec::with_capacity(8)},
                                                "union"         =>
                                                    type_buffer = VkType::Union{name: registry.append_str(find_attribute(tag_attrs, "name").unwrap()), variants: Vec::with_capacity(8)},
                                                _               => panic!("Unexpected category")
                                            }
                                        }
                                    } else {/*panic!("\"type\" tag found outside of \"types\" block")*/}, //TODO: implement fully so panic can be used

                                "member" =>
                                    if VkBlock::Types == cur_block {
                                        match type_buffer {
                                            VkType::Struct{ref mut fields, ..} => fields.push(VkMember::empty()),
                                            VkType::Union{ref mut variants, ..} => variants.push(VkMember::empty()),
                                            _ =>
                                                panic!("Unexpected \"member\" tag found")
                                        }
                                    } else {panic!("\"member\" tag found outside of \"types\" block")},

                                _ => ()
                            },

                        Characters{ref chars, tag} =>
                            if VkBlock::Types == cur_block {
                                match type_buffer {
                                    VkType::Struct{fields: ref mut members, ..} |
                                    VkType::Union{variants: ref mut members, ..} =>
                                        match tag {
                                            "member" =>
                                                match chars.trim() {
                                                    "const" => members.last_mut().unwrap().change_type_const(),
                                                    "*"     => members.last_mut().unwrap().change_type_ptr(),
                                                    _       => ()
                                                },
                                            "type" =>
                                                members.last_mut().unwrap().set_type(registry.append_str(&chars[..])),
                                            "name" =>
                                                members.last_mut().unwrap().set_name(registry.append_str(&chars[..])),
                                            _ => ()
                                        },
                                    _ => ()
                                }
                            }
                    }
                }

                pop_element_stack(&mut vk_elements);
                popped_to = vk_elements.len();
            }

            XmlEvent::Characters(chars) => {
                let tag_ptr =
                    match *vk_elements.last().unwrap() {
                        XmlElement::Tag{name: ref tag, ..} => &tag[..] as *const str,
                        // In circumstances where the xml reads something like <foo>foostart<bar>bar</bar>fooend</foo>, the
                        // "fooend" string will appear in vk_elements after the "foostart" event, instead of after <foo>.
                        // Because of that, we must pull the tag from the other Characters event.
                        XmlElement::Characters{tag, ..} => tag as *const str
                    };

                unsafe{ vk_elements.push(XmlElement::new_chars(chars, &*tag_ptr)) }
            }

            _ => ()
        }
    }

    for t in &registry.types {
        unsafe {
            match *t {
                VkType::Struct{name, ref fields} => {
                    println!("Struct {:?}", CStr::from_ptr(name));

                    for f in fields {
                        println!("{:#?}", f);
                    }
                }
                VkType::Union{name, ref variants} => {
                    println!("Union {:?}", CStr::from_ptr(name));

                    for v in variants {
                        println!("{:#?}", v);
                    }
                }
                _ => ()
            }
        }
    }

    registry
}

fn find_attribute<'v>(source: &'v Vec<OwnedAttribute>, query: &str) -> Option<&'v str> {
    source.into_iter().skip_while(|attr| &attr.name.local_name != query).next().map(|res| &*res.value)
}

/// Takes a mutable reference to a XmlElement stack, popping the stack of Character elements until
/// it pops a Tag
fn pop_element_stack(vk_elements: &mut Vec<XmlElement>) {
    match vk_elements.pop() {
        Some(el) =>
            if let XmlElement::Characters{..} = el {
                pop_element_stack(vk_elements)
            },

        None => panic!("Invalid xml; Unexpected closing tag")
    }
}

#[derive(Debug)]
enum XmlElement<'a> {
    Tag {
        /// The name of the tag e.g. "hello" in <hello>
        name: String,
        /// The attributes contained within the specification xml.
        attributes: Vec<OwnedAttribute>
    },
    Characters{
        chars: String,
        tag: &'a str
    }
}

impl<'a> XmlElement<'a> {
    fn new_tag(name: OwnedName, attributes: Vec<OwnedAttribute>) -> XmlElement<'a> {
        XmlElement::Tag {
            name: name.local_name,
            attributes: attributes
        }
    }

    fn new_chars(chars: String, tag: &'a str) -> XmlElement<'a> {
        XmlElement::Characters {
            chars: chars,
            tag: tag
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
enum VkBlock {
    Types,
    Enums,
    Commands,
    Extensions,
    None
}<|endoftext|>


<commit_before>use std::fmt;
use std::fmt::{Show, Formatter};
use std::os;
use std::c_str::CString;
use std::io::process::{Command, ProcessOutput, InheritFd};
use std::collections::HashMap;

use util::{ProcessError, process_error};

#[deriving(Clone,PartialEq)]
pub struct ProcessBuilder {
    program: CString,
    args: Vec<String>,
    path: Vec<String>,
    env: HashMap<String, String>,
    cwd: Path
}

impl Show for ProcessBuilder {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "`{}", self.program.as_str().unwrap_or("<not-utf8>")));

        if self.args.len() > 0 {
            try!(write!(f, " {}", self.args.connect(" ")));
        }

        write!(f, "`")
    }
}

// TODO: Upstream a Windows/Posix branch to Rust proper
#[cfg(unix)]
static PATH_SEP : &'static str = ":";
#[cfg(windows)]
static PATH_SEP : &'static str = ";";

impl ProcessBuilder {
    pub fn arg<T: Str>(mut self, arg: T) -> ProcessBuilder {
        self.args.push(arg.as_slice().to_string());
        self
    }

    pub fn args<T: Str>(mut self, arguments: &[T]) -> ProcessBuilder {
        self.args = arguments.iter().map(|a| a.as_slice().to_string()).collect();
        self
    }

    pub fn get_args<'a>(&'a self) -> &'a [String] {
        self.args.as_slice()
    }

    pub fn extra_path(mut self, path: Path) -> ProcessBuilder {
        // For now, just convert to a string, but we should do something better
        self.path.unshift(path.display().to_string());
        self
    }

    pub fn cwd(mut self, path: Path) -> ProcessBuilder {
        self.cwd = path;
        self
    }

    pub fn env(mut self, key: &str, val: Option<&str>) -> ProcessBuilder {
        match val {
            Some(v) => {
                self.env.insert(key.to_string(), v.to_string());
            },
            None => {
                self.env.remove(&key.to_string());
            }
        }

        self
    }

    // TODO: should InheritFd be hardcoded?
    pub fn exec(&self) -> Result<(), ProcessError> {
        let mut command = self.build_command();
        command
            .env(self.build_env().as_slice())
            .stdout(InheritFd(1))
            .stderr(InheritFd(2));

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let exit = try!(command.status().map_err(|e|
            process_error(msg(), Some(e), None, None)));

        if exit.success() {
            Ok(())
        } else {
            Err(process_error(msg(), None, Some(&exit), None))
        }
    }

    pub fn exec_with_output(&self) -> Result<ProcessOutput, ProcessError> {
        let mut command = self.build_command();
        command.env(self.build_env().as_slice());

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let output = try!(command.output().map_err(|e| {
            process_error(msg(), Some(e), None, None)
        }));

        if output.status.success() {
            Ok(output)
        } else {
            Err(process_error(msg(), None, Some(&output.status),
                              Some(&output)))
        }
    }

    pub fn build_command(&self) -> Command {
        let mut command = Command::new(self.program.as_bytes_no_nul());
        command.args(self.args.as_slice()).cwd(&self.cwd);
        command
    }

    fn debug_string(&self) -> String {
        let program = self.program.as_str().unwrap_or("<not-utf8>");
        if self.args.len() == 0 {
            program.to_string()
        } else {
            format!("{} {}", program, self.args.connect(" "))
        }
    }

    fn build_env(&self) -> Vec<(String, String)> {
        let mut ret = Vec::new();

        for (key, val) in self.env.iter() {
            // Skip path
            if key.as_slice() != "PATH" {
                ret.push((key.clone(), val.clone()));
            }
        }

        match self.build_path() {
            Some(path) => ret.push(("PATH".to_string(), path)),
            _ => ()
        }

        ret.as_slice().to_owned()
    }

    fn build_path(&self) -> Option<String> {
        let path = self.path.connect(PATH_SEP);

        match self.env.find_equiv(&("PATH")) {
            Some(existing) => {
                if self.path.is_empty() {
                    Some(existing.clone())
                } else {
                    Some(format!("{}{}{}", existing, PATH_SEP, path))
                }
            },
            None => {
                if self.path.is_empty() {
                    None
                } else {
                    Some(path)
                }
            }
        }
    }
}

pub fn process<T: ToCStr>(cmd: T) -> ProcessBuilder {
    ProcessBuilder {
        program: cmd.to_c_str(),
        args: vec!(),
        path: vec!(),
        cwd: os::getcwd(),
        env: os::env().move_iter().collect()
    }
}
<commit_msg>Use command.env_set_all() instead of command.env()<commit_after>use std::fmt;
use std::fmt::{Show, Formatter};
use std::os;
use std::c_str::CString;
use std::io::process::{Command, ProcessOutput, InheritFd};
use std::collections::HashMap;

use util::{ProcessError, process_error};

#[deriving(Clone,PartialEq)]
pub struct ProcessBuilder {
    program: CString,
    args: Vec<String>,
    path: Vec<String>,
    env: HashMap<String, String>,
    cwd: Path
}

impl Show for ProcessBuilder {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "`{}", self.program.as_str().unwrap_or("<not-utf8>")));

        if self.args.len() > 0 {
            try!(write!(f, " {}", self.args.connect(" ")));
        }

        write!(f, "`")
    }
}

// TODO: Upstream a Windows/Posix branch to Rust proper
#[cfg(unix)]
static PATH_SEP : &'static str = ":";
#[cfg(windows)]
static PATH_SEP : &'static str = ";";

impl ProcessBuilder {
    pub fn arg<T: Str>(mut self, arg: T) -> ProcessBuilder {
        self.args.push(arg.as_slice().to_string());
        self
    }

    pub fn args<T: Str>(mut self, arguments: &[T]) -> ProcessBuilder {
        self.args = arguments.iter().map(|a| a.as_slice().to_string()).collect();
        self
    }

    pub fn get_args<'a>(&'a self) -> &'a [String] {
        self.args.as_slice()
    }

    pub fn extra_path(mut self, path: Path) -> ProcessBuilder {
        // For now, just convert to a string, but we should do something better
        self.path.unshift(path.display().to_string());
        self
    }

    pub fn cwd(mut self, path: Path) -> ProcessBuilder {
        self.cwd = path;
        self
    }

    pub fn env(mut self, key: &str, val: Option<&str>) -> ProcessBuilder {
        match val {
            Some(v) => {
                self.env.insert(key.to_string(), v.to_string());
            },
            None => {
                self.env.remove(&key.to_string());
            }
        }

        self
    }

    // TODO: should InheritFd be hardcoded?
    pub fn exec(&self) -> Result<(), ProcessError> {
        let mut command = self.build_command();
        command
            .env_set_all(self.build_env().as_slice())
            .stdout(InheritFd(1))
            .stderr(InheritFd(2));

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let exit = try!(command.status().map_err(|e|
            process_error(msg(), Some(e), None, None)));

        if exit.success() {
            Ok(())
        } else {
            Err(process_error(msg(), None, Some(&exit), None))
        }
    }

    pub fn exec_with_output(&self) -> Result<ProcessOutput, ProcessError> {
        let mut command = self.build_command();
        command.env_set_all(self.build_env().as_slice());

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let output = try!(command.output().map_err(|e| {
            process_error(msg(), Some(e), None, None)
        }));

        if output.status.success() {
            Ok(output)
        } else {
            Err(process_error(msg(), None, Some(&output.status),
                              Some(&output)))
        }
    }

    pub fn build_command(&self) -> Command {
        let mut command = Command::new(self.program.as_bytes_no_nul());
        command.args(self.args.as_slice()).cwd(&self.cwd);
        command
    }

    fn debug_string(&self) -> String {
        let program = self.program.as_str().unwrap_or("<not-utf8>");
        if self.args.len() == 0 {
            program.to_string()
        } else {
            format!("{} {}", program, self.args.connect(" "))
        }
    }

    fn build_env(&self) -> Vec<(String, String)> {
        let mut ret = Vec::new();

        for (key, val) in self.env.iter() {
            // Skip path
            if key.as_slice() != "PATH" {
                ret.push((key.clone(), val.clone()));
            }
        }

        match self.build_path() {
            Some(path) => ret.push(("PATH".to_string(), path)),
            _ => ()
        }

        ret.as_slice().to_owned()
    }

    fn build_path(&self) -> Option<String> {
        let path = self.path.connect(PATH_SEP);

        match self.env.find_equiv(&("PATH")) {
            Some(existing) => {
                if self.path.is_empty() {
                    Some(existing.clone())
                } else {
                    Some(format!("{}{}{}", existing, PATH_SEP, path))
                }
            },
            None => {
                if self.path.is_empty() {
                    None
                } else {
                    Some(path)
                }
            }
        }
    }
}

pub fn process<T: ToCStr>(cmd: T) -> ProcessBuilder {
    ProcessBuilder {
        program: cmd.to_c_str(),
        args: vec!(),
        path: vec!(),
        cwd: os::getcwd(),
        env: os::env().move_iter().collect()
    }
}
<|endoftext|>