<commit_before>use neb::server::*;
use neb::ram::schema::*;
use neb::ram::types;
use neb::ram::types::*;
use neb::ram::cell::*;
use neb::client;
use neb::client::transaction::TxnError;
use std::thread;
use std::sync::Arc;
use env_logger;
use std::time::Duration;
use parking_lot::Mutex;

use super::*;

#[test]
pub fn general() {
    let server_addr = String::from("127.0.0.1:5400");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    client.transaction(|ref mut trans| {
        Ok(()) // empty transaction
    }).unwrap();
    let should_aborted = client.transaction(|ref mut trans| {
        trans.abort()
    });
    match should_aborted {
        Err(TxnError::Aborted) => {},
        _ => panic!("{:?}", should_aborted)
    }
    let cell_1_id = cell_1.id();
    let thread_count = 50;
    let mut threads: Vec<thread::JoinHandle<()>> = Vec::with_capacity(thread_count);
    for _ in 0..thread_count {
        let client = client.clone();
        threads.push(thread::spawn(move || {
            client.transaction(|ref mut txn| {
                let selected = txn.read_selected(&cell_1_id, &types::key_hashes(
                    &vec![String::from("score")]
                ))?.unwrap();
                let mut cell = txn.read(&cell_1_id)?.unwrap();
                let mut score = cell.data["score"].U64().unwrap();
                assert_eq!(selected.first().unwrap().U64().unwrap(), score);
                score += 1;
                let mut data = cell.data.Map().unwrap().clone();
                data.insert(&String::from("score"), Value::U64(score));
                cell.data = Value::Map(data);
                txn.update(&cell)?;
                let selected = txn.read_selected(&cell_1_id, &types::key_hashes(
                    &vec![String::from("score")]
                ))?.unwrap();
                assert_eq!(selected.first().unwrap().U64().unwrap(), score);
                Ok(())
            }).unwrap();
        }));
    }
    for handle in threads {
        handle.join();
    }
    let mut cell_1_r = client.read_cell(&cell_1.id()).unwrap().unwrap();
    assert_eq!(cell_1_r.data["score"].U64().unwrap(), thread_count as u64);
}

#[test]
pub fn multi_cell_update() {
    let server_addr = String::from("127.0.0.1:5401");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let thread_count = 100;
    let mut threads: Vec<thread::JoinHandle<()>> = Vec::with_capacity(thread_count);
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    let cell_1_id = cell_1.id();
    let mut cell_2 = cell_1.clone();
    cell_2.set_id(&Id::rand());
    client.write_cell(&cell_2).unwrap().unwrap();
    client.read_cell(&cell_2.id()).unwrap().unwrap();
    let cell_2_id = cell_2.id();
    threads = Vec::new();
    for i in 0..thread_count {
        let client = client.clone();
        threads.push(thread::spawn(move || {
            client.transaction(move |txn| {
                let mut score_1 = 0;
                let mut score_2 = 0;
                let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
                let mut cell_2 = txn.read(&cell_2_id)?.unwrap();
                score_1 = cell_1.data["score"].U64().unwrap();
                score_2 = cell_2.data["score"].U64().unwrap();
                score_1 += 1;
                score_2 += 1;
                let mut data_1 = cell_1.data.Map().unwrap().clone();
                data_1.insert(&String::from("score"), Value::U64(score_1));
                cell_1.data = Value::Map(data_1);
                let mut data_2 = cell_2.data.Map().unwrap().clone();
                data_2.insert(&String::from("score"), Value::U64(score_2));
                cell_2.data = Value::Map(data_2);
                txn.update(&cell_1)?;
                txn.update(&cell_2)?;
                assert_eq!(txn.changes, 4);
                Ok(())
            }).unwrap();
        }));
    }
    for handle in threads {
        handle.join();
    }
    let mut cell_1_r = client.read_cell(&cell_1_id).unwrap().unwrap();
    let mut cell_2_r = client.read_cell(&cell_2_id).unwrap().unwrap();
    let cell_1_score = cell_1_r.data["score"].U64().unwrap();
    let cell_2_score = cell_2_r.data["score"].U64().unwrap();
    assert_eq!(cell_1_score + cell_2_score, (thread_count * 2) as u64);
}

#[test]
pub fn write_skew() {
    let server_addr = String::from("127.0.0.1:5402");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let thread_count = 100;
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    let cell_1_id = cell_1.id();
    let client_c1 = client.clone();
    let skew_tried = Arc::new(Mutex::new(0));
    let normal_tried = Arc::new(Mutex::new(0));

    let skew_tried_c = skew_tried.clone();
    let normal_tried_c = normal_tried.clone();

    let t1 = thread::spawn(move || {
        client_c1.transaction(|ref mut txn| {
            *skew_tried_c.lock() += 1;
            let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
            let mut score_1 = cell_1.data["score"].U64().unwrap();
            thread::sleep(Duration::new(5, 0)); // wait 5 secs to let late write occur
            score_1 += 1;
            let mut data_1 = cell_1.data.Map().unwrap().clone();
            data_1.insert(&String::from("score"), Value::U64(score_1));
            cell_1.data = Value::Map(data_1);
            txn.update(&cell_1)?;
            Ok(())
        });
    });
    let client_c2 = client.clone();
    let t2 = thread::spawn(move || {
        client_c2.transaction(|ref mut txn| {
            thread::sleep(Duration::new(1, 0));
            *normal_tried_c.lock() += 1;
            let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
            let mut score_1 = cell_1.data["score"].U64().unwrap();
            score_1 += 1;
            let mut data_1 = cell_1.data.Map().unwrap().clone();
            data_1.insert(&String::from("score"), Value::U64(score_1));
            cell_1.data = Value::Map(data_1);
            txn.update(&cell_1)?;
            Ok(())
        });
    });
    t2.join();
    t1.join();
    let mut cell_1_r = client.read_cell(&cell_1_id).unwrap().unwrap();
    let cell_1_score = cell_1_r.data["score"].U64().unwrap();
    assert_eq!(cell_1_score, 2);
//    assert_eq!(*skew_tried.lock(), 2);
//    assert_eq!(*normal_tried.lock(), 1);
    println!("Skew tried {}, normal tried {}", *skew_tried.lock(), *normal_tried.lock());
}<commit_msg>define simple test for #5<commit_after>use neb::server::*;
use neb::ram::schema::*;
use neb::ram::types;
use neb::ram::types::*;
use neb::ram::cell::*;
use neb::client;
use neb::client::transaction::TxnError;
use std::thread;
use std::sync::Arc;
use env_logger;
use std::time::Duration;
use parking_lot::Mutex;

use super::*;

#[test]
pub fn general() {
    let server_addr = String::from("127.0.0.1:5400");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    client.transaction(|ref mut trans| {
        Ok(()) // empty transaction
    }).unwrap();
    let should_aborted = client.transaction(|ref mut trans| {
        trans.abort()
    });
    match should_aborted {
        Err(TxnError::Aborted) => {},
        _ => panic!("{:?}", should_aborted)
    }
    let cell_1_id = cell_1.id();
    let thread_count = 50;
    let mut threads: Vec<thread::JoinHandle<()>> = Vec::with_capacity(thread_count);
    for _ in 0..thread_count {
        let client = client.clone();
        threads.push(thread::spawn(move || {
            client.transaction(|ref mut txn| {
                let selected = txn.read_selected(&cell_1_id, &types::key_hashes(
                    &vec![String::from("score")]
                ))?.unwrap();
                let mut cell = txn.read(&cell_1_id)?.unwrap();
                let mut score = cell.data["score"].U64().unwrap();
                assert_eq!(selected.first().unwrap().U64().unwrap(), score);
                score += 1;
                let mut data = cell.data.Map().unwrap().clone();
                data.insert(&String::from("score"), Value::U64(score));
                cell.data = Value::Map(data);
                txn.update(&cell)?;
                let selected = txn.read_selected(&cell_1_id, &types::key_hashes(
                    &vec![String::from("score")]
                ))?.unwrap();
                assert_eq!(selected.first().unwrap().U64().unwrap(), score);
                Ok(())
            }).unwrap();
        }));
    }
    for handle in threads {
        handle.join();
    }
    let mut cell_1_r = client.read_cell(&cell_1.id()).unwrap().unwrap();
    assert_eq!(cell_1_r.data["score"].U64().unwrap(), thread_count as u64);
}

#[test]
pub fn multi_cell_update() {
    let server_addr = String::from("127.0.0.1:5401");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let thread_count = 100;
    let mut threads: Vec<thread::JoinHandle<()>> = Vec::with_capacity(thread_count);
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    let cell_1_id = cell_1.id();
    let mut cell_2 = cell_1.clone();
    cell_2.set_id(&Id::rand());
    client.write_cell(&cell_2).unwrap().unwrap();
    client.read_cell(&cell_2.id()).unwrap().unwrap();
    let cell_2_id = cell_2.id();
    threads = Vec::new();
    for i in 0..thread_count {
        let client = client.clone();
        threads.push(thread::spawn(move || {
            client.transaction(move |txn| {
                let mut score_1 = 0;
                let mut score_2 = 0;
                let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
                let mut cell_2 = txn.read(&cell_2_id)?.unwrap();
                score_1 = cell_1.data["score"].U64().unwrap();
                score_2 = cell_2.data["score"].U64().unwrap();
                score_1 += 1;
                score_2 += 1;
                let mut data_1 = cell_1.data.Map().unwrap().clone();
                data_1.insert(&String::from("score"), Value::U64(score_1));
                cell_1.data = Value::Map(data_1);
                let mut data_2 = cell_2.data.Map().unwrap().clone();
                data_2.insert(&String::from("score"), Value::U64(score_2));
                cell_2.data = Value::Map(data_2);
                txn.update(&cell_1)?;
                txn.update(&cell_2)?;
                assert_eq!(txn.changes, 4);
                Ok(())
            }).unwrap();
        }));
    }
    for handle in threads {
        handle.join();
    }
    let mut cell_1_r = client.read_cell(&cell_1_id).unwrap().unwrap();
    let mut cell_2_r = client.read_cell(&cell_2_id).unwrap().unwrap();
    let cell_1_score = cell_1_r.data["score"].U64().unwrap();
    let cell_2_score = cell_2_r.data["score"].U64().unwrap();
    assert_eq!(cell_1_score + cell_2_score, (thread_count * 2) as u64);
}

#[test]
pub fn write_skew() {
    let server_addr = String::from("127.0.0.1:5402");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let mut schema = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let client = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let thread_count = 100;
    client.new_schema(&mut schema).unwrap();
    let mut data_map = Map::new();
    data_map.insert(&String::from("id"), Value::I64(100));
    data_map.insert(&String::from("score"), Value::U64(0));
    data_map.insert(&String::from("name"), Value::String(String::from("Jack")));
    let cell_1 = Cell::new_with_id(schema.id, &Id::rand(), Value::Map(data_map.clone()));
    client.write_cell(&cell_1).unwrap().unwrap();
    client.read_cell(&cell_1.id()).unwrap().unwrap();
    let cell_1_id = cell_1.id();
    let client_c1 = client.clone();
    let skew_tried = Arc::new(Mutex::new(0));
    let normal_tried = Arc::new(Mutex::new(0));

    let skew_tried_c = skew_tried.clone();
    let normal_tried_c = normal_tried.clone();

    let t1 = thread::spawn(move || {
        client_c1.transaction(|ref mut txn| {
            *skew_tried_c.lock() += 1;
            let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
            let mut score_1 = cell_1.data["score"].U64().unwrap();
            thread::sleep(Duration::new(5, 0)); // wait 5 secs to let late write occur
            score_1 += 1;
            let mut data_1 = cell_1.data.Map().unwrap().clone();
            data_1.insert(&String::from("score"), Value::U64(score_1));
            cell_1.data = Value::Map(data_1);
            txn.update(&cell_1)?;
            Ok(())
        });
    });
    let client_c2 = client.clone();
    let t2 = thread::spawn(move || {
        client_c2.transaction(|ref mut txn| {
            thread::sleep(Duration::new(1, 0));
            *normal_tried_c.lock() += 1;
            let mut cell_1 = txn.read(&cell_1_id)?.unwrap();
            let mut score_1 = cell_1.data["score"].U64().unwrap();
            score_1 += 1;
            let mut data_1 = cell_1.data.Map().unwrap().clone();
            data_1.insert(&String::from("score"), Value::U64(score_1));
            cell_1.data = Value::Map(data_1);
            txn.update(&cell_1)?;
            Ok(())
        });
    });
    t2.join();
    t1.join();
    let mut cell_1_r = client.read_cell(&cell_1_id).unwrap().unwrap();
    let cell_1_score = cell_1_r.data["score"].U64().unwrap();
    assert_eq!(cell_1_score, 2);
//    assert_eq!(*skew_tried.lock(), 2);
//    assert_eq!(*normal_tried.lock(), 1);
    println!("Skew tried {}, normal tried {}", *skew_tried.lock(), *normal_tried.lock());
}

#[test]
pub fn server_isolation() {
    let server_addr = String::from("127.0.0.1:5403");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let client1 = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let server_addr = String::from("127.0.0.1:5404");
    let server = NebServer::new(&ServerOptions {
        chunk_count: 1,
        memory_size: 16 * 1024 * 1024,
        standalone: false,
        is_meta: true,
        meta_members: vec!(server_addr.clone()),
        address: server_addr.clone(),
        backup_storage: None,
        meta_storage: None,
        group_name: String::from("test"),
    }).unwrap();
    let client2 = Arc::new(client::Client::new(
        &server.rpc, &vec!(server_addr),
        &String::from("test")).unwrap());
    let mut schema1 = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: default_fields(),
        is_dynamic: false
    };
    let mut schema2 = Schema {
        id: 1,
        name: String::from("test"),
        key_field: None,
        str_key_field: None,
        fields: Field::new (&String::from("*"), 0, false, false, Some(
            vec![
                Field::new(&String::from("-id"), 6, false, false, None),
                Field::new(&String::from("-name"), 20, false, false, None),
                Field::new(&String::from("-score"), 10, false, false, None),
            ]
        )),
        is_dynamic: false
    };
    client1.new_schema_with_id(&schema1).unwrap();
    client2.new_schema_with_id(&schema2).unwrap();
}<|endoftext|>


<commit_before>#![feature(rustc_private)]

extern crate clippy_lints;
extern crate rustc;
extern crate rustc_const_eval;
extern crate rustc_const_math;
extern crate syntax;

use clippy_lints::consts::{constant_simple, Constant, FloatWidth};
use rustc_const_math::ConstInt;
use rustc::hir::*;
use syntax::ast::{LitIntType, LitKind, NodeId, StrStyle};
use syntax::codemap::{Spanned, COMMAND_LINE_SP};
use syntax::symbol::Symbol;
use syntax::ptr::P;
use syntax::util::ThinVec;

fn spanned<T>(t: T) -> Spanned<T> {
    Spanned {
        node: t,
        span: COMMAND_LINE_SP,
    }
}

fn expr(n: Expr_) -> Expr {
    Expr {
        id: NodeId::new(1),
        node: n,
        span: COMMAND_LINE_SP,
        attrs: ThinVec::new(),
    }
}

fn lit(l: LitKind) -> Expr {
    expr(ExprLit(P(spanned(l))))
}

fn binop(op: BinOp_, l: Expr, r: Expr) -> Expr {
    expr(ExprBinary(spanned(op), P(l), P(r)))
}

fn check(expect: Constant, expr: &Expr) {
    assert_eq!(Some(expect), constant_simple(expr))
}

const TRUE: Constant = Constant::Bool(true);
const FALSE: Constant = Constant::Bool(false);
const ZERO: Constant = Constant::Int(ConstInt::Infer(0));
const ONE: Constant = Constant::Int(ConstInt::Infer(1));
const TWO: Constant = Constant::Int(ConstInt::Infer(2));

#[test]
fn test_lit() {
    check(TRUE, &lit(LitKind::Bool(true)));
    check(FALSE, &lit(LitKind::Bool(false)));
    check(ZERO, &lit(LitKind::Int(0, LitIntType::Unsuffixed)));
    check(Constant::Str("cool!".into(), StrStyle::Cooked),
          &lit(LitKind::Str(Symbol::intern("cool!"), StrStyle::Cooked)));
}

#[test]
fn test_ops() {
    check(TRUE, &binop(BiOr, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));
    check(FALSE, &binop(BiAnd, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));

    let litzero = lit(LitKind::Int(0, LitIntType::Unsuffixed));
    let litone = lit(LitKind::Int(1, LitIntType::Unsuffixed));
    check(TRUE, &binop(BiEq, litzero.clone(), litzero.clone()));
    check(TRUE, &binop(BiGe, litzero.clone(), litzero.clone()));
    check(TRUE, &binop(BiLe, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiNe, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiGt, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiLt, litzero.clone(), litzero.clone()));

    check(ZERO, &binop(BiAdd, litzero.clone(), litzero.clone()));
    check(TWO, &binop(BiAdd, litone.clone(), litone.clone()));
    check(ONE, &binop(BiSub, litone.clone(), litzero.clone()));
    check(ONE, &binop(BiMul, litone.clone(), litone.clone()));
    check(ONE, &binop(BiDiv, litone.clone(), litone.clone()));

    let half_any = Constant::Float("0.5".into(), FloatWidth::Any);
    let half32 = Constant::Float("0.5".into(), FloatWidth::F32);
    let half64 = Constant::Float("0.5".into(), FloatWidth::F64);
    let pos_zero = Constant::Float("0.0".into(), FloatWidth::F64);
    let neg_zero = Constant::Float("-0.0".into(), FloatWidth::F64);

    assert_eq!(pos_zero, pos_zero);
    assert_eq!(neg_zero, neg_zero);
    assert_eq!(None, pos_zero.partial_cmp(&neg_zero));

    assert_eq!(half_any, half32);
    assert_eq!(half_any, half64);
    assert_eq!(half32, half64) // for transitivity

    assert_eq!(Constant::Int(ConstInt::Infer(0)), Constant::Int(ConstInt::U8(0)));
    assert_eq!(Constant::Int(ConstInt::Infer(0)), Constant::Int(ConstInt::I8(0)));
    assert_eq!(Constant::Int(ConstInt::InferSigned(-1)), Constant::Int(ConstInt::I8(-1)));
}
<commit_msg>fix build<commit_after>#![feature(rustc_private)]

extern crate clippy_lints;
extern crate rustc;
extern crate rustc_const_eval;
extern crate rustc_const_math;
extern crate syntax;

use clippy_lints::consts::{constant_simple, Constant, FloatWidth};
use rustc_const_math::ConstInt;
use rustc::hir::*;
use syntax::ast::{LitIntType, LitKind, NodeId, StrStyle};
use syntax::codemap::{Spanned, COMMAND_LINE_SP};
use syntax::symbol::Symbol;
use syntax::ptr::P;
use syntax::util::ThinVec;

fn spanned<T>(t: T) -> Spanned<T> {
    Spanned {
        node: t,
        span: COMMAND_LINE_SP,
    }
}

fn expr(n: Expr_) -> Expr {
    Expr {
        id: NodeId::new(1),
        node: n,
        span: COMMAND_LINE_SP,
        attrs: ThinVec::new(),
    }
}

fn lit(l: LitKind) -> Expr {
    expr(ExprLit(P(spanned(l))))
}

fn binop(op: BinOp_, l: Expr, r: Expr) -> Expr {
    expr(ExprBinary(spanned(op), P(l), P(r)))
}

fn check(expect: Constant, expr: &Expr) {
    assert_eq!(Some(expect), constant_simple(expr))
}

const TRUE: Constant = Constant::Bool(true);
const FALSE: Constant = Constant::Bool(false);
const ZERO: Constant = Constant::Int(ConstInt::Infer(0));
const ONE: Constant = Constant::Int(ConstInt::Infer(1));
const TWO: Constant = Constant::Int(ConstInt::Infer(2));

#[test]
fn test_lit() {
    check(TRUE, &lit(LitKind::Bool(true)));
    check(FALSE, &lit(LitKind::Bool(false)));
    check(ZERO, &lit(LitKind::Int(0, LitIntType::Unsuffixed)));
    check(Constant::Str("cool!".into(), StrStyle::Cooked),
          &lit(LitKind::Str(Symbol::intern("cool!"), StrStyle::Cooked)));
}

#[test]
fn test_ops() {
    check(TRUE, &binop(BiOr, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));
    check(FALSE, &binop(BiAnd, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));

    let litzero = lit(LitKind::Int(0, LitIntType::Unsuffixed));
    let litone = lit(LitKind::Int(1, LitIntType::Unsuffixed));
    check(TRUE, &binop(BiEq, litzero.clone(), litzero.clone()));
    check(TRUE, &binop(BiGe, litzero.clone(), litzero.clone()));
    check(TRUE, &binop(BiLe, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiNe, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiGt, litzero.clone(), litzero.clone()));
    check(FALSE, &binop(BiLt, litzero.clone(), litzero.clone()));

    check(ZERO, &binop(BiAdd, litzero.clone(), litzero.clone()));
    check(TWO, &binop(BiAdd, litone.clone(), litone.clone()));
    check(ONE, &binop(BiSub, litone.clone(), litzero.clone()));
    check(ONE, &binop(BiMul, litone.clone(), litone.clone()));
    check(ONE, &binop(BiDiv, litone.clone(), litone.clone()));

    let half_any = Constant::Float("0.5".into(), FloatWidth::Any);
    let half32 = Constant::Float("0.5".into(), FloatWidth::F32);
    let half64 = Constant::Float("0.5".into(), FloatWidth::F64);
    let pos_zero = Constant::Float("0.0".into(), FloatWidth::F64);
    let neg_zero = Constant::Float("-0.0".into(), FloatWidth::F64);

    assert_eq!(pos_zero, pos_zero);
    assert_eq!(neg_zero, neg_zero);
    assert_eq!(None, pos_zero.partial_cmp(&neg_zero));

    assert_eq!(half_any, half32);
    assert_eq!(half_any, half64);
    assert_eq!(half32, half64); // for transitivity

    assert_eq!(Constant::Int(ConstInt::Infer(0)), Constant::Int(ConstInt::U8(0)));
    assert_eq!(Constant::Int(ConstInt::Infer(0)), Constant::Int(ConstInt::I8(0)));
    assert_eq!(Constant::Int(ConstInt::InferSigned(-1)), Constant::Int(ConstInt::I8(-1)));
}
<|endoftext|>


<commit_before>#[macro_escape];

pub macro_rules! wxApp(
    ($f: ident) => (
        fn start(argc: int, argv: **u8) -> int {
            #[start];

            use std::libc::c_void;
            use std::rt::start_on_main_thread;
            use std::vec;

            use wx::base::wxClosure;
            use wx::core::ELJApp;

            static nullptr: *mut c_void = 0 as *mut c_void;

            fn on_main() {
                #[fixed_stack_segment];
                #[inline(never)];
                let closure = wxClosure::new($f as *mut c_void, nullptr);
                let args: ~[*i32] = ~[];
                ELJApp::initializeC(closure, args.len() as i32, vec::raw::to_ptr(args) as *mut *mut i8);
            }
            start_on_main_thread(argc, argv, on_main)
        }
    )
)
<commit_msg>Try to fix build.<commit_after>#[macro_escape];

pub macro_rules! wxApp(
    ($f: ident) => (
        fn start(argc: int, argv: **u8) -> int {
            #[start];

            use std::libc::c_void;
            use std::rt::start_on_main_thread;
            use std::vec;

            use wx::base::wxClosure;
            use wx::core::ELJApp;

            static nullptr: *mut c_void = 0 as *mut c_void;

            fn on_main() {
                #[fixed_stack_segment];
                #[inline(never)];
                let closure = wxClosure::new($f as *mut c_void, nullptr);
                let args: ~[*i32] = ~[];
                ELJApp::initializeC(closure, args.len() as i32, args.as_ptr() as *mut *mut i8);
            }
            start_on_main_thread(argc, argv, on_main)
        }
    )
)
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult};
use common::Span;
use graphql_syntax::{
    Argument, Directive, ExecutableDefinition, ExecutableDocument, FragmentDefinition,
    FragmentSpread, InlineFragment, LinkedField, List, OperationDefinition, ScalarField, Selection,
    TypeCondition,
};
use interner::StringKey;

mod type_path;
pub use type_path::{TypePath, TypePathItem};

#[derive(Debug, Clone, PartialEq)]
pub enum NodeKind {
    OperationDefinition(OperationDefinition),
    FragmentDefinition(FragmentDefinition),
    FieldName,
    FieldArgument(StringKey, StringKey),
    FragmentSpread(StringKey),
    InlineFragment,
    Variable(String),
    Directive(StringKey, Option<StringKey>),
    TypeCondition(StringKey),
}

#[derive(Debug)]
pub struct NodeResolutionInfo {
    /// The type of the leaf node on which the information request was made
    pub kind: NodeKind,
    /// A list of type metadata that we can use to resolve the leaf
    /// type the request is being made against
    pub type_path: TypePath,
}

impl NodeResolutionInfo {
    fn new(kind: NodeKind) -> Self {
        Self {
            kind,
            type_path: Default::default(),
        }
    }
}

fn build_node_resolution_for_directive(
    directives: &[Directive],
    position_span: Span,
) -> Option<NodeResolutionInfo> {
    let directive = directives
        .iter()
        .find(|directive| directive.span.contains(position_span))?;

    let arg_name_opt = if let Some(args) = &directive.arguments {
        args.items
            .iter()
            .find(|arg| arg.span.contains(position_span))
            .map(|arg| arg.name.value)
    } else {
        None
    };

    Some(NodeResolutionInfo {
        kind: NodeKind::Directive(directive.name.value, arg_name_opt),
        type_path: Default::default(),
    })
}

fn type_condition_at_position(
    type_condition: &TypeCondition,
    position_span: Span,
) -> Option<NodeKind> {
    if !type_condition.span.contains(position_span) {
        return None;
    }

    Some(NodeKind::TypeCondition(type_condition.type_.value))
}

pub(crate) fn create_node_resolution_info(
    document: ExecutableDocument,
    position_span: Span,
) -> LSPRuntimeResult<NodeResolutionInfo> {
    let definition = document
        .definitions
        .iter()
        .find(|definition| definition.location().contains(position_span))
        .ok_or(LSPRuntimeError::ExpectedError)?;

    match definition {
        ExecutableDefinition::Operation(operation) => {
            if operation.location.contains(position_span) {
                let mut node_resolution_info =
                    NodeResolutionInfo::new(NodeKind::OperationDefinition(operation.clone()));
                let OperationDefinition {
                    selections,
                    variable_definitions,
                    ..
                } = operation;

                if let Some(variable_definitions) = variable_definitions {
                    if let Some(variable) = variable_definitions
                        .items
                        .iter()
                        .find(|var| var.span.contains(position_span))
                    {
                        node_resolution_info.kind = NodeKind::Variable(variable.type_.to_string());
                        return Ok(node_resolution_info);
                    }
                }

                let (_, kind) = operation.operation.clone().ok_or_else(|| {
                    LSPRuntimeError::UnexpectedError(
                        "Expected operation to exist, but it did not".to_string(),
                    )
                })?;
                node_resolution_info
                    .type_path
                    .add_type(TypePathItem::Operation(kind));

                build_node_resolution_info_from_selections(
                    selections,
                    position_span,
                    &mut node_resolution_info,
                );
                Ok(node_resolution_info)
            } else {
                Err(LSPRuntimeError::UnexpectedError(format!(
                    "Expected operation named {:?} to contain position {:?}, but it did not. Operation span {:?}",
                    operation.name, operation.location, position_span
                )))
            }
        }
        ExecutableDefinition::Fragment(fragment) => {
            if fragment.location.contains(position_span) {
                let mut node_resolution_info =
                    NodeResolutionInfo::new(NodeKind::FragmentDefinition(fragment.clone()));
                if let Some(node_resolution_info) =
                    build_node_resolution_for_directive(&fragment.directives, position_span)
                {
                    return Ok(node_resolution_info);
                }

                if let Some(node_kind) =
                    type_condition_at_position(&fragment.type_condition, position_span)
                {
                    node_resolution_info.kind = node_kind;
                    return Ok(node_resolution_info);
                }

                let type_name = fragment.type_condition.type_.value;
                node_resolution_info
                    .type_path
                    .add_type(TypePathItem::FragmentDefinition { type_name });
                build_node_resolution_info_from_selections(
                    &fragment.selections,
                    position_span,
                    &mut node_resolution_info,
                );
                Ok(node_resolution_info)
            } else {
                Err(LSPRuntimeError::UnexpectedError(format!(
                    "Expected fragment named {:?} to contain position {:?}, but it did not. Operation span {:?}",
                    fragment.name, fragment.location, position_span
                )))
            }
        }
    }
}

/// If position_span falls into one of the field arguments,
/// we need to display resolution info for this field
fn build_node_resolution_info_for_argument(
    field_name: StringKey,
    arguments: &Option<List<Argument>>,
    position_span: Span,
    node_resolution_info: &mut NodeResolutionInfo,
) -> Option<()> {
    if let Some(arguments) = &arguments {
        let argument = arguments
            .items
            .iter()
            .find(|item| item.span.contains(position_span))?;

        node_resolution_info.kind = NodeKind::FieldArgument(field_name, argument.name.value);

        Some(())
    } else {
        None
    }
}

fn build_node_resolution_info_from_selections(
    selections: &List<Selection>,
    position_span: Span,
    node_resolution_info: &mut NodeResolutionInfo,
) {
    if let Some(item) = selections
        .items
        .iter()
        .find(|item| item.span().contains(position_span))
    {
        if let Some(directive_resolution_info) =
            build_node_resolution_for_directive(item.directives(), position_span)
        {
            node_resolution_info.kind = directive_resolution_info.kind;
            return;
        }

        match item {
            Selection::LinkedField(node) => {
                node_resolution_info.kind = NodeKind::FieldName;
                let LinkedField {
                    name, selections, ..
                } = node;
                if build_node_resolution_info_for_argument(
                    name.value,
                    &node.arguments,
                    position_span,
                    node_resolution_info,
                )
                .is_none()
                {
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::LinkedField { name: name.value });
                    build_node_resolution_info_from_selections(
                        selections,
                        position_span,
                        node_resolution_info,
                    );
                }
            }
            Selection::FragmentSpread(spread) => {
                let FragmentSpread { name, .. } = spread;
                if name.span.contains(position_span) {
                    node_resolution_info.kind = NodeKind::FragmentSpread(name.value);
                }
            }
            Selection::InlineFragment(node) => {
                let InlineFragment {
                    selections,
                    type_condition,
                    ..
                } = node;

                node_resolution_info.kind = NodeKind::InlineFragment;
                if let Some(type_condition) = type_condition {
                    let type_name = type_condition.type_.value;
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::InlineFragment { type_name });

                    if let Some(node_kind) =
                        type_condition_at_position(&type_condition, position_span)
                    {
                        node_resolution_info.kind = node_kind;
                    } else {
                        build_node_resolution_info_from_selections(
                            selections,
                            position_span,
                            node_resolution_info,
                        )
                    }
                }
            }
            Selection::ScalarField(node) => {
                let ScalarField { name, .. } = node;

                if build_node_resolution_info_for_argument(
                    name.value,
                    &node.arguments,
                    position_span,
                    node_resolution_info,
                )
                .is_none()
                {
                    node_resolution_info.kind = NodeKind::FieldName;
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::ScalarField { name: name.value });
                }
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::create_node_resolution_info;
    use super::{NodeKind, NodeResolutionInfo};
    use common::{SourceLocationKey, Span};
    use graphql_syntax::parse_executable;
    use interner::Intern;

    fn parse_and_get_node_info(source: &str, pos: u32) -> NodeResolutionInfo {
        let document =
            parse_executable(source, SourceLocationKey::standalone("/test/file")).unwrap();

        // Select the `uri` field
        let position_span = Span {
            start: pos,
            end: pos,
        };

        create_node_resolution_info(document, position_span).unwrap()
    }

    #[test]
    fn create_node_resolution_info_test() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
                profile_picture {
                    uri
                }
            }
        "#,
            // Select the `uri` field
            117,
        );

        assert_eq!(node_resolution_info.kind, NodeKind::FieldName);
    }

    #[test]
    fn create_node_resolution_info_test_position_outside() {
        let document = parse_executable(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            SourceLocationKey::standalone("/test/file"),
        )
        .unwrap();
        // Position is outside of the document
        let position_span = Span { start: 86, end: 87 };
        let result = create_node_resolution_info(document, position_span);
        assert!(result.is_err());
    }

    #[test]
    fn create_node_resolution_info_fragment_def_name() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            // Select the `User_data` fragment name
            26,
        );

        match node_resolution_info.kind {
            NodeKind::FragmentDefinition(fragment) => {
                assert_eq!(fragment.name.value, "User_data".intern())
            }
            node_kind => panic!("Unexpected node node_resolution_info.kind {:?}", node_kind),
        }
    }

    #[test]
    fn create_node_resolution_info_fragment_def_type_condition() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            // Select the `User` type in fragment declaration
            35,
        );

        assert_eq!(
            node_resolution_info.kind,
            NodeKind::TypeCondition("User".intern())
        );
    }

    #[test]
    fn create_node_resolution_info_inline_fragment_type_condition() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
                ... on User {
                    id
                }
            }
        "#,
            // Select the `User` type in fragment declaration
            84,
        );

        assert_eq!(
            node_resolution_info.kind,
            NodeKind::TypeCondition("User".intern())
        );
    }
}
<commit_msg>resolve_node<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult};
use common::Span;
use graphql_syntax::{
    Argument, Directive, ExecutableDefinition, ExecutableDocument, FragmentDefinition,
    FragmentSpread, InlineFragment, LinkedField, List, OperationDefinition, ScalarField, Selection,
    TypeCondition,
};
use interner::StringKey;

mod type_path;
pub use type_path::{TypePath, TypePathItem};

#[derive(Debug, Clone, PartialEq)]
pub enum NodeKind {
    OperationDefinition(OperationDefinition),
    FragmentDefinition(FragmentDefinition),
    FieldName,
    FieldArgument(StringKey, StringKey),
    FragmentSpread(StringKey),
    InlineFragment,
    Variable(String),
    Directive(StringKey, Option<StringKey>),
    TypeCondition(StringKey),
}

#[derive(Debug)]
pub struct NodeResolutionInfo {
    /// The type of the leaf node on which the information request was made
    pub kind: NodeKind,
    /// A list of type metadata that we can use to resolve the leaf
    /// type the request is being made against
    pub type_path: TypePath,
}

impl NodeResolutionInfo {
    fn new(kind: NodeKind) -> Self {
        Self {
            kind,
            type_path: Default::default(),
        }
    }
}

fn build_node_resolution_for_directive(
    directives: &[Directive],
    position_span: Span,
) -> Option<NodeResolutionInfo> {
    let directive = directives
        .iter()
        .find(|directive| directive.span.contains(position_span))?;

    let arg_name_opt = if let Some(args) = &directive.arguments {
        args.items
            .iter()
            .find(|arg| arg.span.contains(position_span))
            .map(|arg| arg.name.value)
    } else {
        None
    };

    Some(NodeResolutionInfo {
        kind: NodeKind::Directive(directive.name.value, arg_name_opt),
        type_path: Default::default(),
    })
}

fn type_condition_at_position(
    type_condition: &TypeCondition,
    position_span: Span,
) -> Option<NodeKind> {
    if !type_condition.span.contains(position_span) {
        return None;
    }

    Some(NodeKind::TypeCondition(type_condition.type_.value))
}

pub fn create_node_resolution_info(
    document: ExecutableDocument,
    position_span: Span,
) -> LSPRuntimeResult<NodeResolutionInfo> {
    let definition = document
        .definitions
        .iter()
        .find(|definition| definition.location().contains(position_span))
        .ok_or(LSPRuntimeError::ExpectedError)?;

    match definition {
        ExecutableDefinition::Operation(operation) => {
            if operation.location.contains(position_span) {
                let mut node_resolution_info =
                    NodeResolutionInfo::new(NodeKind::OperationDefinition(operation.clone()));
                let OperationDefinition {
                    selections,
                    variable_definitions,
                    ..
                } = operation;

                if let Some(variable_definitions) = variable_definitions {
                    if let Some(variable) = variable_definitions
                        .items
                        .iter()
                        .find(|var| var.span.contains(position_span))
                    {
                        node_resolution_info.kind = NodeKind::Variable(variable.type_.to_string());
                        return Ok(node_resolution_info);
                    }
                }

                let (_, kind) = operation.operation.clone().ok_or_else(|| {
                    LSPRuntimeError::UnexpectedError(
                        "Expected operation to exist, but it did not".to_string(),
                    )
                })?;
                node_resolution_info
                    .type_path
                    .add_type(TypePathItem::Operation(kind));

                build_node_resolution_info_from_selections(
                    selections,
                    position_span,
                    &mut node_resolution_info,
                );
                Ok(node_resolution_info)
            } else {
                Err(LSPRuntimeError::UnexpectedError(format!(
                    "Expected operation named {:?} to contain position {:?}, but it did not. Operation span {:?}",
                    operation.name, operation.location, position_span
                )))
            }
        }
        ExecutableDefinition::Fragment(fragment) => {
            if fragment.location.contains(position_span) {
                let mut node_resolution_info =
                    NodeResolutionInfo::new(NodeKind::FragmentDefinition(fragment.clone()));
                if let Some(node_resolution_info) =
                    build_node_resolution_for_directive(&fragment.directives, position_span)
                {
                    return Ok(node_resolution_info);
                }

                if let Some(node_kind) =
                    type_condition_at_position(&fragment.type_condition, position_span)
                {
                    node_resolution_info.kind = node_kind;
                    return Ok(node_resolution_info);
                }

                let type_name = fragment.type_condition.type_.value;
                node_resolution_info
                    .type_path
                    .add_type(TypePathItem::FragmentDefinition { type_name });
                build_node_resolution_info_from_selections(
                    &fragment.selections,
                    position_span,
                    &mut node_resolution_info,
                );
                Ok(node_resolution_info)
            } else {
                Err(LSPRuntimeError::UnexpectedError(format!(
                    "Expected fragment named {:?} to contain position {:?}, but it did not. Operation span {:?}",
                    fragment.name, fragment.location, position_span
                )))
            }
        }
    }
}

/// If position_span falls into one of the field arguments,
/// we need to display resolution info for this field
fn build_node_resolution_info_for_argument(
    field_name: StringKey,
    arguments: &Option<List<Argument>>,
    position_span: Span,
    node_resolution_info: &mut NodeResolutionInfo,
) -> Option<()> {
    if let Some(arguments) = &arguments {
        let argument = arguments
            .items
            .iter()
            .find(|item| item.span.contains(position_span))?;

        node_resolution_info.kind = NodeKind::FieldArgument(field_name, argument.name.value);

        Some(())
    } else {
        None
    }
}

fn build_node_resolution_info_from_selections(
    selections: &List<Selection>,
    position_span: Span,
    node_resolution_info: &mut NodeResolutionInfo,
) {
    if let Some(item) = selections
        .items
        .iter()
        .find(|item| item.span().contains(position_span))
    {
        if let Some(directive_resolution_info) =
            build_node_resolution_for_directive(item.directives(), position_span)
        {
            node_resolution_info.kind = directive_resolution_info.kind;
            return;
        }

        match item {
            Selection::LinkedField(node) => {
                node_resolution_info.kind = NodeKind::FieldName;
                let LinkedField {
                    name, selections, ..
                } = node;
                if build_node_resolution_info_for_argument(
                    name.value,
                    &node.arguments,
                    position_span,
                    node_resolution_info,
                )
                .is_none()
                {
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::LinkedField { name: name.value });
                    build_node_resolution_info_from_selections(
                        selections,
                        position_span,
                        node_resolution_info,
                    );
                }
            }
            Selection::FragmentSpread(spread) => {
                let FragmentSpread { name, .. } = spread;
                if name.span.contains(position_span) {
                    node_resolution_info.kind = NodeKind::FragmentSpread(name.value);
                }
            }
            Selection::InlineFragment(node) => {
                let InlineFragment {
                    selections,
                    type_condition,
                    ..
                } = node;

                node_resolution_info.kind = NodeKind::InlineFragment;
                if let Some(type_condition) = type_condition {
                    let type_name = type_condition.type_.value;
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::InlineFragment { type_name });

                    if let Some(node_kind) =
                        type_condition_at_position(&type_condition, position_span)
                    {
                        node_resolution_info.kind = node_kind;
                    } else {
                        build_node_resolution_info_from_selections(
                            selections,
                            position_span,
                            node_resolution_info,
                        )
                    }
                }
            }
            Selection::ScalarField(node) => {
                let ScalarField { name, .. } = node;

                if build_node_resolution_info_for_argument(
                    name.value,
                    &node.arguments,
                    position_span,
                    node_resolution_info,
                )
                .is_none()
                {
                    node_resolution_info.kind = NodeKind::FieldName;
                    node_resolution_info
                        .type_path
                        .add_type(TypePathItem::ScalarField { name: name.value });
                }
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::create_node_resolution_info;
    use super::{NodeKind, NodeResolutionInfo};
    use common::{SourceLocationKey, Span};
    use graphql_syntax::parse_executable;
    use interner::Intern;

    fn parse_and_get_node_info(source: &str, pos: u32) -> NodeResolutionInfo {
        let document =
            parse_executable(source, SourceLocationKey::standalone("/test/file")).unwrap();

        // Select the `uri` field
        let position_span = Span {
            start: pos,
            end: pos,
        };

        create_node_resolution_info(document, position_span).unwrap()
    }

    #[test]
    fn create_node_resolution_info_test() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
                profile_picture {
                    uri
                }
            }
        "#,
            // Select the `uri` field
            117,
        );

        assert_eq!(node_resolution_info.kind, NodeKind::FieldName);
    }

    #[test]
    fn create_node_resolution_info_test_position_outside() {
        let document = parse_executable(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            SourceLocationKey::standalone("/test/file"),
        )
        .unwrap();
        // Position is outside of the document
        let position_span = Span { start: 86, end: 87 };
        let result = create_node_resolution_info(document, position_span);
        assert!(result.is_err());
    }

    #[test]
    fn create_node_resolution_info_fragment_def_name() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            // Select the `User_data` fragment name
            26,
        );

        match node_resolution_info.kind {
            NodeKind::FragmentDefinition(fragment) => {
                assert_eq!(fragment.name.value, "User_data".intern())
            }
            node_kind => panic!("Unexpected node node_resolution_info.kind {:?}", node_kind),
        }
    }

    #[test]
    fn create_node_resolution_info_fragment_def_type_condition() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
            }
        "#,
            // Select the `User` type in fragment declaration
            35,
        );

        assert_eq!(
            node_resolution_info.kind,
            NodeKind::TypeCondition("User".intern())
        );
    }

    #[test]
    fn create_node_resolution_info_inline_fragment_type_condition() {
        let node_resolution_info = parse_and_get_node_info(
            r#"
            fragment User_data on User {
                name
                ... on User {
                    id
                }
            }
        "#,
            // Select the `User` type in fragment declaration
            84,
        );

        assert_eq!(
            node_resolution_info.kind,
            NodeKind::TypeCondition("User".intern())
        );
    }
}
<|endoftext|>


<commit_before>use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
    Target {
        llvm_target: "aarch64-unknown-freebsd".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
        arch: "aarch64".to_string(),
        options: TargetOptions { max_atomic_width: Some(128), ..super::freebsd_base::opts() },
    }
}
<commit_msg>freebsd arm64 add supported sanitizers.<commit_after>use crate::spec::{SanitizerSet, Target, TargetOptions};

pub fn target() -> Target {
    Target {
        llvm_target: "aarch64-unknown-freebsd".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
        arch: "aarch64".to_string(),
        options: TargetOptions {
            max_atomic_width: Some(128),
            supported_sanitizers: SanitizerSet::ADDRESS
                | SanitizerSet::MEMORY
                | SanitizerSet::THREAD,
            ..super::freebsd_base::opts()
        },
    }
}
<|endoftext|>


<commit_before>use settings;
use std::io::Read;
use std::sync::Mutex;
use reqwest;
use reqwest::header::CONTENT_TYPE;
use std::env;
use error::prelude::*;

lazy_static! {
    static ref NEXT_U8_RESPONSE: Mutex<Vec<Vec<u8>>> = Mutex::new(vec![]);
}

//Todo: change this RC to a u32
pub fn post_u8(body_content: &Vec<u8>) -> VcxResult<Vec<u8>> {
    let endpoint = settings::get_config_value(settings::CONFIG_AGENCY_ENDPOINT)?;
    let url = format!("{}/agency/msg", endpoint);

    if settings::test_agency_mode_enabled() {
        return Ok(NEXT_U8_RESPONSE.lock().unwrap().pop().unwrap_or(Vec::new()));
    }

    //Setting SSL Certs location. This is needed on android platform. Or openssl will fail to verify the certs
    if cfg!(target_os = "android") {
        info!("::Android code");
        set_ssl_cert_location();
    }
    let client = reqwest::ClientBuilder::new().timeout(::utils::timeout::TimeoutUtils::long_timeout()).build()
        .or(Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, "Preparing Post failed")))?;
    debug!("Posting encrypted bundle to: \"{}\"", url);

    let mut response =
        client.post(&url)
            .body(body_content.to_owned())
            .header(CONTENT_TYPE, "octet_stream")
            .send()
            .map_err(|err| {
                error!("error: {}", err);
                VcxError::from_msg(VcxErrorKind::PostMessageFailed, "Could not connect")
            })?;

    trace!("Response Header: {:?}", response);
    if !response.status().is_success() {
        let mut content = String::new();
        match response.read_to_string(&mut content) {
            Ok(x) => info!("Request failed: {}", content),
            Err(x) => info!("could not read response"),
        };
        return Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, format!("POST failed with: {}", content)));
    }

    let mut content = Vec::new();
    response.read_to_end(&mut content)
        .or(Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, "could not read response")))?;

    Ok(content)
}

pub fn set_next_u8_response(body: Vec<u8>) {
    NEXT_U8_RESPONSE.lock().unwrap().push(body);
}

fn set_ssl_cert_location() {
    let ssl_cert_file = "SSL_CERT_FILE";
    env::set_var(ssl_cert_file, env::var("EXTERNAL_STORAGE").unwrap() + "/cacert.pem"); //TODO: CHANGE ME, HARDCODING FOR TESTING ONLY
    match env::var(ssl_cert_file) {
        Ok(val) => info!("{}:: {:?}", ssl_cert_file, val),
        Err(e) => error!("couldn't find var in env {}:: {}. This needs to be set on Android to make https calls.\n See https://github.com/seanmonstar/reqwest/issues/70 for more info",
                         ssl_cert_file, e),
    }
    info!("::SSL_CERT_FILE has been set");
}
<commit_msg>better error message<commit_after>use settings;
use std::io::Read;
use std::sync::Mutex;
use reqwest;
use reqwest::header::CONTENT_TYPE;
use std::env;
use error::prelude::*;

lazy_static! {
    static ref NEXT_U8_RESPONSE: Mutex<Vec<Vec<u8>>> = Mutex::new(vec![]);
}

//Todo: change this RC to a u32
pub fn post_u8(body_content: &Vec<u8>) -> VcxResult<Vec<u8>> {
    let endpoint = settings::get_config_value(settings::CONFIG_AGENCY_ENDPOINT)?;
    let url = format!("{}/agency/msg", endpoint);

    if settings::test_agency_mode_enabled() {
        return Ok(NEXT_U8_RESPONSE.lock().unwrap().pop().unwrap_or(Vec::new()));
    }

    //Setting SSL Certs location. This is needed on android platform. Or openssl will fail to verify the certs
    if cfg!(target_os = "android") {
        info!("::Android code");
        set_ssl_cert_location();
    }
    let client = reqwest::ClientBuilder::new().timeout(::utils::timeout::TimeoutUtils::long_timeout()).build()
        .or(Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, "Preparing Post failed")))?;
    debug!("Posting encrypted bundle to: \"{}\"", url);

    let mut response =
        client.post(&url)
            .body(body_content.to_owned())
            .header(CONTENT_TYPE, "octet_stream")
            .send()
            .map_err(|err| {
                error!("error: {}", err);
                VcxError::from_msg(VcxErrorKind::PostMessageFailed, format!("Could not connect {:?}", err))
            })?;

    trace!("Response Header: {:?}", response);
    if !response.status().is_success() {
        let mut content = String::new();
        match response.read_to_string(&mut content) {
            Ok(x) => info!("Request failed: {}", content),
            Err(x) => info!("could not read response"),
        };
        return Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, format!("POST failed with: {}", content)));
    }

    let mut content = Vec::new();
    response.read_to_end(&mut content)
        .or(Err(VcxError::from_msg(VcxErrorKind::PostMessageFailed, "could not read response")))?;

    Ok(content)
}

pub fn set_next_u8_response(body: Vec<u8>) {
    NEXT_U8_RESPONSE.lock().unwrap().push(body);
}

fn set_ssl_cert_location() {
    let ssl_cert_file = "SSL_CERT_FILE";
    env::set_var(ssl_cert_file, env::var("EXTERNAL_STORAGE").unwrap() + "/cacert.pem"); //TODO: CHANGE ME, HARDCODING FOR TESTING ONLY
    match env::var(ssl_cert_file) {
        Ok(val) => info!("{}:: {:?}", ssl_cert_file, val),
        Err(e) => error!("couldn't find var in env {}:: {}. This needs to be set on Android to make https calls.\n See https://github.com/seanmonstar/reqwest/issues/70 for more info",
                         ssl_cert_file, e),
    }
    info!("::SSL_CERT_FILE has been set");
}
<|endoftext|>


<commit_before>// spell-checker:ignore mockstream abcdefgh bcdefgh

use std::cmp;
use std::io;
use std::io::Read;

use crate::multifilereader::HasError;

/// When a large number of bytes must be skipped, it will be read into a
/// dynamically allocated buffer. The buffer will be limited to this size.
const MAX_SKIP_BUFFER: usize = 64 * 1024;

/// Wrapper for `std::io::Read` which can skip bytes at the beginning
/// of the input, and it can limit the returned bytes to a particular
/// number of bytes.
pub struct PartialReader<R> {
    inner: R,
    skip: usize,
    limit: Option<usize>,
}

impl<R> PartialReader<R> {
    /// Create a new `PartialReader` wrapping `inner`, which will skip
    /// `skip` bytes, and limits the output to `limit` bytes. Set `limit`
    /// to `None` if there should be no limit.
    pub fn new(inner: R, skip: usize, limit: Option<usize>) -> Self {
        PartialReader { inner, skip, limit }
    }
}

impl<R: Read> Read for PartialReader<R> {
    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
        if self.skip > 0 {
            let buf_size = cmp::min(self.skip, MAX_SKIP_BUFFER);
            let mut bytes: Vec<u8> = Vec::with_capacity(buf_size);
            unsafe {
                bytes.set_len(buf_size);
            }

            while self.skip > 0 {
                let skip_count = cmp::min(self.skip, buf_size);

                match self.inner.read_exact(&mut bytes[..skip_count]) {
                    Err(e) => return Err(e),
                    Ok(()) => self.skip -= skip_count,
                }
            }
        }
        match self.limit {
            None => self.inner.read(out),
            Some(0) => Ok(0),
            Some(ref mut limit) => {
                let slice = if *limit > out.len() {
                    out
                } else {
                    &mut out[0..*limit]
                };
                match self.inner.read(slice) {
                    Err(e) => Err(e),
                    Ok(r) => {
                        *limit -= r;
                        Ok(r)
                    }
                }
            }
        }
    }
}

impl<R: HasError> HasError for PartialReader<R> {
    fn has_error(&self) -> bool {
        self.inner.has_error()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::mockstream::*;
    use std::io::{Cursor, ErrorKind, Read};

    #[test]
    fn test_read_without_limits() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 8);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0]);
    }

    #[test]
    fn test_read_without_limits_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 0, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_skipping_bytes() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 2, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_skipping_all() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 20, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::UnexpectedEof);
    }

    #[test]
    fn test_read_skipping_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 2, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_skipping_with_two_reads_during_skip() {
        let mut v = [0; 10];
        let c = Cursor::new(&b"a"[..]).chain(Cursor::new(&b"bcdefgh"[..]));
        let mut sut = PartialReader::new(c, 2, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_skipping_huge_number() {
        let mut v = [0; 10];
        // test if it does not eat all memory....
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), usize::max_value(), None);

        sut.read(v.as_mut()).unwrap_err();
    }

    #[test]
    fn test_read_limiting_all() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(0));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 0);
    }

    #[test]
    fn test_read_limiting() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(6));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_limiting_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 0, Some(6));

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_limiting_with_large_limit() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(20));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 8);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0]);
    }

    #[test]
    fn test_read_limiting_with_multiple_reads() {
        let mut v = [0; 3];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(6));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 3);
        assert_eq!(v, [0x61, 0x62, 0x63]);
        assert_eq!(sut.read(v.as_mut()).unwrap(), 3);
        assert_eq!(v, [0x64, 0x65, 0x66]);
        assert_eq!(sut.read(v.as_mut()).unwrap(), 0);
    }

    #[test]
    fn test_read_skipping_and_limiting() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 2, Some(4));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 4);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0, 0, 0, 0, 0, 0]);
    }
}
<commit_msg>od: remove potential unsoundness and an allocation in PartialReader (#1730)<commit_after>// spell-checker:ignore mockstream abcdefgh bcdefgh

use std::cmp;
use std::io;
use std::io::Read;

use crate::multifilereader::HasError;

/// When a large number of bytes must be skipped, it will be read into a
/// dynamically allocated buffer. The buffer will be limited to this size.
const MAX_SKIP_BUFFER: usize = 16 * 1024;

/// Wrapper for `std::io::Read` which can skip bytes at the beginning
/// of the input, and it can limit the returned bytes to a particular
/// number of bytes.
pub struct PartialReader<R> {
    inner: R,
    skip: usize,
    limit: Option<usize>,
}

impl<R> PartialReader<R> {
    /// Create a new `PartialReader` wrapping `inner`, which will skip
    /// `skip` bytes, and limits the output to `limit` bytes. Set `limit`
    /// to `None` if there should be no limit.
    pub fn new(inner: R, skip: usize, limit: Option<usize>) -> Self {
        PartialReader { inner, skip, limit }
    }
}

impl<R: Read> Read for PartialReader<R> {
    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
        if self.skip > 0 {
            let mut bytes = [0; MAX_SKIP_BUFFER];

            while self.skip > 0 {
                let skip_count = cmp::min(self.skip, MAX_SKIP_BUFFER);

                match self.inner.read(&mut bytes[..skip_count]) {
                    Ok(0) => {
                        // this is an error as we still have more to skip
                        return Err(io::Error::new(
                            io::ErrorKind::UnexpectedEof,
                            "tried to skip past end of input",
                        ));
                    }
                    Ok(n) => self.skip -= n,
                    Err(e) => return Err(e),
                }
            }
        }

        match self.limit {
            None => self.inner.read(out),
            Some(0) => Ok(0),
            Some(ref mut limit) => {
                let slice = if *limit > out.len() {
                    out
                } else {
                    &mut out[0..*limit]
                };
                match self.inner.read(slice) {
                    Err(e) => Err(e),
                    Ok(r) => {
                        *limit -= r;
                        Ok(r)
                    }
                }
            }
        }
    }
}

impl<R: HasError> HasError for PartialReader<R> {
    fn has_error(&self) -> bool {
        self.inner.has_error()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::mockstream::*;
    use std::io::{Cursor, ErrorKind, Read};

    #[test]
    fn test_read_without_limits() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 8);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0]);
    }

    #[test]
    fn test_read_without_limits_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 0, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_skipping_bytes() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 2, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_skipping_all() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 20, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::UnexpectedEof);
    }

    #[test]
    fn test_read_skipping_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 2, None);

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_skipping_with_two_reads_during_skip() {
        let mut v = [0; 10];
        let c = Cursor::new(&b"a"[..]).chain(Cursor::new(&b"bcdefgh"[..]));
        let mut sut = PartialReader::new(c, 2, None);

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_skipping_huge_number() {
        let mut v = [0; 10];
        // test if it does not eat all memory....
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), usize::max_value(), None);

        sut.read(v.as_mut()).unwrap_err();
    }

    #[test]
    fn test_read_limiting_all() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(0));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 0);
    }

    #[test]
    fn test_read_limiting() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(6));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 6);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0, 0, 0, 0]);
    }

    #[test]
    fn test_read_limiting_with_error() {
        let mut v = [0; 10];
        let f = FailingMockStream::new(ErrorKind::PermissionDenied, "No access", 3);
        let mut sut = PartialReader::new(f, 0, Some(6));

        let error = sut.read(v.as_mut()).unwrap_err();
        assert_eq!(error.kind(), ErrorKind::PermissionDenied);
        assert_eq!(error.to_string(), "No access");
    }

    #[test]
    fn test_read_limiting_with_large_limit() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(20));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 8);
        assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0]);
    }

    #[test]
    fn test_read_limiting_with_multiple_reads() {
        let mut v = [0; 3];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 0, Some(6));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 3);
        assert_eq!(v, [0x61, 0x62, 0x63]);
        assert_eq!(sut.read(v.as_mut()).unwrap(), 3);
        assert_eq!(v, [0x64, 0x65, 0x66]);
        assert_eq!(sut.read(v.as_mut()).unwrap(), 0);
    }

    #[test]
    fn test_read_skipping_and_limiting() {
        let mut v = [0; 10];
        let mut sut = PartialReader::new(Cursor::new(&b"abcdefgh"[..]), 2, Some(4));

        assert_eq!(sut.read(v.as_mut()).unwrap(), 4);
        assert_eq!(v, [0x63, 0x64, 0x65, 0x66, 0, 0, 0, 0, 0, 0]);
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[macro_export]
macro_rules! size_of_test {
    ($testname: ident, $t: ty, $expected_size: expr) => {
        #[test]
        fn $testname() {
            let new = ::std::mem::size_of::<$t>();
            let old = $expected_size;
            if new < old {
                panic!(
                    "Your changes have decreased the stack size of {} from {} to {}. \
                     Good work! Please update the expected size in {}.",
                    stringify!($t), old, new, file!()
                )
            } else if new > old {
                panic!(
                    "Your changes have increased the stack size of {} from {} to {}. \
                     Please consider choosing a design which avoids this increase. \
                     If you feel that the increase is necessary, update the size in {}.",
                    stringify!($t), old, new, file!()
                )
            }
        }
    }
}
<commit_msg>Format component size_of_test<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[macro_export]
macro_rules! size_of_test {
    ($testname: ident, $t: ty, $expected_size: expr) => {
        #[test]
        fn $testname() {
            let new = ::std::mem::size_of::<$t>();
            let old = $expected_size;
            if new < old {
                panic!(
                    "Your changes have decreased the stack size of {} from {} to {}. \
                     Good work! Please update the expected size in {}.",
                    stringify!($t),
                    old,
                    new,
                    file!()
                )
            } else if new > old {
                panic!(
                    "Your changes have increased the stack size of {} from {} to {}. \
                     Please consider choosing a design which avoids this increase. \
                     If you feel that the increase is necessary, update the size in {}.",
                    stringify!($t),
                    old,
                    new,
                    file!()
                )
            }
        }
    };
}
<|endoftext|>


<commit_before>use tag;
use err;
use byte;

use std::cmp::Ordering;
use std::io;

pub trait StreamDecodee {
  /// This function is called when an ASN.1 tag is encountered. In other
  /// words, at the start of an ASN.1 element.
  fn start_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  /// This function is called when an ASN.1 element has finished decoding.
  /// Specifically, this is called for both constructed, and un-constructed
  /// elements.
  fn end_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  // FIXME: Currently it's the function's responsibility to decode the element
  // with the correct amounts of bytes. Without heap allocation, this might be
  // the only way.
  /// This is called when a primitive element is encountered. The start_element
  /// function is always called before this.
  fn primitive<I: Iterator<Item=io::Result<u8>>>(&mut self, reader: &mut byte::ByteReader<I>,
      len: tag::LenNum) -> ParseResult {
    for _ in 0..len {
      match reader.read() {
        Err(e) => return e.into(),
        _ => {},
      }
    }
    ParseResult::Ok
  }

  fn warning(_: err::DecodeError) -> ParseResult {
    ParseResult::Stop
  }

  /// This is called when a fatal decoding error occurs.
  fn error(_: err::DecodeError) {
  }
}

/// A decoder that calls into an object implementing the StreamDecodee
/// trait.
pub struct StreamDecoder<'a, I: Iterator<Item=io::Result<u8>>, S: StreamDecodee + 'a> {
  /// Internal reader with an included byte counter.
  reader: byte::ByteReader<I>,
  /// Object implementing StreamDecodee trait, called into during decoding.
  decodee: &'a mut S,
}

impl<'a, I: Iterator<Item=io::Result<u8>>, S: StreamDecodee> StreamDecoder<'a, I, S> {
  pub fn new<R: Into<byte::ByteReader<I>>>(reader: R, decodee: &'a mut S) -> Self {
    StreamDecoder {
      reader: reader.into(),
      decodee: decodee,
    }
  }

  /// Decode an asn1 element.
  pub fn decode(&mut self) -> Result<(), err::DecodeError> {
    self._decode().and(Ok(()))
  }

  // FIXME: Convert explicit decoded_len to use diff of internal reader count.
  /// Internal decode function.
  fn _decode(&mut self) -> Result<tag::TagLen, err::DecodeError> {
    // Decode tag.
    let taglen = try!(tag::TagLen::read_taglen(&mut self.reader));
    let (tag, len) = (taglen.tag, taglen.len);
    let post_tag_count: tag::LenNum  = self.reader.count;

    // Call the decodee start element callback;
    self.decodee.start_element(taglen);

    // If this type is constructed, decode child element..
    if tag.constructed {
      // Loop over child elements.
      loop {
        let decoded_len = self.reader.count - post_tag_count;
        // Compare decoded length with length in tag.
        // Put this first to handle zero-length elements.
        match len.partial_cmp(&decoded_len) {
          // Return an error when we've decoded too much.
          Some(Ordering::Less) => return Err(err::DecodeError::GreaterLen),
          // Finish loop when equal, we must be finished.
          Some(Ordering::Equal) => break,
          // Continue when we are still decoding.
          Some(Ordering::Greater) => {},
          // Continue when using indefinite length encoding.
          None => {},
        };

        // Decode each child element.
        let child_tag = try!(self._decode());

        // If applicable, identify end of indefinite length encoding.
        // When decoding indefinite length encoding, stop on '00 00'
        // tag.
        if child_tag.len == tag::Len::Def(0) &&
           child_tag.tag.class == tag::Class::Universal &&
           child_tag.tag.tagnum == 0 {
          break;
        }
      }
    // Otherwise decode primitive value.
    } else {
      let len_num = try!(match len {
        tag::Len::Def(l) => Ok(l),
        tag::Len::Indef =>
          Err(err::DecodeError::PrimIndef),
      });

      // Call decodee primitive decode callback.
      self.decodee.primitive(&mut self.reader, len_num);

      // Calculate decoded length.
      let decoded_len = self.reader.count - post_tag_count;
      // Ensure the exact amout of bytes was decoded.
      match len.partial_cmp(&decoded_len) {
        Some(Ordering::Less) => return Err(err::DecodeError::GreaterLen),
        Some(Ordering::Greater) => return Err(err::DecodeError::SmallerLen),
        _ => {},
      }
    }

    // Call decodee end element callback.
    self.decodee.end_element(taglen);

    // Return decoded + tag_len, which is total decoded length.
    Ok(taglen)
  }
}

pub struct StreamEncoder<W: io::Write> {
  writer: byte::ByteWriter<W>
}

impl<W: io::Write> StreamEncoder<W> {
  pub fn new<T: Into<byte::ByteWriter<W>>>(writer: T) -> Self {
    StreamEncoder {
      writer: writer.into(),
    }
  }
}

impl<W: io::Write> StreamDecodee for StreamEncoder<W> {
  fn start_element(&mut self, tag: tag::TagLen) -> ParseResult {
    match tag.write_taglen(&mut self.writer) {
      Err(e) =>  return e.into(),
      _ => (),
    };
    ParseResult::Ok
  }

  fn end_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  fn primitive<I: Iterator<Item=io::Result<u8>>>(&mut self, reader: &mut byte::ByteReader<I>,
      len: tag::LenNum) -> ParseResult {
    for _ in 0..len {
      // Read a byte and write a byte.
      match reader.read() {
        Ok(byte) => match self.writer.write_byte(byte) {
          Err(e) => return e.into(),
          _ => (),
        },
        Err(e) => return e.into(),
      };
    }
    ParseResult::Ok
  }
}

// FIXME: This seems to have two mixed meanings, perhaps split it?
/// The result of a parsing function.
pub enum ParseResult {
  /// Everything went okay.
  Ok,
  /// Decoding should stop.
  Stop,
  /// Decoding should skip next element.
  Skip,
  /// An error occured decoding an element.
  DecodeError(err::DecodeError),
  /// An error occured encoding an element.
  EncodeError(err::EncodeError),
  /// An IO error occured.
  IO(io::Error),
}

impl From<err::DecodeError> for ParseResult {
  fn from(err: err::DecodeError) -> Self {
    ParseResult::DecodeError(err)
  }
}

impl From<err::EncodeError> for ParseResult {
  fn from(err: err::EncodeError) -> Self {
    ParseResult::EncodeError(err)
  }
}

impl From<io::Error> for ParseResult {
  fn from(err: io::Error) -> Self {
    ParseResult::IO(err)
  }
}
<commit_msg>Add more documentation to ber::stream<commit_after>//! A SAXParser inspired stream parser and encoder for tags in an ASN.1 streams.
//!
//! Given a struct that implements StreamDecodee, a StreamDecoder can be used to
//! decode the stream, calling each function in the StreamDecodee trait as they
//! are encountered.
//!
//! The StreamEncoder struct is also provided, which itself implements the
//! StreamDecodee trait. This allows you to encode an ASN.1 stream using
//! the StreamDecodee interface as the caller.

use tag;
use err;
use byte;

use std::cmp::Ordering;
use std::io;

/// This trait provides a SAXParser inspired interface for parsing ASN.1 streams.
///
/// If it were implemented, the ParseResult return types would be used to
/// provide feedback on whether parsing of that element was successful.
pub trait StreamDecodee {
  /// This function is called when an ASN.1 tag is encountered. In other
  /// words, at the start of an ASN.1 element.
  fn start_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  /// This function is called when an ASN.1 element has finished decoding.
  /// Note that this is also called for all elements, even after a primitive()
  /// call. For this reason, you may need to check the constructed flag in some
  /// cases.
  fn end_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  // FIXME: Currently it's the function's responsibility to decode the element
  // with the correct amounts of bytes. Without heap allocation, this might be
  // the only way.
  /// This function is called when a primitive element is encountered. Note that both
  /// start_element and end_element are called before/after this function.
  fn primitive<I: Iterator<Item=io::Result<u8>>>(&mut self, reader: &mut byte::ByteReader<I>,
      len: tag::LenNum) -> ParseResult {
    for _ in 0..len {
      match reader.read() {
        Err(e) => return e.into(),
        _ => {},
      }
    }
    ParseResult::Ok
  }

  /// This function would be called when a recoverable decode error occurs, however
  /// currently nothing calls this.
  fn warning(_: err::DecodeError) -> ParseResult {
    ParseResult::Stop
  }

  /// This function would be called when a fatal decoding error occurs, however
  /// currently nothing calls this.
  fn error(_: err::DecodeError) {
  }
}

/// A decoder that calls into a struct implementing the StreamDecodee trait,
/// similar to a SAXParser
pub struct StreamDecoder<'a, I: Iterator<Item=io::Result<u8>>, S: StreamDecodee + 'a> {
  /// Internal reader with an included byte counter.
  reader: byte::ByteReader<I>,
  /// Object implementing StreamDecodee trait, functions are called when
  /// specific things are found in the ASN.1 stream.
  decodee: &'a mut S,
}

impl<'a, I: Iterator<Item=io::Result<u8>>, S: StreamDecodee> StreamDecoder<'a, I, S> {
  pub fn new<R: Into<byte::ByteReader<I>>>(reader: R, decodee: &'a mut S) -> Self {
    StreamDecoder {
      reader: reader.into(),
      decodee: decodee,
    }
  }

  /// Decode an asn1 element.
  pub fn decode(&mut self) -> Result<(), err::DecodeError> {
    self._decode().and(Ok(()))
  }

  // FIXME: Convert explicit decoded_len to use diff of internal reader count.
  /// Internal decode function.
  fn _decode(&mut self) -> Result<tag::TagLen, err::DecodeError> {
    // Decode tag.
    let taglen = try!(tag::TagLen::read_taglen(&mut self.reader));
    let (tag, len) = (taglen.tag, taglen.len);
    let post_tag_count: tag::LenNum  = self.reader.count;

    // Call the decodee start element callback;
    self.decodee.start_element(taglen);

    // If this type is constructed, decode child element..
    if tag.constructed {
      // Loop over child elements.
      loop {
        let decoded_len = self.reader.count - post_tag_count;
        // Compare decoded length with length in tag.
        // Put this first to handle zero-length elements.
        match len.partial_cmp(&decoded_len) {
          // Return an error when we've decoded too much.
          Some(Ordering::Less) => return Err(err::DecodeError::GreaterLen),
          // Finish loop when equal, we must be finished.
          Some(Ordering::Equal) => break,
          // Continue when we are still decoding.
          Some(Ordering::Greater) => {},
          // Continue when using indefinite length encoding.
          None => {},
        };

        // Decode each child element.
        let child_tag = try!(self._decode());

        // If applicable, identify end of indefinite length encoding.
        // When decoding indefinite length encoding, stop on '00 00'
        // tag.
        if child_tag.len == tag::Len::Def(0) &&
           child_tag.tag.class == tag::Class::Universal &&
           child_tag.tag.tagnum == 0 {
          break;
        }
      }
    // Otherwise decode primitive value.
    } else {
      let len_num = try!(match len {
        tag::Len::Def(l) => Ok(l),
        tag::Len::Indef =>
          Err(err::DecodeError::PrimIndef),
      });

      // Call decodee primitive decode callback.
      self.decodee.primitive(&mut self.reader, len_num);

      // Calculate decoded length.
      let decoded_len = self.reader.count - post_tag_count;
      // Ensure the exact amout of bytes was decoded.
      match len.partial_cmp(&decoded_len) {
        Some(Ordering::Less) => return Err(err::DecodeError::GreaterLen),
        Some(Ordering::Greater) => return Err(err::DecodeError::SmallerLen),
        _ => {},
      }
    }

    // Call decodee end element callback.
    self.decodee.end_element(taglen);

    // Return decoded + tag_len, which is total decoded length.
    Ok(taglen)
  }
}

/// A stream encoder that implements StreamDecodee. Using this,
/// a ASN.1 stream can be written using a SAXParser style interface.
pub struct StreamEncoder<W: io::Write> {
  writer: byte::ByteWriter<W>
}

impl<W: io::Write> StreamEncoder<W> {
  pub fn new<T: Into<byte::ByteWriter<W>>>(writer: T) -> Self {
    StreamEncoder {
      writer: writer.into(),
    }
  }
}

impl<W: io::Write> StreamDecodee for StreamEncoder<W> {
  fn start_element(&mut self, tag: tag::TagLen) -> ParseResult {
    match tag.write_taglen(&mut self.writer) {
      Err(e) =>  return e.into(),
      _ => (),
    };
    ParseResult::Ok
  }

  fn end_element(&mut self, _: tag::TagLen) -> ParseResult {
    ParseResult::Ok
  }

  fn primitive<I: Iterator<Item=io::Result<u8>>>(&mut self, reader: &mut byte::ByteReader<I>,
      len: tag::LenNum) -> ParseResult {
    for _ in 0..len {
      // Read a byte and write a byte.
      match reader.read() {
        Ok(byte) => match self.writer.write_byte(byte) {
          Err(e) => return e.into(),
          _ => (),
        },
        Err(e) => return e.into(),
      };
    }
    ParseResult::Ok
  }
}

// FIXME: This seems to have two mixed meanings, perhaps split it?
/// The result of parsing after a callback on a StreamDecodee.
///
/// If it were implemented, this would provide feedback to the Decoder/Parser.
pub enum ParseResult {
  /// Everything went okay.
  Ok,
  /// Decoding should stop.
  Stop,
  /// Decoding should skip next element.
  Skip,
  /// An error occured decoding an element.
  DecodeError(err::DecodeError),
  /// An error occured encoding an element.
  EncodeError(err::EncodeError),
  /// An IO error occured.
  IO(io::Error),
}

impl From<err::DecodeError> for ParseResult {
  fn from(err: err::DecodeError) -> Self {
    ParseResult::DecodeError(err)
  }
}

impl From<err::EncodeError> for ParseResult {
  fn from(err: err::EncodeError) -> Self {
    ParseResult::EncodeError(err)
  }
}

impl From<io::Error> for ParseResult {
  fn from(err: io::Error) -> Self {
    ParseResult::IO(err)
  }
}
<|endoftext|>


<commit_before>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>,
//               whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution.
pub use self::imp::*;

// rust-lang/rust#25544
// #[cfg_attr(target_arch = "x86",    path = "x86.rs")]
// #[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
// mod imp;

#[cfg(target_arch = "x86")]
#[path = "x86.rs"]
mod imp;

#[cfg(target_arch = "x86_64")]
#[path = "x86_64.rs"]
mod imp;
<commit_msg>Remove workaround for rust-lang/rust#25544.<commit_after>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>,
//               whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution.

pub use self::imp::*;

#[allow(unused_attributes)] // rust-lang/rust#35584
#[cfg_attr(target_arch = "x86",    path = "x86.rs")]
#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
mod imp;
<|endoftext|>


<commit_before>use {
    ImageSize,
};

/// Implemented by all graphics back-ends.
/// This trait uses default methods to simplify implementation.
///
/// ## Alpha blending
/// The default behavior for alpha blending is assumed to be turned off.
/// A back-end might choose to turn it on by default and ignore enable/disable.
/// The default behavior for not supporting alpha blending is ignoring enable/disable.
/// Alpha blending is assumed to be expensive and turned off when not needed.
/// For cases when alpha blending is explicitly not wanted there will be own methods,
/// in case the back-end needs to restore to its own default afterwards.
pub trait BackEnd<I: ImageSize> {
    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_clear_rgba(&self) -> bool { false }

    /// Clears background with a color.
    fn clear_rgba(&mut self, _r: f32, _g: f32, _b: f32, _a: f32) {}

    /// Turns on alpha blending.
    fn enable_alpha_blend(&mut self) {}

    /// Turns off alpha blending.
    fn disable_alpha_blend(&mut self) {}

    /// Returns true if texture feature is supported.
    #[inline(always)]
    fn supports_single_texture(&self) -> bool { false }

    /// Sets the current single-texture.
    fn enable_single_texture(&mut self, _texture: &I) {}

    /// Disables single-texture.
    fn disable_single_texture(&mut self) {}

    /// Should return true if texture has alpha channel.
    ///
    /// This will enable alpha blending.
    /// Alpha blending might be enabled if color per vertex has alpha.
    /// Ignore if alpha blending is not supported.
    /// Ignore if alpha channel is not used.
    #[inline(always)]
    fn has_texture_alpha(&self, _texture: &I) -> bool { false }

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_f32_rgba_f32(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_f32_rgba_f32(
        &mut self,
        _vertices: &[f32],
        _colors: &[f32]
    ) {}

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_f32_rgba_f32_uv_f32(&self) -> bool { false }

    /// Renders list of 2d triangles.
    ///
    /// A color and a texture coordinate is assigned per vertex.
    /// The texture coordinates refers to the current single-texture.
    fn tri_list_xy_f32_rgba_f32_uv_f32(
        &mut self,
        _vertices: &[f32],
        _colors: &[f32],
        _texture_coords: &[f32]
    ) {}
}

<commit_msg>Removed ImageSize constraint<commit_after>/// Implemented by all graphics back-ends.
/// This trait uses default methods to simplify implementation.
///
/// ## Alpha blending
/// The default behavior for alpha blending is assumed to be turned off.
/// A back-end might choose to turn it on by default and ignore enable/disable.
/// The default behavior for not supporting alpha blending is ignoring enable/disable.
/// Alpha blending is assumed to be expensive and turned off when not needed.
/// For cases when alpha blending is explicitly not wanted there will be own methods,
/// in case the back-end needs to restore to its own default afterwards.
pub trait BackEnd<I> {
    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_clear_rgba(&self) -> bool { false }

    /// Clears background with a color.
    fn clear_rgba(&mut self, _r: f32, _g: f32, _b: f32, _a: f32) {}

    /// Turns on alpha blending.
    fn enable_alpha_blend(&mut self) {}

    /// Turns off alpha blending.
    fn disable_alpha_blend(&mut self) {}

    /// Returns true if texture feature is supported.
    #[inline(always)]
    fn supports_single_texture(&self) -> bool { false }

    /// Sets the current single-texture.
    fn enable_single_texture(&mut self, _texture: &I) {}

    /// Disables single-texture.
    fn disable_single_texture(&mut self) {}

    /// Should return true if texture has alpha channel.
    ///
    /// This will enable alpha blending.
    /// Alpha blending might be enabled if color per vertex has alpha.
    /// Ignore if alpha blending is not supported.
    /// Ignore if alpha channel is not used.
    #[inline(always)]
    fn has_texture_alpha(&self, _texture: &I) -> bool { false }

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_f32_rgba_f32(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_f32_rgba_f32(
        &mut self,
        _vertices: &[f32],
        _colors: &[f32]
    ) {}

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_f32_rgba_f32_uv_f32(&self) -> bool { false }

    /// Renders list of 2d triangles.
    ///
    /// A color and a texture coordinate is assigned per vertex.
    /// The texture coordinates refers to the current single-texture.
    fn tri_list_xy_f32_rgba_f32_uv_f32(
        &mut self,
        _vertices: &[f32],
        _colors: &[f32],
        _texture_coords: &[f32]
    ) {}
}

<|endoftext|>