<commit_before>//! Common builtins.

use std::rc::Rc;
use item::StackItem;
use vm::{Vm, Error, Method};
use num::{zero, one, Integer};

pub fn insert_arithmetic<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("+", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 + n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("-", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 - n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("*", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 * n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("/", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            if n2 == zero() {
                return Err(Error::DivideByZero);
            }
            vm.stack.push(StackItem::Integer(n1 / n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_fn<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("fn", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let name = try!(vm.stack.pop());
        match (name, block) {
            (StackItem::Symbol(s), StackItem::Block(b)) =>
                { vm.methods.insert(s, Rc::new(Method::Block(b))); },
            _ => return Err(Error::TypeError),
        }
        Ok(())
    }));
}

pub fn insert_stack_ops<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("swap", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(b);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("over", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(a.clone());
        vm.stack.push(b);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("rot", Box::new(|vm| {
        let c = try!(vm.stack.pop());
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(b);
        vm.stack.push(c);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("dup", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        vm.stack.push(a.clone());
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("pop", Box::new(|vm| {
        let _ = try!(vm.stack.pop());
        Ok(())
    }));
}

pub fn insert_boolean_ops<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("false", Box::new(|vm| {
        vm.stack.push(StackItem::Boolean(false));
        Ok(())
    }));
    vm.insert_builtin("true", Box::new(|vm| {
        vm.stack.push(StackItem::Boolean(true));
        Ok(())
    }));
    vm.insert_builtin("eq", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        let b = try!(vm.stack.pop());
        vm.stack.push(StackItem::Boolean(a == b));
        Ok(())
    }));
    vm.insert_builtin("not", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        if let StackItem::Boolean(boolean) = a {
            vm.stack.push(StackItem::Boolean(!boolean));
        } else {
            return Err(Error::TypeError)
        }
        Ok(())
    }));
    vm.insert_builtin("or", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        if let (StackItem::Boolean(a), StackItem::Boolean(b)) = (a, b) {
            vm.stack.push(StackItem::Boolean(a || b));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_string_ops<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("cat", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        if let (StackItem::String(b), StackItem::String(mut a)) =
                (b, a) {
            a.push_str(&b);
            vm.stack.push(StackItem::String(a));
        }
        Ok(())
    }));
}

pub fn insert_control_flow<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("if", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let condition = try!(vm.stack.pop());
        if let (StackItem::Block(block), StackItem::Boolean(condition)) =
                (block, condition) {
            if condition {
                try!(vm.run_block(&block));
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("ifelse", Box::new(|vm| {
        let else_block = try!(vm.stack.pop());
        let if_block = try!(vm.stack.pop());
        let condition = try!(vm.stack.pop());
        if let (StackItem::Block(else_block), StackItem::Block(if_block), StackItem::Boolean(condition)) =
                (else_block, if_block, condition) {
            if condition {
                try!(vm.run_block(&if_block));
            } else {
                try!(vm.run_block(&else_block));
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("while", Box::new(|vm| {
        let action_block = try!(vm.stack.pop());
        let condition_block = try!(vm.stack.pop());
        if let (StackItem::Block(action_block), StackItem::Block(condition_block)) =
                (action_block, condition_block) {
            loop {
                try!(vm.run_block(&condition_block));
                let condition = try!(vm.stack.pop());
                if let StackItem::Boolean(condition) = condition {
                    if condition {
                        try!(vm.run_block(&action_block));
                    } else {
                        break;
                    }
                } else {
                    return Err(Error::TypeError);
                }
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("times", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let times = try!(vm.stack.pop());
        if let (StackItem::Block(block), StackItem::Integer(mut times)) =
                (block, times) {
            while times > zero() {
                try!(vm.run_block(&block));
                times = times - one::<I>();
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_all<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    insert_arithmetic(vm);
    insert_fn(vm);
    insert_stack_ops(vm);
    insert_boolean_ops(vm);
    insert_string_ops(vm);
    insert_control_flow(vm);
}
<commit_msg>Rename and extend stack ops<commit_after>//! Common builtins.

use std::rc::Rc;
use item::StackItem;
use vm::{Vm, Error, Method};
use num::{zero, one, Integer, ToPrimitive, FromPrimitive};

pub fn insert_arithmetic<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("+", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 + n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("-", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 - n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("*", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            vm.stack.push(StackItem::Integer(n1 * n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("/", Box::new(|vm| {
        let n2 = try!(vm.stack.pop());
        let n1 = try!(vm.stack.pop());
        if let (StackItem::Integer(n2), StackItem::Integer(n1)) = (n2, n1) {
            if n2 == zero() {
                return Err(Error::DivideByZero);
            }
            vm.stack.push(StackItem::Integer(n1 / n2));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_fn<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("fn", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let name = try!(vm.stack.pop());
        match (name, block) {
            (StackItem::Symbol(s), StackItem::Block(b)) =>
                { vm.methods.insert(s, Rc::new(Method::Block(b))); },
            _ => return Err(Error::TypeError),
        }
        Ok(())
    }));
}

pub fn insert_stack_ops<I>(vm: &mut Vm<I>)
        where I: Integer + Clone + ToPrimitive + FromPrimitive {
    vm.insert_builtin("swap", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(b);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("clone", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        vm.stack.push(a.clone());
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("clone-nth", Box::new(|vm| {
        if let StackItem::Integer(n) = try!(vm.stack.pop()) {
            if let Some(n) = n.to_usize() {
                if n <= vm.stack.0.len() {
                    let idx = vm.stack.0.len() - n;
                    let nth = vm.stack.0.get(idx).map(|i| i.clone());
                    if let Some(nth) = nth {
                        vm.stack.push(nth);
                    } else {
                        return Err(Error::OutOfBounds);
                    }
                } else {
                    return Err(Error::OutOfBounds);
                }
            } else {
                return Err(Error::IntegerOverflow);
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("clear", Box::new(|vm| {
        vm.stack.0.clear();
        Ok(())
    }));
    vm.insert_builtin("len", Box::new(|vm| {
        let count = try!(FromPrimitive::from_usize(vm.stack.0.len())
                         .ok_or(Error::IntegerOverflow));
        vm.stack.push(StackItem::Integer(count));
        Ok(())
    }));
    vm.insert_builtin("over", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(a.clone());
        vm.stack.push(b);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("rot", Box::new(|vm| {
        let c = try!(vm.stack.pop());
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        vm.stack.push(b);
        vm.stack.push(c);
        vm.stack.push(a);
        Ok(())
    }));
    vm.insert_builtin("pop", Box::new(|vm| {
        let _ = try!(vm.stack.pop());
        Ok(())
    }));
}

pub fn insert_boolean_ops<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("false", Box::new(|vm| {
        vm.stack.push(StackItem::Boolean(false));
        Ok(())
    }));
    vm.insert_builtin("true", Box::new(|vm| {
        vm.stack.push(StackItem::Boolean(true));
        Ok(())
    }));
    vm.insert_builtin("eq", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        let b = try!(vm.stack.pop());
        vm.stack.push(StackItem::Boolean(a == b));
        Ok(())
    }));
    vm.insert_builtin("not", Box::new(|vm| {
        let a = try!(vm.stack.pop());
        if let StackItem::Boolean(boolean) = a {
            vm.stack.push(StackItem::Boolean(!boolean));
        } else {
            return Err(Error::TypeError)
        }
        Ok(())
    }));
    vm.insert_builtin("or", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        if let (StackItem::Boolean(a), StackItem::Boolean(b)) = (a, b) {
            vm.stack.push(StackItem::Boolean(a || b));
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_string_ops<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("cat", Box::new(|vm| {
        let b = try!(vm.stack.pop());
        let a = try!(vm.stack.pop());
        if let (StackItem::String(b), StackItem::String(mut a)) =
                (b, a) {
            a.push_str(&b);
            vm.stack.push(StackItem::String(a));
        }
        Ok(())
    }));
}

pub fn insert_control_flow<I>(vm: &mut Vm<I>) where I: Integer + Clone {
    vm.insert_builtin("if", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let condition = try!(vm.stack.pop());
        if let (StackItem::Block(block), StackItem::Boolean(condition)) =
                (block, condition) {
            if condition {
                try!(vm.run_block(&block));
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("ifelse", Box::new(|vm| {
        let else_block = try!(vm.stack.pop());
        let if_block = try!(vm.stack.pop());
        let condition = try!(vm.stack.pop());
        if let (StackItem::Block(else_block), StackItem::Block(if_block), StackItem::Boolean(condition)) =
                (else_block, if_block, condition) {
            if condition {
                try!(vm.run_block(&if_block));
            } else {
                try!(vm.run_block(&else_block));
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("while", Box::new(|vm| {
        let action_block = try!(vm.stack.pop());
        let condition_block = try!(vm.stack.pop());
        if let (StackItem::Block(action_block), StackItem::Block(condition_block)) =
                (action_block, condition_block) {
            loop {
                try!(vm.run_block(&condition_block));
                let condition = try!(vm.stack.pop());
                if let StackItem::Boolean(condition) = condition {
                    if condition {
                        try!(vm.run_block(&action_block));
                    } else {
                        break;
                    }
                } else {
                    return Err(Error::TypeError);
                }
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
    vm.insert_builtin("times", Box::new(|vm| {
        let block = try!(vm.stack.pop());
        let times = try!(vm.stack.pop());
        if let (StackItem::Block(block), StackItem::Integer(mut times)) =
                (block, times) {
            while times > zero() {
                try!(vm.run_block(&block));
                times = times - one::<I>();
            }
        } else {
            return Err(Error::TypeError);
        }
        Ok(())
    }));
}

pub fn insert_all<I>(vm: &mut Vm<I>)
        where I: Integer + Clone + ToPrimitive + FromPrimitive {
    insert_arithmetic(vm);
    insert_fn(vm);
    insert_stack_ops(vm);
    insert_boolean_ops(vm);
    insert_string_ops(vm);
    insert_control_flow(vm);
}
<|endoftext|>


<commit_before>use super::*;
use byteorder::BigEndian;
use byteorder::WriteBytesExt;
use client;
use futures::prelude::*;
use index::btree;
use index::btree::test::u64_to_slice;
use index::key_with_id;
use index::lsmtree::tree::KeyRange;
use index::lsmtree::tree::LSMTree;
use index::Cursor;
use index::Ordering;
use itertools::Itertools;
use ram::types::Id;
use rand::distributions::Uniform;
use rand::thread_rng;
use rand::Rng;
use rayon::prelude::*;
use server::NebServer;
use server::ServerOptions;
use smallvec::SmallVec;
use std::env;
use std::io::Cursor as StdCursor;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn dump_trees(lsm_tree: &LSMTree, name: &str) {
    for i in 0..lsm_tree.trees.len() {
        lsm_tree.trees[i].dump(&format!("{}_lsm_{}_dump.json", name, i));
    }
}

fn default_key_range() -> KeyRange {
    (smallvec!(), smallvec!())
}

#[test]
pub fn insertions() {
    env_logger::init();
    let tree = Arc::new(LSMTree::new(default_key_range(), Id::unit_id()));
    let num = env::var("LSM_TREE_TEST_ITEMS")
        // this value cannot do anything useful to the test
        // must arrange a long-term test to cover every levels
        .unwrap_or("331776".to_string())
        .parse::<u64>()
        .unwrap();

    let tree_clone = tree.clone();
    debug!("Testing LSM-tree");
    thread::spawn(move || loop {
        thread::sleep(Duration::from_secs(10));
        let tree_len = tree_clone.len();
        debug!(
            "LSM-Tree now have {}/{} elements, total {:.2}%",
            tree_len,
            num,
            tree_len as f32 / num as f32 * 100.0
        );
    });

    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        key_with_id(&mut key, &id);
        tree.insert(key);
    });

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}", i);
    });

    dump_trees(&*tree, "stage_1_before_insertion");
    for _ in 0..50 {
        tree.check_and_merge();
    }
    dump_trees(&*tree, "stage_1_after_insertion");

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}, looking for {:?}", i, key);
    });
}

#[test]
pub fn hybrid() {
    env_logger::init();
    let tree = Arc::new(LSMTree::new(default_key_range(), Id::unit_id()));
    let num = env::var("LSM_TREE_TEST_ITEMS")
        // this value cannot do anything useful to the test
        // must arrange a long-term test to cover every levels
        .unwrap_or("663552".to_string())
        .parse::<u64>()
        .unwrap();

    LSMTree::start_sentinel(&tree);
    let tree_clone = tree.clone();
    debug!("Testing LSM-tree");
    thread::spawn(move || loop {
        thread::sleep(Duration::from_secs(10));
        let tree_len = tree_clone.len();
        debug!(
            "LSM-Tree now have {}/{} elements, total {:.2}%",
            tree_len,
            num,
            tree_len as f32 / num as f32 * 100.0
        );
    });

    let mut test_data = (0..num).collect_vec();
    thread_rng().shuffle(test_data.as_mut_slice());
    test_data.par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        key_with_id(&mut key, &id);
        tree.insert(key);
    });

    dump_trees(&*tree, "hybird_after_insertion");
    thread::sleep(Duration::new(30, 0));
    dump_trees(&*tree, "hybird_after_sleep");

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}", i);
    });
}
<commit_msg>unparallel last point query check<commit_after>use super::*;
use byteorder::BigEndian;
use byteorder::WriteBytesExt;
use client;
use futures::prelude::*;
use index::btree;
use index::btree::test::u64_to_slice;
use index::key_with_id;
use index::lsmtree::tree::KeyRange;
use index::lsmtree::tree::LSMTree;
use index::Cursor;
use index::Ordering;
use itertools::Itertools;
use ram::types::Id;
use rand::distributions::Uniform;
use rand::thread_rng;
use rand::Rng;
use rayon::prelude::*;
use server::NebServer;
use server::ServerOptions;
use smallvec::SmallVec;
use std::env;
use std::io::Cursor as StdCursor;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn dump_trees(lsm_tree: &LSMTree, name: &str) {
    for i in 0..lsm_tree.trees.len() {
        lsm_tree.trees[i].dump(&format!("{}_lsm_{}_dump.json", name, i));
    }
}

fn default_key_range() -> KeyRange {
    (smallvec!(), smallvec!())
}

#[test]
pub fn insertions() {
    env_logger::init();
    let tree = Arc::new(LSMTree::new(default_key_range(), Id::unit_id()));
    let num = env::var("LSM_TREE_TEST_ITEMS")
        // this value cannot do anything useful to the test
        // must arrange a long-term test to cover every levels
        .unwrap_or("331776".to_string())
        .parse::<u64>()
        .unwrap();

    let tree_clone = tree.clone();
    debug!("Testing LSM-tree");
    thread::spawn(move || loop {
        thread::sleep(Duration::from_secs(10));
        let tree_len = tree_clone.len();
        debug!(
            "LSM-Tree now have {}/{} elements, total {:.2}%",
            tree_len,
            num,
            tree_len as f32 / num as f32 * 100.0
        );
    });

    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        key_with_id(&mut key, &id);
        tree.insert(key);
    });

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}", i);
    });

    dump_trees(&*tree, "stage_1_before_insertion");
    for _ in 0..50 {
        tree.check_and_merge();
    }
    dump_trees(&*tree, "stage_1_after_insertion");

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}, looking for {:?}", i, key);
    });
}

#[test]
pub fn hybrid() {
    env_logger::init();
    let tree = Arc::new(LSMTree::new(default_key_range(), Id::unit_id()));
    let num = env::var("LSM_TREE_TEST_ITEMS")
        // this value cannot do anything useful to the test
        // must arrange a long-term test to cover every levels
        .unwrap_or("663552".to_string())
        .parse::<u64>()
        .unwrap();

    LSMTree::start_sentinel(&tree);
    let tree_clone = tree.clone();
    debug!("Testing LSM-tree");
    thread::spawn(move || loop {
        thread::sleep(Duration::from_secs(10));
        let tree_len = tree_clone.len();
        debug!(
            "LSM-Tree now have {}/{} elements, total {:.2}%",
            tree_len,
            num,
            tree_len as f32 / num as f32 * 100.0
        );
    });

    let mut test_data = (0..num).collect_vec();
    thread_rng().shuffle(test_data.as_mut_slice());
    test_data.par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        key_with_id(&mut key, &id);
        tree.insert(key);
    });

    dump_trees(&*tree, "hybird_after_insertion");
    thread::sleep(Duration::new(30, 0));
    dump_trees(&*tree, "hybird_after_sleep");

    debug!("Start point search validations");
    (0..num).collect::<Vec<_>>().par_iter().for_each(|i| {
        let i = *i;
        let id = Id::new(0, i);
        let key_slice = u64_to_slice(i);
        let mut key = SmallVec::from_slice(&key_slice);
        debug!("checking: {}", i);
        let cursor = tree.seek(&key, Ordering::Forward);
        key_with_id(&mut key, &id);
        assert_eq!(cursor.current(), Some(&key), "{}", i);
    });
}
<|endoftext|>


<commit_before>//! Connection helper.
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;

use tungstenite::client::uri_mode;
use tungstenite::handshake::client::Response;
use tungstenite::Error;

use super::{client_async, Request, IntoClientRequest, WebSocketStream};

#[cfg(feature = "tls")]
pub(crate) mod encryption {
    use native_tls::TlsConnector;
    use tokio_tls::{TlsConnector as TokioTlsConnector, TlsStream};

    use tokio::io::{AsyncRead, AsyncWrite};

    use tungstenite::stream::Mode;
    use tungstenite::Error;

    use crate::stream::Stream as StreamSwitcher;

    /// A stream that might be protected with TLS.
    pub type MaybeTlsStream<S> = StreamSwitcher<S, TlsStream<S>>;

    pub type AutoStream<S> = MaybeTlsStream<S>;

    pub async fn wrap_stream<S>(
        socket: S,
        domain: String,
        mode: Mode,
    ) -> Result<AutoStream<S>, Error>
    where
        S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    {
        match mode {
            Mode::Plain => Ok(StreamSwitcher::Plain(socket)),
            Mode::Tls => {
                let try_connector = TlsConnector::new();
                let connector = try_connector.map_err(Error::Tls)?;
                let stream = TokioTlsConnector::from(connector);
                let connected = stream.connect(&domain, socket).await;
                match connected {
                    Err(e) => Err(Error::Tls(e)),
                    Ok(s) => Ok(StreamSwitcher::Tls(s)),
                }
            }
        }
    }
}

#[cfg(feature = "tls")]
pub use self::encryption::MaybeTlsStream;

#[cfg(not(feature = "tls"))]
pub(crate) mod encryption {
    use tokio::io::{AsyncRead, AsyncWrite};

    use tungstenite::stream::Mode;
    use tungstenite::Error;

    pub type AutoStream<S> = S;

    pub async fn wrap_stream<S>(
        socket: S,
        _domain: String,
        mode: Mode,
    ) -> Result<AutoStream<S>, Error>
    where
        S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    {
        match mode {
            Mode::Plain => Ok(socket),
            Mode::Tls => Err(Error::Url("TLS support not compiled in.".into())),
        }
    }
}

use self::encryption::{wrap_stream, AutoStream};

/// Get a domain from an URL.
#[inline]
fn domain(request: &Request) -> Result<String, Error> {
    match request.uri().host() {
        Some(d) => Ok(d.to_string()),
        None => Err(Error::Url("no host name in the url".into())),
    }
}

/// Creates a WebSocket handshake from a request and a stream,
/// upgrading the stream to TLS if required.
pub async fn client_async_tls<R, S>(
    request: R,
    stream: S,
) -> Result<(WebSocketStream<AutoStream<S>>, Response), Error>
where
    R: IntoClientRequest + Unpin,
    S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    AutoStream<S>: Unpin,
{
    let request = request.into_client_request()?;

    let domain = domain(&request)?;

    // Make sure we check domain and mode first. URL must be valid.
    let mode = uri_mode(&request.uri())?;

    let stream = wrap_stream(stream, domain, mode).await?;
    client_async(request, stream).await
}

/// Connect to a given URL.
pub async fn connect_async<R>(
    request: R,
) -> Result<(WebSocketStream<AutoStream<TcpStream>>, Response), Error>
where
    R: IntoClientRequest + Unpin,
{
    let request = request.into_client_request()?;

    let domain = domain(&request)?;
    let port = request
        .uri()
        .port_u16()
        .or_else(|| {
            match request.uri().scheme_str() {
                Some("wss") => Some(443),
                Some("ws") => Some(80),
                _ => None
            }
        })
        .ok_or(Error::Url("Url scheme not supported".into()))?;

    let addr = format!("{}:{}", domain, port);
    let try_socket = TcpStream::connect(addr).await;
    let socket = try_socket.map_err(Error::Io)?;
    client_async_tls(request, socket).await
}
<commit_msg>Fix clippy warning about ok_or() followed by a function call<commit_after>//! Connection helper.
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;

use tungstenite::client::uri_mode;
use tungstenite::handshake::client::Response;
use tungstenite::Error;

use super::{client_async, Request, IntoClientRequest, WebSocketStream};

#[cfg(feature = "tls")]
pub(crate) mod encryption {
    use native_tls::TlsConnector;
    use tokio_tls::{TlsConnector as TokioTlsConnector, TlsStream};

    use tokio::io::{AsyncRead, AsyncWrite};

    use tungstenite::stream::Mode;
    use tungstenite::Error;

    use crate::stream::Stream as StreamSwitcher;

    /// A stream that might be protected with TLS.
    pub type MaybeTlsStream<S> = StreamSwitcher<S, TlsStream<S>>;

    pub type AutoStream<S> = MaybeTlsStream<S>;

    pub async fn wrap_stream<S>(
        socket: S,
        domain: String,
        mode: Mode,
    ) -> Result<AutoStream<S>, Error>
    where
        S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    {
        match mode {
            Mode::Plain => Ok(StreamSwitcher::Plain(socket)),
            Mode::Tls => {
                let try_connector = TlsConnector::new();
                let connector = try_connector.map_err(Error::Tls)?;
                let stream = TokioTlsConnector::from(connector);
                let connected = stream.connect(&domain, socket).await;
                match connected {
                    Err(e) => Err(Error::Tls(e)),
                    Ok(s) => Ok(StreamSwitcher::Tls(s)),
                }
            }
        }
    }
}

#[cfg(feature = "tls")]
pub use self::encryption::MaybeTlsStream;

#[cfg(not(feature = "tls"))]
pub(crate) mod encryption {
    use tokio::io::{AsyncRead, AsyncWrite};

    use tungstenite::stream::Mode;
    use tungstenite::Error;

    pub type AutoStream<S> = S;

    pub async fn wrap_stream<S>(
        socket: S,
        _domain: String,
        mode: Mode,
    ) -> Result<AutoStream<S>, Error>
    where
        S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    {
        match mode {
            Mode::Plain => Ok(socket),
            Mode::Tls => Err(Error::Url("TLS support not compiled in.".into())),
        }
    }
}

use self::encryption::{wrap_stream, AutoStream};

/// Get a domain from an URL.
#[inline]
fn domain(request: &Request) -> Result<String, Error> {
    match request.uri().host() {
        Some(d) => Ok(d.to_string()),
        None => Err(Error::Url("no host name in the url".into())),
    }
}

/// Creates a WebSocket handshake from a request and a stream,
/// upgrading the stream to TLS if required.
pub async fn client_async_tls<R, S>(
    request: R,
    stream: S,
) -> Result<(WebSocketStream<AutoStream<S>>, Response), Error>
where
    R: IntoClientRequest + Unpin,
    S: 'static + AsyncRead + AsyncWrite + Send + Unpin,
    AutoStream<S>: Unpin,
{
    let request = request.into_client_request()?;

    let domain = domain(&request)?;

    // Make sure we check domain and mode first. URL must be valid.
    let mode = uri_mode(&request.uri())?;

    let stream = wrap_stream(stream, domain, mode).await?;
    client_async(request, stream).await
}

/// Connect to a given URL.
pub async fn connect_async<R>(
    request: R,
) -> Result<(WebSocketStream<AutoStream<TcpStream>>, Response), Error>
where
    R: IntoClientRequest + Unpin,
{
    let request = request.into_client_request()?;

    let domain = domain(&request)?;
    let port = request
        .uri()
        .port_u16()
        .or_else(|| {
            match request.uri().scheme_str() {
                Some("wss") => Some(443),
                Some("ws") => Some(80),
                _ => None
            }
        })
        .ok_or_else(|| Error::Url("Url scheme not supported".into()))?;

    let addr = format!("{}:{}", domain, port);
    let try_socket = TcpStream::connect(addr).await;
    let socket = try_socket.map_err(Error::Io)?;
    client_async_tls(request, socket).await
}
<|endoftext|>


<commit_before>pub struct Context;

impl Context {
    pub unsafe fn current_context() -> Self {
        Context
    }
}
<commit_msg>Add `Context.clear` and `clear_color`<commit_after>use super::gl;

pub struct Context;

impl Context {
    pub unsafe fn current_context() -> Self {
        Context
    }

    pub fn clear_color(&mut self, color: super::Color) {
        unsafe {
            gl::ClearColor(color.r, color.g, color.b, color.a);
        }
    }

    pub fn clear(&mut self, buffers: super::BufferBits) {
        unsafe {
            gl::Clear(buffers.bits())
        }
    }
}
<|endoftext|>


<commit_before>use ffi;
use types::{Result, PortMidiDeviceId, Error};
use io::{InputPort, OutputPort};
use device::DeviceInfo;

/// The PortMidi base struct.
/// Initializes PortMidi on creation and terminates it on drop.
pub struct PortMidi {
    device_cnt: i32,
    buffer_size: usize,
}
impl PortMidi {
    /// Initializes the underlying PortMidi C library.
    /// PortMidi does not support *hot plugging*, this means
    /// that devices that are connect after calling `new`
    /// are not picked up by PortMidi.
    pub fn new(buffer_size: usize) -> Result<Self> {
        try!(Result::from(unsafe { ffi::Pm_Initialize() }));

        Ok(PortMidi {
            device_cnt: unsafe { ffi::Pm_CountDevices() },
            buffer_size: buffer_size,
        })
    }

    /// Return the number of devices. This number will not change during the lifetime
    /// of the program.
    pub fn device_cnt(&self) -> PortMidiDeviceId {
        self.device_cnt
    }

    /// Returns the `PortMidiDeviceId` for the default input device, or an `Error::NoDefaultDevice` if
    /// there is no available.
    pub fn default_input_device_id(&self) -> Result<PortMidiDeviceId> {
        match unsafe { ffi::Pm_GetDefaultInputDeviceID() } {
            ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
            id @ _ => Ok(id),
        }
    }

    /// Returns the `PortMidiDeviceId` for the default output device, or an `Error::NoDefaultDevice` if
    /// there is no available.
    pub fn default_output_device_id(&self) -> Result<PortMidiDeviceId> {
        match unsafe { ffi::Pm_GetDefaultOutputDeviceID() } {
            ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
            id @ _ => Ok(id),
        }
    }

    /// Returns the `DeviceInfo` for the given device id or an `Error::PortMidi(_)` if
    /// the given id is invalid.
    pub fn device(&self, id: PortMidiDeviceId) -> Result<DeviceInfo> {
        DeviceInfo::new(id)
    }

    /// Returns a `Vec<DeviceInfo>` containing all known device infos.
    /// An `Error::PortMidi(_)` is returned if the info for a device can't be obtained.
    pub fn devices(&self) -> Result<Vec<DeviceInfo>> {
        let mut devices = Vec::with_capacity(self.device_cnt() as usize);
        for res in (0..self.device_cnt()).map(|id| self.device(id)) {
            match res {
                Ok(device) => devices.push(device),
                Err(err) => return Err(err),
            }
        }
        Ok(devices)
    }

    pub fn default_input_port(&self) -> Result<InputPort> {
        let info = try!(self.default_input_device_id().and_then(|id| self.device(id)));
        InputPort::new(info, self.buffer_size)
    }

    pub fn input_port(&self, device: DeviceInfo) -> Result<InputPort> {
        if device.is_input() {
            InputPort::new(device, self.buffer_size)
        } else {
            Err(Error::NotAnInputDevice)
        }
    }

    pub fn default_output_port(&self) -> Result<OutputPort> {
        let info = try!(self.default_output_device_id().and_then(|id| self.device(id)));
        OutputPort::new(info, self.buffer_size)
    }

    pub fn output_port(&self, device: DeviceInfo) -> Result<InputPort> {
        if device.is_output() {
            InputPort::new(device, self.buffer_size)
        } else {
            Err(Error::NotAnOutputDevice)
        }
    }
}
impl Drop for PortMidi {
    fn drop(&mut self) {
        Result::from(unsafe { ffi::Pm_Terminate() })
            .map_err(|err| println!("Could not terminate: {}", err));
    }
}
<commit_msg>Remove `buffer_size` from context and use `u32` for `device_count`<commit_after>use ffi;
use std::os::raw::c_int;
use types::{Result, PortMidiDeviceId, Error};
use io::{InputPort, OutputPort};
use device::DeviceInfo;

/// The PortMidi base struct.
/// Initializes PortMidi on creation and terminates it on drop.
pub struct PortMidi {
    device_cnt: u32,
}
impl PortMidi {
    /// Initializes the underlying PortMidi C library.
    /// PortMidi does not support *hot plugging*, this means
    /// that devices that are connect after calling `new`
    /// are not picked up.
    pub fn new() -> Result<Self> {
        try!(Result::from(unsafe { ffi::Pm_Initialize() }));
        let device_cnt = unsafe { ffi::Pm_CountDevices() };
        if device_cnt >= 0 {
            Ok(PortMidi { device_cnt: device_cnt as u32 })
        } else {
            Err(Error::Invalid)
        }
    }

    /// Return the number of devices. This number will not change during the lifetime
    /// of the program.
    pub fn device_cnt(&self) -> PortMidiDeviceId {
        self.device_cnt as c_int
    }

    /// Returns the `PortMidiDeviceId` for the default input device, or an `Error::NoDefaultDevice` if
    /// there is no available.
    pub fn default_input_device_id(&self) -> Result<PortMidiDeviceId> {
        match unsafe { ffi::Pm_GetDefaultInputDeviceID() } {
            ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
            id @ _ => Ok(id),
        }
    }

    /// Returns the `PortMidiDeviceId` for the default output device, or an `Error::NoDefaultDevice` if
    /// there is no available.
    pub fn default_output_device_id(&self) -> Result<PortMidiDeviceId> {
        match unsafe { ffi::Pm_GetDefaultOutputDeviceID() } {
            ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
            id @ _ => Ok(id),
        }
    }

    /// Returns the `DeviceInfo` for the given device id or an `Error::PortMidi(_)` if
    /// the given id is invalid.
    pub fn device(&self, id: PortMidiDeviceId) -> Result<DeviceInfo> {
        DeviceInfo::new(id)
    }

    /// Returns a `Vec<DeviceInfo>` containing all known device infos.
    /// An `Error::PortMidi(_)` is returned if the info for a device can't be obtained.
    pub fn devices(&self) -> Result<Vec<DeviceInfo>> {
        let mut devices = Vec::with_capacity(self.device_cnt() as usize);
        for res in (0..self.device_cnt()).map(|id| self.device(id)) {
            match res {
                Ok(device) => devices.push(device),
                Err(err) => return Err(err),
            }
        }
        Ok(devices)
    }

    /// Creates an `InputPort` instance with the given buffer size for the default input device.
    pub fn default_input_port(&self, buffer_size: usize) -> Result<InputPort> {
        let info = try!(self.default_input_device_id().and_then(|id| self.device(id)));
        InputPort::new(info, buffer_size)
    }

    /// Creates an `InputPort` instance for the given device and buffer size.
    /// If the given device is not an input device an `Error::NotAnInputDevice` is returned.
    pub fn input_port(&self, device: DeviceInfo, buffer_size: usize) -> Result<InputPort> {
        if device.is_input() {
            InputPort::new(device, buffer_size)
        } else {
            Err(Error::NotAnInputDevice)
        }
    }

    /// Creates an `OutputPort` instance with the given buffer size for the default output device.
    pub fn default_output_port(&self, buffer_size: usize) -> Result<OutputPort> {
        let info = try!(self.default_output_device_id().and_then(|id| self.device(id)));
        OutputPort::new(info, buffer_size)
    }

    /// Creates an `OutputPort` instance for the given device and buffer size.
    /// If the given device is not an output device an `Error::NotAnOutputDevice` is returned.
    pub fn output_port(&self, device: DeviceInfo, buffer_size: usize) -> Result<OutputPort> {
        if device.is_output() {
            OutputPort::new(device, buffer_size)
        } else {
            Err(Error::NotAnOutputDevice)
        }
    }
}
impl Drop for PortMidi {
    fn drop(&mut self) {
        Result::from(unsafe { ffi::Pm_Terminate() })
            .map_err(|err| println!("Could not terminate: {}", err));
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, edef <edef@edef.eu>
// See the LICENSE file included in this distribution.
use core::prelude::*;
use core::marker::PhantomData;
use arch::Registers;
use stack;
use debug::StackId;

pub struct Context<'a, Stack: stack::Stack> {
  regs: Registers,
  _stack_id: StackId,
  stack: Stack,
  _ref: PhantomData<&'a ()>
}

impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
  #[inline]
  pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
    where F: FnOnce() + Send + 'a {
    let stack_id = StackId::register(&mut stack);
    let regs = Registers::new(&mut stack, f);
    Context {
      regs: regs,
      _stack_id: stack_id,
      stack: stack,
      _ref: PhantomData
    }
  }

  #[inline(always)]
  pub unsafe fn swap(&mut self) {
    self.regs.swap()
  }

  pub unsafe fn destroy(self) -> Stack {
    self.stack
  }
}
<commit_msg>make Context::destroy inlineable<commit_after>// Copyright (c) 2015, edef <edef@edef.eu>
// See the LICENSE file included in this distribution.
use core::prelude::*;
use core::marker::PhantomData;
use arch::Registers;
use stack;
use debug::StackId;

pub struct Context<'a, Stack: stack::Stack> {
  regs: Registers,
  _stack_id: StackId,
  stack: Stack,
  _ref: PhantomData<&'a ()>
}

impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
  #[inline]
  pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
    where F: FnOnce() + Send + 'a {
    let stack_id = StackId::register(&mut stack);
    let regs = Registers::new(&mut stack, f);
    Context {
      regs: regs,
      _stack_id: stack_id,
      stack: stack,
      _ref: PhantomData
    }
  }

  #[inline(always)]
  pub unsafe fn swap(&mut self) {
    self.regs.swap()
  }

  #[inline]
  pub unsafe fn destroy(self) -> Stack {
    self.stack
  }
}
<|endoftext|>


<commit_before>use std::io::{Write, Result as IoResult};
use {Color, Mode};

/// Controlling terminals.
pub trait TermControl {

    /// Print the CSI (control sequence introducer) followed by a byte string.
    fn csi(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Print OSC (operating system command) followed by a byte string.
    fn osc(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Print OSC (device control string) followed by a byte string.
    fn dsc(&mut self, b: &[u8]) -> IoResult<usize>;

    /// Clear the terminal.
    fn clear(&mut self) -> IoResult<usize> {
        self.csi(b"2J")
    }
    /// Show the cursor.
    fn show(&mut self) -> IoResult<usize> {
        self.csi(b"?25h")
    }
    /// Hide the cursor.
    fn hide(&mut self) -> IoResult<usize> {
        self.csi(b"?25l")
    }
    /// Reset the rendition mode.
    fn reset(&mut self) -> IoResult<usize> {
        self.csi(b"m")
    }
    /// Go to a given position.
    fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
        self.csi(&[
             (x / 10000) as u8 + b'0', (x / 1000) as u8 % 10 + b'0', (x / 100) as u8 % 10 + b'0', (x / 10) as u8 % 10 + b'0', x as u8 % 10 + b'0',
             b';',
             (y / 10000) as u8 + b'0', (y / 1000) as u8 % 10 + b'0', (y / 100) as u8 % 10 + b'0', (y / 10) as u8 % 10 + b'0', y as u8 % 10 + b'0',
             b'H',
        ])
    }
    /// Set graphic rendition.
    fn rendition(&mut self, r: u8) -> IoResult<usize> {
        self.csi(&[
             r / 100 + b'0', r / 10 % 10 + b'0', r % 10 + b'0',
             b'm',
        ])
    }
    /// Set foreground color
    fn color(&mut self, color: Color) -> IoResult<usize> {
        let ansi = color.to_ansi_val();
        self.csi(&[
            b'3',
            b'8',
            b';',
            b'5',
            b';',
            b'0' + ansi / 100,
            b'0' + ansi / 10 % 10,
            b'0' + ansi % 10,
            b'm',
        ])
    }
    /// Set background color
    fn bg_color(&mut self, color: Color) -> IoResult<usize> {
        let ansi = color.to_ansi_val();
        self.csi(&[
            b'4',
            b'8',
            b';',
            b'5',
            b';',
            b'0' + ansi / 100,
            b'0' + ansi / 10 % 10,
            b'0' + ansi % 10,
            b'm',
        ])
    }
    /// Set rendition mode (SGR).
    fn mode(&mut self, mode: Mode) -> IoResult<usize> {
        self.rendition(mode as u8)
    }
}

impl<W: Write> TermControl for W {
    fn csi(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b[").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
    fn osc(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b]").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
    fn dsc(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1bP").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
}
<commit_msg>Minor cosmetic changes<commit_after>use std::io::{Write, Result as IoResult};
use {Color, Mode};

/// Controlling terminals.
pub trait TermControl {

    /// Print the CSI (control sequence introducer) followed by a byte string.
    fn csi(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Print OSC (operating system command) followed by a byte string.
    fn osc(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Print OSC (device control string) followed by a byte string.
    fn dsc(&mut self, b: &[u8]) -> IoResult<usize>;

    /// Clear the terminal.
    fn clear(&mut self) -> IoResult<usize> {
        self.csi(b"2J")
    }
    /// Show the cursor.
    fn show(&mut self) -> IoResult<usize> {
        self.csi(b"?25h")
    }
    /// Hide the cursor.
    fn hide(&mut self) -> IoResult<usize> {
        self.csi(b"?25l")
    }
    /// Reset the rendition mode.
    fn reset(&mut self) -> IoResult<usize> {
        self.csi(b"m")
    }
    /// Go to a given position.
    fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
        self.csi(&[
            b'0' + (x / 10000) as u8,
            b'0' + (x / 1000) as u8 % 10,
            b'0' + (x / 100) as u8 % 10,
            b'0' + (x / 10) as u8 % 10,
            b'0' + x as u8 % 10,
            b';',
            b'0' + (y / 10000) as u8,
            b'0' + (y / 1000) as u8 % 10,
            b'0' + (y / 100) as u8 % 10,
            b'0' + (y / 10) as u8 % 10,
            b'0' + y as u8 % 10,
            b'H',
        ])
    }
    /// Set graphic rendition.
    fn rendition(&mut self, r: u8) -> IoResult<usize> {
        self.csi(&[
            b'0' + r / 100,
            b'0' + r / 10 % 10,
            b'0' + r % 10,
            b'm',
        ])
    }
    /// Set foreground color
    fn color(&mut self, color: Color) -> IoResult<usize> {
        let ansi = color.to_ansi_val();
        self.csi(&[
            b'3',
            b'8',
            b';',
            b'5',
            b';',
            b'0' + ansi / 100,
            b'0' + ansi / 10 % 10,
            b'0' + ansi % 10,
            b'm',
        ])
    }
    /// Set background color
    fn bg_color(&mut self, color: Color) -> IoResult<usize> {
        let ansi = color.to_ansi_val();
        self.csi(&[
            b'4',
            b'8',
            b';',
            b'5',
            b';',
            b'0' + ansi / 100,
            b'0' + ansi / 10 % 10,
            b'0' + ansi % 10,
            b'm',
        ])
    }
    /// Set rendition mode (SGR).
    fn mode(&mut self, mode: Mode) -> IoResult<usize> {
        self.rendition(mode as u8)
    }
}

impl<W: Write> TermControl for W {
    fn csi(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b[").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
    fn osc(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b]").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
    fn dsc(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1bP").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
}
<|endoftext|>


<commit_before>use ide_db::SymbolKind;
use syntax::{
    ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
    match_ast, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange,
    WalkEvent,
};

#[derive(Debug, Clone)]
pub struct StructureNode {
    pub parent: Option<usize>,
    pub label: String,
    pub navigation_range: TextRange,
    pub node_range: TextRange,
    pub kind: SymbolKind,
    pub detail: Option<String>,
    pub deprecated: bool,
}

// Feature: File Structure
//
// Provides a tree of the symbols defined in the file. Can be used to
//
// * fuzzy search symbol in a file (super useful)
// * draw breadcrumbs to describe the context around the cursor
// * draw outline of the file
//
// |===
// | Editor  | Shortcut
//
// | VS Code | kbd:[Ctrl+Shift+O]
// |===
pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
    let mut res = Vec::new();
    let mut stack = Vec::new();

    for event in file.syntax().preorder_with_tokens() {
        match event {
            WalkEvent::Enter(NodeOrToken::Node(node)) => {
                if let Some(mut symbol) = structure_node(&node) {
                    symbol.parent = stack.last().copied();
                    stack.push(res.len());
                    res.push(symbol);
                }
            }
            WalkEvent::Leave(NodeOrToken::Node(node)) => {
                if structure_node(&node).is_some() {
                    stack.pop().unwrap();
                }
            }
            WalkEvent::Enter(NodeOrToken::Token(token)) => {
                if let Some(mut symbol) = structure_token(token) {
                    symbol.parent = stack.last().copied();
                    stack.push(res.len());
                    res.push(symbol);
                }
            }
            WalkEvent::Leave(NodeOrToken::Token(token)) => {
                if structure_token(token).is_some() {
                    stack.pop().unwrap();
                }
            }
        }
    }
    res
}

fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
    fn decl<N: NameOwner + AttrsOwner>(node: N, kind: SymbolKind) -> Option<StructureNode> {
        decl_with_detail(&node, None, kind)
    }

    fn decl_with_type_ref<N: NameOwner + AttrsOwner>(
        node: &N,
        type_ref: Option<ast::Type>,
        kind: SymbolKind,
    ) -> Option<StructureNode> {
        let detail = type_ref.map(|type_ref| {
            let mut detail = String::new();
            collapse_ws(type_ref.syntax(), &mut detail);
            detail
        });
        decl_with_detail(node, detail, kind)
    }

    fn decl_with_detail<N: NameOwner + AttrsOwner>(
        node: &N,
        detail: Option<String>,
        kind: SymbolKind,
    ) -> Option<StructureNode> {
        let name = node.name()?;

        Some(StructureNode {
            parent: None,
            label: name.text().to_string(),
            navigation_range: name.syntax().text_range(),
            node_range: node.syntax().text_range(),
            kind,
            detail,
            deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
        })
    }

    fn collapse_ws(node: &SyntaxNode, output: &mut String) {
        let mut can_insert_ws = false;
        node.text().for_each_chunk(|chunk| {
            for line in chunk.lines() {
                let line = line.trim();
                if line.is_empty() {
                    if can_insert_ws {
                        output.push(' ');
                        can_insert_ws = false;
                    }
                } else {
                    output.push_str(line);
                    can_insert_ws = true;
                }
            }
        })
    }

    match_ast! {
        match node {
            ast::Fn(it) => {
                let mut detail = String::from("fn");
                if let Some(type_param_list) = it.generic_param_list() {
                    collapse_ws(type_param_list.syntax(), &mut detail);
                }
                if let Some(param_list) = it.param_list() {
                    collapse_ws(param_list.syntax(), &mut detail);
                }
                if let Some(ret_type) = it.ret_type() {
                    detail.push_str(" ");
                    collapse_ws(ret_type.syntax(), &mut detail);
                }

                decl_with_detail(&it, Some(detail), SymbolKind::Function)
            },
            ast::Struct(it) => decl(it, SymbolKind::Struct),
            ast::Union(it) => decl(it, SymbolKind::Union),
            ast::Enum(it) => decl(it, SymbolKind::Enum),
            ast::Variant(it) => decl(it, SymbolKind::Variant),
            ast::Trait(it) => decl(it, SymbolKind::Trait),
            ast::Module(it) => decl(it, SymbolKind::Module),
            ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias),
            ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field),
            ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const),
            ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static),
            ast::Impl(it) => {
                let target_type = it.self_ty()?;
                let target_trait = it.trait_();
                let label = match target_trait {
                    None => format!("impl {}", target_type.syntax().text()),
                    Some(t) => {
                        format!("impl {} for {}", t.syntax().text(), target_type.syntax().text(),)
                    }
                };

                let node = StructureNode {
                    parent: None,
                    label,
                    navigation_range: target_type.syntax().text_range(),
                    node_range: it.syntax().text_range(),
                    kind: SymbolKind::Impl,
                    detail: None,
                    deprecated: false,
                };
                Some(node)
            },
            ast::MacroRules(it) => decl(it, SymbolKind::Macro),
            _ => None,
        }
    }
}

fn structure_token(token: SyntaxToken) -> Option<StructureNode> {
    if let Some(comment) = ast::Comment::cast(token) {
        let text = comment.text().trim();

        if let Some(region_name) = text.strip_prefix("// region:").map(|text| text.trim()) {
            return Some(StructureNode {
                parent: None,
                label: region_name.to_string(),
                navigation_range: comment.syntax().text_range(),
                node_range: comment.syntax().text_range(),
                kind: SymbolKind::Region,
                detail: None,
                deprecated: false,
            });
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use super::*;

    fn check(ra_fixture: &str, expect: Expect) {
        let file = SourceFile::parse(ra_fixture).ok().unwrap();
        let structure = file_structure(&file);
        expect.assert_debug_eq(&structure)
    }

    #[test]
    fn test_file_structure() {
        check(
            r#"
struct Foo {
    x: i32
}

mod m {
    fn bar1() {}
    fn bar2<T>(t: T) -> T {}
    fn bar3<A,
        B>(a: A,
        b: B) -> Vec<
        u32
    > {}
}

enum E { X, Y(i32) }
type T = ();
static S: i32 = 92;
const C: i32 = 92;

impl E {}

impl fmt::Debug for E {}

macro_rules! mc {
    () => {}
}

#[macro_export]
macro_rules! mcexp {
    () => {}
}

/// Doc comment
macro_rules! mcexp {
    () => {}
}

#[deprecated]
fn obsolete() {}

#[deprecated(note = "for awhile")]
fn very_obsolete() {}

// region: Some region name
// endregion
"#,
            expect![[r#"
                [
                    StructureNode {
                        parent: None,
                        label: "Foo",
                        navigation_range: 8..11,
                        node_range: 1..26,
                        kind: Struct,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            0,
                        ),
                        label: "x",
                        navigation_range: 18..19,
                        node_range: 18..24,
                        kind: Field,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "m",
                        navigation_range: 32..33,
                        node_range: 28..158,
                        kind: Module,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar1",
                        navigation_range: 43..47,
                        node_range: 40..52,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar2",
                        navigation_range: 60..64,
                        node_range: 57..81,
                        kind: Function,
                        detail: Some(
                            "fn<T>(t: T) -> T",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar3",
                        navigation_range: 89..93,
                        node_range: 86..156,
                        kind: Function,
                        detail: Some(
                            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "E",
                        navigation_range: 165..166,
                        node_range: 160..180,
                        kind: Enum,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            6,
                        ),
                        label: "X",
                        navigation_range: 169..170,
                        node_range: 169..170,
                        kind: Variant,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            6,
                        ),
                        label: "Y",
                        navigation_range: 172..173,
                        node_range: 172..178,
                        kind: Variant,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "T",
                        navigation_range: 186..187,
                        node_range: 181..193,
                        kind: TypeAlias,
                        detail: Some(
                            "()",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "S",
                        navigation_range: 201..202,
                        node_range: 194..213,
                        kind: Static,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "C",
                        navigation_range: 220..221,
                        node_range: 214..232,
                        kind: Const,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "impl E",
                        navigation_range: 239..240,
                        node_range: 234..243,
                        kind: Impl,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "impl fmt::Debug for E",
                        navigation_range: 265..266,
                        node_range: 245..269,
                        kind: Impl,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mc",
                        navigation_range: 284..286,
                        node_range: 271..303,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mcexp",
                        navigation_range: 334..339,
                        node_range: 305..356,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mcexp",
                        navigation_range: 387..392,
                        node_range: 358..409,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "obsolete",
                        navigation_range: 428..436,
                        node_range: 411..441,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: true,
                    },
                    StructureNode {
                        parent: None,
                        label: "very_obsolete",
                        navigation_range: 481..494,
                        node_range: 443..499,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: true,
                    },
                    StructureNode {
                        parent: None,
                        label: "Some region name",
                        navigation_range: 501..528,
                        node_range: 501..528,
                        kind: Region,
                        detail: None,
                        deprecated: false,
                    },
                ]
            "#]],
        );
    }
}
<commit_msg>Shorten trim call<commit_after>use ide_db::SymbolKind;
use syntax::{
    ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
    match_ast, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange,
    WalkEvent,
};

#[derive(Debug, Clone)]
pub struct StructureNode {
    pub parent: Option<usize>,
    pub label: String,
    pub navigation_range: TextRange,
    pub node_range: TextRange,
    pub kind: SymbolKind,
    pub detail: Option<String>,
    pub deprecated: bool,
}

// Feature: File Structure
//
// Provides a tree of the symbols defined in the file. Can be used to
//
// * fuzzy search symbol in a file (super useful)
// * draw breadcrumbs to describe the context around the cursor
// * draw outline of the file
//
// |===
// | Editor  | Shortcut
//
// | VS Code | kbd:[Ctrl+Shift+O]
// |===
pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
    let mut res = Vec::new();
    let mut stack = Vec::new();

    for event in file.syntax().preorder_with_tokens() {
        match event {
            WalkEvent::Enter(NodeOrToken::Node(node)) => {
                if let Some(mut symbol) = structure_node(&node) {
                    symbol.parent = stack.last().copied();
                    stack.push(res.len());
                    res.push(symbol);
                }
            }
            WalkEvent::Leave(NodeOrToken::Node(node)) => {
                if structure_node(&node).is_some() {
                    stack.pop().unwrap();
                }
            }
            WalkEvent::Enter(NodeOrToken::Token(token)) => {
                if let Some(mut symbol) = structure_token(token) {
                    symbol.parent = stack.last().copied();
                    stack.push(res.len());
                    res.push(symbol);
                }
            }
            WalkEvent::Leave(NodeOrToken::Token(token)) => {
                if structure_token(token).is_some() {
                    stack.pop().unwrap();
                }
            }
        }
    }
    res
}

fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
    fn decl<N: NameOwner + AttrsOwner>(node: N, kind: SymbolKind) -> Option<StructureNode> {
        decl_with_detail(&node, None, kind)
    }

    fn decl_with_type_ref<N: NameOwner + AttrsOwner>(
        node: &N,
        type_ref: Option<ast::Type>,
        kind: SymbolKind,
    ) -> Option<StructureNode> {
        let detail = type_ref.map(|type_ref| {
            let mut detail = String::new();
            collapse_ws(type_ref.syntax(), &mut detail);
            detail
        });
        decl_with_detail(node, detail, kind)
    }

    fn decl_with_detail<N: NameOwner + AttrsOwner>(
        node: &N,
        detail: Option<String>,
        kind: SymbolKind,
    ) -> Option<StructureNode> {
        let name = node.name()?;

        Some(StructureNode {
            parent: None,
            label: name.text().to_string(),
            navigation_range: name.syntax().text_range(),
            node_range: node.syntax().text_range(),
            kind,
            detail,
            deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
        })
    }

    fn collapse_ws(node: &SyntaxNode, output: &mut String) {
        let mut can_insert_ws = false;
        node.text().for_each_chunk(|chunk| {
            for line in chunk.lines() {
                let line = line.trim();
                if line.is_empty() {
                    if can_insert_ws {
                        output.push(' ');
                        can_insert_ws = false;
                    }
                } else {
                    output.push_str(line);
                    can_insert_ws = true;
                }
            }
        })
    }

    match_ast! {
        match node {
            ast::Fn(it) => {
                let mut detail = String::from("fn");
                if let Some(type_param_list) = it.generic_param_list() {
                    collapse_ws(type_param_list.syntax(), &mut detail);
                }
                if let Some(param_list) = it.param_list() {
                    collapse_ws(param_list.syntax(), &mut detail);
                }
                if let Some(ret_type) = it.ret_type() {
                    detail.push_str(" ");
                    collapse_ws(ret_type.syntax(), &mut detail);
                }

                decl_with_detail(&it, Some(detail), SymbolKind::Function)
            },
            ast::Struct(it) => decl(it, SymbolKind::Struct),
            ast::Union(it) => decl(it, SymbolKind::Union),
            ast::Enum(it) => decl(it, SymbolKind::Enum),
            ast::Variant(it) => decl(it, SymbolKind::Variant),
            ast::Trait(it) => decl(it, SymbolKind::Trait),
            ast::Module(it) => decl(it, SymbolKind::Module),
            ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias),
            ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field),
            ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const),
            ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static),
            ast::Impl(it) => {
                let target_type = it.self_ty()?;
                let target_trait = it.trait_();
                let label = match target_trait {
                    None => format!("impl {}", target_type.syntax().text()),
                    Some(t) => {
                        format!("impl {} for {}", t.syntax().text(), target_type.syntax().text(),)
                    }
                };

                let node = StructureNode {
                    parent: None,
                    label,
                    navigation_range: target_type.syntax().text_range(),
                    node_range: it.syntax().text_range(),
                    kind: SymbolKind::Impl,
                    detail: None,
                    deprecated: false,
                };
                Some(node)
            },
            ast::MacroRules(it) => decl(it, SymbolKind::Macro),
            _ => None,
        }
    }
}

fn structure_token(token: SyntaxToken) -> Option<StructureNode> {
    if let Some(comment) = ast::Comment::cast(token) {
        let text = comment.text().trim();

        if let Some(region_name) = text.strip_prefix("// region:").map(str::trim) {
            return Some(StructureNode {
                parent: None,
                label: region_name.to_string(),
                navigation_range: comment.syntax().text_range(),
                node_range: comment.syntax().text_range(),
                kind: SymbolKind::Region,
                detail: None,
                deprecated: false,
            });
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use super::*;

    fn check(ra_fixture: &str, expect: Expect) {
        let file = SourceFile::parse(ra_fixture).ok().unwrap();
        let structure = file_structure(&file);
        expect.assert_debug_eq(&structure)
    }

    #[test]
    fn test_file_structure() {
        check(
            r#"
struct Foo {
    x: i32
}

mod m {
    fn bar1() {}
    fn bar2<T>(t: T) -> T {}
    fn bar3<A,
        B>(a: A,
        b: B) -> Vec<
        u32
    > {}
}

enum E { X, Y(i32) }
type T = ();
static S: i32 = 92;
const C: i32 = 92;

impl E {}

impl fmt::Debug for E {}

macro_rules! mc {
    () => {}
}

#[macro_export]
macro_rules! mcexp {
    () => {}
}

/// Doc comment
macro_rules! mcexp {
    () => {}
}

#[deprecated]
fn obsolete() {}

#[deprecated(note = "for awhile")]
fn very_obsolete() {}

// region: Some region name
// endregion
"#,
            expect![[r#"
                [
                    StructureNode {
                        parent: None,
                        label: "Foo",
                        navigation_range: 8..11,
                        node_range: 1..26,
                        kind: Struct,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            0,
                        ),
                        label: "x",
                        navigation_range: 18..19,
                        node_range: 18..24,
                        kind: Field,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "m",
                        navigation_range: 32..33,
                        node_range: 28..158,
                        kind: Module,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar1",
                        navigation_range: 43..47,
                        node_range: 40..52,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar2",
                        navigation_range: 60..64,
                        node_range: 57..81,
                        kind: Function,
                        detail: Some(
                            "fn<T>(t: T) -> T",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            2,
                        ),
                        label: "bar3",
                        navigation_range: 89..93,
                        node_range: 86..156,
                        kind: Function,
                        detail: Some(
                            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "E",
                        navigation_range: 165..166,
                        node_range: 160..180,
                        kind: Enum,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            6,
                        ),
                        label: "X",
                        navigation_range: 169..170,
                        node_range: 169..170,
                        kind: Variant,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: Some(
                            6,
                        ),
                        label: "Y",
                        navigation_range: 172..173,
                        node_range: 172..178,
                        kind: Variant,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "T",
                        navigation_range: 186..187,
                        node_range: 181..193,
                        kind: TypeAlias,
                        detail: Some(
                            "()",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "S",
                        navigation_range: 201..202,
                        node_range: 194..213,
                        kind: Static,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "C",
                        navigation_range: 220..221,
                        node_range: 214..232,
                        kind: Const,
                        detail: Some(
                            "i32",
                        ),
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "impl E",
                        navigation_range: 239..240,
                        node_range: 234..243,
                        kind: Impl,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "impl fmt::Debug for E",
                        navigation_range: 265..266,
                        node_range: 245..269,
                        kind: Impl,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mc",
                        navigation_range: 284..286,
                        node_range: 271..303,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mcexp",
                        navigation_range: 334..339,
                        node_range: 305..356,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "mcexp",
                        navigation_range: 387..392,
                        node_range: 358..409,
                        kind: Macro,
                        detail: None,
                        deprecated: false,
                    },
                    StructureNode {
                        parent: None,
                        label: "obsolete",
                        navigation_range: 428..436,
                        node_range: 411..441,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: true,
                    },
                    StructureNode {
                        parent: None,
                        label: "very_obsolete",
                        navigation_range: 481..494,
                        node_range: 443..499,
                        kind: Function,
                        detail: Some(
                            "fn()",
                        ),
                        deprecated: true,
                    },
                    StructureNode {
                        parent: None,
                        label: "Some region name",
                        navigation_range: 501..528,
                        node_range: 501..528,
                        kind: Region,
                        detail: None,
                        deprecated: false,
                    },
                ]
            "#]],
        );
    }
}
<|endoftext|>