<commit_before>#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]

include!("bindings.rs");

use std::os::raw::c_char;
use std::io::Write;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::IntoRawFd;

extern crate libc;

#[derive(PartialEq)]
enum PrintState {
    OUT,
    IN,
    DISPLAY
}

fn print_ptr_rec<W: Write>(port: &mut W, p: ptr, state: PrintState) {
    let x = p as u32;
    if  (x & fx_mask) == fx_tag {
        write!(port, "{}", (x as i32) >> fx_shift);
    } else if x == bool_f {
        write!(port, "#f");
    } else if x == bool_t {
        write!(port, "#t");
    } else if x == list_nil {
        write!(port, "()");
    } else if x == eof_obj {
        write!(port, "#!eof");
    } else if (x & char_mask) == char_tag {
        let c = std::char::from_u32(x >> char_shift).
            expect("a char");
        if state == PrintState::DISPLAY {
            write!(port, "{}", c);
        } else {
            if      c == '\t' { write!(port, "#\\tab"); }
            else if c == '\n' { write!(port, "#\\newline"); }
            else if c == '\r' { write!(port, "#\\return"); }
            else if c == ' '  { write!(port, "#\\space"); }
            else              { write!(port, "#\\{}", c); }
        }
    } else if (x & obj_mask) == pair_tag {
        if state == PrintState::OUT { write!(port, "("); }
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let car = cell.car;
        print_ptr_rec(port, car, PrintState::OUT);
        let cdr = cell.cdr;
        if cdr != list_nil {
            if (cdr & obj_mask) != pair_tag {
                write!(port, " . ");
                print_ptr_rec(port, cdr, PrintState::OUT);
            } else {
                write!(port, " ");
                print_ptr_rec(port, cdr, PrintState::IN);
            }
        }
        if state == PrintState::OUT { write!(port, ")"); }
    } else if (x & obj_mask) == vector_tag {
        write!(port, "#(");
        unsafe {
        let p = &*((x-vector_tag) as *const vector);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            if i > 0 { write!(port, " "); }
            print_ptr_rec(port,
                *((p.buf.as_ptr()).offset(i as isize)),
                PrintState::OUT)
        }}
        write!(port, ")");
    } else if (x & obj_mask) == string_tag {
        if state == PrintState::OUT { write!(port, "\""); }
        unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            let c = std::char::from_u32(*((p.buf.as_ptr()).offset(i as isize)) as u32)
                .expect("char");
            if c == '"'       { write!(port, "\\\""); }
            else if c == '\\' { write!(port, "\\\\"); }
            else              { write!(port, "{}", c); }
        }}
        if state == PrintState::OUT { write!(port, "\""); }
    } else if (x & obj_mask) == symbol_tag {
        print_ptr_rec(port, (x - symbol_tag) | string_tag, PrintState::IN);
    } else if (x & obj_mask) == closure_tag {
        write!(port, "#<procedure>");
    } else {
        write!(port, "#<unknown 0x{:x}>", x);
    }
}
fn print_ptr(x: ptr) {
    print_ptr_rec(&mut std::io::stdout(), x, PrintState::OUT);
    println!("");
}

fn eprint_ptr(msg: ptr, state: PrintState) {
    print_ptr_rec(&mut std::io::stderr(), msg, PrintState::IN);
}

#[no_mangle]
pub extern "C" fn ik_log(msg: ptr) -> ptr {
    eprint!("log: ");
    eprint_ptr(msg, PrintState::IN);
    eprintln!("");
    0
}
#[no_mangle]
pub extern "C" fn ik_error(x: ptr) {
    eprint!("Exception");
    if (x & obj_mask) == pair_tag {
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let caller = cell.car;
        let msg = cell.cdr;
        if caller != bool_f {
            eprint!(" in ");
            eprint_ptr(caller, PrintState::OUT);
        }
        eprint!(": ");
        eprint_ptr(msg, PrintState::IN);
    }
    eprintln!("");
    std::process::exit(0);
}

fn unshift(x: ptr) -> i32 {
    (x as i32) >> fx_shift
}
fn shift(x: i32) -> ptr {
    (x << fx_shift) as u32
}
fn string_data(x: ptr) -> *mut c_char {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        p.buf.as_ptr() as *mut c_char
    }
}
fn cp_str_data(x: ptr, buf: *mut c_char, buf_length: u32) {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = unshift(p.length) as u32;
        let m = std::cmp::min(n, buf_length-1);
        for i in 0..m {
            *(buf.offset(i as isize)) = *(p.buf.as_ptr().offset(i as isize));
        }
        *(buf.offset(m as isize)) = 0;
    }
}
#[no_mangle]
pub extern "C" fn s_write(fd: ptr, str: ptr, len: ptr) -> ptr {
    let bytes = unsafe { libc::write(unshift(fd), string_data(str) as *const libc::c_void, unshift(len) as usize)};
    shift(bytes as i32)
}
#[no_mangle]
pub extern "C" fn s_open_write(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 100] = [0 as c_char; 100];
    cp_str_data(fname, c_fname.as_mut_ptr(), 100);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC, 0640) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_fflush(fd: ptr) -> ptr {
    unsafe { libc::fflush(libc::fdopen(unshift(fd), b"w".as_ptr() as *const i8)) };
    0
}
#[no_mangle]
pub extern "C" fn scheme_write(fd: ptr, x: ptr, opt: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let state = unshift(opt);
    let state =
        if state == 0 { PrintState::OUT }
    else if state == 1 { PrintState::IN }
    else { PrintState :: DISPLAY };
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    print_ptr_rec(&mut w, x, state);
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn s_open_read(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 100] = [0; 100];
    cp_str_data(fname, c_fname.as_mut_ptr(), 100);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_RDONLY) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_read_char(fd: ptr) -> ptr {
    let mut ca: [u32; 1] = [0;1];
    let ufd = unshift(fd);
    if unsafe { libc::read(ufd, ca.as_mut_ptr() as *mut libc::c_void, 1) } < 1 {
        eof_obj
    } else {
        (ca[0] << char_shift) | char_tag
    }
}
#[no_mangle]
pub extern "C" fn s_close(fd: ptr) -> ptr {
    let ufd = unshift(fd);
    let r = unsafe { libc::close(ufd) };
    shift(r)
}

#[no_mangle]
pub extern "C" fn heap_alloc(mem: *mut memory, stack: *mut c_char, size: usize) -> *mut c_char {
    let heap_next = unsafe { (*mem).heap_next };
    let heap_new = unsafe { heap_next.offset(size as isize) };
    if heap_new >= unsafe { (*mem).heap_top } {
        eprintln!("Exception: overflow");
        std::process::exit(0);
    }
    unsafe {(*mem).heap_next = heap_new};
    return heap_next;
}

fn allocate_protected_space(size: usize) -> *mut c_char {
    let mut v = Vec::with_capacity(size);
    let ptr = v.as_mut_ptr();
    std::mem::forget(v);
    ptr
}

fn deallocate_protected_space(p: *mut c_char, size: usize) {
    unsafe { std::mem::drop(Vec::from_raw_parts(p, 0, size)) };
}

fn main() {
    let stack_size = 16 * 4096;
    let heap_size = 4 * 16 * 4096;
    let global_size = 16 * 4096;
    let scratch_size = 16 * 4096;

    let stack_top = allocate_protected_space(stack_size);
    let stack_base = unsafe { stack_top.offset(stack_size as isize) };

    let heap = allocate_protected_space(heap_size);
    let global = allocate_protected_space(global_size);
    let scratch = allocate_protected_space(scratch_size);

    let uninit = 0 as (*mut std::os::raw::c_void);

    let mut ctxt = context {
        eax : uninit,
        ebx : uninit,
        ecx : uninit,
        edx : uninit,
        esi : uninit,
        edi : uninit,
        ebp : uninit,
        esp : uninit,
    };

    let heap_top = unsafe { heap.offset((heap_size as isize)/2) };
    let mut mem = memory {
        heap_next : heap,
        global_next : global,
        heap_base : heap,
        heap_top : heap_top,
        heap_base_alt : heap_top,
        heap_top_alt : unsafe { heap.offset(heap_size as isize) },
        global_base : global,
        stack_base : stack_base,
        scratch_base : scratch,
        edi : 0
    };

    let r = unsafe {
        scheme_entry(&mut ctxt, stack_base, &mut mem)
    };
    print_ptr(r);

    deallocate_protected_space(stack_top, stack_size);
    deallocate_protected_space(heap, stack_size);
}
<commit_msg>now it works, suspicious<commit_after>#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]

include!("bindings.rs");

use std::os::raw::c_char;
use std::io::Write;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::IntoRawFd;

extern crate libc;

#[derive(PartialEq)]
enum PrintState {
    OUT,
    IN,
    DISPLAY
}

fn print_ptr_rec<W: Write>(port: &mut W, p: ptr, state: PrintState) {
    let x = p as u32;
    if  (x & fx_mask) == fx_tag {
        write!(port, "{}", (x as i32) >> fx_shift);
    } else if x == bool_f {
        write!(port, "#f");
    } else if x == bool_t {
        write!(port, "#t");
    } else if x == list_nil {
        write!(port, "()");
    } else if x == eof_obj {
        write!(port, "#!eof");
    } else if (x & char_mask) == char_tag {
        let c = std::char::from_u32(x >> char_shift).
            expect("a char");
        if state == PrintState::DISPLAY {
            write!(port, "{}", c);
        } else {
            if      c == '\t' { write!(port, "#\\tab"); }
            else if c == '\n' { write!(port, "#\\newline"); }
            else if c == '\r' { write!(port, "#\\return"); }
            else if c == ' '  { write!(port, "#\\space"); }
            else              { write!(port, "#\\{}", c); }
        }
    } else if (x & obj_mask) == pair_tag {
        if state == PrintState::OUT { write!(port, "("); }
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let car = cell.car;
        print_ptr_rec(port, car, PrintState::OUT);
        let cdr = cell.cdr;
        if cdr != list_nil {
            if (cdr & obj_mask) != pair_tag {
                write!(port, " . ");
                print_ptr_rec(port, cdr, PrintState::OUT);
            } else {
                write!(port, " ");
                print_ptr_rec(port, cdr, PrintState::IN);
            }
        }
        if state == PrintState::OUT { write!(port, ")"); }
    } else if (x & obj_mask) == vector_tag {
        write!(port, "#(");
        unsafe {
        let p = &*((x-vector_tag) as *const vector);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            if i > 0 { write!(port, " "); }
            print_ptr_rec(port,
                *((p.buf.as_ptr()).offset(i as isize)),
                PrintState::OUT)
        }}
        write!(port, ")");
    } else if (x & obj_mask) == string_tag {
        if state == PrintState::OUT { write!(port, "\""); }
        unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            let c = std::char::from_u32(*((p.buf.as_ptr()).offset(i as isize)) as u32)
                .expect("char");
            if c == '"'       { write!(port, "\\\""); }
            else if c == '\\' { write!(port, "\\\\"); }
            else              { write!(port, "{}", c); }
        }}
        if state == PrintState::OUT { write!(port, "\""); }
    } else if (x & obj_mask) == symbol_tag {
        print_ptr_rec(port, (x - symbol_tag) | string_tag, PrintState::IN);
    } else if (x & obj_mask) == closure_tag {
        write!(port, "#<procedure>");
    } else {
        write!(port, "#<unknown 0x{:x}>", x);
    }
}
fn print_ptr(x: ptr) {
    print_ptr_rec(&mut std::io::stdout(), x, PrintState::OUT);
    println!("");
}

fn eprint_ptr(msg: ptr, state: PrintState) {
    print_ptr_rec(&mut std::io::stderr(), msg, PrintState::IN);
}

#[no_mangle]
pub extern "C" fn ik_log(msg: ptr) -> ptr {
    eprint!("log: ");
    eprint_ptr(msg, PrintState::IN);
    eprintln!("");
    0
}
#[no_mangle]
pub extern "C" fn ik_error(x: ptr) {
    eprint!("Exception");
    if (x & obj_mask) == pair_tag {
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let caller = cell.car;
        let msg = cell.cdr;
        if caller != bool_f {
            eprint!(" in ");
            eprint_ptr(caller, PrintState::OUT);
        }
        eprint!(": ");
        eprint_ptr(msg, PrintState::IN);
    }
    eprintln!("");
    std::process::exit(0);
}

fn unshift(x: ptr) -> i32 {
    (x as i32) >> fx_shift
}
fn shift(x: i32) -> ptr {
    (x << fx_shift) as u32
}
fn string_data(x: ptr) -> *mut c_char {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        p.buf.as_ptr() as *mut c_char
    }
}
fn cp_str_data(x: ptr, buf: *mut c_char, buf_length: u32) {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = unshift(p.length) as u32;
        let m = std::cmp::min(n, buf_length-1);
        for i in 0..m {
            *(buf.offset(i as isize)) = *(p.buf.as_ptr().offset(i as isize));
        }
        *(buf.offset(m as isize)) = 0;
    }
}
#[no_mangle]
pub extern "C" fn s_write(fd: ptr, str: ptr, len: ptr) -> ptr {
    let bytes = unsafe { libc::write(unshift(fd), string_data(str) as *const libc::c_void, unshift(len) as usize)};
    shift(bytes as i32)
}
#[no_mangle]
pub extern "C" fn s_open_write(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 10] = [0 as c_char; 10];
    cp_str_data(fname, c_fname.as_mut_ptr(), 10);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC, 0640) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_fflush(fd: ptr) -> ptr {
    unsafe { libc::fflush(libc::fdopen(unshift(fd), b"w".as_ptr() as *const i8)) };
    0
}
#[no_mangle]
pub extern "C" fn scheme_write(fd: ptr, x: ptr, opt: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let state = unshift(opt);
    let state =
        if state == 0 { PrintState::OUT }
    else if state == 1 { PrintState::IN }
    else { PrintState :: DISPLAY };
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    print_ptr_rec(&mut w, x, state);
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn s_open_read(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 10] = [0; 10];
    cp_str_data(fname, c_fname.as_mut_ptr(), 10);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_RDONLY) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_read_char(fd: ptr) -> ptr {
    let mut ca: [u32; 1] = [0;1];
    let ufd = unshift(fd);
    if unsafe { libc::read(ufd, ca.as_mut_ptr() as *mut libc::c_void, 1) } < 1 {
        eof_obj
    } else {
        (ca[0] << char_shift) | char_tag
    }
}
#[no_mangle]
pub extern "C" fn s_close(fd: ptr) -> ptr {
    let ufd = unshift(fd);
    let r = unsafe { libc::close(ufd) };
    shift(r)
}

#[no_mangle]
pub extern "C" fn heap_alloc(mem: *mut memory, stack: *mut c_char, size: usize) -> *mut c_char {
    let heap_next = unsafe { (*mem).heap_next };
    let heap_new = unsafe { heap_next.offset(size as isize) };
    if heap_new >= unsafe { (*mem).heap_top } {
        eprintln!("Exception: overflow");
        std::process::exit(0);
    }
    unsafe {(*mem).heap_next = heap_new};
    return heap_next;
}

fn allocate_protected_space(size: usize) -> *mut c_char {
    let mut v = Vec::with_capacity(size);
    let ptr = v.as_mut_ptr();
    std::mem::forget(v);
    ptr
}

fn deallocate_protected_space(p: *mut c_char, size: usize) {
    unsafe { std::mem::drop(Vec::from_raw_parts(p, 0, size)) };
}

fn main() {
    let stack_size = 16 * 4096;
    let heap_size = 4 * 16 * 4096;
    let global_size = 16 * 4096;
    let scratch_size = 16 * 4096;

    let stack_top = allocate_protected_space(stack_size);
    let stack_base = unsafe { stack_top.offset(stack_size as isize) };

    let heap = allocate_protected_space(heap_size);
    let global = allocate_protected_space(global_size);
    let scratch = allocate_protected_space(scratch_size);

    let uninit = 0 as (*mut std::os::raw::c_void);

    let mut ctxt = context {
        eax : uninit,
        ebx : uninit,
        ecx : uninit,
        edx : uninit,
        esi : uninit,
        edi : uninit,
        ebp : uninit,
        esp : uninit,
    };

    let heap_top = unsafe { heap.offset((heap_size as isize)/2) };
    let mut mem = memory {
        heap_next : heap,
        global_next : global,
        heap_base : heap,
        heap_top : heap_top,
        heap_base_alt : heap_top,
        heap_top_alt : unsafe { heap.offset(heap_size as isize) },
        global_base : global,
        stack_base : stack_base,
        scratch_base : scratch,
        edi : 0
    };

    let r = unsafe {
        scheme_entry(&mut ctxt, stack_base, &mut mem)
    };
    print_ptr(r);

    deallocate_protected_space(stack_top, stack_size);
    deallocate_protected_space(heap, stack_size);
}
<|endoftext|>


<commit_before>use syntax::{
    ast::{self, AstNode},
    SyntaxElement, SyntaxKind, TextRange, TextSize, T,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     <|>dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let new_contents = adjusted_macro_contents(&macro_call)?;

    let macro_text_range = macro_call.syntax().text_range();
    let macro_end = if macro_call.semicolon_token().is_some() {
        macro_text_range.end() - TextSize::of(';')
    } else {
        macro_text_range.end()
    };

    acc.add(
        AssistId("remove_dbg", AssistKind::Refactor),
        "Remove dbg!()",
        macro_text_range,
        |builder| {
            builder.replace(TextRange::new(macro_text_range.start(), macro_end), new_contents);
        },
    )
}

fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> {
    let contents = get_valid_macrocall_contents(&macro_call, "dbg")?;
    let macro_text_with_brackets = macro_call.token_tree()?.syntax().text();
    let macro_text_in_brackets = macro_text_with_brackets.slice(TextRange::new(
        TextSize::of('('),
        macro_text_with_brackets.len() - TextSize::of(')'),
    ));

    let is_leaf = macro_call.syntax().next_sibling().is_none();
    Some(if !is_leaf && needs_parentheses_around_macro_contents(contents) {
        format!("({})", macro_text_in_brackets)
    } else {
        macro_text_in_brackets.to_string()
    })
}

/// Verifies that the given macro_call actually matches the given name
/// and contains proper ending tokens, then returns the contents between the ending tokens
fn get_valid_macrocall_contents(
    macro_call: &ast::MacroCall,
    macro_name: &str,
) -> Option<Vec<SyntaxElement>> {
    let path = macro_call.path()?;
    let name_ref = path.segment()?.name_ref()?;

    // Make sure it is actually a dbg-macro call, dbg followed by !
    let excl = path.syntax().next_sibling_or_token()?;
    if name_ref.text() != macro_name || excl.kind() != T![!] {
        return None;
    }

    let mut children_with_tokens = macro_call.token_tree()?.syntax().children_with_tokens();
    let first_child = children_with_tokens.next()?;
    let mut contents_between_brackets = children_with_tokens.collect::<Vec<_>>();
    let last_child = contents_between_brackets.pop()?;

    if contents_between_brackets.is_empty() {
        None
    } else {
        match (first_child.kind(), last_child.kind()) {
            (T!['('], T![')']) | (T!['['], T![']']) | (T!['{'], T!['}']) => {
                Some(contents_between_brackets)
            }
            _ => None,
        }
    }
}

fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) -> bool {
    if macro_contents.len() < 2 {
        return false;
    }
    let mut unpaired_brackets_in_contents = Vec::new();
    for element in macro_contents {
        match element.kind() {
            T!['('] | T!['['] | T!['{'] => unpaired_brackets_in_contents.push(element),
            T![')'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['('])
                {
                    return true;
                }
            }
            T![']'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['['])
                {
                    return true;
                }
            }
            T!['}'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['{'])
                {
                    return true;
                }
            }
            symbol_kind => {
                let symbol_not_in_bracket = unpaired_brackets_in_contents.is_empty();
                if symbol_not_in_bracket
                    && symbol_kind != SyntaxKind::COLON
                    && symbol_kind.is_punct()
                {
                    return true;
                }
            }
        }
    }
    !unpaired_brackets_in_contents.is_empty()
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};

    use super::*;

    #[test]
    fn test_remove_dbg() {
        check_assist(remove_dbg, "<|>dbg!(1 + 1)", "1 + 1");

        check_assist(remove_dbg, "dbg!<|>((1 + 1))", "(1 + 1)");

        check_assist(remove_dbg, "dbg!(1 <|>+ 1)", "1 + 1");

        check_assist(remove_dbg, "let _ = <|>dbg!(1 + 1)", "let _ = 1 + 1");

        check_assist(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "
fn foo(n: usize) {
    if let Some(_) = n.checked_sub(4) {
        // ...
    }
}
",
        );

        check_assist(remove_dbg, "<|>dbg!(Foo::foo_test()).bar()", "Foo::foo_test().bar()");
    }

    #[test]
    fn test_remove_dbg_with_brackets_and_braces() {
        check_assist(remove_dbg, "dbg![<|>1 + 1]", "1 + 1");
        check_assist(remove_dbg, "dbg!{<|>1 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "<|>vec![1, 2, 3]");
        check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)");
        check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7");
    }

    #[test]
    fn test_remove_dbg_target() {
        check_assist_target(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "dbg!(n.checked_sub(4))",
        );
    }

    #[test]
    fn test_remove_dbg_keep_semicolon() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        // not quite though
        // adding a comment at the end of the line makes
        // the ast::MacroCall to include the semicolon at the end
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
    }

    #[test]
    fn remove_dbg_from_non_leaf_simple_expression() {
        check_assist(
            remove_dbg,
            "
fn main() {
    let mut a = 1;
    while dbg!<|>(a) < 10000 {
        a += 1;
    }
}
",
            "
fn main() {
    let mut a = 1;
    while a < 10000 {
        a += 1;
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_keep_expression() {
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(a + b).foo();"#,
            r#"let res = (a + b).foo();"#,
        );

        check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#);
        check_assist(remove_dbg, r#"let res = <|>dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#);
    }

    #[test]
    fn test_remove_dbg_from_inside_fn() {
        check_assist_target(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            "dbg!(5 + 10)",
        );

        check_assist(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(5 + 10);
    println!("{}", x);
}"#,
        );
    }
}
<commit_msg>Don't keep parens around with remove-dbg when encountering method chaining<commit_after>use syntax::{
    ast::{self, AstNode},
    SyntaxElement, SyntaxKind, TextRange, TextSize, T,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     <|>dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let new_contents = adjusted_macro_contents(&macro_call)?;

    let macro_text_range = macro_call.syntax().text_range();
    let macro_end = if macro_call.semicolon_token().is_some() {
        macro_text_range.end() - TextSize::of(';')
    } else {
        macro_text_range.end()
    };

    acc.add(
        AssistId("remove_dbg", AssistKind::Refactor),
        "Remove dbg!()",
        macro_text_range,
        |builder| {
            builder.replace(TextRange::new(macro_text_range.start(), macro_end), new_contents);
        },
    )
}

fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> {
    let contents = get_valid_macrocall_contents(&macro_call, "dbg")?;
    let macro_text_with_brackets = macro_call.token_tree()?.syntax().text();
    let macro_text_in_brackets = macro_text_with_brackets.slice(TextRange::new(
        TextSize::of('('),
        macro_text_with_brackets.len() - TextSize::of(')'),
    ));

    let is_leaf = macro_call.syntax().next_sibling().is_none();
    Some(if !is_leaf && needs_parentheses_around_macro_contents(contents) {
        format!("({})", macro_text_in_brackets)
    } else {
        macro_text_in_brackets.to_string()
    })
}

/// Verifies that the given macro_call actually matches the given name
/// and contains proper ending tokens, then returns the contents between the ending tokens
fn get_valid_macrocall_contents(
    macro_call: &ast::MacroCall,
    macro_name: &str,
) -> Option<Vec<SyntaxElement>> {
    let path = macro_call.path()?;
    let name_ref = path.segment()?.name_ref()?;

    // Make sure it is actually a dbg-macro call, dbg followed by !
    let excl = path.syntax().next_sibling_or_token()?;
    if name_ref.text() != macro_name || excl.kind() != T![!] {
        return None;
    }

    let mut children_with_tokens = macro_call.token_tree()?.syntax().children_with_tokens();
    let first_child = children_with_tokens.next()?;
    let mut contents_between_brackets = children_with_tokens.collect::<Vec<_>>();
    let last_child = contents_between_brackets.pop()?;

    if contents_between_brackets.is_empty() {
        None
    } else {
        match (first_child.kind(), last_child.kind()) {
            (T!['('], T![')']) | (T!['['], T![']']) | (T!['{'], T!['}']) => {
                Some(contents_between_brackets)
            }
            _ => None,
        }
    }
}

fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) -> bool {
    if macro_contents.len() < 2 {
        return false;
    }
    let mut unpaired_brackets_in_contents = Vec::new();
    for element in macro_contents {
        match element.kind() {
            T!['('] | T!['['] | T!['{'] => unpaired_brackets_in_contents.push(element),
            T![')'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['('])
                {
                    return true;
                }
            }
            T![']'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['['])
                {
                    return true;
                }
            }
            T!['}'] => {
                if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['{'])
                {
                    return true;
                }
            }
            symbol_kind => {
                let symbol_not_in_bracket = unpaired_brackets_in_contents.is_empty();
                if symbol_not_in_bracket
                    && symbol_kind != SyntaxKind::COLON
                    && symbol_kind != SyntaxKind::DOT
                    && symbol_kind.is_punct()
                {
                    return true;
                }
            }
        }
    }
    !unpaired_brackets_in_contents.is_empty()
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};

    use super::*;

    #[test]
    fn test_remove_dbg() {
        check_assist(remove_dbg, "<|>dbg!(1 + 1)", "1 + 1");

        check_assist(remove_dbg, "dbg!<|>((1 + 1))", "(1 + 1)");

        check_assist(remove_dbg, "dbg!(1 <|>+ 1)", "1 + 1");

        check_assist(remove_dbg, "let _ = <|>dbg!(1 + 1)", "let _ = 1 + 1");

        check_assist(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "
fn foo(n: usize) {
    if let Some(_) = n.checked_sub(4) {
        // ...
    }
}
",
        );

        check_assist(remove_dbg, "<|>dbg!(Foo::foo_test()).bar()", "Foo::foo_test().bar()");
    }

    #[test]
    fn test_remove_dbg_with_brackets_and_braces() {
        check_assist(remove_dbg, "dbg![<|>1 + 1]", "1 + 1");
        check_assist(remove_dbg, "dbg!{<|>1 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "<|>vec![1, 2, 3]");
        check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)");
        check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7");
    }

    #[test]
    fn test_remove_dbg_target() {
        check_assist_target(
            remove_dbg,
            "
fn foo(n: usize) {
    if let Some(_) = dbg!(n.<|>checked_sub(4)) {
        // ...
    }
}
",
            "dbg!(n.checked_sub(4))",
        );
    }

    #[test]
    fn test_remove_dbg_keep_semicolon() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        // not quite though
        // adding a comment at the end of the line makes
        // the ast::MacroCall to include the semicolon at the end
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
    }

    #[test]
    fn remove_dbg_from_non_leaf_simple_expression() {
        check_assist(
            remove_dbg,
            "
fn main() {
    let mut a = 1;
    while dbg!<|>(a) < 10000 {
        a += 1;
    }
}
",
            "
fn main() {
    let mut a = 1;
    while a < 10000 {
        a += 1;
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_keep_expression() {
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(a + b).foo();"#,
            r#"let res = (a + b).foo();"#,
        );

        check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#);
        check_assist(remove_dbg, r#"let res = <|>dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#);
    }

    #[test]
    fn test_remove_dbg_method_chaining() {
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(foo().bar()).baz();"#,
            r#"let res = foo().bar().baz();"#,
        );
        check_assist(
            remove_dbg,
            r#"let res = <|>dbg!(foo.bar()).baz();"#,
            r#"let res = foo.bar().baz();"#,
        );
    }

    #[test]
    fn test_remove_dbg_field_chaining() {
        check_assist(remove_dbg, r#"let res = <|>dbg!(foo.bar).baz;"#, r#"let res = foo.bar.baz;"#);
    }

    #[test]
    fn test_remove_dbg_from_inside_fn() {
        check_assist_target(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            "dbg!(5 + 10)",
        );

        check_assist(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg<|>!(5 + 10));
    println!("{}", x);
}"#,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(5 + 10);
    println!("{}", x);
}"#,
        );
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn left_shift(&mut self, v: &i32) {}
}

fn main() {
    let mut a = Tree::new(&3);
    a.insert(&2);
    a.insert(&1);
    a.insert(&4);
    a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);
}
<commit_msg>finish left shift<commit_after>#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.left.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn cut_left_tree(&mut self) -> Box<Self> {
        self.left.clone().unwrap()
    }

    fn cut_right_tree(&mut self) -> Box<Self> {
        self.right.clone().unwrap()
    }

    fn left_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_left_tree();
        let mut son = this.cut_right_tree();
        let grand_son = son.cut_left_tree();

        this.right = Some(grand_son);
        son.left = Some(this);
        father.left = Some(son);
    }
}

fn main() {
    //let mut a = Tree::new(&3);
    //a.insert(&2);
    //a.insert(&1);
    //a.insert(&4);
    //a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    //println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);

    let mut b = Tree::new(&10);
    b.insert(&2);
    b.insert(&1);
    b.insert(&5);
    b.insert(&3);
    b.insert(&6);
    b.insert(&11);

    //println!("{:?}", b);
    //println!("{:?}", b.look_up_father(&2));
    b.left_shift(&2);
    println!("{:?}", b);
}
<|endoftext|>


<commit_before>use serial_support::messages::{SerialResponse, SerialRequest};

error_chain! {

  foreign_links {
    Fmt(::std::fmt::Error);
    Io(::std::io::Error) #[cfg(unix)];
    Serialport(::serialport::Error) #[cfg(unix)];
    Utf8(::std::string::FromUtf8Error);
    Json(::serde_json::error::Error);
    SendResponse(::std::sync::mpsc::SendError<SerialResponse>);
    Base64(::base64::DecodeError);
    SendRequest(::std::sync::mpsc::SendError<(String,SerialRequest)>);
    SendWsMessage(::websocket::result::WebSocketError);
  }

  errors{
    UnknownRequest{
      description("Unknown request")
      display("Unknown request,")
    }
    OpenPortNotFound(port:String){
      description("Open serial port not found")
      display("Serial port '{}' not found, try opening it first", port)
    }
    SubscriptionNotFound(sub_id:String){
      description("Subscription not found")
      display("Subscription for id '{}' not found", sub_id)
    }
    AlreadyWriteLocked(port:String){
      description("Port already write locked by another client")
      display("Open serial port '{}' is already write locked by another client", port)
    }
    NeedWriteLock(port:String){
      description("Need write lock")
      display("Write to open port '{}' failed, you need to write lock first", port)
    }
    PortReadError(port:String){
      description("Error reading serial port")
      display("Read from port '{}' failed", port)
    }
    PortEOFError(port:String){
      description("Encountered EOF reading serial port")
      display("Encountered EOF reading serial port {}", port)
    }
    PortWriteError(port:String){
      description("Error writing serial port")
      display("Writing to port '{}' failed", port)
    }
    SubscriberSendError(sub_id:String){
      description("Error sending message to subscriber")
      display("Send to subscriber '{}' failed", sub_id)
    }
  }
}

pub fn to_serial_response_error(err: Error) -> SerialResponse {
  SerialResponse::Error {
    description: err.description().to_string(),
    display: format!("{}", err),
  }
}
<commit_msg>Added some comments<commit_after>use serial_support::messages::{SerialResponse, SerialRequest};

error_chain! {

  foreign_links {
    // Wrapped Format error
    Fmt(::std::fmt::Error);
    // Wrapped IO error
    Io(::std::io::Error) #[cfg(unix)];
    // Wrapped serial port error
    Serialport(::serialport::Error) #[cfg(unix)];
    // Wrapped Ut8 decode error
    Utf8(::std::string::FromUtf8Error);
    // Wrapped json error
    Json(::serde_json::error::Error);
    // Wrapped sync send response error
    SendResponse(::std::sync::mpsc::SendError<SerialResponse>);
    // Wrapped Base64 decode error
    Base64(::base64::DecodeError);
    // Wrapped sync send request error
    SendRequest(::std::sync::mpsc::SendError<(String,SerialRequest)>);
    // wrapped send websocket error.
    SendWsMessage(::websocket::result::WebSocketError);
  }

  errors{
    /// Unknown server request
    UnknownRequest{
      description("Unknown request")
      display("Unknown request,")
    }
    /// Open port not found
    OpenPortNotFound(port:String){
      description("Open serial port not found")
      display("Serial port '{}' not found, try opening it first", port)
    }
    /// Subscription not found
    SubscriptionNotFound(sub_id:String){
      description("Subscription not found")
      display("Subscription for id '{}' not found", sub_id)
    }
    /// Port already write locked error
    AlreadyWriteLocked(port:String){
      description("Port already write locked by another client")
      display("Open serial port '{}' is already write locked by another client", port)
    }
    /// Need write lock error
    NeedWriteLock(port:String){
      description("Need write lock")
      display("Write to open port '{}' failed, you need to write lock first", port)
    }
    /// Serial port read error
    PortReadError(port:String){
      description("Error reading serial port")
      display("Read from port '{}' failed", port)
    }
    /// Serial Port EOF error
    PortEOFError(port:String){
      description("Encountered EOF reading serial port")
      display("Encountered EOF reading serial port {}", port)
    }
    /// Serial port write error
    PortWriteError(port:String){
      description("Error writing serial port")
      display("Writing to port '{}' failed", port)
    }
    /// Send to subscriber error
    SubscriberSendError(sub_id:String){
      description("Error sending message to subscriber")
      display("Send to subscriber '{}' failed", sub_id)
    }
  }
}

/// Convert Error to serial response error enum type
pub fn to_serial_response_error(err: Error) -> SerialResponse {
  SerialResponse::Error {
    description: err.description().to_string(),
    display: format!("{}", err),
  }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }

    fn make_black(&mut self) {
        self.color = Color::Black;
    }

    fn make_red(&mut self) {
        self.color = Color::Red;
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        let mut root = Node::new(v);
        root.make_black();
        Tree {
            enter: root,
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };

        match target {
            Some(next) => next.insert(v),
            None => {
                let mut new_node = Node::new(v);
                new_node.make_red();
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> ReTr {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.left.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn cut_left_tree(&mut self) -> Option<Box<Self>> {
        self.left.clone()
    }

    fn cut_right_tree(&mut self) -> Option<Box<Self>> {
        self.right.clone()
    }

    fn left_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_left_tree().unwrap();
        let mut son = this.cut_right_tree().unwrap();
        let grand_son = son.cut_left_tree().unwrap();

        this.right = Some(grand_son);
        son.left = Some(this);
        father.left = Some(son);
    }

    fn right_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_right_tree().unwrap();
        let mut son = this.cut_left_tree().unwrap();
        let grand_son = son.cut_right_tree().unwrap();

        this.left = Some(grand_son);
        son.right = Some(this);
        father.right = Some(son);
    }
}

fn main() {
    //let mut a = Tree::new(&3);
    //a.insert(&2);
    //a.insert(&1);
    //a.insert(&4);
    //a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    //println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);

    //let mut b = Tree::new(&10);
    //b.insert(&2);
    //b.insert(&1);
    //b.insert(&5);
    //b.insert(&3);
    //b.insert(&6);
    //b.insert(&11);

    //println!("{:?}", b);
    //println!("{:?}", b.look_up_father(&2));
    //b.left_shift(&2);
    //println!("{:?}", b);

    let mut c = Tree::new(&2);
    c.insert(&8);
    c.insert(&1);
    c.insert(&5);
    c.insert(&4);
    c.insert(&7);
    c.insert(&9);
    //println!("{:?}", c.look_up_father(&8));
    c.right_shift(&8);
    println!("{:?}", c);
}
<commit_msg>fix when this node is root node then no father<commit_after>use std::fmt;

#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

/*impl fmt::Display for Tree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(this: {:#?}, \nleft: {:#?}, \nright: {:#?})",
            self.enter, self.left, self.right
        )
    }
}*/

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }

    fn make_black(&mut self) {
        self.color = Color::Black;
    }

    fn make_red(&mut self) {
        self.color = Color::Red;
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        let mut root = Node::new(v);
        root.make_black();
        Tree {
            enter: root,
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };

        match target {
            Some(next) => next.insert(v),
            None => {
                let mut new_node = Node::new(v);
                new_node.make_red();
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> ReTr {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return (Err("no father".to_string()), "this".to_string());
            } else if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.left.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn cut_left_tree(&mut self) -> Option<Box<Self>> {
        self.left.clone()
    }

    fn cut_right_tree(&mut self) -> Option<Box<Self>> {
        self.right.clone()
    }

    fn left_shift(&mut self, v: &i32) {
        match self.look_up_father(v).0 {
            Ok(r) => {
                let father = r;
                let mut this = father.cut_left_tree().unwrap();
                let mut son = this.cut_right_tree().unwrap();
                let grand_son = son.cut_left_tree().unwrap();

                this.right = Some(grand_son);
                son.left = Some(this);
                father.left = Some(son);
                return;
            }
            _ => (),
        }

        let left = self.cut_left_tree().unwrap();
        let mut new_left = Tree::new(&self.enter.val);
        new_left.left = Some(left);

        let mut right = self.cut_right_tree().unwrap();
        let right_left = right.cut_left_tree().unwrap();
        let right_right = right.cut_right_tree().unwrap();
        new_left.right = Some(right_left);

        self.enter = Node::new(&right.enter.val);

        self.right = Some(right_right);

        self.left = Some(Box::new(new_left));
    }

    fn right_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_right_tree().unwrap();
        let mut son = this.cut_left_tree().unwrap();
        let grand_son = son.cut_right_tree().unwrap();

        this.left = Some(grand_son);
        son.right = Some(this);
        father.right = Some(son);
    }
}

fn main() {
    //let mut a = Tree::new(&3);
    //a.insert(&2);
    //a.insert(&1);
    //a.insert(&4);
    //a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    //println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);

    let mut b = Tree::new(&10);
    b.insert(&2);
    b.insert(&1);
    b.insert(&5);
    b.insert(&3);
    b.insert(&6);
    b.insert(&11);

    //println!("{:?}", b);
    //println!("{:?}", b.look_up_father(&2));
    let mut c = b.cut_left_tree().unwrap();
    //println!("{:#?}", c);
    c.left_shift(&2);
    println!("{:#?}", c);

    //let mut c = Tree::new(&2);
    //c.insert(&8);
    //c.insert(&1);
    //c.insert(&5);
    //c.insert(&4);
    //c.insert(&7);
    //c.insert(&9);
    //println!("{:?}", c.look_up_father(&8));
    //c.right_shift(&8);
    //println!("{:#?}", c);
}
<|endoftext|>


<commit_before>extern crate lapin;
#[macro_use] extern crate nom;

use std::net::TcpStream;
use std::iter::repeat;
use std::io::{Read,Write,Error};

use nom::HexDisplay;

use lapin::connection::*;
use lapin::method::*;
use lapin::frame::*;

#[test]
fn connection() {
      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();

      let capacity = 4096;
      let mut send_buffer: Vec<u8> = Vec::with_capacity(capacity);
      send_buffer.extend(repeat(0).take(capacity));
      let mut receive_buffer: Vec<u8> = Vec::with_capacity(capacity);
      receive_buffer.extend(repeat(0).take(capacity));

      //let (sl, bytes_written) = gen_protocol_header((&mut send_buffer, 0)).unwrap();
      //assert_eq!(stream.write(&sl[..bytes_written]).unwrap(), bytes_written);

      let mut conn: Connection = Connection::new();
      assert_eq!(conn.connect(&mut stream).unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));

      /*
      let bytes_read = stream.read(&mut receive_buffer).unwrap();

      println!("received:\n{}", (&receive_buffer[..bytes_read]).to_hex(16));
      //assert_eq!(&receive_buffer[..8], &['A' as u8, 'M' as u8, 'Q' as u8, 'P' as u8, 0, 0, 9, 1]);
      let res = frame(&receive_buffer[..bytes_read]);
      println!("received: {:?}", res);

      let payload = &receive_buffer[7..bytes_read];
      println!("payload:\n{}", (&receive_buffer[7..bytes_read]).to_hex(16));

      let res2 = method(payload);
      println!("method: {:?}", res2);
      */
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());
      panic!();
}
<commit_msg>open channels<commit_after>extern crate lapin;
#[macro_use] extern crate nom;

use std::net::TcpStream;
use std::iter::repeat;
use std::io::{Read,Write,Error};

use nom::HexDisplay;

use lapin::connection::*;
use lapin::method::*;
use lapin::frame::*;

#[test]
fn connection() {
      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();

      let capacity = 4096;
      let mut send_buffer: Vec<u8> = Vec::with_capacity(capacity);
      send_buffer.extend(repeat(0).take(capacity));
      let mut receive_buffer: Vec<u8> = Vec::with_capacity(capacity);
      receive_buffer.extend(repeat(0).take(capacity));

      //let (sl, bytes_written) = gen_protocol_header((&mut send_buffer, 0)).unwrap();
      //assert_eq!(stream.write(&sl[..bytes_written]).unwrap(), bytes_written);

      let mut conn: Connection = Connection::new();
      assert_eq!(conn.connect(&mut stream).unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));

      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());

      //now connected

      //send channel
      conn.channel_open(1, "".to_string());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());

      //receive channel
      conn.channel_open(2, "".to_string());
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());

      conn.basic_publish(1, 0, "".to_string(), "".to_string(), false, false);
      println!("[{}] state: {:?}", line!(), conn.write(&mut stream).unwrap());
      println!("[{}] state: {:?}", line!(), conn.read(&mut stream).unwrap());

      panic!();
}
<|endoftext|>


<commit_before>use std::mem;
use std::sync::Arc;

use VulkanObject;
use buffer::Buffer;
use formats::Format;
use vk;

#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum VertexInputRate {
    Vertex = vk::VERTEX_INPUT_RATE_VERTEX,
    Instance = vk::VERTEX_INPUT_RATE_INSTANCE,
}

/// Describes an individual `Vertex`. More precisely, a collection of attributes that can be read
/// from a vertex shader.
pub unsafe trait Vertex {
    /// Returns the characteristics of a vertex attribute.
    fn attrib(name: &str) -> Option<VertexAttribute>;
}

pub struct VertexAttribute {
    pub offset: usize,
    pub format: Format,
}

/// Trait for types that contain the layout of a collection of vertex buffers.
pub unsafe trait MultiVertex {
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)>;

    /// Returns the number of buffers in this collection.
    fn num_buffers() -> u32;

    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate);

    // TODO: hacky
    fn ids(&self) -> Vec<u64>;
}

unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>> where T: Vertex {
    #[inline]
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
        T::attrib(name).map(|attr| (0, attr))
    }

    #[inline]
    fn num_buffers() -> u32 {
        1
    }

    #[inline]
    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
        assert_eq!(buffer_id, 0);
        (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
    }

    fn ids(&self) -> Vec<u64> {
        vec![self.internal_object()]
    }
}

unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>> where T: Vertex {
    #[inline]
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
        T::attrib(name).map(|attr| (0, attr))
    }

    #[inline]
    fn num_buffers() -> u32 {
        1
    }

    #[inline]
    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
        assert_eq!(buffer_id, 0);
        (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
    }

    fn ids(&self) -> Vec<u64> {
        vec![self.internal_object()]
    }
}

macro_rules! impl_mv {
    ($t1:ident, $t2:ty) => (
        unsafe impl<$t1, M> MultiVertex for Arc<Buffer<$t2, M>> where T: Vertex {
            #[inline]
            fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
                T::attrib(name).map(|attr| (0, attr))
            }

            #[inline]
            fn num_buffers() -> u32 {
                1
            }

            #[inline]
            fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
                assert_eq!(buffer_id, 0);
                (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
            }

            fn ids(&self) -> Vec<u64> {
                vec![self.internal_object()]
            }
        }
    );
}

impl_mv!(T, [T; 1]);
impl_mv!(T, [T; 2]);
impl_mv!(T, [T; 3]);
impl_mv!(T, [T; 4]);
impl_mv!(T, [T; 5]);
impl_mv!(T, [T; 6]);
impl_mv!(T, [T; 7]);
impl_mv!(T, [T; 8]);
impl_mv!(T, [T; 9]);
impl_mv!(T, [T; 10]);
impl_mv!(T, [T; 11]);
impl_mv!(T, [T; 12]);
impl_mv!(T, [T; 13]);
impl_mv!(T, [T; 14]);
impl_mv!(T, [T; 15]);
impl_mv!(T, [T; 16]);
impl_mv!(T, [T; 32]);
impl_mv!(T, [T; 64]);
impl_mv!(T, [T; 128]);
impl_mv!(T, [T; 256]);
impl_mv!(T, [T; 512]);
impl_mv!(T, [T; 1024]);
impl_mv!(T, [T; 2048]);
impl_mv!(T, [T; 4096]);

#[macro_export]
macro_rules! impl_vertex {
    ($out:ident $(, $member:ident)*) => (
        unsafe impl $crate::pipeline::vertex::Vertex for $out {
            #[inline(always)]
            fn attrib(name: &str) -> Option<$crate::pipeline::vertex::VertexAttribute> {
                $(
                    if name == stringify!($member) {
                        return Some($crate::pipeline::vertex::VertexAttribute {
                            offset: unsafe {
                                let dummy = 0usize as *const $out;
                                let member = (&(&*dummy).$member) as *const _;
                                member as usize
                            },

                            format: <$crate::formats::R32G32Sfloat as $crate::formats::FormatMarker>::format(),     // FIXME:
                        });
                    }
                )*

                None
            }
        }
    )
}
<commit_msg>Correctly determine vertex format<commit_after>use std::mem;
use std::sync::Arc;

use VulkanObject;
use buffer::Buffer;
use formats::Format;
use vk;

#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum VertexInputRate {
    Vertex = vk::VERTEX_INPUT_RATE_VERTEX,
    Instance = vk::VERTEX_INPUT_RATE_INSTANCE,
}

/// Describes an individual `Vertex`. More precisely, a collection of attributes that can be read
/// from a vertex shader.
pub unsafe trait Vertex {
    /// Returns the characteristics of a vertex attribute.
    fn attrib(name: &str) -> Option<VertexAttribute>;
}

pub struct VertexAttribute {
    pub offset: usize,
    pub format: Format,
}

/// Trait for types that contain the layout of a collection of vertex buffers.
pub unsafe trait MultiVertex {
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)>;

    /// Returns the number of buffers in this collection.
    fn num_buffers() -> u32;

    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate);

    // TODO: hacky
    fn ids(&self) -> Vec<u64>;
}

unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>> where T: Vertex {
    #[inline]
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
        T::attrib(name).map(|attr| (0, attr))
    }

    #[inline]
    fn num_buffers() -> u32 {
        1
    }

    #[inline]
    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
        assert_eq!(buffer_id, 0);
        (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
    }

    fn ids(&self) -> Vec<u64> {
        vec![self.internal_object()]
    }
}

unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>> where T: Vertex {
    #[inline]
    fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
        T::attrib(name).map(|attr| (0, attr))
    }

    #[inline]
    fn num_buffers() -> u32 {
        1
    }

    #[inline]
    fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
        assert_eq!(buffer_id, 0);
        (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
    }

    fn ids(&self) -> Vec<u64> {
        vec![self.internal_object()]
    }
}

macro_rules! impl_mv {
    ($t1:ident, $t2:ty) => (
        unsafe impl<$t1, M> MultiVertex for Arc<Buffer<$t2, M>> where T: Vertex {
            #[inline]
            fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
                T::attrib(name).map(|attr| (0, attr))
            }

            #[inline]
            fn num_buffers() -> u32 {
                1
            }

            #[inline]
            fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate) {
                assert_eq!(buffer_id, 0);
                (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
            }

            fn ids(&self) -> Vec<u64> {
                vec![self.internal_object()]
            }
        }
    );
}

impl_mv!(T, [T; 1]);
impl_mv!(T, [T; 2]);
impl_mv!(T, [T; 3]);
impl_mv!(T, [T; 4]);
impl_mv!(T, [T; 5]);
impl_mv!(T, [T; 6]);
impl_mv!(T, [T; 7]);
impl_mv!(T, [T; 8]);
impl_mv!(T, [T; 9]);
impl_mv!(T, [T; 10]);
impl_mv!(T, [T; 11]);
impl_mv!(T, [T; 12]);
impl_mv!(T, [T; 13]);
impl_mv!(T, [T; 14]);
impl_mv!(T, [T; 15]);
impl_mv!(T, [T; 16]);
impl_mv!(T, [T; 32]);
impl_mv!(T, [T; 64]);
impl_mv!(T, [T; 128]);
impl_mv!(T, [T; 256]);
impl_mv!(T, [T; 512]);
impl_mv!(T, [T; 1024]);
impl_mv!(T, [T; 2048]);
impl_mv!(T, [T; 4096]);

#[macro_export]
macro_rules! impl_vertex {
    ($out:ident $(, $member:ident)*) => (
        unsafe impl $crate::pipeline::vertex::Vertex for $out {
            #[inline(always)]
            fn attrib(name: &str) -> Option<$crate::pipeline::vertex::VertexAttribute> {
                $(
                    if name == stringify!($member) {
                        return Some($crate::pipeline::vertex::VertexAttribute {
                            offset: unsafe {
                                let dummy = 0usize as *const $out;
                                let member = (&(&*dummy).$member) as *const _;
                                member as usize
                            },

                            format: unsafe {
                                #[inline] fn f<T: $crate::pipeline::vertex::Attribute>(_: &T) -> $crate::formats::Format { T::format() }
                                let dummy = 0usize as *const $out;
                                f(&(&*dummy).$member)
                            },
                        });
                    }
                )*

                None
            }
        }
    )
}

pub unsafe trait Attribute {
    fn format() -> Format;
}

unsafe impl Attribute for [f32; 1] {
    #[inline]
    fn format() -> Format {
        Format::R32Sfloat
    }
}

unsafe impl Attribute for [f32; 2] {
    #[inline]
    fn format() -> Format {
        Format::R32G32Sfloat
    }
}

unsafe impl Attribute for [f32; 3] {
    #[inline]
    fn format() -> Format {
        Format::R32G32B32Sfloat
    }
}

unsafe impl Attribute for [f32; 4] {
    #[inline]
    fn format() -> Format {
        Format::R32G32B32A32Sfloat
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code)]

use server::Node;
use server::transport::{ServerRaftStoreRouter, RaftStoreRouter};
use raftstore::store::Transport;
use raftstore::errors::Error as RaftServerError;
use util::HandyRwLock;
use kvproto::raft_cmdpb::{RaftCmdRequest, RaftCmdResponse, RaftRequestHeader, Request, Response,
                          GetRequest, CmdType, SeekRequest, DeleteRequest, PutRequest};
use kvproto::errorpb;
use kvproto::metapb;
use kvproto::kvrpcpb::Context;

use pd::PdClient;
use uuid::Uuid;
use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::fmt::{self, Formatter, Debug};
use std::io::Error as IoError;
use std::result;
use protobuf::RepeatedField;

use super::{Result as EngineResult, Error as EngineError, Engine, Modify};
use storage::{Key, Value, KvPair};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        RequestFailed(e: errorpb::Error) {
            from()
            description(e.get_message())
        }
        Io(e: IoError) {
            from()
            cause(e)
            description(e.description())
        }
        RocksDb(reason: String) {
            description(reason)
        }
        Server(e: RaftServerError) {
            from()
            cause(e)
            description(e.description())
        }
        InvalidResponse(reason: String) {
            description(reason)
        }
        InvalidRequest(reason: String) {
            description(reason)
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

impl From<Error> for EngineError {
    fn from(e: Error) -> EngineError {
        match e {
            Error::RequestFailed(e) => EngineError::Request(e),
            e => EngineError::Other(box e),
        }
    }
}

/// RaftKv is a storage engine base on RaftKvServer.
pub struct RaftKv<T: PdClient + 'static, Trans: Transport + 'static> {
    node: Node<T, Trans>,
    router: Arc<RwLock<ServerRaftStoreRouter>>,
}

impl<T: PdClient, Trans: Transport> RaftKv<T, Trans> {
    /// Create a RaftKv using specified configuration.
    pub fn new(node: Node<T, Trans>) -> RaftKv<T, Trans> {
        let router = node.raft_store_router();
        RaftKv {
            node: node,
            router: router,
        }
    }

    fn exec_cmd_request(&self, req: RaftCmdRequest) -> Result<RaftCmdResponse> {
        let (tx, rx) = mpsc::channel();
        let uuid = req.get_header().get_uuid().to_vec();
        let l = req.get_requests().len();

        try!(self.router.rl().send_command(req,
                                           box move |r| {
                                               box_try!(tx.send(r));
                                               Ok(())
                                           }));

        // Only when tx is closed will recv return Err, which should never happen.
        let mut resp = rx.recv().unwrap();
        if resp.get_header().get_uuid() != &*uuid {
            return Err(Error::InvalidResponse("response is not correct!!!".to_owned()));
        }
        if resp.get_header().has_error() {
            return Err(Error::RequestFailed(resp.mut_header().take_error()));
        }
        if l != resp.get_responses().len() {
            return Err(Error::InvalidResponse("response count is not equal to requests, \
                                               something must go wrong."
                                                  .to_owned()));
        }
        Ok(resp)
    }

    fn new_request_header(&self, region_id: u64, peer: metapb::Peer) -> RaftRequestHeader {
        let mut header = RaftRequestHeader::new();
        header.set_region_id(region_id);
        header.set_peer(peer);
        header.set_uuid(Uuid::new_v4().as_bytes().to_vec());
        header
    }

    fn exec_requests(&self,
                     region_id: u64,
                     peer: metapb::Peer,
                     reqs: Vec<Request>)
                     -> Result<Vec<Response>> {
        let header = self.new_request_header(region_id, peer);
        let mut command = RaftCmdRequest::new();
        command.set_header(header);
        command.set_requests(RepeatedField::from_vec(reqs));
        let mut resp = try!(self.exec_cmd_request(command));
        Ok(resp.take_responses().to_vec())
    }

    fn exec_request(&self, region_id: u64, peer: metapb::Peer, req: Request) -> Result<Response> {
        let resps = self.exec_requests(region_id, peer, vec![req]);
        resps.map(|mut v| v.remove(0))
    }
}

impl<T: PdClient, Trans: Transport> Debug for RaftKv<T, Trans> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "RaftKv")
    }
}

impl<T: PdClient, Trans: Transport> Engine for RaftKv<T, Trans> {
    fn get(&self, ctx: &Context, key: &Key) -> EngineResult<Option<Value>> {
        let mut get = GetRequest::new();
        get.set_key(key.raw().clone());
        let mut req = Request::new();
        req.set_cmd_type(CmdType::Get);
        req.set_get(get);
        let lead = ctx.get_peer().clone();
        let mut resp = try!(self.exec_request(ctx.get_region_id(), lead, req));
        if resp.get_cmd_type() != CmdType::Get {
            return Err(Error::InvalidResponse(format!("cmd type not match, want {:?}, got {:?}!",
                                                      CmdType::Get,
                                                      resp.get_cmd_type()))
                           .into());
        }
        let get_resp = resp.mut_get();
        if get_resp.has_value() {
            Ok(Some(get_resp.take_value()))
        } else {
            Ok(None)
        }
    }

    fn seek(&self, ctx: &Context, key: &Key) -> EngineResult<Option<KvPair>> {
        let mut seek = SeekRequest::new();
        seek.set_key(key.raw().clone());
        let mut req = Request::new();
        req.set_cmd_type(CmdType::Seek);
        req.set_seek(seek);
        let lead = ctx.get_peer().clone();
        let mut resp = try!(self.exec_request(ctx.get_region_id(), lead, req));
        if resp.get_cmd_type() != CmdType::Seek {
            return Err(Error::InvalidResponse(format!("cmd type not match, want {:?}, got {:?}",
                                                      CmdType::Seek,
                                                      resp.get_cmd_type()))
                           .into());
        }
        let seek_resp = resp.mut_seek();
        if seek_resp.has_key() {
            Ok(Some((seek_resp.take_key(), seek_resp.take_value())))
        } else {
            Ok(None)
        }
    }

    fn write(&self, ctx: &Context, mut modifies: Vec<Modify>) -> EngineResult<()> {
        if modifies.len() == 0 {
            return Ok(());
        }
        let mut reqs = Vec::with_capacity(modifies.len());
        while !modifies.is_empty() {
            let m = modifies.pop().unwrap();
            let mut req = Request::new();
            match m {
                Modify::Delete(k) => {
                    let mut delete = DeleteRequest::new();
                    delete.set_key(k.raw().clone());
                    req.set_cmd_type(CmdType::Delete);
                    req.set_delete(delete);
                }
                Modify::Put((k, v)) => {
                    let mut put = PutRequest::new();
                    put.set_key(k.raw().clone());
                    put.set_value(v);
                    req.set_cmd_type(CmdType::Put);
                    req.set_put(put);
                }
            }
            reqs.push(req);
        }
        try!(self.exec_requests(ctx.get_region_id(), ctx.get_peer().clone(), reqs));
        Ok(())
    }
}
<commit_msg>raftkv: Tiny clean up.<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code)]

use server::Node;
use server::transport::{ServerRaftStoreRouter, RaftStoreRouter};
use raftstore::store::Transport;
use raftstore::errors::Error as RaftServerError;
use util::HandyRwLock;
use kvproto::raft_cmdpb::{RaftCmdRequest, RaftCmdResponse, RaftRequestHeader, Request, Response,
                          GetRequest, CmdType, SeekRequest, DeleteRequest, PutRequest};
use kvproto::errorpb;
use kvproto::metapb;
use kvproto::kvrpcpb::Context;

use pd::PdClient;
use uuid::Uuid;
use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::fmt::{self, Formatter, Debug};
use std::io::Error as IoError;
use std::result;
use protobuf::RepeatedField;

use super::{Result as EngineResult, Error as EngineError, Engine, Modify};
use storage::{Key, Value, KvPair};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        RequestFailed(e: errorpb::Error) {
            from()
            description(e.get_message())
        }
        Io(e: IoError) {
            from()
            cause(e)
            description(e.description())
        }
        RocksDb(reason: String) {
            description(reason)
        }
        Server(e: RaftServerError) {
            from()
            cause(e)
            description(e.description())
        }
        InvalidResponse(reason: String) {
            description(reason)
        }
        InvalidRequest(reason: String) {
            description(reason)
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

impl From<Error> for EngineError {
    fn from(e: Error) -> EngineError {
        match e {
            Error::RequestFailed(e) => EngineError::Request(e),
            e => EngineError::Other(box e),
        }
    }
}

/// RaftKv is a storage engine base on RaftKvServer.
pub struct RaftKv<T: PdClient + 'static, Trans: Transport + 'static> {
    node: Node<T, Trans>,
    router: Arc<RwLock<ServerRaftStoreRouter>>,
}

impl<T: PdClient, Trans: Transport> RaftKv<T, Trans> {
    /// Create a RaftKv using specified configuration.
    pub fn new(node: Node<T, Trans>) -> RaftKv<T, Trans> {
        let router = node.raft_store_router();
        RaftKv {
            node: node,
            router: router,
        }
    }

    fn exec_cmd_request(&self, req: RaftCmdRequest) -> Result<RaftCmdResponse> {
        let (tx, rx) = mpsc::channel();
        let uuid = req.get_header().get_uuid().to_vec();
        let l = req.get_requests().len();

        try!(self.router.rl().send_command(req,
                                           box move |r| {
                                               box_try!(tx.send(r));
                                               Ok(())
                                           }));

        // Only when tx is closed will recv return Err, which should never happen.
        let mut resp = rx.recv().unwrap();
        if resp.get_header().get_uuid() != &*uuid {
            return Err(Error::InvalidResponse("response is not correct!!!".to_owned()));
        }
        if resp.get_header().has_error() {
            return Err(Error::RequestFailed(resp.mut_header().take_error()));
        }
        if l != resp.get_responses().len() {
            return Err(Error::InvalidResponse("response count is not equal to requests, \
                                               something must go wrong."
                                                  .to_owned()));
        }
        Ok(resp)
    }

    fn new_request_header(&self, region_id: u64, peer: metapb::Peer) -> RaftRequestHeader {
        let mut header = RaftRequestHeader::new();
        header.set_region_id(region_id);
        header.set_peer(peer);
        header.set_uuid(Uuid::new_v4().as_bytes().to_vec());
        header
    }

    fn exec_requests(&self,
                     region_id: u64,
                     peer: metapb::Peer,
                     reqs: Vec<Request>)
                     -> Result<Vec<Response>> {
        let header = self.new_request_header(region_id, peer);
        let mut cmd = RaftCmdRequest::new();
        cmd.set_header(header);
        cmd.set_requests(RepeatedField::from_vec(reqs));
        let mut resp = try!(self.exec_cmd_request(cmd));
        Ok(resp.take_responses().to_vec())
    }

    fn exec_request(&self, region_id: u64, peer: metapb::Peer, req: Request) -> Result<Response> {
        let resps = self.exec_requests(region_id, peer, vec![req]);
        resps.map(|mut v| v.remove(0))
    }
}

impl<T: PdClient, Trans: Transport> Debug for RaftKv<T, Trans> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "RaftKv")
    }
}

impl<T: PdClient, Trans: Transport> Engine for RaftKv<T, Trans> {
    fn get(&self, ctx: &Context, key: &Key) -> EngineResult<Option<Value>> {
        let mut get = GetRequest::new();
        get.set_key(key.raw().clone());
        let mut req = Request::new();
        req.set_cmd_type(CmdType::Get);
        req.set_get(get);
        let lead = ctx.get_peer().clone();
        let mut resp = try!(self.exec_request(ctx.get_region_id(), lead, req));
        if resp.get_cmd_type() != CmdType::Get {
            return Err(Error::InvalidResponse(format!("cmd type not match, want {:?}, got {:?}!",
                                                      CmdType::Get,
                                                      resp.get_cmd_type()))
                           .into());
        }
        let get_resp = resp.mut_get();
        if get_resp.has_value() {
            Ok(Some(get_resp.take_value()))
        } else {
            Ok(None)
        }
    }

    fn seek(&self, ctx: &Context, key: &Key) -> EngineResult<Option<KvPair>> {
        let mut seek = SeekRequest::new();
        seek.set_key(key.raw().clone());
        let mut req = Request::new();
        req.set_cmd_type(CmdType::Seek);
        req.set_seek(seek);
        let lead = ctx.get_peer().clone();
        let mut resp = try!(self.exec_request(ctx.get_region_id(), lead, req));
        if resp.get_cmd_type() != CmdType::Seek {
            return Err(Error::InvalidResponse(format!("cmd type not match, want {:?}, got {:?}",
                                                      CmdType::Seek,
                                                      resp.get_cmd_type()))
                           .into());
        }
        let seek_resp = resp.mut_seek();
        if seek_resp.has_key() {
            Ok(Some((seek_resp.take_key(), seek_resp.take_value())))
        } else {
            Ok(None)
        }
    }

    fn write(&self, ctx: &Context, mut modifies: Vec<Modify>) -> EngineResult<()> {
        if modifies.len() == 0 {
            return Ok(());
        }
        let mut reqs = Vec::with_capacity(modifies.len());
        while !modifies.is_empty() {
            let m = modifies.pop().unwrap();
            let mut req = Request::new();
            match m {
                Modify::Delete(k) => {
                    let mut delete = DeleteRequest::new();
                    delete.set_key(k.raw().clone());
                    req.set_cmd_type(CmdType::Delete);
                    req.set_delete(delete);
                }
                Modify::Put((k, v)) => {
                    let mut put = PutRequest::new();
                    put.set_key(k.raw().clone());
                    put.set_value(v);
                    req.set_cmd_type(CmdType::Put);
                    req.set_put(put);
                }
            }
            reqs.push(req);
        }
        try!(self.exec_requests(ctx.get_region_id(), ctx.get_peer().clone(), reqs));
        Ok(())
    }
}
<|endoftext|>