<commit_before>use std::ffi::CString;
use std::mem;
use libc::size_t;

use {encode, Encode};
use runtime::{Class, Imp, Sel};
use runtime;

/// A type for declaring a new method.
/// `MethodDecl`s are usually created using the `method!` macro.
pub struct MethodDecl {
    /// The method's selector.
    pub sel: Sel,
    /// The method's implementation.
    pub imp: Imp,
    /// The types of the method's arguments.
    pub types: String,
}

/// A type for declaring a new class and adding new methods and ivars to it
/// before registering it.
pub struct ClassDecl {
    cls: *mut Class,
}

impl ClassDecl {
    /// Constructs a `ClassDecl` with the given superclass and name.
    /// Returns `None` if the class couldn't be allocated.
    pub fn new(superclass: &Class, name: &str) -> Option<ClassDecl> {
        let name = CString::from_slice(name.as_bytes());
        let cls = unsafe {
            runtime::objc_allocateClassPair(superclass, name.as_ptr(), 0)
        };
        if cls.is_null() {
            None
        } else {
            Some(ClassDecl { cls: cls })
        }
    }

    /// Adds a method declared with the given `MethodDecl` to self.
    /// Returns true if the method was sucessfully added.
    pub fn add_method(&mut self, method: MethodDecl) -> bool {
        let MethodDecl { sel, imp, types } = method;
        let types = CString::from_vec(types.into_bytes());
        unsafe {
            runtime::class_addMethod(self.cls, sel, imp, types.as_ptr())
        }
    }

    /// Adds an ivar with type `T` and the provided name to self.
    /// Returns true if the ivar was sucessfully added.
    pub fn add_ivar<T: Encode>(&mut self, name: &str) -> bool {
        let name = CString::from_slice(name.as_bytes());
        let types = CString::from_slice(encode::<T>().as_bytes());
        let size = mem::size_of::<T>() as size_t;
        let align = mem::align_of::<T>() as u8;
        unsafe {
            runtime::class_addIvar(self.cls, name.as_ptr(), size, align,
                types.as_ptr())
        }
    }

    /// Registers self, consuming it and returning a reference to the
    /// newly registered `Class`.
    pub fn register(self) -> &'static Class {
        unsafe {
            let cls = self.cls;
            runtime::objc_registerClassPair(cls);
            // Forget self otherwise the class will be disposed in drop
            mem::forget(self);
            &*cls
        }
    }
}

impl Drop for ClassDecl {
    fn drop(&mut self) {
        unsafe {
            runtime::objc_disposeClassPair(self.cls);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use encode;
    use runtime::{Class, Object, Sel};
    use super::{ClassDecl, MethodDecl};

    #[test]
    fn test_custom_class() {
        let superclass = Class::get("NSObject").unwrap();
        let decl = ClassDecl::new(superclass, "MyObject");
        assert!(decl.is_some());
        let mut decl = decl.unwrap();

        decl.add_ivar::<uint>("_foo");

        extern fn my_object_get_foo(this: &Object, _cmd: Sel) -> uint {
            unsafe {
                *this.get_ivar::<uint>("_foo")
            }
        }
        decl.add_method(MethodDecl {
            sel: Sel::register("foo"),
            imp: unsafe { mem::transmute(my_object_get_foo) },
            types: String::from_str(encode::<uint>()) + "@:",
        });

        extern fn my_object_set_foo(this: &mut Object, _cmd: Sel, foo: uint) {
            unsafe {
                this.set_ivar::<uint>("_foo", foo);
            }
        }
        decl.add_method(MethodDecl {
            sel: Sel::register("setFoo:"),
            imp: unsafe { mem::transmute(my_object_set_foo) },
            types: String::from_str("v@:") + encode::<uint>(),
        });

        let cls = decl.register();
        unsafe {
            let obj = msg_send![cls, alloc];
            let obj = msg_send![obj, init];

            msg_send![obj, setFoo:13u];
            let result = msg_send![obj, foo] as uint;
            assert!(result == 13);

            msg_send![obj, release];
        }
    }
}
<commit_msg>Made declare tests use the method! macro again.<commit_after>use std::ffi::CString;
use std::mem;
use libc::size_t;

use {encode, Encode};
use runtime::{Class, Imp, Sel};
use runtime;

/// A type for declaring a new method.
/// `MethodDecl`s are usually created using the `method!` macro.
pub struct MethodDecl {
    /// The method's selector.
    pub sel: Sel,
    /// The method's implementation.
    pub imp: Imp,
    /// The types of the method's arguments.
    pub types: String,
}

/// A type for declaring a new class and adding new methods and ivars to it
/// before registering it.
pub struct ClassDecl {
    cls: *mut Class,
}

impl ClassDecl {
    /// Constructs a `ClassDecl` with the given superclass and name.
    /// Returns `None` if the class couldn't be allocated.
    pub fn new(superclass: &Class, name: &str) -> Option<ClassDecl> {
        let name = CString::from_slice(name.as_bytes());
        let cls = unsafe {
            runtime::objc_allocateClassPair(superclass, name.as_ptr(), 0)
        };
        if cls.is_null() {
            None
        } else {
            Some(ClassDecl { cls: cls })
        }
    }

    /// Adds a method declared with the given `MethodDecl` to self.
    /// Returns true if the method was sucessfully added.
    pub fn add_method(&mut self, method: MethodDecl) -> bool {
        let MethodDecl { sel, imp, types } = method;
        let types = CString::from_vec(types.into_bytes());
        unsafe {
            runtime::class_addMethod(self.cls, sel, imp, types.as_ptr())
        }
    }

    /// Adds an ivar with type `T` and the provided name to self.
    /// Returns true if the ivar was sucessfully added.
    pub fn add_ivar<T: Encode>(&mut self, name: &str) -> bool {
        let name = CString::from_slice(name.as_bytes());
        let types = CString::from_slice(encode::<T>().as_bytes());
        let size = mem::size_of::<T>() as size_t;
        let align = mem::align_of::<T>() as u8;
        unsafe {
            runtime::class_addIvar(self.cls, name.as_ptr(), size, align,
                types.as_ptr())
        }
    }

    /// Registers self, consuming it and returning a reference to the
    /// newly registered `Class`.
    pub fn register(self) -> &'static Class {
        unsafe {
            let cls = self.cls;
            runtime::objc_registerClassPair(cls);
            // Forget self otherwise the class will be disposed in drop
            mem::forget(self);
            &*cls
        }
    }
}

impl Drop for ClassDecl {
    fn drop(&mut self) {
        unsafe {
            runtime::objc_disposeClassPair(self.cls);
        }
    }
}

#[cfg(test)]
mod tests {
    use runtime::{Class, Object};
    use super::ClassDecl;

    #[test]
    fn test_custom_class() {
        let superclass = Class::get("NSObject").unwrap();
        let decl = ClassDecl::new(superclass, "MyObject");
        assert!(decl.is_some());
        let mut decl = decl.unwrap();

        decl.add_ivar::<uint>("_foo");
        decl.add_method(method!(
            (*mut Object)_this, doNothing; {
                ()
            }
        ));
        decl.add_method(method!(
            (&mut Object)this, setFoo:(uint)foo; {
                unsafe {
                    this.set_ivar::<uint>("_foo", foo);
                }
            }
        ));
        decl.add_method(method!(
            (&Object)this, foo -> uint, {
                unsafe {
                    *this.get_ivar::<uint>("_foo")
                }
            }
        ));
        decl.add_method(method!(
            (*mut Object)this, doSomethingWithFoo:(uint)_foo -> *mut Object, {
                this
            }
        ));

        let cls = decl.register();
        unsafe {
            let obj = msg_send![cls, alloc];
            let obj = msg_send![obj, init];

            msg_send![obj, doNothing];
            msg_send![obj, setFoo:13u];
            let result = msg_send![obj, foo] as uint;
            assert!(result == 13);
            let result = msg_send![obj, doSomethingWithFoo:13u];
            assert!(result == obj);

            msg_send![obj, release];
        }
    }
}
<|endoftext|>


<commit_before>use anyhow::{bail, Result};

/// Send a signal to a windows process.
pub fn send_signal(pid: u32, action: &ProcessAction, children: bool) -> Result<bool> {
    bail!("not supported on windows.")
}

/// Get all children of a specific process
pub fn get_children(pid: i32) -> Option<Vec<i32>> {
    None
}

/// A small helper that sends a signal to all children of a specific process by id.
pub fn send_signal_to_children(pid: i32, action: &ProcessAction) {
    error!(
        "Calling send_signal_to_children on task {} on windows. This shouldn't happen!",
        task_id
    )
}
<commit_msg>Fix windows function name<commit_after>use anyhow::{bail, Result};

/// Send a signal to a windows process.
pub fn send_signal(pid: u32, action: &ProcessAction, children: bool) -> Result<bool> {
    bail!("not supported on windows.")
}

/// Get all children of a specific process
pub fn get_children(pid: i32) -> Option<Vec<i32>> {
    None
}

/// Send a signal to multiple processes
pub fn send_signal_to_processes(pid: i32, action: &ProcessAction) {}
<|endoftext|>


<commit_before>#[macro_use]
extern crate assert_cli;
extern crate tempdir;
extern crate toml;

use std::process;
mod utils;
use utils::{clone_out_test, execute_command, get_toml, no_manifest_failures};

#[test]
fn adds_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package").is_none());

    execute_command(&["add", "my-package"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_multiple_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1", "my-package2"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dependencies.my-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_dev_build_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.my-dev-package").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package").is_none());

    execute_command(&["add", "my-dev-package", "--dev"], &manifest);
    execute_command(&["add", "my-build-package", "--build"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.my-dev-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");

    // cannot run with both --dev and --build at the same time
    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure", "--dev", "--build"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_multiple_dev_build_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.my-dev-package1").is_none());
    assert!(toml.lookup("dev-dependencies.my-dev-package2").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package1").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package2").is_none());

    execute_command(&["add", "my-dev-package1", "my-dev-package2", "--dev"], &manifest);
    execute_command(&["add", "my-build-package1", "--build", "my-build-package2"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.my-dev-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dev-dependencies.my-dev-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_specified_version() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1"],
                    &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");

    // cannot run with both --dev and --build at the same time
    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure", "--vers", "invalid version string"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_specified_version_with_inline_notation() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package@>=0.1.1"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");
}

#[test]
fn adds_multiple_dependencies_with_versions() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1@>=0.1.1", "my-package2@0.2.3"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");
    let val = toml.lookup("dependencies.my-package2").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "0.2.3");
}

#[test]
fn adds_multiple_dependencies_with_some_versions() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1", "my-package2@0.2.3"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dependencies.my-package2").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "0.2.3");
}

#[test]
fn adds_git_source() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.git-package").is_none());

    execute_command(&["add", "git-package", "--git", "http://localhost/git-package.git"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.git-package").unwrap();
    assert_eq!(val.as_table().unwrap().get("git").unwrap().as_str().unwrap(),
               "http://localhost/git-package.git");

    // check this works with other flags (e.g. --dev) as well
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.git-dev-pkg").is_none());

    execute_command(&["add", "git-dev-pkg", "--git", "http://site/gp.git", "--dev"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.git-dev-pkg").unwrap();
    assert_eq!(val.as_table().unwrap().get("git").unwrap().as_str().unwrap(),
               "http://site/gp.git");
}

#[test]
fn adds_local_source() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.local").is_none());

    execute_command(&["add", "local", "--path", "/path/to/pkg"], &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.local").unwrap();
    assert_eq!(val.as_table().unwrap().get("path").unwrap().as_str().unwrap(),
               "/path/to/pkg");

    // check this works with other flags (e.g. --dev) as well
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.local-dev").is_none());

    execute_command(&["add", "local-dev", "--path", "/path/to/pkg-dev", "--dev"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.local-dev").unwrap();
    assert_eq!(val.as_table().unwrap().get("path").unwrap().as_str().unwrap(),
               "/path/to/pkg-dev");
}

#[test]
fn package_kinds_are_mutually_exclusive() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure"])
                   .args(&["--vers", "0.4.3"])
                   .args(&["--git", "git://git.git"])
                   .args(&["--path", "/path/here"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_optional_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1", "--optional"],
                    &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
}

#[test]
fn adds_multiple_optional_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "--optional", "my-package1", "my-package2"],
                    &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
    let val = toml.lookup("dependencies.my-package2.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
}

#[test]
#[should_panic]
fn failt_to_add_optional_dev_dependency() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    // Fails because optional dependencies must be in `dependencies` table.
    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1", "--dev", "--optional"],
                    &manifest);
}

#[test]
fn no_argument() {
    assert_cli!("target/debug/cargo-add", &["add"] => Error 1,
                r"Invalid arguments.

Usage:
    cargo add <crate> [--dev|--build|--optional] [--vers=<ver>|--git=<uri>|--path=<uri>] [options]
    cargo add <crates>... [--dev|--build|--optional] [options]
    cargo add (-h|--help)
    cargo add --version")
        .unwrap();
}

#[test]
fn unknown_flags() {
    assert_cli!("target/debug/cargo-add", &["add", "foo", "--flag"] => Error 1,
                r"Unknown flag: '--flag'

Usage:
    cargo add <crate> [--dev|--build|--optional] [--vers=<ver>|--git=<uri>|--path=<uri>] [options]
    cargo add <crates>... [--dev|--build|--optional] [options]
    cargo add (-h|--help)
    cargo add --version")
        .unwrap();
}
<commit_msg>Add Test for Adding Multiple Optional Deps<commit_after>#[macro_use]
extern crate assert_cli;
extern crate tempdir;
extern crate toml;

use std::process;
mod utils;
use utils::{clone_out_test, execute_command, get_toml, no_manifest_failures};

#[test]
fn adds_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package").is_none());

    execute_command(&["add", "my-package"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_multiple_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1", "my-package2"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dependencies.my-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_dev_build_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.my-dev-package").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package").is_none());

    execute_command(&["add", "my-dev-package", "--dev"], &manifest);
    execute_command(&["add", "my-build-package", "--build"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.my-dev-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");

    // cannot run with both --dev and --build at the same time
    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure", "--dev", "--build"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_multiple_dev_build_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.my-dev-package1").is_none());
    assert!(toml.lookup("dev-dependencies.my-dev-package2").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package1").is_none());
    assert!(toml.lookup("build-dependencies.my-build-package2").is_none());

    execute_command(&["add", "my-dev-package1", "my-dev-package2", "--dev"], &manifest);
    execute_command(&["add", "my-build-package1", "--build", "my-build-package2"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.my-dev-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dev-dependencies.my-dev-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package1").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
    let val = toml.lookup("build-dependencies.my-build-package2").unwrap();
    assert_eq!(val.as_str().unwrap(), "CURRENT_VERSION_TEST");
}

#[test]
fn adds_specified_version() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1"],
                    &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");

    // cannot run with both --dev and --build at the same time
    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure", "--vers", "invalid version string"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_specified_version_with_inline_notation() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package@>=0.1.1"], &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");
}

#[test]
fn adds_multiple_dependencies_with_versions() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1@>=0.1.1", "my-package2@0.2.3"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").expect("not added");
    assert_eq!(val.as_str().expect("not string"), ">=0.1.1");
    let val = toml.lookup("dependencies.my-package2").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "0.2.3");
}

#[test]
fn adds_multiple_dependencies_with_some_versions() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "my-package1", "my-package2@0.2.3"], &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "CURRENT_VERSION_TEST");
    let val = toml.lookup("dependencies.my-package2").expect("not added");
    assert_eq!(val.as_str().expect("not string"), "0.2.3");
}

#[test]
fn adds_git_source() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.git-package").is_none());

    execute_command(&["add", "git-package", "--git", "http://localhost/git-package.git"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.git-package").unwrap();
    assert_eq!(val.as_table().unwrap().get("git").unwrap().as_str().unwrap(),
               "http://localhost/git-package.git");

    // check this works with other flags (e.g. --dev) as well
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.git-dev-pkg").is_none());

    execute_command(&["add", "git-dev-pkg", "--git", "http://site/gp.git", "--dev"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.git-dev-pkg").unwrap();
    assert_eq!(val.as_table().unwrap().get("git").unwrap().as_str().unwrap(),
               "http://site/gp.git");
}

#[test]
fn adds_local_source() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.local").is_none());

    execute_command(&["add", "local", "--path", "/path/to/pkg"], &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.local").unwrap();
    assert_eq!(val.as_table().unwrap().get("path").unwrap().as_str().unwrap(),
               "/path/to/pkg");

    // check this works with other flags (e.g. --dev) as well
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dev-dependencies.local-dev").is_none());

    execute_command(&["add", "local-dev", "--path", "/path/to/pkg-dev", "--dev"],
                    &manifest);

    let toml = get_toml(&manifest);
    let val = toml.lookup("dev-dependencies.local-dev").unwrap();
    assert_eq!(val.as_table().unwrap().get("path").unwrap().as_str().unwrap(),
               "/path/to/pkg-dev");
}

#[test]
fn package_kinds_are_mutually_exclusive() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    let call = process::Command::new("target/debug/cargo-add")
                   .args(&["add", "failure"])
                   .args(&["--vers", "0.4.3"])
                   .args(&["--git", "git://git.git"])
                   .args(&["--path", "/path/here"])
                   .arg(format!("--manifest-path={}", &manifest))
                   .output()
                   .unwrap();

    assert!(!call.status.success());
    assert!(no_manifest_failures(&get_toml(&manifest)));
}

#[test]
fn adds_optional_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1", "--optional"],
                    &manifest);

    // dependency present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.versioned-package.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
}

#[test]
fn adds_multiple_optional_dependencies() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependencies not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.my-package1").is_none());
    assert!(toml.lookup("dependencies.my-package2").is_none());

    execute_command(&["add", "--optional", "my-package1", "my-package2"],
                    &manifest);

    // dependencies present afterwards
    let toml = get_toml(&manifest);
    let val = toml.lookup("dependencies.my-package1.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
    let val = toml.lookup("dependencies.my-package2.optional").expect("not added optionally");
    assert_eq!(val.as_bool().expect("optional not a bool"), true);
}

#[test]
#[should_panic]
fn fails_to_add_optional_dev_dependency() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    // Fails because optional dependencies must be in `dependencies` table.
    execute_command(&["add", "versioned-package", "--vers", ">=0.1.1", "--dev", "--optional"],
                    &manifest);
}

#[test]
#[should_panic]
fn fails_to_add_multiple_optional_dev_dependency() {
    let (_tmpdir, manifest) = clone_out_test("tests/fixtures/add/Cargo.toml.sample");

    // dependency not present beforehand
    let toml = get_toml(&manifest);
    assert!(toml.lookup("dependencies.versioned-package").is_none());

    // Fails because optional dependencies must be in `dependencies` table.
    execute_command(&["add", "--optional", "my-package1", "my-package2", "--dev"],
                    &manifest);
}

#[test]
fn no_argument() {
    assert_cli!("target/debug/cargo-add", &["add"] => Error 1,
                r"Invalid arguments.

Usage:
    cargo add <crate> [--dev|--build|--optional] [--vers=<ver>|--git=<uri>|--path=<uri>] [options]
    cargo add <crates>... [--dev|--build|--optional] [options]
    cargo add (-h|--help)
    cargo add --version")
        .unwrap();
}

#[test]
fn unknown_flags() {
    assert_cli!("target/debug/cargo-add", &["add", "foo", "--flag"] => Error 1,
                r"Unknown flag: '--flag'

Usage:
    cargo add <crate> [--dev|--build|--optional] [--vers=<ver>|--git=<uri>|--path=<uri>] [options]
    cargo add <crates>... [--dev|--build|--optional] [options]
    cargo add (-h|--help)
    cargo add --version")
        .unwrap();
}
<|endoftext|>


<commit_before>mod drop;

use self::drop::DetectDrop;
use anyhow::Error;
use std::marker::Unpin;
use std::mem;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::Arc;

#[test]
fn test_error_size() {
    assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
}

#[test]
fn test_autotraits() {
    fn assert<E: Unpin + Send + Sync + 'static>() {}
    assert::<Error>();
}

#[test]
fn test_drop() {
    let has_dropped = Arc::new(AtomicBool::new(false));
    drop(Error::new(DetectDrop::new(&has_dropped)));
    assert!(has_dropped.load(SeqCst));
}
<commit_msg>Test null pointer optimization of Result<(), Error><commit_after>mod drop;

use self::drop::DetectDrop;
use anyhow::Error;
use std::marker::Unpin;
use std::mem;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::Arc;

#[test]
fn test_error_size() {
    assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
}

#[test]
fn test_null_pointer_optimization() {
    assert_eq!(mem::size_of::<Result<(), Error>>(), mem::size_of::<usize>());
}

#[test]
fn test_autotraits() {
    fn assert<E: Unpin + Send + Sync + 'static>() {}
    assert::<Error>();
}

#[test]
fn test_drop() {
    let has_dropped = Arc::new(AtomicBool::new(false));
    drop(Error::new(DetectDrop::new(&has_dropped)));
    assert!(has_dropped.load(SeqCst));
}
<|endoftext|>


<commit_before>use std::ops::{Mul, Add, Div, Sub, Index};
use libnum::{One, Zero, Float};
use std::cmp::PartialEq;
use math::linalg::Metric;
use math::linalg::vector::Vector;
use math::utils::dot;

pub struct Matrix<T> {
	pub cols: usize,
	pub rows: usize,
	pub data: Vec<T>
}

impl<T: Zero + One + Copy> Matrix<T> {
    pub fn new(rows: usize, cols: usize, data: Vec<T>) -> Matrix<T> {

        assert_eq!(cols*rows, data.len());
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    pub fn zeros(rows: usize, cols: usize) -> Matrix<T> {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![T::zero(); cols*rows]
        }
    }

    pub fn ones(rows: usize, cols: usize) -> Matrix<T> {
        Matrix {
            cols: cols,
            rows: rows,
            data: vec![T::one(); cols*rows]
        }
    }

    pub fn identity(size: usize) -> Matrix<T> {
    	let mut data = vec![T::zero(); size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = T::one();
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    pub fn from_diag(diag: &[T]) -> Matrix<T> {
    	let size = diag.len();
    	let mut data = vec![T::zero(); size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    pub fn transpose(&self) -> Matrix<T> {
        let mut new_data = vec![T::zero(); self.cols * self.rows];
        for i in 0..self.cols
        {
            for j in 0..self.rows
            {
                new_data[i*self.rows+j] = self.data[j*self.cols + i];
            }
        }

        Matrix {
            cols: self.rows,
            rows: self.cols,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T> + Mul<T, Output=T>> Matrix<T> {
    pub fn plu_decomp(&self) -> (Matrix<T>, Matrix<T>) {
        let a = Matrix { cols: self.cols, rows: self.rows, data: vec![T::zero();self.rows*self.cols] };
        let b = Matrix { cols: self.cols, rows: self.rows, data: vec![T::zero();self.rows*self.cols] };

        unimplemented!();
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T>> Mul<T> for Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, f: T) -> Matrix<T> {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + Zero + One + Mul<T, Output=T> + Add<T, Output=T>> Mul<Matrix<T>> for Matrix<T> {
	type Output = Matrix<T>;

	fn mul(self, m: Matrix<T>) -> Matrix<T> {
		// Will use Strassen algorithm if large, traditional otherwise
		assert!(self.cols == m.rows);

        let mut new_data = vec![T::zero(); self.rows * m.cols];

        let mt = &m.transpose();

        for i in 0..self.rows
        {
            for j in 0..m.cols
            {
                new_data[i * m.cols + j] = dot( &self.data[(i * self.cols)..((i+1)*self.cols)], &mt.data[(j*m.rows)..((j+1)*m.rows)] );
            }
        }

        Matrix {
            rows: self.rows,
            cols: m.cols,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Mul<T, Output=T> + Add<T, Output=T>> Mul<Vector<T>> for Matrix<T> {
    type Output = Vector<T>;

    fn mul(self, v: Vector<T>) -> Vector<T> {
        assert!(v.size == self.cols);

        let mut new_data = vec![T::zero(); self.rows];

        for i in 0..self.rows
        {
            new_data[i] = dot(&self.data[i*self.cols..(i+1)*self.cols], &v.data);
        }

        return Vector {
            size: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<T> for Matrix<T> {
	type Output = Matrix<T>;

	fn add(self, f: T) -> Matrix<T> {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<Matrix<T>> for Matrix<T> {
	type Output = Matrix<T>;

	fn add(self, m: Matrix<T>) -> Matrix<T> {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<T> for Matrix<T> {
    type Output = Matrix<T>;

    fn sub(self, f: T) -> Matrix<T> {
        let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<Matrix<T>> for Matrix<T> {
	type Output = Matrix<T>;

	fn sub(self, m: Matrix<T>) -> Matrix<T> {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<T> for Matrix<T> {
	type Output = Matrix<T>;

	fn div(self, f: T) -> Matrix<T> {
		assert!(f != T::zero());

		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T> Index<[usize; 2]> for Matrix<T> {
	type Output = T;

	fn index(&self, idx : [usize; 2]) -> &T {
		assert!(idx[0] < self.rows);
		assert!(idx[1] < self.cols);

		&self.data[idx[0] * self.cols + idx[1]]
	}
}

impl<T: Float> Metric<T> for Matrix<T> {
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + (*u) * (*u);
        }

        s.sqrt()
    }
}<commit_msg>Beginning implementation of LUP. Also generalized multiplication of mat * mat.<commit_after>use std::ops::{Mul, Add, Div, Sub, Index};
use libnum::{One, Zero, Float};
use std::cmp::PartialEq;
use math::linalg::Metric;
use math::linalg::vector::Vector;
use math::utils::{dot, argmax};

pub struct Matrix<T> {
	pub cols: usize,
	pub rows: usize,
	pub data: Vec<T>
}

impl<T: Zero + One + Copy> Matrix<T> {
    pub fn new(rows: usize, cols: usize, data: Vec<T>) -> Matrix<T> {

        assert_eq!(cols*rows, data.len());
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    pub fn zeros(rows: usize, cols: usize) -> Matrix<T> {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![T::zero(); cols*rows]
        }
    }

    pub fn ones(rows: usize, cols: usize) -> Matrix<T> {
        Matrix {
            cols: cols,
            rows: rows,
            data: vec![T::one(); cols*rows]
        }
    }

    pub fn identity(size: usize) -> Matrix<T> {
    	let mut data = vec![T::zero(); size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = T::one();
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    pub fn from_diag(diag: &[T]) -> Matrix<T> {
    	let size = diag.len();
    	let mut data = vec![T::zero(); size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    pub fn transpose(&self) -> Matrix<T> {
        let mut new_data = vec![T::zero(); self.cols * self.rows];
        for i in 0..self.cols
        {
            for j in 0..self.rows
            {
                new_data[i*self.rows+j] = self.data[j*self.cols + i];
            }
        }

        Matrix {
            cols: self.rows,
            rows: self.cols,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T> + Mul<T, Output=T> + PartialOrd> Matrix<T> {
    pub fn plu_decomp(&self) -> (Matrix<T>, Matrix<T>) {
        assert!(self.rows == self.cols);

        let mut l = Matrix { cols: self.cols, rows: self.rows, data: vec![T::zero();self.rows*self.cols] };
        let mut u = Matrix { cols: self.cols, rows: self.rows, data: vec![T::zero();self.rows*self.cols] };

        let mt = self.transpose();

        let mut p = Matrix::<T>::identity(self.cols);

        for i in 0..self.cols {
            let row = argmax(&mt.data[i*(self.cols+1)..(i+1)*self.cols]);

            if row != i {
                for j in 0..self.cols {
                    p.data.swap(i*self.cols + j, row*self.cols+j)
                }
            }
        }

        let a_2 = &p * self;

        unimplemented!();
    }
}

impl<T: Copy + One + Zero + Mul<T, Output=T>> Mul<T> for Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, f: T) -> Matrix<T> {
        let new_data = self.data.into_iter().map(|v| v * f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl <T: Copy + Zero + One + Mul<T, Output=T> + Add<T, Output=T>> Mul<Matrix<T>> for Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, m: Matrix<T>) -> Matrix<T> {
        (&self) * (&m)
    }
}

impl <'a, T: Copy + Zero + One + Mul<T, Output=T> + Add<T, Output=T>> Mul<Matrix<T>> for &'a Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, m: Matrix<T>) -> Matrix<T> {
        self * (&m)
    }
}

impl <'a, T: Copy + Zero + One + Mul<T, Output=T> + Add<T, Output=T>> Mul<&'a Matrix<T>> for Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, m: &Matrix<T>) -> Matrix<T> {
        (&self) * m
    }
}

impl<'a, 'b, T: Copy + Zero + One + Mul<T, Output=T> + Add<T, Output=T>> Mul<&'b Matrix<T>> for &'a Matrix<T> {
	type Output = Matrix<T>;

	fn mul(self, m: &Matrix<T>) -> Matrix<T> {
		// Will use Strassen algorithm if large, traditional otherwise
		assert!(self.cols == m.rows);

        let mut new_data = vec![T::zero(); self.rows * m.cols];

        let mt = m.transpose();

        for i in 0..self.rows
        {
            for j in 0..m.cols
            {
                new_data[i * m.cols + j] = dot( &self.data[(i * self.cols)..((i+1)*self.cols)], &mt.data[(j*m.rows)..((j+1)*m.rows)] );
            }
        }

        Matrix {
            rows: self.rows,
            cols: m.cols,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Mul<T, Output=T> + Add<T, Output=T>> Mul<Vector<T>> for Matrix<T> {
    type Output = Vector<T>;

    fn mul(self, v: Vector<T>) -> Vector<T> {
        assert!(v.size == self.cols);

        let mut new_data = vec![T::zero(); self.rows];

        for i in 0..self.rows
        {
            new_data[i] = dot(&self.data[i*self.cols..(i+1)*self.cols], &v.data);
        }

        return Vector {
            size: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<T> for Matrix<T> {
	type Output = Matrix<T>;

	fn add(self, f: T) -> Matrix<T> {
		let new_data = self.data.into_iter().map(|v| v + f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Add<T, Output=T>> Add<Matrix<T>> for Matrix<T> {
	type Output = Matrix<T>;

	fn add(self, m: Matrix<T>) -> Matrix<T> {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v + m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<T> for Matrix<T> {
    type Output = Matrix<T>;

    fn sub(self, f: T) -> Matrix<T> {
        let new_data = self.data.into_iter().map(|v| v - f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl<T: Copy + One + Zero + Sub<T, Output=T>> Sub<Matrix<T>> for Matrix<T> {
	type Output = Matrix<T>;

	fn sub(self, m: Matrix<T>) -> Matrix<T> {
		assert!(self.cols == m.cols);
		assert!(self.rows == m.rows);

		let new_data = self.data.into_iter().enumerate().map(|(i,v)| v - m.data[i]).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T: Copy + One + Zero + PartialEq + Div<T, Output=T>> Div<T> for Matrix<T> {
	type Output = Matrix<T>;

	fn div(self, f: T) -> Matrix<T> {
		assert!(f != T::zero());

		let new_data = self.data.into_iter().map(|v| v / f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
	}
}

impl<T> Index<[usize; 2]> for Matrix<T> {
	type Output = T;

	fn index(&self, idx : [usize; 2]) -> &T {
		assert!(idx[0] < self.rows);
		assert!(idx[1] < self.cols);

		&self.data[idx[0] * self.cols + idx[1]]
	}
}

impl<T: Float> Metric<T> for Matrix<T> {
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + (*u) * (*u);
        }

        s.sqrt()
    }
}<|endoftext|>


<commit_before>use graph::{Edge, Graph};
use adjacency_matrix::AdjacencyMatrix;

use std::usize;

// maximum_flow returns the maximum flow from source to sink in g.
pub fn maximum_flow(g: &Graph, source: usize, sink: usize) -> u32 {
    // Initially, the residual flow graph of g is just the same as g.
    let mut residual_flow_graph = AdjacencyMatrix::from_graph(g);

    let mut flow = 0;
    loop {
        let path_capacity = residual_flow_graph.add_augmenting_path(source, sink);
        if path_capacity > 0 {
            flow += path_capacity;
        } else {
            return flow;
        }
    }
}

impl AdjacencyMatrix {
    // addAugmentingPath looks for an augmenting path from source to sink in the residual flow
    // graph.
    // If an augmenting path is found, addAugmentingPath updates the residual flow graph to reflect
    // the addition of the augmenting path, and returns the capacity of the augmenting path.
    // If no augmenting path is found, addAugmentingPath returns 0.
    fn add_augmenting_path(&mut self, source: usize, sink: usize) -> u32 {
        let mut parents = vec![usize::MAX; self.size()];

        for Edge { x, y } in self.breadth_first_search(source) {
            parents[y] = x;
            if y == sink {
                // Abort the BFS.
                break;
            }
        }

        self.substract_path(&parents, sink)
    }

    // substractPath substracts the path described by parents and end from the residual flow graph,
    // and returns the capacity of the path.
    fn substract_path(&mut self, parents: &Vec<usize>, end: usize) -> u32 {
        let capacity = self.path_capacity(parents, end);

        for (x, y) in edges(parents, end) {
            self[x][y] -= capacity;
            self[y][x] += capacity;
        }

        capacity
    }

    // pathCapacity returns the capacity of the path described by parents and end in the residual
    // flow graph.
    fn path_capacity(&self, parents: &Vec<usize>, end: usize) -> u32 {
        let mut capacity = 0;

        for (x, y) in edges(parents, end) {
            let c = self[x][y];
            if capacity == 0 || capacity > c {
                capacity = c
            }
        }

        capacity
    }
}

// edges returns the edges of the path described by parents and end.
fn edges(parents: &Vec<usize>, mut end: usize) -> Vec<(usize, usize)> {
    let mut edges = vec![];

    loop {
        let p = parents[end];
        if p == usize::MAX {
            edges.reverse();
            return edges
        }
        edges.push((p, end));
        end = p
    }
}
<commit_msg>[edge_connectivity/rust] Use Edge struct instead of (x, y) tuple<commit_after>use graph::{Edge, Graph};
use adjacency_matrix::AdjacencyMatrix;

use std::usize;

// maximum_flow returns the maximum flow from source to sink in g.
pub fn maximum_flow(g: &Graph, source: usize, sink: usize) -> u32 {
    // Initially, the residual flow graph of g is just the same as g.
    let mut residual_flow_graph = AdjacencyMatrix::from_graph(g);

    let mut flow = 0;
    loop {
        let path_capacity = residual_flow_graph.add_augmenting_path(source, sink);
        if path_capacity > 0 {
            flow += path_capacity;
        } else {
            return flow;
        }
    }
}

impl AdjacencyMatrix {
    // addAugmentingPath looks for an augmenting path from source to sink in the residual flow
    // graph.
    // If an augmenting path is found, addAugmentingPath updates the residual flow graph to reflect
    // the addition of the augmenting path, and returns the capacity of the augmenting path.
    // If no augmenting path is found, addAugmentingPath returns 0.
    fn add_augmenting_path(&mut self, source: usize, sink: usize) -> u32 {
        let mut parents = vec![usize::MAX; self.size()];

        for Edge { x, y } in self.breadth_first_search(source) {
            parents[y] = x;
            if y == sink {
                // Abort the BFS.
                break;
            }
        }

        self.substract_path(&parents, sink)
    }

    // substractPath substracts the path described by parents and end from the residual flow graph,
    // and returns the capacity of the path.
    fn substract_path(&mut self, parents: &Vec<usize>, end: usize) -> u32 {
        let capacity = self.path_capacity(parents, end);

        for Edge {x, y} in edges(parents, end) {
            self[x][y] -= capacity;
            self[y][x] += capacity;
        }

        capacity
    }

    // pathCapacity returns the capacity of the path described by parents and end in the residual
    // flow graph.
    fn path_capacity(&self, parents: &Vec<usize>, end: usize) -> u32 {
        let mut capacity = 0;

        for Edge {x, y} in edges(parents, end) {
            let edge_capacity = self[x][y];
            if capacity == 0 || capacity > edge_capacity {
                capacity = edge_capacity
            }
        }

        capacity
    }
}

// edges returns the edges of the path described by parents and end.
fn edges(parents: &Vec<usize>, mut end: usize) -> Vec<Edge> {
    let mut edges = vec![];

    while parents[end] < usize::MAX {
        let edge = Edge { x: parents[end], y: end };
        edges.push(edge);
        end = parents[end];
    }

    edges.reverse();
    edges
}
<|endoftext|>


<commit_before>#![recursion_limit = "256"]
extern crate proc_macro;

use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, DeriveInput};

/// Returns a Vec of `syn::Ident` for each named field in the struct, whilst filtering out fields
/// that should not be hashed.
///
/// # Panics
/// Any unnamed struct field (like in a tuple struct) will raise a panic at compile time.
fn get_hashable_named_field_idents<'a>(struct_data: &'a syn::DataStruct) -> Vec<&'a syn::Ident> {
    struct_data
        .fields
        .iter()
        .filter_map(|f| {
            if should_skip_hashing(&f) {
                None
            } else {
                Some(match &f.ident {
                    Some(ref ident) => ident,
                    _ => panic!("tree_hash_derive only supports named struct fields."),
                })
            }
        })
        .collect()
}

/// Returns true if some field has an attribute declaring it should not be hashed.
///
/// The field attribute is: `#[tree_hash(skip_hashing)]`
fn should_skip_hashing(field: &syn::Field) -> bool {
    field.attrs.iter().any(|attr| {
        attr.path.is_ident("tree_hash") && attr.tts.to_string().replace(" ", "") == "(skip_hashing)"
    })
}

/// Implements `tree_hash::TreeHash` for some `struct`.
///
/// Fields are hashed in the order they are defined.
#[proc_macro_derive(TreeHash, attributes(tree_hash))]
pub fn tree_hash_derive(input: TokenStream) -> TokenStream {
    let item = parse_macro_input!(input as DeriveInput);

    let name = &item.ident;
    let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl();

    let struct_data = match &item.data {
        syn::Data::Struct(s) => s,
        _ => panic!("tree_hash_derive only supports structs."),
    };

    let idents = get_hashable_named_field_idents(&struct_data);

    let output = quote! {
        impl #impl_generics tree_hash::TreeHash for #name #ty_generics #where_clause {
            fn tree_hash_type() -> tree_hash::TreeHashType {
                tree_hash::TreeHashType::Container
            }

            fn tree_hash_packed_encoding(&self) -> Vec<u8> {
                unreachable!("Struct should never be packed.")
            }

            fn tree_hash_packing_factor() -> usize {
                unreachable!("Struct should never be packed.")
            }

            fn tree_hash_root(&self) -> Vec<u8> {
                let mut leaves = Vec::with_capacity(4 * tree_hash::HASHSIZE);

                #(
                    leaves.append(&mut self.#idents.tree_hash_root());
                )*

                tree_hash::merkle_root(&leaves, 0)
            }
        }
    };
    output.into()
}

#[proc_macro_derive(SignedRoot, attributes(signed_root))]
pub fn tree_hash_signed_root_derive(input: TokenStream) -> TokenStream {
    let item = parse_macro_input!(input as DeriveInput);

    let name = &item.ident;
    let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl();

    let struct_data = match &item.data {
        syn::Data::Struct(s) => s,
        _ => panic!("tree_hash_derive only supports structs."),
    };

    let idents = get_signed_root_named_field_idents(&struct_data);
    let num_elems = idents.len();

    let output = quote! {
        impl #impl_generics tree_hash::SignedRoot for #name #ty_generics #where_clause {
            fn signed_root(&self) -> Vec<u8> {
                let mut leaves = Vec::with_capacity(#num_elems * tree_hash::HASHSIZE);

                #(
                    leaves.append(&mut self.#idents.tree_hash_root());
                )*

                tree_hash::merkle_root(&leaves, 0)
            }
        }
    };
    output.into()
}

fn get_signed_root_named_field_idents(struct_data: &syn::DataStruct) -> Vec<&syn::Ident> {
    struct_data
        .fields
        .iter()
        .filter_map(|f| {
            if should_skip_signed_root(&f) {
                None
            } else {
                Some(match &f.ident {
                    Some(ref ident) => ident,
                    _ => panic!("tree_hash_derive only supports named struct fields"),
                })
            }
        })
        .collect()
}

fn should_skip_signed_root(field: &syn::Field) -> bool {
    field
        .attrs
        .iter()
        .any(|attr| attr.into_token_stream().to_string() == "# [ signed_root ( skip_hashing ) ]")
}
<commit_msg>Fix SignedRoot macro attribute parsing<commit_after>#![recursion_limit = "256"]
extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

/// Returns a Vec of `syn::Ident` for each named field in the struct, whilst filtering out fields
/// that should not be hashed.
///
/// # Panics
/// Any unnamed struct field (like in a tuple struct) will raise a panic at compile time.
fn get_hashable_named_field_idents<'a>(struct_data: &'a syn::DataStruct) -> Vec<&'a syn::Ident> {
    struct_data
        .fields
        .iter()
        .filter_map(|f| {
            if should_skip_hashing(&f) {
                None
            } else {
                Some(match &f.ident {
                    Some(ref ident) => ident,
                    _ => panic!("tree_hash_derive only supports named struct fields."),
                })
            }
        })
        .collect()
}

/// Returns true if some field has an attribute declaring it should not be hashed.
///
/// The field attribute is: `#[tree_hash(skip_hashing)]`
fn should_skip_hashing(field: &syn::Field) -> bool {
    field.attrs.iter().any(|attr| {
        attr.path.is_ident("tree_hash") && attr.tts.to_string().replace(" ", "") == "(skip_hashing)"
    })
}

/// Implements `tree_hash::TreeHash` for some `struct`.
///
/// Fields are hashed in the order they are defined.
#[proc_macro_derive(TreeHash, attributes(tree_hash))]
pub fn tree_hash_derive(input: TokenStream) -> TokenStream {
    let item = parse_macro_input!(input as DeriveInput);

    let name = &item.ident;
    let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl();

    let struct_data = match &item.data {
        syn::Data::Struct(s) => s,
        _ => panic!("tree_hash_derive only supports structs."),
    };

    let idents = get_hashable_named_field_idents(&struct_data);

    let output = quote! {
        impl #impl_generics tree_hash::TreeHash for #name #ty_generics #where_clause {
            fn tree_hash_type() -> tree_hash::TreeHashType {
                tree_hash::TreeHashType::Container
            }

            fn tree_hash_packed_encoding(&self) -> Vec<u8> {
                unreachable!("Struct should never be packed.")
            }

            fn tree_hash_packing_factor() -> usize {
                unreachable!("Struct should never be packed.")
            }

            fn tree_hash_root(&self) -> Vec<u8> {
                let mut leaves = Vec::with_capacity(4 * tree_hash::HASHSIZE);

                #(
                    leaves.append(&mut self.#idents.tree_hash_root());
                )*

                tree_hash::merkle_root(&leaves, 0)
            }
        }
    };
    output.into()
}

#[proc_macro_derive(SignedRoot, attributes(signed_root))]
pub fn tree_hash_signed_root_derive(input: TokenStream) -> TokenStream {
    let item = parse_macro_input!(input as DeriveInput);

    let name = &item.ident;
    let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl();

    let struct_data = match &item.data {
        syn::Data::Struct(s) => s,
        _ => panic!("tree_hash_derive only supports structs."),
    };

    let idents = get_signed_root_named_field_idents(&struct_data);
    let num_elems = idents.len();

    let output = quote! {
        impl #impl_generics tree_hash::SignedRoot for #name #ty_generics #where_clause {
            fn signed_root(&self) -> Vec<u8> {
                let mut leaves = Vec::with_capacity(#num_elems * tree_hash::HASHSIZE);

                #(
                    leaves.append(&mut self.#idents.tree_hash_root());
                )*

                tree_hash::merkle_root(&leaves, 0)
            }
        }
    };
    output.into()
}

fn get_signed_root_named_field_idents(struct_data: &syn::DataStruct) -> Vec<&syn::Ident> {
    struct_data
        .fields
        .iter()
        .filter_map(|f| {
            if should_skip_signed_root(&f) {
                None
            } else {
                Some(match &f.ident {
                    Some(ref ident) => ident,
                    _ => panic!("tree_hash_derive only supports named struct fields"),
                })
            }
        })
        .collect()
}

fn should_skip_signed_root(field: &syn::Field) -> bool {
    field.attrs.iter().any(|attr| {
        attr.path.is_ident("signed_root")
            && attr.tts.to_string().replace(" ", "") == "(skip_hashing)"
    })
}
<|endoftext|>


<commit_before>extern crate bitflags;
extern crate log;

pub mod aspace;
pub mod basicblock;
pub mod config;
pub mod insn;
pub mod module;
pub mod pagemap;
pub mod pe;
pub mod util;

// helpers that are useful during doctests, tests.
//#[cfg(feature="test")]
pub mod rsrc;
pub mod test;

type VA = u64;
type RVA = u64;
<commit_msg>pe: add tests<commit_after>extern crate bitflags;
extern crate log;

pub mod aspace;
pub mod basicblock;
pub mod config;
pub mod insn;
pub mod module;
pub mod pagemap;
pub mod pe;
pub mod util;

// helpers that are useful during doctests, tests.
// TODO: restrict this to tests only
pub mod rsrc;
pub mod test;

type VA = u64;
type RVA = u64;
<|endoftext|>


<commit_before>//! Everything in thes file is implemented in terms of required functionality.
//! You are free to use anything, if it suits you.
//! They are useful for the test framework, but the implementation is trivial.
//! We supply them to reduce work both for you and the mentors.
use crate::{Cursor, LinkedList};

impl<T> LinkedList<T> {
    pub fn push_back(&mut self, element: T) {
        self.cursor_back().insert_after(element);
    }

    pub fn push_front(&mut self, element: T) {
        self.cursor_front().insert_before(element);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        self.cursor_back().take()
    }

    pub fn pop_front(&mut self) -> Option<T> {
        self.cursor_front().take()
    }

    pub fn front(&self) -> Option<&T> {
        self.iter().next()
    }

    pub fn back(&self) -> Option<&T> {
        self.iter().last()
    }
}

impl<T> std::iter::FromIterator<T> for LinkedList<T> {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = T>,
    {
        let mut list = Self::new();
        for elem in iter {
            list.push_back(elem);
        }
        list
    }
}

impl<T: Clone> Clone for LinkedList<T> {
    fn clone(&self) -> Self {
        self.iter().cloned().collect()
    }
}

// seek methods, return false if end of list is reached prematurely
impl<T> Cursor<'_, T> {
    pub fn seek_forward(&mut self, n: usize) -> bool {
        (0..n).all(|_| self.next().is_some())
    }

    pub fn seek_backward(&mut self, n: usize) -> bool {
        (0..n).all(|_| self.prev().is_some())
    }
}

// These are tests for code that must not compile. They need to be here (or in lib.rs)
// because only doctests can use `compile_fail` without additional dependencies
// and doctests are ignored inside tests/doubly-linked-list.rs.

#[allow(unused)]
#[cfg(feature = "advanced")]
/// ```compile_fail
/// use doubly_linked_list::LinkedList;
/// trait AssertSend: Send {}
/// impl<T> AssertSend for LinkedList<T> {}
/// ```
pub struct IllegalSend;

#[allow(unused)]
#[cfg(feature = "advanced")]
/// ```compile_fail
/// use doubly_linked_list::LinkedList;
/// trait AssertSync: Sync {}
/// impl<T> AssertSync for LinkedList<T> {}
/// ```
pub struct IllegalSync;
<commit_msg>remove Clone impl<commit_after>//! Everything in thes file is implemented in terms of required functionality.
//! You are free to use anything, if it suits you.
//! They are useful for the test framework, but the implementation is trivial.
//! We supply them to reduce work both for you and the mentors.
use crate::{Cursor, LinkedList};

impl<T> LinkedList<T> {
    pub fn push_back(&mut self, element: T) {
        self.cursor_back().insert_after(element);
    }

    pub fn push_front(&mut self, element: T) {
        self.cursor_front().insert_before(element);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        self.cursor_back().take()
    }

    pub fn pop_front(&mut self) -> Option<T> {
        self.cursor_front().take()
    }

    pub fn front(&self) -> Option<&T> {
        self.iter().next()
    }

    pub fn back(&self) -> Option<&T> {
        self.iter().last()
    }
}

impl<T> std::iter::FromIterator<T> for LinkedList<T> {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = T>,
    {
        let mut list = Self::new();
        for elem in iter {
            list.push_back(elem);
        }
        list
    }
}

// seek methods, return false if end of list is reached prematurely
impl<T> Cursor<'_, T> {
    pub fn seek_forward(&mut self, n: usize) -> bool {
        (0..n).all(|_| self.next().is_some())
    }

    pub fn seek_backward(&mut self, n: usize) -> bool {
        (0..n).all(|_| self.prev().is_some())
    }
}

// These are tests for code that must not compile. They need to be here (or in lib.rs)
// because only doctests can use `compile_fail` without additional dependencies
// and doctests are ignored inside tests/doubly-linked-list.rs.

#[allow(unused)]
#[cfg(feature = "advanced")]
/// ```compile_fail
/// use doubly_linked_list::LinkedList;
/// trait AssertSend: Send {}
/// impl<T> AssertSend for LinkedList<T> {}
/// ```
pub struct IllegalSend;

#[allow(unused)]
#[cfg(feature = "advanced")]
/// ```compile_fail
/// use doubly_linked_list::LinkedList;
/// trait AssertSync: Sync {}
/// impl<T> AssertSync for LinkedList<T> {}
/// ```
pub struct IllegalSync;
<|endoftext|>


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

use crate::{
    fat_type::{FatStructType, FatType},
    resolver::Resolver,
};
use anyhow::{anyhow, bail, Result};
use diem_state_view::StateView;
use diem_types::{
    access_path::AccessPath, account_address::AccountAddress, account_state::AccountState,
    contract_event::ContractEvent,
};
use move_core_types::{
    identifier::Identifier,
    language_storage::{ModuleId, StructTag},
    value::{MoveStruct, MoveValue},
};
use move_vm_runtime::data_cache::RemoteCache;
use std::{
    collections::btree_map::BTreeMap,
    convert::TryInto,
    fmt::{Display, Formatter},
};
use vm::errors::{Location, PartialVMError, PartialVMResult, VMResult};

mod fat_type;
mod module_cache;
mod resolver;

#[derive(Debug)]
pub struct AnnotatedAccountStateBlob(BTreeMap<StructTag, AnnotatedMoveStruct>);

#[derive(Debug)]
pub struct AnnotatedMoveStruct {
    is_resource: bool,
    type_: StructTag,
    value: Vec<(Identifier, AnnotatedMoveValue)>,
}

/// AnnotatedMoveValue is a fully expanded version of on chain Move data. This should only be used
/// for debugging/client purpose right now and just for a better visualization of on chain data. In
/// the long run, we would like to transform this struct to a Json value so that we can have a cross
/// platform interpretation of the on chain data.
#[derive(Debug)]
pub enum AnnotatedMoveValue {
    U8(u8),
    U64(u64),
    U128(u128),
    Bool(bool),
    Address(AccountAddress),
    Vector(Vec<AnnotatedMoveValue>),
    Bytes(Vec<u8>),
    Struct(AnnotatedMoveStruct),
}

pub struct MoveValueAnnotator<'a> {
    cache: Resolver<'a>,
    _data_view: &'a dyn RemoteCache,
}

impl<'a> MoveValueAnnotator<'a> {
    pub fn new(view: &'a dyn RemoteCache) -> Self {
        Self {
            cache: Resolver::new(view, true),
            _data_view: view,
        }
    }

    pub fn new_no_stdlib(view: &'a dyn RemoteCache) -> Self {
        Self {
            cache: Resolver::new(view, false),
            _data_view: view,
        }
    }

    pub fn view_access_path(
        &self,
        access_path: AccessPath,
        blob: &[u8],
    ) -> Result<AnnotatedMoveStruct> {
        match access_path.get_struct_tag() {
            Some(tag) => self.view_resource(&tag, blob),
            None => bail!("Bad resource access path"),
        }
    }

    pub fn view_resource(&self, tag: &StructTag, blob: &[u8]) -> Result<AnnotatedMoveStruct> {
        let ty = self.cache.resolve_struct(tag)?;
        let struct_def = (&ty)
            .try_into()
            .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;
        let move_struct = MoveStruct::simple_deserialize(blob, &struct_def)?;
        self.annotate_struct(&move_struct, &ty)
    }

    pub fn view_contract_event(&self, event: &ContractEvent) -> Result<AnnotatedMoveValue> {
        let ty = self.cache.resolve_type(event.type_tag())?;
        let move_ty = (&ty)
            .try_into()
            .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;

        let move_value = MoveValue::simple_deserialize(event.event_data(), &move_ty)?;
        self.annotate_value(&move_value, &ty)
    }

    pub fn view_account_state(&self, state: &AccountState) -> Result<AnnotatedAccountStateBlob> {
        let mut output = BTreeMap::new();
        for (k, v) in state.iter() {
            let tag = match AccessPath::new(AccountAddress::random(), k.to_vec()).get_struct_tag() {
                Some(t) => t,
                None => {
                    println!("Uncached AccessPath: {:?}", k);
                    continue;
                }
            };
            let ty = self.cache.resolve_struct(&tag)?;
            let struct_def = (&ty)
                .try_into()
                .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;

            let move_struct = MoveStruct::simple_deserialize(v.as_slice(), &struct_def)?;
            output.insert(
                ty.struct_tag()
                    .map_err(|e| e.finish(Location::Undefined).into_vm_status())
                    .unwrap(),
                self.annotate_struct(&move_struct, &ty)?,
            );
        }
        Ok(AnnotatedAccountStateBlob(output))
    }

    fn annotate_struct(
        &self,
        move_struct: &MoveStruct,
        ty: &FatStructType,
    ) -> Result<AnnotatedMoveStruct> {
        let struct_tag = ty
            .struct_tag()
            .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
        let field_names = self.cache.get_field_names(ty)?;
        let mut annotated_fields = vec![];
        for (ty, v) in ty.layout.iter().zip(move_struct.fields().iter()) {
            annotated_fields.push(self.annotate_value(v, ty)?);
        }
        Ok(AnnotatedMoveStruct {
            is_resource: ty.is_resource,
            type_: struct_tag,
            value: field_names
                .into_iter()
                .zip(annotated_fields.into_iter())
                .collect(),
        })
    }

    fn annotate_value(&self, value: &MoveValue, ty: &FatType) -> Result<AnnotatedMoveValue> {
        Ok(match (value, ty) {
            (MoveValue::Bool(b), FatType::Bool) => AnnotatedMoveValue::Bool(*b),
            (MoveValue::U8(i), FatType::U8) => AnnotatedMoveValue::U8(*i),
            (MoveValue::U64(i), FatType::U64) => AnnotatedMoveValue::U64(*i),
            (MoveValue::U128(i), FatType::U128) => AnnotatedMoveValue::U128(*i),
            (MoveValue::Address(a), FatType::Address) => AnnotatedMoveValue::Address(*a),
            (MoveValue::Vector(a), FatType::Vector(ty)) => match ty.as_ref() {
                FatType::U8 => AnnotatedMoveValue::Bytes(
                    a.iter()
                        .map(|v| match v {
                            MoveValue::U8(i) => Ok(*i),
                            _ => Err(anyhow!("unexpected value type")),
                        })
                        .collect::<Result<_>>()?,
                ),
                _ => AnnotatedMoveValue::Vector(
                    a.iter()
                        .map(|v| self.annotate_value(v, ty.as_ref()))
                        .collect::<Result<_>>()?,
                ),
            },
            (MoveValue::Struct(s), FatType::Struct(ty)) => {
                AnnotatedMoveValue::Struct(self.annotate_struct(s, ty.as_ref())?)
            }
            _ => {
                return Err(anyhow!(
                    "Cannot annotate value {:?} with type {:?}",
                    value,
                    ty
                ))
            }
        })
    }
}

fn write_indent(f: &mut Formatter, indent: u64) -> std::fmt::Result {
    for _i in 0..indent {
        write!(f, " ")?;
    }
    Ok(())
}

fn pretty_print_value(
    f: &mut Formatter,
    value: &AnnotatedMoveValue,
    indent: u64,
) -> std::fmt::Result {
    match value {
        AnnotatedMoveValue::Bool(b) => write!(f, "{}", b),
        AnnotatedMoveValue::U8(v) => write!(f, "{}u8", v),
        AnnotatedMoveValue::U64(v) => write!(f, "{}", v),
        AnnotatedMoveValue::U128(v) => write!(f, "{}u128", v),
        AnnotatedMoveValue::Address(a) => write!(f, "{}", a.short_str_lossless()),
        AnnotatedMoveValue::Vector(v) => {
            writeln!(f, "[")?;
            for value in v.iter() {
                write_indent(f, indent + 4)?;
                pretty_print_value(f, value, indent + 4)?;
                writeln!(f, ",")?;
            }
            write_indent(f, indent)?;
            write!(f, "]")
        }
        AnnotatedMoveValue::Bytes(v) => write!(f, "{}", hex::encode(&v)),
        AnnotatedMoveValue::Struct(s) => pretty_print_struct(f, s, indent),
    }
}

fn pretty_print_struct(
    f: &mut Formatter,
    value: &AnnotatedMoveStruct,
    indent: u64,
) -> std::fmt::Result {
    writeln!(
        f,
        "{}{} {{",
        if value.is_resource { "resource " } else { "" },
        value.type_
    )?;
    for (field_name, v) in value.value.iter() {
        write_indent(f, indent + 4)?;
        write!(f, "{}: ", field_name)?;
        pretty_print_value(f, v, indent + 4)?;
        writeln!(f)?;
    }
    write_indent(f, indent)?;
    write!(f, "}}")
}

impl Display for AnnotatedMoveValue {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        pretty_print_value(f, self, 0)
    }
}

impl Display for AnnotatedMoveStruct {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        pretty_print_struct(f, self, 0)
    }
}

impl Display for AnnotatedAccountStateBlob {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        writeln!(f, "{{")?;
        for v in self.0.values() {
            write!(f, "{}", v)?;
            writeln!(f, ",")?;
        }
        writeln!(f, "}}")
    }
}

#[derive(Default)]
pub struct NullStateView();

impl StateView for NullStateView {
    fn get(&self, _access_path: &AccessPath) -> Result<Option<Vec<u8>>> {
        Err(anyhow!("No data"))
    }

    fn multi_get(&self, _access_paths: &[AccessPath]) -> Result<Vec<Option<Vec<u8>>>> {
        Err(anyhow!("No data"))
    }

    fn is_genesis(&self) -> bool {
        false
    }
}

impl RemoteCache for NullStateView {
    fn get_module(&self, _module_id: &ModuleId) -> VMResult<Option<Vec<u8>>> {
        Ok(None)
    }

    fn get_resource(
        &self,
        _address: &AccountAddress,
        _tag: &StructTag,
    ) -> PartialVMResult<Option<Vec<u8>>> {
        Ok(None)
    }
}
<commit_msg>[resource-viewer] Change AnnotatedMoveStruct fields to public<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    fat_type::{FatStructType, FatType},
    resolver::Resolver,
};
use anyhow::{anyhow, bail, Result};
use diem_state_view::StateView;
use diem_types::{
    access_path::AccessPath, account_address::AccountAddress, account_state::AccountState,
    contract_event::ContractEvent,
};
use move_core_types::{
    identifier::Identifier,
    language_storage::{ModuleId, StructTag},
    value::{MoveStruct, MoveValue},
};
use move_vm_runtime::data_cache::RemoteCache;
use std::{
    collections::btree_map::BTreeMap,
    convert::TryInto,
    fmt::{Display, Formatter},
};
use vm::errors::{Location, PartialVMError, PartialVMResult, VMResult};

mod fat_type;
mod module_cache;
mod resolver;

#[derive(Debug)]
pub struct AnnotatedAccountStateBlob(BTreeMap<StructTag, AnnotatedMoveStruct>);

#[derive(Debug)]
pub struct AnnotatedMoveStruct {
    pub is_resource: bool,
    pub type_: StructTag,
    pub value: Vec<(Identifier, AnnotatedMoveValue)>,
}

/// AnnotatedMoveValue is a fully expanded version of on chain Move data. This should only be used
/// for debugging/client purpose right now and just for a better visualization of on chain data. In
/// the long run, we would like to transform this struct to a Json value so that we can have a cross
/// platform interpretation of the on chain data.
#[derive(Debug)]
pub enum AnnotatedMoveValue {
    U8(u8),
    U64(u64),
    U128(u128),
    Bool(bool),
    Address(AccountAddress),
    Vector(Vec<AnnotatedMoveValue>),
    Bytes(Vec<u8>),
    Struct(AnnotatedMoveStruct),
}

pub struct MoveValueAnnotator<'a> {
    cache: Resolver<'a>,
    _data_view: &'a dyn RemoteCache,
}

impl<'a> MoveValueAnnotator<'a> {
    pub fn new(view: &'a dyn RemoteCache) -> Self {
        Self {
            cache: Resolver::new(view, true),
            _data_view: view,
        }
    }

    pub fn new_no_stdlib(view: &'a dyn RemoteCache) -> Self {
        Self {
            cache: Resolver::new(view, false),
            _data_view: view,
        }
    }

    pub fn view_access_path(
        &self,
        access_path: AccessPath,
        blob: &[u8],
    ) -> Result<AnnotatedMoveStruct> {
        match access_path.get_struct_tag() {
            Some(tag) => self.view_resource(&tag, blob),
            None => bail!("Bad resource access path"),
        }
    }

    pub fn view_resource(&self, tag: &StructTag, blob: &[u8]) -> Result<AnnotatedMoveStruct> {
        let ty = self.cache.resolve_struct(tag)?;
        let struct_def = (&ty)
            .try_into()
            .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;
        let move_struct = MoveStruct::simple_deserialize(blob, &struct_def)?;
        self.annotate_struct(&move_struct, &ty)
    }

    pub fn view_contract_event(&self, event: &ContractEvent) -> Result<AnnotatedMoveValue> {
        let ty = self.cache.resolve_type(event.type_tag())?;
        let move_ty = (&ty)
            .try_into()
            .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;

        let move_value = MoveValue::simple_deserialize(event.event_data(), &move_ty)?;
        self.annotate_value(&move_value, &ty)
    }

    pub fn view_account_state(&self, state: &AccountState) -> Result<AnnotatedAccountStateBlob> {
        let mut output = BTreeMap::new();
        for (k, v) in state.iter() {
            let tag = match AccessPath::new(AccountAddress::random(), k.to_vec()).get_struct_tag() {
                Some(t) => t,
                None => {
                    println!("Uncached AccessPath: {:?}", k);
                    continue;
                }
            };
            let ty = self.cache.resolve_struct(&tag)?;
            let struct_def = (&ty)
                .try_into()
                .map_err(|e: PartialVMError| e.finish(Location::Undefined).into_vm_status())?;

            let move_struct = MoveStruct::simple_deserialize(v.as_slice(), &struct_def)?;
            output.insert(
                ty.struct_tag()
                    .map_err(|e| e.finish(Location::Undefined).into_vm_status())
                    .unwrap(),
                self.annotate_struct(&move_struct, &ty)?,
            );
        }
        Ok(AnnotatedAccountStateBlob(output))
    }

    fn annotate_struct(
        &self,
        move_struct: &MoveStruct,
        ty: &FatStructType,
    ) -> Result<AnnotatedMoveStruct> {
        let struct_tag = ty
            .struct_tag()
            .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
        let field_names = self.cache.get_field_names(ty)?;
        let mut annotated_fields = vec![];
        for (ty, v) in ty.layout.iter().zip(move_struct.fields().iter()) {
            annotated_fields.push(self.annotate_value(v, ty)?);
        }
        Ok(AnnotatedMoveStruct {
            is_resource: ty.is_resource,
            type_: struct_tag,
            value: field_names
                .into_iter()
                .zip(annotated_fields.into_iter())
                .collect(),
        })
    }

    fn annotate_value(&self, value: &MoveValue, ty: &FatType) -> Result<AnnotatedMoveValue> {
        Ok(match (value, ty) {
            (MoveValue::Bool(b), FatType::Bool) => AnnotatedMoveValue::Bool(*b),
            (MoveValue::U8(i), FatType::U8) => AnnotatedMoveValue::U8(*i),
            (MoveValue::U64(i), FatType::U64) => AnnotatedMoveValue::U64(*i),
            (MoveValue::U128(i), FatType::U128) => AnnotatedMoveValue::U128(*i),
            (MoveValue::Address(a), FatType::Address) => AnnotatedMoveValue::Address(*a),
            (MoveValue::Vector(a), FatType::Vector(ty)) => match ty.as_ref() {
                FatType::U8 => AnnotatedMoveValue::Bytes(
                    a.iter()
                        .map(|v| match v {
                            MoveValue::U8(i) => Ok(*i),
                            _ => Err(anyhow!("unexpected value type")),
                        })
                        .collect::<Result<_>>()?,
                ),
                _ => AnnotatedMoveValue::Vector(
                    a.iter()
                        .map(|v| self.annotate_value(v, ty.as_ref()))
                        .collect::<Result<_>>()?,
                ),
            },
            (MoveValue::Struct(s), FatType::Struct(ty)) => {
                AnnotatedMoveValue::Struct(self.annotate_struct(s, ty.as_ref())?)
            }
            _ => {
                return Err(anyhow!(
                    "Cannot annotate value {:?} with type {:?}",
                    value,
                    ty
                ))
            }
        })
    }
}

fn write_indent(f: &mut Formatter, indent: u64) -> std::fmt::Result {
    for _i in 0..indent {
        write!(f, " ")?;
    }
    Ok(())
}

fn pretty_print_value(
    f: &mut Formatter,
    value: &AnnotatedMoveValue,
    indent: u64,
) -> std::fmt::Result {
    match value {
        AnnotatedMoveValue::Bool(b) => write!(f, "{}", b),
        AnnotatedMoveValue::U8(v) => write!(f, "{}u8", v),
        AnnotatedMoveValue::U64(v) => write!(f, "{}", v),
        AnnotatedMoveValue::U128(v) => write!(f, "{}u128", v),
        AnnotatedMoveValue::Address(a) => write!(f, "{}", a.short_str_lossless()),
        AnnotatedMoveValue::Vector(v) => {
            writeln!(f, "[")?;
            for value in v.iter() {
                write_indent(f, indent + 4)?;
                pretty_print_value(f, value, indent + 4)?;
                writeln!(f, ",")?;
            }
            write_indent(f, indent)?;
            write!(f, "]")
        }
        AnnotatedMoveValue::Bytes(v) => write!(f, "{}", hex::encode(&v)),
        AnnotatedMoveValue::Struct(s) => pretty_print_struct(f, s, indent),
    }
}

fn pretty_print_struct(
    f: &mut Formatter,
    value: &AnnotatedMoveStruct,
    indent: u64,
) -> std::fmt::Result {
    writeln!(
        f,
        "{}{} {{",
        if value.is_resource { "resource " } else { "" },
        value.type_
    )?;
    for (field_name, v) in value.value.iter() {
        write_indent(f, indent + 4)?;
        write!(f, "{}: ", field_name)?;
        pretty_print_value(f, v, indent + 4)?;
        writeln!(f)?;
    }
    write_indent(f, indent)?;
    write!(f, "}}")
}

impl Display for AnnotatedMoveValue {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        pretty_print_value(f, self, 0)
    }
}

impl Display for AnnotatedMoveStruct {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        pretty_print_struct(f, self, 0)
    }
}

impl Display for AnnotatedAccountStateBlob {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        writeln!(f, "{{")?;
        for v in self.0.values() {
            write!(f, "{}", v)?;
            writeln!(f, ",")?;
        }
        writeln!(f, "}}")
    }
}

#[derive(Default)]
pub struct NullStateView();

impl StateView for NullStateView {
    fn get(&self, _access_path: &AccessPath) -> Result<Option<Vec<u8>>> {
        Err(anyhow!("No data"))
    }

    fn multi_get(&self, _access_paths: &[AccessPath]) -> Result<Vec<Option<Vec<u8>>>> {
        Err(anyhow!("No data"))
    }

    fn is_genesis(&self) -> bool {
        false
    }
}

impl RemoteCache for NullStateView {
    fn get_module(&self, _module_id: &ModuleId) -> VMResult<Option<Vec<u8>>> {
        Ok(None)
    }

    fn get_resource(
        &self,
        _address: &AccountAddress,
        _tag: &StructTag,
    ) -> PartialVMResult<Option<Vec<u8>>> {
        Ok(None)
    }
}
<|endoftext|>


<commit_before>extern crate sql;

pub use sql::lexer::Lexer;
pub use sql::lexer::Token::*;

describe! lexer_test {

    it "create lexer" {
        Lexer::new("some line here");
    }

    it "emptyline" {
        let mut lexer = Lexer::new("");

        assert_eq!(lexer.next_lexem(), None);
    }

    it "word token" {
        let mut lexer = Lexer::new("iNseRt");

        assert_eq!(lexer.next_lexem(), Some(Word("insert".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "left parenthesis" {
        let mut lexer = Lexer::new("(");

        assert_eq!(lexer.next_lexem(), Some(LeftParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "right parenthesis" {
        let mut lexer = Lexer::new(")");

        assert_eq!(lexer.next_lexem(), Some(RightParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "semicolon" {
        let mut lexer = Lexer::new(";");

        assert_eq!(lexer.next_lexem(), Some(SemiColon));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "single quote" {
        let mut lexer = Lexer::new("'");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines between words" {
        let mut lexer = Lexer::new("one\n\n\n\ntwo\n\n\nthree");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines in the end of lexer line" {
        let mut lexer = Lexer::new("one two three\n\n\n");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of single quotes separeted by spaces as lexer string" {
        let mut lexer = Lexer::new("' '' '' '' '");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word(" ' ' ' ".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of signle quotes in begin and end of string expression" {
        let mut lexer = Lexer::new("''''' '' '' '''''");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word("'' ' ' ''".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "exclude line comments" {
        let mut lexer = Lexer::new("one two -- some line comment here \n three");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }
}
<commit_msg>test: chars inside strings<commit_after>extern crate sql;

pub use sql::lexer::Lexer;
pub use sql::lexer::Token::*;

describe! lexer_test {

    it "create lexer" {
        Lexer::new("some line here");
    }

    it "emptyline" {
        let mut lexer = Lexer::new("");

        assert_eq!(lexer.next_lexem(), None);
    }

    it "word token" {
        let mut lexer = Lexer::new("iNseRt");

        assert_eq!(lexer.next_lexem(), Some(Word("insert".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "left parenthesis" {
        let mut lexer = Lexer::new("(");

        assert_eq!(lexer.next_lexem(), Some(LeftParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "right parenthesis" {
        let mut lexer = Lexer::new(")");

        assert_eq!(lexer.next_lexem(), Some(RightParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "semicolon" {
        let mut lexer = Lexer::new(";");

        assert_eq!(lexer.next_lexem(), Some(SemiColon));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "single quote" {
        let mut lexer = Lexer::new("'");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines between words" {
        let mut lexer = Lexer::new("one\n\n\n\ntwo\n\n\nthree");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines in the end of lexer line" {
        let mut lexer = Lexer::new("one two three\n\n\n");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of single quotes separeted by spaces as lexer string" {
        let mut lexer = Lexer::new("' '' '' '' '");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word(" ' ' ' ".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of signle quotes in begin and end of string expression" {
        let mut lexer = Lexer::new("''''' '' '' '''''");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word("'' ' ' ''".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "exclude line comments" {
        let mut lexer = Lexer::new("one two -- some line comment here \n three");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "should include diff chars into string expression" {
        let mut lexer = Lexer::new("'one two --- \n\n\t _ 1123'");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word("one two --- \n\n\t _ 1123".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
    }
}
<|endoftext|>