<commit_before>//  notty is a new kind of terminal emulator.
//  Copyright (C) 2015 without boats
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
use base64;

pub struct Attachments {
    data: Vec<String>,
}

impl Default for Attachments {
    fn default() -> Attachments {
        Attachments { data: vec![String::new()] }
    }
}

impl Attachments {

    pub fn clear(&mut self) {
        self.data.truncate(1);
        self.data.last_mut().unwrap().clear();
    }

    pub fn iter(&self) -> AttachmentIter {
        self.into_iter()
    }

    pub fn append(&mut self, ch: char) -> Option<bool> {
        match ch {
            '0'...'9' | 'A'...'Z' | 'a'...'z' | '+' | '/' | '=' => {
                self.data.last_mut().unwrap().push(ch);
                None
            }
            '#'                                                 => {
                self.data.push(String::new());
                None
            }
            '\u{9c}'                                            => Some(true),
            _                                                   => Some(false),
        }
    }

}

impl<'a> IntoIterator for &'a Attachments {
    type Item = Vec<u8>;
    type IntoIter = AttachmentIter<'a>;
    fn into_iter(self) -> AttachmentIter<'a> {
        AttachmentIter {
            attachments: self.data.iter(),
        }
    }
}

pub struct AttachmentIter<'a>{
    attachments: <&'a Vec<String> as IntoIterator>::IntoIter,
}

impl<'a> Iterator for AttachmentIter<'a> {
    type Item = Vec<u8>;
    fn next(&mut self) -> Option<Vec<u8>> {
        self.attachments.next().and_then(|data| base64::u8de(data.as_bytes()).ok())
    }
}

#[cfg(test)]
mod tests {

    use base64;
    use super::*;

    static BLOCKS: &'static [&'static str] = &[
        "YELLOW SUBMARINE",
        "Hello, world!",
        "History is a nightmare from which I am trying to awaken.",
        "#",
        "Happy familie are all alike; every unhappy family is unhappy in its own way.",
        "--A little more test data.--"
    ];

    #[test]
    fn iterates() {
        let attachments = Attachments {
            data: BLOCKS.iter().map(|s| base64::encode(s).unwrap()).collect()
        };
        for (attachment, block) in (&attachments).into_iter().zip(BLOCKS) {
            assert_eq!(attachment, block.as_bytes());
        }
    }

    #[test]
    fn appends() {
        let mut attachments = Attachments::default();
        for data in BLOCKS.iter().map(|s| base64::encode(s).unwrap()) {
            for ch in data.chars() {
                assert_eq!(attachments.append(ch), None);
            }
            assert_eq!(attachments.append('#'), None);
        }
        assert_eq!(attachments.append('\x07'), Some(true));
        for (attachment, block) in (&attachments).into_iter().zip(BLOCKS) {
            assert_eq!(attachment, block.as_bytes());
        }
    }

    #[test]
    fn wont_append_invalid_chars() {
        let mut attachments = Attachments::default();
        assert_eq!(attachments.append('~'), Some(false));
        assert_eq!(attachments.data.last().unwrap().len(), 0);
    }

}
<commit_msg>Fix breaking test.<commit_after>//  notty is a new kind of terminal emulator.
//  Copyright (C) 2015 without boats
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
use base64;

pub struct Attachments {
    data: Vec<String>,
}

impl Default for Attachments {
    fn default() -> Attachments {
        Attachments { data: vec![String::new()] }
    }
}

impl Attachments {

    pub fn clear(&mut self) {
        self.data.truncate(1);
        self.data.last_mut().unwrap().clear();
    }

    pub fn iter(&self) -> AttachmentIter {
        self.into_iter()
    }

    pub fn append(&mut self, ch: char) -> Option<bool> {
        match ch {
            '0'...'9' | 'A'...'Z' | 'a'...'z' | '+' | '/' | '=' => {
                self.data.last_mut().unwrap().push(ch);
                None
            }
            '#'                                                 => {
                self.data.push(String::new());
                None
            }
            '\u{9c}'                                            => Some(true),
            _                                                   => Some(false),
        }
    }

}

impl<'a> IntoIterator for &'a Attachments {
    type Item = Vec<u8>;
    type IntoIter = AttachmentIter<'a>;
    fn into_iter(self) -> AttachmentIter<'a> {
        AttachmentIter {
            attachments: self.data.iter(),
        }
    }
}

pub struct AttachmentIter<'a>{
    attachments: <&'a Vec<String> as IntoIterator>::IntoIter,
}

impl<'a> Iterator for AttachmentIter<'a> {
    type Item = Vec<u8>;
    fn next(&mut self) -> Option<Vec<u8>> {
        self.attachments.next().and_then(|data| base64::u8de(data.as_bytes()).ok())
    }
}

#[cfg(test)]
mod tests {

    use base64;
    use super::*;

    static BLOCKS: &'static [&'static str] = &[
        "YELLOW SUBMARINE",
        "Hello, world!",
        "History is a nightmare from which I am trying to awaken.",
        "#",
        "Happy familie are all alike; every unhappy family is unhappy in its own way.",
        "--A little more test data.--"
    ];

    #[test]
    fn iterates() {
        let attachments = Attachments {
            data: BLOCKS.iter().map(|s| base64::encode(s).unwrap()).collect()
        };
        for (attachment, block) in (&attachments).into_iter().zip(BLOCKS) {
            assert_eq!(attachment, block.as_bytes());
        }
    }

    #[test]
    fn appends() {
        let mut attachments = Attachments::default();
        for data in BLOCKS.iter().map(|s| base64::encode(s).unwrap()) {
            for ch in data.chars() {
                assert_eq!(attachments.append(ch), None);
            }
            assert_eq!(attachments.append('#'), None);
        }
        assert_eq!(attachments.append('\u{9c}'), Some(true));
        for (attachment, block) in (&attachments).into_iter().zip(BLOCKS) {
            assert_eq!(attachment, block.as_bytes());
        }
    }

    #[test]
    fn wont_append_invalid_chars() {
        let mut attachments = Attachments::default();
        assert_eq!(attachments.append('~'), Some(false));
        assert_eq!(attachments.data.last().unwrap().len(), 0);
    }

}
<|endoftext|>


<commit_before>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, ConfigWrapper, Mode, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use cargo_tarpaulin::traces::TraceMap;
use clap::App;
use std::env;
use std::path::Path;
use std::process::Command;
use std::time::Duration;

#[cfg(nightly)]
mod doc_coverage;
mod failure_thresholds;
mod failures;
mod line_coverage;
mod test_types;
mod utils;
mod workspaces;

pub fn check_percentage_with_cli_args(minimum_coverage: f64, has_lines: bool, args: &[String]) {
    let restore_dir = env::current_dir().unwrap();
    let matches = App::new("tarpaulin")
        .args_from_usage(
             "--config [FILE] 'Path to a toml file specifying a list of options this will override any other options set'
             --ignore-config 'Ignore any project config files'
             --debug 'Show debug output - this is used for diagnosing issues with tarpaulin'
             --verbose -v 'Show extra output'
             --root -r [DIR] 'directory'"
        ).get_matches_from(args);

    let configs = ConfigWrapper::from(&matches).0;
    let mut res = TraceMap::new();
    for config in &configs {
        let (t, _) = launch_tarpaulin(&config, &None).unwrap();
        res.merge(&t);
    }
    res.dedup();
    env::set_current_dir(restore_dir).unwrap();
    assert!(
        res.coverage_percentage() >= minimum_coverage,
        "Assertion failed {} >= {}",
        res.coverage_percentage(),
        minimum_coverage
    );
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    // Note to contributors. If an integration test fails, uncomment this to be able to see the
    // tarpaulin logs
    //cargo_tarpaulin::setup_logging(true, true);

    let (res, _) = launch_tarpaulin(&config, &None).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    if has_lines {
        assert!(res.total_coverable() > 0);
        assert!(
            res.coverage_percentage() >= minimum_coverage,
            "Assertion failed {} >= {}",
            res.coverage_percentage(),
            minimum_coverage
        );
    } else {
        assert_eq!(res.total_coverable(), 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    let launch = launch_tarpaulin(&config, &None);
    assert!(launch.is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config, &None).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
fn config_file_coverage() {
    let test_dir = get_test_path("configs");
    let mut args = vec![
        "tarpaulin".to_string(),
        "--root".to_string(),
        test_dir.display().to_string(),
    ];
    check_percentage_with_cli_args(1.0f64, true, &args);
    args.push("--ignore-config".to_string());
    check_percentage_with_cli_args(0.0f64, true, &args);
}

#[test]
fn match_expr_coverage() {
    check_percentage("matches", 1.0f64, true);
}

#[test]
#[ignore]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn cargo_run_coverage() {
    let mut config = Config::default();
    config.command = Mode::Build;
    check_percentage_with_config("run_coverage", 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config.clone());

    config.run_types.clear();
    config.example_names.insert("say_hello".to_string());
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn access_env_var() {
    // This test is mainly to check that expected environment variables are present
    // using `CARGO_BIN_EXE_<name>` to test
    let test = "env_var";
    check_percentage(test, 1.0f64, true);
}

#[test]
fn tarpaulin_attrs() {
    check_percentage("tarpaulin_attrs", 0.0f64, true);
}

#[test]
#[cfg(nightly)]
fn tarpaulin_tool_attr() {
    check_percentage("tool_attr", 0.0f64, false);
}

#[test]
#[cfg(nightly)]
fn filter_with_inner_attributes() {
    check_percentage("filter_inner_modules", 0.0f64, false);
}

#[test]
fn cargo_home_filtering() {
    let new_home =
        Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/HttptestAndReqwest/new_home");
    let previous = env::var("CARGO_HOME");

    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path("HttptestAndReqwest");
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    env::set_var("CARGO_HOME", new_home.display().to_string());
    let run = launch_tarpaulin(&config, &None);
    match previous {
        Ok(s) => env::set_var("CARGO_HOME", s),
        Err(_) => {
            let _ = Command::new("unset").args(&["CARGO_HOME"]).output();
        }
    }
    let (res, _) = run.unwrap();

    env::set_current_dir(restore_dir).unwrap();

    assert_eq!(res.iter().count(), 1);
}

#[ignore]
fn follow_exes_down() {
    check_percentage("follow_exe", 1.0f64, true);
}
<commit_msg>Enable test for normal use<commit_after>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, ConfigWrapper, Mode, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use cargo_tarpaulin::traces::TraceMap;
use clap::App;
use std::env;
use std::path::Path;
use std::process::Command;
use std::time::Duration;

#[cfg(nightly)]
mod doc_coverage;
mod failure_thresholds;
mod failures;
mod line_coverage;
mod test_types;
mod utils;
mod workspaces;

pub fn check_percentage_with_cli_args(minimum_coverage: f64, has_lines: bool, args: &[String]) {
    let restore_dir = env::current_dir().unwrap();
    let matches = App::new("tarpaulin")
        .args_from_usage(
             "--config [FILE] 'Path to a toml file specifying a list of options this will override any other options set'
             --ignore-config 'Ignore any project config files'
             --debug 'Show debug output - this is used for diagnosing issues with tarpaulin'
             --verbose -v 'Show extra output'
             --root -r [DIR] 'directory'"
        ).get_matches_from(args);

    let configs = ConfigWrapper::from(&matches).0;
    let mut res = TraceMap::new();
    for config in &configs {
        let (t, _) = launch_tarpaulin(&config, &None).unwrap();
        res.merge(&t);
    }
    res.dedup();
    env::set_current_dir(restore_dir).unwrap();
    assert!(
        res.coverage_percentage() >= minimum_coverage,
        "Assertion failed {} >= {}",
        res.coverage_percentage(),
        minimum_coverage
    );
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    // Note to contributors. If an integration test fails, uncomment this to be able to see the
    // tarpaulin logs
    //cargo_tarpaulin::setup_logging(true, true);

    let (res, _) = launch_tarpaulin(&config, &None).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    if has_lines {
        assert!(res.total_coverable() > 0);
        assert!(
            res.coverage_percentage() >= minimum_coverage,
            "Assertion failed {} >= {}",
            res.coverage_percentage(),
            minimum_coverage
        );
    } else {
        assert_eq!(res.total_coverable(), 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    let launch = launch_tarpaulin(&config, &None);
    assert!(launch.is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config, &None).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
fn config_file_coverage() {
    let test_dir = get_test_path("configs");
    let mut args = vec![
        "tarpaulin".to_string(),
        "--root".to_string(),
        test_dir.display().to_string(),
    ];
    check_percentage_with_cli_args(1.0f64, true, &args);
    args.push("--ignore-config".to_string());
    check_percentage_with_cli_args(0.0f64, true, &args);
}

#[test]
fn match_expr_coverage() {
    check_percentage("matches", 1.0f64, true);
}

#[test]
#[ignore]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn cargo_run_coverage() {
    let mut config = Config::default();
    config.command = Mode::Build;
    check_percentage_with_config("run_coverage", 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config.clone());

    config.run_types.clear();
    config.example_names.insert("say_hello".to_string());
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn access_env_var() {
    // This test is mainly to check that expected environment variables are present
    // using `CARGO_BIN_EXE_<name>` to test
    let test = "env_var";
    check_percentage(test, 1.0f64, true);
}

#[test]
fn tarpaulin_attrs() {
    check_percentage("tarpaulin_attrs", 0.0f64, true);
}

#[test]
#[cfg(nightly)]
fn tarpaulin_tool_attr() {
    check_percentage("tool_attr", 0.0f64, false);
}

#[test]
#[cfg(nightly)]
fn filter_with_inner_attributes() {
    check_percentage("filter_inner_modules", 0.0f64, false);
}

#[test]
fn cargo_home_filtering() {
    let new_home =
        Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/HttptestAndReqwest/new_home");
    let previous = env::var("CARGO_HOME");

    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path("HttptestAndReqwest");
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    env::set_var("CARGO_HOME", new_home.display().to_string());
    let run = launch_tarpaulin(&config, &None);
    match previous {
        Ok(s) => env::set_var("CARGO_HOME", s),
        Err(_) => {
            let _ = Command::new("unset").args(&["CARGO_HOME"]).output();
        }
    }
    let (res, _) = run.unwrap();

    env::set_current_dir(restore_dir).unwrap();

    assert_eq!(res.iter().count(), 1);
}

fn follow_exes_down() {
    check_percentage("follow_exe", 1.0f64, true);
}
<|endoftext|>


<commit_before>extern crate syntax;
extern crate rustc;

use test_node::TestNode;

use syntax::ext::base::ExtCtxt;
use syntax::codemap::DUMMY_SP;
use syntax::codemap::Spanned;
use syntax::ast_util::empty_generics;
use syntax::abi;
use syntax::ast;
use syntax::attr;
use syntax::ptr::P;
use syntax::parse::token;
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;

pub struct TestCaseNode {
    name: String,
    block: P<ast::Block>,
    should_fail: bool,
    should_be_ignored: bool
}

impl TestCaseNode {
    pub fn new(name: String,
               block: P<ast::Block>,
               should_fail: bool,
               should_be_ignored: bool
              ) -> Box<TestCaseNode> {
        box TestCaseNode { name: name, block: block, should_fail: should_fail, should_be_ignored: should_be_ignored }
    }

    fn build_test_attributes(&self, cx: &mut ExtCtxt) -> Vec<Spanned<ast::Attribute_>> {
        let mut attributes = vec![];

        attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("test"))));
        attributes.push(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                InternedString::new("allow"),
                vec!(attr::mk_word_item(InternedString::new("non_snake_case")))
            )
        ));

        if self.should_fail {
            attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("should_fail"))));
        }

        if self.should_be_ignored {
            attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("ignore"))));
        }

        attributes
    }
}

impl TestNode for TestCaseNode {
    fn to_item(&self, cx: &mut ExtCtxt, before_blocks: &mut Vec<P<ast::Block>>) -> P<ast::Item> {
        let body = if before_blocks.is_empty() {
            self.block.clone()
        } else {
            let block = self.block.deref().clone();

            let (before_view_items, before_stmts) = before_blocks.iter().fold(
                (vec![], vec![]),
                |(view_accum, stmts_accum), b|
                (view_accum + b.view_items, stmts_accum + b.stmts)
            );

            P(ast::Block {
                view_items: before_view_items + block.view_items,
                stmts: before_stmts + block.stmts,
                ..block
            })
        };

        P(ast::Item {
            ident: cx.ident_of(self.get_name().as_slice()),
            attrs: self.build_test_attributes(cx),
            id: ast::DUMMY_NODE_ID,
            node: ast::ItemFn(
                cx.fn_decl(Vec::new(), cx.ty_nil()),
                ast::NormalFn,
                abi::Rust,
                empty_generics(),
                body.clone()
            ),
            vis: ast::Inherited,
            span: body.span,
        })
    }

    fn get_name(&self) -> String {
        self.name.replace(" ", "_").replace("$", "")
    }
}

<commit_msg>TyNil is gone form nighty<commit_after>extern crate syntax;
extern crate rustc;

use test_node::TestNode;

use syntax::ext::base::ExtCtxt;
use syntax::codemap::DUMMY_SP;
use syntax::codemap::Spanned;
use syntax::ast_util::empty_generics;
use syntax::abi;
use syntax::ast;
use syntax::attr;
use syntax::ptr::P;
use syntax::parse::token;
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;

pub struct TestCaseNode {
    name: String,
    block: P<ast::Block>,
    should_fail: bool,
    should_be_ignored: bool
}

impl TestCaseNode {
    pub fn new(name: String,
               block: P<ast::Block>,
               should_fail: bool,
               should_be_ignored: bool
              ) -> Box<TestCaseNode> {
        box TestCaseNode { name: name, block: block, should_fail: should_fail, should_be_ignored: should_be_ignored }
    }

    fn build_test_attributes(&self, cx: &mut ExtCtxt) -> Vec<Spanned<ast::Attribute_>> {
        let mut attributes = vec![];

        attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("test"))));
        attributes.push(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                InternedString::new("allow"),
                vec!(attr::mk_word_item(InternedString::new("non_snake_case")))
            )
        ));

        if self.should_fail {
            attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("should_fail"))));
        }

        if self.should_be_ignored {
            attributes.push(cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, token::InternedString::new("ignore"))));
        }

        attributes
    }
}

impl TestNode for TestCaseNode {
    fn to_item(&self, cx: &mut ExtCtxt, before_blocks: &mut Vec<P<ast::Block>>) -> P<ast::Item> {
        let body = if before_blocks.is_empty() {
            self.block.clone()
        } else {
            let block = self.block.deref().clone();

            let (before_view_items, before_stmts) = before_blocks.iter().fold(
                (vec![], vec![]),
                |(view_accum, stmts_accum), b|
                (view_accum + b.view_items, stmts_accum + b.stmts)
            );

            P(ast::Block {
                view_items: before_view_items + block.view_items,
                stmts: before_stmts + block.stmts,
                ..block
            })
        };

        P(ast::Item {
            ident: cx.ident_of(self.get_name().as_slice()),
            attrs: self.build_test_attributes(cx),
            id: ast::DUMMY_NODE_ID,
            node: ast::ItemFn(
                cx.fn_decl(
                    Vec::new(),
                    P(ast::Ty {
                        id: ast::DUMMY_NODE_ID,
                        node: ast::TyTup(vec![]),
                        span: DUMMY_SP,
                    })
                ),
                ast::NormalFn,
                abi::Rust,
                empty_generics(),
                body.clone()
            ),
            vis: ast::Inherited,
            span: body.span,
        })
    }

    fn get_name(&self) -> String {
        self.name.replace(" ", "_").replace("$", "")
    }
}

<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::ffi::OsString;
use hyper;

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

easy_error! {
    ErrorChain / ChainError;

    Error {
        LocatingHome {
            description("could not locate home directory")
        }
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not crate {} directory: '{}'", name, path.display())
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy  file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        Download404 {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        OpeningBrowser {
            description("could not open browser")
        }
        NoBrowser {
            description("could not open browser: no browser installed")
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}

#[macro_export]
macro_rules! extend_error {
    ($cur:ty: $base:ty, $p:ident => $e:expr) => (
        impl From<$base> for $cur {
            fn from($p: $base) -> $cur {
                $e
            }
        }
    )
}
<commit_msg>Remove unused macro<commit_after>use std::path::PathBuf;
use std::ffi::OsString;
use hyper;

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

easy_error! {
    ErrorChain / ChainError;

    Error {
        LocatingHome {
            description("could not locate home directory")
        }
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not crate {} directory: '{}'", name, path.display())
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy  file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        Download404 {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        OpeningBrowser {
            description("could not open browser")
        }
        NoBrowser {
            description("could not open browser: no browser installed")
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}
<|endoftext|>


<commit_before>//! A portable encoding for `cge` [`Network`]s. See [`PortableCGE`].

mod error;
mod functions;
pub mod v1;

use serde::{Deserialize, Serialize};

use crate::network::{self, Network};

pub use error::Error;
pub(crate) use functions::*;
pub use v1::{Data, Metadata};

/// The portable encoding type, which can be serialized and deserialized to save or load networks
/// and their metadata.
///
/// [`Network::load_file`], [`Network::to_file`], and related methods are more convenient to use,
/// but this type must be used when deserializing from a format other than JSON. See
/// [`Network::to_serializable`] for serialization to different formats.
///
/// # Examples
///
/// ```
/// # let string =
/// #     include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/test_data/test_network_v1.cge"));
/// use cge::encoding::PortableCGE;
///
/// // Any format supported by `serde` can be used here
/// let deserialized: PortableCGE<()> = serde_json::from_str(&string).unwrap();
/// let (network, metadata, extra) = deserialized.build().unwrap();
/// ```
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "version", content = "network")]
pub enum PortableCGE<E> {
    #[serde(rename = "1")]
    V1(v1::Data<E>),
}

impl<E> PortableCGE<E> {
    /// Builds the `PortableCGE` into a [`Network`], its [`CommonMetadata`], and the user defined
    /// extra data.
    pub fn build(self) -> Result<(Network, CommonMetadata, E), network::Error> {
        match self {
            Self::V1(e) => e.build(),
        }
    }
}

impl<E> From<v1::Data<E>> for PortableCGE<E> {
    fn from(net: Data<E>) -> Self {
        Self::V1(net)
    }
}

/// A metadata type that can be produced from all encoding versions.
///
/// `CommonMetadata` can also be converted to specific metadata versions if all required fields are
/// present using `Self::into_*`.
#[derive(Clone, Debug)]
pub struct CommonMetadata {
    pub description: Option<String>,
}

impl CommonMetadata {
    fn new(description: Option<String>) -> Self {
        Self { description }
    }

    /// Tries to convert `self` into the metadata type of the latest version, discarding any
    /// unused fields and returning `None` if any required fields are missing.
    pub fn into_latest_version(self) -> Option<Metadata> {
        Some(Metadata::new(self.description))
    }

    /// Converts `self` into the metadata type of version one, discarding any unused fields.
    pub fn into_v1(self) -> v1::Metadata {
        v1::Metadata::new(self.description)
    }
}

/// A trait implemented by all versioned encoding types.
pub trait EncodingVersion<E>: Into<PortableCGE<E>> {
    /// The metadata type for this version.
    type Metadata: Into<CommonMetadata>;

    /// Creates a [`PortableCGE`] from a network, its metadata, and the user-defined extra data,
    /// which can be set to `()` if unused.
    fn new(network: &Network, metadata: Self::Metadata, extra: E) -> PortableCGE<E>;

    /// Converts `self` into a [`Network`][crate::Network], its metadata, and the user-defined
    /// extra data.
    fn build(self) -> Result<(Network, CommonMetadata, E), network::Error>;
}

/// A trait implemented by all versioned metadata types.
pub trait MetadataVersion<E> {
    type Data: EncodingVersion<E, Metadata = Self>;
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Read;

    use super::*;

    fn get_file_path(file_name: &str) -> String {
        format!("{}/test_data/{}", env!("CARGO_MANIFEST_DIR"), file_name)
    }

    #[test]
    fn test_v1() {
        let mut loaded_string = String::new();

        let mut file = File::open(get_file_path("test_network_v1.cge")).unwrap();
        file.read_to_string(&mut loaded_string).unwrap();

        // Load and save a network in the v1 format
        let (network, metadata, extra) = Network::load_str::<()>(&loaded_string).unwrap();
        let metadata = v1::Metadata::new(metadata.description);
        let saved_string = network.to_string(metadata, extra).unwrap();

        assert_eq!(loaded_string.trim(), saved_string.trim());
    }
}
<commit_msg>Use type aliases instead of re-exports for latest encoding version types<commit_after>//! A portable encoding for `cge` [`Network`]s. See [`PortableCGE`].

mod error;
mod functions;
pub mod v1;

use serde::{Deserialize, Serialize};

use crate::network::{self, Network};

pub use error::Error;
pub(crate) use functions::*;

/// The latest metadata version.
pub type Metadata = v1::Metadata;
/// The latest encoding version.
pub type Data<E> = v1::Data<E>;

/// The portable encoding type, which can be serialized and deserialized to save or load networks
/// and their metadata.
///
/// [`Network::load_file`], [`Network::to_file`], and related methods are more convenient to use,
/// but this type must be used when deserializing from a format other than JSON. See
/// [`Network::to_serializable`] for serialization to different formats.
///
/// # Examples
///
/// ```
/// # let string =
/// #     include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/test_data/test_network_v1.cge"));
/// use cge::encoding::PortableCGE;
///
/// // Any format supported by `serde` can be used here
/// let deserialized: PortableCGE<()> = serde_json::from_str(&string).unwrap();
/// let (network, metadata, extra) = deserialized.build().unwrap();
/// ```
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "version", content = "network")]
pub enum PortableCGE<E> {
    #[serde(rename = "1")]
    V1(v1::Data<E>),
}

impl<E> PortableCGE<E> {
    /// Builds the `PortableCGE` into a [`Network`], its [`CommonMetadata`], and the user defined
    /// extra data.
    pub fn build(self) -> Result<(Network, CommonMetadata, E), network::Error> {
        match self {
            Self::V1(e) => e.build(),
        }
    }
}

impl<E> From<v1::Data<E>> for PortableCGE<E> {
    fn from(net: Data<E>) -> Self {
        Self::V1(net)
    }
}

/// A metadata type that can be produced from all encoding versions.
///
/// `CommonMetadata` can also be converted to specific metadata versions if all required fields are
/// present using `Self::into_*`.
#[derive(Clone, Debug)]
pub struct CommonMetadata {
    pub description: Option<String>,
}

impl CommonMetadata {
    fn new(description: Option<String>) -> Self {
        Self { description }
    }

    /// Tries to convert `self` into the metadata type of the latest version, discarding any
    /// unused fields and returning `None` if any required fields are missing.
    pub fn into_latest_version(self) -> Option<Metadata> {
        Some(Metadata::new(self.description))
    }

    /// Converts `self` into the metadata type of version one, discarding any unused fields.
    pub fn into_v1(self) -> v1::Metadata {
        v1::Metadata::new(self.description)
    }
}

/// A trait implemented by all versioned encoding types.
pub trait EncodingVersion<E>: Into<PortableCGE<E>> {
    /// The metadata type for this version.
    type Metadata: Into<CommonMetadata>;

    /// Creates a [`PortableCGE`] from a network, its metadata, and the user-defined extra data,
    /// which can be set to `()` if unused.
    fn new(network: &Network, metadata: Self::Metadata, extra: E) -> PortableCGE<E>;

    /// Converts `self` into a [`Network`][crate::Network], its metadata, and the user-defined
    /// extra data.
    fn build(self) -> Result<(Network, CommonMetadata, E), network::Error>;
}

/// A trait implemented by all versioned metadata types.
pub trait MetadataVersion<E> {
    type Data: EncodingVersion<E, Metadata = Self>;
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Read;

    use super::*;

    fn get_file_path(file_name: &str) -> String {
        format!("{}/test_data/{}", env!("CARGO_MANIFEST_DIR"), file_name)
    }

    #[test]
    fn test_v1() {
        let mut loaded_string = String::new();

        let mut file = File::open(get_file_path("test_network_v1.cge")).unwrap();
        file.read_to_string(&mut loaded_string).unwrap();

        // Load and save a network in the v1 format
        let (network, metadata, extra) = Network::load_str::<()>(&loaded_string).unwrap();
        let metadata = v1::Metadata::new(metadata.description);
        let saved_string = network.to_string(metadata, extra).unwrap();

        assert_eq!(loaded_string.trim(), saved_string.trim());
    }
}
<|endoftext|>


<commit_before>use coord::Coordinate;

pub struct Cam {
    coord: Coordinate,
    buf_x: u64,
    buf_y: u64,
    range: Range,
    level_w: u64,
    level_h: u64,
}

impl Cam {
    pub fn new(buf_x: u64, buf_y: u64) -> Self {
        Cam {
            coord: Coordinate::new(0, 0),
            buf_x: buf_x,
            buf_y: buf_y,
            range: Range::new(),
            level_w: 0,
            level_h: 0,
        }
    }
    pub fn set_borders(&mut self, (w,h): (u64, u64)) {
        self.level_w = w;
        self.level_h = h;

    }

    pub fn calc_coordinates(&mut self, coord1: Coordinate, coord2: Coordinate) {

        let new_x = (coord1.get_x() + coord2.get_x()) / 2;
        let new_y = (coord1.get_y() + coord2.get_y()) / 2;
        self.coord.set_coord(new_x, new_y);
        self.coord.move_coord_with_buf(0, 0, self.buf_x, self.buf_y, self.level_w, self.level_h);

    }
    pub fn get_range(&mut self) -> Range {
        self.range = Range::calc_range(self.buf_x, self.buf_y, self);
        self.range
    }
}
#[derive(Copy, Clone)]
pub struct Range {
    pub x_min: u64,
    pub y_min: u64,
    pub x_max: u64,
    pub y_max: u64,
}

impl Range {
    fn new() -> Self {
        Range {
            x_min: 0,
            y_min: 0,
            x_max: 0,
            y_max: 0,
        }
    }
    fn calc_range(buf_x: u64, buf_y: u64, cam:&mut Cam) -> Self {
        let mut new = Range::new();
        new.x_min = if cam.coord.get_x() < buf_x {
            0
        } else {
            cam.coord.get_x() - buf_x
        };
        new.y_min = if cam.coord.get_y() < buf_y {
            0
        } else {
            cam.coord.get_y() - buf_y
        };
        new.x_max = if cam.coord.get_x() + buf_x > cam.level_w {
            cam.level_w
        } else {
            cam.coord.get_x() + buf_x
        };
        new.y_max = if cam.coord.get_y() + buf_y > cam.level_h {
            cam.level_h
        } else {
            cam.coord.get_y() + buf_y
        };
        // DEBUG
        println!("{} {} {} {} coord: {:?}", new.x_max, new.x_min, new.y_max, new.y_min, cam.coord);
        new

    }
}
<commit_msg>Autoformat Code<commit_after>use coord::Coordinate;

pub struct Cam {
    coord: Coordinate,
    buf_x: u64,
    buf_y: u64,
    range: Range,
    level_w: u64,
    level_h: u64,
}

impl Cam {
    pub fn new(buf_x: u64, buf_y: u64) -> Self {
        Cam {
            coord: Coordinate::new(0, 0),
            buf_x: buf_x,
            buf_y: buf_y,
            range: Range::new(),
            level_w: 0,
            level_h: 0,
        }
    }
    pub fn set_borders(&mut self, (w, h): (u64, u64)) {
        self.level_w = w;
        self.level_h = h;

    }

    pub fn calc_coordinates(&mut self, coord1: Coordinate, coord2: Coordinate) {

        let new_x = (coord1.get_x() + coord2.get_x()) / 2;
        let new_y = (coord1.get_y() + coord2.get_y()) / 2;
        self.coord.set_coord(new_x, new_y);
        self.coord.move_coord_with_buf(0, 0, self.buf_x, self.buf_y, self.level_w, self.level_h);

    }
    pub fn get_range(&mut self) -> Range {
        self.range = Range::calc_range(self.buf_x, self.buf_y, self);
        self.range
    }
}
#[derive(Copy, Clone)]
pub struct Range {
    pub x_min: u64,
    pub y_min: u64,
    pub x_max: u64,
    pub y_max: u64,
}

impl Range {
    fn new() -> Self {
        Range {
            x_min: 0,
            y_min: 0,
            x_max: 0,
            y_max: 0,
        }
    }
    fn calc_range(buf_x: u64, buf_y: u64, cam: &mut Cam) -> Self {
        let mut new = Range::new();
        new.x_min = if cam.coord.get_x() < buf_x {
            0
        } else {
            cam.coord.get_x() - buf_x
        };
        new.y_min = if cam.coord.get_y() < buf_y {
            0
        } else {
            cam.coord.get_y() - buf_y
        };
        new.x_max = if cam.coord.get_x() + buf_x > cam.level_w {
            cam.level_w
        } else {
            cam.coord.get_x() + buf_x
        };
        new.y_max = if cam.coord.get_y() + buf_y > cam.level_h {
            cam.level_h
        } else {
            cam.coord.get_y() + buf_y
        };
        // DEBUG
        //println!("{} {} {} {} coord: {:?}", new.x_max, new.x_min, new.y_max, new.y_min, cam.coord);
        new

    }
}
<|endoftext|>


<commit_before>use std::io::{Cursor, Seek, SeekFrom};
use std::cmp;

use byteorder::{LittleEndian, ReadBytesExt};

use mesh;
use asset;
use model;

use vertex;

extern {
  /// The `llvm.convert.from.fp16.f64` intrinsic.
  #[link_name = "llvm.convert.from.fp16.f64"]
  pub fn convert_from_fp16_f64(a: i16) -> f64;
}

pub fn export(asset: &asset::Asset) -> Vec<(String, String)> {
  let mut files = Vec::new();

  for object in &asset.objects {
    match object {
      &asset::Object::Model(ref m) => files.push_all(export_model(m).as_slice())
    }
  }

  return files;
}

pub fn export_model(model: &model::Model) -> Vec<(String, String)> {
  let mut result = String::new();

  let mesh = &model.mesh;

  if !write("v", vertex::AttributeName::Position, 4, mesh, &mut result) {
    panic!("No positions when exporting to .obj");
  }

  let textures_written = write("vt", vertex::AttributeName::TextureCoordinate, 3, mesh, &mut result);
  let normals_written = write("vn", vertex::AttributeName::Normal, 3, mesh, &mut result);

  for submesh in &mesh.submeshes {
    write_faces(textures_written, normals_written, &submesh, &mut result);
  }

  return vec![(mesh.name.clone() + ".obj", result)];
}

fn write(prefix: &str, name: vertex::AttributeName, max_elements: usize, mesh: &mesh::Mesh, result: &mut String) -> bool {
  let attribute = match mesh.attribute_for(&name) {
    Some(s) => s, None => return false
  };

  let vertex_buffer = &mesh.buffers[attribute.buffer_index];
  let mut cursor = Cursor::new(vertex_buffer.as_slice());

  cursor.seek(SeekFrom::Current(attribute.offset as i64)).unwrap();

  let elements = cmp::min(attribute.format.elements(), max_elements);

  let stride = &mesh.descriptor.layouts[attribute.buffer_index].stride;

  for i in 0 .. mesh.vertex_count {
    cursor.seek(SeekFrom::Start((stride * i + attribute.offset) as u64)).unwrap();

    result.push_str(prefix);
    for _ in 0 .. elements {
      let value = match attribute.format.scalar() {
        vertex::Scalar::f16 => unsafe { convert_from_fp16_f64(cursor.read_i16::<LittleEndian>().unwrap()) },
        vertex::Scalar::i16 => cursor.read_i16::<LittleEndian>().unwrap() as f64,
        _ => panic!("Unknown ty when exporting .obj")
      };

      result.push_str(format!(" {}", value).as_str());
    }
    result.push_str("\n");
  }

  return true;
}

fn write_faces(textures_written: bool, normals_written: bool, submesh: &mesh::Submesh, result: &mut String) {
  result.push_str(format!("o {}\n", submesh.name).as_str());

  for face in submesh.faces() {
    result.push_str("  f");

    for vertex in face {
      write_face_part(textures_written, normals_written, vertex + 1, result);
    }

    result.push_str("\n")
  }
}

fn write_face_part(textures_written: bool, normals_written: bool, value: usize, result: &mut String) {
  result.push_str(format!(" {}", value).as_str());

  if textures_written {
    result.push_str(format!("/{}", value).as_str());
  }

  if normals_written {
    if !textures_written { result.push_str("/") };

    result.push_str(format!("/{}", value).as_str());
  }
}
<commit_msg>Reduce the obj exporter, again<commit_after>use mesh;
use asset;
use model;

use vertex;

pub fn export(asset: &asset::Asset) -> Vec<(String, String)> {
  let mut files = Vec::new();

  for object in &asset.objects {
    match object {
      &asset::Object::Model(ref m) => files.push_all(export_model(m).as_slice())
    }
  }

  return files;
}

pub fn export_model(model: &model::Model) -> Vec<(String, String)> {
  let mut result = String::new();

  let mesh = &model.mesh;

  if !write("v", vertex::AttributeName::Position, 4, mesh, &mut result) {
    panic!("No positions when exporting to .obj");
  }

  let textures_written = write("vt", vertex::AttributeName::TextureCoordinate, 3, mesh, &mut result);
  let normals_written = write("vn", vertex::AttributeName::Normal, 3, mesh, &mut result);

  for submesh in &mesh.submeshes {
    write_faces(textures_written, normals_written, &submesh, &mut result);
  }

  return vec![(mesh.name.clone() + ".obj", result)];
}

fn write(prefix: &str, name: vertex::AttributeName, max_elements: usize, mesh: &mesh::Mesh, result: &mut String) -> bool {
  if let Some(view) = mesh.untyped_view_for(&name) {
    for i in 0 .. view.len() {
      let value: Vec<String> = view.get_f32(i).iter().take(max_elements).map(|x| format!("{}", x)).collect();

      result.push_str(format!("{} {}\n", prefix, value.join(" ")).as_str());
    }

    return true;
  }

  return false;
}

fn write_faces(textures_written: bool, normals_written: bool, submesh: &mesh::Submesh, result: &mut String) {
  result.push_str(format!("o {}\n", submesh.name).as_str());

  for face in submesh.faces() {
    result.push_str("  f");

    for vertex in face {
      write_face_part(textures_written, normals_written, vertex + 1, result);
    }

    result.push_str("\n")
  }
}

fn write_face_part(textures_written: bool, normals_written: bool, value: usize, result: &mut String) {
  result.push_str(format!(" {}", value).as_str());

  if textures_written {
    result.push_str(format!("/{}", value).as_str());
  }

  if normals_written {
    if !textures_written { result.push_str("/") };

    result.push_str(format!("/{}", value).as_str());
  }
}
<|endoftext|>


<commit_before>#![feature(phase)]

#[phase(plugin, link)]
extern crate conrod;
extern crate piston;
extern crate collections;
extern crate string_telephone;
extern crate opengl_graphics;
extern crate sdl2_game_window;

use opengl_graphics::{
    Gl,
    Texture,
};

use conrod::{
    UIContext,
    label,
    Color,
    Point,
    widget_matrix,
    Button,
    Callable,
    Colorable,
    Drawable,
    DropDownList,
    EnvelopeEditor,
    Frameable,
    Labelable,
    NumberDialer,
    Positionable,
    Slider,
    Shapeable,
    TextBox,
    Toggle,
    XYPad,
};

use collections::str::{Slice, Owned};
use std::io::net::ip::{Ipv4Addr, SocketAddr};
use piston::{EventIterator, EventSettings, WindowSettings, graphics, Render};
use piston::graphics::{AddColor, Draw};
use string_telephone::{Client, ConnectionConfig, UserPacket, Command, PacketDisconnect, PacketConnect};
use sdl2_game_window::WindowSDL2;

fn deserializer(message: &Vec<u8>) -> String {
    match String::from_utf8_lossy(message.as_slice()) {
        Slice(slice) => slice.to_string(),
        Owned(item) => item
    }
}

fn serializer(packet: &String) -> Vec<u8> {
    packet.clone().into_bytes()
}

fn main() {
    let settings = ConnectionConfig {
        protocol_id: 88869,
        timeout_period: 10,
        packet_deserializer: deserializer,
        packet_serializer: serializer
    };

    /*let mut client = match Client::connect(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 0}, SocketAddr {ip: Ipv4Addr(127, 0, 0, 1), port: 8869}, settings) {
        Ok(client) => {
            client
        },
        Err(e) => fail!("Failed to connect - {}", e)
    };*/

    let opengl = piston::shader_version::opengl::OpenGL_3_2;
    let mut window = WindowSDL2::new(
        opengl,
        WindowSettings {
            title: "SuperMegaTag".to_string(),
            size: [800, 600],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    let event_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };
    let ref mut gl = Gl::new(opengl);

    let ref mut uic = UIContext::new("Dense-Regular.otf");

    let mut edit_ip = vec!["127".to_string(), "0".to_string(), "0".to_string(), "1".to_string()];

    for ref e in EventIterator::new(&mut window, &event_settings) {
        uic.handle_event(e);
        match e {
            &Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = &graphics::Context::abs(args.width as f64, args.height as f64);
                c.rgb(1.0, 1.0, 1.0).draw(gl);
                label::draw(
                    gl,
                    uic,
                    Point::new(0f64, 0f64, 0f64), // Screen position.
                    48u32, // Font size.
                    Color::new(1.0, 0.0, 0.0, 1.0),
                    "Select a server"
                );

                widget_matrix::draw(
                    4, // cols.
                    1, // rows.
                    Point::new(0.0, 56.0, 0.0), // matrix position.
                    300.0, // width.
                    240.0, // height.
                    |num, col, row, pos, width, height| { // This is called for every widget.
                        // Now draw the widgets with the given callback.
                        uic.text_box(2 + num as u64, edit_ip.get_mut(num))
                            .font_size(24u32)
                            .dimensions(width, 36.0)
                            .position(pos.x, pos.y)
                            .frame(2.0, Color::black())
                            .color(Color::black())
                            .draw(gl);

                    }
                );

                uic.button(7u64)
                    .dimensions(90.0, 36.0)
                    .position(0.0, 128.0)
                    .color(Color::black())
                    .frame(2.0, Color::black())
                    .label("Connect", 24u32, Color::white())
                    .callback(|| () )
                    .draw(gl);

            },
            _ => {},
        }
    }
}
<commit_msg>Started working on scene switching<commit_after>#![feature(phase)]

#[phase(plugin, link)]
extern crate conrod;
extern crate piston;
extern crate collections;
extern crate string_telephone;
extern crate opengl_graphics;
extern crate sdl2_game_window;

use opengl_graphics::{
    Gl,
    Texture,
};

use conrod::{
    UIContext,
    label,
    Color,
    Point,
    widget_matrix,
    Button,
    Callable,
    Colorable,
    Drawable,
    DropDownList,
    EnvelopeEditor,
    Frameable,
    Labelable,
    NumberDialer,
    Positionable,
    Slider,
    Shapeable,
    TextBox,
    Toggle,
    XYPad,
};

use collections::str::{Slice, Owned};
use std::io::net::ip::{Ipv4Addr, SocketAddr};
use piston::{EventIterator, EventSettings, WindowSettings, graphics, Render, Event};
use piston::graphics::{AddColor, Draw};
use string_telephone::{Client, ConnectionConfig, UserPacket, Command, PacketDisconnect, PacketConnect};
use sdl2_game_window::WindowSDL2;

trait Scene<T> {
    fn handle_event(&mut self, e: &Event, state: &T);
}

struct ConnectScene<T>;

impl <T> Scene<uint> for ConnectScene <T> {
    fn handle_event(&mut self, e: &Event, state: &uint) {
    }
}

struct SceneManager <T> {
    current_scene: Box<Scene<T> + 'static>
}

impl <T> SceneManager <T> {
    pub fn new(initial_scene: Box<Scene<T> + 'static>) -> SceneManager<T> {
        SceneManager {
            current_scene: initial_scene
        }
    }

    pub fn set_scene(&mut self, new_scene: Box<Scene<T> + 'static>) {
        self.current_scene = new_scene
    }
}

fn deserializer(message: &Vec<u8>) -> String {
    match String::from_utf8_lossy(message.as_slice()) {
        Slice(slice) => slice.to_string(),
        Owned(item) => item
    }
}

fn serializer(packet: &String) -> Vec<u8> {
    packet.clone().into_bytes()
}

fn main() {
    let settings = ConnectionConfig {
        protocol_id: 88869,
        timeout_period: 10,
        packet_deserializer: deserializer,
        packet_serializer: serializer
    };

    /*let mut client = match Client::connect(SocketAddr {ip: Ipv4Addr(0, 0, 0, 0), port: 0}, SocketAddr {ip: Ipv4Addr(127, 0, 0, 1), port: 8869}, settings) {
        Ok(client) => {
            client
        },
        Err(e) => fail!("Failed to connect - {}", e)
    };*/

    let opengl = piston::shader_version::opengl::OpenGL_3_2;
    let mut window = WindowSDL2::new(
        opengl,
        WindowSettings {
            title: "SuperMegaTag".to_string(),
            size: [800, 600],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    let event_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };
    let ref mut gl = Gl::new(opengl);

    let ref mut uic = UIContext::new("Dense-Regular.otf");

    let mut edit_ip = vec!["127".to_string(), "0".to_string(), "0".to_string(), "1".to_string()];

    let mut manager = SceneManager::new(box ConnectScene::<uint>);

    for ref e in EventIterator::new(&mut window, &event_settings) {
        uic.handle_event(e);
        match e {
            &Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = &graphics::Context::abs(args.width as f64, args.height as f64);
                c.rgb(1.0, 1.0, 1.0).draw(gl);
                label::draw(
                    gl,
                    uic,
                    Point::new(0f64, 0f64, 0f64), // Screen position.
                    48u32, // Font size.
                    Color::new(1.0, 0.0, 0.0, 1.0),
                    "Select a server"
                );

                widget_matrix::draw(
                    4, // cols.
                    1, // rows.
                    Point::new(0.0, 56.0, 0.0), // matrix position.
                    300.0, // width.
                    240.0, // height.
                    |num, col, row, pos, width, height| { // This is called for every widget.
                        // Now draw the widgets with the given callback.
                        uic.text_box(2 + num as u64, edit_ip.get_mut(num))
                            .font_size(24u32)
                            .dimensions(width, 36.0)
                            .position(pos.x, pos.y)
                            .frame(2.0, Color::black())
                            .color(Color::black())
                            .draw(gl);

                    }
                );

                uic.button(7u64)
                    .dimensions(90.0, 36.0)
                    .position(0.0, 128.0)
                    .color(Color::black())
                    .frame(2.0, Color::black())
                    .label("Connect", 24u32, Color::white())
                    .callback(|| () )
                    .draw(gl);

            },
            _ => {},
        }
    }
}
<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();
    static mut visit_count : int = 0;

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            let first_line = request_str.split('\n').next().unwrap();
            let first_line_array = first_line.split(' ').to_owned_vec();

            if (first_line_array[0].trim() == "GET" &&
                    first_line_array[2].trim() == "HTTP/1.1" &&
                    first_line_array[1].trim() != "/")  {

                let filepath = ~std::path::posix::Path::new(
                    first_line_array[1].trim().split('/').to_owned_vec()[1].trim());
                    // ^ Removes leading '/' in order to get into current directory.

                let mut response : ~str = ~"";

                if (filepath.is_file()) {

                    if (first_line_array[1].trim().split('.').last().unwrap() == "html") {
                        let mut file = File::open(filepath);
                        stream.write(file.read_to_end());
                    }

                    else { response = response + format!("HTTP/1.1 403 FORBIDDEN"); }
                }

                else { response = response + format!("HTTP/1.1 404 NOT FOUND"); }

                if (!filepath.is_file() || first_line_array[1].trim().split('.').last().unwrap() != "html") {
                    response = response +
                        format!("\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                        <doctype !html><title>{:s}</title>

{:s}

                            This isn't the file you are looking for.

                         \r\n",
                         if(!filepath.is_file()) { "404 - NOT FOUND" } else { "403 - FORBIDDEN" },
                         if(!filepath.is_file()) { "404 - NOT FOUND" } else { "403 - FORBIDDEN" });
                    stream.write(response.as_bytes());
                }
            }
            else {
                unsafe {
                    visit_count += 1;

                    let response: ~str =
                        format!("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                         <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

Visitor count is {:d}.

                         \r\n", visit_count);
                    stream.write(response.as_bytes());
                }
            }
            println!("Connection terminates.");
        }
    }
}
<commit_msg>Fixed string comparison errors, added checking for moving up dirs. Other small fixes.<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();
    static mut visit_count : int = 0;

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            let first_line = request_str.split('\n').next().unwrap();
            let first_line_array = first_line.split(' ').to_owned_vec();

            if (str::eq(&first_line_array[0].trim().to_owned(), &~"GET") &&
                    str::eq(&first_line_array[2].trim().to_owned(), &~"HTTP/1.1") &&
                    !str::eq(&first_line_array[1].trim().to_owned(), &~"/"))  {

                let filepathStr = first_line_array[1].trim().slice_from(1);
                    // ^ Removes leading '/' in order to get into cwd.

                let filepath = ~std::path::posix::Path::new(filepathStr);

                let mut response : ~str = ~"";
                let isHTML : bool = str::eq(&filepathStr.slice_from(filepathStr.len() - 5).to_owned(), &~".html")
                    && !filepathStr.contains("../");

                if (isHTML) {
                    if (filepath.is_file()) {
                        let mut file = File::open(filepath);
                        stream.write(file.read_to_end());
                    }
                    else { response = response + format!("HTTP/1.1 404 NOT FOUND"); }
                }
                else { response = response + format!("HTTP/1.1 403 FORBIDDEN"); }

                if (!filepath.is_file() || !isHTML) {
                    response = response +
                        format!("\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                        <doctype !html><title>{:s}</title>

{:s}

                            This isn't the file you are looking for.

                         \r\n",
                         if(isHTML) { "404 - NOT FOUND" } else { "403 - FORBIDDEN" },
                         if(isHTML) { "404 - NOT FOUND" } else { "403 - FORBIDDEN" });
                    stream.write(response.as_bytes());
                }
            }
            else {
                unsafe {
                    visit_count += 1;

                    let response: ~str =
                        format!("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                         <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

Visitor count is {:d}.

                         \r\n", visit_count);
                    stream.write(response.as_bytes());
                }
            }
            println!("Connection terminates.");
        }
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

mod util;
mod derive_enum;
mod derive_input_object;
mod derive_object;

use proc_macro::TokenStream;

#[proc_macro_derive(GraphQLEnum, attributes(graphql))]
pub fn derive_enum(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_enum::impl_enum(&ast);
    gen.parse().unwrap()
}

#[proc_macro_derive(GraphQLInputObject, attributes(graphql))]
pub fn derive_input_object(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_input_object::impl_input_object(&ast);
    gen.parse().unwrap()
}

#[proc_macro_derive(GraphQLObject, attributes(graphql))]
pub fn derive_object(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_object::impl_object(&ast);
    gen.parse().unwrap()
}
<commit_msg>(docs) Add short crate docs to codegen.<commit_after>//! This crate supplies custom derive implementations for the
//! [juniper](https://github.com/graphql-rust/juniper) crate.
//!
//! You should not depend on juniper_codegen directly.
//! You only need the `juniper` crate.

#![recursion_limit = "1024"]

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

mod util;
mod derive_enum;
mod derive_input_object;
mod derive_object;

use proc_macro::TokenStream;

#[proc_macro_derive(GraphQLEnum, attributes(graphql))]
pub fn derive_enum(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_enum::impl_enum(&ast);
    gen.parse().unwrap()
}

#[proc_macro_derive(GraphQLInputObject, attributes(graphql))]
pub fn derive_input_object(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_input_object::impl_input_object(&ast);
    gen.parse().unwrap()
}

#[proc_macro_derive(GraphQLObject, attributes(graphql))]
pub fn derive_object(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = derive_object::impl_object(&ast);
    gen.parse().unwrap()
}
<|endoftext|>


<commit_before>#[derive(Debug)]
pub struct SceneNode {
    pub name: String,
    pub material_id: i32,
    pub start_position: i32,
    pub end_position: i32,
}

#[derive(Debug)]
pub struct Material {
    pub name: String,
    pub diffuse: [f32; 3],
    pub diffuse_texname: String,
}

#[derive(Debug)]
pub struct Shader {
    pub name: String,
    // pub vertex_source_110: String,
    // pub fragment_source_110: String,
    // pub vertex_source_120: String,
    // pub fragment_source_120: String,
    // pub vertex_source_130: String,
    // pub fragment_source_130: String,
    pub vertex_source_140: String,
    pub fragment_source_140: String, /* pub vertex_source_150: String,
                                      * pub fragment_source_150: String,
                                      * pub vertex_source_330: String,
                                      * pub fragment_source_330: String,
                                      * pub vertex_source_400: String,
                                      * pub fragment_source_400: String,
                                      * pub vertex_source_410: String,
                                      * pub fragment_source_401: String,
                                      * pub vertex_source_420: String,
                                      * pub fragment_source_420: String,
                                      * pub vertex_source_430: String,
                                      * pub fragment_source_430: String,
                                      * pub vertex_source_100es: String,
                                      * pub fragment_source_100es: String,
                                      * pub vertex_source_300es: String,
                                      * pub fragment_source_300es: String,
                                      * */
}

#[derive(Debug)]
#[derive(Copy, Clone)]
pub struct Vertex8f32 {
    pub position: [f32; 3],
    pub normal: [f32; 3],
    pub texcoord: [f32; 2],
}

#[derive(Debug)]
pub struct Mesh {
    pub name: String,
    pub vertices: Vec<Vertex8f32>,
    pub material_id: i32,
}

#[derive(Debug)]
pub struct Scene {
    pub materials: Vec<Material>,
    pub meshes: Vec<Mesh>,
    pub shaders: Vec<Shader>,
}
<commit_msg>added Clone to material and mesh<commit_after>#[derive(Debug)]
pub struct SceneNode {
    pub name: String,
    pub material_id: i32,
    pub start_position: i32,
    pub end_position: i32,
}

#[derive(Debug)]
#[derive(Clone)]
pub struct Material {
    pub name: String,
    pub diffuse: [f32; 3],
    pub diffuse_texname: String,
}

#[derive(Debug)]
pub struct Shader {
    pub name: String,
    // pub vertex_source_110: String,
    // pub fragment_source_110: String,
    // pub vertex_source_120: String,
    // pub fragment_source_120: String,
    // pub vertex_source_130: String,
    // pub fragment_source_130: String,
    pub vertex_source_140: String,
    pub fragment_source_140: String, /* pub vertex_source_150: String,
                                      * pub fragment_source_150: String,
                                      * pub vertex_source_330: String,
                                      * pub fragment_source_330: String,
                                      * pub vertex_source_400: String,
                                      * pub fragment_source_400: String,
                                      * pub vertex_source_410: String,
                                      * pub fragment_source_401: String,
                                      * pub vertex_source_420: String,
                                      * pub fragment_source_420: String,
                                      * pub vertex_source_430: String,
                                      * pub fragment_source_430: String,
                                      * pub vertex_source_100es: String,
                                      * pub fragment_source_100es: String,
                                      * pub vertex_source_300es: String,
                                      * pub fragment_source_300es: String,
                                      * */
}

#[derive(Debug)]
#[derive(Copy, Clone)]
pub struct Vertex8f32 {
    pub position: [f32; 3],
    pub normal: [f32; 3],
    pub texcoord: [f32; 2],
}

#[derive(Debug)]
#[derive(Clone)]
pub struct Mesh {
    pub name: String,
    pub vertices: Vec<Vertex8f32>,
    pub material_id: i32,
}

#[derive(Debug)]
pub struct Scene {
    pub materials: Vec<Material>,
    pub meshes: Vec<Mesh>,
    pub shaders: Vec<Shader>,
}
<|endoftext|>