<commit_before>pub struct Point<T> {
    x: T,
    y: T
}

pub fn Point<T>(x: T, y: T) -> Point<T> {
    return Point{x: x, y: y};
}

impl<T:Clone + Add<T,T>> Add<Point<T>, Point<T>> for Point<T> {
    fn add(&self, other: &Point<T>) -> Point<T> {
        return Point(self.x + other.x, self.y + other.y);
    }
}

impl<T:Clone + Mul<T,T>> Point<T> {
    pub fn scale(&self, factor: T) -> Point<T> {
        return Point(self.x * factor, self.y * factor);
    }
}

#[test]
fn test_add() {
    let p1 = Point(2, 3);
    let p2 = Point(1, 5);
    let p3 = p1 + p2;
    assert_eq!((p3.x, p3.y), (3, 8));
}

#[test]
fn test_scale() {
    let p = Point(2, 3).scale(2);
    assert_eq!((p.x, p.y), (4, 6));
}
<commit_msg>implement point subtraction<commit_after>pub struct Point<T> {
    x: T,
    y: T
}

pub fn Point<T>(x: T, y: T) -> Point<T> {
    return Point{x: x, y: y};
}

impl<T:Clone + Add<T,T>> Add<Point<T>, Point<T>> for Point<T> {
    fn add(&self, other: &Point<T>) -> Point<T> {
        return Point(self.x + other.x, self.y + other.y);
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point<T>, Point<T>> for Point<T> {
    fn sub(&self, other: &Point<T>) -> Point<T> {
        return Point(self.x - other.x, self.y - other.y);
    }
}

impl<T:Clone + Mul<T,T>> Point<T> {
    pub fn scale(&self, factor: T) -> Point<T> {
        return Point(self.x * factor, self.y * factor);
    }
}

#[test]
fn test_add() {
    let p1 = Point(2, 3);
    let p2 = Point(1, 5);
    let p3 = p1 + p2;
    assert_eq!((p3.x, p3.y), (3, 8));
}

#[test]
fn test_sub() {
    let p1 = Point(2, 3);
    let p2 = Point(1, 5);
    let p3 = p1 - p2;
    assert_eq!((p3.x, p3.y), (1, -2));
}

#[test]
fn test_scale() {
    let p = Point(2, 3).scale(2);
    assert_eq!((p.x, p.y), (4, 6));
}
<|endoftext|>


<commit_before>use socket::Socket;

#[derive(Clone)]
pub enum Form {
    SINE,
    SQUARE,
    TRIANGLE,
    SAWU,
    SAWD,
    PWM,
    ARBITRARY,
}

impl ::std::fmt::Display for Form {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Form::SINE => "SINE",
            &Form::SQUARE => "SQUARE",
            &Form::TRIANGLE => "TRIANGLE",
            &Form::SAWU => "SAWU",
            &Form::SAWD => "SAWD",
            &Form::PWM => "PWM",
            &Form::ARBITRARY => "ARBITRARY",
        };

        write!(f, "{}", display)
    }
}

pub enum Source {
    OUT1,
    OUT2,
}

impl ::std::fmt::Display for Source {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Source::OUT1 => "SOUR1",
            &Source::OUT2 => "SOUR2",
        };

        write!(f, "{}", display)
    }
}

// @TODO impl std::slice::SliceIndex<generator::State> instead
impl ::std::convert::Into<usize> for Source {
    fn into(self) -> usize {
        match self {
            Source::OUT1 => 0,
            Source::OUT2 => 1,
        }
    }
}

struct State {
    started: bool,
    form: Form,
    amplitude: f32,
    frequency: u32,
    dcyc: u32,
}

impl State {
    pub fn new() -> Self {
        State {
            started: false,
            form: Form::SINE,
            amplitude: 1.0,
            frequency: 1000,
            dcyc: 50,
        }
    }
}

pub struct Generator {
    socket: Socket,
    states: [State; 2],
}

impl Generator {
    pub fn new(socket: Socket) -> Self {
        Generator {
            socket: socket,
            states: [
                State::new(),
                State::new(),
            ],
        }
    }

    pub fn start(&mut self, source: Source) {
        self.set_state(&source, "ON");
        self.states[source as usize].started = true;
    }

    pub fn stop(&mut self, source: Source) {
        self.set_state(&source, "OFF");
        self.states[source as usize].started = false;
    }

    fn set_state(&mut self, source: &Source, state: &str) {
        let output = match *source {
            Source::OUT1 => "OUTPUT1",
            Source::OUT2 => "OUTPUT2",
        };

        self.socket.send(format!("{}:STATE {}", output, state));
    }

    pub fn is_started(&self, source: Source) -> bool {
        self.states[source as usize].started
    }

    pub fn set_form(&mut self, source: Source, form: Form) {
        self.socket.send(format!("{}:FUNC {}", source, form));
        self.states[source as usize].form = form;
    }

    pub fn get_form(&self, source: Source) -> Form {
        self.states[source as usize].form.clone()
    }

    pub fn set_amplitude(&mut self, source: Source, amplitude: f32) {
        self.socket.send(format!("{}:VOLT {}", source, amplitude));
        self.states[source as usize].amplitude = amplitude;
    }

    pub fn get_amplitude(&self, source: Source) -> f32 {
        self.states[source as usize].amplitude
    }

    pub fn set_offset(&mut self, source: Source, offset: f32) {
        self.socket.send(format!("{}:VOLT:OFFS {}", source, offset));
    }

    pub fn set_phase(&mut self, source: Source, phase: i32) {
        self.socket.send(format!("{}:PHAS {}", source, phase));
    }

    pub fn set_dcyc(&mut self, source: Source, dcyc: u32) {
        self.socket.send(format!("{}:DCYC {}", source, dcyc));
        self.states[source as usize].dcyc = dcyc;
    }

    pub fn get_dcyc(&self, source: Source) -> u32 {
        self.states[source as usize].dcyc
    }

    pub fn arbitrary_waveform(&mut self, source: Source, data: Vec<f32>) {
        let mut data = data.iter()
            .fold(String::new(), |acc, e| {
                format!("{}{},", acc, e)
            });
        data.pop();

        self.socket.send(format!("{}:TRAC:DATA:DATA {}", source, data));
    }

    pub fn set_frequency(&mut self, source: Source, frequency: u32) {
        self.socket.send(format!("{}:FREQ:FIX {}", source, frequency));
        self.states[source as usize].frequency = frequency;
    }

    pub fn get_frequency(&self, source: Source) -> u32 {
        self.states[source as usize].frequency
    }

    pub fn set_trigger_source(&mut self, source: Source, trigger: &str) {
        self.socket.send(format!("{}:TRIG:SOUR {}", source, trigger));
    }

    pub fn trigger(&mut self, source: Source) {
        self.socket.send(format!("{}:TRIG:IMM", source));
    }

    pub fn trigger_all(&mut self) {
        self.socket.send("TRIG:IMM");
    }

    pub fn reset(&mut self) {
        self.socket.send("GEN:RST");
    }
}

#[cfg(test)]
mod test {
    macro_rules! generator_assert {
        ($f:ident, $e:expr) => {
            let (rx, mut generator) = create_generator();

            generator.$f();
            assert_eq!($e, rx.recv().unwrap());
        }
    }

    #[test]
    fn test_start() {
        let (rx, mut generator) = create_generator();

        generator.start(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE ON\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_stop() {
        let (rx, mut generator) = create_generator();

        generator.stop(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE OFF\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_is_started() {
        let (_, mut generator) = create_generator();

        assert_eq!(generator.is_started(::generator::Source::OUT1), false);
        generator.start(::generator::Source::OUT1);
        assert_eq!(generator.is_started(::generator::Source::OUT1), true);
        generator.stop(::generator::Source::OUT1);
        assert_eq!(generator.is_started(::generator::Source::OUT1), false);
    }

    #[test]
    fn test_form() {
        let (rx, mut generator) = create_generator();

        generator.set_form(::generator::Source::OUT1, ::generator::Form::SINE);
        assert_eq!("SOUR1:FUNC SINE\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_amplitude() {
        let (rx, mut generator) = create_generator();

        generator.set_amplitude(::generator::Source::OUT1, -0.9);
        assert_eq!("SOUR1:VOLT -0.9\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_offset() {
        let (rx, mut generator) = create_generator();

        generator.set_offset(::generator::Source::OUT1, -1.0);
        assert_eq!("SOUR1:VOLT:OFFS -1\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_phase() {
        let (rx, mut generator) = create_generator();

        generator.set_phase(::generator::Source::OUT1, -360);
        assert_eq!("SOUR1:PHAS -360\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_dcyc() {
        let (rx, mut generator) = create_generator();

        generator.set_dcyc(::generator::Source::OUT1, 100);
        assert_eq!("SOUR1:DCYC 100\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_arbitrary_waveform() {
        let (rx, mut generator) = create_generator();

        generator.arbitrary_waveform(::generator::Source::OUT1, vec![1.0, 0.5, 0.2]);
        assert_eq!("SOUR1:TRAC:DATA:DATA 1,0.5,0.2\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_frequency() {
        let (rx, mut generator) = create_generator();

        generator.set_frequency(::generator::Source::OUT1, 500);
        assert_eq!("SOUR1:FREQ:FIX 500\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_get_frequency() {
        let (_, generator) = create_generator();

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), 1000);
    }

    #[test]
    fn test_set_trigger_source() {
        let (rx, mut generator) = create_generator();

        generator.set_trigger_source(::generator::Source::OUT1, "EXT");
        assert_eq!("SOUR1:TRIG:SOUR EXT\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger() {
        let (rx, mut generator) = create_generator();

        generator.trigger(::generator::Source::OUT1);
        assert_eq!("SOUR1:TRIG:IMM\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger_all() {
        generator_assert!(trigger_all, "TRIG:IMM\r\n");
    }

    #[test]
    fn test_reset() {
        generator_assert!(reset, "GEN:RST\r\n");
    }

    fn create_generator() -> (::std::sync::mpsc::Receiver<String>, ::generator::Generator) {
        let (addr, rx) = ::test::launch_server();
        let socket = ::socket::Socket::new(
            format!("{}", addr.ip()).as_str(),
            addr.port()
        );

        (rx, ::generator::Generator::new(socket))
    }
}
<commit_msg>[generator] Add generator::TriggerSource enum<commit_after>use socket::Socket;

pub enum TriggerSource {
    EXT_PE,
    EXT_NE,
    INT,
    GATED,
}

impl ::std::fmt::Display for TriggerSource {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &TriggerSource::EXT_PE => "EXT_PE",
            &TriggerSource::EXT_NE => "EXT_NE",
            &TriggerSource::INT => "INT",
            &TriggerSource::GATED => "GATED",
        };

        write!(f, "{}", display)
    }
}

#[derive(Clone)]
pub enum Form {
    SINE,
    SQUARE,
    TRIANGLE,
    SAWU,
    SAWD,
    PWM,
    ARBITRARY,
}

impl ::std::fmt::Display for Form {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Form::SINE => "SINE",
            &Form::SQUARE => "SQUARE",
            &Form::TRIANGLE => "TRIANGLE",
            &Form::SAWU => "SAWU",
            &Form::SAWD => "SAWD",
            &Form::PWM => "PWM",
            &Form::ARBITRARY => "ARBITRARY",
        };

        write!(f, "{}", display)
    }
}

pub enum Source {
    OUT1,
    OUT2,
}

impl ::std::fmt::Display for Source {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Source::OUT1 => "SOUR1",
            &Source::OUT2 => "SOUR2",
        };

        write!(f, "{}", display)
    }
}

// @TODO impl std::slice::SliceIndex<generator::State> instead
impl ::std::convert::Into<usize> for Source {
    fn into(self) -> usize {
        match self {
            Source::OUT1 => 0,
            Source::OUT2 => 1,
        }
    }
}

struct State {
    started: bool,
    form: Form,
    amplitude: f32,
    frequency: u32,
    dcyc: u32,
}

impl State {
    pub fn new() -> Self {
        State {
            started: false,
            form: Form::SINE,
            amplitude: 1.0,
            frequency: 1000,
            dcyc: 50,
        }
    }
}

pub struct Generator {
    socket: Socket,
    states: [State; 2],
}

impl Generator {
    pub fn new(socket: Socket) -> Self {
        Generator {
            socket: socket,
            states: [
                State::new(),
                State::new(),
            ],
        }
    }

    pub fn start(&mut self, source: Source) {
        self.set_state(&source, "ON");
        self.states[source as usize].started = true;
    }

    pub fn stop(&mut self, source: Source) {
        self.set_state(&source, "OFF");
        self.states[source as usize].started = false;
    }

    fn set_state(&mut self, source: &Source, state: &str) {
        let output = match *source {
            Source::OUT1 => "OUTPUT1",
            Source::OUT2 => "OUTPUT2",
        };

        self.socket.send(format!("{}:STATE {}", output, state));
    }

    pub fn is_started(&self, source: Source) -> bool {
        self.states[source as usize].started
    }

    pub fn set_form(&mut self, source: Source, form: Form) {
        self.socket.send(format!("{}:FUNC {}", source, form));
        self.states[source as usize].form = form;
    }

    pub fn get_form(&self, source: Source) -> Form {
        self.states[source as usize].form.clone()
    }

    pub fn set_amplitude(&mut self, source: Source, amplitude: f32) {
        self.socket.send(format!("{}:VOLT {}", source, amplitude));
        self.states[source as usize].amplitude = amplitude;
    }

    pub fn get_amplitude(&self, source: Source) -> f32 {
        self.states[source as usize].amplitude
    }

    pub fn set_offset(&mut self, source: Source, offset: f32) {
        self.socket.send(format!("{}:VOLT:OFFS {}", source, offset));
    }

    pub fn set_phase(&mut self, source: Source, phase: i32) {
        self.socket.send(format!("{}:PHAS {}", source, phase));
    }

    pub fn set_dcyc(&mut self, source: Source, dcyc: u32) {
        self.socket.send(format!("{}:DCYC {}", source, dcyc));
        self.states[source as usize].dcyc = dcyc;
    }

    pub fn get_dcyc(&self, source: Source) -> u32 {
        self.states[source as usize].dcyc
    }

    pub fn arbitrary_waveform(&mut self, source: Source, data: Vec<f32>) {
        let mut data = data.iter()
            .fold(String::new(), |acc, e| {
                format!("{}{},", acc, e)
            });
        data.pop();

        self.socket.send(format!("{}:TRAC:DATA:DATA {}", source, data));
    }

    pub fn set_frequency(&mut self, source: Source, frequency: u32) {
        self.socket.send(format!("{}:FREQ:FIX {}", source, frequency));
        self.states[source as usize].frequency = frequency;
    }

    pub fn get_frequency(&self, source: Source) -> u32 {
        self.states[source as usize].frequency
    }

    pub fn set_trigger_source(&mut self, source: Source, trigger: TriggerSource) {
        self.socket.send(format!("{}:TRIG:SOUR {}", source, trigger));
    }

    pub fn trigger(&mut self, source: Source) {
        self.socket.send(format!("{}:TRIG:IMM", source));
    }

    pub fn trigger_all(&mut self) {
        self.socket.send("TRIG:IMM");
    }

    pub fn reset(&mut self) {
        self.socket.send("GEN:RST");
    }
}

#[cfg(test)]
mod test {
    macro_rules! generator_assert {
        ($f:ident, $e:expr) => {
            let (rx, mut generator) = create_generator();

            generator.$f();
            assert_eq!($e, rx.recv().unwrap());
        }
    }

    #[test]
    fn test_start() {
        let (rx, mut generator) = create_generator();

        generator.start(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE ON\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_stop() {
        let (rx, mut generator) = create_generator();

        generator.stop(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE OFF\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_is_started() {
        let (_, mut generator) = create_generator();

        assert_eq!(generator.is_started(::generator::Source::OUT1), false);
        generator.start(::generator::Source::OUT1);
        assert_eq!(generator.is_started(::generator::Source::OUT1), true);
        generator.stop(::generator::Source::OUT1);
        assert_eq!(generator.is_started(::generator::Source::OUT1), false);
    }

    #[test]
    fn test_form() {
        let (rx, mut generator) = create_generator();

        generator.set_form(::generator::Source::OUT1, ::generator::Form::SINE);
        assert_eq!("SOUR1:FUNC SINE\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_amplitude() {
        let (rx, mut generator) = create_generator();

        generator.set_amplitude(::generator::Source::OUT1, -0.9);
        assert_eq!("SOUR1:VOLT -0.9\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_offset() {
        let (rx, mut generator) = create_generator();

        generator.set_offset(::generator::Source::OUT1, -1.0);
        assert_eq!("SOUR1:VOLT:OFFS -1\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_phase() {
        let (rx, mut generator) = create_generator();

        generator.set_phase(::generator::Source::OUT1, -360);
        assert_eq!("SOUR1:PHAS -360\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_dcyc() {
        let (rx, mut generator) = create_generator();

        generator.set_dcyc(::generator::Source::OUT1, 100);
        assert_eq!("SOUR1:DCYC 100\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_arbitrary_waveform() {
        let (rx, mut generator) = create_generator();

        generator.arbitrary_waveform(::generator::Source::OUT1, vec![1.0, 0.5, 0.2]);
        assert_eq!("SOUR1:TRAC:DATA:DATA 1,0.5,0.2\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_set_frequency() {
        let (rx, mut generator) = create_generator();

        generator.set_frequency(::generator::Source::OUT1, 500);
        assert_eq!("SOUR1:FREQ:FIX 500\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_get_frequency() {
        let (_, generator) = create_generator();

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), 1000);
    }

    #[test]
    fn test_set_trigger_source() {
        let (rx, mut generator) = create_generator();

        generator.set_trigger_source(::generator::Source::OUT1, ::generator::TriggerSource::EXT_PE);
        assert_eq!("SOUR1:TRIG:SOUR EXT_PE\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger() {
        let (rx, mut generator) = create_generator();

        generator.trigger(::generator::Source::OUT1);
        assert_eq!("SOUR1:TRIG:IMM\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger_all() {
        generator_assert!(trigger_all, "TRIG:IMM\r\n");
    }

    #[test]
    fn test_reset() {
        generator_assert!(reset, "GEN:RST\r\n");
    }

    fn create_generator() -> (::std::sync::mpsc::Receiver<String>, ::generator::Generator) {
        let (addr, rx) = ::test::launch_server();
        let socket = ::socket::Socket::new(
            format!("{}", addr.ip()).as_str(),
            addr.port()
        );

        (rx, ::generator::Generator::new(socket))
    }
}
<|endoftext|>


<commit_before>
#![crate_name = "geoip"]
#![crate_type = "rlib"]

#![warn(non_camel_case_types,
        non_upper_case_globals,
        unused_qualifications)]
#![allow(unstable)]

extern crate libc;
extern crate "rustc-serialize" as rustc_serialize;
extern crate "geoip-sys" as geoip_sys;

use libc::{c_char, c_int, c_ulong};
use std::ffi;
use std::fmt;
use std::io::net::ip::{IpAddr,Ipv4Addr,Ipv6Addr};

#[cfg(test)]
use std::str::FromStr;

enum Charset {
    UTF8 = 1
}

pub enum Options {
    Standard = 0,
    MemoryCache = 1,
    CheckCache = 2,
    IndexCache = 4,
    MmapCache = 8
}

impl Copy for Options { }

pub enum DBType {
    CountryEdition = 1,
    RegionEditionRev0 = 7,
    CityEditionRev0 = 6,
    ORGEdition = 5,
    ISPEdition = 4,
    CityEditionRev1 = 2,
    RegionEditionRev1 = 3,
    ProxyEdition = 8,
    ASNUMEdition = 9,
    NetSpeedEdition = 10,
    DomainEdition = 11,
    CountryEditionV6 = 12,
    LocationAEdition = 13,
    AccuracyRadiusEdition = 14,
    LargeCountryEdition = 17,
    LargeCountryEditionV6 = 18,
    ASNumEditionV6 = 21,
    ISPEditionV6 = 22,
    ORGEditionV6 = 23,
    DomainEditionV6 = 24,
    LoctionAEditionV6 = 25,
    RegistrarEdition = 26,
    RegistrarEditionV6 = 27,
    UserTypeEdition = 28,
    UserTypeEditionV6 = 29,
    CityEditionRev1V6 = 30,
    CityEditionRev0V6 = 31,
    NetSpeedEditionRev1 = 32,
    NetSpeedEditionRev1V6 = 33,
    CountryConfEdition = 34,
    CityConfEdition = 35,
    RegionConfEdition = 36,
    PostalConfEdition = 37,
    AccuracyRadiusEditionV6 = 38
}

impl Copy for DBType { }

pub struct GeoIp {
    db: geoip_sys::RawGeoIp
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct ASInfo {
    pub asn: u32,
    pub name: String,
    pub netmask: u32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct CityInfo {
    pub country_code: Option<String>,
    pub country_code3: Option<String>,
    pub country_name: Option<String>,
    pub region: Option<String>,
    pub city: Option<String>,
    pub postal_code: Option<String>,
    pub latitude: f32,
    pub longitude: f32,
    pub dma_code: u32,
    pub area_code: u32,
    pub charset: u32,
    pub continent_code: Option<String>,
    pub netmask: u32
}

fn maybe_string(c_str: *const c_char) -> Option<String> {
    if c_str.is_null() {
        None
    } else {
        String::from_utf8(unsafe { ffi::c_str_to_bytes(&c_str) }.to_vec()).ok()
    }
}

impl CityInfo {
    unsafe fn from_geoiprecord(res: &geoip_sys::GeoIpRecord) -> CityInfo {
        CityInfo {
            country_code: maybe_string(res.country_code),
            country_code3: maybe_string(res.country_code3),
            country_name: maybe_string(res.country_name),
            region: maybe_string(res.region),
            city: maybe_string(res.city),
            postal_code: maybe_string(res.postal_code),
            latitude: res.latitude as f32,
            longitude: res.longitude as f32,
            dma_code: res.dma_code as u32,
            area_code: res.area_code as u32,
            charset: res.charset as u32,
            continent_code: maybe_string(res.continent_code),
            netmask: res.netmask as u32
        }
    }
}

impl fmt::Show for ASInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}\t{}", self.asn, self.name)
    }
}

enum CNetworkIp {
    V4(c_ulong),
    V6(geoip_sys::In6Addr)
}

impl CNetworkIp {
    fn new(ip: IpAddr) -> CNetworkIp {
        match ip {
            Ipv4Addr(a, b, c, d) => {
                CNetworkIp::V4(((a as c_ulong) << 24) | ((b as c_ulong) << 16) |
                               ((c as c_ulong) << 8)  | ((d as c_ulong)))
            },
            Ipv6Addr(a, b, c, d, e, f, g, h) => {
                CNetworkIp::V6([(a >> 8) as u8, a as u8,
                                (b >> 8) as u8, b as u8,
                                (c >> 8) as u8, c as u8,
                                (d >> 8) as u8, d as u8,
                                (e >> 8) as u8, e as u8,
                                (f >> 8) as u8, f as u8,
                                (g >> 8) as u8, g as u8,
                                (h >> 8) as u8, h as u8])
            }
        }
    }
}

impl GeoIp {
    pub fn open(path: &Path, options: Options) -> Result<GeoIp, String> {
        let file = match path.as_str() {
            None => return Err(format!("Invalid path {}", path.display())),
            Some(file) => file
        };
        let db = unsafe {
            geoip_sys::GeoIP_open(ffi::CString::from_slice(file.as_bytes()).as_ptr(),
                                  options as c_int)
        };
        if db.is_null() {
            return Err(format!("Can't open {}", file));
        }
        if unsafe { geoip_sys::GeoIP_set_charset(db, Charset::UTF8 as c_int)
        } != 0 {
            return Err("Can't set charset to UTF8".to_string());
        }
        Ok(GeoIp { db: db })
    }

    pub fn city_info_by_ip(&self, ip: IpAddr) -> Option<CityInfo> {
        let cres = match CNetworkIp::new(ip) {
            CNetworkIp::V4(ip) => unsafe {
                geoip_sys::GeoIP_record_by_ipnum(self.db, ip) },
            CNetworkIp::V6(ip) => unsafe {
                geoip_sys::GeoIP_record_by_ipnum_v6(self.db, ip) }
        };

        if cres.is_null() { return None; }

        unsafe {
            let city_info = CityInfo::from_geoiprecord(&*cres);
            geoip_sys::GeoIPRecord_delete(cres);
            std::mem::forget(cres);
            Some(city_info)
        }
    }

    pub fn as_info_by_ip(&self, ip: IpAddr) -> Option<ASInfo> {
        let mut gl = geoip_sys::GeoIpLookup::new();
        let cres = match CNetworkIp::new(ip) {
            CNetworkIp::V4(ip) => unsafe {
                geoip_sys::GeoIP_name_by_ipnum_gl(self.db, ip, &mut gl) },
            CNetworkIp::V6(ip) => unsafe {
                geoip_sys::GeoIP_name_by_ipnum_v6_gl(self.db, ip, &mut gl) }
        };

        if cres.is_null() {
            return None;
        }
        let description = match maybe_string(cres) {
            None => return None,
            Some(description) => description
        };
        let mut di = description.splitn(1, ' ');
        let asn = match di.next() {
            None => return None,
            Some(asn) => {
                if ! asn.starts_with("AS") {
                    return None
                } else {
                    asn[2..].parse::<u32>().unwrap()
                }
            }
        };
        let name = di.next().unwrap_or("(none)");
        let as_info = ASInfo {
            asn: asn,
            name: name.to_string(),
            netmask: gl.netmask as u32
        };
        Some(as_info)
    }
}

impl Drop for GeoIp {
    fn drop(&mut self) {
        unsafe {
            geoip_sys::GeoIP_delete(self.db);
        }
    }
}

#[test]
fn geoip_test_basic() {
    let geoip = match GeoIp::open(&Path::new("/opt/geoip/GeoIPASNum.dat"), Options::MemoryCache) {
        Err(err) => panic!(err),
        Ok(geoip) => geoip
    };
    let ip = FromStr::from_str("91.203.184.192").unwrap();
    let res = geoip.as_info_by_ip(ip).unwrap();
    assert!(res.asn == 41064);
    assert!(res.name.as_slice().contains("Telefun"));
    assert!(res.netmask == 22);
}

#[test]
fn geoip_test_city() {
    let geoip = match GeoIp::open(&Path::new("/opt/geoip/GeoLiteCity.dat"), Options::MemoryCache) {
        Err(err) => panic!(err),
        Ok(geoip) => geoip
    };
    let ip = FromStr::from_str("8.8.8.8").unwrap();
    let res = geoip.city_info_by_ip(ip).unwrap();
    assert!(res.city.unwrap().as_slice() == "Mountain View");
}
<commit_msg>fmt::Show -> fmt::Debug<commit_after>
#![crate_name = "geoip"]
#![crate_type = "rlib"]

#![warn(non_camel_case_types,
        non_upper_case_globals,
        unused_qualifications)]
#![allow(unstable)]

extern crate libc;
extern crate "rustc-serialize" as rustc_serialize;
extern crate "geoip-sys" as geoip_sys;

use libc::{c_char, c_int, c_ulong};
use std::ffi;
use std::fmt;
use std::io::net::ip::{IpAddr,Ipv4Addr,Ipv6Addr};

#[cfg(test)]
use std::str::FromStr;

enum Charset {
    UTF8 = 1
}

pub enum Options {
    Standard = 0,
    MemoryCache = 1,
    CheckCache = 2,
    IndexCache = 4,
    MmapCache = 8
}

impl Copy for Options { }

pub enum DBType {
    CountryEdition = 1,
    RegionEditionRev0 = 7,
    CityEditionRev0 = 6,
    ORGEdition = 5,
    ISPEdition = 4,
    CityEditionRev1 = 2,
    RegionEditionRev1 = 3,
    ProxyEdition = 8,
    ASNUMEdition = 9,
    NetSpeedEdition = 10,
    DomainEdition = 11,
    CountryEditionV6 = 12,
    LocationAEdition = 13,
    AccuracyRadiusEdition = 14,
    LargeCountryEdition = 17,
    LargeCountryEditionV6 = 18,
    ASNumEditionV6 = 21,
    ISPEditionV6 = 22,
    ORGEditionV6 = 23,
    DomainEditionV6 = 24,
    LoctionAEditionV6 = 25,
    RegistrarEdition = 26,
    RegistrarEditionV6 = 27,
    UserTypeEdition = 28,
    UserTypeEditionV6 = 29,
    CityEditionRev1V6 = 30,
    CityEditionRev0V6 = 31,
    NetSpeedEditionRev1 = 32,
    NetSpeedEditionRev1V6 = 33,
    CountryConfEdition = 34,
    CityConfEdition = 35,
    RegionConfEdition = 36,
    PostalConfEdition = 37,
    AccuracyRadiusEditionV6 = 38
}

impl Copy for DBType { }

pub struct GeoIp {
    db: geoip_sys::RawGeoIp
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct ASInfo {
    pub asn: u32,
    pub name: String,
    pub netmask: u32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct CityInfo {
    pub country_code: Option<String>,
    pub country_code3: Option<String>,
    pub country_name: Option<String>,
    pub region: Option<String>,
    pub city: Option<String>,
    pub postal_code: Option<String>,
    pub latitude: f32,
    pub longitude: f32,
    pub dma_code: u32,
    pub area_code: u32,
    pub charset: u32,
    pub continent_code: Option<String>,
    pub netmask: u32
}

fn maybe_string(c_str: *const c_char) -> Option<String> {
    if c_str.is_null() {
        None
    } else {
        String::from_utf8(unsafe { ffi::c_str_to_bytes(&c_str) }.to_vec()).ok()
    }
}

impl CityInfo {
    unsafe fn from_geoiprecord(res: &geoip_sys::GeoIpRecord) -> CityInfo {
        CityInfo {
            country_code: maybe_string(res.country_code),
            country_code3: maybe_string(res.country_code3),
            country_name: maybe_string(res.country_name),
            region: maybe_string(res.region),
            city: maybe_string(res.city),
            postal_code: maybe_string(res.postal_code),
            latitude: res.latitude as f32,
            longitude: res.longitude as f32,
            dma_code: res.dma_code as u32,
            area_code: res.area_code as u32,
            charset: res.charset as u32,
            continent_code: maybe_string(res.continent_code),
            netmask: res.netmask as u32
        }
    }
}

impl fmt::Debug for ASInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}\t{}", self.asn, self.name)
    }
}

enum CNetworkIp {
    V4(c_ulong),
    V6(geoip_sys::In6Addr)
}

impl CNetworkIp {
    fn new(ip: IpAddr) -> CNetworkIp {
        match ip {
            Ipv4Addr(a, b, c, d) => {
                CNetworkIp::V4(((a as c_ulong) << 24) | ((b as c_ulong) << 16) |
                               ((c as c_ulong) << 8)  | ((d as c_ulong)))
            },
            Ipv6Addr(a, b, c, d, e, f, g, h) => {
                CNetworkIp::V6([(a >> 8) as u8, a as u8,
                                (b >> 8) as u8, b as u8,
                                (c >> 8) as u8, c as u8,
                                (d >> 8) as u8, d as u8,
                                (e >> 8) as u8, e as u8,
                                (f >> 8) as u8, f as u8,
                                (g >> 8) as u8, g as u8,
                                (h >> 8) as u8, h as u8])
            }
        }
    }
}

impl GeoIp {
    pub fn open(path: &Path, options: Options) -> Result<GeoIp, String> {
        let file = match path.as_str() {
            None => return Err(format!("Invalid path {}", path.display())),
            Some(file) => file
        };
        let db = unsafe {
            geoip_sys::GeoIP_open(ffi::CString::from_slice(file.as_bytes()).as_ptr(),
                                  options as c_int)
        };
        if db.is_null() {
            return Err(format!("Can't open {}", file));
        }
        if unsafe { geoip_sys::GeoIP_set_charset(db, Charset::UTF8 as c_int)
        } != 0 {
            return Err("Can't set charset to UTF8".to_string());
        }
        Ok(GeoIp { db: db })
    }

    pub fn city_info_by_ip(&self, ip: IpAddr) -> Option<CityInfo> {
        let cres = match CNetworkIp::new(ip) {
            CNetworkIp::V4(ip) => unsafe {
                geoip_sys::GeoIP_record_by_ipnum(self.db, ip) },
            CNetworkIp::V6(ip) => unsafe {
                geoip_sys::GeoIP_record_by_ipnum_v6(self.db, ip) }
        };

        if cres.is_null() { return None; }

        unsafe {
            let city_info = CityInfo::from_geoiprecord(&*cres);
            geoip_sys::GeoIPRecord_delete(cres);
            std::mem::forget(cres);
            Some(city_info)
        }
    }

    pub fn as_info_by_ip(&self, ip: IpAddr) -> Option<ASInfo> {
        let mut gl = geoip_sys::GeoIpLookup::new();
        let cres = match CNetworkIp::new(ip) {
            CNetworkIp::V4(ip) => unsafe {
                geoip_sys::GeoIP_name_by_ipnum_gl(self.db, ip, &mut gl) },
            CNetworkIp::V6(ip) => unsafe {
                geoip_sys::GeoIP_name_by_ipnum_v6_gl(self.db, ip, &mut gl) }
        };

        if cres.is_null() {
            return None;
        }
        let description = match maybe_string(cres) {
            None => return None,
            Some(description) => description
        };
        let mut di = description.splitn(1, ' ');
        let asn = match di.next() {
            None => return None,
            Some(asn) => {
                if ! asn.starts_with("AS") {
                    return None
                } else {
                    asn[2..].parse::<u32>().unwrap()
                }
            }
        };
        let name = di.next().unwrap_or("(none)");
        let as_info = ASInfo {
            asn: asn,
            name: name.to_string(),
            netmask: gl.netmask as u32
        };
        Some(as_info)
    }
}

impl Drop for GeoIp {
    fn drop(&mut self) {
        unsafe {
            geoip_sys::GeoIP_delete(self.db);
        }
    }
}

#[test]
fn geoip_test_basic() {
    let geoip = match GeoIp::open(&Path::new("/opt/geoip/GeoIPASNum.dat"), Options::MemoryCache) {
        Err(err) => panic!(err),
        Ok(geoip) => geoip
    };
    let ip = FromStr::from_str("91.203.184.192").unwrap();
    let res = geoip.as_info_by_ip(ip).unwrap();
    assert!(res.asn == 41064);
    assert!(res.name.as_slice().contains("Telefun"));
    assert!(res.netmask == 22);
}

#[test]
fn geoip_test_city() {
    let geoip = match GeoIp::open(&Path::new("/opt/geoip/GeoLiteCity.dat"), Options::MemoryCache) {
        Err(err) => panic!(err),
        Ok(geoip) => geoip
    };
    let ip = FromStr::from_str("8.8.8.8").unwrap();
    let res = geoip.city_info_by_ip(ip).unwrap();
    assert!(res.city.unwrap().as_slice() == "Mountain View");
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std::rand::*;
use common::*;
use carsales_capnp::*;

pub type RequestBuilder<'a> = ParkingLot::Builder<'a>;
pub type RequestReader<'a> = ParkingLot::Reader<'a>;
pub type ResponseBuilder<'a> = TotalValue::Builder<'a>;
pub type ResponseReader<'a> = TotalValue::Reader<'a>;
pub type Expectation = u64;

trait CarValue {
    fn car_value(&self) -> u64;
}

macro_rules! car_value_impl(
    ($typ:ty) => (
            impl <'a> CarValue for $typ {
                fn car_value (&self) -> u64 {
                    let mut result : u64 = 0;
                    result += self.get_seats() as u64 * 200;
                    result += self.get_doors() as u64 * 350;

                    // TODO Lists should have iterators.
                    for i in range(0, self.get_wheels().size()) {
                        let wheel = self.get_wheels()[i];
                        result += wheel.get_diameter() as u64 * wheel.get_diameter() as u64;
                        result += if (wheel.get_snow_tires()) { 100 } else { 0 };
                    }

                    result += self.get_length() as u64 * self.get_width() as u64 * self.get_height() as u64 / 50;

                    let engine = self.get_engine();
                    result += engine.get_horsepower() as u64 * 40;
                    if (engine.get_uses_electric()) {
                        if (engine.get_uses_gas()) {
                            //# hybrid
                            result += 5000;
                        } else {
                            result += 3000;
                        }
                    }

                    result += if (self.get_has_power_windows()) { 100 } else { 0 };
                    result += if (self.get_has_power_steering()) { 200 } else { 0 };
                    result += if (self.get_has_cruise_control()) { 400 } else { 0 };
                    result += if (self.get_has_nav_system()) { 2000 } else { 0 };

                    result += self.get_cup_holders() as u64 * 25;

                    return result;
                }

            }
        )
   )

car_value_impl!(Car::Reader<'a>)
car_value_impl!(Car::Builder<'a>)

static MAKES : [&'static str, .. 5] = ["Toyota", "GM", "Ford", "Honda", "Tesla"];
static MODELS : [&'static str, .. 6] = ["Camry", "Prius", "Volt", "Accord", "Leaf", "Model S"];

pub fn random_car(rng : &mut FastRand, car : Car::Builder) {
    use std::cast::*;

    car.set_make(MAKES[rng.nextLessThan(MAKES.len() as u32)]);
    car.set_model(MODELS[rng.nextLessThan(MODELS.len() as u32)]);

    car.set_color(unsafe {transmute(rng.nextLessThan(Color::Silver as u32 + 1) as u16) });
    car.set_seats(2 + rng.nextLessThan(6) as u8);
    car.set_doors(2 + rng.nextLessThan(3) as u8);

    let wheels = car.init_wheels(4);
    for i in range(0, wheels.size()) {
        let wheel = wheels[i];
        wheel.set_diameter(25 + rng.nextLessThan(15) as u16);
        wheel.set_air_pressure((30.0 + rng.nextDouble(20.0)) as f32);
        wheel.set_snow_tires(rng.nextLessThan(16) == 0);
    }

    car.set_length(170 + rng.nextLessThan(150) as u16);
    car.set_width(48 + rng.nextLessThan(36) as u16);
    car.set_height(54 + rng.nextLessThan(48) as u16);
    car.set_weight(car.get_length() as u32 * car.get_width() as u32 *
                   car.get_height() as u32 / 200);

    let engine = car.init_engine();
    engine.set_horsepower(100 * rng.nextLessThan(400) as u16);
    engine.set_cylinders(4 + 2 * rng.nextLessThan(3) as u8);
    engine.set_cc(800 + rng.nextLessThan(10000));
    engine.set_uses_gas(true);
    engine.set_uses_electric(rng.gen());

    car.set_fuel_capacity((10.0 + rng.nextDouble(30.0)) as f32);
    car.set_fuel_level(rng.nextDouble(car.get_fuel_capacity() as f64) as f32);
    car.set_has_power_windows(rng.gen());
    car.set_has_power_steering(rng.gen());
    car.set_has_cruise_control(rng.gen());
    car.set_cup_holders(rng.nextLessThan(12) as u8);
    car.set_has_nav_system(rng.gen());
}

pub fn setup_request(rng : &mut FastRand, request : ParkingLot::Builder) -> u64 {
    let mut result = 0;
    let cars = request.init_cars(rng.nextLessThan(200) as uint);
    for i in range(0, cars.size()) {
        let car = cars[i];
        random_car(rng, car);
        result += car.car_value();
    }

    result
}

pub fn handle_request(request : ParkingLot::Reader, response : TotalValue::Builder) {
    let mut result = 0;
    let cars = request.get_cars();
    for i in range(0, cars.size()) {
        result += cars[i].car_value();
    }
    response.set_amount(result);
}

#[inline]
pub fn check_response(response : TotalValue::Reader, expected : u64) -> bool {
    response.get_amount() == expected
}
<commit_msg>cleaner way to define car_value_impl<commit_after>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std::rand::*;
use common::*;
use carsales_capnp::*;

pub type RequestBuilder<'a> = ParkingLot::Builder<'a>;
pub type RequestReader<'a> = ParkingLot::Reader<'a>;
pub type ResponseBuilder<'a> = TotalValue::Builder<'a>;
pub type ResponseReader<'a> = TotalValue::Reader<'a>;
pub type Expectation = u64;

trait CarValue {
    fn car_value(&self) -> u64;
}

macro_rules! car_value_impl(
    ($typ:ident) => (
            impl <'a> CarValue for Car::$typ<'a> {
                fn car_value (&self) -> u64 {
                    let mut result : u64 = 0;
                    result += self.get_seats() as u64 * 200;
                    result += self.get_doors() as u64 * 350;

                    // TODO Lists should have iterators.
                    for i in range(0, self.get_wheels().size()) {
                        let wheel = self.get_wheels()[i];
                        result += wheel.get_diameter() as u64 * wheel.get_diameter() as u64;
                        result += if (wheel.get_snow_tires()) { 100 } else { 0 };
                    }

                    result += self.get_length() as u64 * self.get_width() as u64 * self.get_height() as u64 / 50;

                    let engine = self.get_engine();
                    result += engine.get_horsepower() as u64 * 40;
                    if (engine.get_uses_electric()) {
                        if (engine.get_uses_gas()) {
                            //# hybrid
                            result += 5000;
                        } else {
                            result += 3000;
                        }
                    }

                    result += if (self.get_has_power_windows()) { 100 } else { 0 };
                    result += if (self.get_has_power_steering()) { 200 } else { 0 };
                    result += if (self.get_has_cruise_control()) { 400 } else { 0 };
                    result += if (self.get_has_nav_system()) { 2000 } else { 0 };

                    result += self.get_cup_holders() as u64 * 25;

                    return result;
                }

            }
        )
   )

car_value_impl!(Reader)
car_value_impl!(Builder)

static MAKES : [&'static str, .. 5] = ["Toyota", "GM", "Ford", "Honda", "Tesla"];
static MODELS : [&'static str, .. 6] = ["Camry", "Prius", "Volt", "Accord", "Leaf", "Model S"];

pub fn random_car(rng : &mut FastRand, car : Car::Builder) {
    use std::cast::*;

    car.set_make(MAKES[rng.nextLessThan(MAKES.len() as u32)]);
    car.set_model(MODELS[rng.nextLessThan(MODELS.len() as u32)]);

    car.set_color(unsafe {transmute(rng.nextLessThan(Color::Silver as u32 + 1) as u16) });
    car.set_seats(2 + rng.nextLessThan(6) as u8);
    car.set_doors(2 + rng.nextLessThan(3) as u8);

    let wheels = car.init_wheels(4);
    for i in range(0, wheels.size()) {
        let wheel = wheels[i];
        wheel.set_diameter(25 + rng.nextLessThan(15) as u16);
        wheel.set_air_pressure((30.0 + rng.nextDouble(20.0)) as f32);
        wheel.set_snow_tires(rng.nextLessThan(16) == 0);
    }

    car.set_length(170 + rng.nextLessThan(150) as u16);
    car.set_width(48 + rng.nextLessThan(36) as u16);
    car.set_height(54 + rng.nextLessThan(48) as u16);
    car.set_weight(car.get_length() as u32 * car.get_width() as u32 *
                   car.get_height() as u32 / 200);

    let engine = car.init_engine();
    engine.set_horsepower(100 * rng.nextLessThan(400) as u16);
    engine.set_cylinders(4 + 2 * rng.nextLessThan(3) as u8);
    engine.set_cc(800 + rng.nextLessThan(10000));
    engine.set_uses_gas(true);
    engine.set_uses_electric(rng.gen());

    car.set_fuel_capacity((10.0 + rng.nextDouble(30.0)) as f32);
    car.set_fuel_level(rng.nextDouble(car.get_fuel_capacity() as f64) as f32);
    car.set_has_power_windows(rng.gen());
    car.set_has_power_steering(rng.gen());
    car.set_has_cruise_control(rng.gen());
    car.set_cup_holders(rng.nextLessThan(12) as u8);
    car.set_has_nav_system(rng.gen());
}

pub fn setup_request(rng : &mut FastRand, request : ParkingLot::Builder) -> u64 {
    let mut result = 0;
    let cars = request.init_cars(rng.nextLessThan(200) as uint);
    for i in range(0, cars.size()) {
        let car = cars[i];
        random_car(rng, car);
        result += car.car_value();
    }

    result
}

pub fn handle_request(request : ParkingLot::Reader, response : TotalValue::Builder) {
    let mut result = 0;
    let cars = request.get_cars();
    for i in range(0, cars.size()) {
        result += cars[i].car_value();
    }
    response.set_amount(result);
}

#[inline]
pub fn check_response(response : TotalValue::Reader, expected : u64) -> bool {
    response.get_amount() == expected
}
<|endoftext|>


<commit_before>//! [PUT /_matrix/federation/v1/send/{txnId}](https://matrix.org/docs/spec/server_server/r0.1.3#put-matrix-federation-v1-send-txnid)

use std::{collections::BTreeMap, time::SystemTime};

use ruma_api::ruma_api;
use ruma_events::pdu::Pdu;
use ruma_identifiers::{EventId, ServerName};
use ruma_serde::Raw;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;

ruma_api! {
    metadata: {
        description: "Send transaction messages to another server",
        name: "send_transaction_message",
        method: PUT,
        path: "/_matrix/federation/v1/send/:transaction_id",
        rate_limited: false,
        authentication: ServerSignatures,
    }

    request: {
        /// A transaction ID unique between sending and receiving homeservers.
        #[ruma_api(path)]
        pub transaction_id: &'a str,

        /// The server_name of the homeserver sending this transaction.
        pub origin: &'a ServerName,

        /// POSIX timestamp in milliseconds on the originating homeserver when this transaction
        /// started.
        #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
        pub origin_server_ts: SystemTime,

        /// List of persistent updates to rooms.
        ///
        /// Must not be more than 50 items.
        #[cfg_attr(feature = "unstable-pre-spec", serde(default, skip_serializing_if = "<[_]>::is_empty"))]
        pub pdus: &'a [Raw<Pdu>],

        /// List of ephemeral messages.
        ///
        /// Must not be more than 100 items.
        #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
        pub edus: &'a [Raw<Edu>],
    }

    #[derive(Default)]
    response: {
        /// Map of event IDs and response for each PDU given in the request.
        #[serde(with = "crate::serde::pdu_process_response")]
        pub pdus: BTreeMap<EventId, Result<(), String>>,
    }
}

impl<'a> Request<'a> {
    /// Creates a new `Request` with the given transaction ID, origin, timestamp.
    ///
    /// The PDU and EDU lists will start off empty.
    pub fn new(
        transaction_id: &'a str,
        origin: &'a ServerName,
        origin_server_ts: SystemTime,
    ) -> Self {
        Self { transaction_id, origin, origin_server_ts, pdus: &[], edus: &[] }
    }
}

impl Response {
    /// Creates a new `Response` with the given PDUs.
    pub fn new(pdus: BTreeMap<EventId, Result<(), String>>) -> Self {
        Self { pdus }
    }
}

/// Type for passing ephemeral data to homeservers.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Edu {
    /// Type of the ephemeral message.
    pub edu_type: String,

    /// Content of ephemeral message
    pub content: JsonValue,
}
<commit_msg>Revert "federation-api: Make pdus of transactions optional under `unstable-pre-spec`"<commit_after>//! [PUT /_matrix/federation/v1/send/{txnId}](https://matrix.org/docs/spec/server_server/r0.1.3#put-matrix-federation-v1-send-txnid)

use std::{collections::BTreeMap, time::SystemTime};

use ruma_api::ruma_api;
use ruma_events::pdu::Pdu;
use ruma_identifiers::{EventId, ServerName};
use ruma_serde::Raw;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;

ruma_api! {
    metadata: {
        description: "Send transaction messages to another server",
        name: "send_transaction_message",
        method: PUT,
        path: "/_matrix/federation/v1/send/:transaction_id",
        rate_limited: false,
        authentication: ServerSignatures,
    }

    request: {
        /// A transaction ID unique between sending and receiving homeservers.
        #[ruma_api(path)]
        pub transaction_id: &'a str,

        /// The server_name of the homeserver sending this transaction.
        pub origin: &'a ServerName,

        /// POSIX timestamp in milliseconds on the originating homeserver when this transaction
        /// started.
        #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
        pub origin_server_ts: SystemTime,

        /// List of persistent updates to rooms.
        ///
        /// Must not be more than 50 items.
        pub pdus: &'a [Raw<Pdu>],

        /// List of ephemeral messages.
        ///
        /// Must not be more than 100 items.
        #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
        pub edus: &'a [Raw<Edu>],
    }

    #[derive(Default)]
    response: {
        /// Map of event IDs and response for each PDU given in the request.
        #[serde(with = "crate::serde::pdu_process_response")]
        pub pdus: BTreeMap<EventId, Result<(), String>>,
    }
}

impl<'a> Request<'a> {
    /// Creates a new `Request` with the given transaction ID, origin, timestamp.
    ///
    /// The PDU and EDU lists will start off empty.
    pub fn new(
        transaction_id: &'a str,
        origin: &'a ServerName,
        origin_server_ts: SystemTime,
    ) -> Self {
        Self { transaction_id, origin, origin_server_ts, pdus: &[], edus: &[] }
    }
}

impl Response {
    /// Creates a new `Response` with the given PDUs.
    pub fn new(pdus: BTreeMap<EventId, Result<(), String>>) -> Self {
        Self { pdus }
    }
}

/// Type for passing ephemeral data to homeservers.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Edu {
    /// Type of the ephemeral message.
    pub edu_type: String,

    /// Content of ephemeral message
    pub content: JsonValue,
}
<|endoftext|>


<commit_before>//! Starts drivers for found PCI devices,
//! and then reponds to device queries

#![no_std]
#![feature(allocator_api)]
#![deny(unused_must_use)]

#[macro_use]
extern crate alloc;

#[macro_use]
extern crate libd7;

use alloc::vec::Vec;
use alloc::string::String;
use alloc::borrow::ToOwned;

use hashbrown::HashMap;
use serde::Deserialize;

use libd7::{ipc, process::Process, syscall};

#[derive(Debug, Deserialize)]
struct ConfigDevice {
    shortname: Option<String>,
    name: String,
    driver: Option<ConfigDeviceDriver>,
}

#[derive(Debug, Deserialize)]
struct ConfigDeviceDriver {
    from_initrd: bool,
    executable: String,
}

#[no_mangle]
fn main() -> ! {
    syscall::debug_print("PCI driver starting");

    libd7::service::register("driver_pci", false);

    let s: Vec<u8> = ipc::request("initrd/read", "pci_devices.json".to_owned()).unwrap();
    let config_devices: HashMap<String, ConfigDevice> = serde_json::from_slice(&s).unwrap();

    let devices = unsafe { d7pci::list_devices() };

    for device in &devices {
        let vendor_and_id = format!("{:x}:{:x}", device.vendor, device.id);

        if let Some(device_config) = config_devices.get(&vendor_and_id) {
            println!(
                "PCI device: {} ({})",
                device_config.name,
                device_config
                    .driver
                    .as_ref()
                    .map(|d| d.executable.as_ref())
                    .unwrap_or("no driver")
            );
            if let Some(driver) = &device_config.driver {
                assert!(
                    driver.from_initrd,
                    "Non-initrd executables are not supported yet"
                );
                Process::spawn(&driver.executable).unwrap();
            }
        } else {
            println!("Ignoring unknown PCI device {}", vendor_and_id);
        }
    }

    // (DriverName|"vendor:id") -> d7pci::Device
    let server: ipc::Server<String, Option<d7pci::Device>> =
        ipc::Server::exact("pci/device").unwrap();

    loop {
        server
            .handle(|name| {
                for device in &devices {
                    let vendor_and_id = format!("{:x}:{:x}", device.vendor, device.id);
                    if name == vendor_and_id {
                        return Ok(Some(device.clone()));
                    }

                    if let Some(device_config) = config_devices.get(&vendor_and_id) {
                        if name == device_config.name
                            || Some(&name) == device_config.shortname.as_ref()
                        {
                            return Ok(Some(device.clone()));
                        }
                    }
                }

                Ok(None)
            })
            .unwrap();
    }
}
<commit_msg>Print more info during PCI enumeration<commit_after>//! Starts drivers for found PCI devices,
//! and then reponds to device queries

#![no_std]
#![feature(allocator_api)]
#![deny(unused_must_use)]

#[macro_use]
extern crate alloc;

#[macro_use]
extern crate libd7;

use alloc::vec::Vec;
use alloc::string::String;
use alloc::borrow::ToOwned;

use hashbrown::HashMap;
use serde::Deserialize;

use libd7::{ipc, process::Process, syscall};

#[derive(Debug, Deserialize)]
struct ConfigDevice {
    shortname: Option<String>,
    name: String,
    driver: Option<ConfigDeviceDriver>,
}

#[derive(Debug, Deserialize)]
struct ConfigDeviceDriver {
    from_initrd: bool,
    executable: String,
}

#[no_mangle]
fn main() -> ! {
    syscall::debug_print("PCI driver starting");

    libd7::service::register("driver_pci", false);

    let s: Vec<u8> = ipc::request("initrd/read", "pci_devices.json".to_owned()).unwrap();
    let config_devices: HashMap<String, ConfigDevice> = serde_json::from_slice(&s).unwrap();

    let devices = unsafe { d7pci::list_devices() };

    for device in &devices {
        let vendor_and_id = format!("{:x}:{:x}", device.vendor, device.id);

        if let Some(device_config) = config_devices.get(&vendor_and_id) {
            println!(
                "PCI device: {}/{:?} {} ({})",
                vendor_and_id,
                device.location,
                device_config.name,
                device_config
                    .driver
                    .as_ref()
                    .map(|d| d.executable.as_ref())
                    .unwrap_or("no driver")
            );
            if let Some(driver) = &device_config.driver {
                assert!(
                    driver.from_initrd,
                    "Non-initrd executables are not supported yet"
                );
                Process::spawn(&driver.executable).unwrap();
            }
        } else {
            println!("Ignoring unknown PCI device {}", vendor_and_id);
        }
    }

    // (DriverName|"vendor:id") -> d7pci::Device
    let server: ipc::Server<String, Option<d7pci::Device>> =
        ipc::Server::exact("pci/device").unwrap();

    loop {
        server
            .handle(|name| {
                for device in &devices {
                    let vendor_and_id = format!("{:x}:{:x}", device.vendor, device.id);
                    if name == vendor_and_id {
                        return Ok(Some(device.clone()));
                    }

                    if let Some(device_config) = config_devices.get(&vendor_and_id) {
                        if name == device_config.name
                            || Some(&name) == device_config.shortname.as_ref()
                        {
                            return Ok(Some(device.clone()));
                        }
                    }
                }

                Ok(None)
            })
            .unwrap();
    }
}
<|endoftext|>


<commit_before>use super::entities::{Entities, Entity, EntityId};
use super::errors::{NeededBy, Result};
use super::system::InfallibleSystem;
use super::window::Window;
use glium::index::{IndexBuffer, IndicesSource, PrimitiveType};
use glium::vertex::{Vertex, IntoVerticesSource, VertexBuffer, VerticesSource};
use glium_typed::TypedVertexBufferAny;
use idcontain::IdMapVec;

#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)]
pub struct MeshId(EntityId);

pub struct Meshes {
    map: IdMapVec<Entity, Mesh>,
}

impl Meshes {
    pub fn add<'a>(
        &'a mut self,
        window: &'a Window,
        entities: &'a mut Entities,
        parent: EntityId,
        name: &'static str,
    ) -> MeshAdder<'a, (), ()> {
        MeshAdder {
            context: MeshAdderContext {
                meshes: self,
                window,
                entities,
                parent,
                name,
            },
            vertices: (),
            indices: (),
        }
    }

    pub fn get(&self, mesh_id: MeshId) -> Option<MeshRef> {
        self.map.get(mesh_id.0).map(|mesh| match mesh.data {
            InternalMeshData::Owned {
                ref vertices,
                ref indices,
            } => MeshRef {
                vertices,
                indices: indices.as_ref(),
            },
            InternalMeshData::Inherit {
                vertices_from,
                ref indices,
            } => MeshRef {
                vertices: match self.map
                    .get(vertices_from.0)
                    .expect("missing mesh in stored vertices_from")
                    .data {
                    InternalMeshData::Owned { ref vertices, .. } => vertices,
                    _ => panic!("unowned mesh in stored vertices_from"),
                },
                indices: Some(indices),
            },
        })
    }
}

pub struct MeshRef<'a> {
    vertices: &'a TypedVertexBufferAny,
    indices: Option<&'a IndexBuffer<u32>>,
}

impl<'a, 'b: 'a> Into<IndicesSource<'a>> for &'a MeshRef<'b> {
    fn into(self) -> IndicesSource<'a> {
        self.indices.map_or(
            IndicesSource::NoIndices { primitives: PrimitiveType::TrianglesList },
            |buffer| buffer.into(),
            )
    }
}

impl<'a, 'b: 'a> IntoVerticesSource<'a> for &'a MeshRef<'b> {
    fn into_vertices_source(self) -> VerticesSource<'a> {
        self.vertices.into_vertices_source()
    }
}

#[must_use]
pub struct MeshAdder<'a, VertexDataT, IndexDataT> {
    context: MeshAdderContext<'a>,
    vertices: VertexDataT,
    indices: IndexDataT,
}

pub struct OwnedVertexData(TypedVertexBufferAny);
pub struct SharedVertexData(MeshId);
pub struct IndexData(IndexBuffer<u32>);

impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> {
    pub fn immutable<VertexT>(
        self,
        vertices: &[VertexT],
    ) -> Result<MeshAdder<'a, OwnedVertexData, IndexDataT>>
    where
        VertexT: Vertex + Send + 'static,
    {
        Ok(MeshAdder {
            vertices: OwnedVertexData(
                VertexBuffer::immutable(self.context.window.facade(), vertices)
                    .needed_by(self.context.name)?
                    .into(),
            ),
            indices: self.indices,
            context: self.context,
        })
    }

    pub fn persistent<VertexT>(
        self,
        vertices: &[VertexT],
    ) -> Result<MeshAdder<'a, OwnedVertexData, IndexDataT>>
    where
        VertexT: Vertex + Send + 'static,
    {
        Ok(MeshAdder {
            vertices: OwnedVertexData(
                VertexBuffer::persistent(self.context.window.facade(), vertices)
                    .needed_by(self.context.name)?
                    .into(),
            ),
            indices: self.indices,
            context: self.context,
        })
    }

    pub fn shared(self, vertices_from: MeshId) -> MeshAdder<'a, SharedVertexData, IndexDataT> {
        // TODO(cristicbz): If parent comes from a different `Meshes` object, the assertion that
        // the parent is in the map is in incorrect.
        let mut owner = vertices_from;
        while let InternalMeshData::Inherit { vertices_from, .. } =
            self.context
                .meshes
                .map
                .get(owner.0)
                .expect("missing mesh for MeshId")
                .data
        {
            owner = vertices_from;
        }
        MeshAdder {
            vertices: SharedVertexData(owner),
            indices: self.indices,
            context: self.context,
        }
    }
}

impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> {
    pub fn immutable_indices(
        self,
        indices: &[u32],
    ) -> Result<MeshAdder<'a, VertexDataT, IndexData>> {
        Ok(MeshAdder {
            indices: IndexData(IndexBuffer::persistent(
                self.context.window.facade(),
                PrimitiveType::TrianglesList,
                indices,
            ).needed_by(self.context.name)?),
            vertices: self.vertices,
            context: self.context,
        })
    }

    pub fn persistent_indices(
        self,
        indices: &[u32],
    ) -> Result<MeshAdder<'a, VertexDataT, IndexData>> {
        Ok(MeshAdder {
            indices: IndexData(IndexBuffer::persistent(
                self.context.window.facade(),
                PrimitiveType::TrianglesList,
                indices,
            ).needed_by(self.context.name)?),
            vertices: self.vertices,
            context: self.context,
        })
    }
}

impl<'a> MeshAdder<'a, OwnedVertexData, ()> {
    pub fn build_unindexed(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Owned {
            vertices: self.vertices.0,
            indices: None,
        })
    }
}

impl<'a> MeshAdder<'a, SharedVertexData, IndexData> {
    pub fn build(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Inherit {
            vertices_from: self.vertices.0,
            indices: self.indices.0,
        })
    }
}

impl<'a> MeshAdder<'a, OwnedVertexData, IndexData> {
    pub fn build(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Owned {
            vertices: self.vertices.0,
            indices: Some(self.indices.0),
        })
    }
}

pub struct Mesh {
    data: InternalMeshData,
}

impl<'context> InfallibleSystem<'context> for Meshes {
    type Dependencies = &'context Entities;

    fn debug_name() -> &'static str {
        "meshes"
    }

    fn create(_deps: &Entities) -> Self {
        Meshes { map: IdMapVec::with_capacity(128) }
    }

    fn update(&mut self, entities: &Entities) {
        for &entity in entities.last_removed() {
            if self.map.remove(entity).is_some() {
                debug!("Removed mesh {:?}.", entity);
            }
        }
    }

    fn teardown(&mut self, entities: &Entities) {
        self.update(entities);
    }

    fn destroy(mut self, entities: &Entities) {
        self.update(entities);
        if !self.map.is_empty() {
            error!("Meshes leaked, {} instances.", self.map.len());
        }
    }
}

#[cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
enum InternalMeshData {
    Owned {
        vertices: TypedVertexBufferAny,
        indices: Option<IndexBuffer<u32>>,
    },
    Inherit {
        vertices_from: MeshId,
        indices: IndexBuffer<u32>,
    },
}

struct MeshAdderContext<'a> {
    meshes: &'a mut Meshes,
    window: &'a Window,
    entities: &'a mut Entities,
    parent: EntityId,
    name: &'static str,
}

impl<'a> MeshAdderContext<'a> {
    fn add(self, data: InternalMeshData) -> Result<MeshId> {
        let id = self.entities.add(self.parent, self.name)?;
        self.meshes.map.insert(id, Mesh { data });
        debug!(
            "Added mesh {:?} {:?} as child of {:?}.",
            self.name,
            id,
            self.parent
        );
        Ok(MeshId(id))
    }
}
<commit_msg>meshes: add MeshRefMut for mapping<commit_after>use super::entities::{Entities, Entity, EntityId};
use super::errors::{NeededBy, Result};
use super::system::InfallibleSystem;
use super::window::Window;
use glium::index::{IndicesSource, PrimitiveType};
pub use glium::index::IndexBuffer;
use glium::vertex::{Vertex, IntoVerticesSource, VertexBuffer, VerticesSource};
pub use glium_typed::TypedVertexBufferAny;
use idcontain::IdMapVec;

#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)]
pub struct MeshId(EntityId);

pub struct Meshes {
    map: IdMapVec<Entity, Mesh>,
}

impl Meshes {
    pub fn add<'a>(
        &'a mut self,
        window: &'a Window,
        entities: &'a mut Entities,
        parent: EntityId,
        name: &'static str,
    ) -> MeshAdder<'a, (), ()> {
        MeshAdder {
            context: MeshAdderContext {
                meshes: self,
                window,
                entities,
                parent,
                name,
            },
            vertices: (),
            indices: (),
        }
    }

    pub fn get(&self, mesh_id: MeshId) -> Option<MeshRef> {
        self.map.get(mesh_id.0).map(|mesh| match mesh.data {
            InternalMeshData::Owned {
                ref vertices,
                ref indices,
            } => MeshRef {
                vertices,
                indices: indices.as_ref(),
            },
            InternalMeshData::Inherit {
                vertices_from,
                ref indices,
            } => MeshRef {
                vertices: match self.map
                    .get(vertices_from.0)
                    .expect("missing mesh in stored vertices_from")
                    .data {
                    InternalMeshData::Owned { ref vertices, .. } => vertices,
                    _ => panic!("unowned mesh in stored vertices_from"),
                },
                indices: Some(indices),
            },
        })
    }

    pub fn get_mut(&mut self, mesh_id: MeshId) -> Option<MeshRefMut> {
        self.map.get_mut(mesh_id.0).map(|mesh| match mesh.data {
            InternalMeshData::Owned {
                ref mut vertices,
                ref mut indices,
            } => MeshRefMut {
                vertices: Some(vertices),
                indices: indices.as_mut(),
            },
            InternalMeshData::Inherit {
                vertices_from: _,
                ref mut indices,
            } => MeshRefMut {
                vertices: None,
                indices: Some(indices),
            },
        })
    }
}

pub struct MeshRefMut<'a> {
    pub vertices: Option<&'a mut TypedVertexBufferAny>,
    pub indices: Option<&'a mut IndexBuffer<u32>>,
}

pub struct MeshRef<'a> {
    vertices: &'a TypedVertexBufferAny,
    indices: Option<&'a IndexBuffer<u32>>,
}

impl<'a, 'b: 'a> Into<IndicesSource<'a>> for &'a MeshRef<'b> {
    fn into(self) -> IndicesSource<'a> {
        self.indices.map_or(
            IndicesSource::NoIndices { primitives: PrimitiveType::TrianglesList },
            |indices| indices.into())
    }
}

impl<'a, 'b: 'a> IntoVerticesSource<'a> for &'a MeshRef<'b> {
    fn into_vertices_source(self) -> VerticesSource<'a> {
        self.vertices.into_vertices_source()
    }
}

#[must_use]
pub struct MeshAdder<'a, VertexDataT, IndexDataT> {
    context: MeshAdderContext<'a>,
    vertices: VertexDataT,
    indices: IndexDataT,
}

pub struct OwnedVertexData(TypedVertexBufferAny);
pub struct SharedVertexData(MeshId);
pub struct IndexData(IndexBuffer<u32>);

impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> {
    pub fn immutable<VertexT>(
        self,
        vertices: &[VertexT],
    ) -> Result<MeshAdder<'a, OwnedVertexData, IndexDataT>>
    where
        VertexT: Vertex + Send + 'static,
    {
        Ok(MeshAdder {
            vertices: OwnedVertexData(
                VertexBuffer::immutable(self.context.window.facade(), vertices)
                    .needed_by(self.context.name)?
                    .into(),
            ),
            indices: self.indices,
            context: self.context,
        })
    }

    pub fn persistent<VertexT>(
        self,
        vertices: &[VertexT],
    ) -> Result<MeshAdder<'a, OwnedVertexData, IndexDataT>>
    where
        VertexT: Vertex + Send + 'static,
    {
        Ok(MeshAdder {
            vertices: OwnedVertexData(
                VertexBuffer::persistent(self.context.window.facade(), vertices)
                    .needed_by(self.context.name)?
                    .into(),
            ),
            indices: self.indices,
            context: self.context,
        })
    }

    pub fn shared(self, vertices_from: MeshId) -> MeshAdder<'a, SharedVertexData, IndexDataT> {
        // TODO(cristicbz): If parent comes from a different `Meshes` object, the assertion that
        // the parent is in the map is in incorrect.
        let mut owner = vertices_from;
        while let InternalMeshData::Inherit { vertices_from, .. } =
            self.context
                .meshes
                .map
                .get(owner.0)
                .expect("missing mesh for MeshId")
                .data
        {
            owner = vertices_from;
        }
        MeshAdder {
            vertices: SharedVertexData(owner),
            indices: self.indices,
            context: self.context,
        }
    }
}

impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> {
    pub fn immutable_indices(
        self,
        indices: &[u32],
    ) -> Result<MeshAdder<'a, VertexDataT, IndexData>> {
        Ok(MeshAdder {
            indices: IndexData(IndexBuffer::persistent(
                self.context.window.facade(),
                PrimitiveType::TrianglesList,
                indices,
            ).needed_by(self.context.name)?),
            vertices: self.vertices,
            context: self.context,
        })
    }

    pub fn persistent_indices(
        self,
        indices: &[u32],
    ) -> Result<MeshAdder<'a, VertexDataT, IndexData>> {
        Ok(MeshAdder {
            indices: IndexData(IndexBuffer::persistent(
                self.context.window.facade(),
                PrimitiveType::TrianglesList,
                indices,
            ).needed_by(self.context.name)?),
            vertices: self.vertices,
            context: self.context,
        })
    }
}

impl<'a> MeshAdder<'a, OwnedVertexData, ()> {
    pub fn build_unindexed(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Owned {
            vertices: self.vertices.0,
            indices: None,
        })
    }
}

impl<'a> MeshAdder<'a, SharedVertexData, IndexData> {
    pub fn build(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Inherit {
            vertices_from: self.vertices.0,
            indices: self.indices.0,
        })
    }
}

impl<'a> MeshAdder<'a, OwnedVertexData, IndexData> {
    pub fn build(self) -> Result<MeshId> {
        self.context.add(InternalMeshData::Owned {
            vertices: self.vertices.0,
            indices: Some(self.indices.0),
        })
    }
}

pub struct Mesh {
    data: InternalMeshData,
}

impl<'context> InfallibleSystem<'context> for Meshes {
    type Dependencies = &'context Entities;

    fn debug_name() -> &'static str {
        "meshes"
    }

    fn create(_deps: &Entities) -> Self {
        Meshes { map: IdMapVec::with_capacity(128) }
    }

    fn update(&mut self, entities: &Entities) {
        for &entity in entities.last_removed() {
            if self.map.remove(entity).is_some() {
                debug!("Removed mesh {:?}.", entity);
            }
        }
    }

    fn teardown(&mut self, entities: &Entities) {
        self.update(entities);
    }

    fn destroy(mut self, entities: &Entities) {
        self.update(entities);
        if !self.map.is_empty() {
            error!("Meshes leaked, {} instances.", self.map.len());
        }
    }
}

#[cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
enum InternalMeshData {
    Owned {
        vertices: TypedVertexBufferAny,
        indices: Option<IndexBuffer<u32>>,
    },
    Inherit {
        vertices_from: MeshId,
        indices: IndexBuffer<u32>,
    },
}

struct MeshAdderContext<'a> {
    meshes: &'a mut Meshes,
    window: &'a Window,
    entities: &'a mut Entities,
    parent: EntityId,
    name: &'static str,
}

impl<'a> MeshAdderContext<'a> {
    fn add(self, data: InternalMeshData) -> Result<MeshId> {
        let id = self.entities.add(self.parent, self.name)?;
        self.meshes.map.insert(id, Mesh { data });
        debug!(
            "Added mesh {:?} {:?} as child of {:?}.",
            self.name,
            id,
            self.parent
        );
        Ok(MeshId(id))
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};
use std::fmt::Arguments;

use super::request::Request;
use super::http;
use super::response::{Response, ResponseBuilder};
use super::results::CabotResult;

pub struct RequestExecutor {
    verbose: bool
}

impl RequestExecutor {

    pub fn new() -> Self {
        RequestExecutor{verbose: false}
    }

    pub fn execute(&self, request: &Request) -> CabotResult<Response> {
        let mut out = CabotLibWrite::new();
        http::http_query(&request, &mut out, self.verbose)?;
        out.response()
    }
}

struct CabotLibWrite {
    response_builder: ResponseBuilder
}

impl CabotLibWrite {

    pub fn new() -> Self {
        CabotLibWrite{response_builder: ResponseBuilder::new()}
    }

    pub fn response(&self) -> CabotResult<Response> {
        self.response_builder.build()
    }
}

impl Write for CabotLibWrite {

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        info!("Parsing response");
        let mut response = Vec::with_capacity(buf.len());
        response.extend_from_slice(buf);
        let response = unsafe { String::from_utf8_unchecked(response) };
        let response: Vec<&str> = response.splitn(2, "\r\n\r\n").collect();
        let header_len = response.get(0).unwrap().len();
        let mut headers: Vec<&str> = response.get(0).unwrap().split("\r\n").collect();
        let mut builder = ResponseBuilder::new();
        let status_line = headers.remove(0);
        info!("Adding status line {}", status_line);
        builder = builder.set_status_line(status_line);
        for header in  headers.iter() {
            info!("Adding header {}", header);
            builder = builder.add_header(header);
        }
        let body = &buf[(header_len + 4)..buf.len()];
        //debug!("Adding body {:?}", body);
        builder = builder.set_body(body);
        self.response_builder = builder;
        debug!("Response Builder - {:?}", self.response_builder);
        Ok(())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }

    // Don't implemented unused method

    fn write(&mut self, _: &[u8]) -> io::Result<usize> {
        Err(io::Error::new(io::ErrorKind::Other, "Not Implemented"))
    }

    fn write_fmt(&mut self, _: Arguments) -> io::Result<()> {
        Err(io::Error::new(io::ErrorKind::Other, "Not Implemented"))
    }

} <commit_msg>Add test for executor<commit_after>use std::io::{self, Write};
use std::fmt::Arguments;

use super::request::Request;
use super::http;
use super::response::{Response, ResponseBuilder};
use super::results::CabotResult;

pub struct RequestExecutor {
    verbose: bool
}

impl RequestExecutor {

    pub fn new() -> Self {
        RequestExecutor{verbose: false}
    }

    pub fn execute(&self, request: &Request) -> CabotResult<Response> {
        let mut out = CabotLibWrite::new();
        http::http_query(&request, &mut out, self.verbose)?;
        out.response()
    }
}

struct CabotLibWrite {
    response_builder: ResponseBuilder
}

impl CabotLibWrite {

    pub fn new() -> Self {
        CabotLibWrite{response_builder: ResponseBuilder::new()}
    }

    pub fn response(&self) -> CabotResult<Response> {
        self.response_builder.build()
    }
}

impl Write for CabotLibWrite {

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        info!("Parsing http response");
        let mut response = Vec::with_capacity(buf.len());
        response.extend_from_slice(buf);
        let response = unsafe { String::from_utf8_unchecked(response) };
        let response: Vec<&str> = response.splitn(2, "\r\n\r\n").collect();
        let header_len = response.get(0).unwrap().len();
        let mut headers: Vec<&str> = response.get(0).unwrap().split("\r\n").collect();
        let mut builder = ResponseBuilder::new();
        let status_line = headers.remove(0);
        debug!("Adding status line {}", status_line);
        builder = builder.set_status_line(status_line);
        for header in  headers.iter() {
            debug!("Adding header {}", header);
            builder = builder.add_header(header);
        }

        let body = if (header_len + 4) < buf.len() {
            &buf[(header_len + 4)..buf.len()]
        }
        else {
            &buf[..]
        };
        //debug!("Adding body {:?}", body);
        builder = builder.set_body(body);
        self.response_builder = builder;
        // debug!("Response Builder - {:?}", self.response_builder);
        Ok(())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }

    // Don't implemented unused method

    fn write(&mut self, _: &[u8]) -> io::Result<usize> {
        Err(io::Error::new(io::ErrorKind::Other, "Not Implemented"))
    }

    fn write_fmt(&mut self, _: Arguments) -> io::Result<()> {
        Err(io::Error::new(io::ErrorKind::Other, "Not Implemented"))
    }

}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_build_http_response_from_string() {
        let response = vec!["HTTP/1.1 200 Ok",
                            "Content-Type: text/plain",
                            "Content-Length: 12",
                            "",
                            "Hello World!"];
        let response = response.join("\r\n");

        let mut out = CabotLibWrite::new();
        out.write_all(response.as_bytes()).unwrap();
        let response = out.response().unwrap();
        assert_eq!(response.http_version(), "HTTP/1.1");
        assert_eq!(response.status_code(), 200);
        assert_eq!(response.status_line(), "200 Ok");
        let headers: &[&str] = &["Content-Type: text/plain", "Content-Length: 12"];
        assert_eq!(response.headers(), headers);
        assert_eq!(response.body_as_string().unwrap(), "Hello World!".to_owned());

    }

}<|endoftext|>


<commit_before>use bytes::Bytes;
use futures::{Poll, Stream};
use futures::sync::mpsc;
use tokio_proto;

use http::Chunk;

pub type TokioBody = tokio_proto::streaming::Body<Chunk, ::Error>;

/// A `Stream` for `Chunk`s used in requests and responses.
#[derive(Debug)]
pub struct Body(TokioBody);

impl Body {
    /// Return an empty body stream
    pub fn empty() -> Body {
        Body(TokioBody::empty())
    }

    /// Return a body stream with an associated sender half
    pub fn pair() -> (mpsc::Sender<Result<Chunk, ::Error>>, Body) {
        let (tx, rx) = TokioBody::pair();
        let rx = Body(rx);
        (tx, rx)
    }
}

impl Stream for Body {
    type Item = Chunk;
    type Error = ::Error;

    fn poll(&mut self) -> Poll<Option<Chunk>, ::Error> {
        self.0.poll()
    }
}

impl From<Body> for tokio_proto::streaming::Body<Chunk, ::Error> {
    fn from(b: Body) -> tokio_proto::streaming::Body<Chunk, ::Error> {
        b.0
    }
}

impl From<tokio_proto::streaming::Body<Chunk, ::Error>> for Body {
    fn from(tokio_body: tokio_proto::streaming::Body<Chunk, ::Error>) -> Body {
        Body(tokio_body)
    }
}

impl From<mpsc::Receiver<Result<Chunk, ::Error>>> for Body {
    fn from(src: mpsc::Receiver<Result<Chunk, ::Error>>) -> Body {
        Body(src.into())
    }
}

impl From<Chunk> for Body {
    fn from (chunk: Chunk) -> Body {
        Body(TokioBody::from(chunk))
    }
}

impl From<Bytes> for Body {
    fn from (bytes: Bytes) -> Body {
        Body(TokioBody::from(Chunk::from(bytes)))
    }
}

impl From<Vec<u8>> for Body {
    fn from (vec: Vec<u8>) -> Body {
        Body(TokioBody::from(Chunk::from(vec)))
    }
}

impl From<&'static [u8]> for Body {
    fn from (slice: &'static [u8]) -> Body {
        Body(TokioBody::from(Chunk::from(slice)))
    }
}

impl From<String> for Body {
    fn from (s: String) -> Body {
        Body(TokioBody::from(Chunk::from(s.into_bytes())))
    }
}

impl From<&'static str> for Body {
    fn from (slice: &'static str) -> Body {
        Body(TokioBody::from(Chunk::from(slice.as_bytes())))
    }
}

fn _assert_send_sync() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}

    _assert_send::<Body>();
    _assert_send::<Chunk>();
    _assert_sync::<Chunk>();
}

#[test]
fn test_body_stream_concat() {
    use futures::{Sink, Stream, Future};
    let (tx, body) = Body::pair();

    ::std::thread::spawn(move || {
        let tx = tx.send(Ok("hello ".into())).wait().unwrap();
        tx.send(Ok("world".into())).wait().unwrap();
    });

    let total = body.concat().wait().unwrap();
    assert_eq!(total.as_ref(), b"hello world");

}
<commit_msg>feat(http): implement `Default` for `Body`<commit_after>use bytes::Bytes;
use futures::{Poll, Stream};
use futures::sync::mpsc;
use tokio_proto;

use http::Chunk;

pub type TokioBody = tokio_proto::streaming::Body<Chunk, ::Error>;

/// A `Stream` for `Chunk`s used in requests and responses.
#[derive(Debug)]
pub struct Body(TokioBody);

impl Body {
    /// Return an empty body stream
    #[inline]
    pub fn empty() -> Body {
        Body(TokioBody::empty())
    }

    /// Return a body stream with an associated sender half
    #[inline]
    pub fn pair() -> (mpsc::Sender<Result<Chunk, ::Error>>, Body) {
        let (tx, rx) = TokioBody::pair();
        let rx = Body(rx);
        (tx, rx)
    }
}

impl Default for Body {
    #[inline]
    fn default() -> Body {
        Body::empty()
    }
}

impl Stream for Body {
    type Item = Chunk;
    type Error = ::Error;

    #[inline]
    fn poll(&mut self) -> Poll<Option<Chunk>, ::Error> {
        self.0.poll()
    }
}

impl From<Body> for tokio_proto::streaming::Body<Chunk, ::Error> {
    #[inline]
    fn from(b: Body) -> tokio_proto::streaming::Body<Chunk, ::Error> {
        b.0
    }
}

impl From<tokio_proto::streaming::Body<Chunk, ::Error>> for Body {
    #[inline]
    fn from(tokio_body: tokio_proto::streaming::Body<Chunk, ::Error>) -> Body {
        Body(tokio_body)
    }
}

impl From<mpsc::Receiver<Result<Chunk, ::Error>>> for Body {
    #[inline]
    fn from(src: mpsc::Receiver<Result<Chunk, ::Error>>) -> Body {
        Body(src.into())
    }
}

impl From<Chunk> for Body {
    #[inline]
    fn from (chunk: Chunk) -> Body {
        Body(TokioBody::from(chunk))
    }
}

impl From<Bytes> for Body {
    #[inline]
    fn from (bytes: Bytes) -> Body {
        Body(TokioBody::from(Chunk::from(bytes)))
    }
}

impl From<Vec<u8>> for Body {
    #[inline]
    fn from (vec: Vec<u8>) -> Body {
        Body(TokioBody::from(Chunk::from(vec)))
    }
}

impl From<&'static [u8]> for Body {
    #[inline]
    fn from (slice: &'static [u8]) -> Body {
        Body(TokioBody::from(Chunk::from(slice)))
    }
}

impl From<String> for Body {
    #[inline]
    fn from (s: String) -> Body {
        Body(TokioBody::from(Chunk::from(s.into_bytes())))
    }
}

impl From<&'static str> for Body {
    #[inline]
    fn from (slice: &'static str) -> Body {
        Body(TokioBody::from(Chunk::from(slice.as_bytes())))
    }
}

fn _assert_send_sync() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}

    _assert_send::<Body>();
    _assert_send::<Chunk>();
    _assert_sync::<Chunk>();
}

#[test]
fn test_body_stream_concat() {
    use futures::{Sink, Stream, Future};
    let (tx, body) = Body::pair();

    ::std::thread::spawn(move || {
        let tx = tx.send(Ok("hello ".into())).wait().unwrap();
        tx.send(Ok("world".into())).wait().unwrap();
    });

    let total = body.concat2().wait().unwrap();
    assert_eq!(total.as_ref(), b"hello world");

}
<|endoftext|>


<commit_before>#![feature(proc_macro, conservative_impl_trait, generators)]
extern crate bytes;
extern crate futures_await as futures;
extern crate tokio_core;
extern crate tokio_io;

mod cmd;
mod ftp;
mod error;
mod codec;

use std::result;
use std::io;
use futures::prelude::*;
use tokio_core::reactor::Core;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use tokio_core::reactor::Handle;
use tokio_core::net::TcpListener;

use tokio_core::net::TcpStream;

use futures::{Sink, Stream};
use futures::stream::SplitSink;

use tokio_io::AsyncRead;
use tokio_io::codec::Framed;
use codec::FtpCodec;
use error::Result;
use ftp::{Answer, ResultCode};
use std::path::PathBuf;

use cmd::Command;
type Writer = SplitSink<Framed<TcpStream, FtpCodec>>;

struct Client {
    cwd: PathBuf,
    writer: Writer,
}

impl Client {
    fn new(writer: Writer) -> Client {
        Client {
            cwd: PathBuf::from("/"),
            writer,
        }
    }
    #[async]
    fn send(mut self, answer: Answer) -> Result<Self> {
        self.writer = await!(self.writer.send(answer))?;
        Ok(self)
    }

    #[async]
    fn handle_cmd(mut self, cmd: Command) -> Result<Self> {
        println!("Received command: {:?}", cmd);
        match cmd {
            Command::User(content) => {
                if content.is_empty() {
                    self = await!(self.send(Answer::new(ResultCode::InvalidParameterOrArgument,"Invalid username")))?;
                } else {
                    self = await!(self.send(Answer::new(ResultCode::UserloggedIn,&format!("Welcome {}",content))))?;
                }
            },
            Command::Pwd => {
                let msg = format!("{}", self.cwd.to_str().unwrap_or(""));
                if !msg.is_empty() {
                    let message = format!("\"/{}\" ",msg);
                    self = await!(self.send(Answer::new(ResultCode::PATHNAMECreated, &message)))?;
                } else {
                    self = await!(self.send(Answer::new(ResultCode::FileNotFound, "No such file or directory")))?;
                }
            },
            Command::Unknown(s) => self = await!(self.send(Answer::new(ResultCode::UnknownCommand, &format!("\"{}\": Not Implemented",s))))?,
            _=>  self = await!(self.send(Answer::new(ResultCode::CommandNotImplemented, "Not implemented")))?,
        }
        return Ok(self);
    }

}

#[async]
fn client(stream: TcpStream) -> Result<()>{
    let (writer, reader) = stream.framed(FtpCodec).split();
    let writer = await!(writer.send(Answer::new(ResultCode::ServiceReadyForNewUser, "Welcome to this FTP Server!")))?;
    let mut client = Client::new(writer);
    #[async]
    for cmd in reader {
        client = await!(client.handle_cmd(cmd))?;
    }
    println!("Client closed");
    return Ok(());;
}

#[async]
fn handle_client(stream: TcpStream) -> result::Result<(), ()> {
    await!(client(stream)).map_err(|error| println!("Error handling client: {}", error))
}

#[async]
fn server(handle: Handle) -> io::Result<()> {
    let port = 1234;
    let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127,0,0,1)), port);
    let listener = TcpListener::bind(&addr,&handle)?;
    println!("Waiting clients on port {}...",port);
    #[async]
    for (stream, addr) in listener.incoming() {
        let address = format!("[address : {}]",addr);
        println!("New client {}", address);
        handle.spawn(handle_client(stream));
        println!("Waiting another client...");
    }
    return Ok(());
}

fn main() {
    let mut core = Core::new().expect("Cannot create tokio Core");
    let handle = core.handle();
    if let Err(error) = core.run(server(handle)) {
        println!("Error running the server: {}", error);
    }

}
<commit_msg>Added new oper in ftp<commit_after>#![feature(proc_macro, conservative_impl_trait, generators)]
extern crate bytes;
extern crate futures_await as futures;
extern crate tokio_core;
extern crate tokio_io;

mod cmd;
mod ftp;
mod error;
mod codec;

use std::result;
use std::io;
use std::env;
use futures::prelude::*;
use tokio_core::reactor::Core;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use tokio_core::reactor::Handle;
use tokio_core::net::TcpListener;

use tokio_core::net::TcpStream;

use futures::{Sink, Stream};
use futures::stream::SplitSink;

use tokio_io::AsyncRead;
use tokio_io::codec::Framed;
use codec::FtpCodec;
use error::Result;
use ftp::{Answer, ResultCode};
use std::path::PathBuf;
use std::path::StripPrefixError;

use cmd::Command;
type Writer = SplitSink<Framed<TcpStream, FtpCodec>>;

struct Client {
    cwd: PathBuf,
    server_root: PathBuf,
    writer: Writer,
}

impl Client {
    fn new(writer: Writer, server_root: PathBuf) -> Client {
        Client {
            cwd: PathBuf::from("/"),
            server_root,
            writer,
        }
    }
    #[async]
    fn send(mut self, answer: Answer) -> Result<Self> {
        self.writer = await!(self.writer.send(answer))?;
        Ok(self)
    }

    fn complete_path(self, path: PathBuf) -> (Self, result::Result<PathBuf, io::Error>) {
        let directory = self.server_root.join(if path.has_root() {
                path.iter().skip(1).collect()
            } else {
                path
        });
        let dir = directory.canocalize();
        if let Ok(ref dir) = dir {
            if !dir.starts_with(&self.server_root) {
                return (self, Err(io::ErrorKind::PermissionDenied.into()));
            }
        }
        (self,dir)
    }
    fn strip_prefix(self, dir:PathBuf) -> (Self, result::Result<PathBuf, StripPrefixError>) {
        let res = dir.strip_prefix(&self.server_root).map(|p| p.to_path_buf());
        (self,res)
    }

    #[async]
    fn cwd(mut self, directory: PathBuf) -> Result<Self>{
        let path = self.cwd.join(&directory);
        let (new_self, res) = self.complete_path(path);
        self = new_self;
        if let Ok(dir) = res {
            let (new_self, res) = self.strip_prefix(dir);
            self = new_self;
            if let Ok(prefix) = res {
                self.cwd = prefix.to_path_buf();
                self = await!(self.send(Answer::new(ResultCode::Ok, &format!("Directory changed to \"{}\"", directory.display()))))?;
                return Ok(self)
            }
        }
        self = await!(self.send(Answer::new(ResultCode::FileNotFound, "No such file or directory")))?;
        Ok(self);
    }

    #[async]
    fn handle_cmd(mut self, cmd: Command) -> Result<Self> {
        println!("Received command: {:?}", cmd);
        match cmd {
            Command::Cwd(directory) => {
                self= await!(self.cwd(directory))?;
            },
            Command::User(content) => {
                if content.is_empty() {
                    self = await!(self.send(Answer::new(ResultCode::InvalidParameterOrArgument,"Invalid username")))?;
                } else {
                    self = await!(self.send(Answer::new(ResultCode::UserloggedIn,&format!("Welcome {}",content))))?;
                }
            },
            Command::Pwd => {
                let msg = format!("{}", self.cwd.to_str().unwrap_or(""));
                if !msg.is_empty() {
                    let message = format!("\"/{}\" ",msg);
                    self = await!(self.send(Answer::new(ResultCode::PATHNAMECreated, &message)))?;
                } else {
                    self = await!(self.send(Answer::new(ResultCode::FileNotFound, "No such file or directory")))?;
                }
            },
            Command::Unknown(s) => self = await!(self.send(Answer::new(ResultCode::UnknownCommand, &format!("\"{}\": Not Implemented",s))))?,
            _=>  self = await!(self.send(Answer::new(ResultCode::CommandNotImplemented, "Not implemented")))?,
        }
        return Ok(self);
    }
}

#[async]
fn client(stream: TcpStream, server_root: PathBuf) -> Result<()>{
    let (writer, reader) = stream.framed(FtpCodec).split();
    let writer = await!(writer.send(Answer::new(ResultCode::ServiceReadyForNewUser, "Welcome to this FTP Server!")))?;
    let mut client = Client::new(writer, server_root);
    #[async]
    for cmd in reader {
        client = await!(client.handle_cmd(cmd))?;
    }
    println!("Client closed");
    return Ok(());;
}

#[async]
fn handle_client(stream: TcpStream, server_root: PathBuf) -> result::Result<(), ()> {
    await!(client(stream, server_root)).map_err(|error| println!("Error handling client: {}", error))
}

#[async]
fn server(handle: Handle, server_root: PathBuf) -> io::Result<()> {
    let port = 1234;
    let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127,0,0,1)), port);
    let listener = TcpListener::bind(&addr,&handle)?;
    println!("Waiting clients on port {}...",port);
    #[async]
    for (stream, addr) in listener.incoming() {
        let address = format!("[address : {}]",addr);
        println!("New client {}", address);
        handle.spawn(handle_client(stream, server_root.clone()));
        println!("Waiting another client...");
    }
    return Ok(());
}

fn main() {
    let mut core = Core::new().expect("Cannot create tokio Core");
    let handle = core.handle();
    match env::current_dir() {
        Ok(server_root) => {
            if let Err(error) = core.run(server(handle, server_root)) {
                println!("Error running the server: {}", error);
            }
        },
        Err(e) => println!("Could not start server: {:?}",e),

    }

}
<|endoftext|>


<commit_before>#![cfg(feature = "std")]

extern crate rand;
extern crate libc;

use rand::rngs::SmallRng;
use rand::FromEntropy;
use rand::distributions::{Distribution, Bernoulli};

#[link_name = "m"]
extern "C" {
    fn nextafter(x: f64, y: f64) -> f64;
}

/// This test should make sure that we don't accidentally have undefined
/// behavior for large propabilties due to
/// https://github.com/rust-lang/rust/issues/10184.
#[test]
fn large_probability() {
    let p = unsafe { nextafter(1., 0.) };
    assert!(p < 1.);
    let d = Bernoulli::new(p);
    let mut rng = SmallRng::from_entropy();
    for _ in 0..10 {
        assert!(d.sample(&mut rng));
    }
}
<commit_msg>Improve bool test<commit_after>#![no_std]

extern crate rand;

use rand::rngs::SmallRng;
use rand::FromEntropy;
use rand::distributions::{Distribution, Bernoulli};

/// This test should make sure that we don't accidentally have undefined
/// behavior for large propabilties due to
/// https://github.com/rust-lang/rust/issues/10184.
/// Expressions like `1.0*(u64::MAX as f64) as u64` have to be avoided.
#[test]
fn large_probability() {
    let p = 1. - ::core::f64::EPSILON / 2.;
    assert!(p < 1.);
    let d = Bernoulli::new(p);
    let mut rng = SmallRng::from_entropy();
    for _ in 0..10 {
        assert!(d.sample(&mut rng), "extremely unlikely to fail by accident");
    }
}
<|endoftext|>