<commit_before>#[macro_use] extern crate log;

use std::sync::{Arc, Mutex};
use log::{LogLevel, set_logger, LogLevelFilter, Log, LogRecord, LogMetadata};
use log::MaxLogLevelFilter;

struct State {
    last_log: Mutex<Option<LogLevel>>,
    filter: MaxLogLevelFilter,
}

impl Log for Arc<State> {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, record: &LogRecord) {
        *self.last_log.lock().unwrap() = Some(record.level());
    }
}

fn main() {
    let mut a = None;
    set_logger(|max| {
        let me = Arc::new(State {
            last_log: Mutex::new(None),
            filter: max,
        });
        a = Some(me.clone());
        Box::new(me)
    }).unwrap();
    let a = a.unwrap();

    test(&a, LogLevelFilter::Off);
    test(&a, LogLevelFilter::Error);
    test(&a, LogLevelFilter::Warn);
    test(&a, LogLevelFilter::Info);
    test(&a, LogLevelFilter::Debug);
    test(&a, LogLevelFilter::Trace);
}

fn test(a: &State, filter: LogLevelFilter) {
    a.filter.set(filter);
    error!("");
    last(&a, t(LogLevel::Error, filter));
    warn!("");
    last(&a, t(LogLevel::Warn, filter));
    info!("");
    last(&a, t(LogLevel::Info, filter));
    debug!("");
    last(&a, t(LogLevel::Debug, filter));
    trace!("");
    last(&a, t(LogLevel::Trace, filter));

    fn t(lvl: LogLevel, filter: LogLevelFilter) -> Option<LogLevel> {
        if lvl <= filter {Some(lvl)} else {None}
    }
}

fn last(state: &State, expected: Option<LogLevel>) {
    let mut lvl = state.last_log.lock().unwrap();
    assert_eq!(*lvl, expected);
    *lvl = None;
}
<commit_msg>Fix tests for rust master<commit_after>#[macro_use] extern crate log;

use std::sync::{Arc, Mutex};
use log::{LogLevel, set_logger, LogLevelFilter, Log, LogRecord, LogMetadata};
use log::MaxLogLevelFilter;

struct State {
    last_log: Mutex<Option<LogLevel>>,
    filter: MaxLogLevelFilter,
}

struct Logger(Arc<State>);

impl Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, record: &LogRecord) {
        *self.0.last_log.lock().unwrap() = Some(record.level());
    }
}

fn main() {
    let mut a = None;
    set_logger(|max| {
        let me = Arc::new(State {
            last_log: Mutex::new(None),
            filter: max,
        });
        a = Some(me.clone());
        Box::new(Logger(me))
    }).unwrap();
    let a = a.unwrap();

    test(&a, LogLevelFilter::Off);
    test(&a, LogLevelFilter::Error);
    test(&a, LogLevelFilter::Warn);
    test(&a, LogLevelFilter::Info);
    test(&a, LogLevelFilter::Debug);
    test(&a, LogLevelFilter::Trace);
}

fn test(a: &State, filter: LogLevelFilter) {
    a.filter.set(filter);
    error!("");
    last(&a, t(LogLevel::Error, filter));
    warn!("");
    last(&a, t(LogLevel::Warn, filter));
    info!("");
    last(&a, t(LogLevel::Info, filter));
    debug!("");
    last(&a, t(LogLevel::Debug, filter));
    trace!("");
    last(&a, t(LogLevel::Trace, filter));

    fn t(lvl: LogLevel, filter: LogLevelFilter) -> Option<LogLevel> {
        if lvl <= filter {Some(lvl)} else {None}
    }
}

fn last(state: &State, expected: Option<LogLevel>) {
    let mut lvl = state.last_log.lock().unwrap();
    assert_eq!(*lvl, expected);
    *lvl = None;
}
<|endoftext|>


<commit_before>use boxcars::{self, ParserBuilder};
use std::borrow::Cow;

#[test]
fn test_sample1() {
    let data = include_bytes!("../assets/replays/good/3d07e.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let frames = replay.network_frames.unwrap().frames;

    // random usage of the API
    let new_count = frames
        .iter()
        .flat_map(|x| x.new_actors.iter())
        .filter(|x| x.actor_id.0 != x.object_id.0)
        .count();
    assert_eq!(4545, new_count);

    let sleeping_rigid_bodies = frames
        .iter()
        .flat_map(|x| x.updated_actors.iter())
        .filter(|act| match act.attribute {
            boxcars::Attribute::RigidBody(body) => body.sleeping,
            _ => false,
        })
        .count();

    assert_eq!(32, sleeping_rigid_bodies);

    let first_actor = frames
        .iter()
        .flat_map(|x| x.new_actors.iter())
        .find(|_| true)
        .unwrap();
    let first_update = frames
        .iter()
        .flat_map(|x| x.updated_actors.iter())
        .find(|_| true)
        .unwrap();

    let first_actor_id: boxcars::ActorId = first_actor.actor_id;
    assert_eq!(0, first_actor_id.0);

    let first_object_id: boxcars::ObjectId = first_actor.object_id;
    assert_eq!(26, first_object_id.0);

    let first_stream_id: boxcars::StreamId = first_update.stream_id;
    assert_eq!(31, first_stream_id.0);
}

fn extract_online_id(
    replay: &boxcars::Replay<'_>,
    user: &str,
) -> (u64, boxcars::attributes::RemoteId) {
    let (_, stats) = replay
        .properties
        .iter()
        .find(|(prop, _)| *prop == "PlayerStats")
        .unwrap();

    let online_id = match stats {
        boxcars::HeaderProp::Array(arr) => {
            let our_player = arr
                .iter()
                .find(|properties| {
                    properties
                        .iter()
                        .find(|(prop, val)| {
                            *prop == "Name" && *val == boxcars::HeaderProp::Str(Cow::Borrowed(user))
                        })
                        .is_some()
                })
                .unwrap();

            let (_, online_id) = our_player
                .iter()
                .find(|(prop, _val)| *prop == "OnlineID")
                .unwrap();
            if let boxcars::HeaderProp::QWord(oid) = online_id {
                *oid
            } else {
                panic!("unexpected property");
            }
        }
        _ => panic!("Expected array"),
    };

    let frames = &replay.network_frames.as_ref().unwrap().frames;
    let reservation = frames
        .iter()
        .flat_map(|x| {
            x.updated_actors.iter().filter_map(|x| {
                if let boxcars::Attribute::Reservation(r) = &x.attribute {
                    if r.name.as_ref().map(|x| x == user).unwrap_or(false) {
                        Some(&r.unique_id.remote_id)
                    } else {
                        None
                    }
                } else {
                    None
                }
            })
        })
        .last()
        .unwrap();

    (online_id, reservation.clone())
}

#[test]
fn test_long_psynet_id() {
    let data = include_bytes!("../assets/replays/good/d52eb.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "FunFactJac");
    assert_eq!(15633594671552264637, header_oid);

    if let boxcars::attributes::RemoteId::PsyNet(psy) = network_oid {
        assert_eq!(header_oid, psy.online_id);
    } else {
        panic!("Needed psynet remote_id");
    }
}

#[test]
fn test_short_psynet_id() {
    let data = include_bytes!("../assets/replays/good/60dfe.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "Shope");
    assert_eq!(18091002852234862424, header_oid);

    if let boxcars::attributes::RemoteId::PsyNet(psy) = network_oid {
        assert_eq!(header_oid, psy.online_id);
    } else {
        panic!("Needed psynet remote_id");
    }
}

#[test]
fn test_switch_id() {
    let data = include_bytes!("../assets/replays/good/7083.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "Leon");
    assert_eq!(13979735202661301154, header_oid);

    if let boxcars::attributes::RemoteId::Switch(switch) = network_oid {
        assert_eq!(header_oid, switch.online_id);
    } else {
        panic!("Needed switch remote_id");
    }
}

#[test]
fn test_long_ps4_id() {
    let data = include_bytes!("../assets/replays/good/159a4.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "SyCoz-Chaos");
    assert_eq!(3373421750759248985, header_oid);

    if let boxcars::attributes::RemoteId::PlayStation(ps) = network_oid {
        assert_eq!(header_oid, ps.online_id);
        assert_eq!(ps.name, "SyCoz-Chaos");
    } else {
        panic!("Needed playstation remote_id");
    }
}

#[test]
fn test_short_ps4_id() {
    let data = include_bytes!("../assets/replays/good/3d07e.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "TheGoldenGarp");
    assert_eq!(0, header_oid);

    if let boxcars::attributes::RemoteId::PlayStation(ps) = network_oid {
        assert_eq!(1, ps.online_id);
        assert_eq!(ps.name, "TheGoldenGarp");
    } else {
        panic!("Needed playstation remote_id");
    }
}
<commit_msg>Add sample test for endian check<commit_after>use boxcars::{self, ParserBuilder};
use std::borrow::Cow;

#[test]
fn test_sample1() {
    let data = include_bytes!("../assets/replays/good/3d07e.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let frames = replay.network_frames.unwrap().frames;

    // random usage of the API
    let new_count = frames
        .iter()
        .flat_map(|x| x.new_actors.iter())
        .filter(|x| x.actor_id.0 != x.object_id.0)
        .count();
    assert_eq!(4545, new_count);

    let sleeping_rigid_bodies = frames
        .iter()
        .flat_map(|x| x.updated_actors.iter())
        .filter(|act| match act.attribute {
            boxcars::Attribute::RigidBody(body) => body.sleeping,
            _ => false,
        })
        .count();

    assert_eq!(32, sleeping_rigid_bodies);

    let first_actor = frames
        .iter()
        .flat_map(|x| x.new_actors.iter())
        .find(|_| true)
        .unwrap();
    let first_update = frames
        .iter()
        .flat_map(|x| x.updated_actors.iter())
        .find(|_| true)
        .unwrap();

    let first_actor_id: boxcars::ActorId = first_actor.actor_id;
    assert_eq!(0, first_actor_id.0);

    let first_object_id: boxcars::ObjectId = first_actor.object_id;
    assert_eq!(26, first_object_id.0);

    let first_stream_id: boxcars::StreamId = first_update.stream_id;
    assert_eq!(31, first_stream_id.0);
}

fn extract_online_id(
    replay: &boxcars::Replay<'_>,
    user: &str,
) -> (u64, boxcars::attributes::RemoteId) {
    let (_, stats) = replay
        .properties
        .iter()
        .find(|(prop, _)| *prop == "PlayerStats")
        .unwrap();

    let online_id = match stats {
        boxcars::HeaderProp::Array(arr) => {
            let our_player = arr
                .iter()
                .find(|properties| {
                    properties
                        .iter()
                        .find(|(prop, val)| {
                            *prop == "Name" && *val == boxcars::HeaderProp::Str(Cow::Borrowed(user))
                        })
                        .is_some()
                })
                .unwrap();

            let (_, online_id) = our_player
                .iter()
                .find(|(prop, _val)| *prop == "OnlineID")
                .unwrap();
            if let boxcars::HeaderProp::QWord(oid) = online_id {
                *oid
            } else {
                panic!("unexpected property");
            }
        }
        _ => panic!("Expected array"),
    };

    let frames = &replay.network_frames.as_ref().unwrap().frames;
    let reservation = frames
        .iter()
        .flat_map(|x| {
            x.updated_actors.iter().filter_map(|x| {
                if let boxcars::Attribute::Reservation(r) = &x.attribute {
                    if r.name.as_ref().map(|x| x == user).unwrap_or(false) {
                        Some(&r.unique_id.remote_id)
                    } else {
                        None
                    }
                } else {
                    None
                }
            })
        })
        .last()
        .unwrap();

    (online_id, reservation.clone())
}

#[test]
fn test_long_psynet_id() {
    let data = include_bytes!("../assets/replays/good/d52eb.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "FunFactJac");
    assert_eq!(15633594671552264637, header_oid);

    if let boxcars::attributes::RemoteId::PsyNet(psy) = network_oid {
        assert_eq!(header_oid, psy.online_id);
    } else {
        panic!("Needed psynet remote_id");
    }
}

#[test]
fn test_short_psynet_id() {
    let data = include_bytes!("../assets/replays/good/60dfe.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "Shope");
    assert_eq!(18091002852234862424, header_oid);

    if let boxcars::attributes::RemoteId::PsyNet(psy) = network_oid {
        assert_eq!(header_oid, psy.online_id);
    } else {
        panic!("Needed psynet remote_id");
    }
}

#[test]
fn test_switch_id() {
    let data = include_bytes!("../assets/replays/good/7083.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "Leon");
    assert_eq!(13979735202661301154, header_oid);

    if let boxcars::attributes::RemoteId::Switch(switch) = network_oid {
        assert_eq!(header_oid, switch.online_id);
    } else {
        panic!("Needed switch remote_id");
    }
}

#[test]
fn test_long_ps4_id() {
    let data = include_bytes!("../assets/replays/good/159a4.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "SyCoz-Chaos");
    assert_eq!(3373421750759248985, header_oid);

    if let boxcars::attributes::RemoteId::PlayStation(ps) = network_oid {
        assert_eq!(header_oid, ps.online_id);
        assert_eq!(ps.name, "SyCoz-Chaos");
    } else {
        panic!("Needed playstation remote_id");
    }
}

#[test]
fn test_short_ps4_id() {
    let data = include_bytes!("../assets/replays/good/3d07e.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let (header_oid, network_oid) = extract_online_id(&replay, "TheGoldenGarp");
    assert_eq!(0, header_oid);

    if let boxcars::attributes::RemoteId::PlayStation(ps) = network_oid {
        assert_eq!(1, ps.online_id);
        assert_eq!(ps.name, "TheGoldenGarp");
    } else {
        panic!("Needed playstation remote_id");
    }
}

#[test]
fn test_preserve_endian() {
    let data = include_bytes!("../assets/replays/good/fc427.replay");
    let replay = ParserBuilder::new(&data[..])
        .always_check_crc()
        .must_parse_network_data()
        .parse()
        .unwrap();

    let frames = &replay.network_frames.as_ref().unwrap().frames;
    let new_paints: Vec<u32> = frames
        .iter()
        .flat_map(|x| x.updated_actors.iter())
        .filter_map(|ac| match &ac.attribute {
            boxcars::Attribute::LoadoutsOnline(x) => Some(x.blue.iter().flat_map(|pr| pr.iter())),
            _ => None,
        })
        .flat_map(|x| x)
        .filter_map(|x| match x.value {
            boxcars::attributes::ProductValue::NewPaint(p) => Some(p),
            _ => None,
        })
        .collect::<Vec<_>>();

    assert_eq!(*new_paints.get(0).unwrap(), 11);
}
<|endoftext|>


<commit_before>#![feature(proc_macro)]

mod tests {
    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register_macro::register;

    #[register()]
    struct Bit0Test {
        #[bitfield(at=0)]
        bit: u8,
    }

    #[test]
    fn bit_0_is_lsb() {
        let mut test = Bit0Test::default();

        assert_eq!(test.get_bit(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_bit(1);

        assert_eq!(test.get_bit(), 1);
        assert_eq!(test.0, [1;1]);
    }

    #[register()]
    struct Bit7Test {
        #[bitfield(at=7)]
        bit: u8,
    }

    #[test]
    fn bit_7_is_msb() {
        let mut test = Bit7Test::default();

        assert_eq!(test.get_bit(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_bit(1);

        assert_eq!(test.get_bit(), 1);
        assert_eq!(test.0, [128;1]);
    }

    #[register()]
    struct Bit8Test {
        #[bitfield(at=8)]
        bit: u8,
    }

    #[test]
    fn bit_8_is_lsb() {
        let mut test = Bit8Test::default();

        assert_eq!(test.get_bit(), 0);
        assert_eq!(test.0, [0;2]);

        test.set_bit(1);

        assert_eq!(test.get_bit(), 1);
        assert_eq!(test.0, [0,1]);
    }

    #[register()]
    struct Bit15Test {
        #[bitfield(at=15)]
        bit: u8,
    }

    #[test]
    fn bit_15_is_msb() {
        let mut test = Bit15Test::default();

        assert_eq!(test.get_bit(), 0);
        assert_eq!(test.0, [0;2]);

        test.set_bit(1);

        assert_eq!(test.get_bit(), 1);
        assert_eq!(test.0, [0,128]);
    }

    #[register()]
    struct Field00Test {
        #[bitfield(from=0, to=0)]
        field: u8,
    }

    #[test]
    fn field_0_0_is_in_lsb() {
        let mut test = Field00Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 1);
        assert_eq!(test.0, [0b1]);

        test.set_field(0b11);

        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b1]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b11111111]);
    }

    #[register()]
    struct Field03Test {
        #[bitfield(from=0, to=3)]
        field: u8,
    }

    #[test]
    fn field_0_3_is_in_lsb() {
        let mut test = Field03Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 1);
        assert_eq!(test.0, [0b1]);

        test.set_field(0b1111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b1111]);

        test.set_field(0b11111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b1111]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b11111111]);
    }

    #[register()]
    struct Field25Test {
        #[bitfield(from=2, to=5)]
        field: u8,
    }

    #[test]
    fn field_2_5_test() {
        let mut test = Field25Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b100]);

        test.set_field(0b1111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b111100]);

        test.set_field(0b11111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b111100]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b11111111]);
    }
}
<commit_msg>Refactor single bit tests<commit_after>#![feature(proc_macro)]

extern crate bitfield_register;
extern crate bitfield_register_macro;

use self::bitfield_register::BitfieldRegister;
use self::bitfield_register_macro::register;

macro_rules! test_default {
    ($reg_type:ty, expected_value = $value:expr, expected_data = $data:expr) => (
        let reg = <$reg_type as Default>::default();
        assert_eq!(reg.get_field(), $value);
        assert_eq!(reg.data(), &$data);
    )
}

macro_rules! test_get {
    ($reg_type:ty, from = $from:expr, expected_value = $value:expr) => (
        let reg : $reg_type = From::from($from);
        assert_eq!(reg.get_field(), $value);
    )
}

macro_rules! test_set {
    ($reg_type:ty, from = $from:expr, value = $value:expr, expected_value = $exp_value:expr, expected_data = $data:expr) => (
        let mut reg : $reg_type = From::from($from);
        reg.set_field($value);
        assert_eq!(reg.get_field(), $exp_value);
        assert_eq!(reg.data(), &$data);
    )
}

mod bit0_test {

    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register::BitfieldRegister;
    use super::bitfield_register_macro::register;

    #[register()]
    struct Bit0 {
        #[bitfield(at = 0)]
        field: u8,
    }

    #[test]
    fn bit_0_is_lsb() {
        test_default!(
            Bit0,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_get!(
            Bit0,
            from = [0;1],
            expected_value = 0
        );

        test_get!(
            Bit0,
            from = [0b1;1],
            expected_value = 1
        );

        test_get!(
            Bit0,
            from = [0b11111110;1],
            expected_value = 0
        );

        test_get!(
            Bit0,
            from = [0b11111111;1],
            expected_value = 1
        );

        test_set!(
            Bit0,
            from = [0;1],
            value = 0,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit0,
            from = [0;1],
            value = 1,
            expected_value = 1,
            expected_data = [1;1]
        );

        test_set!(
            Bit0,
            from = [0;1],
            value = 0b10,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit0,
            from = [0;1],
            value = 0b11,
            expected_value = 1,
            expected_data = [1;1]
        );

        test_set!(
            Bit0,
            from = [0b11111111;1],
            value = 0,
            expected_value = 0,
            expected_data = [0b11111110;1]
        );

        test_set!(
            Bit0,
            from = [0b11111111;1],
            value = 1,
            expected_value = 1,
            expected_data = [0b11111111;1]
        );
    }
}

mod bit2_test {
    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register::BitfieldRegister;
    use super::bitfield_register_macro::register;

    #[register()]
    struct Bit2 {
        #[bitfield(at = 2)]
        field: u8,
    }

    #[test]
    fn bit_2_test() {
        test_default!(
            Bit2,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_get!(
            Bit2,
            from = [0;1],
            expected_value = 0
        );

        test_get!(
            Bit2,
            from = [0b00000100;1],
            expected_value = 1
        );

        test_get!(
            Bit2,
            from = [0b11111011;1],
            expected_value = 0
        );

        test_get!(
            Bit2,
            from = [0b11111111;1],
            expected_value = 1
        );

        test_set!(
            Bit2,
            from = [0;1],
            value = 0,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit2,
            from = [0;1],
            value = 1,
            expected_value = 1,
            expected_data = [0b00000100;1]
        );

        test_set!(
            Bit2,
            from = [0;1],
            value = 0b10,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit2,
            from = [0;1],
            value = 0b11,
            expected_value = 1,
            expected_data = [0b00000100;1]
        );

        test_set!(
            Bit2,
            from = [0b11111111;1],
            value = 0,
            expected_value = 0,
            expected_data = [0b11111011;1]
        );

        test_set!(
            Bit2,
            from = [0b11111111;1],
            value = 1,
            expected_value = 1,
            expected_data = [0b11111111;1]
        );
    }
}

mod bit7_test {
    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register::BitfieldRegister;
    use super::bitfield_register_macro::register;

    #[register()]
    struct Bit7 {
        #[bitfield(at = 7)]
        field: u8,
    }

    #[test]
    fn bit_7_is_msb() {
        test_default!(
            Bit7,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_get!(
            Bit7,
            from = [0;1],
            expected_value = 0
        );

        test_get!(
            Bit7,
            from = [0b10000000;1],
            expected_value = 1
        );

        test_get!(
            Bit7,
            from = [0b01111111;1],
            expected_value = 0
        );

        test_get!(
            Bit7,
            from = [0b11111111;1],
            expected_value = 1
        );

        test_set!(
            Bit7,
            from = [0;1],
            value = 0,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit7,
            from = [0;1],
            value = 1,
            expected_value = 1,
            expected_data = [0b10000000;1]
        );

        test_set!(
            Bit7,
            from = [0;1],
            value = 0b10,
            expected_value = 0,
            expected_data = [0;1]
        );

        test_set!(
            Bit7,
            from = [0;1],
            value = 0b11,
            expected_value = 1,
            expected_data = [0b10000000;1]
        );

        test_set!(
            Bit7,
            from = [0b11111111;1],
            value = 0,
            expected_value = 0,
            expected_data = [0b01111111;1]
        );

        test_set!(
            Bit7,
            from = [0b11111111;1],
            value = 1,
            expected_value = 1,
            expected_data = [0b11111111;1]
        );
    }
}

mod bit8_test {

    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register::BitfieldRegister;
    use super::bitfield_register_macro::register;

    #[register()]
    struct Bit8 {
        #[bitfield(at = 8)]
        field: u8,
    }

    #[test]
    fn bit_8_is_lsb() {
        test_default!(
            Bit8,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_get!(
            Bit8,
            from = [0;2],
            expected_value = 0
        );

        test_get!(
            Bit8,
            from = [0,0b1],
            expected_value = 1
        );

        test_get!(
            Bit8,
            from = [0,0b11111110],
            expected_value = 0
        );

        test_get!(
            Bit8,
            from = [0,0b11111111],
            expected_value = 1
        );

        test_set!(
            Bit8,
            from = [0;2],
            value = 0,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_set!(
            Bit8,
            from = [0;2],
            value = 1,
            expected_value = 1,
            expected_data = [0,1]
        );

        test_set!(
            Bit8,
            from = [0;2],
            value = 0b10,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_set!(
            Bit8,
            from = [0;2],
            value = 0b11,
            expected_value = 1,
            expected_data = [0,1]
        );

        test_set!(
            Bit8,
            from = [0,0b11111111],
            value = 0,
            expected_value = 0,
            expected_data = [0,0b11111110]
        );

        test_set!(
            Bit8,
            from = [0,0b11111111],
            value = 1,
            expected_value = 1,
            expected_data = [0,0b11111111]
        );
    }
}

mod bit15_test {

    extern crate bitfield_register;
    extern crate bitfield_register_macro;

    use self::bitfield_register::BitfieldRegister;
    use super::bitfield_register_macro::register;

    #[register()]
    struct Bit15 {
        #[bitfield(at = 15)]
        field: u8,
    }

    #[test]
    fn bit_15_is_msb() {
        test_default!(
            Bit15,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_get!(
            Bit15,
            from = [0;2],
            expected_value = 0
        );

        test_get!(
            Bit15,
            from = [0,0b10000000],
            expected_value = 1
        );

        test_get!(
            Bit15,
            from = [0,0b01111111],
            expected_value = 0
        );

        test_get!(
            Bit15,
            from = [0,0b11111111],
            expected_value = 1
        );

        test_set!(
            Bit15,
            from = [0;2],
            value = 0,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_set!(
            Bit15,
            from = [0;2],
            value = 1,
            expected_value = 1,
            expected_data = [0,0b10000000]
        );

        test_set!(
            Bit15,
            from = [0;2],
            value = 0b10,
            expected_value = 0,
            expected_data = [0;2]
        );

        test_set!(
            Bit15,
            from = [0;2],
            value = 0b11,
            expected_value = 1,
            expected_data = [0,0b10000000]
        );

        test_set!(
            Bit15,
            from = [0,0b11111111],
            value = 0,
            expected_value = 0,
            expected_data = [0,0b01111111]
        );

        test_set!(
            Bit15,
            from = [0,0b11111111],
            value = 1,
            expected_value = 1,
            expected_data = [0,0b11111111]
        );
    }
}

    #[register()]
    struct Field00Test {
        #[bitfield(from=0, to=0)]
        field: u8,
    }

    #[test]
    fn field_0_0_is_in_lsb() {
        let mut test = Field00Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 1);
        assert_eq!(test.0, [0b1]);

        test.set_field(0b11);

        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b1]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b11111111]);
    }

    #[register()]
    struct Field03Test {
        #[bitfield(from=0, to=3)]
        field: u8,
    }

    #[test]
    fn field_0_3_is_in_lsb() {
        let mut test = Field03Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 1);
        assert_eq!(test.0, [0b1]);

        test.set_field(0b1111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b1111]);

        test.set_field(0b11111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b1111]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b11111111]);
    }

    #[register()]
    struct Field25Test {
        #[bitfield(from=2, to=5)]
        field: u8,
    }

    #[test]
    fn field_2_5_test() {
        let mut test = Field25Test::default();

        assert_eq!(test.get_field(), 0);
        assert_eq!(test.0, [0;1]);

        test.set_field(0b1);

        assert_eq!(test.get_field(), 0b1);
        assert_eq!(test.0, [0b100]);

        test.set_field(0b1111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b111100]);

        test.set_field(0b11111);

        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b111100]);

        test.0 = [0b11111111];
        assert_eq!(test.get_field(), 0b1111);
        assert_eq!(test.0, [0b11111111]);
    }
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Read;

use hyper::{Body, Request, Response};
use hyper::header::CONTENT_TYPE;

use octobot_lib::errors::Result;
use crate::server::http::Handler;
use crate::http_util;

pub struct HtmlHandler {
    path: String,
    contents: String,
}

impl HtmlHandler {
    pub fn new(path: &str, contents: &str) -> Box<HtmlHandler> {
        Box::new(HtmlHandler {
            path: path.into(),
            contents: contents.into(),
        })
    }

    pub fn contents(&self) -> String {
        if http_util::is_dev_mode() && self.path.len() > 0 {
            let mut file_contents = String::new();
            let mut file = match File::open(format!("src/assets/{}", self.path)) {
                Ok(f) => f,
                Err(e) => return format!("Error opening file: {}", e),
            };
            if let Err(e) = file.read_to_string(&mut file_contents) {
                return format!("Error reading file: {}", e);
            }

            file_contents
        } else {
            self.contents.clone()
        }
    }
}

#[async_trait::async_trait]
impl Handler for HtmlHandler {
    async fn handle(&self, _: Request<Body>) -> Result<Response<Body>> {
        let mut resp = Response::new(Body::from(self.contents()));
        resp.headers_mut().insert(CONTENT_TYPE, "text/html".parse().unwrap());

        Ok(resp)
    }
}
<commit_msg>Fix relative path for devmode (#302)<commit_after>use std::fs::File;
use std::io::Read;

use hyper::{Body, Request, Response};
use hyper::header::CONTENT_TYPE;

use octobot_lib::errors::Result;
use crate::server::http::Handler;
use crate::http_util;

pub struct HtmlHandler {
    path: String,
    contents: String,
}

impl HtmlHandler {
    pub fn new(path: &str, contents: &str) -> Box<HtmlHandler> {
        Box::new(HtmlHandler {
            path: path.into(),
            contents: contents.into(),
        })
    }

    pub fn contents(&self) -> String {
        if http_util::is_dev_mode() && self.path.len() > 0 {
            let mut file_contents = String::new();
            let mut file = match File::open(format!("octobot/src/assets/{}", self.path)) {
                Ok(f) => f,
                Err(e) => return format!("Error opening file: {}", e),
            };
            if let Err(e) = file.read_to_string(&mut file_contents) {
                return format!("Error reading file: {}", e);
            }

            file_contents
        } else {
            self.contents.clone()
        }
    }
}

#[async_trait::async_trait]
impl Handler for HtmlHandler {
    async fn handle(&self, _: Request<Body>) -> Result<Response<Body>> {
        let mut resp = Response::new(Body::from(self.contents()));
        resp.headers_mut().insert(CONTENT_TYPE, "text/html".parse().unwrap());

        Ok(resp)
    }
}
<|endoftext|>


<commit_before>
fn main() {}
<commit_msg>Bandwidth server one example<commit_after>extern crate libmodbus_rs;

mod unit_test_config;

use libmodbus_rs::{Modbus, ModbusMapping, ModbusServer, ModbusTCP, ModbusRTU};
use std::env;
use std::io::Error;
use std::mem::size_of;
use unit_test_config::*;

fn run() -> Result<(), std::io::Error> {
    let args: Vec<_> = env::args().collect();
    let backend = if args.len() > 1 {
        match args[1].to_lowercase().as_ref() {
            "tcp" => Backend::TCP,
            "rtu" => Backend::RTU,
            _ => {
                println!("Usage:\n  {} [tcp|rtu] - Modbus client to measure data bandwith\n", args[0]);
                std::process::exit(-1);
            }
        }
    } else {
        Backend::TCP
    };

    let mut modbus;
    let mut socket;
    if backend == Backend::TCP {
        modbus = Modbus::new_tcp("127.0.0.1", 1502).expect("Could not create TCP context");
        socket = modbus.tcp_listen(1).expect("Could not listen to TCP socket");
        modbus.tcp_accept(&mut socket);
    } else {
        modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).expect("Could not create RTU context");
        modbus.set_slave(1);
        modbus.connect();
    }

    let mb_mapping = ModbusMapping::new(Modbus::MAX_READ_BITS, 0,
                                        Modbus::MAX_READ_REGISTERS, 0).expect("Failed to allocate the mapping");

    loop {
        let mut query = vec![0u8; Modbus::TCP_MAX_ADU_LENGTH];

        match modbus.receive(&mut query) {
            Ok(rc) => modbus.reply(&query, rc, &mb_mapping),
            Err(err) => {
                println!("Quit the loop: {}", err);
                break;
            }
        };
    }

    Ok(())
}

fn main() {
    if let Err(ref err) = run() {
        println!("{}", Modbus::strerror(err.raw_os_error().unwrap()));

        std::process::exit(1)
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::types::Namespace;
use itertools::Itertools;
use std::collections::HashMap;

/// Type to generate unique names for entries in the [cxx::bridge]
/// mod which is flat.
///
/// # All about the names involved in autocxx
///
/// A given function may have many, many names. From C++ to Rust...
///
/// 1. The actual C++ name. Fixed, obviously.
/// 2. The name reported by bindgen. Not always the same, as
///    bindgen may generate a different name for different overloads.
///    See `overload_tracker` for the conversion here.
/// 3. The name in the cxx::bridge mod. This is a flat namespace,
///    and it's the responsibility of this type to generate a
///    suitable name here.
///    If this is different from the C++ name in (1), we'll
///    add a #[cxx_name] attribute to the cxx::bridge declaration.
/// 4. The name we wish to present to Rust users. Again, we have
///    to take stock of the fact Rust doesn't support overloading
///    so two different functions called 'get' may end up being
///    'get' and 'get1'. Yet, this may not be the same as the
///    bindgen name in (2) because we wish to generate such number
///    sequences on a per-type basis, whilst bindgen does it globally.
///
/// This fourth name, the final Rust user name, may be finagled
/// into place in three different ways:
/// 1. For methods, we generate an 'impl' block where the
///    method name is the intended name, but it calls the
///    cxxbridge name.
/// 2. For simple functions, we use the #[rust_name] attribute.
/// 3. Occasionally, there can be conflicts in the rust_name
///    namespace (if there are two identically named functions
///    in different C++ namespaces). That's detected by
///    rust_name_tracker.rs. In such a case, we'll omit the
///    #[rust_name] attribute and instead generate a 'use A = B;'
///    declaration in the mod which we generate for the output
///    namespace.
#[derive(Default)]
pub(crate) struct BridgeNameTracker {
    next_cxx_bridge_name_for_prefix: HashMap<String, usize>,
}

impl BridgeNameTracker {
    pub(crate) fn new() -> Self {
        Self::default()
    }

    /// Figure out the least confusing unique name for this function in the
    /// cxx::bridge section, which has a flat namespace.
    /// We mostly just qualify the name with the namespace_with_underscores.
    /// It doesn't really matter; we'll rebind these things to
    /// better Rust-side names so it's really just a matter of how it shows up
    /// in stack traces and for our own sanity as maintainers of autocxx.
    /// This may become unnecessary if and when cxx supports hierarchic
    /// namespace mods.
    /// There is a slight advantage in using the same name as either the
    /// Rust or C++ symbols as it reduces the amount of rebinding required
    /// by means of cxx_name or rust_name attributes. In extreme cases it
    /// may even allow us to remove whole impl blocks. So we may wish to try
    /// harder to find better names in future instead of always prepending
    /// the namespace.
    pub(crate) fn get_unique_cxx_bridge_name(
        &mut self,
        type_name: Option<&str>,
        found_name: &str,
        ns: &Namespace,
    ) -> String {
        let count = self
            .next_cxx_bridge_name_for_prefix
            .entry(found_name.to_string())
            .or_default();
        if *count == 0 {
            // Oh, good, we can use this function name as-is.
            *count += 1;
            return found_name.to_string();
        }
        let prefix = ns
            .iter()
            .cloned()
            .chain(type_name.iter().map(|x| x.to_string()))
            .chain(std::iter::once(found_name.to_string()))
            .join("_");
        let count = self
            .next_cxx_bridge_name_for_prefix
            .entry(prefix.clone())
            .or_default();
        if *count == 0 {
            *count += 1;
            prefix
        } else {
            let r = format!("{}_autocxx{}", prefix, count);
            *count += 1;
            r
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::types::Namespace;

    use super::BridgeNameTracker;

    #[test]
    fn test() {
        let mut bnt = BridgeNameTracker::new();
        let ns_root = Namespace::new();
        let ns_a = Namespace::from_user_input("A");
        let ns_b = Namespace::from_user_input("B");
        let ns_ab = Namespace::from_user_input("A::B");
        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "do", &ns_root), "do");
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(None, "do", &ns_root),
            "do_autocxx1"
        );
        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "did", &ns_root), "did");
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
            "ty1_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
            "ty1_do_autocxx1"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty2"), "do", &ns_root),
            "ty2_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_a),
            "A_ty_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_b),
            "B_ty_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_ab),
            "A_B_ty_do"
        );
    }
}
<commit_msg>Avoid the name 'new'<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::types::Namespace;
use itertools::Itertools;
use std::collections::HashMap;

/// Type to generate unique names for entries in the [cxx::bridge]
/// mod which is flat.
///
/// # All about the names involved in autocxx
///
/// A given function may have many, many names. From C++ to Rust...
///
/// 1. The actual C++ name. Fixed, obviously.
/// 2. The name reported by bindgen. Not always the same, as
///    bindgen may generate a different name for different overloads.
///    See `overload_tracker` for the conversion here.
/// 3. The name in the cxx::bridge mod. This is a flat namespace,
///    and it's the responsibility of this type to generate a
///    suitable name here.
///    If this is different from the C++ name in (1), we'll
///    add a #[cxx_name] attribute to the cxx::bridge declaration.
/// 4. The name we wish to present to Rust users. Again, we have
///    to take stock of the fact Rust doesn't support overloading
///    so two different functions called 'get' may end up being
///    'get' and 'get1'. Yet, this may not be the same as the
///    bindgen name in (2) because we wish to generate such number
///    sequences on a per-type basis, whilst bindgen does it globally.
///
/// This fourth name, the final Rust user name, may be finagled
/// into place in three different ways:
/// 1. For methods, we generate an 'impl' block where the
///    method name is the intended name, but it calls the
///    cxxbridge name.
/// 2. For simple functions, we use the #[rust_name] attribute.
/// 3. Occasionally, there can be conflicts in the rust_name
///    namespace (if there are two identically named functions
///    in different C++ namespaces). That's detected by
///    rust_name_tracker.rs. In such a case, we'll omit the
///    #[rust_name] attribute and instead generate a 'use A = B;'
///    declaration in the mod which we generate for the output
///    namespace.
#[derive(Default)]
pub(crate) struct BridgeNameTracker {
    next_cxx_bridge_name_for_prefix: HashMap<String, usize>,
}

impl BridgeNameTracker {
    pub(crate) fn new() -> Self {
        Self::default()
    }

    /// Figure out the least confusing unique name for this function in the
    /// cxx::bridge section, which has a flat namespace.
    /// We mostly just qualify the name with the namespace_with_underscores.
    /// It doesn't really matter; we'll rebind these things to
    /// better Rust-side names so it's really just a matter of how it shows up
    /// in stack traces and for our own sanity as maintainers of autocxx.
    /// This may become unnecessary if and when cxx supports hierarchic
    /// namespace mods.
    /// There is a slight advantage in using the same name as either the
    /// Rust or C++ symbols as it reduces the amount of rebinding required
    /// by means of cxx_name or rust_name attributes. In extreme cases it
    /// may even allow us to remove whole impl blocks. So we may wish to try
    /// harder to find better names in future instead of always prepending
    /// the namespace.
    pub(crate) fn get_unique_cxx_bridge_name(
        &mut self,
        type_name: Option<&str>,
        found_name: &str,
        ns: &Namespace,
    ) -> String {
        let found_name = if found_name == "new" {
            "new_autocxx"
        } else {
            found_name
        };
        let count = self
            .next_cxx_bridge_name_for_prefix
            .entry(found_name.to_string())
            .or_default();
        if *count == 0 {
            // Oh, good, we can use this function name as-is.
            *count += 1;
            return found_name.to_string();
        }
        let prefix = ns
            .iter()
            .cloned()
            .chain(type_name.iter().map(|x| x.to_string()))
            .chain(std::iter::once(found_name.to_string()))
            .join("_");
        let count = self
            .next_cxx_bridge_name_for_prefix
            .entry(prefix.clone())
            .or_default();
        if *count == 0 {
            *count += 1;
            prefix
        } else {
            let r = format!("{}_autocxx{}", prefix, count);
            *count += 1;
            r
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::types::Namespace;

    use super::BridgeNameTracker;

    #[test]
    fn test() {
        let mut bnt = BridgeNameTracker::new();
        let ns_root = Namespace::new();
        let ns_a = Namespace::from_user_input("A");
        let ns_b = Namespace::from_user_input("B");
        let ns_ab = Namespace::from_user_input("A::B");
        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "do", &ns_root), "do");
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(None, "do", &ns_root),
            "do_autocxx1"
        );
        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "did", &ns_root), "did");
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
            "ty1_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
            "ty1_do_autocxx1"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty2"), "do", &ns_root),
            "ty2_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_a),
            "A_ty_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_b),
            "B_ty_do"
        );
        assert_eq!(
            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_ab),
            "A_B_ty_do"
        );
    }
}
<|endoftext|>


<commit_before>mod cursor;
pub mod raw;
#[doc(hidden)]
pub mod result;
mod row;
mod stmt;

use std::ffi::CString;
use std::os::raw as libc;

use self::cursor::*;
use self::raw::RawConnection;
use self::result::PgResult;
use self::stmt::Statement;
use crate::connection::*;
use crate::deserialize::FromSqlRow;
use crate::expression::QueryMetadata;
use crate::pg::metadata_lookup::{GetPgMetadataCache, PgMetadataCache};
use crate::pg::{Pg, TransactionBuilder};
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::query_builder::*;
use crate::result::ConnectionError::CouldntSetupConfiguration;
use crate::result::Error::DeserializationError;
use crate::result::*;

/// The connection string expected by `PgConnection::establish`
/// should be a PostgreSQL connection string, as documented at
/// <https://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-CONNSTRING>
#[allow(missing_debug_implementations)]
pub struct PgConnection {
    pub(crate) raw_connection: RawConnection,
    pub(crate) transaction_manager: AnsiTransactionManager,
    statement_cache: StatementCache<Pg, Statement>,
    metadata_cache: PgMetadataCache,
}

unsafe impl Send for PgConnection {}

impl SimpleConnection for PgConnection {
    fn batch_execute(&self, query: &str) -> QueryResult<()> {
        let query = CString::new(query)?;
        let inner_result = unsafe { self.raw_connection.exec(query.as_ptr()) };
        PgResult::new(inner_result?)?;
        Ok(())
    }
}

impl Connection for PgConnection {
    type Backend = Pg;
    type TransactionManager = AnsiTransactionManager;

    fn establish(database_url: &str) -> ConnectionResult<PgConnection> {
        RawConnection::establish(database_url).and_then(|raw_conn| {
            let conn = PgConnection {
                raw_connection: raw_conn,
                transaction_manager: AnsiTransactionManager::new(),
                statement_cache: StatementCache::new(),
                metadata_cache: PgMetadataCache::new(),
            };
            conn.set_config_options()
                .map_err(CouldntSetupConfiguration)?;
            Ok(conn)
        })
    }

    #[doc(hidden)]
    fn execute(&self, query: &str) -> QueryResult<usize> {
        self.execute_inner(query).map(|res| res.rows_affected())
    }

    #[doc(hidden)]
    fn load<T, U>(&self, source: T) -> QueryResult<Vec<U>>
    where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        U: FromSqlRow<T::SqlType, Self::Backend>,
        Self::Backend: QueryMetadata<T::SqlType>,
    {
        let (query, params) = self.prepare_query(&source.as_query())?;
        let result = query.execute(self, &params)?;
        let cursor = Cursor::new(&result);

        cursor
            .map(|row| U::build_from_row(&row).map_err(DeserializationError))
            .collect::<QueryResult<Vec<_>>>()
    }

    #[doc(hidden)]
    fn execute_returning_count<T>(&self, source: &T) -> QueryResult<usize>
    where
        T: QueryFragment<Pg> + QueryId,
    {
        let (query, params) = self.prepare_query(source)?;
        query.execute(self, &params).map(|r| r.rows_affected())
    }

    #[doc(hidden)]
    fn transaction_manager(&self) -> &Self::TransactionManager {
        &self.transaction_manager
    }
}

impl GetPgMetadataCache for PgConnection {
    fn get_metadata_cache(&self) -> &PgMetadataCache {
        &self.metadata_cache
    }
}

impl PgConnection {
    /// Build a transaction, specifying additional details such as isolation level
    ///
    /// See [`TransactionBuilder`] for more examples.
    ///
    /// [`TransactionBuilder`]: ../pg/struct.TransactionBuilder.html
    ///
    /// ```rust
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # fn main() {
    /// #     run_test().unwrap();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use schema::users::dsl::*;
    /// #     let conn = connection_no_transaction();
    /// conn.build_transaction()
    ///     .read_only()
    ///     .serializable()
    ///     .deferrable()
    ///     .run(|| Ok(()))
    /// # }
    /// ```
    pub fn build_transaction(&self) -> TransactionBuilder {
        TransactionBuilder::new(self)
    }

    #[allow(clippy::type_complexity)]
    fn prepare_query<T: QueryFragment<Pg> + QueryId>(
        &self,
        source: &T,
    ) -> QueryResult<(MaybeCached<Statement>, Vec<Option<Vec<u8>>>)> {
        let mut bind_collector = RawBytesBindCollector::<Pg>::new();
        source.collect_binds(&mut bind_collector, self)?;
        let binds = bind_collector.binds;
        let metadata = bind_collector.metadata;

        let cache_len = self.statement_cache.len();
        let query = self
            .statement_cache
            .cached_statement(source, &metadata, |sql| {
                let query_name = if source.is_safe_to_cache_prepared()? {
                    Some(format!("__diesel_stmt_{}", cache_len))
                } else {
                    None
                };
                Statement::prepare(self, sql, query_name.as_ref().map(|s| &**s), &metadata)
            });

        Ok((query?, binds))
    }

    fn execute_inner(&self, query: &str) -> QueryResult<PgResult> {
        let query = Statement::prepare(self, query, None, &[])?;
        query.execute(self, &Vec::new())
    }

    fn set_config_options(&self) -> QueryResult<()> {
        self.execute("SET TIME ZONE 'UTC'")?;
        self.execute("SET CLIENT_ENCODING TO 'UTF8'")?;
        self.raw_connection
            .set_notice_processor(noop_notice_processor);
        Ok(())
    }
}

extern "C" fn noop_notice_processor(_: *mut libc::c_void, _message: *const libc::c_char) {}

#[cfg(test)]
mod tests {
    extern crate dotenv;

    use self::dotenv::dotenv;
    use std::env;

    use super::*;
    use crate::dsl::sql;
    use crate::prelude::*;
    use crate::sql_types::{Integer, VarChar};

    #[test]
    fn prepared_statements_are_cached() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>());

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(1, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_identical_sql_but_different_types_are_cached_separately() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>());
        let query2 = crate::select("hi".into_sql::<VarChar>());

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_identical_types_and_sql_but_different_bind_types_are_cached_separately() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>()).into_boxed::<Pg>();
        let query2 = crate::select("hi".into_sql::<VarChar>()).into_boxed::<Pg>();

        assert_eq!(0, connection.statement_cache.len());
        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    sql_function!(fn lower(x: VarChar) -> VarChar);

    #[test]
    fn queries_with_identical_types_and_binds_but_different_sql_are_cached_separately() {
        let connection = connection();

        let hi = "HI".into_sql::<VarChar>();
        let query = crate::select(hi).into_boxed::<Pg>();
        let query2 = crate::select(lower(hi)).into_boxed::<Pg>();

        assert_eq!(0, connection.statement_cache.len());
        assert_eq!(Ok("HI".to_string()), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_sql_literal_nodes_are_not_cached() {
        let connection = connection();
        let query = crate::select(sql::<Integer>("1"));

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(0, connection.statement_cache.len());
    }

    fn connection() -> PgConnection {
        dotenv().ok();
        let database_url = env::var("PG_DATABASE_URL")
            .or_else(|_| env::var("DATABASE_URL"))
            .expect("DATABASE_URL must be set in order to run tests");
        PgConnection::establish(&database_url).unwrap()
    }
}
<commit_msg>add tests<commit_after>mod cursor;
pub mod raw;
#[doc(hidden)]
pub mod result;
mod row;
mod stmt;

use std::ffi::CString;
use std::os::raw as libc;

use self::cursor::*;
use self::raw::RawConnection;
use self::result::PgResult;
use self::stmt::Statement;
use crate::connection::*;
use crate::deserialize::FromSqlRow;
use crate::expression::QueryMetadata;
use crate::pg::metadata_lookup::{GetPgMetadataCache, PgMetadataCache};
use crate::pg::{Pg, TransactionBuilder};
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::query_builder::*;
use crate::result::ConnectionError::CouldntSetupConfiguration;
use crate::result::Error::DeserializationError;
use crate::result::*;

/// The connection string expected by `PgConnection::establish`
/// should be a PostgreSQL connection string, as documented at
/// <https://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-CONNSTRING>
#[allow(missing_debug_implementations)]
pub struct PgConnection {
    pub(crate) raw_connection: RawConnection,
    pub(crate) transaction_manager: AnsiTransactionManager,
    statement_cache: StatementCache<Pg, Statement>,
    metadata_cache: PgMetadataCache,
}

unsafe impl Send for PgConnection {}

impl SimpleConnection for PgConnection {
    fn batch_execute(&self, query: &str) -> QueryResult<()> {
        let query = CString::new(query)?;
        let inner_result = unsafe { self.raw_connection.exec(query.as_ptr()) };
        PgResult::new(inner_result?)?;
        Ok(())
    }
}

impl Connection for PgConnection {
    type Backend = Pg;
    type TransactionManager = AnsiTransactionManager;

    fn establish(database_url: &str) -> ConnectionResult<PgConnection> {
        RawConnection::establish(database_url).and_then(|raw_conn| {
            let conn = PgConnection {
                raw_connection: raw_conn,
                transaction_manager: AnsiTransactionManager::new(),
                statement_cache: StatementCache::new(),
                metadata_cache: PgMetadataCache::new(),
            };
            conn.set_config_options()
                .map_err(CouldntSetupConfiguration)?;
            Ok(conn)
        })
    }

    #[doc(hidden)]
    fn execute(&self, query: &str) -> QueryResult<usize> {
        self.execute_inner(query).map(|res| res.rows_affected())
    }

    #[doc(hidden)]
    fn load<T, U>(&self, source: T) -> QueryResult<Vec<U>>
    where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        U: FromSqlRow<T::SqlType, Self::Backend>,
        Self::Backend: QueryMetadata<T::SqlType>,
    {
        let (query, params) = self.prepare_query(&source.as_query())?;
        let result = query.execute(self, &params)?;
        let cursor = Cursor::new(&result);

        cursor
            .map(|row| U::build_from_row(&row).map_err(DeserializationError))
            .collect::<QueryResult<Vec<_>>>()
    }

    #[doc(hidden)]
    fn execute_returning_count<T>(&self, source: &T) -> QueryResult<usize>
    where
        T: QueryFragment<Pg> + QueryId,
    {
        let (query, params) = self.prepare_query(source)?;
        query.execute(self, &params).map(|r| r.rows_affected())
    }

    #[doc(hidden)]
    fn transaction_manager(&self) -> &Self::TransactionManager {
        &self.transaction_manager
    }
}

impl GetPgMetadataCache for PgConnection {
    fn get_metadata_cache(&self) -> &PgMetadataCache {
        &self.metadata_cache
    }
}

impl PgConnection {
    /// Build a transaction, specifying additional details such as isolation level
    ///
    /// See [`TransactionBuilder`] for more examples.
    ///
    /// [`TransactionBuilder`]: ../pg/struct.TransactionBuilder.html
    ///
    /// ```rust
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # fn main() {
    /// #     run_test().unwrap();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use schema::users::dsl::*;
    /// #     let conn = connection_no_transaction();
    /// conn.build_transaction()
    ///     .read_only()
    ///     .serializable()
    ///     .deferrable()
    ///     .run(|| Ok(()))
    /// # }
    /// ```
    pub fn build_transaction(&self) -> TransactionBuilder {
        TransactionBuilder::new(self)
    }

    #[allow(clippy::type_complexity)]
    fn prepare_query<T: QueryFragment<Pg> + QueryId>(
        &self,
        source: &T,
    ) -> QueryResult<(MaybeCached<Statement>, Vec<Option<Vec<u8>>>)> {
        let mut bind_collector = RawBytesBindCollector::<Pg>::new();
        source.collect_binds(&mut bind_collector, self)?;
        let binds = bind_collector.binds;
        let metadata = bind_collector.metadata;

        let cache_len = self.statement_cache.len();
        let query = self
            .statement_cache
            .cached_statement(source, &metadata, |sql| {
                let query_name = if source.is_safe_to_cache_prepared()? {
                    Some(format!("__diesel_stmt_{}", cache_len))
                } else {
                    None
                };
                Statement::prepare(self, sql, query_name.as_ref().map(|s| &**s), &metadata)
            });

        Ok((query?, binds))
    }

    fn execute_inner(&self, query: &str) -> QueryResult<PgResult> {
        let query = Statement::prepare(self, query, None, &[])?;
        query.execute(self, &Vec::new())
    }

    fn set_config_options(&self) -> QueryResult<()> {
        self.execute("SET TIME ZONE 'UTC'")?;
        self.execute("SET CLIENT_ENCODING TO 'UTF8'")?;
        self.raw_connection
            .set_notice_processor(noop_notice_processor);
        Ok(())
    }
}

extern "C" fn noop_notice_processor(_: *mut libc::c_void, _message: *const libc::c_char) {}

#[cfg(test)]
mod tests {
    extern crate dotenv;

    use self::dotenv::dotenv;
    use std::env;

    use super::*;
    use crate::dsl::sql;
    use crate::prelude::*;
    use crate::result::Error::DatabaseError;
    use crate::sql_types::{Integer, VarChar};

    #[test]
    fn malformed_sql_query() {
        let connection = connection();
        let query =
            crate::sql_query("SELECT not_existent FROM also_not_there;").execute(&connection);
        if let Err(err) = query {
            match err {
                DatabaseError(_, string) => {
                    assert_eq!(Some(26), string.statement_position());
                }
                _ => unreachable!(),
            }
        } else {
            unreachable!();
        }
    }

    #[test]
    fn prepared_statements_are_cached() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>());

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(1, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_identical_sql_but_different_types_are_cached_separately() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>());
        let query2 = crate::select("hi".into_sql::<VarChar>());

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_identical_types_and_sql_but_different_bind_types_are_cached_separately() {
        let connection = connection();

        let query = crate::select(1.into_sql::<Integer>()).into_boxed::<Pg>();
        let query2 = crate::select("hi".into_sql::<VarChar>()).into_boxed::<Pg>();

        assert_eq!(0, connection.statement_cache.len());
        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    sql_function!(fn lower(x: VarChar) -> VarChar);

    #[test]
    fn queries_with_identical_types_and_binds_but_different_sql_are_cached_separately() {
        let connection = connection();

        let hi = "HI".into_sql::<VarChar>();
        let query = crate::select(hi).into_boxed::<Pg>();
        let query2 = crate::select(lower(hi)).into_boxed::<Pg>();

        assert_eq!(0, connection.statement_cache.len());
        assert_eq!(Ok("HI".to_string()), query.get_result(&connection));
        assert_eq!(Ok("hi".to_string()), query2.get_result(&connection));
        assert_eq!(2, connection.statement_cache.len());
    }

    #[test]
    fn queries_with_sql_literal_nodes_are_not_cached() {
        let connection = connection();
        let query = crate::select(sql::<Integer>("1"));

        assert_eq!(Ok(1), query.get_result(&connection));
        assert_eq!(0, connection.statement_cache.len());
    }

    fn connection() -> PgConnection {
        dotenv().ok();
        let database_url = env::var("PG_DATABASE_URL")
            .or_else(|_| env::var("DATABASE_URL"))
            .expect("DATABASE_URL must be set in order to run tests");
        PgConnection::establish(&database_url).unwrap()
    }
}
<|endoftext|>


<commit_before>use std::{
    future::Future,
    pin::Pin,
    sync::Arc,
    task::{Context, Poll, Waker},
};

use parking_lot::{Condvar, Mutex};

use super::Result;

#[derive(Debug)]
struct OneShotState<T> {
    filled: bool,
    fused: bool,
    item: Option<T>,
    waker: Option<Waker>,
}

impl<T> Default for OneShotState<T> {
    fn default() -> OneShotState<T> {
        OneShotState {
            filled: false,
            fused: false,
            item: None,
            waker: None,
        }
    }
}

/// A Future value which may or may not be filled
#[derive(Debug)]
pub struct OneShot<T> {
    mu: Arc<Mutex<OneShotState<T>>>,
    cv: Arc<Condvar>,
}

/// The completer side of the Future
pub struct OneShotFiller<T> {
    mu: Arc<Mutex<OneShotState<T>>>,
    cv: Arc<Condvar>,
}

impl<T> OneShot<T> {
    /// Create a new OneShotFiller and the OneShot
    /// that will be filled by its completion.
    pub fn pair() -> (OneShotFiller<T>, Self) {
        let mu = Arc::new(Mutex::new(OneShotState::default()));
        let cv = Arc::new(Condvar::new());
        let future = Self {
            mu: mu.clone(),
            cv: cv.clone(),
        };
        let filler = OneShotFiller { mu, cv };

        (filler, future)
    }

    /// Block on the OneShot's completion
    /// or dropping of the OneShotFiller
    pub fn wait(self) -> Option<T> {
        let mut inner = self.mu.lock();
        while !inner.filled {
            self.cv.wait(&mut inner);
        }
        inner.item.take()
    }

    /// Block on the OneShot's completion
    /// or dropping of the OneShotFiller.
    ///
    /// # Panics
    /// panics if the OneShotFiller is dropped
    /// without completing the promise.
    pub fn unwrap(self) -> T {
        self.wait().unwrap()
    }
}

impl<T> Future for OneShot<Result<T>> {
    type Output = Result<T>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut state = self.mu.lock();
        if state.fused {
            return Poll::Pending;
        }
        state.waker = Some(cx.waker().clone());
        if state.filled {
            state.fused = true;
            Poll::Ready(state.item.take().unwrap())
        } else {
            Poll::Pending
        }
    }
}

impl<T> OneShotFiller<T> {
    /// Complete the OneShot
    pub fn fill(self, inner: T) {
        let mut state = self.mu.lock();

        if let Some(waker) = state.waker.take() {
            waker.wake();
        }

        state.filled = true;
        state.item = Some(inner);

        self.cv.notify_all();
    }
}

impl<T> Drop for OneShotFiller<T> {
    fn drop(&mut self) {
        let mut state = self.mu.lock();

        if state.filled {
            return;
        }

        if let Some(waker) = state.waker.take() {
            waker.wake();
        }

        state.filled = true;

        self.cv.notify_all();
    }
}
<commit_msg>Only clone the Context's waker when the OneShot is not yet ready<commit_after>use std::{
    future::Future,
    pin::Pin,
    sync::Arc,
    task::{Context, Poll, Waker},
};

use parking_lot::{Condvar, Mutex};

use super::Result;

#[derive(Debug)]
struct OneShotState<T> {
    filled: bool,
    fused: bool,
    item: Option<T>,
    waker: Option<Waker>,
}

impl<T> Default for OneShotState<T> {
    fn default() -> OneShotState<T> {
        OneShotState {
            filled: false,
            fused: false,
            item: None,
            waker: None,
        }
    }
}

/// A Future value which may or may not be filled
#[derive(Debug)]
pub struct OneShot<T> {
    mu: Arc<Mutex<OneShotState<T>>>,
    cv: Arc<Condvar>,
}

/// The completer side of the Future
pub struct OneShotFiller<T> {
    mu: Arc<Mutex<OneShotState<T>>>,
    cv: Arc<Condvar>,
}

impl<T> OneShot<T> {
    /// Create a new OneShotFiller and the OneShot
    /// that will be filled by its completion.
    pub fn pair() -> (OneShotFiller<T>, Self) {
        let mu = Arc::new(Mutex::new(OneShotState::default()));
        let cv = Arc::new(Condvar::new());
        let future = Self {
            mu: mu.clone(),
            cv: cv.clone(),
        };
        let filler = OneShotFiller { mu, cv };

        (filler, future)
    }

    /// Block on the OneShot's completion
    /// or dropping of the OneShotFiller
    pub fn wait(self) -> Option<T> {
        let mut inner = self.mu.lock();
        while !inner.filled {
            self.cv.wait(&mut inner);
        }
        inner.item.take()
    }

    /// Block on the OneShot's completion
    /// or dropping of the OneShotFiller.
    ///
    /// # Panics
    /// panics if the OneShotFiller is dropped
    /// without completing the promise.
    pub fn unwrap(self) -> T {
        self.wait().unwrap()
    }
}

impl<T> Future for OneShot<Result<T>> {
    type Output = Result<T>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut state = self.mu.lock();
        if state.fused {
            return Poll::Pending;
        }
        if state.filled {
            state.fused = true;
            Poll::Ready(state.item.take().unwrap())
        } else {
            state.waker = Some(cx.waker().clone());
            Poll::Pending
        }
    }
}

impl<T> OneShotFiller<T> {
    /// Complete the OneShot
    pub fn fill(self, inner: T) {
        let mut state = self.mu.lock();

        if let Some(waker) = state.waker.take() {
            waker.wake();
        }

        state.filled = true;
        state.item = Some(inner);

        self.cv.notify_all();
    }
}

impl<T> Drop for OneShotFiller<T> {
    fn drop(&mut self) {
        let mut state = self.mu.lock();

        if state.filled {
            return;
        }

        if let Some(waker) = state.waker.take() {
            waker.wake();
        }

        state.filled = true;

        self.cv.notify_all();
    }
}
<|endoftext|>


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

// xfail-test
trait Positioned<S> {
  fn SetX(&mut self, S);
  fn X(&self) -> S;
}

#[allow(default_methods)]
trait Movable<S, T>: Positioned<T> {
  fn translate(&self, dx: T) {
    self.SetX(self.X() + dx);
  }
}

struct Point { x: int, y: int }

impl Positioned<int> for Point {
    fn SetX(&mut self, x: int) {
        self.x = x;
    }
    fn X(&self) -> int {
        self.x
    }
}

impl Point: Movable<int, int>;

pub fn main() {
    let p = Point{ x: 1, y: 2};
    p.translate(3);
    assert!(p.X() == 4);
}
<commit_msg>changed to impl trait for type stx<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
trait Positioned<S> {
  fn SetX(&mut self, S);
  fn X(&self) -> S;
}

#[allow(default_methods)]
trait Movable<S, T>: Positioned<T> {
  fn translate(&self, dx: T) {
    self.SetX(self.X() + dx);
  }
}

struct Point { x: int, y: int }

impl Positioned<int> for Point {
    fn SetX(&mut self, x: int) {
        self.x = x;
    }
    fn X(&self) -> int {
        self.x
    }
}

impl Movable<int, int> for Point;

pub fn main() {
    let p = Point{ x: 1, y: 2};
    p.translate(3);
    assert!(p.X() == 4);
}
<|endoftext|>


<commit_before>use common::util::*;
use std::fs::set_permissions;

static TEST_EXISTING_FILE:           &str = "existing_file.txt";
static TEST_HELLO_WORLD_SOURCE:      &str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST:        &str = "copy_of_hello_world.txt";
static TEST_HOW_ARE_YOU_SOURCE:      &str = "how_are_you.txt";
static TEST_HOW_ARE_YOU_DEST:        &str = "hello_dir/how_are_you.txt";
static TEST_COPY_TO_FOLDER:          &str = "hello_dir/";
static TEST_COPY_TO_FOLDER_FILE:     &str = "hello_dir/hello_world.txt";
static TEST_COPY_FROM_FOLDER:        &str = "hello_dir_with_file/";
static TEST_COPY_FROM_FOLDER_FILE:   &str = "hello_dir_with_file/hello_world.txt";
static TEST_COPY_TO_FOLDER_NEW:      &str = "hello_dir_new/";
static TEST_COPY_TO_FOLDER_NEW_FILE: &str = "hello_dir_new/hello_world.txt";

#[test]
fn test_cp_cp() {
    let (at, mut ucmd) = at_and_ucmd!();
    // Invoke our binary to make the copy.
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
                     .arg(TEST_HELLO_WORLD_DEST)
                     .run();

    // Check that the exit code represents a successful copy.
    let exit_success = result.success;
    assert!(exit_success);

    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_duplicate_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("specified more than once"));
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_multiple_files_target_is_file() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_EXISTING_FILE)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("not a directory"));
}

#[test]
fn test_cp_directory_not_recursive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("omitting directory"));
}

#[test]
fn test_cp_multiple_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
    assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
}

#[test]
fn test_cp_recurse() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd
        .arg("-r")
        .arg(TEST_COPY_FROM_FOLDER)
        .arg(TEST_COPY_TO_FOLDER_NEW)
        .run();

    assert!(result.success);
    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs_t() {
    let (at, mut ucmd) = at_and_ucmd!();

    //using -t option
    let result_to_dir_t = ucmd
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .run();
    assert!(result_to_dir_t.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs() {
    let scene = TestScenario::new(util_name!());
    let at = &scene.fixtures;

    //using -t option
    let result_to_dir = scene.ucmd()
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();
    assert!(result_to_dir.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");

    let result_from_dir = scene.ucmd()
        .arg(TEST_COPY_FROM_FOLDER_FILE)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();
    assert!(result_from_dir.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_target_directory() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_arg_no_target_directory() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-v")
        .arg("-T")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("cannot overwrite directory"));
}

#[test]
fn test_cp_arg_interactive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg("-i")
        .pipe_in("N\n")
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(target_os="unix")]
fn test_cp_arg_link() {
    use std::os::linux::fs::MetadataExt;

    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
}

#[test]
fn test_cp_arg_symlink() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--symbolic-link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
}

#[test]
fn test_cp_arg_no_clobber() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--no-clobber")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(not(windows))]
fn test_cp_arg_force() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--force")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    println!("{:?}", result.stderr);
    println!("{:?}", result.stdout);

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

/// TODO: write a better test that differentiates --remove-destination
/// from --force. Also this test currently doesn't work on
/// Windows. This test originally checked file timestamps, which
/// proved to be unreliable per target / CI platform
#[test]
#[cfg(not(windows))]
fn test_cp_arg_remove_destination() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--remove-destination")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_backup() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--backup")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}

#[test]
fn test_cp_arg_suffix() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--suffix")
        .arg(".bak")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}
<commit_msg>fix: gate unix-only imports<commit_after>use common::util::*;
#[cfg(not(windows))]
use std::fs::set_permissions;

static TEST_EXISTING_FILE:           &str = "existing_file.txt";
static TEST_HELLO_WORLD_SOURCE:      &str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST:        &str = "copy_of_hello_world.txt";
static TEST_HOW_ARE_YOU_SOURCE:      &str = "how_are_you.txt";
static TEST_HOW_ARE_YOU_DEST:        &str = "hello_dir/how_are_you.txt";
static TEST_COPY_TO_FOLDER:          &str = "hello_dir/";
static TEST_COPY_TO_FOLDER_FILE:     &str = "hello_dir/hello_world.txt";
static TEST_COPY_FROM_FOLDER:        &str = "hello_dir_with_file/";
static TEST_COPY_FROM_FOLDER_FILE:   &str = "hello_dir_with_file/hello_world.txt";
static TEST_COPY_TO_FOLDER_NEW:      &str = "hello_dir_new/";
static TEST_COPY_TO_FOLDER_NEW_FILE: &str = "hello_dir_new/hello_world.txt";

#[test]
fn test_cp_cp() {
    let (at, mut ucmd) = at_and_ucmd!();
    // Invoke our binary to make the copy.
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
                     .arg(TEST_HELLO_WORLD_DEST)
                     .run();

    // Check that the exit code represents a successful copy.
    let exit_success = result.success;
    assert!(exit_success);

    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_duplicate_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("specified more than once"));
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_multiple_files_target_is_file() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_EXISTING_FILE)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("not a directory"));
}

#[test]
fn test_cp_directory_not_recursive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("omitting directory"));
}

#[test]
fn test_cp_multiple_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
    assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
}

#[test]
fn test_cp_recurse() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd
        .arg("-r")
        .arg(TEST_COPY_FROM_FOLDER)
        .arg(TEST_COPY_TO_FOLDER_NEW)
        .run();

    assert!(result.success);
    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs_t() {
    let (at, mut ucmd) = at_and_ucmd!();

    //using -t option
    let result_to_dir_t = ucmd
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .run();
    assert!(result_to_dir_t.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs() {
    let scene = TestScenario::new(util_name!());
    let at = &scene.fixtures;

    //using -t option
    let result_to_dir = scene.ucmd()
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();
    assert!(result_to_dir.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");

    let result_from_dir = scene.ucmd()
        .arg(TEST_COPY_FROM_FOLDER_FILE)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();
    assert!(result_from_dir.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_target_directory() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_arg_no_target_directory() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-v")
        .arg("-T")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("cannot overwrite directory"));
}

#[test]
fn test_cp_arg_interactive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg("-i")
        .pipe_in("N\n")
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(target_os="unix")]
fn test_cp_arg_link() {
    use std::os::linux::fs::MetadataExt;

    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
}

#[test]
fn test_cp_arg_symlink() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--symbolic-link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
}

#[test]
fn test_cp_arg_no_clobber() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--no-clobber")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(not(windows))]
fn test_cp_arg_force() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--force")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    println!("{:?}", result.stderr);
    println!("{:?}", result.stdout);

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

/// TODO: write a better test that differentiates --remove-destination
/// from --force. Also this test currently doesn't work on
/// Windows. This test originally checked file timestamps, which
/// proved to be unreliable per target / CI platform
#[test]
#[cfg(not(windows))]
fn test_cp_arg_remove_destination() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--remove-destination")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_backup() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--backup")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}

#[test]
fn test_cp_arg_suffix() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--suffix")
        .arg(".bak")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}
<|endoftext|>