<commit_before>use common::file_utils::{PathBufWithAdded, create_dir};
use common::utils::run_command;
use common::cpp_lib_builder::{CppLibBuilder, BuildType};
use common::errors::fancy_unwrap;
use config::{Config, CrateProperties, CacheUsage};
use common::cpp_build_config::CppBuildConfigData;
use common::target;
use common::cargo_override::set_cargo_override;
use std::process::Command;
use std::path::PathBuf;
use tests::TempTestDir;

fn build_cpp_lib() -> TempTestDir {
  let cpp_lib_source_dir = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("cpp");
    path
  };
  assert!(cpp_lib_source_dir.exists());
  let temp_dir = TempTestDir::new("test_full_run");
  let build_dir = temp_dir.path().with_added("build");
  let install_dir = temp_dir.path().with_added("install");
  if !build_dir.exists() {
    create_dir(&build_dir).unwrap();
  }
  if !install_dir.exists() {
    create_dir(&install_dir).unwrap();
  }
  fancy_unwrap(CppLibBuilder {
                   cmake_source_dir: cpp_lib_source_dir,
                   build_dir: build_dir,
                   build_type: BuildType::Release,
                   install_dir: install_dir,
                   num_jobs: None,
                   cmake_vars: Vec::new(),
                 }
                 .run());
  temp_dir
}

#[test]
fn full_run() {
  let temp_dir = build_cpp_lib();
  let crate_dir = temp_dir.path().with_added("crate");
  let cpp_install_lib_dir = temp_dir.path().with_added("install").with_added("lib");
  assert!(cpp_install_lib_dir.exists());
  let mut crate_properties = CrateProperties::new("rust_ctrt1", "0.0.0");
  crate_properties.set_links_attribute("ctrt1");

  let mut config = Config::new(&crate_dir,
                               temp_dir.path().with_added("cache"),
                               crate_properties);
  config.add_include_directive("ctrt1/all.h");
  let include_path = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("cpp");
    path.push("include");
    path
  };
  let crate_template_path = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("crate");
    path
  };
  assert!(include_path.exists());
  config.add_include_path(&include_path);
  config.add_target_include_path(&include_path);

  {
    let mut data = CppBuildConfigData::new();
    data.add_linked_lib("ctrt1");
    config
      .cpp_build_config_mut()
      .add(target::Condition::True, data);
  }
  {
    let mut data = CppBuildConfigData::new();
    data.add_compiler_flag("-fPIC");
    data.add_compiler_flag("-std=gnu++11");
    config
      .cpp_build_config_mut()
      .add(target::Condition::Env(target::Env::Msvc).negate(), data);
  }
  if target::current_env() == target::Env::Msvc {
    config.add_cpp_parser_flag("-std=c++14");
  } else {
    config.add_cpp_parser_flag("-std=gnu++11");
  }
  config.set_crate_template_path(&crate_template_path);
  config.set_cache_usage(CacheUsage::None);
  fancy_unwrap(config.exec());
  assert!(crate_dir.exists());

  for cargo_cmd in &["update", "build", "test", "doc"] {
    let mut command = Command::new("cargo");
    command.arg(cargo_cmd);
    command.arg("-v");
    if *cargo_cmd != "update" {
      command.arg("-j1");
    }
    command.current_dir(&crate_dir);
    command.env("CPP_TO_RUST_INCLUDE_PATHS", &include_path);
    command.env("CPP_TO_RUST_LIB_PATHS", &cpp_install_lib_dir);
    run_command(&mut command).unwrap();
  }
}
<commit_msg>build fix<commit_after>use common::file_utils::{PathBufWithAdded, create_dir};
use common::utils::run_command;
use common::cpp_lib_builder::{CppLibBuilder, BuildType};
use common::errors::fancy_unwrap;
use config::{Config, CrateProperties, CacheUsage};
use common::cpp_build_config::CppBuildConfigData;
use common::target;
use std::process::Command;
use std::path::PathBuf;
use tests::TempTestDir;

fn build_cpp_lib() -> TempTestDir {
  let cpp_lib_source_dir = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("cpp");
    path
  };
  assert!(cpp_lib_source_dir.exists());
  let temp_dir = TempTestDir::new("test_full_run");
  let build_dir = temp_dir.path().with_added("build");
  let install_dir = temp_dir.path().with_added("install");
  if !build_dir.exists() {
    create_dir(&build_dir).unwrap();
  }
  if !install_dir.exists() {
    create_dir(&install_dir).unwrap();
  }
  fancy_unwrap(CppLibBuilder {
                   cmake_source_dir: cpp_lib_source_dir,
                   build_dir: build_dir,
                   build_type: BuildType::Release,
                   install_dir: install_dir,
                   num_jobs: None,
                   cmake_vars: Vec::new(),
                 }
                 .run());
  temp_dir
}

#[test]
fn full_run() {
  let temp_dir = build_cpp_lib();
  let crate_dir = temp_dir.path().with_added("crate");
  let cpp_install_lib_dir = temp_dir.path().with_added("install").with_added("lib");
  assert!(cpp_install_lib_dir.exists());
  let mut crate_properties = CrateProperties::new("rust_ctrt1", "0.0.0");
  crate_properties.set_links_attribute("ctrt1");

  let mut config = Config::new(&crate_dir,
                               temp_dir.path().with_added("cache"),
                               crate_properties);
  config.add_include_directive("ctrt1/all.h");
  let include_path = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("cpp");
    path.push("include");
    path
  };
  let crate_template_path = {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("test_assets");
    path.push("ctrt1");
    path.push("crate");
    path
  };
  assert!(include_path.exists());
  config.add_include_path(&include_path);
  config.add_target_include_path(&include_path);

  {
    let mut data = CppBuildConfigData::new();
    data.add_linked_lib("ctrt1");
    config
      .cpp_build_config_mut()
      .add(target::Condition::True, data);
  }
  {
    let mut data = CppBuildConfigData::new();
    data.add_compiler_flag("-fPIC");
    data.add_compiler_flag("-std=gnu++11");
    config
      .cpp_build_config_mut()
      .add(target::Condition::Env(target::Env::Msvc).negate(), data);
  }
  if target::current_env() == target::Env::Msvc {
    config.add_cpp_parser_flag("-std=c++14");
  } else {
    config.add_cpp_parser_flag("-std=gnu++11");
  }
  config.set_crate_template_path(&crate_template_path);
  config.set_cache_usage(CacheUsage::None);
  fancy_unwrap(config.exec());
  assert!(crate_dir.exists());

  for cargo_cmd in &["update", "build", "test", "doc"] {
    let mut command = Command::new("cargo");
    command.arg(cargo_cmd);
    command.arg("-v");
    if *cargo_cmd != "update" {
      command.arg("-j1");
    }
    command.current_dir(&crate_dir);
    command.env("CPP_TO_RUST_INCLUDE_PATHS", &include_path);
    command.env("CPP_TO_RUST_LIB_PATHS", &cpp_install_lib_dir);
    run_command(&mut command).unwrap();
  }
}
<|endoftext|>


<commit_before>extern crate regex;

use regex::Regex;

struct Gradient {
    start: Vec<u32>,
    steps: Vec<u32>,
    n: u32,
    total: u32,
}

impl Gradient {
    fn to_parts(hex: &str) -> Vec<u32> {
        let re = Regex::new(r"[0-9a-fA-F]{2}").unwrap();

        re.split(&hex)
          .map(|c| u32::from_str_radix(c, 16).unwrap_or(0))
          .collect()
    }

    fn to_steps(start: &[u32], stop: &[u32]) -> Vec<u32> {
        vec![17, 17, 17]
    }

    pub fn new(start: String, stop: String, n: u32) -> Gradient {
        let from = Gradient::to_parts(&start[..]);
        let to = Gradient::to_parts(&stop[..]);
        let steps = Gradient::to_steps(&from[..], &to[..]);

        Gradient{
            start: from,
            steps: steps,
            n: 0,
            total: n,
        }
    }
}

impl Iterator for Gradient {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        match self.n {
            n if n == self.total => None,
            n => {
                let rgb: String = self.start
                    .iter()
                    .zip(self.steps.iter())
                    .map(|(&a, &b)| a + (b * n))
                    .map(|i| format!("{:02x}", i))
                    .collect();

                self.n += 1;

                Some(rgb)
            }
        }
    }
}

fn main() {
    let g = Gradient::new("000000".to_string(), "ffffff".to_string(), 10000);

    g.collect::<Vec<String>>();
}

#[test]
fn it_works() {
    let g = Gradient::new("000000".to_string(), "ffffff".to_string(), 16);
    let result = vec!["000000", "111111", "222222", "333333", "444444",
                      "555555", "666666", "777777", "888888", "999999",
                      "aaaaaa", "bbbbbb", "cccccc", "dddddd", "eeeeee",
                      "ffffff"];

    assert_eq!(g.collect::<Vec<String>>(), result.iter().map(|r| r.to_string()).collect::<Vec<String>>());
}
<commit_msg>got it working. Probably should refactor this<commit_after>struct Gradient {
    start: Vec<i32>,
    steps: Vec<f32>,
    n: i32,
    total: i32,
}

impl Gradient {
    fn to_parts(hex: &str) -> Vec<i32> {
        [0, 2, 4].iter()
                 .map(|&n| i32::from_str_radix(&hex[n..(n + 2)], 16).unwrap())
                 .collect()
    }

    fn to_steps(start: &[i32], stop: &[i32], n: i32) -> Vec<f32> {
        start.iter()
             .zip(stop.iter())
             .map(|(&a, &b)| (a as f32 - b as f32) / (n as f32 - 1.0))
             .collect()
    }

    pub fn new(start: &str, stop: &str, n: i32) -> Gradient {
        let from = Gradient::to_parts(&start);
        let to = Gradient::to_parts(&stop);
        let steps = Gradient::to_steps(&from[..], &to[..], n);

        Gradient{
            start: from,
            steps: steps,
            n: 0,
            total: n,
        }
    }
}

impl Iterator for Gradient {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        match self.n {
            n if n == self.total => None,
            n => {
                let rgb: String = self.start
                    .iter()
                    .zip(self.steps.iter())
                    .map(|(&a, &b)| a - (n as f32 * b) as i32)
                    .map(|i| format!("{:02x}", i))
                    .collect();

                self.n += 1;

                Some(rgb)
            }
        }
    }
}

fn main() {
    let g = Gradient::new("000000", "ffffff", 10000);

    g.collect::<Vec<String>>();
}

#[test]
fn it_works() {
    let ga = Gradient::new("000000", "ffffff", 16);
    let gb = Gradient::new("ff334c", "d8ff1a", 10);
    let result_a = vec!["000000", "111111", "222222", "333333", "444444",
                        "555555", "666666", "777777", "888888", "999999",
                        "aaaaaa", "bbbbbb", "cccccc", "dddddd", "eeeeee",
                        "ffffff"];
    let result_b = vec!["ff334c", "fb4947", "f76041", "f2773c", "ee8d36",
                        "eaa431", "e5bb2b", "e1d126", "dde820", "d8ff1a"];

    assert_eq!(ga.collect::<Vec<String>>(), result_a.iter().map(|r| r.to_string()).collect::<Vec<String>>());
    assert_eq!(gb.collect::<Vec<String>>(), result_b.iter().map(|r| r.to_string()).collect::<Vec<String>>());

    let a = Gradient::to_parts("000000");
    let b = Gradient::to_parts("ffffff");
    assert_eq!(Gradient::to_steps(&a[..], &b[..], 16), vec![-17.0, -17.0, -17.0]);

    assert_eq!(Gradient::to_parts("000000"), vec![0, 0, 0]);
    assert_eq!(Gradient::to_parts("ffffff"), vec![255, 255, 255]);
}
<|endoftext|>


<commit_before>//! FIXME: write short doc here

use crate::completion::{CompletionContext, Completions};

pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) {
    let (ty, variant) = match ctx.record_lit_pat.as_ref().and_then(|it| {
        Some((ctx.sema.type_of_pat(&it.clone().into())?, ctx.sema.resolve_record_pattern(it)?))
    }) {
        Some(it) => it,
        _ => return,
    };

    for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
        acc.add_field(ctx, field, &field_ty);
    }
}

#[cfg(test)]
mod tests {
    use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
    use insta::assert_debug_snapshot;

    fn complete(code: &str) -> Vec<CompletionItem> {
        do_completion(code, CompletionKind::Reference)
    }

    #[test]
    fn test_record_pattern_field() {
        let completions = complete(
            r"
            struct S { foo: u32 }

            fn process(f: S) {
                match f {
                    S { f<|>: 92 } => (),
                }
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "foo",
                source_range: [117; 118),
                delete: [117; 118),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }

    #[test]
    fn test_record_pattern_enum_variant() {
        let completions = complete(
            r"
            enum E {
                S { foo: u32, bar: () }
            }

            fn process(e: E) {
                match e {
                    E::S { <|> } => (),
                }
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "bar",
                source_range: [161; 161),
                delete: [161; 161),
                insert: "bar",
                kind: Field,
                detail: "()",
            },
            CompletionItem {
                label: "foo",
                source_range: [161; 161),
                delete: [161; 161),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }

    #[test]
    fn test_record_pattern_field_in_simple_macro() {
        let completions = complete(
            r"
            macro_rules! m { ($e:expr) => { $e } }
            struct S { foo: u32 }

            fn process(f: S) {
                m!(match f {
                    S { f<|>: 92 } => (),
                })
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "foo",
                source_range: [171; 172),
                delete: [171; 172),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }
}
<commit_msg>Complete only missing fields in pats<commit_after>//! FIXME: write short doc here

use crate::completion::{CompletionContext, Completions};
use ra_syntax::{ast::NameOwner, SmolStr};

pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) {
    let (ty, variant) = match ctx.record_lit_pat.as_ref().and_then(|it| {
        Some((ctx.sema.type_of_pat(&it.clone().into())?, ctx.sema.resolve_record_pattern(it)?))
    }) {
        Some(it) => it,
        _ => return,
    };

    let already_present_names: Vec<SmolStr> = ctx
        .record_lit_pat
        .as_ref()
        .and_then(|record_pat| record_pat.record_field_pat_list())
        .map(|pat_list| pat_list.bind_pats())
        .map(|bind_pats| {
            bind_pats
                .into_iter()
                .filter_map(|pat| pat.name())
                .map(|name| name.text().clone())
                .collect()
        })
        .unwrap_or_default();

    for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
        if !already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string())) {
            acc.add_field(ctx, field, &field_ty);
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
    use insta::assert_debug_snapshot;

    fn complete(code: &str) -> Vec<CompletionItem> {
        do_completion(code, CompletionKind::Reference)
    }

    #[test]
    fn test_record_pattern_field() {
        let completions = complete(
            r"
            struct S { foo: u32 }

            fn process(f: S) {
                match f {
                    S { f<|>: 92 } => (),
                }
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "foo",
                source_range: [117; 118),
                delete: [117; 118),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }

    #[test]
    fn test_record_pattern_enum_variant() {
        let completions = complete(
            r"
            enum E {
                S { foo: u32, bar: () }
            }

            fn process(e: E) {
                match e {
                    E::S { <|> } => (),
                }
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "bar",
                source_range: [161; 161),
                delete: [161; 161),
                insert: "bar",
                kind: Field,
                detail: "()",
            },
            CompletionItem {
                label: "foo",
                source_range: [161; 161),
                delete: [161; 161),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }

    #[test]
    fn test_record_pattern_field_in_simple_macro() {
        let completions = complete(
            r"
            macro_rules! m { ($e:expr) => { $e } }
            struct S { foo: u32 }

            fn process(f: S) {
                m!(match f {
                    S { f<|>: 92 } => (),
                })
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "foo",
                source_range: [171; 172),
                delete: [171; 172),
                insert: "foo",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }

    #[test]
    fn only_missing_fields_are_completed_in_destruct_pats() {
        let completions = complete(
            r"
            struct S {
                foo1: u32,
                foo2: u32,
                bar: u32,
                baz: u32,
            }

            fn main() {
                let s = S {
                    foo1: 1,
                    foo2: 2,
                    bar: 3,
                    baz: 4,
                };
                if let S { foo1, foo2, <|> } = s {}
            }
            ",
        );
        assert_debug_snapshot!(completions, @r###"
        [
            CompletionItem {
                label: "bar",
                source_range: [369; 369),
                delete: [369; 369),
                insert: "bar",
                kind: Field,
                detail: "u32",
            },
            CompletionItem {
                label: "baz",
                source_range: [369; 369),
                delete: [369; 369),
                insert: "baz",
                kind: Field,
                detail: "u32",
            },
        ]
        "###);
    }
}
<|endoftext|>


<commit_before>/// List of material font icons. Use this to generate a font Icon.
// emacs: use C-x 8 Ret => #xf207 ("BUS"-Glyph)
// pub const FLOPPY_FONT_ICON: &str = "";
// pub const ADD_FONT_ICON: &str = "";
// pub const LOAD_FONT_ICON: &str = "";
// pub const SAVE_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
// pub const REMOVE_ICON: &str = "";
// pub const ARROW_DOWN_ICON: &str = "";

// pub const MENU_FONT_ICON: &str = "";
// pub const SETTINGS_FONT_ICON: &str = "";
// pub const HELP_OUTLINE_FONT_ICON: &str = "";

// // category: Social
// pub const ANDROID_FONT_ICON: &str = "";
// pub const APPLE_FONT_ICON: &str = "";
// pub const GITHUB_FONT_ICON: &str = "";
// pub const GOOGLE_FONT_ICON: &str = "";
// pub const GOOGLE_DRIVE_FONT_ICON: &str = "";
// pub const GOOGLE_MAPS_FONT_ICON: &str = "";
// pub const LANGUAGE_JAVASCRIPT_FONT_ICON: &str = "";
// pub const LANGUAGE_HTML5_FONT_ICON: &str = "";
// pub const LANGUAGE_PYTHON_ICON: &str = "";
// pub const PAYPAL_FONT_ICON: &str = "";
// pub const POCKET_FONT_ICON: &str = "";
// pub const RSS_FONT_ICON: &str = "";
// pub const SHARE_FONT_ICON: &str = "";
// pub const STEAM_FONT_ICON: &str = "";
// pub const TWITTER_BOX_FONT_ICON: &str = "";
// pub const TWITTER_FONT_ICON: &str = "";
// pub const WIKIPEDIA_FONT_ICON: &str = "";
// pub const LINKEDIN_FONT_ICON: &str = "";
// pub const REDDIT_FONT_ICON: &str = "";
// pub const VIMEO_FONT_ICON: &str = "";
// pub const WINDOWS_FONT_ICON: &str = "";

// // category: Person
// pub const ACCOUNT_FONT_ICON: &str = "";
// pub const ACCOUNT_ADD_FONT_ICON: &str = "";
// pub const ACCOUNT_BOX_FONT_ICON: &str = "";
// pub const ACCOUNT_CIRCLE_FONT_ICON: &str = "";
// pub const ACCOUNTS_ADD_FONT_ICON: &str = "";
// pub const ACCOUNTS_FONT_ICON: &str = "";
// pub const MALE_FONT_ICON: &str = "";
// pub const FEMALE_FONT_ICON: &str = "";
// pub const MALE_FEMALE_FONT_ICON: &str = "";
// pub const RUN_FONT_ICON: &str = "";
// pub const WALK_FONT_ICON: &str = "";

// // category: File
// pub const CLOUD_FONT_ICON: &str = "";
// pub const DOWNLOAD_FONT_ICON: &str = "";
// pub const UPLOAD_FONT_ICON: &str = "";
// pub const FILE_FONT_ICON: &str = "";
// pub const FOLDER_FONT_ICON: &str = "";
// pub const FOLDER_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_DONE_FONT_ICON: &str = "";
// pub const CLOUD_OFF_FONT_ICON: &str = "";
// pub const CLOUD_DOWNLOAD_FONT_ICON: &str = "";
// pub const CLOUD_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_UPLOAD_FONT_ICON: &str = "";

// // category: Comment
// pub const COMMENT_FONT_ICON: &str = "";
// pub const COMMENT_LIST_FONT_ICON: &str = "";
// pub const COMMENT_IMAGE_FONT_ICON: &str = "";
// pub const COMMENT_EDIT_FONT_ICON: &str = "";
// pub const COMMENT_ALERT_FONT_ICON: &str = "";
// pub const COMMENT_MORE_FONT_ICON: &str = "";
// pub const COMMENT_OUTLINE_FONT_ICON: &str = "";
// pub const COMMENTS_FONT_ICON: &str = "";
// pub const COMMENT_VIDEO_TEXT_FONT_ICON: &str = "";
// pub const COMMENT_TEXT_FONT_ICON: &str = "";

// // category: Form
// pub const CHECK_ALL_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_U_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_FONT_ICON: &str = "";
// pub const CHECK_SQUARE_FONT_ICON: &str = "";
// pub const CHECK_FONT_ICON: &str = "";
// //pub const CHECK_FONT_ICON: &str = "";
// pub const CIRCLE_O_FONT_ICON: &str = "";
// pub const CIRCLE_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_ALT_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_OUTLINE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_SQUARE_FONT_ICON: &str = "";
// pub const MINUS_FONT_ICON: &str = "";
// //pub const MINUS_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_DUPLICATE_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_FONT_ICON: &str = "";
// pub const PLUS_SQUARE_FONT_ICON: &str = "";
// pub const PLUS_FONT_ICON: &str = "";
// pub const SQUARE_O_FONT_ICON: &str = "";
// pub const STAR_CIRCLE_FONT_ICON: &str = "";
// pub const STAR_HALF_FONT_ICON: &str = "";
// pub const STAR_OUTLINE_FONT_ICON: &str = "";
// pub const STAR_STAR_FONT_ICON: &str = "";

/// List of material font icons. Use this to generate a font Icon.
pub const FLOPPY_FONT_ICON: &str = "";
pub const CHECK_FONT_ICON: &str = "";
pub const ADD_FONT_ICON: &str = "";
pub const MINUS_FONT_ICON: &str = "";
pub const LOAD_FONT_ICON: &str = "";
pub const SAVE_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
pub const REMOVE_ICON: &str = "";
pub const ARROW_DOWN_ICON: &str = "";<commit_msg>material_font_icons: remove old unused code name<commit_after>/// List of material font icons. Use this to generate a font Icon.
// emacs: use C-x 8 Ret => #xf207 ("BUS"-Glyph)
// pub const FLOPPY_FONT_ICON: &str = "";
// pub const ADD_FONT_ICON: &str = "";
// pub const LOAD_FONT_ICON: &str = "";
// pub const SAVE_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
// pub const REMOVE_ICON: &str = "";
// pub const ARROW_DOWN_ICON: &str = "";

// pub const MENU_FONT_ICON: &str = "";
// pub const SETTINGS_FONT_ICON: &str = "";
// pub const HELP_OUTLINE_FONT_ICON: &str = "";

// // category: Social
// pub const ANDROID_FONT_ICON: &str = "";
// pub const APPLE_FONT_ICON: &str = "";
// pub const GITHUB_FONT_ICON: &str = "";
// pub const GOOGLE_FONT_ICON: &str = "";
// pub const GOOGLE_DRIVE_FONT_ICON: &str = "";
// pub const GOOGLE_MAPS_FONT_ICON: &str = "";
// pub const LANGUAGE_JAVASCRIPT_FONT_ICON: &str = "";
// pub const LANGUAGE_HTML5_FONT_ICON: &str = "";
// pub const LANGUAGE_PYTHON_ICON: &str = "";
// pub const PAYPAL_FONT_ICON: &str = "";
// pub const POCKET_FONT_ICON: &str = "";
// pub const RSS_FONT_ICON: &str = "";
// pub const SHARE_FONT_ICON: &str = "";
// pub const STEAM_FONT_ICON: &str = "";
// pub const TWITTER_BOX_FONT_ICON: &str = "";
// pub const TWITTER_FONT_ICON: &str = "";
// pub const WIKIPEDIA_FONT_ICON: &str = "";
// pub const LINKEDIN_FONT_ICON: &str = "";
// pub const REDDIT_FONT_ICON: &str = "";
// pub const VIMEO_FONT_ICON: &str = "";
// pub const WINDOWS_FONT_ICON: &str = "";

// // category: Person
// pub const ACCOUNT_FONT_ICON: &str = "";
// pub const ACCOUNT_ADD_FONT_ICON: &str = "";
// pub const ACCOUNT_BOX_FONT_ICON: &str = "";
// pub const ACCOUNT_CIRCLE_FONT_ICON: &str = "";
// pub const ACCOUNTS_ADD_FONT_ICON: &str = "";
// pub const ACCOUNTS_FONT_ICON: &str = "";
// pub const MALE_FONT_ICON: &str = "";
// pub const FEMALE_FONT_ICON: &str = "";
// pub const MALE_FEMALE_FONT_ICON: &str = "";
// pub const RUN_FONT_ICON: &str = "";
// pub const WALK_FONT_ICON: &str = "";

// // category: File
// pub const CLOUD_FONT_ICON: &str = "";
// pub const DOWNLOAD_FONT_ICON: &str = "";
// pub const UPLOAD_FONT_ICON: &str = "";
// pub const FILE_FONT_ICON: &str = "";
// pub const FOLDER_FONT_ICON: &str = "";
// pub const FOLDER_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_DONE_FONT_ICON: &str = "";
// pub const CLOUD_OFF_FONT_ICON: &str = "";
// pub const CLOUD_DOWNLOAD_FONT_ICON: &str = "";
// pub const CLOUD_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_UPLOAD_FONT_ICON: &str = "";

// // category: Comment
// pub const COMMENT_FONT_ICON: &str = "";
// pub const COMMENT_LIST_FONT_ICON: &str = "";
// pub const COMMENT_IMAGE_FONT_ICON: &str = "";
// pub const COMMENT_EDIT_FONT_ICON: &str = "";
// pub const COMMENT_ALERT_FONT_ICON: &str = "";
// pub const COMMENT_MORE_FONT_ICON: &str = "";
// pub const COMMENT_OUTLINE_FONT_ICON: &str = "";
// pub const COMMENTS_FONT_ICON: &str = "";
// pub const COMMENT_VIDEO_TEXT_FONT_ICON: &str = "";
// pub const COMMENT_TEXT_FONT_ICON: &str = "";

// // category: Form
// pub const CHECK_ALL_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_U_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_FONT_ICON: &str = "";
// pub const CHECK_SQUARE_FONT_ICON: &str = "";
// pub const CHECK_FONT_ICON: &str = "";
// //pub const CHECK_FONT_ICON: &str = "";
// pub const CIRCLE_O_FONT_ICON: &str = "";
// pub const CIRCLE_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_ALT_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_OUTLINE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_SQUARE_FONT_ICON: &str = "";
// pub const MINUS_FONT_ICON: &str = "";
// //pub const MINUS_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_DUPLICATE_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_FONT_ICON: &str = "";
// pub const PLUS_SQUARE_FONT_ICON: &str = "";
// pub const PLUS_FONT_ICON: &str = "";
// pub const SQUARE_O_FONT_ICON: &str = "";
// pub const STAR_CIRCLE_FONT_ICON: &str = "";
// pub const STAR_HALF_FONT_ICON: &str = "";
// pub const STAR_OUTLINE_FONT_ICON: &str = "";
// pub const STAR_STAR_FONT_ICON: &str = "";

/// List of material font icons. Use this to generate a font Icon.
pub const FLOPPY_FONT_ICON: &str = "";
pub const CHECK_FONT_ICON: &str = "";
pub const ADD_FONT_ICON: &str = "";
pub const MINUS_FONT_ICON: &str = "";
pub const LOAD_FONT_ICON: &str = "";
pub const SAVE_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
pub const REMOVE_ICON: &str = "";
pub const ARROW_DOWN_ICON: &str = "";
<|endoftext|>


<commit_before>use rustc::hir::*;
use rustc::lint::*;
use utils::{SpanlessEq, span_lint, span_lint_and_then, multispan_sugg, snippet, implements_trait, is_copy};

/// **What it does:** Checks for equal operands to comparison, logical and
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
/// `||`, `&`, `|`, `^`, `-` and `/`).
///
/// **Why is this bad?** This is usually just a typo or a copy and paste error.
///
/// **Known problems:** False negatives: We had some false positives regarding
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance
/// of `x.pop() && x.pop()`), so we removed matching any function or method
/// calls. We may introduce a whitelist of known pure functions in the future.
///
/// **Example:**
/// ```rust
/// x + 1 == x + 1
/// ```
declare_lint! {
    pub EQ_OP,
    Warn,
    "equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
}

/// **What it does:** Checks for arguments to `==` which have their address taken to satisfy a bound
/// and suggests to dereference the other argument instead
///
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// &x == y
/// ```
declare_lint! {
    pub OP_REF,
    Warn,
    "taking a reference to satisfy the type constraints on `==`"
}

#[derive(Copy,Clone)]
pub struct EqOp;

impl LintPass for EqOp {
    fn get_lints(&self) -> LintArray {
        lint_array!(EQ_OP, OP_REF)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprBinary(ref op, ref left, ref right) = e.node {
            if is_valid_operator(op) {
                if SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
                    span_lint(cx,
                              EQ_OP,
                              e.span,
                              &format!("equal expressions as operands to `{}`", op.node.as_str()));
                    return;
                }
            }
            let (trait_id, requires_ref) = match op.node {
                BiAdd => (cx.tcx.lang_items.add_trait(), false),
                BiSub => (cx.tcx.lang_items.sub_trait(), false),
                BiMul => (cx.tcx.lang_items.mul_trait(), false),
                BiDiv => (cx.tcx.lang_items.div_trait(), false),
                BiRem => (cx.tcx.lang_items.rem_trait(), false),
                // don't lint short circuiting ops
                BiAnd | BiOr => return,
                BiBitXor => (cx.tcx.lang_items.bitxor_trait(), false),
                BiBitAnd => (cx.tcx.lang_items.bitand_trait(), false),
                BiBitOr => (cx.tcx.lang_items.bitor_trait(), false),
                BiShl => (cx.tcx.lang_items.shl_trait(), false),
                BiShr => (cx.tcx.lang_items.shr_trait(), false),
                BiNe | BiEq => (cx.tcx.lang_items.eq_trait(), true),
                BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items.ord_trait(), true),
            };
            let parent = cx.tcx.hir.get_parent(e.id);
            if let Some(trait_id) = trait_id {
                #[allow(match_same_arms)]
                match (&left.node, &right.node) {
                    // do not suggest to dereference literals
                    (&ExprLit(..), _) |
                    (_, &ExprLit(..)) => {},
                    // &foo == &bar
                    (&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
                        let lty = cx.tables.expr_ty(l);
                        let rty = cx.tables.expr_ty(r);
                        let lcpy = is_copy(cx, lty, parent);
                        let rcpy = is_copy(cx, rty, parent);
                        // either operator autorefs or both args are copyable
                        if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of both operands",
                                                |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                multispan_sugg(db,
                                                "use the values directly".to_string(),
                                                vec![(left.span, lsnip),
                                                    (right.span, rsnip)]);
                            })
                        } else if lcpy && !rcpy && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of left operand",
                                                |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                db.span_suggestion(left.span, "use the left value directly", lsnip);
                            })
                        } else if !lcpy && rcpy && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of right operand",
                                                |db| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                db.span_suggestion(right.span, "use the right value directly", rsnip);
                            })
                        }
                    },
                    // &foo == bar
                    (&ExprAddrOf(_, ref l), _) => {
                        let lty = cx.tables.expr_ty(l);
                        let lcpy = is_copy(cx, lty, parent);
                        if (requires_ref || lcpy) && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) {
                            span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                db.span_suggestion(left.span, "use the left value directly", lsnip);
                            })
                        }
                    },
                    // foo == &bar
                    (_, &ExprAddrOf(_, ref r)) => {
                        let rty = cx.tables.expr_ty(r);
                        let rcpy = is_copy(cx, rty, parent);
                        if (requires_ref || rcpy) && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) {
                            span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |db| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                db.span_suggestion(left.span, "use the right value directly", rsnip);
                            })
                        }
                    },
                    _ => {},
                }
            }
        }
    }
}

fn is_valid_operator(op: &BinOp) -> bool {
    match op.node {
        BiSub | BiDiv | BiEq | BiLt | BiLe | BiGt | BiGe | BiNe | BiAnd | BiOr | BiBitXor | BiBitAnd | BiBitOr => true,
        _ => false,
    }
}
<commit_msg>Fix dogfood tests<commit_after>use rustc::hir::*;
use rustc::lint::*;
use utils::{SpanlessEq, span_lint, span_lint_and_then, multispan_sugg, snippet, implements_trait, is_copy};

/// **What it does:** Checks for equal operands to comparison, logical and
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
/// `||`, `&`, `|`, `^`, `-` and `/`).
///
/// **Why is this bad?** This is usually just a typo or a copy and paste error.
///
/// **Known problems:** False negatives: We had some false positives regarding
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance
/// of `x.pop() && x.pop()`), so we removed matching any function or method
/// calls. We may introduce a whitelist of known pure functions in the future.
///
/// **Example:**
/// ```rust
/// x + 1 == x + 1
/// ```
declare_lint! {
    pub EQ_OP,
    Warn,
    "equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
}

/// **What it does:** Checks for arguments to `==` which have their address taken to satisfy a bound
/// and suggests to dereference the other argument instead
///
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// &x == y
/// ```
declare_lint! {
    pub OP_REF,
    Warn,
    "taking a reference to satisfy the type constraints on `==`"
}

#[derive(Copy,Clone)]
pub struct EqOp;

impl LintPass for EqOp {
    fn get_lints(&self) -> LintArray {
        lint_array!(EQ_OP, OP_REF)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprBinary(ref op, ref left, ref right) = e.node {
            if is_valid_operator(op) && SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
                span_lint(cx,
                            EQ_OP,
                            e.span,
                            &format!("equal expressions as operands to `{}`", op.node.as_str()));
                return;
            }
            let (trait_id, requires_ref) = match op.node {
                BiAdd => (cx.tcx.lang_items.add_trait(), false),
                BiSub => (cx.tcx.lang_items.sub_trait(), false),
                BiMul => (cx.tcx.lang_items.mul_trait(), false),
                BiDiv => (cx.tcx.lang_items.div_trait(), false),
                BiRem => (cx.tcx.lang_items.rem_trait(), false),
                // don't lint short circuiting ops
                BiAnd | BiOr => return,
                BiBitXor => (cx.tcx.lang_items.bitxor_trait(), false),
                BiBitAnd => (cx.tcx.lang_items.bitand_trait(), false),
                BiBitOr => (cx.tcx.lang_items.bitor_trait(), false),
                BiShl => (cx.tcx.lang_items.shl_trait(), false),
                BiShr => (cx.tcx.lang_items.shr_trait(), false),
                BiNe | BiEq => (cx.tcx.lang_items.eq_trait(), true),
                BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items.ord_trait(), true),
            };
            let parent = cx.tcx.hir.get_parent(e.id);
            if let Some(trait_id) = trait_id {
                #[allow(match_same_arms)]
                match (&left.node, &right.node) {
                    // do not suggest to dereference literals
                    (&ExprLit(..), _) |
                    (_, &ExprLit(..)) => {},
                    // &foo == &bar
                    (&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
                        let lty = cx.tables.expr_ty(l);
                        let rty = cx.tables.expr_ty(r);
                        let lcpy = is_copy(cx, lty, parent);
                        let rcpy = is_copy(cx, rty, parent);
                        // either operator autorefs or both args are copyable
                        if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of both operands",
                                                |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                multispan_sugg(db,
                                                "use the values directly".to_string(),
                                                vec![(left.span, lsnip),
                                                    (right.span, rsnip)]);
                            })
                        } else if lcpy && !rcpy && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of left operand",
                                                |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                db.span_suggestion(left.span, "use the left value directly", lsnip);
                            })
                        } else if !lcpy && rcpy && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) {
                            span_lint_and_then(cx,
                                                OP_REF,
                                                e.span,
                                                "needlessly taken reference of right operand",
                                                |db| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                db.span_suggestion(right.span, "use the right value directly", rsnip);
                            })
                        }
                    },
                    // &foo == bar
                    (&ExprAddrOf(_, ref l), _) => {
                        let lty = cx.tables.expr_ty(l);
                        let lcpy = is_copy(cx, lty, parent);
                        if (requires_ref || lcpy) && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) {
                            span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| {
                                let lsnip = snippet(cx, l.span, "...").to_string();
                                db.span_suggestion(left.span, "use the left value directly", lsnip);
                            })
                        }
                    },
                    // foo == &bar
                    (_, &ExprAddrOf(_, ref r)) => {
                        let rty = cx.tables.expr_ty(r);
                        let rcpy = is_copy(cx, rty, parent);
                        if (requires_ref || rcpy) && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) {
                            span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |db| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                db.span_suggestion(left.span, "use the right value directly", rsnip);
                            })
                        }
                    },
                    _ => {},
                }
            }
        }
    }
}

fn is_valid_operator(op: &BinOp) -> bool {
    match op.node {
        BiSub | BiDiv | BiEq | BiLt | BiLe | BiGt | BiGe | BiNe | BiAnd | BiOr | BiBitXor | BiBitAnd | BiBitOr => true,
        _ => false,
    }
}
<|endoftext|>


<commit_before>
mod ffi;

use std::os::raw::*;
use std::mem;

const INTERFACE: ffi::SMikkTSpaceInterface = ffi::SMikkTSpaceInterface {
    m_getNumFaces: faces,
    m_getNumVerticesOfFace: vertices,
    m_getPosition: position,
    m_getNormal: normal,
    m_getTexCoord: tex_coord,
    m_setTSpaceBasic: set_tspace_basic,
    m_setTSpace: set_tspace,
};

pub struct Context {
    faces: i32,
}

/// Returns the number of faces (triangles/quads) on the mesh to be processed.
#[no_mangle]
extern "C" fn faces(pContext: *const ffi::SMikkTSpaceContext) -> c_int {
    unsafe {
        let m: *const Context = mem::transmute(pContext);
        (*m).faces as c_int
    }
}

/// Returns the number of vertices on face number iFace
/// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
#[no_mangle]
extern "C" fn vertices(
    pContext: *const ffi::SMikkTSpaceContext,
    iFace: c_int,
) -> c_int {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
        unimplemented!()
    }
}

/// Returns the position of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn position(
    pContext: *const ffi::SMikkTSpaceContext,
    fvPosOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the normal of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn normal(
    pContext: *const ffi::SMikkTSpaceContext,
    fvPosOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the texcoord of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn tex_coord(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTexcOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the tangent and its sign to the application.
#[no_mangle]
extern "C" fn set_tspace_basic(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTangent: *const c_float,
    fSign: *const c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns tangent space results to the application.
#[no_mangle]
extern "C" fn set_tspace(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTangent: *const c_float,
    fvBiTangent: *const c_float,
    fMagS: *const c_float,
    fMagT: *const c_float,
    bIsOrientationPreserving: ffi::tbool,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

impl Context {
    pub fn new() -> Self {
        Context {
            faces: 3,
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Add Context abstraction<commit_after>
mod ffi;

use std::os::raw::*;
use std::mem;

/// Rust FFI for the MikkTSpace implementation.
const INTERFACE: ffi::SMikkTSpaceInterface = ffi::SMikkTSpaceInterface {
    m_getNumFaces: faces,
    m_getNumVerticesOfFace: vertices,
    m_getPosition: position,
    m_getNormal: normal,
    m_getTexCoord: tex_coord,
    m_setTSpaceBasic: set_tspace_basic,
    m_setTSpace: set_tspace,
};

pub struct Context {
    faces: Box<ExactSizeIterator<Item = Face>>,
    positions: Box<ExactSizeIterator<Item = [f32; 3]>>,
    tex_coords: Box<ExactSizeIterator<Item = [f32; 2]>>,
    normals: Box<ExactSizeIterator<Item = [f32; 3]>>,
}

/// Specifies whether a face is a triangle or a quad.
pub enum Face {
    Triangle,
    Quad,
}

impl Face {
    /// Returns the number of vertices bound by this face.
    pub fn vertices(&self) -> i32 {
        match self {
            &Face::Triangle { .. } => 3,
            &Face::Quad { .. } => 4,
        }
    }
}

/// Returns the number of faces (triangles/quads) on the mesh to be processed.
#[no_mangle]
extern "C" fn faces(pContext: *const ffi::SMikkTSpaceContext) -> c_int {
    unsafe {
        let m: *const Context = mem::transmute(pContext);
        (*m).faces.len() as c_int
    }
}

/// Returns the number of vertices on face number iFace
/// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
#[no_mangle]
extern "C" fn vertices(
    pContext: *const ffi::SMikkTSpaceContext,
    iFace: c_int,
) -> c_int {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
        3
    }
}

/// Returns the position of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn position(
    pContext: *const ffi::SMikkTSpaceContext,
    fvPosOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the normal of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn normal(
    pContext: *const ffi::SMikkTSpaceContext,
    fvPosOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the texcoord of the referenced face of vertex number
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
#[no_mangle]
extern "C" fn tex_coord(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTexcOut: *mut c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns the tangent and its sign to the application.
#[no_mangle]
extern "C" fn set_tspace_basic(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTangent: *const c_float,
    fSign: *const c_float,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

/// Returns tangent space results to the application.
#[no_mangle]
extern "C" fn set_tspace(
    pContext: *const ffi::SMikkTSpaceContext,
    fvTangent: *const c_float,
    fvBiTangent: *const c_float,
    fMagS: *const c_float,
    fMagT: *const c_float,
    bIsOrientationPreserving: ffi::tbool,
    iFace: c_int,
    iVert: c_int,
) {
    unsafe {
        let _: *const Context = mem::transmute(pContext);
    }
}

impl Context {
    /// Constructor for a MikkTSpace `Context`.
    pub fn new<F, P, T, N>(faces: F, positions: P, tex_coords: T, normals: N) -> Self
    where
        F: 'static + ExactSizeIterator<Item = Face>,
        P: 'static + ExactSizeIterator<Item = [f32; 3]>,
        T: 'static + ExactSizeIterator<Item = [f32; 2]>,
        N: 'static + ExactSizeIterator<Item = [f32; 3]>,
    {
        Context {
            faces: Box::new(faces),
            positions: Box::new(positions),
            tex_coords: Box::new(tex_coords),
            normals: Box::new(normals),
        }
    }
}
<|endoftext|>


<commit_before>/// Return early with an error.
///
/// This macro is equivalent to `return Err(anyhow!($args...))`.
///
/// The surrounding function's or closure's return value is required to be
/// `Result<_, anyhow::Error>`.
///
/// # Example
///
/// ```
/// # use anyhow::{bail, Result};
/// #
/// # fn has_permission(user: usize, resource: usize) -> bool {
/// #     true
/// # }
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #     let resource = 0;
/// #
/// if !has_permission(user, resource) {
///     bail!("permission denied for accessing {}", resource);
/// }
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{bail, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error("recursion limit exceeded")]
///     RecursionLimitExceeded,
///     # #[error("...")]
///     # More = (stringify! {
///     ...
///     # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// if depth > MAX_DEPTH {
///     bail!(ScienceError::RecursionLimitExceeded);
/// }
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! bail {
    ($msg:literal $(,)?) => {
        return $crate::private::Err($crate::anyhow!($msg));
    };
    ($err:expr $(,)?) => {
        return $crate::private::Err($crate::anyhow!($err));
    };
    ($fmt:expr, $($arg:tt)*) => {
        return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
    };
}

/// Return early with an error if a condition is not satisfied.
///
/// This macro is equivalent to `if !$cond { return Err(anyhow!($args...)); }`.
///
/// The surrounding function's or closure's return value is required to be
/// `Result<_, anyhow::Error>`.
///
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
/// rather than panicking.
///
/// # Example
///
/// ```
/// # use anyhow::{ensure, Result};
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #
/// ensure!(user == 0, "only user 0 is allowed");
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{ensure, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error("recursion limit exceeded")]
///     RecursionLimitExceeded,
///     # #[error("...")]
///     # More = (stringify! {
///     ...
///     # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $msg:literal $(,)?) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($msg));
        }
    };
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($err));
        }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
        }
    };
}

/// Construct an ad-hoc error from a string or existing non-`anyhow` error
/// value.
///
/// This evaluates to an [`Error`][crate::Error]. It can take either just a
/// string, or a format string with arguments. It also can take any custom type
/// which implements `Debug` and `Display`.
///
/// If called with a single argument whose type implements `std::error::Error`
/// (in addition to `Debug` and `Display`, which are always required), then that
/// Error impl's `source` is preserved as the `source` of the resulting
/// `anyhow::Error`.
///
/// # Example
///
/// ```
/// # type V = ();
/// #
/// use anyhow::{anyhow, Result};
///
/// fn lookup(key: &str) -> Result<V> {
///     if key.len() != 16 {
///         return Err(anyhow!("key length must be 16 characters, got {:?}", key));
///     }
///
///     // ...
///     # Ok(())
/// }
/// ```
#[macro_export]
macro_rules! anyhow {
    ($msg:literal $(,)?) => {
        // Handle $:literal as a special case to make cargo-expanded code more
        // concise in the common case.
        $crate::private::new_adhoc($msg)
    };
    ($err:expr $(,)?) => ({
        use $crate::private::kind::*;
        let error = $err;
        (&error).anyhow_kind().new(error)
    });
    ($fmt:expr, $($arg:tt)*) => {
        $crate::private::new_adhoc(format!($fmt, $($arg)*))
    };
}
<commit_msg>Link from `bail!` and `ensure!` to anyhow::Error<commit_after>/// Return early with an error.
///
/// This macro is equivalent to `return Err(anyhow!($args...))`.
///
/// The surrounding function's or closure's return value is required to be
/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
///
/// # Example
///
/// ```
/// # use anyhow::{bail, Result};
/// #
/// # fn has_permission(user: usize, resource: usize) -> bool {
/// #     true
/// # }
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #     let resource = 0;
/// #
/// if !has_permission(user, resource) {
///     bail!("permission denied for accessing {}", resource);
/// }
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{bail, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error("recursion limit exceeded")]
///     RecursionLimitExceeded,
///     # #[error("...")]
///     # More = (stringify! {
///     ...
///     # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// if depth > MAX_DEPTH {
///     bail!(ScienceError::RecursionLimitExceeded);
/// }
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! bail {
    ($msg:literal $(,)?) => {
        return $crate::private::Err($crate::anyhow!($msg));
    };
    ($err:expr $(,)?) => {
        return $crate::private::Err($crate::anyhow!($err));
    };
    ($fmt:expr, $($arg:tt)*) => {
        return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
    };
}

/// Return early with an error if a condition is not satisfied.
///
/// This macro is equivalent to `if !$cond { return Err(anyhow!($args...)); }`.
///
/// The surrounding function's or closure's return value is required to be
/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
///
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
/// rather than panicking.
///
/// # Example
///
/// ```
/// # use anyhow::{ensure, Result};
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #
/// ensure!(user == 0, "only user 0 is allowed");
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{ensure, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error("recursion limit exceeded")]
///     RecursionLimitExceeded,
///     # #[error("...")]
///     # More = (stringify! {
///     ...
///     # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $msg:literal $(,)?) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($msg));
        }
    };
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($err));
        }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
        if !$cond {
            return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
        }
    };
}

/// Construct an ad-hoc error from a string or existing non-`anyhow` error
/// value.
///
/// This evaluates to an [`Error`][crate::Error]. It can take either just a
/// string, or a format string with arguments. It also can take any custom type
/// which implements `Debug` and `Display`.
///
/// If called with a single argument whose type implements `std::error::Error`
/// (in addition to `Debug` and `Display`, which are always required), then that
/// Error impl's `source` is preserved as the `source` of the resulting
/// `anyhow::Error`.
///
/// # Example
///
/// ```
/// # type V = ();
/// #
/// use anyhow::{anyhow, Result};
///
/// fn lookup(key: &str) -> Result<V> {
///     if key.len() != 16 {
///         return Err(anyhow!("key length must be 16 characters, got {:?}", key));
///     }
///
///     // ...
///     # Ok(())
/// }
/// ```
#[macro_export]
macro_rules! anyhow {
    ($msg:literal $(,)?) => {
        // Handle $:literal as a special case to make cargo-expanded code more
        // concise in the common case.
        $crate::private::new_adhoc($msg)
    };
    ($err:expr $(,)?) => ({
        use $crate::private::kind::*;
        let error = $err;
        (&error).anyhow_kind().new(error)
    });
    ($fmt:expr, $($arg:tt)*) => {
        $crate::private::new_adhoc(format!($fmt, $($arg)*))
    };
}
<|endoftext|>


<commit_before>//! Types used for indexing into HLists and coproducts.
//!
//! frunk frequently uses phantom index types as a technique to avoid
//! overlapping impls for some traits.
//!
//! Currently, `Index` type parameters in traits are not ever really intended
//! to be selected by the user, and are instead simply solved for by type
//! inference wherever the compiler can see that there is a unique solution.
//! Therefore, you don't really have much of a reason to use the things in this
//! module.
//!
//! **...yet.** `;)`

use std::marker::PhantomData;

// Largely lifted from https://github.com/Sgeo/hlist/blob/master/src/lib.rs#L30

/// Used as an index into an `HList`.
///
/// `Here` is 0, pointing to the head of the HList.
///
/// Users should normally allow type inference to create this type.
pub struct Here(());

/// Used as an index into an `HList`.
///
/// `There<T>` is 1 + `T`.
///
/// Users should normally allow type inference to create this type.
pub struct There<T>(PhantomData<T>);

/// An index denoting that `Suffix` is just that.
pub struct Suffixed<Suffix>(PhantomData<Suffix>);
<commit_msg>turn indices into non-tuple structs<commit_after>//! Types used for indexing into HLists and coproducts.
//!
//! frunk frequently uses phantom index types as a technique to avoid
//! overlapping impls for some traits.
//!
//! Currently, `Index` type parameters in traits are not ever really intended
//! to be selected by the user, and are instead simply solved for by type
//! inference wherever the compiler can see that there is a unique solution.
//! Therefore, you don't really have much of a reason to use the things in this
//! module.
//!
//! **...yet.** `;)`

use std::marker::PhantomData;

// Largely lifted from https://github.com/Sgeo/hlist/blob/master/src/lib.rs#L30

/// Used as an index into an `HList`.
///
/// `Here` is 0, pointing to the head of the HList.
///
/// Users should normally allow type inference to create this type.
pub struct Here {
    _priv: (),
}

/// Used as an index into an `HList`.
///
/// `There<T>` is 1 + `T`.
///
/// Users should normally allow type inference to create this type.
pub struct There<T> {
    _marker: PhantomData<T>,
}

/// An index denoting that `Suffix` is just that.
pub struct Suffixed<Suffix> {
    _marker: PhantomData<Suffix>,
}
<|endoftext|>


<commit_before>extern crate core;

use core::num::FromPrimitive;
use core::fmt;

use std::rand::random;

use Direction::{SpinUp, SpinDown, SpinSuper};
use Plan::{Trivial, OddBall};

#[derive(Copy)]
#[derive(Show)]
#[derive(PartialEq)]
enum Direction {
    SpinUp,
    SpinDown,
    SpinSuper,
}

impl fmt::String for Direction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let r = match self {
            &SpinUp => "SpinUp",
            &SpinDown => "SpinDown",
            &SpinSuper => "SpinSuper"
        };
        write!(f, "{}", r)
    }
}

impl fmt::String for Detector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Detector::{D12, D3, D9};
        let r = match self {
            &D12 => "12 oclock",
            &D3 => "3 oclock",
            &D9 => "9 oclock"
        };
        write!(f, "{}", r)
    }
}

struct Pair<T> {
    lhs: T,
    rhs: T
}

struct Particle {
    spin: Direction
}

enum Plan {
    Trivial, // up-up-up -> down-down-down
    OddBall  // up-down-up -> down-up-down
}

#[derive(Show)]
enum Detector {
    D12, // 12 o'clock
    D3, // 3 o'clock
    D9, // 9 o' clock
}

impl Particle {
    fn new_pair () -> Pair<Particle> {
        let d1 = SpinSuper;
        let d2 = SpinSuper;
        let p1 = Particle{spin: d1};
        let p2 = Particle{spin: d2};

        return Pair{lhs: p1, rhs: p2};
    }

    pub fn measure (&mut self, theta: isize) {
        // TODO theta = 60degrees use 3/4th and 1/4th
        // TODO theta = 0 SpinUp
        // TODO theta = 180 SpinDown
    }

    // NOTE on spooky and premeditated only if measured in the same
    // direction must the spins be opposite

    // measure with with a message
    pub fn spooky (&mut self, friend: &mut Particle) -> Pair<Direction> {

        let spin = match self.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            SpinSuper => SpinUp
        };
        friend.spin = spin;

        let spin = match friend.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            _ => panic!("broke the universe")
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }

    fn get_detector_direction () -> Detector {
        let rnd = random::<f32>();

        let detector;
        if rnd < 0.33 {
            detector = Detector::D12;
        } else if rnd >= 0.33 && rnd < 0.66 {
            detector = Detector::D3;
        } else {
            detector = Detector::D9;
        }
        //println!("d1 {}", detector);

        return detector;
    }

    pub fn hidden_information (&mut self, friend: &mut Particle, plan: Plan) -> Pair<Direction> {

        let rnd = random::<f32>();

        let detector = Particle::get_detector_direction();
        let spin = match plan {
            Trivial => SpinUp,
            OddBall => match detector {
                Detector::D3 => SpinDown,
                _ => SpinUp
            }
        };
        friend.spin = spin;

        let detector = Particle::get_detector_direction();
        let spin = match plan {
            Trivial => SpinDown,
            OddBall => match detector {
                Detector::D3 => SpinUp,
                _ => SpinDown
            }
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }
}

fn main () {

    let particles = Particle::new_pair();

    let mut lhs = particles.lhs;
    let mut rhs = particles.rhs;

    lhs.spooky(&mut rhs);

    println!("lhs.spin {}, rhs.spin {}", lhs.spin, rhs.spin);

    // hidden_information should give +55.6% difference, spooky would give 50%

    let mut trials: f64 = 1000f64;
    let mut num_different: f64 = 0f64;

    for _ in range(0, trials as usize) {
        let particles = Particle::new_pair();
        let mut lhs = particles.lhs;
        let mut rhs = particles.rhs;
        lhs.hidden_information(&mut rhs, OddBall);

        //println!("lhs.spin {}, rhs.spin {}", lhs.spin, rhs.spin);
        if lhs.spin != rhs.spin {
            num_different += 1.0;
        }
    }

    println!("num_different {}%", 100f64 * (trials - num_different) / trials as f64);

}
<commit_msg>add numeric range match for detector<commit_after>extern crate core;

use core::num::FromPrimitive;
use core::fmt;

use std::rand::random;

use Direction::{SpinUp, SpinDown, SpinSuper};
use Plan::{Trivial, OddBall};

#[derive(Copy)]
#[derive(Show)]
#[derive(PartialEq)]
enum Direction {
    SpinUp,
    SpinDown,
    SpinSuper,
}

impl fmt::String for Direction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let r = match self {
            &SpinUp => "SpinUp",
            &SpinDown => "SpinDown",
            &SpinSuper => "SpinSuper"
        };
        write!(f, "{}", r)
    }
}

impl fmt::String for Detector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Detector::{D12, D3, D9};
        let r = match self {
            &D12 => "12 oclock",
            &D3 => "3 oclock",
            &D9 => "9 oclock"
        };
        write!(f, "{}", r)
    }
}

struct Pair<T> {
    lhs: T,
    rhs: T
}

struct Particle {
    spin: Direction
}

enum Plan {
    Trivial, // up-up-up -> down-down-down
    OddBall  // up-down-up -> down-up-down
}

#[derive(Show)]
enum Detector {
    D12, // 12 o'clock
    D3, // 3 o'clock
    D9, // 9 o' clock
}

impl Particle {
    fn new_pair () -> Pair<Particle> {
        let d1 = SpinSuper;
        let d2 = SpinSuper;
        let p1 = Particle{spin: d1};
        let p2 = Particle{spin: d2};

        return Pair{lhs: p1, rhs: p2};
    }

    pub fn measure (&mut self, theta: isize) {
        // TODO theta = 60degrees use 3/4th and 1/4th
        // TODO theta = 0 SpinUp
        // TODO theta = 180 SpinDown
    }

    // NOTE on spooky and premeditated only if measured in the same
    // direction must the spins be opposite

    // measure with with a message
    pub fn spooky (&mut self, friend: &mut Particle) -> Pair<Direction> {

        let spin = match self.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            SpinSuper => SpinUp
        };
        friend.spin = spin;

        let spin = match friend.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            _ => panic!("broke the universe")
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }

    fn get_detector_direction () -> Detector {
        let rnd = random::<f32>();

        let detector = match rnd {
            0.0  ... 0.33 => Detector::D12,
            0.33 ... 0.66 => Detector::D3,
            0.66 ... 1.00 => Detector::D9,
            _ => unreachable!()
        };

        return detector;
    }

    pub fn hidden_information (&mut self, friend: &mut Particle, plan: Plan) -> Pair<Direction> {

        let rnd = random::<f32>();

        let detector = Particle::get_detector_direction();
        let spin = match plan {
            Trivial => SpinUp,
            OddBall => match detector {
                Detector::D3 => SpinDown,
                _ => SpinUp
            }
        };
        friend.spin = spin;

        let detector = Particle::get_detector_direction();
        let spin = match plan {
            Trivial => SpinDown,
            OddBall => match detector {
                Detector::D3 => SpinUp,
                _ => SpinDown
            }
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }
}

fn main () {

    let particles = Particle::new_pair();

    let mut lhs = particles.lhs;
    let mut rhs = particles.rhs;

    lhs.spooky(&mut rhs);

    println!("lhs.spin {}, rhs.spin {}", lhs.spin, rhs.spin);

    // hidden_information should give +55.6% difference, spooky would give 50%

    let mut trials: f64 = 1000f64;
    let mut num_different: f64 = 0f64;

    for _ in range(0, trials as usize) {
        let particles = Particle::new_pair();
        let mut lhs = particles.lhs;
        let mut rhs = particles.rhs;
        lhs.hidden_information(&mut rhs, OddBall);

        //println!("lhs.spin {}, rhs.spin {}", lhs.spin, rhs.spin);
        if lhs.spin != rhs.spin {
            num_different += 1.0;
        }
    }

    println!("num_different {}%", 100f64 * (trials - num_different) / trials as f64);

}
<|endoftext|>