<commit_before>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, Element};
use std::iter::Extend;

// use std::iter::Iterator;

// define a traversal as a series of stages

pub struct GraphQuery {
    // many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
            let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

    pub fn get_paths(&self) -> &Vec<Path> {
        &self.paths
    }
    pub fn push(&mut self, path:Path) {
        self.paths.push(path)
    }

    /*
    generic mapper for our queries
    future this may use worker threads to perform
    traversals
     */
    fn map<F: Fn(&Path) -> Vec<Element>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
        for path in self.paths.iter() {
            let mut tmp = closure(&path);
            // let mut tmp2 = tmp.as_slice();
            // currently gets back a Vec<Path> but what if it gets Elements?
            let new_elements = path.permute(&tmp);
            result.paths.extend(new_elements);
        }
        result
    }

    pub fn outV(&self) -> GraphQuery {
        // needs to be modified to return a Vec of elements or a slice?
        // map can figure out the rest
        let f = |path: &Path| {
            println!("applying outV");
            //take the final element in the path
            let element = path.last().unwrap();

            let result : Vec<Element> = match element {
                &Element::Vertex(v) =>
                    v.outV().iter().map(|v| Element::Vertex(*v)).collect(),
                    // Vec::new(),
                &Element::Edge(ref e) =>
                    Vec::new()
            };
            // apply outV
            result
        };
        self.map(f)
    }

//    pub fn inV(&self) -> GraphQuery {
//        let g = GraphQuery::empty();
//        let f = |element: &Element| {
//            element.inV()
//        };
//        self.map(f)
//    }
}
<commit_msg>removed comment thats no longer valid and debug print statement<commit_after>
use vertex::{RawVertex, Vertex};
use edge::{Edge, EdgeProxy};
use graph::TraversableToVertex;
use path::{Path, Element};
use std::iter::Extend;

// use std::iter::Iterator;

// define a traversal as a series of stages

pub struct GraphQuery {
    // many paths
    pub paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<Vertex>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let mut paths = Vec::new();
        for p in vertices {
            let mut path = Path::new(p);
            paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

    pub fn get_paths(&self) -> &Vec<Path> {
        &self.paths
    }
    pub fn push(&mut self, path:Path) {
        self.paths.push(path)
    }

    /*
    generic mapper for our queries
    future this may use worker threads to perform
    traversals
     */
    fn map<F: Fn(&Path) -> Vec<Element>>(&self, closure: F) -> GraphQuery  {
        let mut result = GraphQuery::empty(); // result
        for path in self.paths.iter() {
            let mut tmp = closure(&path);
            // let mut tmp2 = tmp.as_slice();
            // currently gets back a Vec<Path> but what if it gets Elements?
            let new_elements = path.permute(&tmp);
            result.paths.extend(new_elements);
        }
        result
    }

    pub fn outV(&self) -> GraphQuery {
        // map can figure out the rest
        let f = |path: &Path| {
            //take the final element in the path
            let element = path.last().unwrap();

            let result : Vec<Element> = match element {
                &Element::Vertex(v) =>
                    v.outV().iter().map(|v| Element::Vertex(*v)).collect(),
                    // Vec::new(),
                &Element::Edge(ref e) =>
                    Vec::new()
            };
            // apply outV
            result
        };
        self.map(f)
    }

//    pub fn inV(&self) -> GraphQuery {
//        let g = GraphQuery::empty();
//        let f = |element: &Element| {
//            element.inV()
//        };
//        self.map(f)
//    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[derive(Debug)]
pub struct Stack<T: Clone> {
    ops: Vec<StackOp<T>>,
    cache: Vec<T>,
    snapshots: Vec<usize>
}

impl<T: Clone> Stack<T> {
    pub fn new() -> Self {
        Stack {
            ops: vec![],
            cache: vec![],
            snapshots: vec![]
        }
    }

    pub fn is_empty(&self) -> bool {
        self.cache.is_empty()
    }

    pub fn peek(&self) -> Option<&T> {
        self.cache.last()
    }

    pub fn push(&mut self, elem: T) {
        self.ops.push(StackOp::Push(elem.clone()));
        self.cache.push(elem);
    }

    pub fn pop(&mut self) -> Option<T> {
        self.ops.push(StackOp::Pop());
        self.cache.pop()
    }

    pub fn snapshot(&mut self) {
        self.snapshots.push(self.ops.len());
    }

    pub fn backtrack(&mut self) {
        match self.snapshots.pop() {
            Some(index) => {
                self.ops.truncate(index);
                self.recache();
            }
            None => {}
        }
    }

    fn recache(&mut self) {
        self.cache.clear();
        for op in self.ops.iter() {
            match op {
                &StackOp::Push(ref elem) => {
                    self.cache.push(elem.clone());
                },
                &StackOp::Pop() => {
                    self.cache.pop();
                }
            }
        }
    }
}

#[derive(Debug)]
enum StackOp<T> {
    Push(T),
    Pop()
}

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

    #[test]
    fn stack_ops() {
        let mut stack = Stack::new();

        // []
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // [0]
        stack.push(0);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 1]
        stack.push(1);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&1));

        // [0]
        assert_eq!(stack.pop(), Some(1));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 2]
        stack.push(2);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // [0, 2, 3]
        stack.push(3);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&3));

        // Take a snapshot of the current stack
        // [0, 2, 3]
        stack.snapshot();

        // [0, 2]
        assert_eq!(stack.pop(), Some(3));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // Take a snapshot of the current stack
        // [0, 2]
        stack.snapshot();

        // [0]
        assert_eq!(stack.pop(), Some(2));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // []
        assert_eq!(stack.pop(), Some(0));
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2]
        stack.backtrack();
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2, 3]
        stack.backtrack();
        assert_eq!(stack.pop(), Some(3));
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);
    }
}
<commit_msg>add a clear method to the stack<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[derive(Debug)]
pub struct Stack<T: Clone> {
    ops: Vec<StackOp<T>>,
    cache: Vec<T>,
    snapshots: Vec<usize>
}

impl<T: Clone> Stack<T> {
    pub fn new() -> Self {
        Stack {
            ops: vec![],
            cache: vec![],
            snapshots: vec![]
        }
    }

    pub fn is_empty(&self) -> bool {
        self.cache.is_empty()
    }

    pub fn peek(&self) -> Option<&T> {
        self.cache.last()
    }

    pub fn push(&mut self, elem: T) {
        self.ops.push(StackOp::Push(elem.clone()));
        self.cache.push(elem);
    }

    pub fn pop(&mut self) -> Option<T> {
        self.ops.push(StackOp::Pop);
        self.cache.pop()
    }

    pub fn clear(&mut self) {
        self.ops.push(StackOp::Clear);
        self.cache.clear();
    }

    pub fn snapshot(&mut self) {
        self.snapshots.push(self.ops.len());
    }

    pub fn backtrack(&mut self) {
        match self.snapshots.pop() {
            Some(index) => {
                self.ops.truncate(index);
                self.recache();
            }
            None => {}
        }
    }

    fn recache(&mut self) {
        self.cache.clear();
        for op in self.ops.iter() {
            match op {
                &StackOp::Push(ref elem) => {
                    self.cache.push(elem.clone());
                },
                &StackOp::Pop => {
                    self.cache.pop();
                },
                &StackOp::Clear => {
                    self.cache.clear();
                }
            }
        }
    }
}

#[derive(Debug)]
enum StackOp<T> {
    Push(T),
    Pop,
    Clear
}

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

    #[test]
    fn stack_ops() {
        let mut stack = Stack::new();

        // []
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // [0]
        stack.push(0);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 1]
        stack.push(1);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&1));

        // [0]
        assert_eq!(stack.pop(), Some(1));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 2]
        stack.push(2);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // [0, 2, 3]
        stack.push(3);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&3));

        // Take a snapshot of the current stack
        // [0, 2, 3]
        stack.snapshot();

        // [0, 2]
        assert_eq!(stack.pop(), Some(3));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // Take a snapshot of the current stack
        // [0, 2]
        stack.snapshot();

        // [0]
        assert_eq!(stack.pop(), Some(2));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // []
        assert_eq!(stack.pop(), Some(0));
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2]
        stack.backtrack();
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2, 3]
        stack.backtrack();
        assert_eq!(stack.pop(), Some(3));
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);
    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::ops::{ Range, Index };

/// Implementation of a `Stack` which maintains an log of `StackOp`s in order to rewind the stack
/// to a previous state.
#[derive(Debug)]
pub struct Stack<T: Clone> {
    ops: Vec<StackOp<T>>,
    cache: Vec<T>,
    snapshots: Vec<usize>
}

impl<T: Clone> Stack<T> {
    /// Creates a new `Stack`.
    pub fn new() -> Self {
        Stack {
            ops: vec![],
            cache: vec![],
            snapshots: vec![]
        }
    }

    /// Returns `true` if the stack is currently empty.
    #[allow(dead_code)]
    pub fn is_empty(&self) -> bool {
        self.cache.is_empty()
    }

    /// Returns the top-most `&T` in the `Stack`.
    pub fn peek(&self) -> Option<&T> {
        self.cache.last()
    }

    /// Pushes a `T` onto the `Stack`.
    pub fn push(&mut self, elem: T) {
        self.ops.push(StackOp::Push(elem.clone()));
        self.cache.push(elem);
    }

    /// Pops the top-most `T` from the `Stack`.
    pub fn pop(&mut self) -> Option<T> {
        let popped = self.cache.pop();
        if let Some(ref val) = popped {
            self.ops.push(StackOp::Pop(val.clone()));
        }
        popped
    }

    /// Returns the size of the stack
    pub fn len(&self) -> usize {
        self.cache.len()
    }

    /// Takes a snapshot of the current `Stack`.
    pub fn snapshot(&mut self) {
        self.snapshots.push(self.ops.len());
    }

    /// Rewinds the `Stack` to the most recent `snapshot()`. If no `snapshot()` has been taken, this
    /// function return the stack to its initial state.
    pub fn restore(&mut self) {
        match self.snapshots.pop() {
            Some(ops_index) => {
                self.rewind_to(ops_index);
                self.ops.truncate(ops_index);
            },
            None => {
                self.cache.clear();
                self.ops.clear();
            }
        }
    }

    // Rewind the stack to a particular index
    fn rewind_to(&mut self, index: usize) {
        let ops_to_rewind = &self.ops[index..];
        for op in ops_to_rewind.iter().rev() {
            match *op {
                StackOp::Push(_) => {
                    self.cache.pop();
                }
                StackOp::Pop(ref elem) => {
                    self.cache.push(elem.clone());
                }
            }
        }
    }
}

impl<T: Clone> Index<Range<usize>> for Stack<T> {
    type Output = [T];

    fn index(&self, range: Range<usize>) -> &[T] {
        self.cache.index(range)
    }
}

#[derive(Debug)]
enum StackOp<T> {
    Push(T),
    Pop(T)
}

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

    #[test]
    fn snapshot_with_empty() {
        let mut stack = Stack::new();

        stack.snapshot();
        // []
        assert!(stack.is_empty());
        // [0]
        stack.push(0);
        stack.restore();
        assert!(stack.is_empty());
    }

    #[test]
    fn snapshot_twice() {
        let mut stack = Stack::new();

        stack.push(0);

        stack.snapshot();
        stack.snapshot();
        stack.restore();
        stack.restore();

        assert_eq!(stack.iter().collect::<Vec<&i32>>(), vec![&0]);
    }

    #[test]
    fn stack_ops() {
        let mut stack = Stack::new();

        // []
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // [0]
        stack.push(0);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 1]
        stack.push(1);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&1));

        // [0]
        assert_eq!(stack.pop(), Some(1));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 2]
        stack.push(2);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // [0, 2, 3]
        stack.push(3);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&3));

        // Take a snapshot of the current stack
        // [0, 2, 3]
        stack.snapshot();

        // [0, 2]
        assert_eq!(stack.pop(), Some(3));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // Take a snapshot of the current stack
        // [0, 2]
        stack.snapshot();

        // [0]
        assert_eq!(stack.pop(), Some(2));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // []
        assert_eq!(stack.pop(), Some(0));
        assert!(stack.is_empty());

        // Test backtracking
        // [0, 2]
        stack.restore();
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2, 3]
        stack.restore();
        assert_eq!(stack.pop(), Some(3));
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);
    }
}
<commit_msg>Style<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::ops::{Range, Index};

/// Implementation of a `Stack` which maintains an log of `StackOp`s in order to rewind the stack
/// to a previous state.
#[derive(Debug)]
pub struct Stack<T: Clone> {
    ops: Vec<StackOp<T>>,
    cache: Vec<T>,
    snapshots: Vec<usize>
}

impl<T: Clone> Stack<T> {
    /// Creates a new `Stack`.
    pub fn new() -> Self {
        Stack {
            ops: vec![],
            cache: vec![],
            snapshots: vec![]
        }
    }

    /// Returns `true` if the stack is currently empty.
    #[allow(dead_code)]
    pub fn is_empty(&self) -> bool {
        self.cache.is_empty()
    }

    /// Returns the top-most `&T` in the `Stack`.
    pub fn peek(&self) -> Option<&T> {
        self.cache.last()
    }

    /// Pushes a `T` onto the `Stack`.
    pub fn push(&mut self, elem: T) {
        self.ops.push(StackOp::Push(elem.clone()));
        self.cache.push(elem);
    }

    /// Pops the top-most `T` from the `Stack`.
    pub fn pop(&mut self) -> Option<T> {
        let popped = self.cache.pop();
        if let Some(ref val) = popped {
            self.ops.push(StackOp::Pop(val.clone()));
        }
        popped
    }

    /// Returns the size of the stack
    pub fn len(&self) -> usize {
        self.cache.len()
    }

    /// Takes a snapshot of the current `Stack`.
    pub fn snapshot(&mut self) {
        self.snapshots.push(self.ops.len());
    }

    /// Rewinds the `Stack` to the most recent `snapshot()`. If no `snapshot()` has been taken, this
    /// function return the stack to its initial state.
    pub fn restore(&mut self) {
        match self.snapshots.pop() {
            Some(ops_index) => {
                self.rewind_to(ops_index);
                self.ops.truncate(ops_index);
            },
            None => {
                self.cache.clear();
                self.ops.clear();
            }
        }
    }

    // Rewind the stack to a particular index
    fn rewind_to(&mut self, index: usize) {
        let ops_to_rewind = &self.ops[index..];
        for op in ops_to_rewind.iter().rev() {
            match *op {
                StackOp::Push(_) => {
                    self.cache.pop();
                }
                StackOp::Pop(ref elem) => {
                    self.cache.push(elem.clone());
                }
            }
        }
    }
}

impl<T: Clone> Index<Range<usize>> for Stack<T> {
    type Output = [T];

    fn index(&self, range: Range<usize>) -> &[T] {
        self.cache.index(range)
    }
}

#[derive(Debug)]
enum StackOp<T> {
    Push(T),
    Pop(T)
}

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

    #[test]
    fn snapshot_with_empty() {
        let mut stack = Stack::new();

        stack.snapshot();
        // []
        assert!(stack.is_empty());
        // [0]
        stack.push(0);
        stack.restore();
        assert!(stack.is_empty());
    }

    #[test]
    fn snapshot_twice() {
        let mut stack = Stack::new();

        stack.push(0);

        stack.snapshot();
        stack.snapshot();
        stack.restore();
        stack.restore();

        assert_eq!(stack.iter().collect::<Vec<&i32>>(), vec![&0]);
    }

    #[test]
    fn stack_ops() {
        let mut stack = Stack::new();

        // []
        assert!(stack.is_empty());
        assert_eq!(stack.peek(), None);
        assert_eq!(stack.pop(), None);

        // [0]
        stack.push(0);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 1]
        stack.push(1);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&1));

        // [0]
        assert_eq!(stack.pop(), Some(1));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // [0, 2]
        stack.push(2);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // [0, 2, 3]
        stack.push(3);
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&3));

        // Take a snapshot of the current stack
        // [0, 2, 3]
        stack.snapshot();

        // [0, 2]
        assert_eq!(stack.pop(), Some(3));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&2));

        // Take a snapshot of the current stack
        // [0, 2]
        stack.snapshot();

        // [0]
        assert_eq!(stack.pop(), Some(2));
        assert!(!stack.is_empty());
        assert_eq!(stack.peek(), Some(&0));

        // []
        assert_eq!(stack.pop(), Some(0));
        assert!(stack.is_empty());

        // Test backtracking
        // [0, 2]
        stack.restore();
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);

        // Test backtracking
        // [0, 2, 3]
        stack.restore();
        assert_eq!(stack.pop(), Some(3));
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(0));
        assert_eq!(stack.pop(), None);
    }
}
<|endoftext|>


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

//! Logging wrapper to be used throughout all crates in the workspace
use std::ops::Deref;
use Mutex;

use backtrace::Backtrace;
use std::{panic, thread};

use types::{LogLevel, LoggingConfig};

use log::{LevelFilter, Record};
use log4rs;
use log4rs::append::console::ConsoleAppender;
use log4rs::append::file::FileAppender;
use log4rs::append::rolling_file::{
	policy::compound::roll::fixed_window::FixedWindowRoller,
	policy::compound::trigger::size::SizeTrigger, policy::compound::CompoundPolicy,
	RollingFileAppender,
};
use log4rs::append::Append;
use log4rs::config::{Appender, Config, Root};
use log4rs::encode::pattern::PatternEncoder;
use log4rs::filter::{threshold::ThresholdFilter, Filter, Response};

fn convert_log_level(in_level: &LogLevel) -> LevelFilter {
	match *in_level {
		LogLevel::Info => LevelFilter::Info,
		LogLevel::Warning => LevelFilter::Warn,
		LogLevel::Debug => LevelFilter::Debug,
		LogLevel::Trace => LevelFilter::Trace,
		LogLevel::Error => LevelFilter::Error,
	}
}

lazy_static! {
	/// Flag to observe whether logging was explicitly initialised (don't output otherwise)
	static ref WAS_INIT: Mutex<bool> = Mutex::new(false);
	/// Flag to observe whether tui is running, and we therefore don't want to attempt to write
	/// panics to stdout
	static ref TUI_RUNNING: Mutex<bool> = Mutex::new(false);
	/// Static Logging configuration, should only be set once, before first logging call
	static ref LOGGING_CONFIG: Mutex<LoggingConfig> = Mutex::new(LoggingConfig::default());
}

/// This filter is rejecting messages that doesn't start with "grin"
/// in order to save log space for only Grin-related records
#[derive(Debug)]
struct GrinFilter;

impl Filter for GrinFilter {
	fn filter(&self, record: &Record) -> Response {
		if let Some(module_path) = record.module_path() {
			if module_path.starts_with("grin") {
				return Response::Neutral;
			}
		}

		Response::Reject
	}
}

/// Initialize the logger with the given configuration
pub fn init_logger(config: Option<LoggingConfig>) {
	if let Some(c) = config {
		// Save current logging configuration
		let mut config_ref = LOGGING_CONFIG.lock();
		*config_ref = c.clone();

		let level_stdout = convert_log_level(&c.stdout_log_level);
		let level_file = convert_log_level(&c.file_log_level);
		let level_minimum;

		// Determine minimum logging level for Root logger
		if level_stdout > level_file {
			level_minimum = level_stdout;
		} else {
			level_minimum = level_file;
		}

		// Start logger
		let stdout = ConsoleAppender::builder()
			.encoder(Box::new(PatternEncoder::default()))
			.build();

		let mut root = Root::builder();

		let mut appenders = vec![];

		if c.log_to_stdout {
			let filter = Box::new(ThresholdFilter::new(level_stdout));
			appenders.push(
				Appender::builder()
					.filter(filter)
					.filter(Box::new(GrinFilter))
					.build("stdout", Box::new(stdout)),
			);

			root = root.appender("stdout");
		}

		if c.log_to_file {
			// If maximum log size is specified, use rolling file appender
			// or use basic one otherwise
			let filter = Box::new(ThresholdFilter::new(level_file));
			let file: Box<Append> = {
				if let Some(size) = c.log_max_size {
					let roller = FixedWindowRoller::builder()
						.build(&format!("{}.{{}}.gz", c.log_file_path), 32)
						.unwrap();
					let trigger = SizeTrigger::new(size);

					let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller));

					Box::new(
						RollingFileAppender::builder()
							.append(c.log_file_append)
							.encoder(Box::new(PatternEncoder::new("{d} {l} {M} - {m}{n}")))
							.build(c.log_file_path, Box::new(policy))
							.unwrap(),
					)
				} else {
					Box::new(
						FileAppender::builder()
							.append(c.log_file_append)
							.encoder(Box::new(PatternEncoder::new("{d} {l} {M} - {m}{n}")))
							.build(c.log_file_path)
							.unwrap(),
					)
				}
			};

			appenders.push(
				Appender::builder()
					.filter(filter)
					.filter(Box::new(GrinFilter))
					.build("file", file),
			);
			root = root.appender("file");
		}

		let config = Config::builder()
			.appenders(appenders)
			.build(root.build(level_minimum))
			.unwrap();

		let _ = log4rs::init_config(config).unwrap();

		info!(
			"log4rs is initialized, file level: {:?}, stdout level: {:?}, min. level: {:?}",
			level_file, level_stdout, level_minimum
		);

		// Mark logger as initialized
		let mut was_init_ref = WAS_INIT.lock();
		*was_init_ref = true;
	}

	send_panic_to_log();
}

/// Initializes the logger for unit and integration tests
pub fn init_test_logger() {
	let mut was_init_ref = WAS_INIT.lock();
	if *was_init_ref.deref() {
		return;
	}
	let mut logger = LoggingConfig::default();
	logger.log_to_file = false;
	logger.stdout_log_level = LogLevel::Debug;
	let mut config_ref = LOGGING_CONFIG.lock();
	*config_ref = logger;
	*was_init_ref = true;
}

/// hook to send panics to logs as well as stderr
fn send_panic_to_log() {
	panic::set_hook(Box::new(|info| {
		let backtrace = Backtrace::new();

		let thread = thread::current();
		let thread = thread.name().unwrap_or("unnamed");

		let msg = match info.payload().downcast_ref::<&'static str>() {
			Some(s) => *s,
			None => match info.payload().downcast_ref::<String>() {
				Some(s) => &**s,
				None => "Box<Any>",
			},
		};

		match info.location() {
			Some(location) => {
				error!(
					"\nthread '{}' panicked at '{}': {}:{}{:?}\n\n",
					thread,
					msg,
					location.file(),
					location.line(),
					backtrace
				);
			}
			None => error!("thread '{}' panicked at '{}'{:?}", thread, msg, backtrace),
		}
		//also print to stderr
		let tui_running = TUI_RUNNING.lock().clone();
		if !tui_running {
			let config = LOGGING_CONFIG.lock();

			eprintln!(
				"Thread '{}' panicked with message:\n\"{}\"\nSee {} for further details.",
				thread, msg, config.log_file_path
			);
		}
	}));
}
<commit_msg>Avoid stdout and panic logging when TUI is running (#1837)<commit_after>// Copyright 2018 The Grin Developers
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Logging wrapper to be used throughout all crates in the workspace
use std::ops::Deref;
use Mutex;

use backtrace::Backtrace;
use std::{panic, thread};

use types::{LogLevel, LoggingConfig};

use log::{LevelFilter, Record};
use log4rs;
use log4rs::append::console::ConsoleAppender;
use log4rs::append::file::FileAppender;
use log4rs::append::rolling_file::{
	policy::compound::roll::fixed_window::FixedWindowRoller,
	policy::compound::trigger::size::SizeTrigger, policy::compound::CompoundPolicy,
	RollingFileAppender,
};
use log4rs::append::Append;
use log4rs::config::{Appender, Config, Root};
use log4rs::encode::pattern::PatternEncoder;
use log4rs::filter::{threshold::ThresholdFilter, Filter, Response};

fn convert_log_level(in_level: &LogLevel) -> LevelFilter {
	match *in_level {
		LogLevel::Info => LevelFilter::Info,
		LogLevel::Warning => LevelFilter::Warn,
		LogLevel::Debug => LevelFilter::Debug,
		LogLevel::Trace => LevelFilter::Trace,
		LogLevel::Error => LevelFilter::Error,
	}
}

lazy_static! {
	/// Flag to observe whether logging was explicitly initialised (don't output otherwise)
	static ref WAS_INIT: Mutex<bool> = Mutex::new(false);
	/// Flag to observe whether tui is running, and we therefore don't want to attempt to write
	/// panics to stdout
	static ref TUI_RUNNING: Mutex<bool> = Mutex::new(false);
	/// Static Logging configuration, should only be set once, before first logging call
	static ref LOGGING_CONFIG: Mutex<LoggingConfig> = Mutex::new(LoggingConfig::default());
}

/// This filter is rejecting messages that doesn't start with "grin"
/// in order to save log space for only Grin-related records
#[derive(Debug)]
struct GrinFilter;

impl Filter for GrinFilter {
	fn filter(&self, record: &Record) -> Response {
		if let Some(module_path) = record.module_path() {
			if module_path.starts_with("grin") {
				return Response::Neutral;
			}
		}

		Response::Reject
	}
}

/// Initialize the logger with the given configuration
pub fn init_logger(config: Option<LoggingConfig>) {
	if let Some(c) = config {
		let tui_running = c.tui_running.unwrap_or(false);
		if tui_running {
			let mut tui_running_ref = TUI_RUNNING.lock();
			*tui_running_ref = true;
		}

		// Save current logging configuration
		let mut config_ref = LOGGING_CONFIG.lock();
		*config_ref = c.clone();

		let level_stdout = convert_log_level(&c.stdout_log_level);
		let level_file = convert_log_level(&c.file_log_level);
		let level_minimum;

		// Determine minimum logging level for Root logger
		if level_stdout > level_file {
			level_minimum = level_stdout;
		} else {
			level_minimum = level_file;
		}

		// Start logger
		let stdout = ConsoleAppender::builder()
			.encoder(Box::new(PatternEncoder::default()))
			.build();

		let mut root = Root::builder();

		let mut appenders = vec![];

		if c.log_to_stdout && !tui_running {
			let filter = Box::new(ThresholdFilter::new(level_stdout));
			appenders.push(
				Appender::builder()
					.filter(filter)
					.filter(Box::new(GrinFilter))
					.build("stdout", Box::new(stdout)),
			);

			root = root.appender("stdout");
		}

		if c.log_to_file {
			// If maximum log size is specified, use rolling file appender
			// or use basic one otherwise
			let filter = Box::new(ThresholdFilter::new(level_file));
			let file: Box<Append> = {
				if let Some(size) = c.log_max_size {
					let roller = FixedWindowRoller::builder()
						.build(&format!("{}.{{}}.gz", c.log_file_path), 32)
						.unwrap();
					let trigger = SizeTrigger::new(size);

					let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller));

					Box::new(
						RollingFileAppender::builder()
							.append(c.log_file_append)
							.encoder(Box::new(PatternEncoder::new("{d} {l} {M} - {m}{n}")))
							.build(c.log_file_path, Box::new(policy))
							.unwrap(),
					)
				} else {
					Box::new(
						FileAppender::builder()
							.append(c.log_file_append)
							.encoder(Box::new(PatternEncoder::new("{d} {l} {M} - {m}{n}")))
							.build(c.log_file_path)
							.unwrap(),
					)
				}
			};

			appenders.push(
				Appender::builder()
					.filter(filter)
					.filter(Box::new(GrinFilter))
					.build("file", file),
			);
			root = root.appender("file");
		}

		let config = Config::builder()
			.appenders(appenders)
			.build(root.build(level_minimum))
			.unwrap();

		let _ = log4rs::init_config(config).unwrap();

		info!(
			"log4rs is initialized, file level: {:?}, stdout level: {:?}, min. level: {:?}",
			level_file, level_stdout, level_minimum
		);

		// Mark logger as initialized
		let mut was_init_ref = WAS_INIT.lock();
		*was_init_ref = true;
	}

	send_panic_to_log();
}

/// Initializes the logger for unit and integration tests
pub fn init_test_logger() {
	let mut was_init_ref = WAS_INIT.lock();
	if *was_init_ref.deref() {
		return;
	}
	let mut logger = LoggingConfig::default();
	logger.log_to_file = false;
	logger.stdout_log_level = LogLevel::Debug;
	let mut config_ref = LOGGING_CONFIG.lock();
	*config_ref = logger;
	*was_init_ref = true;
}

/// hook to send panics to logs as well as stderr
fn send_panic_to_log() {
	panic::set_hook(Box::new(|info| {
		let backtrace = Backtrace::new();

		let thread = thread::current();
		let thread = thread.name().unwrap_or("unnamed");

		let msg = match info.payload().downcast_ref::<&'static str>() {
			Some(s) => *s,
			None => match info.payload().downcast_ref::<String>() {
				Some(s) => &**s,
				None => "Box<Any>",
			},
		};

		match info.location() {
			Some(location) => {
				error!(
					"\nthread '{}' panicked at '{}': {}:{}{:?}\n\n",
					thread,
					msg,
					location.file(),
					location.line(),
					backtrace
				);
			}
			None => error!("thread '{}' panicked at '{}'{:?}", thread, msg, backtrace),
		}
		//also print to stderr
		let tui_running = TUI_RUNNING.lock().clone();
		if !tui_running {
			let config = LOGGING_CONFIG.lock();

			eprintln!(
				"Thread '{}' panicked with message:\n\"{}\"\nSee {} for further details.",
				thread, msg, config.log_file_path
			);
		}
	}));
}
<|endoftext|>


<commit_before>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Request boundary validator

use std::mem;

pub fn is_valid(_buf: &[u8]) -> bool {
    true
}

pub fn extract_requests(buf: &[u8]) -> (Vec<String>, usize) {
    let utf8 = match String::from_utf8(buf.to_vec()) {
        Ok(val) => val,
        Err(_) => { return (Vec::new(), 0) }
    };

    let mut str_buf = String::new();
    let mut depth = 0;
    let mut res = Vec::new();
    let mut last_req = 0;
    let mut in_str = false;
    let mut is_escaped = false;

    for (idx, char) in utf8.char_indices() {
        str_buf.push(char);

        if (char == '{' || char == '[') && !in_str {
            depth += 1;
        }
        else if (char == '}' || char == ']') && !in_str {
            depth -= 1;
        }
        else if char == '"' && !is_escaped {
            in_str = !in_str;
        }
        else if char == '\\' && is_escaped && !in_str {
            is_escaped = !is_escaped;
        }

        if depth == 0 && str_buf.len() > 0 {
            res.push(mem::replace(&mut str_buf, String::new()));
            last_req = idx;
        }
    }

    (res, last_req)
}

#[test]
fn can_extract_request() {
    let buf = b"{ \"val\" : 1 } ffuuu";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"val\" : 1 }");
}

#[test]
fn can_extract_requests() {
    let buf = b"{ \"val\" : 1 }{ \"val2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"val\" : 1 }");
    assert_eq!(res.0[1], "{ \"val2\" : 2 }");
}

#[test]
fn can_extract_requests_with_slash() {
    let buf = b"{ \"va\\l\" : 1 }{ \"va\\l2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"va\\l\" : 1 }");
    assert_eq!(res.0[1], "{ \"va\\l2\" : 2 }");
}

#[test]
fn can_extract_requests_with_brackets() {
    let buf = b"[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]");
}

#[test]
fn can_extract_requests_with_braces() {
    let buf = b"{ \"va{l\" : 1 }{ \"va}l2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"va{l\" : 1 }");
    assert_eq!(res.0[1], "{ \"va}l2\" : 2 }");
}<commit_msg>vitro test<commit_after>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Request boundary validator

use std::mem;

pub fn is_valid(_buf: &[u8]) -> bool {
    true
}

pub fn extract_requests(buf: &[u8]) -> (Vec<String>, usize) {
    let utf8 = match String::from_utf8(buf.to_vec()) {
        Ok(val) => val,
        Err(_) => { return (Vec::new(), 0) }
    };

    let mut str_buf = String::new();
    let mut depth = 0;
    let mut res = Vec::new();
    let mut last_req = 0;
    let mut in_str = false;
    let mut is_escaped = false;

    for (idx, char) in utf8.char_indices() {
        str_buf.push(char);

        if (char == '{' || char == '[') && !in_str {
            depth += 1;
        }
        else if (char == '}' || char == ']') && !in_str {
            depth -= 1;
        }
        else if char == '"' && !is_escaped {
            in_str = !in_str;
        }
        else if char == '\\' && is_escaped && !in_str {
            is_escaped = !is_escaped;
        }

        if depth == 0 && str_buf.len() > 0 {
            res.push(mem::replace(&mut str_buf, String::new()));
            last_req = idx;
        }
    }

    (res, last_req)
}

#[test]
fn can_extract_request() {
    let buf = b"{ \"val\" : 1 } ffuuu";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"val\" : 1 }");
}

#[test]
fn can_extract_requests() {
    let buf = b"{ \"val\" : 1 }{ \"val2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"val\" : 1 }");
    assert_eq!(res.0[1], "{ \"val2\" : 2 }");
}

#[test]
fn can_extract_requests_with_slash() {
    let buf = b"{ \"va\\l\" : 1 }{ \"va\\l2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"va\\l\" : 1 }");
    assert_eq!(res.0[1], "{ \"va\\l2\" : 2 }");
}

#[test]
fn can_extract_requests_with_brackets() {
    let buf = b"[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "[{ \"val_s1\" : 10 }{ \"val_s2\" : 20 }]");
}

#[test]
fn can_extract_requests_with_braces() {
    let buf = b"{ \"va{l\" : 1 }{ \"va}l2\" : 2 }";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "{ \"va{l\" : 1 }");
    assert_eq!(res.0[1], "{ \"va}l2\" : 2 }");
}

#[test]
fn can_extract_vitro1() {
    let buf = b"[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}][{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]";
    let res = extract_requests(buf);
    assert_eq!(res.0[0], "[{\"jsonrpc\":\"2.0\",\"id\":\"3a3472c0-c7be-4070-a05c-8042c0a94892\",\"method\":\"eth_accounts\",\"params\":[]}]");
    assert_eq!(res.0[1], "[{\"jsonrpc\":\"2.0\",\"id\":\"a7329aff-888e-4aa7-a925-651c9545f356\",\"method\":\"net_peerCount\",\"params\":[]}]");
}<|endoftext|>


<commit_before>use game::{Game, View, ViewAction};
use game::data::Rectangle;
use game::gfx::{CopySprite, Sprite};
use sdl2::pixels::Color;
use sdl2::render::Renderer;
use conv::prelude::*;
use chrono::*;

const PLAYER_SPEED: f64 = 150.0;
const CHARACTER_W: f64 = 56.0;
const CHARACTER_H: f64 = 43.0;

const TERRAIN_W: f64 = 100.0;
const TERRAIN_H: f64 = 50.0;

const TILES_W: usize = 32;
const TILES_H: usize = 29;

#[derive(Clone)]
struct Background {
  pos: f64,
  sprite: Sprite,
}

impl Background {
  fn render(&mut self, renderer: &mut Renderer) {
    let size = self.sprite.size();

    let (window_w, window_h) = renderer.output_size().unwrap();
    let scale = window_h as f64 / size.1;
    renderer.copy_sprite(&self.sprite, Rectangle {
      x: 0.0,
      y: 0.0,
      w: size.0,
      h: window_h as f64,
    })
  }
}

#[derive(Clone, Copy)]
enum CharacterFrame {
  Down = 0,
  DownLeft = 1,
  Left = 2,
  UpLeft = 3,
  Up = 4,
  UpRight = 5,
  Right = 6,
  DownRight = 7
}

#[derive(Clone, Copy)]
enum TerrainFrame {
  Sand = 0,
  Grass = 1,
  Water = 2,
  Wood = 3,
}

struct Character {
  rect: Rectangle,
  sprites: Vec<Sprite>,
  current: CharacterFrame,
}

struct TerrainTile {
  rect: Rectangle,
  terrain_sprites: Vec<Sprite>,
  current: TerrainFrame,
}

pub struct GameView {
  player: Character,
  tiles: Vec<TerrainTile>,
  background: Background,
}

impl GameView {
  pub fn new(game: &mut Game) -> GameView {
    let spritesheet = Sprite::load(&mut game.renderer, "assets/warrior.png").unwrap();
    let terrain_spritesheet = Sprite::load(&mut game.renderer, "assets/terrain.png").unwrap();
    let mut sprites = Vec::with_capacity(9);
    let mut terrain_sprites = Vec::with_capacity(TILES_W);
    let mut tiles = Vec::with_capacity(TILES_W * TILES_H * 2);

    for x in 0..3 {
      terrain_sprites.push(terrain_spritesheet.region(Rectangle {
        w: TERRAIN_W,
        h: TERRAIN_H,
        x: TERRAIN_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..8 {
      sprites.push(spritesheet.region(Rectangle {
        w: CHARACTER_W,
        h: CHARACTER_H,
        x: CHARACTER_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let x2: f64 = 100.0 * 1.5 as f64;
        let y2: f64 = 50.0 * 1.5 as f64;
        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * x as f64,
            y: 50.0 * y as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Grass,
        });

        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * f64::value_from(x).unwrap() - x2 as f64,
            y: 50.0 * f64::value_from(y).unwrap() - y2 as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Sand,
        });
      }
    }

    GameView {
      player: Character {
        rect: Rectangle {
          x: 64.0,
          y: 64.0,
          w: CHARACTER_W,
          h: CHARACTER_H,
        },
        sprites: sprites.clone(),
        current: CharacterFrame::Down,
      },

      tiles: tiles,

      background: Background {
        pos: 0.0,
        sprite: Sprite::load(&mut game.renderer, "assets/background.png").unwrap(),
      },
    }
  }
}

impl View for GameView {
  fn render(&mut self, game: &mut Game, elapsed: f64) -> ViewAction {
    if game.events.now.quit || game.events.now.key_escape == Some(true) {
      return ViewAction::Quit;
    }

    let diagonal = (game.events.key_up ^ game.events.key_down) && (game.events.key_left ^ game.events.key_right);
    let moved = if diagonal { 1.0 / 2.0f64.sqrt() } else { 1.0 } * PLAYER_SPEED * elapsed;
    let dx = match (game.events.key_left, game.events.key_right) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    let dy = match (game.events.key_up, game.events.key_down) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    self.player.rect.x += dx;
    self.player.rect.y += dy;

    let movable_region = Rectangle {
      x: 0.0,
      y: 0.0,
      w: game.output_size().0 * 0.70,
      h: game.output_size().1,
    };

    self.player.rect = self.player.rect.move_inside(movable_region).unwrap();
    self.player.current =
    if dx == 0.0 && dy < 0.0       { CharacterFrame::Up }
    else if dx > 0.0 && dy < 0.0   { CharacterFrame::UpRight }
    else if dx < 0.0 && dy < 0.0   { CharacterFrame::UpLeft }
    else if dx == 0.0 && dy == 0.0 { CharacterFrame::Down }
    else if dx > 0.0 && dy == 0.0  { CharacterFrame::Right }
    else if dx < 0.0 && dy == 0.0  { CharacterFrame::Left }
    else if dx == 0.0 && dy > 0.0  { CharacterFrame::Down }
    else if dx > 0.0 && dy > 0.0   { CharacterFrame::DownRight }
    else if dx < 0.0 && dy > 0.0   { CharacterFrame::DownLeft }
    else { unreachable!() };

    game.renderer.set_draw_color(Color::RGBA(120, 120, 120, 0));
    game.renderer.clear();

    // background
    self.background.render(&mut game.renderer);

    // tile
    game.renderer.set_draw_color(Color::RGBA(255, 255, 255, 0));
    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let index = x * TILES_H + y;
        let local: DateTime<Local> = Local::now();
        println!("{} index {:?}", local, index);
        game.renderer.copy_sprite(&self.tiles[index].terrain_sprites[self.tiles[index].current as usize], self.tiles[index].rect);
      }
    }

    // player
    game.renderer.set_draw_color(Color::RGBA(119,119,119,0));
    game.renderer.copy_sprite(&self.player.sprites[self.player.current as usize], self.player.rect);

    ViewAction::None
  }
}
<commit_msg>Remove debug logging<commit_after>use game::{Game, View, ViewAction};
use game::data::Rectangle;
use game::gfx::{CopySprite, Sprite};
use sdl2::pixels::Color;
use sdl2::render::Renderer;
use conv::prelude::*;
use chrono::*;

const PLAYER_SPEED: f64 = 150.0;
const CHARACTER_W: f64 = 56.0;
const CHARACTER_H: f64 = 43.0;

const TERRAIN_W: f64 = 100.0;
const TERRAIN_H: f64 = 50.0;

const TILES_W: usize = 32;
const TILES_H: usize = 29;

#[derive(Clone)]
struct Background {
  pos: f64,
  sprite: Sprite,
}

impl Background {
  fn render(&mut self, renderer: &mut Renderer) {
    let size = self.sprite.size();

    let (window_w, window_h) = renderer.output_size().unwrap();
    let scale = window_h as f64 / size.1;
    renderer.copy_sprite(&self.sprite, Rectangle {
      x: 0.0,
      y: 0.0,
      w: size.0,
      h: window_h as f64,
    })
  }
}

#[derive(Clone, Copy)]
enum CharacterFrame {
  Down = 0,
  DownLeft = 1,
  Left = 2,
  UpLeft = 3,
  Up = 4,
  UpRight = 5,
  Right = 6,
  DownRight = 7
}

#[derive(Clone, Copy)]
enum TerrainFrame {
  Sand = 0,
  Grass = 1,
  Water = 2,
  Wood = 3,
}

struct Character {
  rect: Rectangle,
  sprites: Vec<Sprite>,
  current: CharacterFrame,
}

struct TerrainTile {
  rect: Rectangle,
  terrain_sprites: Vec<Sprite>,
  current: TerrainFrame,
}

pub struct GameView {
  player: Character,
  tiles: Vec<TerrainTile>,
  background: Background,
}

impl GameView {
  pub fn new(game: &mut Game) -> GameView {
    let spritesheet = Sprite::load(&mut game.renderer, "assets/warrior.png").unwrap();
    let terrain_spritesheet = Sprite::load(&mut game.renderer, "assets/terrain.png").unwrap();
    let mut sprites = Vec::with_capacity(9);
    let mut terrain_sprites = Vec::with_capacity(TILES_W);
    let mut tiles = Vec::with_capacity(TILES_W * TILES_H * 2);

    for x in 0..3 {
      terrain_sprites.push(terrain_spritesheet.region(Rectangle {
        w: TERRAIN_W,
        h: TERRAIN_H,
        x: TERRAIN_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..8 {
      sprites.push(spritesheet.region(Rectangle {
        w: CHARACTER_W,
        h: CHARACTER_H,
        x: CHARACTER_W * x as f64,
        y: 0.0 as f64,
      }).unwrap());
    }

    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let x2: f64 = 100.0 * 1.5 as f64;
        let y2: f64 = 50.0 * 1.5 as f64;
        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * x as f64,
            y: 50.0 * y as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Grass,
        });

        tiles.push(TerrainTile {
          rect: Rectangle {
            x: 100.0 * f64::value_from(x).unwrap() - x2 as f64,
            y: 50.0 * f64::value_from(y).unwrap() - y2 as f64,
            w: TERRAIN_W,
            h: TERRAIN_H,
          },
          terrain_sprites: terrain_sprites.clone(),
          current: TerrainFrame::Sand,
        });
      }
    }

    GameView {
      player: Character {
        rect: Rectangle {
          x: 64.0,
          y: 64.0,
          w: CHARACTER_W,
          h: CHARACTER_H,
        },
        sprites: sprites.clone(),
        current: CharacterFrame::Down,
      },

      tiles: tiles,

      background: Background {
        pos: 0.0,
        sprite: Sprite::load(&mut game.renderer, "assets/background.png").unwrap(),
      },
    }
  }
}

impl View for GameView {
  fn render(&mut self, game: &mut Game, elapsed: f64) -> ViewAction {
    if game.events.now.quit || game.events.now.key_escape == Some(true) {
      return ViewAction::Quit;
    }

    let diagonal = (game.events.key_up ^ game.events.key_down) && (game.events.key_left ^ game.events.key_right);
    let moved = if diagonal { 1.0 / 2.0f64.sqrt() } else { 1.0 } * PLAYER_SPEED * elapsed;
    let dx = match (game.events.key_left, game.events.key_right) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    let dy = match (game.events.key_up, game.events.key_down) {
      (true, true) | (false, false) => 0.0,
      (true, false) => -moved,
      (false, true) => moved,
    };

    self.player.rect.x += dx;
    self.player.rect.y += dy;

    let movable_region = Rectangle {
      x: 0.0,
      y: 0.0,
      w: game.output_size().0 * 0.70,
      h: game.output_size().1,
    };

    self.player.rect = self.player.rect.move_inside(movable_region).unwrap();
    self.player.current =
    if dx == 0.0 && dy < 0.0       { CharacterFrame::Up }
    else if dx > 0.0 && dy < 0.0   { CharacterFrame::UpRight }
    else if dx < 0.0 && dy < 0.0   { CharacterFrame::UpLeft }
    else if dx == 0.0 && dy == 0.0 { CharacterFrame::Down }
    else if dx > 0.0 && dy == 0.0  { CharacterFrame::Right }
    else if dx < 0.0 && dy == 0.0  { CharacterFrame::Left }
    else if dx == 0.0 && dy > 0.0  { CharacterFrame::Down }
    else if dx > 0.0 && dy > 0.0   { CharacterFrame::DownRight }
    else if dx < 0.0 && dy > 0.0   { CharacterFrame::DownLeft }
    else { unreachable!() };

    game.renderer.set_draw_color(Color::RGBA(120, 120, 120, 0));
    game.renderer.clear();

    // background
    self.background.render(&mut game.renderer);

    // tile
    game.renderer.set_draw_color(Color::RGBA(255, 255, 255, 0));
    for x in 0..TILES_W {
      for y in 0..TILES_H {
        let index = x * TILES_H + y;
        game.renderer.copy_sprite(&self.tiles[index].terrain_sprites[self.tiles[index].current as usize], self.tiles[index].rect);
      }
    }

    // player
    game.renderer.set_draw_color(Color::RGBA(119,119,119,0));
    game.renderer.copy_sprite(&self.player.sprites[self.player.current as usize], self.player.rect);

    ViewAction::None
  }
}
<|endoftext|>


<commit_before>//! Common HTTP functionality for the Teepee project.
//!
//! Anything shared between both client and server belongs in here, but this crate is not expected
//! to be used directly.
//!
//! Any crate using types from this crate should re‐export them. For example, the ``status`` module
//! should be exported in the root of the HTTP client crate ``httpc`` so that people can write
//! ``httpc::status`` instead of ``httpcommon::status``.

#![doc(html_logo_url = "http://teepee.rs/logo.100.png",
       html_root_url = "http://www.rust-ci.org/teepee/teepee/doc/")]

#![feature(slicing_syntax, unsafe_destructor, plugin, core, hash, std_misc)]

#![warn(non_upper_case_globals, unused_typecasts, missing_docs, unused_results)]
//#![warn(unstable)]

#[plugin] #[no_link]
extern crate phf_mac;
extern crate phf;

#[macro_use]
extern crate mucell;

#[macro_use]
extern crate mopa;

pub mod method;
pub mod status;
pub mod headers;
pub mod grammar;
<commit_msg>Fix an unstable warning in testing.<commit_after>//! Common HTTP functionality for the Teepee project.
//!
//! Anything shared between both client and server belongs in here, but this crate is not expected
//! to be used directly.
//!
//! Any crate using types from this crate should re‐export them. For example, the ``status`` module
//! should be exported in the root of the HTTP client crate ``httpc`` so that people can write
//! ``httpc::status`` instead of ``httpcommon::status``.

#![doc(html_logo_url = "http://teepee.rs/logo.100.png",
       html_root_url = "http://www.rust-ci.org/teepee/teepee/doc/")]

#![feature(slicing_syntax, unsafe_destructor, plugin, core, hash, std_misc)]
#![cfg_attr(test, feature(io))]

#![warn(non_upper_case_globals, unused_typecasts, missing_docs, unused_results)]

#[plugin] #[no_link]
extern crate phf_mac;
extern crate phf;

#[macro_use]
extern crate mucell;

#[macro_use]
extern crate mopa;

pub mod method;
pub mod status;
pub mod headers;
pub mod grammar;
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::slice;
use std::iter;

use htslib;

use bam::record;
use bam;

/// Iterator over alignments of a pileup.
pub type Alignments<'a> = iter::Map<
    slice::Iter<'a, htslib::bam_pileup1_t>,
    fn(&'a htslib::bam_pileup1_t) -> Alignment<'a>
>;

/// A pileup over one genomic position.
pub struct Pileup {
    inner: *const htslib::bam_pileup1_t,
    depth: u32,
    tid: u32,
    pos: u32,
}

impl Pileup {
    pub fn tid(&self) -> u32 {
        self.tid
    }

    pub fn pos(&self) -> u32 {
        self.pos
    }

    pub fn depth(&self) -> u32 {
        self.depth
    }

    pub fn alignments(&self) -> Alignments {
        self.inner().iter().map(Alignment::new)
    }

    fn inner(&self) -> &[htslib::bam_pileup1_t] {
        unsafe { slice::from_raw_parts(self.inner as *mut htslib::bam_pileup1_t, self.depth as usize) }
    }
}

/// An aligned read in a pileup.
pub struct Alignment<'a> {
    inner: &'a htslib::bam_pileup1_t,
}

impl<'a> Alignment<'a> {
    pub fn new(inner: &'a htslib::bam_pileup1_t) -> Self {
        Alignment { inner: inner }
    }

    /// Position within the read. None if either `is_del` or `is_refskip`.
    pub fn qpos(&self) -> Option<usize> {
        if self.is_del() || self.is_refskip() {
            // there is no alignment position in such a case
            None
        } else {
            Some(self.inner.qpos as usize)
        }
    }

    /// Insertion, deletion (with length) if indel starts at next base or None otherwise.
    pub fn indel(&self) -> Indel {
        match self.inner.indel {
            len if len < 0 => Indel::Del(-len as u32),
            len if len > 0 => Indel::Ins(len as u32),
            _              => Indel::None
        }
    }

    /// Whether there is a deletion in the alignment at this position.
    pub fn is_del(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b1) != 0
    }

    /// Whether the alignment starts at this position.
    pub fn is_head(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b10) != 0
    }

    /// Whether the alignment ends at this position.
    pub fn is_tail(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b100) != 0
    }

    /// Whether this position is marked as refskip in the CIGAR string.
    pub fn is_refskip(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b1000) != 0
    }

    /// The corresponding record.
    pub fn record(&self) -> record::Record {
        record::Record::from_inner(self.inner.b)
    }
}

#[derive(PartialEq)]
#[derive(Debug)]
pub enum Indel {
    Ins(u32),
    Del(u32),
    None
}

/// Iterator over pileups.
pub struct Pileups<'a, R: 'a + bam::Read> {
    reader: &'a R,
    itr: htslib::bam_plp_t,
}

impl<'a, R: bam::Read> Pileups<'a, R> {
    pub fn new(reader: &'a R, itr: htslib::bam_plp_t) -> Self {
        Pileups { reader: reader, itr: itr }
    }

    pub fn set_max_depth(&mut self, depth: u32) {
        unsafe { htslib::bam_plp_set_maxcnt(self.itr, depth as i32); }
    }
}

impl<'a, R: bam::Read> Iterator for Pileups<'a, R> {
    type Item = Result<Pileup, PileupError>;

    fn next(&mut self) -> Option<Result<Pileup, PileupError>> {
        let (mut tid, mut pos, mut depth) = (0i32, 0i32, 0i32);
        let inner = unsafe {
            htslib::bam_plp_auto(self.itr, &mut tid, &mut pos, &mut depth)
        };

        match inner.is_null() {
            true if depth == -1 => Some(Err(PileupError::Some)),
            true              => None,
            false             => Some(Ok(
                    Pileup {
                        inner: inner,
                        depth: depth as u32,
                        tid: tid as u32,
                        pos: pos as u32,
                    }
            ))
        }
    }
}

impl<'a, R: bam::Read> Drop for Pileups<'a, R> {
    fn drop(&mut self) {
        unsafe {
            htslib::bam_plp_reset(self.itr);
            htslib::bam_plp_destroy(self.itr);
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum PileupError {
        Some {
            description("error generating pileup")
        }
    }
}
<commit_msg>Minor.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::slice;
use std::iter;

use htslib;

use bam::record;
use bam;

/// Iterator over alignments of a pileup.
pub type Alignments<'a> = iter::Map<
    slice::Iter<'a, htslib::bam_pileup1_t>,
    fn(&'a htslib::bam_pileup1_t) -> Alignment<'a>
>;

/// A pileup over one genomic position.
pub struct Pileup {
    inner: *const htslib::bam_pileup1_t,
    depth: u32,
    tid: u32,
    pos: u32,
}

impl Pileup {
    pub fn tid(&self) -> u32 {
        self.tid
    }

    pub fn pos(&self) -> u32 {
        self.pos
    }

    pub fn depth(&self) -> u32 {
        self.depth
    }

    pub fn alignments(&self) -> Alignments {
        self.inner().iter().map(Alignment::new)
    }

    fn inner(&self) -> &[htslib::bam_pileup1_t] {
        unsafe { slice::from_raw_parts(self.inner as *mut htslib::bam_pileup1_t, self.depth as usize) }
    }
}

/// An aligned read in a pileup.
pub struct Alignment<'a> {
    inner: &'a htslib::bam_pileup1_t,
}

impl<'a> Alignment<'a> {
    pub fn new(inner: &'a htslib::bam_pileup1_t) -> Self {
        Alignment { inner: inner }
    }

    /// Position within the read. None if either `is_del` or `is_refskip`.
    pub fn qpos(&self) -> Option<usize> {
        if self.is_del() || self.is_refskip() {
            // there is no alignment position in such a case
            None
        } else {
            Some(self.inner.qpos as usize)
        }
    }

    /// Insertion, deletion (with length) if indel starts at next base or None otherwise.
    pub fn indel(&self) -> Indel {
        match self.inner.indel {
            len if len < 0 => Indel::Del(-len as u32),
            len if len > 0 => Indel::Ins(len as u32),
            _              => Indel::None
        }
    }

    /// Whether there is a deletion in the alignment at this position.
    pub fn is_del(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b1) != 0
    }

    /// Whether the alignment starts at this position.
    pub fn is_head(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b10) != 0
    }

    /// Whether the alignment ends at this position.
    pub fn is_tail(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b100) != 0
    }

    /// Whether this position is marked as refskip in the CIGAR string.
    pub fn is_refskip(&self) -> bool {
        (self.inner.isdel_ishead_istail_isrefskip_isaux & 0b1000) != 0
    }

    /// The corresponding record.
    pub fn record(&self) -> record::Record {
        record::Record::from_inner(self.inner.b)
    }
}

#[derive(PartialEq)]
#[derive(Debug)]
pub enum Indel {
    Ins(u32),
    Del(u32),
    None
}

/// Iterator over pileups.
pub struct Pileups<'a, R: 'a + bam::Read> {
    #[allow(dead_code)]
    reader: &'a R,
    itr: htslib::bam_plp_t,
}

impl<'a, R: bam::Read> Pileups<'a, R> {
    pub fn new(reader: &'a R, itr: htslib::bam_plp_t) -> Self {
        Pileups { reader: reader, itr: itr }
    }

    pub fn set_max_depth(&mut self, depth: u32) {
        unsafe { htslib::bam_plp_set_maxcnt(self.itr, depth as i32); }
    }
}

impl<'a, R: bam::Read> Iterator for Pileups<'a, R> {
    type Item = Result<Pileup, PileupError>;

    fn next(&mut self) -> Option<Result<Pileup, PileupError>> {
        let (mut tid, mut pos, mut depth) = (0i32, 0i32, 0i32);
        let inner = unsafe {
            htslib::bam_plp_auto(self.itr, &mut tid, &mut pos, &mut depth)
        };

        match inner.is_null() {
            true if depth == -1 => Some(Err(PileupError::Some)),
            true              => None,
            false             => Some(Ok(
                    Pileup {
                        inner: inner,
                        depth: depth as u32,
                        tid: tid as u32,
                        pos: pos as u32,
                    }
            ))
        }
    }
}

impl<'a, R: bam::Read> Drop for Pileups<'a, R> {
    fn drop(&mut self) {
        unsafe {
            htslib::bam_plp_reset(self.itr);
            htslib::bam_plp_destroy(self.itr);
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum PileupError {
        Some {
            description("error generating pileup")
        }
    }
}
<|endoftext|>


<commit_before>use memory;

pub struct Cpu {
    pub memory: memory::Memory,
    a: u8,
    f: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    h: u8,
    l: u8,
    pc: u16,
    sp: u16,
    cycles: uint
}

impl Cpu {
    pub fn new(memory: memory::Memory) -> Cpu {
        Cpu {
            memory: memory,
            a: 0x01,
            f: 0xB0,
            b: 0x00,
            c: 0x13,
            d: 0x00,
            e: 0xD8,
            h: 0x01,
            l: 0x4D,
            pc: 0x0100,
            sp: 0xFFFE,
            cycles: 0
        }
    }

    pub fn step(&mut self) {
        let opcode = self.read_next_byte();

        println!("Executing: {:#04X}", opcode);

        match opcode {
            0x00 => {
                self.cycles += 4;
            },
            0x3E => {
                self.a = self.read_next_byte();
                self.cycles += 8;
                println!("  a: {:#04X}", self.a);
            },
            0xC3 => {
                self.pc = self.read_next_word();
                self.cycles += 16;
                println!("  address: {:#06X}", self.pc);
            },
            0xE0 => {
                let addr = 0xFF00 + self.read_next_byte() as u16;
                self.memory.write_byte(addr, self.a);
                self.cycles += 12;
                println!("  memory[{:#06X}] = A ({:#04X})", addr, self.a);
            },
            0xF3 => {
                println!("  implement interrupts stuff...");
            },
            _ => fail!("Opcode not implemented: {:#04X}", opcode)
        }
    }

    fn read_next_byte(&mut self) -> u8 {
        let value = self.memory.read_byte(self.pc);
        self.pc += 1;
        value
    }

    fn read_next_word(&mut self) -> u16 {
        let value = self.memory.read_word(self.pc);
        self.pc += 2;
        value
    }

    pub fn run(&mut self) {
        loop {
            self.step();
        }
    }
}
<commit_msg>Add incomplete CPU cycles table<commit_after>use memory;

pub struct Cpu {
    pub memory: memory::Memory,
    a: u8,
    f: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    h: u8,
    l: u8,
    pc: u16,
    sp: u16,
    cycles: uint
}

static CPU_CYCLES: [uint, ..256] = [
//  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, // 0x30
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xA0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xB0
    0, 0, 0,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xC0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xD0
   12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xE0
    0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xF0
];

impl Cpu {
    pub fn new(memory: memory::Memory) -> Cpu {
        Cpu {
            memory: memory,
            a: 0x01,
            f: 0xB0,
            b: 0x00,
            c: 0x13,
            d: 0x00,
            e: 0xD8,
            h: 0x01,
            l: 0x4D,
            pc: 0x0100,
            sp: 0xFFFE,
            cycles: 0
        }
    }

    pub fn step(&mut self) {
        let opcode = self.read_next_byte();

        println!("Executing: {:#04X}", opcode);

        match opcode {
            0x00 => {},
            0x3E => {
                self.a = self.read_next_byte();
                println!("  a: {:#04X}", self.a);
            },
            0xC3 => {
                self.pc = self.read_next_word();
                println!("  address: {:#06X}", self.pc);
            },
            0xE0 => {
                let addr = 0xFF00 + self.read_next_byte() as u16;
                self.memory.write_byte(addr, self.a);
                println!("  memory[{:#06X}] = A ({:#04X})", addr, self.a);
            },
            0xF3 => {
                println!("  implement interrupts stuff...");
            },
            _ => fail!("Opcode not implemented: {:#04X}", opcode)
        }

        self.cycles += CPU_CYCLES[opcode as uint];
        println!("  cycles: {}", self.cycles);
    }

    fn read_next_byte(&mut self) -> u8 {
        let value = self.memory.read_byte(self.pc);
        self.pc += 1;
        value
    }

    fn read_next_word(&mut self) -> u16 {
        let value = self.memory.read_word(self.pc);
        self.pc += 2;
        value
    }

    pub fn run(&mut self) {
        loop {
            self.step();
        }
    }
}
<|endoftext|>


<commit_before>#![feature(convert)] // for convert::AsRef<path::Path> used in config.rs
#![deny(missing_docs)]
//! Fern is a runtime-configurable rust logging library.
//!
//! Current features:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - output to any combination of:
//!   - log files
//!   - stdout or stderr
//!   - your own custom implementation
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console.
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them.
//! - Acts as a backend to the `log` crate - use `trace!()` through `error!()` to log to the global
//!   fern logger.
//!   - Note that fern can also have loggers separate from the global system. You can always set
//!     your main logger as the global logger, then use other fern loggers manually.
//!
//! Although mostly stabilized, fern is still in development. The library is subject to
//! change in non-backwards-compatible ways before the API is completely stabilized.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Upgrade note for fern `0.2.*`
//! ====
//!
//! As of fern 0.2.0, fern depends on the `log` crate to provide the frontend logging macros and
//! logging levels - you will need to depend on and use both the `fern` and `log` crates.
//!
//!
//! Adding fern as a dependency
//! ===========================
//!
//! In order to use fern, the first thing you'll need to add both the `fern` crate and the `log`
//! crate to the dependencies in your project's `Cargo.toml` file:
//!
//! ```toml
//! # ...
//!
//! [dependencies]
//! # ...
//! log = "0.2.*"
//! fern = "0.2.*"
//!
//! # ...
//! ```
//!
//! After this, you'll need to declare the `log` and `fern` to the top of your main.rs or lib.rs
//! file:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//! # fn main() {}
//! ```
//!
//! Examples
//! ========
//!
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! extern crate chrono;
//! use std::path::PathBuf;
//!
//! let logger_config = fern::DispatchConfig {
//!     format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
//!         // This is a fairly simple format, though it's possible to do more complicated ones
//!         format!("[{}][{}] {}", chrono::Local::now().format("%Y-%m-%d][%H:%M:%S"), level, msg)
//!     }),
//!     output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
//!     level: log::LogLevelFilter::Debug,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the logging level.
//!
//! Side note: `chrono::Local::now().format("%Y-%m-%d][%H:%M:%S")` is a usage of the chrono time
//! library, and just returns the date in the format described. An output of this looks something
//! like `2015-03-07][12:55:04`.
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2015-03-07][12:55:04][INFO] A message logged at the Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! messages to stdout (the console), and the file "output.log".
//!
//! `level:` is a `log::LogLevelFilter` which describes the minimum level that should be allowed to pass
//! through this logger. Setting this to `Level::Debug` allows all messages to be logged, as Debug
//! is the lowest logging level.
//!
//! After creating your logging config, you can pass it to `init_global_logger` to set it as the
//! logger used with logging macros in the `log` crate. This function can only be called once, as
//! the log crate may only be set up once.
//!
//! Note that this function also accepts a `LogLevelFilter`. This is so that you can set a global
//! minimum log level separate from the logger configuration. If you don't have any reason for
//! anything else, just set this to `log::LogLevelFilter::Trace`.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! # let logger_config = fern::DispatchConfig {
//! #     format: Box::new(|msg: &str, _level: &log::LogLevel, _location: &log::LogLocation| {
//! #         format!("{}", msg)
//! #     }),
//! #     output: vec![],
//! #     level: log::LogLevelFilter::Debug,
//! # };
//! if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
//!     panic!("Failed to initialize global logger: {}", e);
//! }
//! ```
//!
//! This uses the `if let Err(e) =` syntax to catch any errors that happen when initializing
//! the logger.
//!
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above
//! tutorial paired with the fern docs should be enough to get you started on configuring a logger
//! for your project.
//!
//! #### Logging
//!
//! With the `log` crate, outputting messages is fairly simple. As long as you are using the log
//! crate with `#[macro_use]`, and you have initialized the global logger as shown above, you can
//! use the log macros to log messages.
//!
//! ```rust
//! // You need to have #[macro_use] to use log macros
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//!
//! # fn main() {
//! # /*
//! fern::init_global_logger(...);
//! # */
//! # fern::init_global_logger(fern::OutputConfig::null(), log::LogLevelFilter::Trace);
//!
//! trace!("Trace message");
//! debug!("Debug message");
//! info!("Info message");
//! warn!("Warning message");
//! error!("Error message");
//! # }
//! ```

extern crate log;

pub use errors::{LogError, InitError};
pub use api::Logger;
pub use config::{DispatchConfig, OutputConfig, IntoLog, init_global_logger};
pub use loggers::NullLogger;

mod api;
mod config;
mod loggers;
mod errors;
<commit_msg>Fix small typo in documentation<commit_after>#![feature(convert)] // for convert::AsRef<path::Path> used in config.rs
#![deny(missing_docs)]
//! Fern is a runtime-configurable rust logging library.
//!
//! Current features:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - output to any combination of:
//!   - log files
//!   - stdout or stderr
//!   - your own custom implementation
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console.
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them.
//! - Acts as a backend to the `log` crate - use `trace!()` through `error!()` to log to the global
//!   fern logger.
//!   - Note that fern can also have loggers separate from the global system. You can always set
//!     your main logger as the global logger, then use other fern loggers manually.
//!
//! Although mostly stabilized, fern is still in development. The library is subject to
//! change in non-backwards-compatible ways before the API is completely stabilized.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Upgrade note for fern `0.2.*`
//! ====
//!
//! As of fern 0.2.0, fern depends on the `log` crate to provide the frontend logging macros and
//! logging levels - you will need to depend on and use both the `fern` and `log` crates.
//!
//!
//! Adding fern as a dependency
//! ===========================
//!
//! In order to use fern, the first thing you'll need to add both the `fern` crate and the `log`
//! crate to the dependencies in your project's `Cargo.toml` file:
//!
//! ```toml
//! # ...
//!
//! [dependencies]
//! # ...
//! log = "0.2.*"
//! fern = "0.2.*"
//!
//! # ...
//! ```
//!
//! After this, you'll need to declare the `log` and `fern` at the top of your main.rs or lib.rs
//! file:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//! # fn main() {}
//! ```
//!
//! Examples
//! ========
//!
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! extern crate chrono;
//! use std::path::PathBuf;
//!
//! let logger_config = fern::DispatchConfig {
//!     format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
//!         // This is a fairly simple format, though it's possible to do more complicated ones
//!         format!("[{}][{}] {}", chrono::Local::now().format("%Y-%m-%d][%H:%M:%S"), level, msg)
//!     }),
//!     output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
//!     level: log::LogLevelFilter::Debug,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the logging level.
//!
//! Side note: `chrono::Local::now().format("%Y-%m-%d][%H:%M:%S")` is a usage of the chrono time
//! library, and just returns the date in the format described. An output of this looks something
//! like `2015-03-07][12:55:04`.
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2015-03-07][12:55:04][INFO] A message logged at the Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! messages to stdout (the console), and the file "output.log".
//!
//! `level:` is a `log::LogLevelFilter` which describes the minimum level that should be allowed to pass
//! through this logger. Setting this to `Level::Debug` allows all messages to be logged, as Debug
//! is the lowest logging level.
//!
//! After creating your logging config, you can pass it to `init_global_logger` to set it as the
//! logger used with logging macros in the `log` crate. This function can only be called once, as
//! the log crate may only be set up once.
//!
//! Note that this function also accepts a `LogLevelFilter`. This is so that you can set a global
//! minimum log level separate from the logger configuration. If you don't have any reason for
//! anything else, just set this to `log::LogLevelFilter::Trace`.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! # let logger_config = fern::DispatchConfig {
//! #     format: Box::new(|msg: &str, _level: &log::LogLevel, _location: &log::LogLocation| {
//! #         format!("{}", msg)
//! #     }),
//! #     output: vec![],
//! #     level: log::LogLevelFilter::Debug,
//! # };
//! if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
//!     panic!("Failed to initialize global logger: {}", e);
//! }
//! ```
//!
//! This uses the `if let Err(e) =` syntax to catch any errors that happen when initializing
//! the logger.
//!
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above
//! tutorial paired with the fern docs should be enough to get you started on configuring a logger
//! for your project.
//!
//! #### Logging
//!
//! With the `log` crate, outputting messages is fairly simple. As long as you are using the log
//! crate with `#[macro_use]`, and you have initialized the global logger as shown above, you can
//! use the log macros to log messages.
//!
//! ```rust
//! // You need to have #[macro_use] to use log macros
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//!
//! # fn main() {
//! # /*
//! fern::init_global_logger(...);
//! # */
//! # fern::init_global_logger(fern::OutputConfig::null(), log::LogLevelFilter::Trace);
//!
//! trace!("Trace message");
//! debug!("Debug message");
//! info!("Info message");
//! warn!("Warning message");
//! error!("Error message");
//! # }
//! ```

extern crate log;

pub use errors::{LogError, InitError};
pub use api::Logger;
pub use config::{DispatchConfig, OutputConfig, IntoLog, init_global_logger};
pub use loggers::NullLogger;

mod api;
mod config;
mod loggers;
mod errors;
<|endoftext|>


<commit_before>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;

use std::fs;
use std::path::Path;

mod schema;
pub use schema::Spec;

pub mod errors {
    error_chain!{
        foreign_links {
            Io(::std::io::Error);
            Yaml(::serde_yaml::Error);
            Serialize(::serde_json::Error);
        }
    }
}

pub fn from_path<P>(path: P) -> errors::Result<Spec>
where
    P: AsRef<Path>,
{
    Ok(serde_yaml::from_reader::<_, Spec>(fs::File::open(path)?)?)
}

pub fn to_yaml(spec: &Spec) -> errors::Result<String> {
    Ok(serde_yaml::to_string(spec)?)
}

pub fn to_json(spec: &Spec) -> errors::Result<String> {
    Ok(serde_json::to_string_pretty(spec)?)
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>more flexible<commit_after>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;

use std::fs;
use std::io::Read;
use std::path::Path;

mod schema;
pub use schema::Spec;

pub mod errors {
    error_chain!{
        foreign_links {
            Io(::std::io::Error);
            Yaml(::serde_yaml::Error);
            Serialize(::serde_json::Error);
        }
    }
}

/// deserialize an open api spec from a path
pub fn from_path<P>(path: P) -> errors::Result<Spec>
where
    P: AsRef<Path>,
{
    from_reader(fs::File::open(path)?)
}

/// deserialize an open api spec from type which implements Read
pub fn from_reader<R>(read: R) -> errors::Result<Spec>
where
    R: Read,
{
    Ok(serde_yaml::from_reader::<R, Spec>(read)?)
}

/// serialize to a yaml string
pub fn to_yaml(spec: &Spec) -> errors::Result<String> {
    Ok(serde_yaml::to_string(spec)?)
}

/// serialize to a json string
pub fn to_json(spec: &Spec) -> errors::Result<String> {
    Ok(serde_json::to_string_pretty(spec)?)
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>