<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use chrono::naive::datetime::NaiveDateTime;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;

use datepath::accuracy::Accuracy;
use datepath::format::Format;
use datepath::result::Result;
use datepath::error::DatePathCompilerErrorKind as DPCEK;
use datepath::error::MapErrInto;

pub struct DatePathCompiler {
    accuracy : Accuracy,
    format   : Format,
}

impl DatePathCompiler {

    pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
        DatePathCompiler {
            accuracy : accuracy,
            format   : format,
        }
    }

    /// Compile a NaiveDateTime object into a StoreId object.
    ///
    /// # More information
    ///
    /// See the documentations of the `Format` and the `Accuracy` types as well.
    ///
    /// # Warnings
    ///
    /// This does _not_ guarantee that the StoreId can be created, is not yet in the store or
    /// anything else. Overall, this is just a `spec->path` compiler which is really stupid.
    ///
    /// # Return value
    ///
    /// The `StoreId` object on success.
    ///
    pub fn compile(&self, module_name: &str, datetime: &NaiveDateTime) -> Result<StoreId> {
        let mut s = format!("{}/", module_name);

        if self.accuracy.has_year_accuracy() /* always true */ {
            s.push_str(&format!("{}", datetime.year()));
        }

        if self.accuracy.has_month_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    | Format::YearIsFolder
                    => s.push_str(&format!("/{}", datetime.month())),
            }
        }

        if self.accuracy.has_day_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("/{}", datetime.day())),
                Format::YearIsFolder
                    => s.push_str(&format!("-{}", datetime.day())),
            }
        }

        if self.accuracy.has_hour_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("/{}", datetime.hour())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("-{}", datetime.hour())),
            }
        }

        if self.accuracy.has_minute_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.minute())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.minute())),
            }
        }

        if self.accuracy.has_second_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.second())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.second())),
            }
        }

        StoreId::new_baseless(PathBuf::from(s))
            .map_err_into(DPCEK::StoreIdBuildFailed)
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use datepath::accuracy::Accuracy;
    use datepath::format::Format;

    use chrono::naive::date::NaiveDate;
    use chrono::naive::datetime::NaiveDateTime;

    #[test]
    fn test_compiler_compile_simple() {
        let dt       = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        let compiler = DatePathCompiler::new(Accuracy::default(), Format::default());
        let res      = compiler.compile("testmodule", &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!("testmodule/2000/1/1/0/0/0", s);
    }

    fn test_accuracy(acc: Accuracy, dt: NaiveDateTime, modname: &str, matchstr: &str) {
        let compiler = DatePathCompiler::new(acc, Format::default());
        let res      = compiler.compile(modname, &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!(matchstr, s);
    }

    #[test]
    fn test_compiler_compile_year_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Year, dt, "module", "module/2000");
    }

    #[test]
    fn test_compiler_compile_month_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Month, dt, "module", "module/2000/1");
    }

    #[test]
    fn test_compiler_compile_day_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Day, dt, "module", "module/2000/1/1");
    }

}

<commit_msg>Modify tests: Padding zeros<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;

use chrono::naive::datetime::NaiveDateTime;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;

use datepath::accuracy::Accuracy;
use datepath::format::Format;
use datepath::result::Result;
use datepath::error::DatePathCompilerErrorKind as DPCEK;
use datepath::error::MapErrInto;

pub struct DatePathCompiler {
    accuracy : Accuracy,
    format   : Format,
}

impl DatePathCompiler {

    pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
        DatePathCompiler {
            accuracy : accuracy,
            format   : format,
        }
    }

    /// Compile a NaiveDateTime object into a StoreId object.
    ///
    /// # More information
    ///
    /// See the documentations of the `Format` and the `Accuracy` types as well.
    ///
    /// # Warnings
    ///
    /// This does _not_ guarantee that the StoreId can be created, is not yet in the store or
    /// anything else. Overall, this is just a `spec->path` compiler which is really stupid.
    ///
    /// # Return value
    ///
    /// The `StoreId` object on success.
    ///
    pub fn compile(&self, module_name: &str, datetime: &NaiveDateTime) -> Result<StoreId> {
        let mut s = format!("{}/", module_name);

        if self.accuracy.has_year_accuracy() /* always true */ {
            s.push_str(&format!("{}", datetime.year()));
        }

        if self.accuracy.has_month_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    | Format::YearIsFolder
                    => s.push_str(&format!("/{}", datetime.month())),
            }
        }

        if self.accuracy.has_day_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("/{}", datetime.day())),
                Format::YearIsFolder
                    => s.push_str(&format!("-{}", datetime.day())),
            }
        }

        if self.accuracy.has_hour_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("/{}", datetime.hour())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    => s.push_str(&format!("-{}", datetime.hour())),
            }
        }

        if self.accuracy.has_minute_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.minute())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.minute())),
            }
        }

        if self.accuracy.has_second_accuracy() {
            match self.format {
                Format::ElementIsFolder
                    => s.push_str(&format!("/{}", datetime.second())),
                Format::YearIsFolder
                    | Format::MonthIsFolder
                    | Format::DaysAreFolder
                    => s.push_str(&format!("-{}", datetime.second())),
            }
        }

        StoreId::new_baseless(PathBuf::from(s))
            .map_err_into(DPCEK::StoreIdBuildFailed)
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use datepath::accuracy::Accuracy;
    use datepath::format::Format;

    use chrono::naive::date::NaiveDate;
    use chrono::naive::datetime::NaiveDateTime;

    #[test]
    fn test_compiler_compile_simple() {
        let dt       = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        let compiler = DatePathCompiler::new(Accuracy::default(), Format::default());
        let res      = compiler.compile("testmodule", &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!("testmodule/2000/01/01/00/00/00", s);
    }

    fn test_accuracy(acc: Accuracy, dt: NaiveDateTime, modname: &str, matchstr: &str) {
        let compiler = DatePathCompiler::new(acc, Format::default());
        let res      = compiler.compile(modname, &dt);

        assert!(res.is_ok());
        let res = res.unwrap();

        let s = res.to_str();

        assert!(s.is_ok());
        let s = s.unwrap();

        assert_eq!(matchstr, s);
    }

    #[test]
    fn test_compiler_compile_year_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Year, dt, "module", "module/2000");
    }

    #[test]
    fn test_compiler_compile_month_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Month, dt, "module", "module/2000/01");
    }

    #[test]
    fn test_compiler_compile_day_accuracy() {
        let dt = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Day, dt, "module", "module/2000/01/01");
    }

    #[test]
    fn test_compiler_compile_year_paddning() {
        let dt = NaiveDate::from_ymd(1, 1, 1).and_hms(0, 0, 0);
        test_accuracy(Accuracy::Day, dt, "module", "module/0001/01/01");
    }

}

<|endoftext|>


<commit_before>
extern crate event;

use event::{
    Action,
    IntoState,
    State,
    Sequence,
    Update,
    UpdateArgs,
    Wait,
    WhenAll,
    While,
};

/// Some test actions.
#[deriving(Clone)]
pub enum TestActions {
    /// Increment accumulator.
    Inc,
    /// Decrement accumulator.
    Dec,
}

impl IntoState<()> for TestActions {
    fn into_state(self) {}
}

// A test state machine that can increment and decrement.
fn exec(mut acc: u32, dt: f64, state: &mut State<TestActions>) -> u32 {
    state.update(&Update(UpdateArgs { dt: dt }), |dt, action, _| {
        match *action {
            Inc => { acc += 1; (event::Success, dt) },
            Dec => { acc -= 1; (event::Success, dt) },
        }
    });
    acc
}

// Each action that terminates immediately
// consumes a time of 0.0 seconds.
// This makes it possible to execute one action
// after another without delay or waiting for next update.
fn print_2() {
    let a: u32 = 0;
    let seq = Sequence(vec![Action(Inc), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 0.0, &mut state);
    assert_eq!(a, 2);
}

// If you wait the exact amount before to execute an action,
// it will execute. This behavior makes it easy to predict
// when an action will run.
fn wait_sec() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(1.0), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 1.0, &mut state);
    assert_eq!(a, 1);
}

// When we execute half the time and then the other half,
// then the action should be executed.
fn wait_half_sec() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(1.0), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 0);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 1);
}

// A sequence of wait events is the same as one wait event.
fn wait_two_waits() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(0.5), Wait(0.5), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 1.0, &mut state);
    assert_eq!(a, 1);
}

// Increase counter ten times.
fn loop_ten_times() {
    let a: u32 = 0;
    let rep = While(box Wait(50.0), vec![Wait(0.5), Action(Inc), Wait(0.5)]);
    let mut state = State::new(rep);
    let a = exec(a, 10.0, &mut state);
    assert_eq!(a, 10);
}

fn when_all_wait() {
    let a: u32 = 0;
    let all = Sequence(vec![
            // Wait in parallel.
            WhenAll(vec![Wait(0.5), Wait(1.0)]),
            Action(Inc)
        ]);
    let mut state = State::new(all);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 0);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 1);
}

fn main() {
    print_2();
    wait_sec();
    wait_half_sec();
    wait_two_waits();
    loop_ten_times();
    when_all_wait();
}
<commit_msg>Added missing generic parameter<commit_after>
extern crate event;

use event::{
    Action,
    IntoState,
    State,
    Sequence,
    Update,
    UpdateArgs,
    Wait,
    WhenAll,
    While,
};

/// Some test actions.
#[deriving(Clone)]
pub enum TestActions {
    /// Increment accumulator.
    Inc,
    /// Decrement accumulator.
    Dec,
}

impl IntoState<()> for TestActions {
    fn into_state(self) {}
}

// A test state machine that can increment and decrement.
fn exec(mut acc: u32, dt: f64, state: &mut State<TestActions, ()>) -> u32 {
    state.update(&Update(UpdateArgs { dt: dt }), |dt, action, _| {
        match *action {
            Inc => { acc += 1; (event::Success, dt) },
            Dec => { acc -= 1; (event::Success, dt) },
        }
    });
    acc
}

// Each action that terminates immediately
// consumes a time of 0.0 seconds.
// This makes it possible to execute one action
// after another without delay or waiting for next update.
fn print_2() {
    let a: u32 = 0;
    let seq = Sequence(vec![Action(Inc), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 0.0, &mut state);
    assert_eq!(a, 2);
}

// If you wait the exact amount before to execute an action,
// it will execute. This behavior makes it easy to predict
// when an action will run.
fn wait_sec() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(1.0), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 1.0, &mut state);
    assert_eq!(a, 1);
}

// When we execute half the time and then the other half,
// then the action should be executed.
fn wait_half_sec() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(1.0), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 0);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 1);
}

// A sequence of wait events is the same as one wait event.
fn wait_two_waits() {
    let a: u32 = 0;
    let seq = Sequence(vec![Wait(0.5), Wait(0.5), Action(Inc)]);
    let mut state = State::new(seq);
    let a = exec(a, 1.0, &mut state);
    assert_eq!(a, 1);
}

// Increase counter ten times.
fn loop_ten_times() {
    let a: u32 = 0;
    let rep = While(box Wait(50.0), vec![Wait(0.5), Action(Inc), Wait(0.5)]);
    let mut state = State::new(rep);
    let a = exec(a, 10.0, &mut state);
    assert_eq!(a, 10);
}

fn when_all_wait() {
    let a: u32 = 0;
    let all = Sequence(vec![
            // Wait in parallel.
            WhenAll(vec![Wait(0.5), Wait(1.0)]),
            Action(Inc)
        ]);
    let mut state = State::new(all);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 0);
    let a = exec(a, 0.5, &mut state);
    assert_eq!(a, 1);
}

fn main() {
    print_2();
    wait_sec();
    wait_half_sec();
    wait_two_waits();
    loop_ten_times();
    when_all_wait();
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// This example shows a basic packet logger using libpnet

extern crate pnet;

use pnet::datalink::{self, NetworkInterface};

use pnet::packet::Packet;
use pnet::packet::arp::ArpPacket;
use pnet::packet::ethernet::{EtherTypes, EthernetPacket};
use pnet::packet::icmp::{IcmpPacket, IcmpTypes, echo_reply, echo_request};
use pnet::packet::ip::{IpNextHeaderProtocol, IpNextHeaderProtocols};
use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::ipv6::Ipv6Packet;
use pnet::packet::tcp::TcpPacket;
use pnet::packet::udp::UdpPacket;
use std::env;
use std::net::IpAddr;

fn handle_udp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let udp = UdpPacket::new(packet);

    if let Some(udp) = udp {
        println!("[{}]: UDP Packet: {}:{} > {}:{}; length: {}",
                 interface_name,
                 source,
                 udp.get_source(),
                 destination,
                 udp.get_destination(),
                 udp.get_length());
    } else {
        println!("[{}]: Malformed UDP Packet", interface_name);
    }
}

fn handle_icmp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let icmp_packet = IcmpPacket::new(packet);
    if let Some(icmp_packet) = icmp_packet {
        match icmp_packet.get_icmp_type() {
            IcmpTypes::EchoReply => {
                let echo_reply_packet = echo_reply::EchoReplyPacket::new(packet).unwrap();
                println!("[{}]: ICMP echo reply {} -> {} (seq={:?}, id={:?})",
                         interface_name,
                         source,
                         destination,
                         echo_reply_packet.get_sequence_number(),
                         echo_reply_packet.get_identifier());
            }
            IcmpTypes::EchoRequest => {
                let echo_request_packet = echo_request::EchoRequestPacket::new(packet).unwrap();
                println!("[{}]: ICMP echo request {} -> {} (seq={:?}, id={:?})",
                         interface_name,
                         source,
                         destination,
                         echo_request_packet.get_sequence_number(),
                         echo_request_packet.get_identifier());
            }
            _ => {
                println!("[{}]: ICMP packet {} -> {} (type={:?})",
                         interface_name,
                         source,
                         destination,
                         icmp_packet.get_icmp_type())
            }
        }
    } else {
        println!("[{}]: Malformed ICMP Packet", interface_name);
    }
}

fn handle_tcp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let tcp = TcpPacket::new(packet);
    if let Some(tcp) = tcp {
        println!("[{}]: TCP Packet: {}:{} > {}:{}; length: {}",
                 interface_name,
                 source,
                 tcp.get_source(),
                 destination,
                 tcp.get_destination(),
                 packet.len());
    } else {
        println!("[{}]: Malformed TCP Packet", interface_name);
    }
}

fn handle_transport_protocol(interface_name: &str,
                             source: IpAddr,
                             destination: IpAddr,
                             protocol: IpNextHeaderProtocol,
                             packet: &[u8]) {
    match protocol {
        IpNextHeaderProtocols::Udp => {
            handle_udp_packet(interface_name, source, destination, packet)
        }
        IpNextHeaderProtocols::Tcp => {
            handle_tcp_packet(interface_name, source, destination, packet)
        }
        IpNextHeaderProtocols::Icmp => {
            handle_icmp_packet(interface_name, source, destination, packet)
        }
        _ => {
            println!("[{}]: Unknown {} packet: {} > {}; protocol: {:?} length: {}",
                     interface_name,
                     match source {
                         IpAddr::V4(..) => "IPv4",
                         _ => "IPv6",
                     },
                     source,
                     destination,
                     protocol,
                     packet.len())
        }

    }
}

fn handle_ipv4_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = Ipv4Packet::new(ethernet.payload());
    if let Some(header) = header {
        handle_transport_protocol(interface_name,
                                  IpAddr::V4(header.get_source()),
                                  IpAddr::V4(header.get_destination()),
                                  header.get_next_level_protocol(),
                                  header.payload());
    } else {
        println!("[{}]: Malformed IPv4 Packet", interface_name);
    }
}

fn handle_ipv6_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = Ipv6Packet::new(ethernet.payload());
    if let Some(header) = header {
        handle_transport_protocol(interface_name,
                                  IpAddr::V6(header.get_source()),
                                  IpAddr::V6(header.get_destination()),
                                  header.get_next_header(),
                                  header.payload());
    } else {
        println!("[{}]: Malformed IPv6 Packet", interface_name);
    }
}

fn handle_arp_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = ArpPacket::new(ethernet.payload());
    if let Some(header) = header {
        println!("[{}]: ARP packet: {}({}) > {}({}); operation: {:?}",
                 interface_name,
                 ethernet.get_source(),
                 header.get_sender_proto_addr(),
                 ethernet.get_destination(),
                 header.get_target_proto_addr(),
                 header.get_operation());
    } else {
        println!("[{}]: Malformed ARP Packet", interface_name);
    }
}

fn handle_packet(interface_name: &str, ethernet: &EthernetPacket) {
    match ethernet.get_ethertype() {
        EtherTypes::Ipv4 => handle_ipv4_packet(interface_name, ethernet),
        EtherTypes::Ipv6 => handle_ipv6_packet(interface_name, ethernet),
        EtherTypes::Arp => handle_arp_packet(interface_name, ethernet),
        _ => {
            println!("[{}]: Unknown packet: {} > {}; ethertype: {:?} length: {}",
                     interface_name,
                     ethernet.get_source(),
                     ethernet.get_destination(),
                     ethernet.get_ethertype(),
                     ethernet.packet().len())
        }
    }
}

fn main() {
    use pnet::datalink::Channel::Ethernet;

    let iface_name = env::args().nth(1).unwrap();
    let interface_names_match = |iface: &NetworkInterface| iface.name == iface_name;

    // Find the network interface with the provided name
    let interfaces = datalink::interfaces();
    let interface = interfaces.into_iter().filter(interface_names_match).next().unwrap();

    // Create a channel to receive on
    let (_, mut rx) = match datalink::channel(&interface, Default::default()) {
        Ok(Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("packetdump: unhandled channel type: {}"),
        Err(e) => panic!("packetdump: unable to create channel: {}", e),
    };

    let mut iter = rx.iter();
    loop {
        match iter.next() {
            Ok(packet) => handle_packet(&interface.name[..], &packet),
            Err(e) => panic!("packetdump: unable to receive packet: {}", e),
        }
    }
}
<commit_msg>Add better error handling for packetdump example.<commit_after>// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// This example shows a basic packet logger using libpnet

extern crate pnet;

use pnet::datalink::{self, NetworkInterface};

use pnet::packet::Packet;
use pnet::packet::arp::ArpPacket;
use pnet::packet::ethernet::{EtherTypes, EthernetPacket};
use pnet::packet::icmp::{IcmpPacket, IcmpTypes, echo_reply, echo_request};
use pnet::packet::ip::{IpNextHeaderProtocol, IpNextHeaderProtocols};
use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::ipv6::Ipv6Packet;
use pnet::packet::tcp::TcpPacket;
use pnet::packet::udp::UdpPacket;
use std::env;
use std::io::{self, Write};
use std::process;
use std::net::IpAddr;

fn handle_udp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let udp = UdpPacket::new(packet);

    if let Some(udp) = udp {
        println!("[{}]: UDP Packet: {}:{} > {}:{}; length: {}",
                 interface_name,
                 source,
                 udp.get_source(),
                 destination,
                 udp.get_destination(),
                 udp.get_length());
    } else {
        println!("[{}]: Malformed UDP Packet", interface_name);
    }
}

fn handle_icmp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let icmp_packet = IcmpPacket::new(packet);
    if let Some(icmp_packet) = icmp_packet {
        match icmp_packet.get_icmp_type() {
            IcmpTypes::EchoReply => {
                let echo_reply_packet = echo_reply::EchoReplyPacket::new(packet).unwrap();
                println!("[{}]: ICMP echo reply {} -> {} (seq={:?}, id={:?})",
                         interface_name,
                         source,
                         destination,
                         echo_reply_packet.get_sequence_number(),
                         echo_reply_packet.get_identifier());
            }
            IcmpTypes::EchoRequest => {
                let echo_request_packet = echo_request::EchoRequestPacket::new(packet).unwrap();
                println!("[{}]: ICMP echo request {} -> {} (seq={:?}, id={:?})",
                         interface_name,
                         source,
                         destination,
                         echo_request_packet.get_sequence_number(),
                         echo_request_packet.get_identifier());
            }
            _ => {
                println!("[{}]: ICMP packet {} -> {} (type={:?})",
                         interface_name,
                         source,
                         destination,
                         icmp_packet.get_icmp_type())
            }
        }
    } else {
        println!("[{}]: Malformed ICMP Packet", interface_name);
    }
}

fn handle_tcp_packet(interface_name: &str, source: IpAddr, destination: IpAddr, packet: &[u8]) {
    let tcp = TcpPacket::new(packet);
    if let Some(tcp) = tcp {
        println!("[{}]: TCP Packet: {}:{} > {}:{}; length: {}",
                 interface_name,
                 source,
                 tcp.get_source(),
                 destination,
                 tcp.get_destination(),
                 packet.len());
    } else {
        println!("[{}]: Malformed TCP Packet", interface_name);
    }
}

fn handle_transport_protocol(interface_name: &str,
                             source: IpAddr,
                             destination: IpAddr,
                             protocol: IpNextHeaderProtocol,
                             packet: &[u8]) {
    match protocol {
        IpNextHeaderProtocols::Udp => {
            handle_udp_packet(interface_name, source, destination, packet)
        }
        IpNextHeaderProtocols::Tcp => {
            handle_tcp_packet(interface_name, source, destination, packet)
        }
        IpNextHeaderProtocols::Icmp => {
            handle_icmp_packet(interface_name, source, destination, packet)
        }
        _ => {
            println!("[{}]: Unknown {} packet: {} > {}; protocol: {:?} length: {}",
                     interface_name,
                     match source {
                         IpAddr::V4(..) => "IPv4",
                         _ => "IPv6",
                     },
                     source,
                     destination,
                     protocol,
                     packet.len())
        }

    }
}

fn handle_ipv4_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = Ipv4Packet::new(ethernet.payload());
    if let Some(header) = header {
        handle_transport_protocol(interface_name,
                                  IpAddr::V4(header.get_source()),
                                  IpAddr::V4(header.get_destination()),
                                  header.get_next_level_protocol(),
                                  header.payload());
    } else {
        println!("[{}]: Malformed IPv4 Packet", interface_name);
    }
}

fn handle_ipv6_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = Ipv6Packet::new(ethernet.payload());
    if let Some(header) = header {
        handle_transport_protocol(interface_name,
                                  IpAddr::V6(header.get_source()),
                                  IpAddr::V6(header.get_destination()),
                                  header.get_next_header(),
                                  header.payload());
    } else {
        println!("[{}]: Malformed IPv6 Packet", interface_name);
    }
}

fn handle_arp_packet(interface_name: &str, ethernet: &EthernetPacket) {
    let header = ArpPacket::new(ethernet.payload());
    if let Some(header) = header {
        println!("[{}]: ARP packet: {}({}) > {}({}); operation: {:?}",
                 interface_name,
                 ethernet.get_source(),
                 header.get_sender_proto_addr(),
                 ethernet.get_destination(),
                 header.get_target_proto_addr(),
                 header.get_operation());
    } else {
        println!("[{}]: Malformed ARP Packet", interface_name);
    }
}

fn handle_packet(interface_name: &str, ethernet: &EthernetPacket) {
    match ethernet.get_ethertype() {
        EtherTypes::Ipv4 => handle_ipv4_packet(interface_name, ethernet),
        EtherTypes::Ipv6 => handle_ipv6_packet(interface_name, ethernet),
        EtherTypes::Arp => handle_arp_packet(interface_name, ethernet),
        _ => {
            println!("[{}]: Unknown packet: {} > {}; ethertype: {:?} length: {}",
                     interface_name,
                     ethernet.get_source(),
                     ethernet.get_destination(),
                     ethernet.get_ethertype(),
                     ethernet.packet().len())
        }
    }
}

fn main() {
    use pnet::datalink::Channel::Ethernet;

    let iface_name = match env::args().nth(1) {
        Some(n) => n,
        None => {
            writeln!(io::stderr(), "USAGE: packetdump <NETWORK INTERFACE>").unwrap();
            process::exit(1);
        },
    };
    let interface_names_match = |iface: &NetworkInterface| iface.name == iface_name;

    // Find the network interface with the provided name
    let interfaces = datalink::interfaces();
    let interface = interfaces.into_iter().filter(interface_names_match).next().unwrap();

    // Create a channel to receive on
    let (_, mut rx) = match datalink::channel(&interface, Default::default()) {
        Ok(Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("packetdump: unhandled channel type: {}"),
        Err(e) => panic!("packetdump: unable to create channel: {}", e),
    };

    let mut iter = rx.iter();
    loop {
        match iter.next() {
            Ok(packet) => handle_packet(&interface.name[..], &packet),
            Err(e) => panic!("packetdump: unable to receive packet: {}", e),
        }
    }
}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::cell::{Cell, RefCell};
use std::rc::Rc;

use std::collections::BTreeMap;

use application::Tree;
use backend::Backend;
use dces::{Entity, EntityComponentManager, System};
use event::{
    check_mouse_condition, ClickEvent, EventBox, EventHandler, EventStrategy, MouseDownEvent,
    MouseUpEvent,
};
use structs::{Enabled, Focused, Pressed, Selected};
use widget::WidgetContainer;
use Global;

pub struct EventSystem {
    pub backend: Rc<RefCell<Backend>>,
    pub handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<EventHandler>>>>>,
    pub update: Rc<Cell<bool>>,
}

/// The `EventSystem` pops events from the event queue and delegates the events to the corresponding event handlers of the widgets.
impl EventSystem {
    fn process_top_down_event(
        &self,
        _event: &EventBox,
        _tree: &Tree,
        _ecm: &mut EntityComponentManager,
        _new_events: &mut Vec<EventBox>,
    ) {
    }

    fn process_bottom_up_event(
        &self,
        event: &EventBox,
        tree: &Tree,
        ecm: &mut EntityComponentManager,
        new_events: &mut Vec<EventBox>,
    ) {
        let mut matching_nodes = vec![];

        for node in tree.into_iter() {
            // MouseDownEvent handling
            if let Ok(event) = event.downcast_ref::<MouseDownEvent>() {
                if check_mouse_condition(event.position, &WidgetContainer::new(node, ecm, tree)) {
                    matching_nodes.push(node);
                }

                continue;
            }

            // MouseUpEvent handling
            if event.event_type() == TypeId::of::<MouseUpEvent>() {
                if let Ok(pressed) =
                    WidgetContainer::new(node, ecm, tree).borrow_property::<Pressed>()
                {
                    if pressed.0 {
                        matching_nodes.push(node);
                        break;
                    }
                }
            }

            // Click handling
            if let Ok(event) = event.downcast_ref::<ClickEvent>() {
                if check_mouse_condition(event.position, &WidgetContainer::new(node, ecm, tree)) {
                    matching_nodes.push(node);
                }

                continue;
            }

            matching_nodes.push(node);
        }

        let mut handled = false;
        let mut new_focused_widget = None;
        let mut disabled_parent = None;
        // let mut new_mouse_over_entity = None;

        for node in matching_nodes.iter().rev() {
            if let Some(dp) = disabled_parent {
                if tree.parent[&node] == dp {
                    disabled_parent = Some(*node);
                    continue;
                } else {
                    disabled_parent = None;
                }
            }

            if let Ok(enabled) = ecm.borrow_component::<Enabled>(*node) {
                if !enabled.0 {
                    disabled_parent = Some(*node);
                    continue;
                }
            }
            let mut widget = WidgetContainer::new(*node, ecm, tree);

            if let Some(handlers) = self.handlers.borrow().get(node) {
                for handler in handlers {
                    handled = handler.handle_event(event, &mut widget);

                    if handled {
                        break;
                    }
                }
            }

            // MouseDownEvent handling
            if event.event_type() == TypeId::of::<MouseDownEvent>() {
                if let Ok(focused) = widget.borrow_mut_property::<Focused>() {
                    focused.0 = true;
                    new_focused_widget = Some(*node);
                    self.update.set(true);
                    break;
                }

                if let Ok(pressed) = widget.borrow_mut_property::<Pressed>() {
                    pressed.0 = true;
                    self.update.set(true);
                    break;
                }
            }

            // MouseUpEvent handling
            if let Ok(event) = event.downcast_ref::<MouseUpEvent>() {
                let mut pressed = false;

                if let Ok(selected) = widget.borrow_mut_property::<Selected>() {
                    selected.0 = !selected.0;
                    self.update.set(true);
                }

                if let Ok(pres) = widget.borrow_mut_property::<Pressed>() {
                    pressed = pres.0;
                    pres.0 = false;
                    self.update.set(true);
                }

                if pressed {
                    if check_mouse_condition(event.position, &widget) {
                        new_events.push(EventBox::new(
                            ClickEvent {
                                position: event.position,
                            },
                            EventStrategy::BottomUp,
                        ))
                    }

                    break;
                }
            }

            if handled {
                self.update.set(true);
                break;
            }
        }

        // remove focus from previes focues entity
        let mut old_focused_widget = None;

        if let Ok(global) = ecm.borrow_mut_component::<Global>(tree.root) {
            if let Some(new_focused_widget) = new_focused_widget {
                if let Some(focused_widget) = global.focused_widget {
                    if focused_widget != new_focused_widget {
                        old_focused_widget = Some(focused_widget);
                    }
                }
                global.focused_widget = Some(new_focused_widget);
            }
        }

        if let Some(old_focused_widget) = old_focused_widget {
            if let Ok(focused) = ecm.borrow_mut_component::<Focused>(old_focused_widget) {
                focused.0 = false;
                self.update.set(true);
            }
        }
    }
}

impl System<Tree> for EventSystem {
    fn run(&self, tree: &Tree, ecm: &mut EntityComponentManager) {
        let mut backend = self.backend.borrow_mut();
        let event_context = backend.event_context();

        let mut new_events = vec![];

        for event in event_context.event_queue.borrow_mut().into_iter() {
            match event.strategy {
                EventStrategy::TopDown => {
                    self.process_top_down_event(&event, tree, ecm, &mut new_events);
                }
                EventStrategy::BottomUp => {
                    self.process_bottom_up_event(&event, tree, ecm, &mut new_events);
                }
                _ => {}
            }
        }

        event_context
            .event_queue
            .borrow_mut()
            .append(&mut new_events);
    }
}
<commit_msg>ToggleButton selection fix.<commit_after>use std::any::TypeId;
use std::cell::{Cell, RefCell};
use std::rc::Rc;

use std::collections::BTreeMap;

use application::Tree;
use backend::Backend;
use dces::{Entity, EntityComponentManager, System};
use event::{
    check_mouse_condition, ClickEvent, EventBox, EventHandler, EventStrategy, MouseDownEvent,
    MouseUpEvent,
};
use structs::{Enabled, Focused, Pressed, Selected};
use widget::WidgetContainer;
use Global;

pub struct EventSystem {
    pub backend: Rc<RefCell<Backend>>,
    pub handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<EventHandler>>>>>,
    pub update: Rc<Cell<bool>>,
}

/// The `EventSystem` pops events from the event queue and delegates the events to the corresponding event handlers of the widgets.
impl EventSystem {
    fn process_top_down_event(
        &self,
        _event: &EventBox,
        _tree: &Tree,
        _ecm: &mut EntityComponentManager,
        _new_events: &mut Vec<EventBox>,
    ) {
    }

    fn process_bottom_up_event(
        &self,
        event: &EventBox,
        tree: &Tree,
        ecm: &mut EntityComponentManager,
        new_events: &mut Vec<EventBox>,
    ) {
        let mut matching_nodes = vec![];

        for node in tree.into_iter() {
            // MouseDownEvent handling
            if let Ok(event) = event.downcast_ref::<MouseDownEvent>() {
                if check_mouse_condition(event.position, &WidgetContainer::new(node, ecm, tree)) {
                    matching_nodes.push(node);
                }

                continue;
            }

            // MouseUpEvent handling
            if event.event_type() == TypeId::of::<MouseUpEvent>() {
                if let Ok(pressed) =
                    WidgetContainer::new(node, ecm, tree).borrow_property::<Pressed>()
                {
                    if pressed.0 {
                        matching_nodes.push(node);
                        break;
                    }
                }
            }

            // Click handling
            if let Ok(event) = event.downcast_ref::<ClickEvent>() {
                if check_mouse_condition(event.position, &WidgetContainer::new(node, ecm, tree)) {
                    matching_nodes.push(node);
                }

                continue;
            }

            matching_nodes.push(node);
        }

        let mut handled = false;
        let mut new_focused_widget = None;
        let mut disabled_parent = None;
        // let mut new_mouse_over_entity = None;

        for node in matching_nodes.iter().rev() {
            if let Some(dp) = disabled_parent {
                if tree.parent[&node] == dp {
                    disabled_parent = Some(*node);
                    continue;
                } else {
                    disabled_parent = None;
                }
            }

            if let Ok(enabled) = ecm.borrow_component::<Enabled>(*node) {
                if !enabled.0 {
                    disabled_parent = Some(*node);
                    continue;
                }
            }
            let mut widget = WidgetContainer::new(*node, ecm, tree);

            if let Some(handlers) = self.handlers.borrow().get(node) {
                for handler in handlers {
                    handled = handler.handle_event(event, &mut widget);

                    if handled {
                        break;
                    }
                }
            }

            // MouseDownEvent handling
            if event.event_type() == TypeId::of::<MouseDownEvent>() {
                if let Ok(focused) = widget.borrow_mut_property::<Focused>() {
                    focused.0 = true;
                    new_focused_widget = Some(*node);
                    self.update.set(true);
                    break;
                }

                if let Ok(pressed) = widget.borrow_mut_property::<Pressed>() {
                    pressed.0 = true;
                    self.update.set(true);
                    break;
                }
            }

            // MouseUpEvent handling
            if let Ok(event) = event.downcast_ref::<MouseUpEvent>() {
                let mut pressed = false;
                let mut in_mouse_pos = false;

                if check_mouse_condition(event.position, &widget) {
                    in_mouse_pos = true;
                }

                if in_mouse_pos {
                    if let Ok(selected) = widget.borrow_mut_property::<Selected>() {
                        selected.0 = !selected.0;
                        self.update.set(true);
                    }
                }

                if let Ok(pres) = widget.borrow_mut_property::<Pressed>() {
                    pressed = pres.0;
                    pres.0 = false;
                    self.update.set(true);
                }

                if pressed {
                    if in_mouse_pos {
                        new_events.push(EventBox::new(
                            ClickEvent {
                                position: event.position,
                            },
                            EventStrategy::BottomUp,
                        ))
                    }

                    break;
                }
            }

            if handled {
                self.update.set(true);
                break;
            }
        }

        // remove focus from previes focues entity
        let mut old_focused_widget = None;

        if let Ok(global) = ecm.borrow_mut_component::<Global>(tree.root) {
            if let Some(new_focused_widget) = new_focused_widget {
                if let Some(focused_widget) = global.focused_widget {
                    if focused_widget != new_focused_widget {
                        old_focused_widget = Some(focused_widget);
                    }
                }
                global.focused_widget = Some(new_focused_widget);
            }
        }

        if let Some(old_focused_widget) = old_focused_widget {
            if let Ok(focused) = ecm.borrow_mut_component::<Focused>(old_focused_widget) {
                focused.0 = false;
                self.update.set(true);
            }
        }
    }
}

impl System<Tree> for EventSystem {
    fn run(&self, tree: &Tree, ecm: &mut EntityComponentManager) {
        let mut backend = self.backend.borrow_mut();
        let event_context = backend.event_context();

        let mut new_events = vec![];

        for event in event_context.event_queue.borrow_mut().into_iter() {
            match event.strategy {
                EventStrategy::TopDown => {
                    self.process_top_down_event(&event, tree, ecm, &mut new_events);
                }
                EventStrategy::BottomUp => {
                    self.process_bottom_up_event(&event, tree, ecm, &mut new_events);
                }
                _ => {}
            }
        }

        event_context
            .event_queue
            .borrow_mut()
            .append(&mut new_events);
    }
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 4]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn sub_triangles(v: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let (a, b, c, d) = (v[0], v[1], v[2], v[3]); // Vector destructuring is not yet stable.
    let (sax, say, sbx, sby, scx, scy) = (
            a[0] + ((b[0] - a[0]) / 2.0),
            a[1],
            b[0] - ((b[0] - c[0]) / 2.0),
            b[1] - ((b[1] - c[1]) / 2.0),
            a[0] + ((c[0] - a[0]) / 2.0),
            a[1] - ((a[1] - c[1]) / 2.0));

    vec![
        [[sax, say],
         [sbx, sby],
         [scx, scy],
         [sax, say]],
        [[a[0], a[1]],
         [sax, say],
         [scx, scy],
         [a[0], a[1]]],
        [[sax, say],
         [b[0], b[1]],
         [sbx, sby],
         [sax, say]],
        [[scx, scy],
         [sbx, sby],
         [c[0], c[1]],
         [scx, scy]]]
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d @ _ => {
            let sub_tris = sub_triangles(vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;

    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0],
                                   [500.0, 50.0], [50.0, 750.0]]);

    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events().max_fps(1) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<commit_msg>Remove useless vertice<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 3]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn sub_triangles(v: [[f64; 2]; 3]) -> Vec<[[f64; 2]; 3]> {
    let (a, b, c) = (v[0], v[1], v[2]); // Vector destructuring is not yet stable in Rust 1.3.0.
    let (sax, say, sbx, sby, scx, scy) = (
            a[0] + ((b[0] - a[0]) / 2.0),
            a[1],
            b[0] - ((b[0] - c[0]) / 2.0),
            b[1] - ((b[1] - c[1]) / 2.0),
            a[0] + ((c[0] - a[0]) / 2.0),
            a[1] - ((a[1] - c[1]) / 2.0));

    vec![[[sax, say], [sbx, sby], [scx, scy]],
         [[a[0], a[1]], [sax, say], [scx, scy]],
         [[sax, say], [b[0], b[1]], [sbx, sby]],
         [[scx, scy], [sbx, sby], [c[0], c[1]]]]
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 3]) -> Vec<[[f64; 2]; 3]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d @ _ => {
            let sub_tris = sub_triangles(vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;
    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0], [500.0, 50.0]]);
    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events().max_fps(1) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<|endoftext|>


<commit_before>import core::*;

use std;
import opt = std::getopts;
import result::{err, ok};

tag fail_type {
    argument_missing;
    unrecognized_option;
    option_missing;
    option_duplicated;
    unexpected_argument;
}

fn check_fail_type(f: opt::fail_, ft: fail_type) {
    alt f {
      opt::argument_missing(_) { assert (ft == argument_missing); }
      opt::unrecognized_option(_) { assert (ft == unrecognized_option); }
      opt::option_missing(_) { assert (ft == option_missing); }
      opt::option_duplicated(_) { assert (ft == option_duplicated); }
      opt::unexpected_argument(_) { assert (ft == unexpected_argument); }
      _ { fail; }
    }
}

// Tests for reqopt
#[test]
fn test_reqopt_long() {
    let args = ["--test=20"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_missing() {
    let args = ["blah"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short() {
    let args = ["-t", "20"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_missing() {
    let args = ["blah"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optopt
#[test]
fn test_optopt_long() {
    let args = ["--test=20"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_missing() {
    let args = ["blah"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short() {
    let args = ["-t", "20"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_missing() {
    let args = ["blah"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optflag
#[test]
fn test_optflag_long() {
    let args = ["--test"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_missing() {
    let args = ["blah"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_arg() {
    let args = ["--test=20"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) {
        log_err opt::fail_str(f);
        check_fail_type(f, unexpected_argument);
      }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_multi() {
    let args = ["--test", "--test"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short() {
    let args = ["-t"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_missing() {
    let args = ["blah"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_arg() {
    let args = ["-t", "20"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        // The next variable after the flag is just a free argument

        assert (m.free[0] == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_multi() {
    let args = ["-t", "-t"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optmulti
#[test]
fn test_optmulti_long() {
    let args = ["--test=20"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_missing() {
    let args = ["blah"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
        assert (opt::opt_strs(m, "test")[0] == "20");
        assert (opt::opt_strs(m, "test")[1] == "30");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short() {
    let args = ["-t", "20"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_missing() {
    let args = ["blah"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
        assert (opt::opt_strs(m, "t")[0] == "20");
        assert (opt::opt_strs(m, "t")[1] == "30");
      }
      _ { fail; }
    }
}

#[test]
fn test_unrecognized_option_long() {
    let args = ["--untest"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, unrecognized_option); }
      _ { fail; }
    }
}

#[test]
fn test_unrecognized_option_short() {
    let args = ["-t"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, unrecognized_option); }
      _ { fail; }
    }
}

#[test]
fn test_combined() {
    let args =
        ["prog", "free1", "-s", "20", "free2", "--flag", "--long=30", "-f",
         "-m", "40", "-m", "50"];
    let opts =
        [opt::optopt("s"), opt::optflag("flag"), opt::reqopt("long"),
         opt::optflag("f"), opt::optmulti("m"), opt::optopt("notpresent")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (m.free[0] == "prog");
        assert (m.free[1] == "free1");
        assert (opt::opt_str(m, "s") == "20");
        assert (m.free[2] == "free2");
        assert (opt::opt_present(m, "flag"));
        assert (opt::opt_str(m, "long") == "30");
        assert (opt::opt_present(m, "f"));
        assert (opt::opt_strs(m, "m")[0] == "40");
        assert (opt::opt_strs(m, "m")[1] == "50");
        assert (!opt::opt_present(m, "notpresent"));
      }
      _ { fail; }
    }
}

<commit_msg>getopts: add test for strings with spaces.<commit_after>import core::*;

use std;
import opt = std::getopts;
import result::{err, ok};

tag fail_type {
    argument_missing;
    unrecognized_option;
    option_missing;
    option_duplicated;
    unexpected_argument;
}

fn check_fail_type(f: opt::fail_, ft: fail_type) {
    alt f {
      opt::argument_missing(_) { assert (ft == argument_missing); }
      opt::unrecognized_option(_) { assert (ft == unrecognized_option); }
      opt::option_missing(_) { assert (ft == option_missing); }
      opt::option_duplicated(_) { assert (ft == option_duplicated); }
      opt::unexpected_argument(_) { assert (ft == unexpected_argument); }
      _ { fail; }
    }
}

// Tests for reqopt
#[test]
fn test_reqopt_long() {
    let args = ["--test=20"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_missing() {
    let args = ["blah"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::reqopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short() {
    let args = ["-t", "20"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_missing() {
    let args = ["blah"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_reqopt_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::reqopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optopt
#[test]
fn test_optopt_long() {
    let args = ["--test=20"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_missing() {
    let args = ["blah"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::optopt("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short() {
    let args = ["-t", "20"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_missing() {
    let args = ["blah"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optopt_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::optopt("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optflag
#[test]
fn test_optflag_long() {
    let args = ["--test"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_missing() {
    let args = ["blah"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_arg() {
    let args = ["--test=20"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) {
        log_err opt::fail_str(f);
        check_fail_type(f, unexpected_argument);
      }
      _ { fail; }
    }
}

#[test]
fn test_optflag_long_multi() {
    let args = ["--test", "--test"];
    let opts = [opt::optflag("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short() {
    let args = ["-t"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_missing() {
    let args = ["blah"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_arg() {
    let args = ["-t", "20"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        // The next variable after the flag is just a free argument

        assert (m.free[0] == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optflag_short_multi() {
    let args = ["-t", "-t"];
    let opts = [opt::optflag("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, option_duplicated); }
      _ { fail; }
    }
}

// Tests for optmulti
#[test]
fn test_optmulti_long() {
    let args = ["--test=20"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_missing() {
    let args = ["blah"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "test")); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_no_arg() {
    let args = ["--test"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_long_multi() {
    let args = ["--test=20", "--test=30"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "test"));
        assert (opt::opt_str(m, "test") == "20");
        assert (opt::opt_strs(m, "test")[0] == "20");
        assert (opt::opt_strs(m, "test")[1] == "30");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short() {
    let args = ["-t", "20"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
      }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_missing() {
    let args = ["blah"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) { assert (!opt::opt_present(m, "t")); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_no_arg() {
    let args = ["-t"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, argument_missing); }
      _ { fail; }
    }
}

#[test]
fn test_optmulti_short_multi() {
    let args = ["-t", "20", "-t", "30"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (opt::opt_present(m, "t"));
        assert (opt::opt_str(m, "t") == "20");
        assert (opt::opt_strs(m, "t")[0] == "20");
        assert (opt::opt_strs(m, "t")[1] == "30");
      }
      _ { fail; }
    }
}

#[test]
fn test_unrecognized_option_long() {
    let args = ["--untest"];
    let opts = [opt::optmulti("t")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, unrecognized_option); }
      _ { fail; }
    }
}

#[test]
fn test_unrecognized_option_short() {
    let args = ["-t"];
    let opts = [opt::optmulti("test")];
    let rs = opt::getopts(args, opts);
    alt rs {
      err(f) { check_fail_type(f, unrecognized_option); }
      _ { fail; }
    }
}

#[test]
fn test_combined() {
    let args =
        ["prog", "free1", "-s", "20", "free2", "--flag", "--long=30", "-f",
         "-m", "40", "-m", "50", "-n", "-A B", "-n", "-60 70"];
    let opts =
        [opt::optopt("s"), opt::optflag("flag"), opt::reqopt("long"),
         opt::optflag("f"), opt::optmulti("m"), opt::optmulti("n"),
         opt::optopt("notpresent")];
    let rs = opt::getopts(args, opts);
    alt rs {
      ok(m) {
        assert (m.free[0] == "prog");
        assert (m.free[1] == "free1");
        assert (opt::opt_str(m, "s") == "20");
        assert (m.free[2] == "free2");
        assert (opt::opt_present(m, "flag"));
        assert (opt::opt_str(m, "long") == "30");
        assert (opt::opt_present(m, "f"));
        assert (opt::opt_strs(m, "m")[0] == "40");
        assert (opt::opt_strs(m, "m")[1] == "50");
        assert (opt::opt_strs(m, "n")[0] == "-A B");
        assert (opt::opt_strs(m, "n")[1] == "-60 70");
        assert (!opt::opt_present(m, "notpresent"));
      }
      _ { fail; }
    }
}

<|endoftext|>


<commit_before>use diesel::prelude::*;
use diesel::sql_types::Text;

use app;

#[test]
fn all_columns_called_crate_id_have_a_cascading_foreign_key() {
    for row in get_fk_constraint_definitions("crate_id") {
        let constraint = match row.constraint {
            Some(c) => c,
            None => panic!(
                "Column called crate_id on {} has no foreign key",
                row.table_name
            ),
        };
        if !constraint.definition.contains("ON DELETE CASCADE") {
            panic!(
                "Foreign key {} on table {} should have `ON DELETE CASCADE` \
                 but it doesn't.",
                constraint.name, row.table_name
            );
        }
    }
}

#[test]
fn all_columns_called_version_id_have_a_cascading_foreign_key() {
    for row in get_fk_constraint_definitions("version_id") {
        let constraint = match row.constraint {
            Some(c) => c,
            None => panic!(
                "Column called version_id on {} has no foreign key",
                row.table_name
            ),
        };
        if !constraint.definition.contains("ON DELETE CASCADE") {
            panic!(
                "Foreign key {} on table {} should have `ON DELETE CASCADE` \
                 but it doesn't.",
                constraint.name, row.table_name
            );
        }
    }
}

#[derive(QueryableByName)]
struct FkConstraint {
    #[sql_type = "Text"]
    #[column_name = "conname"]
    name: String,
    #[sql_type = "Text"]
    definition: String,
}

#[derive(QueryableByName)]
struct TableNameAndConstraint {
    #[sql_type = "Text"]
    #[column_name = "relname"]
    table_name: String,
    #[diesel(embed)]
    constraint: Option<FkConstraint>,
}

fn get_fk_constraint_definitions(column_name: &str) -> Vec<TableNameAndConstraint> {
    use diesel::sql_query;

    let (_r, app, _) = app();
    let conn = app.diesel_database.get().unwrap();

    sql_query(include_str!("load_foreign_key_constraints.sql"))
        .bind::<Text, _>(column_name)
        .load(&*conn)
        .unwrap()
}
<commit_msg>Update schema_details test to use TestApp::init()<commit_after>use diesel::prelude::*;
use diesel::sql_types::Text;

use TestApp;

#[test]
fn all_columns_called_crate_id_have_a_cascading_foreign_key() {
    for row in get_fk_constraint_definitions("crate_id") {
        let constraint = match row.constraint {
            Some(c) => c,
            None => panic!(
                "Column called crate_id on {} has no foreign key",
                row.table_name
            ),
        };
        if !constraint.definition.contains("ON DELETE CASCADE") {
            panic!(
                "Foreign key {} on table {} should have `ON DELETE CASCADE` \
                 but it doesn't.",
                constraint.name, row.table_name
            );
        }
    }
}

#[test]
fn all_columns_called_version_id_have_a_cascading_foreign_key() {
    for row in get_fk_constraint_definitions("version_id") {
        let constraint = match row.constraint {
            Some(c) => c,
            None => panic!(
                "Column called version_id on {} has no foreign key",
                row.table_name
            ),
        };
        if !constraint.definition.contains("ON DELETE CASCADE") {
            panic!(
                "Foreign key {} on table {} should have `ON DELETE CASCADE` \
                 but it doesn't.",
                constraint.name, row.table_name
            );
        }
    }
}

#[derive(QueryableByName)]
struct FkConstraint {
    #[sql_type = "Text"]
    #[column_name = "conname"]
    name: String,
    #[sql_type = "Text"]
    definition: String,
}

#[derive(QueryableByName)]
struct TableNameAndConstraint {
    #[sql_type = "Text"]
    #[column_name = "relname"]
    table_name: String,
    #[diesel(embed)]
    constraint: Option<FkConstraint>,
}

fn get_fk_constraint_definitions(column_name: &str) -> Vec<TableNameAndConstraint> {
    use diesel::sql_query;

    let (app, _) = TestApp::init().empty();

    app.db(|conn| {
        sql_query(include_str!("load_foreign_key_constraints.sql"))
            .bind::<Text, _>(column_name)
            .load(conn)
            .unwrap()
    })
}
<|endoftext|>