<commit_before>//! Checks that all error codes have at least one test to prevent having error
//! codes that are silently not thrown by the compiler anymore.

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::path::Path;

use regex::Regex;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
    "E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
    "E0482", "E0514", "E0519", "E0523", "E0554", "E0570", "E0640", "E0717", "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0729"];

#[derive(Default, Debug)]
struct ErrorCodeStatus {
    has_test: bool,
    has_explanation: bool,
    is_used: bool,
}

fn check_error_code_explanation(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    err_code: String,
) -> bool {
    let mut invalid_compile_fail_format = false;
    let mut found_error_code = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains('E') {
                if !found_error_code {
                    error_codes.get_mut(&err_code).map(|x| x.has_test = true);
                    found_error_code = true;
                }
            } else if s.contains("compile-fail") {
                invalid_compile_fail_format = true;
            }
        } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            if !found_error_code {
                error_codes.get_mut(&err_code).map(|x| x.has_test = true);
                found_error_code = true;
            }
        }
    }
    invalid_compile_fail_format
}

fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool {
    let mut ignore_found = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            return true;
        }
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains(err_code) {
                return true;
            } else if s.contains("ignore") {
                // It's very likely that we can't actually make it fail compilation...
                ignore_found = true;
            }
        }
    }
    ignore_found
}

macro_rules! some_or_continue {
    ($e:expr) => {
        match $e {
            Some(e) => e,
            None => continue,
        }
    };
}

fn extract_error_codes(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    path: &Path,
    errors: &mut Vec<String>,
) {
    let mut reached_no_explanation = false;

    for line in f.lines() {
        let s = line.trim();
        if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
            let err_code = s
                .split_once(':')
                .expect(
                    format!(
                        "Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} \
                         without a `:` delimiter",
                        s,
                    )
                    .as_str(),
                )
                .0
                .to_owned();
            error_codes.entry(err_code.clone()).or_default().has_explanation = true;

            // Now we extract the tests from the markdown file!
            let md_file_name = match s.split_once("include_str!(\"") {
                None => continue,
                Some((_, md)) => match md.split_once("\")") {
                    None => continue,
                    Some((file_name, _)) => file_name,
                },
            };
            let path = some_or_continue!(path.parent())
                .join(md_file_name)
                .canonicalize()
                .expect("failed to canonicalize error explanation file path");
            match read_to_string(&path) {
                Ok(content) => {
                    let has_test = check_if_error_code_is_test_in_explanation(&content, &err_code);
                    if !has_test && !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
                        errors.push(format!(
                            "`{}` doesn't use its own error code in compile_fail example",
                            path.display(),
                        ));
                    } else if has_test && IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
                        errors.push(format!(
                            "`{}` has a compile_fail example with its own error code, it shouldn't \
                             be listed in IGNORE_EXPLANATION_CHECK!",
                            path.display(),
                        ));
                    }
                    if check_error_code_explanation(&content, error_codes, err_code) {
                        errors.push(format!(
                            "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
                            path.display(),
                        ));
                    }
                }
                Err(e) => {
                    eprintln!("Couldn't read `{}`: {}", path.display(), e);
                }
            }
        } else if reached_no_explanation && s.starts_with('E') {
            let err_code = match s.split_once(',') {
                None => s,
                Some((err_code, _)) => err_code,
            }
            .to_string();
            if !error_codes.contains_key(&err_code) {
                // this check should *never* fail!
                error_codes.insert(err_code, ErrorCodeStatus::default());
            }
        } else if s == ";" {
            reached_no_explanation = true;
        }
    }
}

fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, ErrorCodeStatus>) {
    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("error[E") || s.starts_with("warning[E") {
            let err_code = match s.split_once(']') {
                None => continue,
                Some((err_code, _)) => match err_code.split_once('[') {
                    None => continue,
                    Some((_, err_code)) => err_code,
                },
            };
            error_codes.entry(err_code.to_owned()).or_default().has_test = true;
        }
    }
}

fn extract_error_codes_from_source(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    regex: &Regex,
) {
    for line in f.lines() {
        if line.trim_start().starts_with("//") {
            continue;
        }
        for cap in regex.captures_iter(line) {
            if let Some(error_code) = cap.get(1) {
                error_codes.entry(error_code.as_str().to_owned()).or_default().is_used = true;
            }
        }
    }
}

pub fn check(paths: &[&Path], bad: &mut bool) {
    let mut errors = Vec::new();
    let mut found_explanations = 0;
    let mut found_tests = 0;
    let mut error_codes: HashMap<String, ErrorCodeStatus> = HashMap::new();
    // We want error codes which match the following cases:
    //
    // * foo(a, E0111, a)
    // * foo(a, E0111)
    // * foo(E0111, a)
    // * #[error = "E0111"]
    let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();

    println!("Checking which error codes lack tests...");

    for path in paths {
        super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
            let file_name = entry.file_name();
            if file_name == "error_codes.rs" {
                extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
                found_explanations += 1;
            } else if entry.path().extension() == Some(OsStr::new("stderr")) {
                extract_error_codes_from_tests(contents, &mut error_codes);
                found_tests += 1;
            } else if entry.path().extension() == Some(OsStr::new("rs")) {
                let path = entry.path().to_string_lossy();
                if ["src/test/", "src/doc/", "src/tools/"].iter().all(|c| !path.contains(c)) {
                    extract_error_codes_from_source(contents, &mut error_codes, &regex);
                }
            }
        });
    }
    if found_explanations == 0 {
        eprintln!("No error code explanation was tested!");
        *bad = true;
    }
    if found_tests == 0 {
        eprintln!("No error code was found in compilation errors!");
        *bad = true;
    }
    if errors.is_empty() {
        println!("Found {} error codes", error_codes.len());

        for (err_code, error_status) in &error_codes {
            if !error_status.has_test && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!("Error code {} needs to have at least one UI test!", err_code));
            } else if error_status.has_test && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!(
                    "Error code {} has a UI test, it shouldn't be listed into EXEMPTED_FROM_TEST!",
                    err_code
                ));
            }
            if !error_status.is_used && !error_status.has_explanation {
                errors.push(format!(
                    "Error code {} isn't used and doesn't have an error explanation, it should be \
                     commented in error_codes.rs file",
                    err_code
                ));
            }
        }
    }
    if errors.is_empty() {
        // Checking if local constants need to be cleaned.
        for err_code in EXEMPTED_FROM_TEST {
            match error_codes.get(err_code.to_owned()) {
                Some(status) => {
                    if status.has_test {
                        errors.push(format!(
                            "{} error code has a test and therefore should be \
                            removed from the `EXEMPTED_FROM_TEST` constant",
                            err_code
                        ));
                    }
                }
                None => errors.push(format!(
                    "{} error code isn't used anymore and therefore should be removed \
                        from `EXEMPTED_FROM_TEST` constant",
                    err_code
                )),
            }
        }
    }
    errors.sort();
    for err in &errors {
        eprintln!("{}", err);
    }
    println!("Found {} error codes with no tests", errors.len());
    if !errors.is_empty() {
        *bad = true;
    }
    println!("Done!");
}
<commit_msg>Handle windows paths as well<commit_after>//! Checks that all error codes have at least one test to prevent having error
//! codes that are silently not thrown by the compiler anymore.

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::path::Path;

use regex::Regex;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
    "E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
    "E0482", "E0514", "E0519", "E0523", "E0554", "E0570", "E0640", "E0717", "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0729"];

// If the file path contains any of these, we don't want to try to extract error codes from it.
//
// We need to declare each path in the windows version (with backslash).
const PATHS_TO_IGNORE_FOR_EXTRACTION: &[&str] =
    &["src/test/", "src\\test\\", "src/doc/", "src\\doc\\", "src/tools/", "src\\tools\\"];

#[derive(Default, Debug)]
struct ErrorCodeStatus {
    has_test: bool,
    has_explanation: bool,
    is_used: bool,
}

fn check_error_code_explanation(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    err_code: String,
) -> bool {
    let mut invalid_compile_fail_format = false;
    let mut found_error_code = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains('E') {
                if !found_error_code {
                    error_codes.get_mut(&err_code).map(|x| x.has_test = true);
                    found_error_code = true;
                }
            } else if s.contains("compile-fail") {
                invalid_compile_fail_format = true;
            }
        } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            if !found_error_code {
                error_codes.get_mut(&err_code).map(|x| x.has_test = true);
                found_error_code = true;
            }
        }
    }
    invalid_compile_fail_format
}

fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool {
    let mut ignore_found = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            return true;
        }
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains(err_code) {
                return true;
            } else if s.contains("ignore") {
                // It's very likely that we can't actually make it fail compilation...
                ignore_found = true;
            }
        }
    }
    ignore_found
}

macro_rules! some_or_continue {
    ($e:expr) => {
        match $e {
            Some(e) => e,
            None => continue,
        }
    };
}

fn extract_error_codes(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    path: &Path,
    errors: &mut Vec<String>,
) {
    let mut reached_no_explanation = false;

    for line in f.lines() {
        let s = line.trim();
        if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
            let err_code = s
                .split_once(':')
                .expect(
                    format!(
                        "Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} \
                         without a `:` delimiter",
                        s,
                    )
                    .as_str(),
                )
                .0
                .to_owned();
            error_codes.entry(err_code.clone()).or_default().has_explanation = true;

            // Now we extract the tests from the markdown file!
            let md_file_name = match s.split_once("include_str!(\"") {
                None => continue,
                Some((_, md)) => match md.split_once("\")") {
                    None => continue,
                    Some((file_name, _)) => file_name,
                },
            };
            let path = some_or_continue!(path.parent())
                .join(md_file_name)
                .canonicalize()
                .expect("failed to canonicalize error explanation file path");
            match read_to_string(&path) {
                Ok(content) => {
                    let has_test = check_if_error_code_is_test_in_explanation(&content, &err_code);
                    if !has_test && !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
                        errors.push(format!(
                            "`{}` doesn't use its own error code in compile_fail example",
                            path.display(),
                        ));
                    } else if has_test && IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
                        errors.push(format!(
                            "`{}` has a compile_fail example with its own error code, it shouldn't \
                             be listed in IGNORE_EXPLANATION_CHECK!",
                            path.display(),
                        ));
                    }
                    if check_error_code_explanation(&content, error_codes, err_code) {
                        errors.push(format!(
                            "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
                            path.display(),
                        ));
                    }
                }
                Err(e) => {
                    eprintln!("Couldn't read `{}`: {}", path.display(), e);
                }
            }
        } else if reached_no_explanation && s.starts_with('E') {
            let err_code = match s.split_once(',') {
                None => s,
                Some((err_code, _)) => err_code,
            }
            .to_string();
            if !error_codes.contains_key(&err_code) {
                // this check should *never* fail!
                error_codes.insert(err_code, ErrorCodeStatus::default());
            }
        } else if s == ";" {
            reached_no_explanation = true;
        }
    }
}

fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, ErrorCodeStatus>) {
    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("error[E") || s.starts_with("warning[E") {
            let err_code = match s.split_once(']') {
                None => continue,
                Some((err_code, _)) => match err_code.split_once('[') {
                    None => continue,
                    Some((_, err_code)) => err_code,
                },
            };
            error_codes.entry(err_code.to_owned()).or_default().has_test = true;
        }
    }
}

fn extract_error_codes_from_source(
    f: &str,
    error_codes: &mut HashMap<String, ErrorCodeStatus>,
    regex: &Regex,
) {
    for line in f.lines() {
        if line.trim_start().starts_with("//") {
            continue;
        }
        for cap in regex.captures_iter(line) {
            if let Some(error_code) = cap.get(1) {
                error_codes.entry(error_code.as_str().to_owned()).or_default().is_used = true;
            }
        }
    }
}

pub fn check(paths: &[&Path], bad: &mut bool) {
    let mut errors = Vec::new();
    let mut found_explanations = 0;
    let mut found_tests = 0;
    let mut error_codes: HashMap<String, ErrorCodeStatus> = HashMap::new();
    // We want error codes which match the following cases:
    //
    // * foo(a, E0111, a)
    // * foo(a, E0111)
    // * foo(E0111, a)
    // * #[error = "E0111"]
    let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();

    println!("Checking which error codes lack tests...");

    for path in paths {
        super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
            let file_name = entry.file_name();
            if file_name == "error_codes.rs" {
                extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
                found_explanations += 1;
            } else if entry.path().extension() == Some(OsStr::new("stderr")) {
                extract_error_codes_from_tests(contents, &mut error_codes);
                found_tests += 1;
            } else if entry.path().extension() == Some(OsStr::new("rs")) {
                let path = entry.path().to_string_lossy();
                if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) {
                    extract_error_codes_from_source(contents, &mut error_codes, &regex);
                }
            }
        });
    }
    if found_explanations == 0 {
        eprintln!("No error code explanation was tested!");
        *bad = true;
    }
    if found_tests == 0 {
        eprintln!("No error code was found in compilation errors!");
        *bad = true;
    }
    if errors.is_empty() {
        println!("Found {} error codes", error_codes.len());

        for (err_code, error_status) in &error_codes {
            if !error_status.has_test && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!("Error code {} needs to have at least one UI test!", err_code));
            } else if error_status.has_test && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!(
                    "Error code {} has a UI test, it shouldn't be listed into EXEMPTED_FROM_TEST!",
                    err_code
                ));
            }
            if !error_status.is_used && !error_status.has_explanation {
                errors.push(format!(
                    "Error code {} isn't used and doesn't have an error explanation, it should be \
                     commented in error_codes.rs file",
                    err_code
                ));
            }
        }
    }
    if errors.is_empty() {
        // Checking if local constants need to be cleaned.
        for err_code in EXEMPTED_FROM_TEST {
            match error_codes.get(err_code.to_owned()) {
                Some(status) => {
                    if status.has_test {
                        errors.push(format!(
                            "{} error code has a test and therefore should be \
                            removed from the `EXEMPTED_FROM_TEST` constant",
                            err_code
                        ));
                    }
                }
                None => errors.push(format!(
                    "{} error code isn't used anymore and therefore should be removed \
                        from `EXEMPTED_FROM_TEST` constant",
                    err_code
                )),
            }
        }
    }
    errors.sort();
    for err in &errors {
        eprintln!("{}", err);
    }
    println!("Found {} error codes with no tests", errors.len());
    if !errors.is_empty() {
        *bad = true;
    }
    println!("Done!");
}
<|endoftext|>


<commit_before>#![feature(test)]
#[cfg(feature = "slog")]
#[macro_use]
extern crate slog;
extern crate test;
extern crate uuid;
use test::Bencher;
use uuid::Uuid;
#[cfg(feature = "slog")]
use slog::Drain;

#[bench]
fn bench_parse(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("");
        let _ = Uuid::parse_str("!");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4");
        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8");
        let _ = Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8");

        // Valid
        let _ = Uuid::parse_str("00000000000000000000000000000000");
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");
        let _ = Uuid::parse_str("01020304-1112-2122-3132-414243444546");
        let _ = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8");

        // Nil
        let _ = Uuid::parse_str("00000000000000000000000000000000");
        let _ = Uuid::parse_str("00000000-0000-0000-0000-000000000000");

        // Test error reporting
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c");
        let _ = Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd");
        let _ = Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4");
    });
}

#[bench]
fn bench_parse_invalid_len(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");
    })
}

#[bench]
fn bench_parse_invalid_character(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
    })
}

#[bench]
fn bench_parse_invalid_group_len(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");
    });
}

#[bench]
fn bench_parse_invalid_groups(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
    });
}

#[bench]
fn bench_valid_hyphenated(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
    });
}

#[bench]
fn bench_valid_short(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");
    });
}

#[cfg(feature = "slog")]
#[bench]
fn bench_log_discard_kv(b: &mut Bencher) {
    let root = slog::Logger::root(slog::Discard.fuse(), o!());
    let u1 = Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap();
    b.iter(|| {
        crit!(root, "test"; "u1" => u1);
    });
}
<commit_msg>fix fmt in parse_str.rs<commit_after>#![feature(test)]
#[cfg(feature = "slog")]
#[macro_use]
extern crate slog;
extern crate test;
extern crate uuid;
#[cfg(feature = "slog")]
use slog::Drain;
use test::Bencher;
use uuid::Uuid;

#[bench]
fn bench_parse(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("");
        let _ = Uuid::parse_str("!");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4");
        let _ = Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4");
        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8");
        let _ = Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8");

        // Valid
        let _ = Uuid::parse_str("00000000000000000000000000000000");
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");
        let _ = Uuid::parse_str("01020304-1112-2122-3132-414243444546");
        let _ = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8");

        // Nil
        let _ = Uuid::parse_str("00000000000000000000000000000000");
        let _ = Uuid::parse_str("00000000-0000-0000-0000-000000000000");

        // Test error reporting
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c");
        let _ = Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd");
        let _ = Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c");
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4");
    });
}

#[bench]
fn bench_parse_invalid_len(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");
    })
}

#[bench]
fn bench_parse_invalid_character(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
    })
}

#[bench]
fn bench_parse_invalid_group_len(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");
    });
}

#[bench]
fn bench_parse_invalid_groups(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
    });
}

#[bench]
fn bench_valid_hyphenated(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");
    });
}

#[bench]
fn bench_valid_short(b: &mut Bencher) {
    b.iter(|| {
        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");
    });
}

#[cfg(feature = "slog")]
#[bench]
fn bench_log_discard_kv(b: &mut Bencher) {
    let root = slog::Logger::root(slog::Discard.fuse(), o!());
    let u1 = Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap();
    b.iter(|| {
        crit!(root, "test"; "u1" => u1);
    });
}
<|endoftext|>


<commit_before>use crate::{DecodeError, WasmbinCountable, WasmbinDecode, WasmbinEncode};
use arbitrary::Arbitrary;
use std::marker::PhantomData;

#[cfg(feature = "lazy-blob")]
macro_rules! if_lazy {
    (if lazy { $($then:tt)* } $(else { $($otherwise:tt)* })?) => {
        $($then)*
    };
}

#[cfg(not(feature = "lazy-blob"))]
macro_rules! if_lazy {
    (if lazy { $($then:tt)* } $(else { $($otherwise:tt)* })?) => {
        $($($otherwise)*)?
    };
}

if_lazy!(if lazy {
    use crate::lazy_mut::{LazyMut, LazyTransform};
});

#[derive(Debug, Arbitrary, PartialEq, Eq)]
pub struct RawBlob<T = Vec<u8>> {
    pub contents: T,
}

impl<T: AsRef<[u8]>> WasmbinEncode for RawBlob<T> {
    fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
        let bytes = self.contents.as_ref();
        bytes.len().encode(w)?;
        bytes.encode(w)
    }
}

impl<T: WasmbinDecode> WasmbinDecode for RawBlob<T> {
    fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
        let size = u32::decode(r)?;
        let mut taken = std::io::Read::take(r, size.into());
        let contents = T::decode(&mut taken)?;
        if taken.limit() != 0 {
            return Err(DecodeError::UnrecognizedData);
        }
        Ok(RawBlob { contents })
    }
}

impl<T: AsRef<[u8]>> AsRef<[u8]> for RawBlob<T> {
    fn as_ref(&self) -> &[u8] {
        self.contents.as_ref()
    }
}

if_lazy!(if lazy {
    pub struct BlobTransform<T>(PhantomData<T>);

    impl<T: WasmbinDecode> LazyTransform for BlobTransform<T> {
        type Input = Box<[u8]>;
        type Output = T;
        type Error = DecodeError;

        fn lazy_transform(input: &Box<[u8]>) -> Result<T, DecodeError> {
            let mut slice = input.as_ref();
            let decoded = T::decode(&mut slice)?;
            if !slice.is_empty() {
                return Err(DecodeError::UnrecognizedData);
            }
            Ok(decoded)
        }
    }

    type BlobContents<T> = LazyMut<BlobTransform<T>>;

    impl<T: WasmbinDecode> Blob<T> {
        pub fn try_contents(&self) -> Result<&T, DecodeError> {
            self.contents.try_output()
        }

        pub fn try_contents_mut(&mut self) -> Result<&mut T, DecodeError> {
            self.contents.try_output_mut()
        }

        pub fn try_into_contents(self) -> Result<T, DecodeError> {
            self.contents.try_into_output()
        }
    }
} else {
    type BlobContents<T> = T;

    impl<T: WasmbinDecode> Blob<T> {
        pub fn try_contents(&self) -> Result<&T, DecodeError> {
            Ok(&self.contents)
        }

        pub fn try_contents_mut(&mut self) -> Result<&mut T, DecodeError> {
            Ok(&mut self.contents)
        }

        pub fn try_into_contents(self) -> Result<T, DecodeError> {
            Ok(self.contents)
        }
    }
});

#[derive(Default, Arbitrary, PartialEq, Eq)]
pub struct Blob<T: WasmbinDecode> {
    contents: BlobContents<T>,
}

impl<T: WasmbinDecode + std::fmt::Debug> std::fmt::Debug for Blob<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        f.write_str("Blob(")?;
        self.contents.fmt(f)?;
        f.write_str(")")
    }
}

impl<T: WasmbinDecode + WasmbinEncode> WasmbinEncode for Blob<T> {
    fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
        let output = if_lazy!(if lazy {
            match self.contents.input_res() {
                Ok(input) => return RawBlob { contents: input }.encode(w),
                Err(output) => output,
            }
        } else {
            &self.contents
        });
        let mut buf;
        buf = Vec::new();
        output.encode(&mut buf)?;
        RawBlob { contents: buf }.encode(w)
    }
}

impl<T: WasmbinDecode> WasmbinDecode for Blob<T> {
    fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
        let contents = RawBlob::decode(r)?.contents;
        if_lazy!(if lazy {
            let contents = LazyMut::new(Vec::into_boxed_slice(contents));
        });
        Ok(Blob { contents })
    }
}

impl<T: WasmbinDecode + WasmbinCountable> WasmbinCountable for Blob<T> {}
<commit_msg>Move PhantomData import to if_lazy<commit_after>use crate::{DecodeError, WasmbinCountable, WasmbinDecode, WasmbinEncode};
use arbitrary::Arbitrary;

#[cfg(feature = "lazy-blob")]
macro_rules! if_lazy {
    (if lazy { $($then:tt)* } $(else { $($otherwise:tt)* })?) => {
        $($then)*
    };
}

#[cfg(not(feature = "lazy-blob"))]
macro_rules! if_lazy {
    (if lazy { $($then:tt)* } $(else { $($otherwise:tt)* })?) => {
        $($($otherwise)*)?
    };
}

if_lazy!(if lazy {
    use crate::lazy_mut::{LazyMut, LazyTransform};
    use std::marker::PhantomData;
});

#[derive(Debug, Arbitrary, PartialEq, Eq)]
pub struct RawBlob<T = Vec<u8>> {
    pub contents: T,
}

impl<T: AsRef<[u8]>> WasmbinEncode for RawBlob<T> {
    fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
        let bytes = self.contents.as_ref();
        bytes.len().encode(w)?;
        bytes.encode(w)
    }
}

impl<T: WasmbinDecode> WasmbinDecode for RawBlob<T> {
    fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
        let size = u32::decode(r)?;
        let mut taken = std::io::Read::take(r, size.into());
        let contents = T::decode(&mut taken)?;
        if taken.limit() != 0 {
            return Err(DecodeError::UnrecognizedData);
        }
        Ok(RawBlob { contents })
    }
}

impl<T: AsRef<[u8]>> AsRef<[u8]> for RawBlob<T> {
    fn as_ref(&self) -> &[u8] {
        self.contents.as_ref()
    }
}

if_lazy!(if lazy {
    pub struct BlobTransform<T>(PhantomData<T>);

    impl<T: WasmbinDecode> LazyTransform for BlobTransform<T> {
        type Input = Box<[u8]>;
        type Output = T;
        type Error = DecodeError;

        fn lazy_transform(input: &Box<[u8]>) -> Result<T, DecodeError> {
            let mut slice = input.as_ref();
            let decoded = T::decode(&mut slice)?;
            if !slice.is_empty() {
                return Err(DecodeError::UnrecognizedData);
            }
            Ok(decoded)
        }
    }

    type BlobContents<T> = LazyMut<BlobTransform<T>>;

    impl<T: WasmbinDecode> Blob<T> {
        pub fn try_contents(&self) -> Result<&T, DecodeError> {
            self.contents.try_output()
        }

        pub fn try_contents_mut(&mut self) -> Result<&mut T, DecodeError> {
            self.contents.try_output_mut()
        }

        pub fn try_into_contents(self) -> Result<T, DecodeError> {
            self.contents.try_into_output()
        }
    }
} else {
    type BlobContents<T> = T;

    impl<T: WasmbinDecode> Blob<T> {
        pub fn try_contents(&self) -> Result<&T, DecodeError> {
            Ok(&self.contents)
        }

        pub fn try_contents_mut(&mut self) -> Result<&mut T, DecodeError> {
            Ok(&mut self.contents)
        }

        pub fn try_into_contents(self) -> Result<T, DecodeError> {
            Ok(self.contents)
        }
    }
});

#[derive(Default, Arbitrary, PartialEq, Eq)]
pub struct Blob<T: WasmbinDecode> {
    contents: BlobContents<T>,
}

impl<T: WasmbinDecode + std::fmt::Debug> std::fmt::Debug for Blob<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        f.write_str("Blob(")?;
        self.contents.fmt(f)?;
        f.write_str(")")
    }
}

impl<T: WasmbinDecode + WasmbinEncode> WasmbinEncode for Blob<T> {
    fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
        let output = if_lazy!(if lazy {
            match self.contents.input_res() {
                Ok(input) => return RawBlob { contents: input }.encode(w),
                Err(output) => output,
            }
        } else {
            &self.contents
        });
        let mut buf;
        buf = Vec::new();
        output.encode(&mut buf)?;
        RawBlob { contents: buf }.encode(w)
    }
}

impl<T: WasmbinDecode> WasmbinDecode for Blob<T> {
    fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
        let contents = RawBlob::decode(r)?.contents;
        if_lazy!(if lazy {
            let contents = LazyMut::new(Vec::into_boxed_slice(contents));
        });
        Ok(Blob { contents })
    }
}

impl<T: WasmbinDecode + WasmbinCountable> WasmbinCountable for Blob<T> {}
<|endoftext|>


<commit_before>pub enum Something {
	Yes,
	No
}

pub fn now() -> &'static str {
	"now"
}
<commit_msg>Cleanup<commit_after><|endoftext|>


<commit_before>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).
//!
//! # Examples
//! Here we take a node and execute some instructions and check if double 1 has
//! the expected result.
//!
//! ```rust
//! extern crate tis_100_superoptimizer;
//!
//! use tis_100_superoptimizer::TIS_100::{Node,Instruction,Source,Destination,Register};
//!
//! fn main() {
//!     let node: Node = Node::new();
//!     let last: Node = node
//!         .execute(Instruction::MOV(Source::Literal(1), Destination::Register(Register::ACC)))
//!         .execute(Instruction::ADD(Source::Register(Register::ACC)));
//!
//!     assert_eq!(2, last.acc);
//! }
//! ```

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug,PartialEq,Eq)]
pub struct Node {
    /// The accumulator for the basic execution node.
    pub acc: i32,
    bac: i32,
    pc: isize,
}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    /// A register
    Register(Register),
    /// A literal value
    Literal(i32)
}

/// Different types of Registers known in TIS-100
pub enum Register {
    /// the NIL register, reading from it provides with zero
    NIL,
    /// The accumulator
    ACC,
}

/// `Destination` are either ports or registers
pub enum Destination {
    /// A register
    Register(Register),
}

impl Node {
    /// Create a `Node` with defaults for accumulator and backup registers
    pub fn new() -> Node {
        Node { acc: 0, bac: 0, pc: 0 }
    }

    /// Create a `Node` with prescribed values for accumulator and backup registers
    pub fn with(acc: i32, bac: i32, pc: isize) -> Node {
        Node::new().set_acc(acc).set_bac(bac).set_pc(pc)
    }

    /// Create a `Node` from self with the program counter incremented
    pub fn increment_pc(&self) -> Node {
        Node { pc: self.pc + 1, .. *self }
    }

    /// Create a `Node` from self with a prescribed program counter value
    pub fn set_pc(&self, pc: isize) -> Node {
        Node { pc: pc, .. *self }
    }

    /// Create a `Node` from self with a prescribed accumulator register value
    pub fn set_acc(&self, acc: i32) -> Node {
        Node { acc: acc, .. *self }
    }

    /// Create a `Node` from self with a prescribed backup register value
    pub fn set_bac(&self, bac: i32) -> Node {
        Node { bac: bac, .. *self }
    }

    /// Execute the `instruction` on this `Node`. Returns a `Node` that reflects
    /// the changes the `instruction` would have on this `Node`.
    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        self.increment_pc()
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = self.value_from(source);

        self.move_value(value, destination)
    }

    fn value_from(&self, source: Source) -> i32 {
        match source {
            Source::Register(Register::NIL) => 0,
            Source::Register(Register::ACC) => self.acc,
            Source::Literal(value) => value,
        }
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::Register(Register::ACC) => self.increment_pc().set_acc(value),
            _ => self.nop(),
        }
    }

    fn swap(&self) -> Node {
        let acc: i32 = self.acc;
        let bac: i32 = self.bac;

        self.increment_pc().set_acc(bac).set_bac(acc)
    }

    fn save(&self) -> Node {
        self.increment_pc().set_bac(self.acc)
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = self.value_from(source);

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        self.increment_pc().set_acc(self.acc + value)
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = self.value_from(source);

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        self.increment_pc().set_acc(self.acc - value)
    }
}

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

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::with(1, 0, 0);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::with(1, 0, 0);
        let instruction: Instruction = Instruction::MOV(Source::Register(Register::NIL),
                                                        Destination::Register(Register::NIL));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::with(2, 1, 0);
        let instruction: Instruction = Instruction::MOV(Source::Register(Register::ACC),
                                                        Destination::Register(Register::ACC));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 1, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::with(0, 0, 0);
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::Register(Register::ACC));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::with(1, 0, 0);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(0, 1, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::with(1, 0, 0);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::with(1, 0, 0);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 0, 1), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::with(2, 0, 0);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0, 1), next);
    }
}

<commit_msg>Replace Node::with with node_with in test<commit_after>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).
//!
//! # Examples
//! Here we take a node and execute some instructions and check if double 1 has
//! the expected result.
//!
//! ```rust
//! extern crate tis_100_superoptimizer;
//!
//! use tis_100_superoptimizer::TIS_100::{Node,Instruction,Source,Destination,Register};
//!
//! fn main() {
//!     let node: Node = Node::new();
//!     let last: Node = node
//!         .execute(Instruction::MOV(Source::Literal(1), Destination::Register(Register::ACC)))
//!         .execute(Instruction::ADD(Source::Register(Register::ACC)));
//!
//!     assert_eq!(2, last.acc);
//! }
//! ```

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug,PartialEq,Eq)]
pub struct Node {
    /// The accumulator for the basic execution node.
    pub acc: i32,
    bac: i32,
    pc: isize,
}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    /// A register
    Register(Register),
    /// A literal value
    Literal(i32)
}

/// Different types of Registers known in TIS-100
pub enum Register {
    /// the NIL register, reading from it provides with zero
    NIL,
    /// The accumulator
    ACC,
}

/// `Destination` are either ports or registers
pub enum Destination {
    /// A register
    Register(Register),
}

impl Node {
    /// Create a `Node` with defaults for accumulator and backup registers
    pub fn new() -> Node {
        Node { acc: 0, bac: 0, pc: 0 }
    }

    /// Create a `Node` from self with the program counter incremented
    pub fn increment_pc(&self) -> Node {
        Node { pc: self.pc + 1, .. *self }
    }

    /// Create a `Node` from self with a prescribed program counter value
    pub fn set_pc(&self, pc: isize) -> Node {
        Node { pc: pc, .. *self }
    }

    /// Create a `Node` from self with a prescribed accumulator register value
    pub fn set_acc(&self, acc: i32) -> Node {
        Node { acc: acc, .. *self }
    }

    /// Create a `Node` from self with a prescribed backup register value
    pub fn set_bac(&self, bac: i32) -> Node {
        Node { bac: bac, .. *self }
    }

    /// Execute the `instruction` on this `Node`. Returns a `Node` that reflects
    /// the changes the `instruction` would have on this `Node`.
    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        self.increment_pc()
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = self.value_from(source);

        self.move_value(value, destination)
    }

    fn value_from(&self, source: Source) -> i32 {
        match source {
            Source::Register(Register::NIL) => 0,
            Source::Register(Register::ACC) => self.acc,
            Source::Literal(value) => value,
        }
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::Register(Register::ACC) => self.increment_pc().set_acc(value),
            _ => self.nop(),
        }
    }

    fn swap(&self) -> Node {
        let acc: i32 = self.acc;
        let bac: i32 = self.bac;

        self.increment_pc().set_acc(bac).set_bac(acc)
    }

    fn save(&self) -> Node {
        self.increment_pc().set_bac(self.acc)
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = self.value_from(source);

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        self.increment_pc().set_acc(self.acc + value)
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = self.value_from(source);

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        self.increment_pc().set_acc(self.acc - value)
    }
}

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

    fn node_with(acc: i32, bac: i32, pc: isize) -> Node {
        Node::new().set_acc(acc).set_bac(bac).set_pc(pc)
    }

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::new().set_acc(1);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::new().set_acc(1);
        let instruction: Instruction = Instruction::MOV(Source::Register(Register::NIL),
                                                        Destination::Register(Register::NIL));

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::new().set_acc(2).set_bac(1);
        let instruction: Instruction = Instruction::MOV(Source::Register(Register::ACC),
                                                        Destination::Register(Register::ACC));

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(2, 1, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::Register(Register::ACC));

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(1, 0, 1), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::new().set_acc(1);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(0, 1, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::new().set_acc(1);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(1, 1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::new().set_acc(1);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(2, 0, 1), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::new().set_acc(2);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(node_with(1, 0, 1), next);
    }
}

<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Adapters for various formats for [`Uuid`]s
//!
//! [`Uuid`]: ../struct.Uuid.html

use prelude::*;

mod core_support;

/// The length of a Hyphenated [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_HYPHENATED_LENGTH: usize = 36;

/// The length of a Simple [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_SIMPLE_LENGTH: usize = 32;

/// The length of a Urn [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_URN_LENGTH: usize = 45;

// TODO: documentation
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidHyphenated(Uuid);
// TODO: documentation
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidHyphenatedRef<'a>(&'a Uuid);
// TODO(kinggoesgaming): documentation
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidSimple(Uuid);
// TODO(kinggoesgaming): documentation
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidSimpleRef<'a>(&'a Uuid);
// TODO(kinggoesgaming): documentation
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidUrn(Uuid);
// TODO(kinggoesgaming): documentation
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidUrnRef<'a>(&'a Uuid);

impl Uuid {
    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_hyphenated(self) -> UuidHyphenated {
        UuidHyphenated::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_hyphenated(self) -> UuidHyphenated {
        UuidHyphenated::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_hyphenated_ref(&self) -> UuidHyphenatedRef {
        UuidHyphenatedRef::from_uuid_ref(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_hyphenated_ref(&self) -> UuidHyphenatedRef {
        UuidHyphenatedRef::from_uuid_ref(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_simple(self) -> UuidSimple {
        UuidSimple::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_simple(self) -> UuidSimple {
        UuidSimple::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_simple_ref(&self) -> UuidSimpleRef {
        UuidSimpleRef::from_uuid_ref(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_simple_ref(&self) -> UuidSimpleRef {
        UuidSimpleRef::from_uuid_ref(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_urn(self) -> UuidUrn {
        UuidUrn::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_urn(self) -> UuidUrn {
        UuidUrn::from_uuid(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_urn_ref(&self) -> UuidUrnRef {
        UuidUrnRef::from_uuid_ref(self)
    }

    // TODO(kinggoesgaming): documentation
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_urn_ref(&self) -> UuidUrnRef {
        UuidUrnRef::from_uuid_ref(self)
    }
}

impl UuidHyphenated {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidHyphenated(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidHyphenated(uuid)
    }
}

impl<'a> UuidHyphenatedRef<'a> {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidHyphenatedRef(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidHyphenatedRef(uuid)
    }
}

impl UuidSimple {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidSimple(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidSimple(uuid)
    }
}

impl<'a> UuidSimpleRef<'a> {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidSimpleRef(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidSimpleRef(uuid)
    }
}

impl UuidUrn {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidUrn(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidUrn(uuid)
    }
}

impl<'a> UuidUrnRef<'a> {
    // TODO(kinggoesgaming): documentation
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidUrnRef(uuid)
    }

    // TODO(kinggoesgaming): documentation
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidUrnRef(uuid)
    }
}
<commit_msg>add docs<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Adapters for various formats for [`Uuid`]s
//!
//! [`Uuid`]: ../struct.Uuid.html

use prelude::*;

mod core_support;

/// The length of a Hyphenated [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_HYPHENATED_LENGTH: usize = 36;

/// The length of a Simple [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_SIMPLE_LENGTH: usize = 32;

/// The length of a Urn [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
pub const UUID_URN_LENGTH: usize = 45;

/// An adaptor for formatting an [`Uuid`] as a hyphenated string.
///
/// Takes an owned instance of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidHyphenated(Uuid);

/// An adaptor for formatting an [`Uuid`] as a hyphenated string.
///
/// Takes a reference of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidHyphenatedRef<'a>(&'a Uuid);

/// An adaptor for formatting an [`Uuid`] as a simple string.
///
/// Takes an owned instance of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidSimple(Uuid);

/// An adaptor for formatting an [`Uuid`] as a simple string.
///
/// Takes a reference of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidSimpleRef<'a>(&'a Uuid);

/// An adaptor for formatting an [`Uuid`] as a URN string.
///
/// Takes an owned instance of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidUrn(Uuid);

/// An adaptor for formatting an [`Uuid`] as a URN string.
///
/// Takes a reference of the [`Uuid`].
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UuidUrnRef<'a>(&'a Uuid);

impl Uuid {
    /// Creates a [`UuidHyphenated`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenated`]: struct.UuidHyphenated.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_hyphenated(self) -> UuidHyphenated {
        UuidHyphenated::from_uuid(self)
    }

    /// Creates a [`UuidHyphenated`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenated`]: struct.UuidHyphenated.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_hyphenated(self) -> UuidHyphenated {
        UuidHyphenated::from_uuid(self)
    }

    /// Creates a [`UuidHyphenatedRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenatedRef`]: struct.UuidHyphenatedRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_hyphenated_ref(&self) -> UuidHyphenatedRef {
        UuidHyphenatedRef::from_uuid_ref(self)
    }

    /// Creates a [`UuidHyphenatedRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenatedRef`]: struct.UuidHyphenatedRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_hyphenated_ref(&self) -> UuidHyphenatedRef {
        UuidHyphenatedRef::from_uuid_ref(self)
    }

    /// Creates a [`UuidSimple`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimple`]: struct.UuidSimple.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_simple(self) -> UuidSimple {
        UuidSimple::from_uuid(self)
    }

    /// Creates a [`UuidSimple`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimple`]: struct.UuidSimple.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_simple(self) -> UuidSimple {
        UuidSimple::from_uuid(self)
    }

    /// Creates a [`UuidSimpleRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimpleRef`]: struct.UuidSimpleRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_simple_ref(&self) -> UuidSimpleRef {
        UuidSimpleRef::from_uuid_ref(self)
    }

    /// Creates a [`UuidSimpleRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimpleRef`]: struct.UuidSimpleRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_simple_ref(&self) -> UuidSimpleRef {
        UuidSimpleRef::from_uuid_ref(self)
    }

    /// Creates a [`UuidUrn`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrn`]: struct.UuidUrn.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_urn(self) -> UuidUrn {
        UuidUrn::from_uuid(self)
    }

    /// Creates a [`UuidUrn`] instance from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrn`]: struct.UuidUrn.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_urn(self) -> UuidUrn {
        UuidUrn::from_uuid(self)
    }

    /// Creates a [`UuidUrnRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrnRef`]: struct.UuidUrnRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn to_urn_ref(&self) -> UuidUrnRef {
        UuidUrnRef::from_uuid_ref(self)
    }

    /// Creates a [`UuidUrnRef`] instance from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrnRef`]: struct.UuidUrnRef.html
    // TODO(kinggoesgaming): discuss to_ vs as_ vs into_
    #[cfg(feature = "const_fn")]
    #[inline]
    pub fn to_urn_ref(&self) -> UuidUrnRef {
        UuidUrnRef::from_uuid_ref(self)
    }
}

impl UuidHyphenated {
    /// Creates a [`UuidHyphenated`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenated`]: struct.UuidHyphenated.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidHyphenated(uuid)
    }

    /// Creates a [`UuidHyphenated`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenated`]: struct.UuidHyphenated.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidHyphenated(uuid)
    }
}

impl<'a> UuidHyphenatedRef<'a> {
    /// Creates a [`UuidHyphenatedRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenatedRef`]: struct.UuidHyphenatedRef.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidHyphenatedRef(uuid)
    }

    /// Creates a [`UuidHyphenatedRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidHyphenatedRef`]: struct.UuidHyphenatedRef.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidHyphenatedRef(uuid)
    }
}

impl UuidSimple {
    /// Creates a [`UuidSimple`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimple`]: struct.UuidSimple.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidSimple(uuid)
    }

    /// Creates a [`UuidSimple`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimple`]: struct.UuidSimple.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidSimple(uuid)
    }
}

impl<'a> UuidSimpleRef<'a> {
    /// Creates a [`UuidSimpleRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimpleRef`]: struct.UuidSimpleRef.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidSimpleRef(uuid)
    }

    /// Creates a [`UuidSimpleRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidSimpleRef`]: struct.UuidSimpleRef.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidSimpleRef(uuid)
    }
}

impl UuidUrn {
    /// Creates a [`UuidUrn`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrn`]: struct.UuidUrn.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidUrn(uuid)
    }

    /// Creates a [`UuidUrn`] from a [`Uuid`].
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrn`]: struct.UuidUrn.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid(uuid: Uuid) -> Self {
        UuidUrn(uuid)
    }
}

impl<'a> UuidUrnRef<'a> {
    /// Creates a [`UuidUrnRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrnRef`]: struct.UuidUrnRef.html
    #[cfg(not(feature = "const_fn"))]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidUrnRef(uuid)
    }

    /// Creates a [`UuidUrnRef`] from a [`Uuid`] reference.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`UuidUrnRef`]: struct.UuidUrnRef.html
    #[cfg(feature = "const_fn")]
    pub fn from_uuid_ref(uuid: &'a Uuid) -> Self {
        UuidUrnRef(&uuid)
    }
}
<|endoftext|>


<commit_before>use num::cast::{NumCast, cast};

pub trait Channel {
    static pure fn channel_max() -> self;

    static pure fn from_channel<T:Channel>(val: T) -> self;
    pure fn convert_channel<T:Channel>() -> T;

    pure fn to_channel_u8()    -> u8;
    pure fn to_channel_u16()   -> u16;
    pure fn to_channel_u32()   -> u32;
    pure fn to_channel_u64()   -> u64;
    pure fn to_channel_f32()   -> f32;
    pure fn to_channel_f64()   -> f64;
    pure fn to_channel_float() -> float;

    pure fn inverse() -> self;
}

pub pure fn convert_channel<T:Channel, U:Channel>(val: T) -> U { val.convert_channel() }

pub impl u8: Channel {
    static pure fn channel_max() -> u8 { 0xFF }  // 2^8

    static pure fn from_channel<T:Channel>(val: T) -> u8 { val.to_channel_u8() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self }
    pure fn to_channel_u16()   -> u16   { (self as u16 << 8) | self as u16 }
    pure fn to_channel_u32()   -> u32   { (self.to_channel_u16() as u32 << 16) | self.to_channel_u16() as u32 }
    pure fn to_channel_u64()   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    pure fn to_channel_f32()   -> f32   { (self as f32)   / (0xFF as f32)   }
    pure fn to_channel_f64()   -> f64   { (self as f64)   / (0xFF as f64)   }
    pure fn to_channel_float() -> float { (self as float) / (0xFF as float) }

    pure fn inverse() -> u8 { !self }
}

pub impl u16: Channel {
    static pure fn channel_max() -> u16 { 0xFFFF }   // 2^16

    static pure fn from_channel<T:Channel>(val: T) -> u16 { val.to_channel_u16() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self / 0x100 as u8 }
    pure fn to_channel_u16()   -> u16   { self }
    pure fn to_channel_u32()   -> u32   { (self as u32 << 16) | self as u32 }
    pure fn to_channel_u64()   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    pure fn to_channel_f32()   -> f32   { self / 0xFFFF as f32   }
    pure fn to_channel_f64()   -> f64   { self / 0xFFFF as f64   }
    pure fn to_channel_float() -> float { self / 0xFFFF as float }

    pure fn inverse() -> u16 { !self }
}

pub impl u32: Channel {
    static pure fn channel_max() -> u32 { 0xFFFF_FFFF }   // 2^32

    static pure fn from_channel<T:Channel>(val: T) -> u32 { val.to_channel_u32() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self / 0x1_0000_00 as u8 }
    pure fn to_channel_u16()   -> u16   { self / 0x1_0000 as u16 }
    pure fn to_channel_u32()   -> u32   { self }
    pure fn to_channel_u64()   -> u64   { (self as u64 << 32) | self as u64 }
    pure fn to_channel_f32()   -> f32   { self / 0xFFFF_FFFF as f32   }
    pure fn to_channel_f64()   -> f64   { self / 0xFFFF_FFFF as f64   }
    pure fn to_channel_float() -> float { self / 0xFFFF_FFFF as float }

    pure fn inverse() -> u32 { !self }
}

pub impl u64: Channel {
    static pure fn channel_max() -> u64 { 0xFFFF_FFFF_FFFF_FFFF_u64 }   // 2^64

    static pure fn from_channel<T:Channel>(val: T) -> u64 { val.to_channel_u64() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self / 0x1_0000_0000_0000_00 as u8 }
    pure fn to_channel_u16()   -> u16   { self / 0x1_0000_0000_0000 as u16 }
    pure fn to_channel_u32()   -> u32   { self / 0x1_0000_0000 as u32 }
    pure fn to_channel_u64()   -> u64   { self }
    pure fn to_channel_f32()   -> f32   { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as f32   }
    pure fn to_channel_f64()   -> f64   { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as f64   }
    pure fn to_channel_float() -> float { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as float }

    pure fn inverse() -> u64 { !self }
}

pub impl f32: Channel {
    static pure fn channel_max() -> f32 { 1f32 }

    static pure fn from_channel<T:Channel>(val: T) -> f32 { val.to_channel_f32() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as f32) as u8  }
    pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as f32) as u16 }
    pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for f32") }
    pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for f32") }
    pure fn to_channel_f32()   -> f32   { self }
    pure fn to_channel_f64()   -> f64   { self as f64 }
    pure fn to_channel_float() -> float { self as float }

    pure fn inverse() -> f32 { 1.0 - self }
}

pub impl f64: Channel {
    static pure fn channel_max() -> f64 { 1f64 }

    static pure fn from_channel<T:Channel>(val: T) -> f64 { val.to_channel_f64() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as f64) as u8  }
    pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as f64) as u16 }
    pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for f64") }
    pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for f64") }
    pure fn to_channel_f32()   -> f32   { self as f32 }
    pure fn to_channel_f64()   -> f64   { self }
    pure fn to_channel_float() -> float { self as float }

    pure fn inverse() -> f64 { 1.0 - self }
}

pub impl float: Channel {
    static pure fn channel_max() -> float { 1f }

    static pure fn from_channel<T:Channel>(val: T) -> float { val.to_channel_float() }
    pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as float) as u8  }
    pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as float) as u16 }
    pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for float") }
    pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for float") }
    pure fn to_channel_f32()   -> f32   { self as f32 }
    pure fn to_channel_f64()   -> f64   { self as f64 }
    pure fn to_channel_float() -> float { self }

    pure fn inverse() -> float { 1.0 - self }
}<commit_msg>Set functions to inline<commit_after>use num::cast::{NumCast, cast};

pub trait Channel {
    static pure fn channel_max() -> self;

    static pure fn from_channel<T:Channel>(val: T) -> self;
    pure fn convert_channel<T:Channel>() -> T;

    pure fn to_channel_u8()    -> u8;
    pure fn to_channel_u16()   -> u16;
    pure fn to_channel_u32()   -> u32;
    pure fn to_channel_u64()   -> u64;
    pure fn to_channel_f32()   -> f32;
    pure fn to_channel_f64()   -> f64;
    pure fn to_channel_float() -> float;

    pure fn inverse() -> self;
}

pub pure fn convert_channel<T:Channel, U:Channel>(val: T) -> U { val.convert_channel() }

pub impl u8: Channel {
    #[inline(always)] static pure fn channel_max() -> u8 { 0xFF }  // 2^8

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> u8 { val.to_channel_u8() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { (self as u16 << 8) | self as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { (self.to_channel_u16() as u32 << 16) | self.to_channel_u16() as u32 }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { (self as f32)   / (0xFF as f32)   }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { (self as f64)   / (0xFF as f64)   }
    #[inline(always)] pure fn to_channel_float() -> float { (self as float) / (0xFF as float) }

    #[inline(always)] pure fn inverse() -> u8 { !self }
}

pub impl u16: Channel {
    #[inline(always)] static pure fn channel_max() -> u16 { 0xFFFF }   // 2^16

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> u16 { val.to_channel_u16() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self / 0x100 as u8 }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { (self as u32 << 16) | self as u32 }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self / 0xFFFF as f32   }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self / 0xFFFF as f64   }
    #[inline(always)] pure fn to_channel_float() -> float { self / 0xFFFF as float }

    #[inline(always)] pure fn inverse() -> u16 { !self }
}

pub impl u32: Channel {
    #[inline(always)] static pure fn channel_max() -> u32 { 0xFFFF_FFFF }   // 2^32

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> u32 { val.to_channel_u32() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self / 0x1_0000_00 as u8 }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self / 0x1_0000 as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { self }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { (self as u64 << 32) | self as u64 }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self / 0xFFFF_FFFF as f32   }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self / 0xFFFF_FFFF as f64   }
    #[inline(always)] pure fn to_channel_float() -> float { self / 0xFFFF_FFFF as float }

    #[inline(always)] pure fn inverse() -> u32 { !self }
}

pub impl u64: Channel {
    #[inline(always)] static pure fn channel_max() -> u64 { 0xFFFF_FFFF_FFFF_FFFF_u64 }   // 2^64

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> u64 { val.to_channel_u64() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self / 0x1_0000_0000_0000_00 as u8 }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self / 0x1_0000_0000_0000 as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { self / 0x1_0000_0000 as u32 }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { self }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as f32   }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as f64   }
    #[inline(always)] pure fn to_channel_float() -> float { self / 0xFFFF_FFFF_FFFF_FFFF_u64 as float }

    #[inline(always)] pure fn inverse() -> u64 { !self }
}

pub impl f32: Channel {
    #[inline(always)] static pure fn channel_max() -> f32 { 1f32 }

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> f32 { val.to_channel_f32() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as f32) as u8  }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as f32) as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for f32") }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self as f64 }
    #[inline(always)] pure fn to_channel_float() -> float { self as float }

    #[inline(always)] pure fn inverse() -> f32 { 1.0 - self }
}

pub impl f64: Channel {
    #[inline(always)] static pure fn channel_max() -> f64 { 1f64 }

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> f64 { val.to_channel_f64() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as f64) as u8  }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as f64) as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for f64") }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self as f32 }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self }
    #[inline(always)] pure fn to_channel_float() -> float { self as float }

    #[inline(always)] pure fn inverse() -> f64 { 1.0 - self }
}

pub impl float: Channel {
    #[inline(always)] static pure fn channel_max() -> float { 1f }

    #[inline(always)] static pure fn from_channel<T:Channel>(val: T) -> float { val.to_channel_float() }
    #[inline(always)] pure fn convert_channel<T:Channel>() -> T { from_channel(self) }

    #[inline(always)] pure fn to_channel_u8()    -> u8    { self * (0xFFu8    as float) as u8  }
    #[inline(always)] pure fn to_channel_u16()   -> u16   { self * (0xFFFFu16 as float) as u16 }
    #[inline(always)] pure fn to_channel_u32()   -> u32   { fail(~"to_channel_u32 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_u64()   -> u64   { fail(~"to_channel_u64 not yet implemented for float") }
    #[inline(always)] pure fn to_channel_f32()   -> f32   { self as f32 }
    #[inline(always)] pure fn to_channel_f64()   -> f64   { self as f64 }
    #[inline(always)] pure fn to_channel_float() -> float { self }

    #[inline(always)] pure fn inverse() -> float { 1.0 - self }
}<|endoftext|>


<commit_before>import std._io.stdio_reader;

fn in_range(char c, char lo, char hi) -> bool {
    ret lo <= c && c <= hi;
}

fn is_alpha(char c) -> bool {
    ret in_range(c, 'a', 'z') ||
        in_range(c, 'A', 'Z');
}

fn is_dec_digit(char c) -> bool {
    ret in_range(c, '0', '9');
}

fn is_hex_digit(char c) -> bool {
    ret in_range(c, '0', '9') ||
        in_range(c, 'a', 'f') ||
        in_range(c, 'A', 'F');
}

fn is_bin_digit(char c) -> bool {
    ret c == '0' || c == '1';
}

fn is_whitespace(char c) -> bool {
    ret c == ' ' || c == '\t' || c == '\r';
}

fn next_token(stdio_reader rdr) -> token.token {
    auto eof = (-1) as char;
    auto c = rdr.getc() as char;
    auto accum = "";

    while (is_whitespace(c) && c != eof) {
        c = rdr.getc() as char;
    }

    if (c == eof) { ret token.EOF(); }

    if (is_alpha(c)) {
        while (is_alpha(c)) {
            accum += (c as u8);
            c = rdr.getc() as char;
        }
        rdr.ungetc(c as int);
        ret token.IDENT(accum);
    }

    if (is_dec_digit(c)) {
        if (c == '0') {
        } else {
            while (is_dec_digit(c)) {
                accum += (c as u8);
                c = rdr.getc() as char;
            }
            rdr.ungetc(c as int);
            ret token.LIT_INT(0);
        }
    }

    // One-byte structural symbols.
    if (c == ';') { ret token.SEMI(); }
    if (c == '.') { ret token.DOT(); }
    if (c == '(') { ret token.LPAREN(); }
    if (c == ')') { ret token.RPAREN(); }
    if (c == '{') { ret token.LBRACE(); }
    if (c == '}') { ret token.RBRACE(); }
    if (c == '[') { ret token.LBRACKET(); }
    if (c == ']') { ret token.RBRACKET(); }
    if (c == '@') { ret token.AT(); }
    if (c == '#') { ret token.POUND(); }

    log "lexer stopping at ";
    log c;
    ret token.EOF();
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Use pattern matching for the one-byte structural symbols in the self-hosted compiler<commit_after>import std._io.stdio_reader;

fn in_range(char c, char lo, char hi) -> bool {
    ret lo <= c && c <= hi;
}

fn is_alpha(char c) -> bool {
    ret in_range(c, 'a', 'z') ||
        in_range(c, 'A', 'Z');
}

fn is_dec_digit(char c) -> bool {
    ret in_range(c, '0', '9');
}

fn is_hex_digit(char c) -> bool {
    ret in_range(c, '0', '9') ||
        in_range(c, 'a', 'f') ||
        in_range(c, 'A', 'F');
}

fn is_bin_digit(char c) -> bool {
    ret c == '0' || c == '1';
}

fn is_whitespace(char c) -> bool {
    ret c == ' ' || c == '\t' || c == '\r';
}

fn next_token(stdio_reader rdr) -> token.token {
    auto eof = (-1) as char;
    auto c = rdr.getc() as char;
    auto accum = "";

    while (is_whitespace(c) && c != eof) {
        c = rdr.getc() as char;
    }

    if (c == eof) { ret token.EOF(); }

    if (is_alpha(c)) {
        while (is_alpha(c)) {
            accum += (c as u8);
            c = rdr.getc() as char;
        }
        rdr.ungetc(c as int);
        ret token.IDENT(accum);
    }

    if (is_dec_digit(c)) {
        if (c == '0') {
        } else {
            while (is_dec_digit(c)) {
                accum += (c as u8);
                c = rdr.getc() as char;
            }
            rdr.ungetc(c as int);
            ret token.LIT_INT(0);
        }
    }

    // One-byte structural symbols.
    alt (c) {
    case (';') { ret token.SEMI(); }
    case ('.') { ret token.DOT(); }
    case ('(') { ret token.LPAREN(); }
    case (')') { ret token.RPAREN(); }
    case ('{') { ret token.LBRACE(); }
    case ('}') { ret token.RBRACE(); }
    case ('[') { ret token.LBRACKET(); }
    case (']') { ret token.RBRACKET(); }
    case ('@') { ret token.AT(); }
    case ('#') { ret token.POUND(); }
    }

    log "lexer stopping at ";
    log c;
    ret token.EOF();
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>