<commit_before>//! Assorted types that can contain multiple widgets.
//!
//! All container types can be nested.
//!
//! Use the `children!{}` macro in this crate to convert a heterogeneous list of widgets into a
//! `Vec<BaseWidget>` for the container constructors.

use base::BaseWidget;
use widget_prelude::*;

/// Vertical alignment setting, used by `Horizontal` and `Grid`.
#[derive(Copy, Clone)]
pub enum VAlign {
    Top,
    Center,
    Bottom,
}

impl VAlign {
    fn as_cstr(self) -> &'static str {
        use self::VAlign::*;

        match self {
            Top => cstr!("ATOP"),
            Center => cstr!("ACENTER"),
            Bottom => cstr!("ABOTTOM"),
        }
    }
}

/// Horizontal alignment setting, used by `Vertical` and `Grid`.
#[derive(Copy, Clone)]
pub enum HAlign {
    Left,
    Center,
    Right,
}

impl HAlign {
    fn as_cstr(self) -> &'static str {
        use self::HAlign::*;

        match self {
            Left => cstr!("ALEFT"),
            Center => cstr!("ACENTER"),
            Right => cstr!("ARIGHT"),
        }
    }
}

/// The behavior of this enum depends on its point of use.
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum Orientation {
    Vertical,
    Horizontal,
}

impl Orientation {
    #[doc(hidden)]
    pub fn as_cstr(self) -> &'static str {
        use self::Orientation::*;

        match self {
            Vertical => cstr!("VERTICAL"),
            Horizontal => cstr!("HORIZONTAL"),
        }
    }
}

fn raw_handle_vec(widgets: B) -> Vec<IUPPtr> where B: AsRef<[BaseWidget]> {
    let mut raw_handles: Vec<_> = widgets.as_ref().iter().cloned().map(BaseWidget::ptr).collect();
    raw_handles.push(::std::ptr::null_mut());
    raw_handles
}

/// A builder for `Absolute`, used to create and add children.
pub struct AbsoluteBuilder {
    handles: Vec<IUPPtr>,
}

impl AbsoluteBuilder {
    fn new() -> AbsoluteBuilder {
        AbsoluteBuilder { handles: Vec::new() }
    }

    /// Add a child to the `Absolute` at the given coordinates, relative to the top-left corner of
    /// the container.
    pub fn add_child_at<W: Widget>(&mut self, x: u32, y: u32, child: W) -> &mut Self {
        Absolute::set_child_pos(x, y, child);
        self.handles.push(child.ptr());
        self
    }
}

/// A container type that makes no effort to arrange its children. Instead, they must be positioned
/// manually.
pub struct Absolute(IUPPtr);

impl Absolute {
    /// Create a new absolute container using the given closure, which will be passed a mutable builder
    /// instance.
    ///
    /// The builder is necessary to ensure that the children have their positions set correctly, as
    /// `Widget::set_position` will not set the attributes that this particular container is
    /// expecting.
    pub fn new<F>(build_fn: F) -> Absolute where F: FnOnce(&mut AbsoluteBuilder) {
        let mut builder = AbsoluteBuilder::new();
        build_fn(&mut builder);

        unsafe {
            let ptr = ::iup_sys::IupCboxv(builder.handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    /// Set the position of a child of an `Absolute` relative to its top-left corner.
    pub fn set_child_pos<W: Widget>(x: u32, y: u32, child: W) {
        child.set_int_attribute(::attrs::CX, x as i32);
        child.set_int_attribute(::attrs::CY, y as i32);
    }
}

impl_widget! { Absolute, "cbox" }

/// A container widget that lines up its children from left to right.
pub struct Horizontal(IUPPtr);

impl Horizontal {
    /// Create a new horizontal container with the given vector or array of children, which may
    /// also be empty.
    ///
    /// See the `children![]` macro in this crate for more info.
    pub fn new<C>(children: C) -> Horizontal where C: AsRef<[BaseWidget]> {
        let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupHboxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    pub fn set_valign(self, valign: VAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_VERT, valign.as_cstr());
        self
    }

    pub fn set_elem_spacing_pixels(self, spacing: u32) -> Self {
        self.set_str_attribute(::attrs::GAP, spacing.to_string());
        self
    }
}

impl_widget! { Horizontal, "hbox" }

/// A container widget that lines up its children from top to bottom.
pub struct Vertical(IUPPtr);

impl Vertical {
    pub fn new<C>(children: C) -> Vertical where C: AsRef<[BaseWidget]> {
       let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupVboxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    pub fn set_halign(self, halign: HAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_HORI, halign.as_cstr());
        self
    }

    pub fn set_elem_spacing_pixels(self, spacing: u32) -> Self {
        self.set_str_attribute(::attrs::GAP, spacing.to_string());
        self
    }
}

impl_widget! { Vertical, "vbox" }

/// A container widget that lines up its children from left to right, and from top to bottom.
pub struct Grid(IUPPtr);

impl Grid {
    pub fn new<C>(children: C) -> Grid where C: AsRef<[BaseWidget]> {
       let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupGridBoxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }
    pub fn set_valign(self, valign: VAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_VERT, valign.as_cstr());
        self
    }

    pub fn set_halign(self, halign: HAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_HORI, halign.as_cstr());
        self
    }

    /// Based on the orientation, set the number of children to place in a:
    ///
    /// * `Vertial`: **column**
    /// * `Horizontal`: **row**
    ///
    /// before beginning the next one.
    pub fn set_ndiv(self, ndiv: u32) -> Self {
        self.set_int_attribute(::attrs::NUMDIV, ndiv as i32);
        self
    }

    /// Sets how children are distributed in the container.
    ///
    /// * `Vertical`: The container will fill columns first.
    ///
    /// Visual example (`ndiv=3` grid with 7 children):
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///

    ///

    ///
    /// * `Horizontal`: The container will fill rows first. **Default.**
    ///
    /// Visual example (`ndiv=3` grid with 7 children):
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///

    ///

    ///
    pub fn set_orientation(&mut self, orientation: Orientation) -> &mut Self {
        self.set_const_str_attribute(::attrs::ORIENTATION, orientation.as_cstr());
        self
    }
}

impl_widget! { Grid, "matrix" }

/// Convert a heterogeneous list of widgets into a `Vec<BaseWidget>`,
/// suitable for passing to any function that takes `AsRef<[BaseWidget]>`, such as a constructor
/// for one of the container types.
#[macro_export]
macro_rules! children [
    // Accepts invocation with or without a final comma.
    ($($child:expr),+,) => (children![$($child),+]);
    ($($child:expr),+) => ({
        use ::kiss_ui::widget::Widget;
        vec![$($child.to_base()),+]
    });
    () => (vec![]);
];
<commit_msg>Typo fix<commit_after>//! Assorted types that can contain multiple widgets.
//!
//! All container types can be nested.
//!
//! Use the `children!{}` macro in this crate to convert a heterogeneous list of widgets into a
//! `Vec<BaseWidget>` for the container constructors.

use base::BaseWidget;
use widget_prelude::*;

/// Vertical alignment setting, used by `Horizontal` and `Grid`.
#[derive(Copy, Clone)]
pub enum VAlign {
    Top,
    Center,
    Bottom,
}

impl VAlign {
    fn as_cstr(self) -> &'static str {
        use self::VAlign::*;

        match self {
            Top => cstr!("ATOP"),
            Center => cstr!("ACENTER"),
            Bottom => cstr!("ABOTTOM"),
        }
    }
}

/// Horizontal alignment setting, used by `Vertical` and `Grid`.
#[derive(Copy, Clone)]
pub enum HAlign {
    Left,
    Center,
    Right,
}

impl HAlign {
    fn as_cstr(self) -> &'static str {
        use self::HAlign::*;

        match self {
            Left => cstr!("ALEFT"),
            Center => cstr!("ACENTER"),
            Right => cstr!("ARIGHT"),
        }
    }
}

/// The behavior of this enum depends on its point of use.
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum Orientation {
    Vertical,
    Horizontal,
}

impl Orientation {
    #[doc(hidden)]
    pub fn as_cstr(self) -> &'static str {
        use self::Orientation::*;

        match self {
            Vertical => cstr!("VERTICAL"),
            Horizontal => cstr!("HORIZONTAL"),
        }
    }
}

fn raw_handle_vec(widgets: B) -> Vec<IUPPtr> where B: AsRef<[BaseWidget]> {
    let mut raw_handles: Vec<_> = widgets.as_ref().iter().cloned().map(BaseWidget::ptr).collect();
    raw_handles.push(::std::ptr::null_mut());
    raw_handles
}

/// A builder for `Absolute`, used to create and add children.
pub struct AbsoluteBuilder {
    handles: Vec<IUPPtr>,
}

impl AbsoluteBuilder {
    fn new() -> AbsoluteBuilder {
        AbsoluteBuilder { handles: Vec::new() }
    }

    /// Add a child to the `Absolute` at the given coordinates, relative to the top-left corner of
    /// the container.
    pub fn add_child_at<W: Widget>(&mut self, x: u32, y: u32, child: W) -> &mut Self {
        Absolute::set_child_pos(x, y, child);
        self.handles.push(child.ptr());
        self
    }
}

/// A container type that makes no effort to arrange its children. Instead, they must be positioned
/// manually.
pub struct Absolute(IUPPtr);

impl Absolute {
    /// Create a new absolute container using the given closure, which will be passed a mutable builder
    /// instance.
    ///
    /// The builder is necessary to ensure that the children have their positions set correctly, as
    /// `Widget::set_position` will not set the attributes that this particular container is
    /// expecting.
    pub fn new<F>(build_fn: F) -> Absolute where F: FnOnce(&mut AbsoluteBuilder) {
        let mut builder = AbsoluteBuilder::new();
        build_fn(&mut builder);

        unsafe {
            let ptr = ::iup_sys::IupCboxv(builder.handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    /// Set the position of a child of an `Absolute` relative to its top-left corner.
    pub fn set_child_pos<W: Widget>(x: u32, y: u32, child: W) {
        child.set_int_attribute(::attrs::CX, x as i32);
        child.set_int_attribute(::attrs::CY, y as i32);
    }
}

impl_widget! { Absolute, "cbox" }

/// A container widget that lines up its children from left to right.
pub struct Horizontal(IUPPtr);

impl Horizontal {
    /// Create a new horizontal container with the given vector or array of children, which may
    /// also be empty.
    ///
    /// See the `children![]` macro in this crate for more info.
    pub fn new<C>(children: C) -> Horizontal where C: AsRef<[BaseWidget]> {
        let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupHboxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    pub fn set_valign(self, valign: VAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_VERT, valign.as_cstr());
        self
    }

    pub fn set_elem_spacing_pixels(self, spacing: u32) -> Self {
        self.set_str_attribute(::attrs::GAP, spacing.to_string());
        self
    }
}

impl_widget! { Horizontal, "hbox" }

/// A container widget that lines up its children from top to bottom.
pub struct Vertical(IUPPtr);

impl Vertical {
    pub fn new<C>(children: C) -> Vertical where C: AsRef<[BaseWidget]> {
       let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupVboxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }

    pub fn set_halign(self, halign: HAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_HORI, halign.as_cstr());
        self
    }

    pub fn set_elem_spacing_pixels(self, spacing: u32) -> Self {
        self.set_str_attribute(::attrs::GAP, spacing.to_string());
        self
    }
}

impl_widget! { Vertical, "vbox" }

/// A container widget that lines up its children from left to right, and from top to bottom.
pub struct Grid(IUPPtr);

impl Grid {
    pub fn new<C>(children: C) -> Grid where C: AsRef<[BaseWidget]> {
       let mut raw_handles = raw_handle_vec(children);

        unsafe {
            let ptr = ::iup_sys::IupGridBoxv(raw_handles.as_mut_ptr());
            Self::from_ptr(ptr)
        }
    }
    pub fn set_valign(self, valign: VAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_VERT, valign.as_cstr());
        self
    }

    pub fn set_halign(self, halign: HAlign) -> Self {
        self.set_const_str_attribute(::attrs::ALIGNMENT_HORI, halign.as_cstr());
        self
    }

    /// Based on the orientation, set the number of children to place in a:
    ///
    /// * `Vertical`: **column**
    /// * `Horizontal`: **row**
    ///
    /// before beginning the next one.
    pub fn set_ndiv(self, ndiv: u32) -> Self {
        self.set_int_attribute(::attrs::NUMDIV, ndiv as i32);
        self
    }

    /// Sets how children are distributed in the container.
    ///
    /// * `Vertical`: The container will fill columns first.
    ///
    /// Visual example (`ndiv=3` grid with 7 children):
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///

    ///

    ///
    /// * `Horizontal`: The container will fill rows first. **Default.**
    ///
    /// Visual example (`ndiv=3` grid with 7 children):
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///         Child
    ///         Child
    ///

    ///

    ///         Child
    ///

    ///

    ///
    pub fn set_orientation(&mut self, orientation: Orientation) -> &mut Self {
        self.set_const_str_attribute(::attrs::ORIENTATION, orientation.as_cstr());
        self
    }
}

impl_widget! { Grid, "matrix" }

/// Convert a heterogeneous list of widgets into a `Vec<BaseWidget>`,
/// suitable for passing to any function that takes `AsRef<[BaseWidget]>`, such as a constructor
/// for one of the container types.
#[macro_export]
macro_rules! children [
    // Accepts invocation with or without a final comma.
    ($($child:expr),+,) => (children![$($child),+]);
    ($($child:expr),+) => ({
        use ::kiss_ui::widget::Widget;
        vec![$($child.to_base()),+]
    });
    () => (vec![]);
];
<|endoftext|>


<commit_before>use std::os;
use std::io::File;
use std::str;

fn main() {
    let args: ~[~str] = os::args();
    let argsClone = args.clone();
    if args.len() != 3 {
        println!("Usage: {:s} <splitFile1> <splitFile2>", args[0]);
    } else {
        let f1name = args[1];
        let f2name = argsClone[2];
        let path1 = Path::new(f1name.clone());
        let path2 = Path::new(f2name.clone());
        let msg_file1 = File::open(&path1);
        let msg_file2 = File::open(&path2);

        match (msg_file1, msg_file2) {
            (Some(mut msg1), Some(mut msg2)) => {
                let msg1_bytes: ~[u8] = msg1.read_to_end();
                let msg2_bytes: ~[u8] = msg2.read_to_end();
                let output_file
                       = File::create(&Path::new("originalMsg"));

                match (output_file) {
                    Some(output) => {
                        split(msg1_bytes, msg2_bytes, output);
                        } ,
                    _ => fail!("Error opening output files!"),
                }
            } ,
            (_, _) => fail!("Error opening split files: {:s}, {:s}", f1name, f2name)
        }
    }
}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}

fn split(msg1_bytes: &[u8], msg2_bytes: &[u8], mut output_file: File) {
    let original_bytes: ~[u8] = xor(msg1_bytes, msg2_bytes);
    output_file.write(original_bytes);
    print(str::from_utf8(original_bytes));
}
<commit_msg>Added a comment<commit_after>use std::os;
use std::io::File;
use std::str;

fn main() {
    let args: ~[~str] = os::args();
    let argsClone = args.clone();
    if args.len() != 3 {
        println!("Usage: {:s} <splitFile1> <splitFile2>", args[0]);
    } else {
        let f1name = args[1];
        let f2name = argsClone[2];
        let path1 = Path::new(f1name.clone());
        let path2 = Path::new(f2name.clone());
        let msg_file1 = File::open(&path1);
        let msg_file2 = File::open(&path2);

        match (msg_file1, msg_file2) {
            (Some(mut msg1), Some(mut msg2)) => {
                let msg1_bytes: ~[u8] = msg1.read_to_end();
                let msg2_bytes: ~[u8] = msg2.read_to_end();
                let output_file
                       = File::create(&Path::new("originalMsg"));

                match (output_file) {
                    Some(output) => {
                        split(msg1_bytes, msg2_bytes, output);
                        } ,
                    _ => fail!("Error opening output files!"),
                }
            } ,
            (_, _) => fail!("Error opening split files: {:s}, {:s}", f1name, f2name)
        }
    }
}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}

fn split(msg1_bytes: &[u8], msg2_bytes: &[u8], mut output_file: File) {
    // I didn't know if I should print the output to stdout or save it to a file, so I did both
    let original_bytes: ~[u8] = xor(msg1_bytes, msg2_bytes);
    output_file.write(original_bytes);
    print(str::from_utf8(original_bytes));
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::field::Field;

pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

pub struct RowBuilder {
    data: HashMap<String, Field>,
}

impl RowBuilder {
    fn new() -> RowBuilder {
        RowBuilder{data:HashMap::new()}
    }
    fn set_string(&mut self, key: &str, val: &str) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Field::String(val.to_string()));
        self
    }
    fn set_int(&mut self, key: &str, val: i64) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Field::Int(val));
        self
    }
    fn commit(mut self, stream: &mut Stream) {

    }
}

pub struct Stream {
    max_id: u64,
    rows: Vec<Row>,
    schema: Schema,
}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream {
            max_id: 0,
            rows: Vec::new(),
            schema: Schema::new(),
        };
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut data: HashMap<String, Field>) -> Result<Row, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Field> = HashMap::new();
        for (key, val) in data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                                      .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row = try!(Row::new(row_map));
        Ok(row)
    }
    pub fn builder(&self) -> RowBuilder {
        let builder = RowBuilder::new();
        builder
    }

}

#[cfg(test)]
mod tests {
    use super::Stream;
    use super::super::schema::{Schema, Type};
    use super::super::field::Field;
    use std::collections::HashMap;

    fn get_stream() -> Stream {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        s.schema.add_type("age", Type::Int);
        s.schema.add_type("created", Type::Timestamp);
        s

    }

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        let mut row = HashMap::new();
        row.insert("name".to_string(), Field::String("Jon".to_string()));
        let result = s.insert(row);

    }

    fn test_builder() {
        let mut s = get_stream();
        let mut row = s.builder();

        row.set_string("name", "value")
           .set_int("age", 10);
        row.commit(&mut s);
    }
}<commit_msg>row builder is now used for insert<commit_after>use std::collections::HashMap;
use std::error;

use super::row::{Row, RowError};
use super::schema::{Schema, Type};
use super::field::Field;

pub enum StreamError {
    ValidationError(String),
    FieldNotFound(String),
    MissingRowId
}

impl From<RowError> for StreamError {
    fn from(err: RowError) -> StreamError {
        StreamError::MissingRowId
    }

}

pub struct RowBuilder {
    data: HashMap<String, Field>,
}

impl RowBuilder {
    fn new() -> RowBuilder {
        RowBuilder{data:HashMap::new()}
    }
    fn set_string(&mut self, key: &str, val: &str) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Field::String(val.to_string()));
        self
    }
    fn set_int(&mut self, key: &str, val: i64) -> &mut RowBuilder {
        self.data.insert(key.to_string(), Field::Int(val));
        self
    }
}

pub struct Stream {
    max_id: u64,
    rows: Vec<Row>,
    schema: Schema,
}

/**
This is a weird DB.  There's no primary key, since everything is based off append only streaming

*/
impl Stream {
    pub fn new() -> Stream {
        let mut stream = Stream {
            max_id: 0,
            rows: Vec::new(),
            schema: Schema::new(),
        };
        stream.schema.add_type("_id", Type::Int);
        stream.schema.add_type("_created", Type::Timestamp);
        stream
    }

    /* we take a HashMap of String -> Field here
    * we're going to convert it to HashMap<u8, Field> for the Row struct
    */
    pub fn insert(&mut self, mut row_builder: RowBuilder) -> Result<Row, StreamError> {
        // validate the inserted data
        let mut row_map : HashMap<u8, Field> = HashMap::new();
        for (key, val) in row_builder.data.drain() {
            // get the field from the schema
            // TypeDef
            let tmp = try!(self.schema.get(&key)
                               .ok_or(StreamError::FieldNotFound(key.to_string())));
            row_map.insert(tmp.id, val);

        }
        let row = try!(Row::new(row_map));
        Ok(row)
    }
    pub fn builder(&self) -> RowBuilder {
        let builder = RowBuilder::new();
        builder
    }

}

#[cfg(test)]
mod tests {
    use super::{Stream, RowBuilder};
    use super::super::schema::{Schema, Type};
    use super::super::field::Field;
    use std::collections::HashMap;

    fn get_stream() -> Stream {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);
        s.schema.add_type("age", Type::Int);
        s.schema.add_type("created", Type::Timestamp);
        s

    }

    #[test]
    fn test_insert_works_normal_case() {
        let mut s = Stream::new();
        s.schema.add_type("name", Type::String);

        let mut row = RowBuilder::new();
        row.set_string("name", "test");
        let result = s.insert(row);

    }

    fn test_builder() {
        let mut s = get_stream();
        let mut row = s.builder();

        row.set_string("name", "value")
           .set_int("age", 10);
        s.insert(row);
    }
}<|endoftext|>


<commit_before>#![crate_type = "bin"]
#![crate_id="demo"]

extern crate sdl2;
extern crate sdl2_mixer;

use std::os;
use mix = sdl2_mixer;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println!("Usage: ./demo audio.[mp3|wav|ogg]")
    } else {
        match dump_info(&Path::new(args[1])) {
            _ => ()
        }
    }
}

fn dump_info(filename: &Path) -> Result<(), ~str> {
    println!("linked version: {}", mix::get_linked_version());
    sdl2::init(sdl2::InitAudio | sdl2::InitTimer);
    println!("inited => {}", mix::init(sdl2_mixer::InitMp3 | sdl2_mixer::InitFlac |
                                       sdl2_mixer::InitMod | sdl2_mixer::InitFluidSynth |
                                       sdl2_mixer::InitModPlug | sdl2_mixer::InitOgg).get());
    // TODO: 0x8010 is SDL_audio flag
    try!(mix::open_audio(mix::DEFAULT_FREQUENCY, 0x8010u16, 2, 1024));
    mix::allocate_channels(0);

    {
        let n = mix::get_chunk_decoders_number();
        println!("available chunk(sample) decoders: {}", n);
        for i in range(0, n) {
            println!("| decoder {} => {:?}", i, mix::get_chunk_decoder(i));
        }
    }

    {
        let n = mix::get_music_decoders_number();
        println!("available music decoders: {}", n);
        for i in range(0, n) {
            println!("| decoder {} => {:?}", i, mix::get_music_decoder(i));
        }
    }

    println!("query spec => {}", mix::query_spec());

    let music = mix::Music::from_file(filename).unwrap();

    mix::Music::hook_finished(|| { println!("play ends! from rust cb") });

    println!("music => {:?}", music);
    println!("music type => {}", music.get_type());

    println!("music volume => {}", mix::Music::get_volume());

    println!("play => {}", music.play(1));

    sdl2::timer::delay(10000);

    println!("fading out ... {}", mix::Music::fade_out(4000));

    sdl2::timer::delay(5000);

    println!("fading in from pos ... {}", music.fade_in_from_pos(1, 10000, 100.0));

    sdl2::timer::delay(5000);

    mix::Music::halt();

    sdl2::timer::delay(1000);
    // here will print hook_finished

    mix::quit();
    sdl2::quit();

    Ok(())
}
<commit_msg>fix demo code compile error<commit_after>#![crate_type = "bin"]
#![crate_id="demo"]

extern crate sdl2;
extern crate sdl2_mixer;

use std::os;
use mix = sdl2_mixer;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println!("Usage: ./demo audio.[mp3|wav|ogg]")
    } else {
        match dump_info(&Path::new(args.get(1).to_owned())) {
            _ => ()
        }
    }
}

fn dump_info(filename: &Path) -> Result<(), ~str> {
    println!("linked version: {}", mix::get_linked_version());
    sdl2::init(sdl2::InitAudio | sdl2::InitTimer);
    println!("inited => {}", mix::init(sdl2_mixer::InitMp3 | sdl2_mixer::InitFlac |
                                       sdl2_mixer::InitMod | sdl2_mixer::InitFluidSynth |
                                       sdl2_mixer::InitModPlug | sdl2_mixer::InitOgg).bits());
    // TODO: 0x8010 is SDL_audio flag
    try!(mix::open_audio(mix::DEFAULT_FREQUENCY, 0x8010u16, 2, 1024));
    mix::allocate_channels(0);

    {
        let n = mix::get_chunk_decoders_number();
        println!("available chunk(sample) decoders: {}", n);
        for i in range(0, n) {
            println!("| decoder {} => {:?}", i, mix::get_chunk_decoder(i));
        }
    }

    {
        let n = mix::get_music_decoders_number();
        println!("available music decoders: {}", n);
        for i in range(0, n) {
            println!("| decoder {} => {:?}", i, mix::get_music_decoder(i));
        }
    }

    println!("query spec => {}", mix::query_spec());

    let music = mix::Music::from_file(filename).unwrap();

    mix::Music::hook_finished(|| { println!("play ends! from rust cb") });

    println!("music => {:?}", music);
    println!("music type => {}", music.get_type());

    println!("music volume => {}", mix::Music::get_volume());

    println!("play => {}", music.play(1));

    sdl2::timer::delay(10000);

    println!("fading out ... {}", mix::Music::fade_out(4000));

    sdl2::timer::delay(5000);

    println!("fading in from pos ... {}", music.fade_in_from_pos(1, 10000, 100.0));

    sdl2::timer::delay(5000);

    mix::Music::halt();

    sdl2::timer::delay(1000);
    // here will print hook_finished

    mix::quit();
    sdl2::quit();

    Ok(())
}
<|endoftext|>


<commit_before>use libc::{c_int, c_double, c_char};

pub type EnergyMonInitFn = unsafe extern fn() -> i32;
pub type EnergyMonReadTotalFn = unsafe extern fn() -> c_double;
pub type EnergyMonFinishFn = unsafe extern fn() -> i32;
pub type EnergyMonGetSourceFn = unsafe extern fn(*mut c_char) -> *mut c_char;

extern {
    fn em_impl_get(ptr: *mut EnergyMonC) -> c_int;
    fn em_init() -> i32;
    fn em_read_total() -> c_double;
    fn em_finish() -> i32;
    fn em_get_source(buffer: *mut c_char) -> *mut c_char;
}

#[repr(C)]
pub struct EnergyMonC {
    pub finit: EnergyMonInitFn,
    pub fread: EnergyMonReadTotalFn,
    pub ffinish: EnergyMonFinishFn,
    pub fsource: EnergyMonGetSourceFn,
}

impl Default for EnergyMonC {
    fn default() -> EnergyMonC {
        EnergyMonC {
            finit: em_init,
            fread: em_read_total,
            ffinish: em_finish,
            fsource: em_get_source,
        }
    }
}

pub struct EnergyMon {
    pub em: EnergyMonC,
}

impl EnergyMon {
    pub fn new() -> Result<EnergyMon, String> {
        let mut em = EnergyMonC::default();
        let result = unsafe {
            em_impl_get(&mut em)
        };
        if result != 0 {
            return Err("Failed to initialize energy reader".to_string());
        }
        Ok(EnergyMon { em: em, })
    }
}
<commit_msg>Simplify<commit_after>use libc::{c_int, c_double, c_char};

pub type EnergyMonInitFn = unsafe extern fn() -> i32;
pub type EnergyMonReadTotalFn = unsafe extern fn() -> c_double;
pub type EnergyMonFinishFn = unsafe extern fn() -> i32;
pub type EnergyMonGetSourceFn = unsafe extern fn(*mut c_char) -> *mut c_char;

extern {
    pub fn em_impl_get(ptr: *mut EnergyMon) -> c_int;
    pub fn em_init() -> i32;
    pub fn em_read_total() -> c_double;
    pub fn em_finish() -> i32;
    pub fn em_get_source(buffer: *mut c_char) -> *mut c_char;
}

#[repr(C)]
pub struct EnergyMon {
    pub finit: EnergyMonInitFn,
    pub fread: EnergyMonReadTotalFn,
    pub ffinish: EnergyMonFinishFn,
    pub fsource: EnergyMonGetSourceFn,
}

impl Default for EnergyMon {
    fn default() -> EnergyMon {
        EnergyMon {
            finit: em_init,
            fread: em_read_total,
            ffinish: em_finish,
            fsource: em_get_source,
        }

    }
}

/*pub struct EnergyMon {
    pub em: EnergyMonC,
}

impl EnergyMon {
    pub fn new() -> Result<EnergyMon, String> {
        let mut em = EnergyMonC::default();
        let result = unsafe {
            em_impl_get(&mut em)
        };
        if result != 0 {
            return Err("Failed to initialize energy reader".to_string());
        }
        Ok(EnergyMon { em: em, })
    }
}
*/<|endoftext|>


<commit_before>use crate::cargo::TestBinary;
use crate::ptrace_control::*;
use crate::statemachine::{ProcessInfo, TracerAction};
use chrono::offset::Local;
use nix::libc::*;
use nix::sys::{signal::Signal, wait::WaitStatus};
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::fs::File;
use std::path::Path;
use tracing::{info, warn};

#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum Event {
    ConfigLaunch(String),
    BinaryLaunch(TestBinary),
    Trace(TraceEvent),
}

#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct TraceEvent {
    pid: Option<pid_t>,
    child: Option<pid_t>,
    signal: Option<String>,
    addr: Option<u64>,
    return_val: Option<i64>,
    description: String,
}

impl TraceEvent {
    pub(crate) fn new_from_action(action: &TracerAction<ProcessInfo>) -> Self {
        match *action {
            TracerAction::TryContinue(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                signal: t.signal.map(|x| x.to_string()),
                description: "Try continue child".to_string(),
                ..Default::default()
            },
            TracerAction::Continue(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                signal: t.signal.map(|x| x.to_string()),
                description: "Continue child".to_string(),
                ..Default::default()
            },
            TracerAction::Step(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                description: "Step child".to_string(),
                ..Default::default()
            },
            TracerAction::Detach(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                description: "Detach child".to_string(),
                ..Default::default()
            },
            _ => TraceEvent {
                description: "Unexpected action".to_string(),
                ..Default::default()
            },
        }
    }

    pub(crate) fn new_from_wait(wait: &WaitStatus) -> Self {
        let pid = wait.pid().map(|p| p.as_raw());
        let mut event = TraceEvent {
            pid,
            ..Default::default()
        };
        match wait {
            WaitStatus::Exited(_, i) => {
                event.description = "Exited".to_string();
                event.return_val = Some(*i as _);
            }
            WaitStatus::Signaled(_, sig, _) => {
                event.signal = Some(sig.to_string());
                event.description = "Signaled".to_string();
            }
            WaitStatus::Stopped(c, sig) => {
                event.signal = Some(sig.to_string());
                if *sig == Signal::SIGTRAP {
                    event.description = "Stopped".to_string();
                    event.addr = current_instruction_pointer(*c).ok().map(|x| (x - 1) as u64);
                } else {
                    event.description = "Non-trace stop".to_string();
                }
            }
            WaitStatus::PtraceEvent(pid, sig, val) => {
                event.signal = Some(sig.to_string());
                match *val {
                    PTRACE_EVENT_CLONE => {
                        event.description = "Ptrace Clone".to_string();
                        if *sig == Signal::SIGTRAP {
                            event.child = get_event_data(*pid).ok().map(|x| x as pid_t);
                        }
                    }
                    PTRACE_EVENT_FORK => {
                        event.description = "Ptrace fork".to_string();
                    }
                    PTRACE_EVENT_VFORK => {
                        event.description = "Ptrace vfork".to_string();
                    }
                    PTRACE_EVENT_EXEC => {
                        event.description = "Ptrace exec".to_string();
                    }
                    PTRACE_EVENT_EXIT => {
                        event.description = "Ptrace exit".to_string();
                    }
                    _ => {
                        event.description = "Ptrace unknown event".to_string();
                    }
                }
            }
            WaitStatus::Continued(_) => {
                event.description = "Continued".to_string();
            }
            WaitStatus::StillAlive => {
                event.description = "StillAlive".to_string();
            }
            WaitStatus::PtraceSyscall(_) => {
                event.description = "PtraceSyscall".to_string();
            }
        }
        event
    }
}

#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EventLog {
    events: RefCell<Vec<Event>>,
}

impl EventLog {
    pub fn new() -> Self {
        Self {
            events: RefCell::new(vec![]),
        }
    }

    pub fn push_binary(&self, binary: TestBinary) {
        self.events.borrow_mut().push(Event::BinaryLaunch(binary));
    }

    pub fn push_trace(&self, event: TraceEvent) {
        self.events.borrow_mut().push(Event::Trace(event));
    }

    pub fn push_config(&self, name: String) {
        self.events.borrow_mut().push(Event::ConfigLaunch(name));
    }
}

impl Drop for EventLog {
    fn drop(&mut self) {
        let fname = format!("tarpaulin-run-{}.json", Local::now().to_rfc3339());
        let path = Path::new(&fname);
        info!("Serializing tarpaulin debug log to {}", path.display());
        if let Ok(output) = File::create(path) {
            if let Err(e) = serde_json::to_writer(output, self) {
                warn!("Failed to serialise or write result: {}", e);
            }
        } else {
            warn!("Failed to create log file");
        }
    }
}
<commit_msg>Make nothing message better<commit_after>use crate::cargo::TestBinary;
use crate::ptrace_control::*;
use crate::statemachine::{ProcessInfo, TracerAction};
use chrono::offset::Local;
use nix::libc::*;
use nix::sys::{signal::Signal, wait::WaitStatus};
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::fs::File;
use std::path::Path;
use tracing::{info, warn};

#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum Event {
    ConfigLaunch(String),
    BinaryLaunch(TestBinary),
    Trace(TraceEvent),
}

#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct TraceEvent {
    pid: Option<pid_t>,
    child: Option<pid_t>,
    signal: Option<String>,
    addr: Option<u64>,
    return_val: Option<i64>,
    description: String,
}

impl TraceEvent {
    pub(crate) fn new_from_action(action: &TracerAction<ProcessInfo>) -> Self {
        match *action {
            TracerAction::TryContinue(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                signal: t.signal.map(|x| x.to_string()),
                description: "Try continue child".to_string(),
                ..Default::default()
            },
            TracerAction::Continue(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                signal: t.signal.map(|x| x.to_string()),
                description: "Continue child".to_string(),
                ..Default::default()
            },
            TracerAction::Step(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                description: "Step child".to_string(),
                ..Default::default()
            },
            TracerAction::Detach(t) => TraceEvent {
                pid: Some(t.pid.as_raw()),
                description: "Detach child".to_string(),
                ..Default::default()
            },
            TracerAction::Nothing => TraceEvent {
                description: "Do nothing".to_string(),
                ..Default::default()
            },
        }
    }

    pub(crate) fn new_from_wait(wait: &WaitStatus) -> Self {
        let pid = wait.pid().map(|p| p.as_raw());
        let mut event = TraceEvent {
            pid,
            ..Default::default()
        };
        match wait {
            WaitStatus::Exited(_, i) => {
                event.description = "Exited".to_string();
                event.return_val = Some(*i as _);
            }
            WaitStatus::Signaled(_, sig, _) => {
                event.signal = Some(sig.to_string());
                event.description = "Signaled".to_string();
            }
            WaitStatus::Stopped(c, sig) => {
                event.signal = Some(sig.to_string());
                if *sig == Signal::SIGTRAP {
                    event.description = "Stopped".to_string();
                    event.addr = current_instruction_pointer(*c).ok().map(|x| (x - 1) as u64);
                } else {
                    event.description = "Non-trace stop".to_string();
                }
            }
            WaitStatus::PtraceEvent(pid, sig, val) => {
                event.signal = Some(sig.to_string());
                match *val {
                    PTRACE_EVENT_CLONE => {
                        event.description = "Ptrace Clone".to_string();
                        if *sig == Signal::SIGTRAP {
                            event.child = get_event_data(*pid).ok().map(|x| x as pid_t);
                        }
                    }
                    PTRACE_EVENT_FORK => {
                        event.description = "Ptrace fork".to_string();
                    }
                    PTRACE_EVENT_VFORK => {
                        event.description = "Ptrace vfork".to_string();
                    }
                    PTRACE_EVENT_EXEC => {
                        event.description = "Ptrace exec".to_string();
                    }
                    PTRACE_EVENT_EXIT => {
                        event.description = "Ptrace exit".to_string();
                    }
                    _ => {
                        event.description = "Ptrace unknown event".to_string();
                    }
                }
            }
            WaitStatus::Continued(_) => {
                event.description = "Continued".to_string();
            }
            WaitStatus::StillAlive => {
                event.description = "StillAlive".to_string();
            }
            WaitStatus::PtraceSyscall(_) => {
                event.description = "PtraceSyscall".to_string();
            }
        }
        event
    }
}

#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EventLog {
    events: RefCell<Vec<Event>>,
}

impl EventLog {
    pub fn new() -> Self {
        Self {
            events: RefCell::new(vec![]),
        }
    }

    pub fn push_binary(&self, binary: TestBinary) {
        self.events.borrow_mut().push(Event::BinaryLaunch(binary));
    }

    pub fn push_trace(&self, event: TraceEvent) {
        self.events.borrow_mut().push(Event::Trace(event));
    }

    pub fn push_config(&self, name: String) {
        self.events.borrow_mut().push(Event::ConfigLaunch(name));
    }
}

impl Drop for EventLog {
    fn drop(&mut self) {
        let fname = format!("tarpaulin-run-{}.json", Local::now().to_rfc3339());
        let path = Path::new(&fname);
        info!("Serializing tarpaulin debug log to {}", path.display());
        if let Ok(output) = File::create(path) {
            if let Err(e) = serde_json::to_writer(output, self) {
                warn!("Failed to serialise or write result: {}", e);
            }
        } else {
            warn!("Failed to create log file");
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    cluster::Cluster,
    health::{Event, HealthCheck, HealthCheckContext, ValidatorEvent},
};
use std::{collections::HashMap, time::Duration};

pub struct LivenessHealthCheck {
    last_committed: HashMap<String, LastCommitInfo>,
}

const MAX_BEHIND: Duration = Duration::from_secs(60);

#[derive(Default)]
struct LastCommitInfo {
    ve: Option<ValidatorEvent>,
    timestamp: Duration,
}

impl LivenessHealthCheck {
    pub fn new(cluster: &Cluster) -> Self {
        let mut last_committed = HashMap::new();
        for instance in cluster.instances() {
            last_committed.insert(instance.short_hash().clone(), LastCommitInfo::default());
        }
        Self { last_committed }
    }
}

impl HealthCheck for LivenessHealthCheck {
    fn on_event(&mut self, ve: &ValidatorEvent, ctx: &mut HealthCheckContext) {
        match ve.event {
            Event::Commit(..) => {
                if let Some(ref prev) = self.last_committed.get(&ve.validator) {
                    if prev.timestamp > ve.timestamp {
                        return;
                    }
                }
                self.last_committed.insert(
                    ve.validator.clone(),
                    LastCommitInfo {
                        ve: Some(ve.clone()),
                        timestamp: ve.timestamp,
                    },
                );
            }
            Event::ConsensusStarted => {
                ctx.report_failure(ve.validator.clone(), "validator restarted".into());
            }
        }
    }

    fn verify(&mut self, ctx: &mut HealthCheckContext) {
        let min_timestamp = ctx.now - MAX_BEHIND;
        for (validator, lci) in &self.last_committed {
            if lci.timestamp < min_timestamp {
                ctx.report_failure(
                    validator.clone(),
                    format!(
                        "Last commit is {} ms behind: {:?}",
                        (min_timestamp - lci.timestamp).as_millis(),
                        lci.ve,
                    ),
                );
            }
        }
    }

    fn invalidate(&mut self, validator: &str) {
        self.last_committed
            .insert(validator.into(), LastCommitInfo::default());
    }

    fn name(&self) -> &'static str {
        "liveness_check"
    }
}
<commit_msg>[cluster-test] Bump liveness health check timeout 1m->2m<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    cluster::Cluster,
    health::{Event, HealthCheck, HealthCheckContext, ValidatorEvent},
};
use std::{collections::HashMap, time::Duration};

pub struct LivenessHealthCheck {
    last_committed: HashMap<String, LastCommitInfo>,
}

const MAX_BEHIND: Duration = Duration::from_secs(120);

#[derive(Default)]
struct LastCommitInfo {
    ve: Option<ValidatorEvent>,
    timestamp: Duration,
}

impl LivenessHealthCheck {
    pub fn new(cluster: &Cluster) -> Self {
        let mut last_committed = HashMap::new();
        for instance in cluster.instances() {
            last_committed.insert(instance.short_hash().clone(), LastCommitInfo::default());
        }
        Self { last_committed }
    }
}

impl HealthCheck for LivenessHealthCheck {
    fn on_event(&mut self, ve: &ValidatorEvent, ctx: &mut HealthCheckContext) {
        match ve.event {
            Event::Commit(..) => {
                if let Some(ref prev) = self.last_committed.get(&ve.validator) {
                    if prev.timestamp > ve.timestamp {
                        return;
                    }
                }
                self.last_committed.insert(
                    ve.validator.clone(),
                    LastCommitInfo {
                        ve: Some(ve.clone()),
                        timestamp: ve.timestamp,
                    },
                );
            }
            Event::ConsensusStarted => {
                ctx.report_failure(ve.validator.clone(), "validator restarted".into());
            }
        }
    }

    fn verify(&mut self, ctx: &mut HealthCheckContext) {
        let min_timestamp = ctx.now - MAX_BEHIND;
        for (validator, lci) in &self.last_committed {
            if lci.timestamp < min_timestamp {
                ctx.report_failure(
                    validator.clone(),
                    format!(
                        "Last commit is {} ms behind: {:?}",
                        (min_timestamp - lci.timestamp).as_millis(),
                        lci.ve,
                    ),
                );
            }
        }
    }

    fn invalidate(&mut self, validator: &str) {
        self.last_committed
            .insert(validator.into(), LastCommitInfo::default());
    }

    fn name(&self) -> &'static str {
        "liveness_check"
    }
}
<|endoftext|>


<commit_before>use std::{
    fs::{self, File},
    io::{BufRead, BufReader},
    path::Path,
};

use crate::Result;

type VersionFn = fn(&str) -> bool;
const SPLITS: &[(&str, VersionFn)] = &[
    ("https://matrix.org/docs/spec/client_server/", |s| {
        // We cannot include the `#` because for every lib.rs file with spec docs the
        // URL is `../rx.x.x.html`
        s.starts_with("r0.6.1") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/server_server/", |s| {
        s.starts_with("r0.1.4") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/application_service/", |s| {
        s.starts_with("r0.1.2") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/identity_service/", |s| {
        s.starts_with("r0.3.0") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/push_gateway/", |s| {
        s.starts_with("r0.1.1") || s.starts_with("unstable#")
    }),
    ("https://spec.matrix.org/", |s| {
        s.starts_with("v1.1") || s.starts_with("v1.2") || s.starts_with("unstable")
    }),
];

pub(crate) fn check_spec_links(path: &Path) -> Result<()> {
    println!("Checking all Matrix Spec links point to same version...");
    // This is WAY overkill but since there are a few mixed in ruma-common
    // and this would catch any wrong version anywhere it's probably ok
    for (split, version_fn) in SPLITS {
        walk_dirs(path, split, *version_fn)?;
    }
    Ok(())
}

fn walk_dirs(path: &Path, split: &str, version_match: fn(&str) -> bool) -> Result<()> {
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                walk_dirs(&path, split, version_match)?;
            } else {
                let mut buf = String::new();
                let mut content = BufReader::new(File::open(&path)?);

                // We can assume a spec link will never overflow to another line
                while content.read_line(&mut buf)? > 0 {
                    // If for some reason a line has 2 spec links
                    for (idx, _) in buf.match_indices(split) {
                        if !version_match(&buf[idx + split.len()..]) {
                            return err(&path, &buf);
                        }
                    }
                    buf.clear();
                }
            }
        }
    }
    Ok(())
}

fn err(path: &Path, snippet: &str) -> Result<()> {
    Err(format!(
        "error: spec URL with wrong version number\nfile: {}\n\nsnippet:\n{}",
        path.display(),
        &snippet[0..25]
    )
    .into())
}
<commit_msg>ci: Forbid old spec links<commit_after>use std::{
    fs::{self, File},
    io::{BufRead, BufReader},
    path::Path,
};

use crate::Result;

pub(crate) fn check_spec_links(path: &Path) -> Result<()> {
    println!("Checking Matrix Spec links are up-to-date...");
    walk_dirs(path, "https://matrix.org/docs/spec/", |_| false)?;
    walk_dirs(path, "https://spec.matrix.org/", |s| {
        s.starts_with("v1.2") || s.starts_with("unstable")
    })?;
    Ok(())
}

fn walk_dirs(path: &Path, split: &str, version_match: fn(&str) -> bool) -> Result<()> {
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                walk_dirs(&path, split, version_match)?;
            } else {
                let mut buf = String::new();
                let mut content = BufReader::new(File::open(&path)?);

                // We can assume a spec link will never overflow to another line
                while content.read_line(&mut buf)? > 0 {
                    // If for some reason a line has 2 spec links
                    for (idx, _) in buf.match_indices(split) {
                        if !version_match(&buf[idx + split.len()..]) {
                            return err(&path, &buf);
                        }
                    }
                    buf.clear();
                }
            }
        }
    }
    Ok(())
}

fn err(path: &Path, snippet: &str) -> Result<()> {
    Err(format!(
        "error: spec URL with wrong version number\nfile: {}\n\nsnippet:\n{}",
        path.display(),
        &snippet[0..25]
    )
    .into())
}
<|endoftext|>


<commit_before>// Based off of libcss's examples/example1.c
mod example1 {

    use CssResult;
    use CssProperty;
    use types::*;
    use hint::*;
    use select::*;
    use util::VoidPtrLike;
    use wapcaplet::LwcString;

    struct MyDomNode {
        name: @LwcString
    }

    impl VoidPtrLike for MyDomNode {
        fn from_void_ptr(node: *libc::c_void) -> MyDomNode {
            assert!(node.is_not_null());
            MyDomNode {
                name: unsafe {
                    let box = cast::reinterpret_cast(&node);
                    cast::bump_box_refcount(box);
                    box
                }
            }
        }

        fn to_void_ptr(&self) -> *libc::c_void {
            unsafe { cast::reinterpret_cast(&self.name) }
        }
    }

    #[test]
    fn run() {
        let data = "h1 { color: red; }\
                    h4 { color: #321; }\
                    h4, h5 { color: #123456; }";

        let resolve: CssUrlResolutionFn = |a,b| resolve_url(a, b);

        let params: CssStylesheetParams = CssStylesheetParams {
            params_version: CssStylesheetParamsVersion1,
            level: CssLevel21,
            charset: ~"UTF-8",
            url: ~"foo",
            title: ~"foo",
            allow_quirks: false,
            inline_style: false,
            resolve: Some(resolve),
            import: None,
            color: None,
            font: None,
        };

        let mut sheet: CssStylesheet = css_stylesheet_create(&params);
        debug!("stylesheet: %?", sheet);
        debug!("stylesheet size: %?", sheet.size());

        sheet.append_data(str::to_bytes(data));
        sheet.data_done();
        debug!("stylesheet size: %?", sheet.size());

        let mut select_ctx: CssSelectCtx = css_select_ctx_create();
        assert!(select_ctx.count_sheets() == 0);
        select_ctx.append_sheet(sheet, CSS_ORIGIN_AUTHOR, CSS_MEDIA_ALL);
        debug!("count sheets: %?", select_ctx.count_sheets());
        assert!(select_ctx.count_sheets() == 1);

        for uint::range(1, 7) |hh| {
            let element = fmt!("h%u", hh);
            let element_name: @LwcString = @from_rust_string(element);
            let node = MyDomNode { name: element_name };
            let select_handler = SelectHandler { bogus: () };
            let style: CssSelectResults = select_ctx.select_style(&node,
                                                                  CSS_MEDIA_SCREEN,
                                                                  None,
                                                                  &select_handler);

            let computed: CssComputedStyle = style.computed_style(CssPseudoElementNone);

            match computed.color() {
                CssColorInherit => {
                    debug!("color of h%u is 'inherit'", hh);
                },
                CssColorColor(color) => {
                    debug!("color of h%u is %x", hh, color.to_ll() as uint);
                }
            }
        }
    }

    fn resolve_url(_base: &str, _rel: &LwcString) -> CssResult<LwcString> {
        fail!(~"resolving url");
    }

    struct SelectHandler {
        bogus: ()
    }

    impl CssSelectHandler<MyDomNode> for SelectHandler {
        fn node_name(&self, node: &MyDomNode) -> CssQName {
            debug!("HL node_name!");
            debug!("SS %?", (*node.name).to_str());

            CssQName {
                ns: None,
                name: node.name.clone()
            }
        }

        fn node_id(&self, _node: &MyDomNode) -> Option<LwcString> { None }

        fn named_parent_node(&self, _node: &MyDomNode, _qname: &CssQName) -> Option<MyDomNode> {
            None
        }

        fn parent_node(&self, _node: &MyDomNode) -> Option<MyDomNode> {
            None
        }

        fn node_has_id(&self, _node: &MyDomNode, _name: LwcString) -> bool { false }

        fn named_ancestor_node(&self, _node: &MyDomNode, _qname: &CssQName) -> Option<MyDomNode> {
            None
        }

        fn node_is_root(&self, _node: &MyDomNode) -> bool { false }

        fn node_is_link(&self, _node: &MyDomNode) -> bool { false }

        fn ua_default_for_property(&self, property: CssProperty) -> CssHint {
            match property {
                _ => CssHintDefault
            }
        }
    }
}

#[test]
fn test_arc() {
    use std::arc::ARC;
    use stylesheet::*;
    use types::CssLevel21;

    let resolve: CssUrlResolutionFn = |a,b| resolve_url(a, b);
    let params: CssStylesheetParams = CssStylesheetParams {
        params_version: CssStylesheetParamsVersion1,
        level: CssLevel21,
        charset: ~"UTF-8",
        url: ~"foo",
        title: ~"foo",
        allow_quirks: false,
        inline_style: false,
        resolve: Some(resolve),
        import: None,
        color: None,
        font: None,
    };

    let sheet: CssStylesheet = css_stylesheet_create(&params);
    let _arc = ARC(sheet);

    fn resolve_url(_base: &str, _rel: &LwcString) -> CssResult<LwcString> {
        fail!(~"resolving url");
    }
}
<commit_msg>Add imports for tests.<commit_after>// Based off of libcss's examples/example1.c
mod example1 {

    use CssResult;
    use CssProperty;
    use types::*;
    use hint::*;
    use select::*;
    use util::VoidPtrLike;
    use wapcaplet::LwcString;

    struct MyDomNode {
        name: @LwcString
    }

    impl VoidPtrLike for MyDomNode {
        fn from_void_ptr(node: *libc::c_void) -> MyDomNode {
            assert!(node.is_not_null());
            MyDomNode {
                name: unsafe {
                    let box = cast::reinterpret_cast(&node);
                    cast::bump_box_refcount(box);
                    box
                }
            }
        }

        fn to_void_ptr(&self) -> *libc::c_void {
            unsafe { cast::reinterpret_cast(&self.name) }
        }
    }

    #[test]
    fn run() {
        use super::super::stylesheet::{CssUrlResolutionFn, CssStylesheetParams, CssStylesheet,
                                       css_stylesheet_create, CssStylesheetParamsVersion1};
        use super::super::computed::CssComputedStyle;
        use super::super::values::{CssColorColor, CssColorInherit};
        use super::super::ll::types::{CSS_ORIGIN_AUTHOR, CSS_MEDIA_ALL, CSS_MEDIA_SCREEN};
        use super::super::conversions::ToLl;
        use wapcaplet::{LwcString, from_rust_string};

        let data = "h1 { color: red; }\
                    h4 { color: #321; }\
                    h4, h5 { color: #123456; }";

        let resolve: CssUrlResolutionFn = |a,b| resolve_url(a, b);

        let params: CssStylesheetParams = CssStylesheetParams {
            params_version: CssStylesheetParamsVersion1,
            level: CssLevel21,
            charset: ~"UTF-8",
            url: ~"foo",
            title: ~"foo",
            allow_quirks: false,
            inline_style: false,
            resolve: Some(resolve),
            import: None,
            color: None,
            font: None,
        };

        let mut sheet: CssStylesheet = css_stylesheet_create(&params);
        debug!("stylesheet: %?", sheet);
        debug!("stylesheet size: %?", sheet.size());

        sheet.append_data(str::to_bytes(data));
        sheet.data_done();
        debug!("stylesheet size: %?", sheet.size());

        let mut select_ctx: CssSelectCtx = css_select_ctx_create();
        assert!(select_ctx.count_sheets() == 0);
        select_ctx.append_sheet(sheet, CSS_ORIGIN_AUTHOR, CSS_MEDIA_ALL);
        debug!("count sheets: %?", select_ctx.count_sheets());
        assert!(select_ctx.count_sheets() == 1);

        for uint::range(1, 7) |hh| {
            let element = fmt!("h%u", hh);
            let element_name: @LwcString = @from_rust_string(element);
            let node = MyDomNode { name: element_name };
            let select_handler = SelectHandler { bogus: () };
            let style: CssSelectResults = select_ctx.select_style(&node,
                                                                  CSS_MEDIA_SCREEN,
                                                                  None,
                                                                  &select_handler);

            let computed: CssComputedStyle = style.computed_style(CssPseudoElementNone);

            match computed.color() {
                CssColorInherit => {
                    debug!("color of h%u is 'inherit'", hh);
                }
                CssColorColor(color) => {
                    debug!("color of h%u is %x", hh, color.to_ll() as uint);
                }
            }
        }
    }

    fn resolve_url(_base: &str, _rel: &LwcString) -> CssResult<LwcString> {
        fail!(~"resolving url");
    }

    struct SelectHandler {
        bogus: ()
    }

    impl CssSelectHandler<MyDomNode> for SelectHandler {
        fn node_name(&self, node: &MyDomNode) -> CssQName {
            debug!("HL node_name!");
            debug!("SS %?", (*node.name).to_str());

            CssQName {
                ns: None,
                name: node.name.clone()
            }
        }

        fn node_id(&self, _node: &MyDomNode) -> Option<LwcString> { None }

        fn named_parent_node(&self, _node: &MyDomNode, _qname: &CssQName) -> Option<MyDomNode> {
            None
        }

        fn parent_node(&self, _node: &MyDomNode) -> Option<MyDomNode> {
            None
        }

        fn node_has_id(&self, _node: &MyDomNode, _name: LwcString) -> bool { false }

        fn named_ancestor_node(&self, _node: &MyDomNode, _qname: &CssQName) -> Option<MyDomNode> {
            None
        }

        fn node_is_root(&self, _node: &MyDomNode) -> bool { false }

        fn node_is_link(&self, _node: &MyDomNode) -> bool { false }

        fn ua_default_for_property(&self, property: CssProperty) -> CssHint {
            match property {
                _ => CssHintDefault
            }
        }
    }
}

#[test]
fn test_arc() {
    use std::arc::ARC;
    use stylesheet::*;
    use types::CssLevel21;
    use wapcaplet::LwcString;
    use super::CssResult;

    let resolve: CssUrlResolutionFn = |a,b| resolve_url(a, b);
    let params: CssStylesheetParams = CssStylesheetParams {
        params_version: CssStylesheetParamsVersion1,
        level: CssLevel21,
        charset: ~"UTF-8",
        url: ~"foo",
        title: ~"foo",
        allow_quirks: false,
        inline_style: false,
        resolve: Some(resolve),
        import: None,
        color: None,
        font: None,
    };

    let sheet: CssStylesheet = css_stylesheet_create(&params);
    let _arc = ARC(sheet);

    fn resolve_url(_base: &str, _rel: &LwcString) -> CssResult<LwcString> {
        fail!(~"resolving url");
    }
}
<|endoftext|>


<commit_before>use CHIP8_HEIGHT;
use CHIP8_WIDTH;
use CHIP8_RAM;

pub struct OutputState<'a> {
    pub vram: &'a [[u8; CHIP8_WIDTH]; CHIP8_HEIGHT],
    pub vram_changed: bool,
    pub beep: bool,
}

pub struct Processor {
    vram: [[u8; CHIP8_WIDTH]; CHIP8_HEIGHT],
    vram_changed: bool,
    ram: [u8; CHIP8_RAM],
    stack: [usize; 16],
    v: [u8; 16],
    i: usize,
    pc: usize,
    sp: usize,
    delay_timer: u8,
    sound_timer: u8,
}

impl Processor {
    pub fn new() -> Self {
        Processor {
            vram: [[0; CHIP8_WIDTH]; CHIP8_HEIGHT],
            vram_changed: false,
            ram: [0; CHIP8_RAM],
            stack: [0; 16],
            v: [0; 16],
            i: 0,
            pc: 0x200,
            sp: 0,
            delay_timer: 0,
            sound_timer: 0,
        }
    }

    pub fn tick(&mut self, keypad: &[bool; 16]) -> OutputState {
        self.vram_changed = false;
        let opcode = self.get_opcode();
        self.run_opcode(opcode);
        OutputState {
            vram: &self.vram,
            vram_changed: self.vram_changed,
            beep: self.sound_timer > 0,
        }
    }

    fn get_opcode(&self) -> u16 {
        (self.ram[self.pc] as u16) << 8 | (self.ram[self.pc + 1] as u16)
    }

    fn run_opcode(&mut self, opcode: u16) {

        let nibbles = (
            (opcode & 0xF000) >> 12 as u8,
            (opcode & 0x0F00) >> 8 as u8,
            (opcode & 0x00F0) >> 4 as u8,
            (opcode & 0x000F) as u8,
        );

        let nnn = (opcode & 0x0FFF) as usize;
        let kk = (opcode & 0x00FF) as u8;
        let x = nibbles.2 as usize;
        let y = nibbles.1 as usize;
        let n = nibbles.0 as u8;

        match nibbles {
            (0x00, 0x00, 0x0e, 0x00) => self.op_00e0(),
            (0x00, 0x00, 0x0e, 0x0e) => self.op_00ee(),
            (0x01, _, _, _) => self.op_1nnn(nnn),
            (0x02, _, _, _) => self.op_2nnn(nnn),
            (0x03, _, _, _) => self.op_3xkk(x, kk),
            (0x04, _, _, _) => self.op_4xkk(x, kk),
            (0x05, _, _, 0x00) => self.op_5xy0(x, y),
            (0x06, _, _, _) => self.op_6xkk(x, kk),
            (0x07, _, _, _) => self.op_7xkk(x, kk),
            (0x08, _, _, 0x00) => self.op_8xy0(x, y),
            (0x08, _, _, 0x01) => self.op_8xy1(x, y),
            (0x08, _, _, 0x02) => self.op_8xy2(x, y),
            (0x08, _, _, 0x03) => self.op_8xy3(x, y),
            (0x08, _, _, 0x04) => self.op_8xy4(x, y),
            (0x08, _, _, 0x05) => self.op_8xy5(x, y),
            (0x08, _, _, 0x06) => self.op_8xy6(x, y),
            (0x08, _, _, 0x07) => self.op_8xy7(x, y),
            (0x08, _, _, 0x0e) => self.op_8xye(x, y),
            (0x09, _, _, 0x00) => self.op_9xy0(x, y),
            (0x0a, _, _, _) => self.op_annn(nnn),
            (0x0b, _, _, _) => self.op_bnnn(nnn),
            (0x0c, _, _, _) => self.op_cxkk(x, kk),
            (0x0d, _, _, _) => self.op_dxyn(x, y, n),
            (0x0e, _, 0x09, 0x0e) => self.op_ex9e(x),
            (0x0e, _, 0x0a, 0x01) => self.op_exa1(x),
            (0x0f, _, 0x00, 0x07) => self.op_fx07(x),
            (0x0f, _, 0x00, 0x0a) => self.op_fx0a(x),
            (0x0f, _, 0x01, 0x05) => self.op_fx15(x),
            (0x0f, _, 0x01, 0x08) => self.op_fx18(x),
            (0x0f, _, 0x01, 0x0e) => self.op_fx1e(x),
            (0x0f, _, 0x02, 0x09) => self.op_fx29(x),
            (0x0f, _, 0x03, 0x03) => self.op_fx33(x),
            (0x0f, _, 0x05, 0x05) => self.op_fx55(x),
            (0x0f, _, 0x06, 0x05) => self.op_fx65(x),
            _ => return,
        }

    }
    // CLS: Clear the display.
    fn op_00e0(&mut self) {
        for y in 0..CHIP8_HEIGHT {
            for x in 0..CHIP8_WIDTH {
                self.vram[y][x] = 0;
            }
        }
        self.vram_changed = true;
    }

    // RET:  Return from a subroutine.
    fn op_00ee(&mut self) {
        self.sp -= 1;
        self.pc = self.stack[self.sp];
    }

    // JP addr
    fn op_1nnn(&mut self, nnn: usize) {
        println!("hello: {:X}", nnn);
        self.pc = nnn;
    }

    // CALL addr
    fn op_2nnn(&mut self, nnn: usize) {
        self.stack[self.sp] = self.pc;
        self.sp += 1;
        self.pc = nnn;
    }

    // SE Vx, byte
    fn op_3xkk(&mut self, x: usize, kk: u8) {}
    // SNE Vx, byte
    fn op_4xkk(&mut self, x: usize, kk: u8) {}
    // SE Vx, Vy
    fn op_5xy0(&mut self, x: usize, y: usize) {}
    // LD Vx, byte
    fn op_6xkk(&mut self, x: usize, kk: u8) {}
    // ADD Vx, byte
    fn op_7xkk(&mut self, x: usize, kk: u8) {}
    // LD Vx, Vy
    fn op_8xy0(&mut self, x: usize, y: usize) {}
    // OR Vx, Vy
    fn op_8xy1(&mut self, x: usize, y: usize) {}
    // AND Vx, Vy
    fn op_8xy2(&mut self, x: usize, y: usize) {}
    // XOR Vx, Vy
    fn op_8xy3(&mut self, x: usize, y: usize) {}
    // ADD Vx, Vy
    fn op_8xy4(&mut self, x: usize, y: usize) {}
    // SUB Vx, Vy
    fn op_8xy5(&mut self, x: usize, y: usize) {}
    // SHR Vx {, Vy}
    fn op_8xy6(&mut self, x: usize, y: usize) {}
    // SUBN Vx, Vy
    fn op_8xy7(&mut self, x: usize, y: usize) {}
    // SHL Vx {, Vy}
    fn op_8xye(&mut self, x: usize, y: usize) {}
    // SNE Vx, Vy
    fn op_9xy0(&mut self, x: usize, y: usize) {}
    // LD I, addr
    fn op_annn(&mut self, nnn: usize) {}
    // JP V0, addr
    fn op_bnnn(&mut self, nnn: usize) {}
    // RND Vx, byte
    fn op_cxkk(&mut self, x: usize, kk: u8) {}
    // DRW Vx, Vy, nibble
    fn op_dxyn(&mut self, x: usize, y: usize, n: u8) {}
    // SKP Vx
    fn op_ex9e(&mut self, x: usize) {}
    // SKNP Vx
    fn op_exa1(&mut self, x: usize) {}
    // LD Vx, DT
    fn op_fx07(&mut self, x: usize) {}
    // LD Vx, K
    fn op_fx0a(&mut self, x: usize) {}
    // LD DT, Vx
    fn op_fx15(&mut self, x: usize) {}
    // LD ST, Vx
    fn op_fx18(&mut self, x: usize) {}
    // ADD I, Vx
    fn op_fx1e(&mut self, x: usize) {}
    // LD F, Vx
    fn op_fx29(&mut self, x: usize) {}
    // LD B, Vx
    fn op_fx33(&mut self, x: usize) {}
    // LD [I], Vx
    fn op_fx55(&mut self, x: usize) {}
    // LD Vx, [I]
    fn op_fx65(&mut self, x: usize) {}
}

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

    #[test]
    fn test_initial_state() {
        let processor = Processor::new();
        assert_eq!(processor.sp, 0);
        assert_eq!(processor.stack, [0; 16]);
    }

    // CLS
    #[test]
    fn test_op_00e0() {
        let mut processor = Processor::new();
        processor.vram = [[128; CHIP8_WIDTH]; CHIP8_HEIGHT];
        processor.run_opcode(0x00e0);
        for y in 0..CHIP8_HEIGHT {
            for x in 0..CHIP8_WIDTH {
                assert_eq!(processor.vram[y][x], 0);
            }
        }
    }

    // RET
    #[test]
    fn test_op_00ee() {
        let mut processor = Processor::new();
        processor.sp = 5;
        processor.stack[4] = 0x6666;
        processor.run_opcode(0x00ee);
        assert_eq!(processor.sp, 4);
        assert_eq!(processor.pc, 0x6666);
    }

    // JP
    #[test]
    fn test_op_1nnn() {
        let mut processor = Processor::new();
        processor.run_opcode(0x1666);
        assert_eq!(processor.pc, 0x0666);
    }

    // CALL
    #[test]
    fn test_op_2nnn() {
        let mut processor = Processor::new();
        processor.pc = 0x400;
        processor.run_opcode(0x2666);
        assert_eq!(processor.pc, 0x0666);
        assert_eq!(processor.sp, 1);
        assert_eq!(processor.stack[0], 0x400);
    }

}
<commit_msg>Make x, y and n point to correct nibbles<commit_after>use CHIP8_HEIGHT;
use CHIP8_WIDTH;
use CHIP8_RAM;

pub struct OutputState<'a> {
    pub vram: &'a [[u8; CHIP8_WIDTH]; CHIP8_HEIGHT],
    pub vram_changed: bool,
    pub beep: bool,
}

pub struct Processor {
    vram: [[u8; CHIP8_WIDTH]; CHIP8_HEIGHT],
    vram_changed: bool,
    ram: [u8; CHIP8_RAM],
    stack: [usize; 16],
    v: [u8; 16],
    i: usize,
    pc: usize,
    sp: usize,
    delay_timer: u8,
    sound_timer: u8,
}

impl Processor {
    pub fn new() -> Self {
        Processor {
            vram: [[0; CHIP8_WIDTH]; CHIP8_HEIGHT],
            vram_changed: false,
            ram: [0; CHIP8_RAM],
            stack: [0; 16],
            v: [0; 16],
            i: 0,
            pc: 0x200,
            sp: 0,
            delay_timer: 0,
            sound_timer: 0,
        }
    }

    pub fn tick(&mut self, keypad: &[bool; 16]) -> OutputState {
        self.vram_changed = false;
        let opcode = self.get_opcode();
        self.run_opcode(opcode);
        OutputState {
            vram: &self.vram,
            vram_changed: self.vram_changed,
            beep: self.sound_timer > 0,
        }
    }

    fn get_opcode(&self) -> u16 {
        (self.ram[self.pc] as u16) << 8 | (self.ram[self.pc + 1] as u16)
    }

    fn run_opcode(&mut self, opcode: u16) {

        let nibbles = (
            (opcode & 0xF000) >> 12 as u8,
            (opcode & 0x0F00) >> 8 as u8,
            (opcode & 0x00F0) >> 4 as u8,
            (opcode & 0x000F) as u8,
        );

        let nnn = (opcode & 0x0FFF) as usize;
        let kk = (opcode & 0x00FF) as u8;
        let x = nibbles.1 as usize;
        let y = nibbles.2 as usize;
        let n = nibbles.3 as u8;

        match nibbles {
            (0x00, 0x00, 0x0e, 0x00) => self.op_00e0(),
            (0x00, 0x00, 0x0e, 0x0e) => self.op_00ee(),
            (0x01, _, _, _) => self.op_1nnn(nnn),
            (0x02, _, _, _) => self.op_2nnn(nnn),
            (0x03, _, _, _) => self.op_3xkk(x, kk),
            (0x04, _, _, _) => self.op_4xkk(x, kk),
            (0x05, _, _, 0x00) => self.op_5xy0(x, y),
            (0x06, _, _, _) => self.op_6xkk(x, kk),
            (0x07, _, _, _) => self.op_7xkk(x, kk),
            (0x08, _, _, 0x00) => self.op_8xy0(x, y),
            (0x08, _, _, 0x01) => self.op_8xy1(x, y),
            (0x08, _, _, 0x02) => self.op_8xy2(x, y),
            (0x08, _, _, 0x03) => self.op_8xy3(x, y),
            (0x08, _, _, 0x04) => self.op_8xy4(x, y),
            (0x08, _, _, 0x05) => self.op_8xy5(x, y),
            (0x08, _, _, 0x06) => self.op_8xy6(x, y),
            (0x08, _, _, 0x07) => self.op_8xy7(x, y),
            (0x08, _, _, 0x0e) => self.op_8xye(x, y),
            (0x09, _, _, 0x00) => self.op_9xy0(x, y),
            (0x0a, _, _, _) => self.op_annn(nnn),
            (0x0b, _, _, _) => self.op_bnnn(nnn),
            (0x0c, _, _, _) => self.op_cxkk(x, kk),
            (0x0d, _, _, _) => self.op_dxyn(x, y, n),
            (0x0e, _, 0x09, 0x0e) => self.op_ex9e(x),
            (0x0e, _, 0x0a, 0x01) => self.op_exa1(x),
            (0x0f, _, 0x00, 0x07) => self.op_fx07(x),
            (0x0f, _, 0x00, 0x0a) => self.op_fx0a(x),
            (0x0f, _, 0x01, 0x05) => self.op_fx15(x),
            (0x0f, _, 0x01, 0x08) => self.op_fx18(x),
            (0x0f, _, 0x01, 0x0e) => self.op_fx1e(x),
            (0x0f, _, 0x02, 0x09) => self.op_fx29(x),
            (0x0f, _, 0x03, 0x03) => self.op_fx33(x),
            (0x0f, _, 0x05, 0x05) => self.op_fx55(x),
            (0x0f, _, 0x06, 0x05) => self.op_fx65(x),
            _ => return,
        }

    }
    // CLS: Clear the display.
    fn op_00e0(&mut self) {
        for y in 0..CHIP8_HEIGHT {
            for x in 0..CHIP8_WIDTH {
                self.vram[y][x] = 0;
            }
        }
        self.vram_changed = true;
    }

    // RET:  Return from a subroutine.
    fn op_00ee(&mut self) {
        self.sp -= 1;
        self.pc = self.stack[self.sp];
    }

    // JP addr
    fn op_1nnn(&mut self, nnn: usize) {
        println!("hello: {:X}", nnn);
        self.pc = nnn;
    }

    // CALL addr
    fn op_2nnn(&mut self, nnn: usize) {
        self.stack[self.sp] = self.pc;
        self.sp += 1;
        self.pc = nnn;
    }

    // SE Vx, byte
    fn op_3xkk(&mut self, x: usize, kk: u8) {}
    // SNE Vx, byte
    fn op_4xkk(&mut self, x: usize, kk: u8) {}
    // SE Vx, Vy
    fn op_5xy0(&mut self, x: usize, y: usize) {}
    // LD Vx, byte
    fn op_6xkk(&mut self, x: usize, kk: u8) {}
    // ADD Vx, byte
    fn op_7xkk(&mut self, x: usize, kk: u8) {}
    // LD Vx, Vy
    fn op_8xy0(&mut self, x: usize, y: usize) {}
    // OR Vx, Vy
    fn op_8xy1(&mut self, x: usize, y: usize) {}
    // AND Vx, Vy
    fn op_8xy2(&mut self, x: usize, y: usize) {}
    // XOR Vx, Vy
    fn op_8xy3(&mut self, x: usize, y: usize) {}
    // ADD Vx, Vy
    fn op_8xy4(&mut self, x: usize, y: usize) {}
    // SUB Vx, Vy
    fn op_8xy5(&mut self, x: usize, y: usize) {}
    // SHR Vx {, Vy}
    fn op_8xy6(&mut self, x: usize, y: usize) {}
    // SUBN Vx, Vy
    fn op_8xy7(&mut self, x: usize, y: usize) {}
    // SHL Vx {, Vy}
    fn op_8xye(&mut self, x: usize, y: usize) {}
    // SNE Vx, Vy
    fn op_9xy0(&mut self, x: usize, y: usize) {}
    // LD I, addr
    fn op_annn(&mut self, nnn: usize) {}
    // JP V0, addr
    fn op_bnnn(&mut self, nnn: usize) {}
    // RND Vx, byte
    fn op_cxkk(&mut self, x: usize, kk: u8) {}
    // DRW Vx, Vy, nibble
    fn op_dxyn(&mut self, x: usize, y: usize, n: u8) {}
    // SKP Vx
    fn op_ex9e(&mut self, x: usize) {}
    // SKNP Vx
    fn op_exa1(&mut self, x: usize) {}
    // LD Vx, DT
    fn op_fx07(&mut self, x: usize) {}
    // LD Vx, K
    fn op_fx0a(&mut self, x: usize) {}
    // LD DT, Vx
    fn op_fx15(&mut self, x: usize) {}
    // LD ST, Vx
    fn op_fx18(&mut self, x: usize) {}
    // ADD I, Vx
    fn op_fx1e(&mut self, x: usize) {}
    // LD F, Vx
    fn op_fx29(&mut self, x: usize) {}
    // LD B, Vx
    fn op_fx33(&mut self, x: usize) {}
    // LD [I], Vx
    fn op_fx55(&mut self, x: usize) {}
    // LD Vx, [I]
    fn op_fx65(&mut self, x: usize) {}
}

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

    #[test]
    fn test_initial_state() {
        let processor = Processor::new();
        assert_eq!(processor.sp, 0);
        assert_eq!(processor.stack, [0; 16]);
    }

    // CLS
    #[test]
    fn test_op_00e0() {
        let mut processor = Processor::new();
        processor.vram = [[128; CHIP8_WIDTH]; CHIP8_HEIGHT];
        processor.run_opcode(0x00e0);
        for y in 0..CHIP8_HEIGHT {
            for x in 0..CHIP8_WIDTH {
                assert_eq!(processor.vram[y][x], 0);
            }
        }
    }

    // RET
    #[test]
    fn test_op_00ee() {
        let mut processor = Processor::new();
        processor.sp = 5;
        processor.stack[4] = 0x6666;
        processor.run_opcode(0x00ee);
        assert_eq!(processor.sp, 4);
        assert_eq!(processor.pc, 0x6666);
    }

    // JP
    #[test]
    fn test_op_1nnn() {
        let mut processor = Processor::new();
        processor.run_opcode(0x1666);
        assert_eq!(processor.pc, 0x0666);
    }

    // CALL
    #[test]
    fn test_op_2nnn() {
        let mut processor = Processor::new();
        processor.pc = 0x400;
        processor.run_opcode(0x2666);
        assert_eq!(processor.pc, 0x0666);
        assert_eq!(processor.sp, 1);
        assert_eq!(processor.stack[0], 0x400);
    }

}
<|endoftext|>


<commit_before>//! Draw rectangle

use internal;
use triangulation;
use Graphics;
use Color;
use DrawState;
use math::Matrix2d;

pub use math::margin_rectangle as margin;

/// Use x, y, half-width, half-height
pub fn centered(rect: internal::Rectangle) -> internal::Rectangle {
    [rect[0] - rect[2], rect[1] - rect[3], 2.0 * rect[2], 2.0 * rect[3]]
}

/// Use centered square
pub fn centered_square(
    x: internal::Scalar,
    y: internal::Scalar,
    radius: internal::Scalar
) -> internal::Rectangle {
    [x - radius, y - radius, 2.0 * radius, 2.0 * radius]
}

/// Use square with x, y in upper left corner
pub fn square(
    x: internal::Scalar,
    y: internal::Scalar,
    size: internal::Scalar
) -> internal::Rectangle {
    [x, y, size, size]
}

/// The shape of the rectangle
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square corners
    Square,
    /// Round corners
    Round(internal::Radius),
    /// Bevel corners
    Bevel(internal::Radius),
}

/// The border of the rectangle
#[derive(Copy, Clone)]
pub struct Border {
    /// The color of the border
    pub color: internal::Color,
    /// The radius of the border
    pub radius: internal::Radius,
}

/// Maybe border property
#[derive(Copy, Clone)]
pub struct MaybeBorder(pub Option<Border>);

/// A filled rectangle
#[derive(Copy, Clone)]
pub struct Rectangle {
    /// The rectangle color
    pub color: internal::Color,
    /// The roundness of the rectangle
    pub shape: Shape,
    /// The border
    pub border: Option<Border>,
}

impl Rectangle {
    /// Creates a new rectangle.
    pub fn new(color: internal::Color) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Square,
            border: None,
        }
    }

    /// Creates a new round rectangle.
    pub fn round(
        color: internal::Color,
        round_radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Round(round_radius),
            border: None
        }
    }

    /// Creates a new rectangle border.
    pub fn border(
        color: internal::Color,
        radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: [0.0; 4],
            shape: Shape::Square,
            border: Some(Border {
                    color: color,
                    radius: radius
                })
        }
    }

    /// Creates a new round rectangle border.
    pub fn round_border(
        color: internal::Color,
        round_radius: internal::Radius,
        border_radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: [0.0; 4],
            shape: Shape::Round(round_radius),
            border: Some(Border {
                    color: color,
                    radius: border_radius
                })
        }
    }

    /// Draws the rectangle
    pub fn draw<G>(
        &self,
        rectangle: internal::Rectangle,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        if self.color[3] != 0.0 {
            match self.shape {
                Shape::Square => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                            f(&triangulation::rect_tri_list_xy(
                                transform,
                                rectangle
                            )),
                    );
                }
                Shape::Round(round_radius) => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                    triangulation::with_round_rectangle_tri_list(
                        32,
                        transform,
                        rectangle,
                        round_radius,
                        |vertices| f(vertices)
                    ));
                }
                Shape::Bevel(bevel_radius) => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                    triangulation::with_round_rectangle_tri_list(
                        2,
                        transform,
                        rectangle,
                        bevel_radius,
                        |vertices| f(vertices)
                    ));
                }
            }
        }

        if let Some(Border { color, radius: border_radius }) = self.border {
            if color[3] == 0.0 { return; }
            match self.shape {
                Shape::Square => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f| f(
                            &triangulation::rect_border_tri_list_xy(
                                transform, rectangle, border_radius),
                        )
                    );
                }
                Shape::Round(round_radius) => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f|
                    triangulation::with_round_rectangle_border_tri_list(
                        128,
                        transform,
                        rectangle,
                        round_radius,
                        border_radius,
                        |vertices| f(vertices)
                    ));
                }
                Shape::Bevel(bevel_radius) => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f|
                    triangulation::with_round_rectangle_border_tri_list(
                        2,
                        transform,
                        rectangle,
                        bevel_radius,
                        border_radius,
                        |vertices| f(vertices)
                    ));
                }
            }
        }
    }
}

/*
quack! {
    r: Rectangle[]
    get:
        fn () -> Color [] { Color(r.color) }
        fn () -> Shape [] { r.shape }
        fn () -> MaybeBorder [] { MaybeBorder(r.border) }
    set:
        fn (val: Color) [] { r.color = val.0 }
        fn (val: Shape) [] { r.shape = val }
        fn (val: Border) [] { r.border = Some(val) }
        fn (val: MaybeBorder) [] { r.border = val.0 }
    action:
}
*/

#[cfg(test)]
mod test {
    use super::Rectangle;
    use super::Shape;
    use super::Border;
    use Color;

    #[test]
    fn test_rectangle() {
        let _rectangle = Rectangle::new([1.0; 4])
            .set(Color([0.0; 4]))
            .set(Shape::Round(10.0))
            .set(Border { color: [0.0; 4], radius: 4.0 });
    }
}
<commit_msg>Renamed `Rectangle::round` to `Rectangle::new_round`<commit_after>//! Draw rectangle

use internal;
use triangulation;
use Graphics;
use Color;
use DrawState;
use math::Matrix2d;

pub use math::margin_rectangle as margin;

/// Use x, y, half-width, half-height
pub fn centered(rect: internal::Rectangle) -> internal::Rectangle {
    [rect[0] - rect[2], rect[1] - rect[3], 2.0 * rect[2], 2.0 * rect[3]]
}

/// Use centered square
pub fn centered_square(
    x: internal::Scalar,
    y: internal::Scalar,
    radius: internal::Scalar
) -> internal::Rectangle {
    [x - radius, y - radius, 2.0 * radius, 2.0 * radius]
}

/// Use square with x, y in upper left corner
pub fn square(
    x: internal::Scalar,
    y: internal::Scalar,
    size: internal::Scalar
) -> internal::Rectangle {
    [x, y, size, size]
}

/// The shape of the rectangle
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square corners
    Square,
    /// Round corners
    Round(internal::Radius),
    /// Bevel corners
    Bevel(internal::Radius),
}

/// The border of the rectangle
#[derive(Copy, Clone)]
pub struct Border {
    /// The color of the border
    pub color: internal::Color,
    /// The radius of the border
    pub radius: internal::Radius,
}

/// Maybe border property
#[derive(Copy, Clone)]
pub struct MaybeBorder(pub Option<Border>);

/// A filled rectangle
#[derive(Copy, Clone)]
pub struct Rectangle {
    /// The rectangle color
    pub color: internal::Color,
    /// The roundness of the rectangle
    pub shape: Shape,
    /// The border
    pub border: Option<Border>,
}

impl Rectangle {
    /// Creates a new rectangle.
    pub fn new(color: internal::Color) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Square,
            border: None,
        }
    }

    /// Creates a new round rectangle.
    pub fn new_round(
        color: internal::Color,
        round_radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Round(round_radius),
            border: None
        }
    }

    /// Creates a new rectangle border.
    pub fn border(
        color: internal::Color,
        radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: [0.0; 4],
            shape: Shape::Square,
            border: Some(Border {
                    color: color,
                    radius: radius
                })
        }
    }

    /// Creates a new round rectangle border.
    pub fn round_border(
        color: internal::Color,
        round_radius: internal::Radius,
        border_radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: [0.0; 4],
            shape: Shape::Round(round_radius),
            border: Some(Border {
                    color: color,
                    radius: border_radius
                })
        }
    }

    /// Draws the rectangle
    pub fn draw<G>(
        &self,
        rectangle: internal::Rectangle,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        if self.color[3] != 0.0 {
            match self.shape {
                Shape::Square => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                            f(&triangulation::rect_tri_list_xy(
                                transform,
                                rectangle
                            )),
                    );
                }
                Shape::Round(round_radius) => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                    triangulation::with_round_rectangle_tri_list(
                        32,
                        transform,
                        rectangle,
                        round_radius,
                        |vertices| f(vertices)
                    ));
                }
                Shape::Bevel(bevel_radius) => {
                    g.tri_list(
                        draw_state,
                        &self.color,
                        |f|
                    triangulation::with_round_rectangle_tri_list(
                        2,
                        transform,
                        rectangle,
                        bevel_radius,
                        |vertices| f(vertices)
                    ));
                }
            }
        }

        if let Some(Border { color, radius: border_radius }) = self.border {
            if color[3] == 0.0 { return; }
            match self.shape {
                Shape::Square => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f| f(
                            &triangulation::rect_border_tri_list_xy(
                                transform, rectangle, border_radius),
                        )
                    );
                }
                Shape::Round(round_radius) => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f|
                    triangulation::with_round_rectangle_border_tri_list(
                        128,
                        transform,
                        rectangle,
                        round_radius,
                        border_radius,
                        |vertices| f(vertices)
                    ));
                }
                Shape::Bevel(bevel_radius) => {
                    g.tri_list(
                        draw_state,
                        &color,
                        |f|
                    triangulation::with_round_rectangle_border_tri_list(
                        2,
                        transform,
                        rectangle,
                        bevel_radius,
                        border_radius,
                        |vertices| f(vertices)
                    ));
                }
            }
        }
    }
}

/*
quack! {
    r: Rectangle[]
    get:
        fn () -> Color [] { Color(r.color) }
        fn () -> Shape [] { r.shape }
        fn () -> MaybeBorder [] { MaybeBorder(r.border) }
    set:
        fn (val: Color) [] { r.color = val.0 }
        fn (val: Shape) [] { r.shape = val }
        fn (val: Border) [] { r.border = Some(val) }
        fn (val: MaybeBorder) [] { r.border = val.0 }
    action:
}
*/

#[cfg(test)]
mod test {
    use super::Rectangle;
    use super::Shape;
    use super::Border;
    use Color;

    #[test]
    fn test_rectangle() {
        let _rectangle = Rectangle::new([1.0; 4])
            .set(Color([0.0; 4]))
            .set(Shape::Round(10.0))
            .set(Border { color: [0.0; 4], radius: 4.0 });
    }
}
<|endoftext|>