<commit_before>use std::io::{Error, ErrorKind};
use std::net::SocketAddr;
use std::result::{Result as BaseResult};

use super::router::{Router};

use futures::{Future, Sink};
use futures::stream::{Stream};
use json::{parse as parse_json, JsonValue};
use tokio_core::net::{TcpListener};
use tokio_core::reactor::{Core};
use tokio_tungstenite::{accept_async};
use tungstenite::protocol::{Message};

pub struct Proxy {
    router: Box<Router>,
}

impl Proxy {
    pub fn new(router: Box<Router>) -> Proxy {
        Proxy {
            router: router
        }
    }

    pub fn run(&self, address: SocketAddr) {
        let mut core = Core::new().unwrap();
        let handle = core.handle();
        let socket = TcpListener::bind(&address, &handle).unwrap();
        println!("Listening on: {}", address);

        // The server loop.
        let server = socket.incoming().for_each(|(stream, addr)| {
            let proxy_inner = self;

            // Handler per each connection.
            accept_async(stream)
                .map_err(|err| {
                    println!("Occurred error during the WebSocket handshake: {}", err);
                    Error::new(ErrorKind::Other, err)
                })
                // Check the Auth header
                .and_then(move |ws_stream| {
                    println!("Checking the user's token");
                    Ok(ws_stream)
                })
                // Process the messages
                .and_then(move |ws_stream| {
                    // Per each message
                    ws_stream.for_each(move |message: Message| {
                        // Convert an incoming message into JSON
                        let text_message = try!(message.into_text());
                        let json_message = try!(proxy_inner.decode_message(text_message.as_str()));

                        // Convert the specified API url to a Kafka topic
                        println!("Message = {}", json_message);
                        Ok(())
                    })
                    .map_err(|err| {
                        println!("Occurred error during the processing a message: {}", err);
                        Error::new(ErrorKind::Other, err)
                    })
                })
        });

        // Run the server
        core.run(server).unwrap();
    }

    fn decode_message(&self, message: &str) -> BaseResult<JsonValue, Error> {
        match parse_json(message) {
            Ok(message) => Ok(message),
            Err(err) => Err(Error::new(ErrorKind::InvalidData, err))
        }
    }
}
<commit_msg>Implemented tranforming URLs to the Kafka topics<commit_after>use std::io::{Error, ErrorKind};
use std::net::SocketAddr;
use std::result::{Result as BaseResult};

use super::router::{Router};

use futures::{Future, Sink};
use futures::stream::{Stream};
use json::{parse as parse_json, JsonValue};
use tokio_core::net::{TcpListener};
use tokio_core::reactor::{Core};
use tokio_tungstenite::{accept_async};
use tungstenite::protocol::{Message};

pub struct Proxy {
    router: Box<Router>,
}

impl Proxy {
    pub fn new(router: Box<Router>) -> Proxy {
        Proxy {
            router: router
        }
    }

    pub fn run(&self, address: SocketAddr) {
        let mut core = Core::new().unwrap();
        let handle = core.handle();
        let socket = TcpListener::bind(&address, &handle).unwrap();
        println!("Listening on: {}", address);

        // The server loop.
        let server = socket.incoming().for_each(|(stream, _addr)| {
            let proxy_inner = self;

            // Handler per each connection.
            accept_async(stream)
                .map_err(|err| {
                    println!("Occurred error during the WebSocket handshake: {}", err);
                    Error::new(ErrorKind::Other, err)
                })
                // Check the Auth header
                .and_then(move |ws_stream| {
                    println!("Checking the user's token");
                    Ok(ws_stream)
                })
                // Process the messages
                .and_then(move |ws_stream| {
                    let (_sink, stream) = ws_stream.split();

                    // Per each message
                    stream.for_each(move |message: Message| {
                        // Convert an incoming message into JSON
                        let text_message = try!(message.into_text());
                        let parsed_json = try!(proxy_inner.decode_message(text_message.as_str()));

                        // Convert the specified API url to a Kafka topic
                        let json_message = try!(proxy_inner.validate_json(parsed_json));
                        let microservice = proxy_inner.match_microservice(json_message);
                        Ok(())
                    })
                    .map_err(|err| {
                        println!("Occurred error during the processing a message: {}", err);
                        Error::new(ErrorKind::Other, err)
                    })
                })
        });

        // Run the server
        core.run(server).unwrap();
    }

    fn decode_message(&self, message: &str) -> BaseResult<Box<JsonValue>, Error> {
        match parse_json(message) {
            Ok(message) => Ok(Box::new(message)),
            Err(err) => Err(Error::new(ErrorKind::InvalidData, err))
        }
    }

    fn validate_json(&self, json: Box<JsonValue>) -> BaseResult<Box<JsonValue>, Error> {
        if !json.has_key("url") {
            return Err(Error::new(ErrorKind::Other, "Key `url` is missing or value is `null`"));
        }

        if json.has_key("matchmaking") {
            return Err(Error::new(ErrorKind::Other, "Key `matchmaking` must be not specified"));
        }

        Ok(json)
    }

    fn match_microservice(&self, json: Box<JsonValue>) -> String {
        let url = json["url"].as_str().unwrap();

        match self.router.match_url(url) {
            Ok(endpoint) => endpoint.get_microservice(),
            _ => {
                let mut external_url = url.clone();
                external_url = external_url.trim_left_matches("/");
                external_url = external_url.trim_right_matches("/");
                external_url.replace("/", ".")
            }
        }
    }
}
<|endoftext|>


<commit_before>mod thread_guard;

use std::fmt;
use std::io;
use std::io::prelude::*;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, Receiver, TryRecvError};
use std::thread;
use std::time::{Duration, Instant};
use std::ops::Deref;

use serial::prelude::*;
use serial;
use self::thread_guard::*;
use super::Packet;

pub enum ConnectionEvent {
    Packet(Packet),
    InvalidPacket(Packet),
    ReadError(io::Error),
    WriteError(io::Error),
    Heartbeat
}

impl fmt::Display for ConnectionEvent {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ConnectionEvent::Packet(ref p) => write!(f, "{}", p),
            &ConnectionEvent::InvalidPacket(ref p) => write!(f, "Invalid! {}", p),
            &ConnectionEvent::ReadError(ref err) => write!(f, "READ ERROR! [{:?}]", err),
            &ConnectionEvent::WriteError(ref err) => write!(f, "WRITE ERROR! [{:?}]", err),
            &ConnectionEvent::Heartbeat => write!(f, "Tick Tock")
        }
    }
}

pub struct Connection {
    pub tty_path: String,
    event_receiver: Receiver<ConnectionEvent>,
    packet_sender: Sender<Packet>,
    kill_thread_signal: Arc<Mutex<bool>>,
    reader_thread_handle: Option<ThreadHandle<()>>,
}

impl Connection {
    pub fn new(tty_path: &str, heartbeat_milliseconds: Option<u64>) -> io::Result<Connection> {
        let (event_sender, event_receiver) = channel::<ConnectionEvent>();
        let (packet_sender, packet_receiver) = channel::<Packet>();

        let kill_signal = Arc::new(Mutex::new(false));

        let reader_thread = build_connection_read_thread(tty_path.to_string(), event_sender, packet_receiver, heartbeat_milliseconds, kill_signal.clone());

        Ok(Connection {
            tty_path: tty_path.to_string(),
            event_receiver: event_receiver,
            packet_sender: packet_sender,
            kill_thread_signal: kill_signal,
            reader_thread_handle: Some(reader_thread)
        })
    }

    pub fn send(&mut self, p: Packet) -> io::Result<()> {
        match self.is_ok() {
            true => {
                self.packet_sender.send(p).unwrap();
                Ok(())
            },
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped"))
        }
    }

    pub fn wait(&self) -> io::Result<ConnectionEvent> {
        match self.is_ok() {
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped")),
            true => {
                Ok(self.event_receiver.recv().unwrap())
            }
        }
    }

    pub fn get_events(&self) -> io::Result<Vec<ConnectionEvent>> {
        match self.is_ok() {
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped")),
            true => {
                let mut data: Vec<ConnectionEvent> = vec!();

                loop {
                    match self.event_receiver.try_recv() {
                        Ok(evt) => { data.push(evt) },
                        Err(TryRecvError::Empty) => { break; },
                        Err(TryRecvError::Disconnected) => { panic!("channels should not disconnect") }
                    }
                }

                Ok(data)
            }
        }
    }

    pub fn is_ok(&self) -> bool {
        let mut ret = true;

        match &self.reader_thread_handle {
            &Some(ref h) => {
                ret = ret && match h.status.lock().unwrap().deref() {
                    &ThreadStatus::Ok => true,
                    _ => false
                }
            },
            _ => {}
        }
        ret
    }
}

impl Drop for Connection {
    fn drop(&mut self) {

        {
            *self.kill_thread_signal.lock().unwrap() = true;
        }

        match self.reader_thread_handle.take() {
            Some(th) => {
                th.handle.join().unwrap();
            },
            None => {}
        }
    }
}

fn build_connection_read_thread(tty_path: String, event_sender: Sender<ConnectionEvent>, packet_receiver: Receiver<Packet>, heartbeat: Option<u64>, kill_signal: Arc<Mutex<bool>>) -> ThreadHandle<()> {
    guard_thread("reader_thread", move || {
        let mut serial = match serial::open(&tty_path) {
            Err(e) => {panic!(format!("Unable to create serial port: {}", e)) },
            Ok(s) => s
        };

        match serial.set_timeout(Duration::from_millis(500)) {
            Err(e) => { panic!(format!("Unable to set serial timeout: {}", e)) },
            Ok(_) => {}
        };

        let mut packet_buffer: Vec<u8> = Vec::new();
        let mut read_buffer: Vec<u8> = Vec::new();
        let mut last_read = Instant::now();
        let mut last_heartbeat = Instant::now();

        while !*kill_signal.lock().unwrap() {

            if packet_buffer.len() > 0 && last_read.elapsed().as_secs() > 2 {
                let evt = ConnectionEvent::ReadError(io::Error::new(io::ErrorKind::InvalidData, format!("Invalid packet data: {:?}", packet_buffer.clone())));
                event_sender.send(evt).unwrap();
                packet_buffer.clear();
            };

            match packet_receiver.try_recv() {
                Ok(p) => {
                    println!("going to write...");
                    match serial.write_all(&p.data) {
                        Ok(_) => {},
                        Err(e) => {
                            let evt = ConnectionEvent::WriteError(e);
                            event_sender.send(evt).unwrap();
                        }
                    }
                },
                Err(TryRecvError::Empty) => {  },
                Err(TryRecvError::Disconnected) => { panic!("channels should not disconnect") }
            }

            match serial.read(&mut read_buffer) {
                Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {},
                Err(e) => {
                    let evt = ConnectionEvent::ReadError(e);
                    event_sender.send(evt).unwrap();
                },
                Ok(bytes) if bytes > 0 => {
                    last_read = Instant::now();
                    for x in 0 .. bytes {
                        packet_buffer.push(read_buffer[x]);
                    }
                },
                Ok(_) => {} // do nothing for 0 bytes read
            };

            while packet_buffer.len() >= 128 {
                let data: Vec<u8> = packet_buffer.drain(0..128).collect();
                let p = Packet::from_bytes(&data);

                if p.is_checksum_valid() {
                    let evt = ConnectionEvent::Packet(p);
                    event_sender.send(evt).unwrap();
                } else {
                    let evt = ConnectionEvent::InvalidPacket(p);
                    event_sender.send(evt).unwrap();
                }
            }

            match heartbeat {
                Some(ms) => {
                    if last_heartbeat.elapsed() >= Duration::from_millis(ms) {
                        let evt = ConnectionEvent::Heartbeat;
                        event_sender.send(evt).unwrap();
                        last_heartbeat = Instant::now();
                    }
                },
                None => {}
            }

            thread::sleep(Duration::from_millis(250));
        }
        ()
    })
}
<commit_msg>debug<commit_after>mod thread_guard;

use std::fmt;
use std::io;
use std::io::prelude::*;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, Receiver, TryRecvError};
use std::thread;
use std::time::{Duration, Instant};
use std::ops::Deref;

use serial::prelude::*;
use serial;
use self::thread_guard::*;
use super::Packet;

pub enum ConnectionEvent {
    Packet(Packet),
    InvalidPacket(Packet),
    ReadError(io::Error),
    WriteError(io::Error),
    Heartbeat
}

impl fmt::Display for ConnectionEvent {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ConnectionEvent::Packet(ref p) => write!(f, "{}", p),
            &ConnectionEvent::InvalidPacket(ref p) => write!(f, "Invalid! {}", p),
            &ConnectionEvent::ReadError(ref err) => write!(f, "READ ERROR! [{:?}]", err),
            &ConnectionEvent::WriteError(ref err) => write!(f, "WRITE ERROR! [{:?}]", err),
            &ConnectionEvent::Heartbeat => write!(f, "Tick Tock")
        }
    }
}

pub struct Connection {
    pub tty_path: String,
    event_receiver: Receiver<ConnectionEvent>,
    packet_sender: Sender<Packet>,
    kill_thread_signal: Arc<Mutex<bool>>,
    reader_thread_handle: Option<ThreadHandle<()>>,
}

impl Connection {
    pub fn new(tty_path: &str, heartbeat_milliseconds: Option<u64>) -> io::Result<Connection> {
        let (event_sender, event_receiver) = channel::<ConnectionEvent>();
        let (packet_sender, packet_receiver) = channel::<Packet>();

        let kill_signal = Arc::new(Mutex::new(false));

        let reader_thread = build_connection_read_thread(tty_path.to_string(), event_sender, packet_receiver, heartbeat_milliseconds, kill_signal.clone());

        Ok(Connection {
            tty_path: tty_path.to_string(),
            event_receiver: event_receiver,
            packet_sender: packet_sender,
            kill_thread_signal: kill_signal,
            reader_thread_handle: Some(reader_thread)
        })
    }

    pub fn send(&mut self, p: Packet) -> io::Result<()> {
        match self.is_ok() {
            true => {
                self.packet_sender.send(p).unwrap();
                Ok(())
            },
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped"))
        }
    }

    pub fn wait(&self) -> io::Result<ConnectionEvent> {
        match self.is_ok() {
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped")),
            true => {
                Ok(self.event_receiver.recv().unwrap())
            }
        }
    }

    pub fn get_events(&self) -> io::Result<Vec<ConnectionEvent>> {
        match self.is_ok() {
            false => Err(io::Error::new(io::ErrorKind::ConnectionAborted, "worker threads have stopped")),
            true => {
                let mut data: Vec<ConnectionEvent> = vec!();

                loop {
                    match self.event_receiver.try_recv() {
                        Ok(evt) => { data.push(evt) },
                        Err(TryRecvError::Empty) => { break; },
                        Err(TryRecvError::Disconnected) => { panic!("channels should not disconnect") }
                    }
                }

                Ok(data)
            }
        }
    }

    pub fn is_ok(&self) -> bool {
        let mut ret = true;

        match &self.reader_thread_handle {
            &Some(ref h) => {
                ret = ret && match h.status.lock().unwrap().deref() {
                    &ThreadStatus::Ok => true,
                    _ => false
                }
            },
            _ => {}
        }
        ret
    }
}

impl Drop for Connection {
    fn drop(&mut self) {

        {
            *self.kill_thread_signal.lock().unwrap() = true;
        }

        match self.reader_thread_handle.take() {
            Some(th) => {
                th.handle.join().unwrap();
            },
            None => {}
        }
    }
}

fn build_connection_read_thread(tty_path: String, event_sender: Sender<ConnectionEvent>, packet_receiver: Receiver<Packet>, heartbeat: Option<u64>, kill_signal: Arc<Mutex<bool>>) -> ThreadHandle<()> {
    guard_thread("reader_thread", move || {
        let mut serial = match serial::open(&tty_path) {
            Err(e) => {panic!(format!("Unable to create serial port: {}", e)) },
            Ok(s) => s
        };

        match serial.set_timeout(Duration::from_millis(500)) {
            Err(e) => { panic!(format!("Unable to set serial timeout: {}", e)) },
            Ok(_) => {}
        };

        let mut packet_buffer: Vec<u8> = Vec::new();
        let mut read_buffer: Vec<u8> = Vec::new();
        let mut last_read = Instant::now();
        let mut last_heartbeat = Instant::now();

        while !*kill_signal.lock().unwrap() {

            if packet_buffer.len() > 0 && last_read.elapsed().as_secs() > 2 {
                let evt = ConnectionEvent::ReadError(io::Error::new(io::ErrorKind::InvalidData, format!("Invalid packet data: {:?}", packet_buffer.clone())));
                event_sender.send(evt).unwrap();
                packet_buffer.clear();
            };

            match packet_receiver.try_recv() {
                Ok(p) => {
                    println!("going to write...");
                    match serial.write_all(&p.data) {
                        Ok(_) => {},
                        Err(e) => {
                            let evt = ConnectionEvent::WriteError(e);
                            event_sender.send(evt).unwrap();
                        }
                    }
                },
                Err(TryRecvError::Empty) => {  },
                Err(TryRecvError::Disconnected) => { panic!("channels should not disconnect") }
            }

            match serial.read(&mut read_buffer) {
                Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {},
                Err(e) => {
                    let evt = ConnectionEvent::ReadError(e);
                    event_sender.send(evt).unwrap();
                },
                Ok(bytes) if bytes > 0 => {
                    println!("bytes: {}", bytes);
                    last_read = Instant::now();
                    for x in 0 .. bytes {
                        packet_buffer.push(read_buffer[x]);
                    }
                },
                Ok(bytes) => { println!("bytes: {}", bytes); } // do nothing for 0 bytes read
            };

            while packet_buffer.len() >= 128 {
                let data: Vec<u8> = packet_buffer.drain(0..128).collect();
                let p = Packet::from_bytes(&data);

                if p.is_checksum_valid() {
                    let evt = ConnectionEvent::Packet(p);
                    event_sender.send(evt).unwrap();
                } else {
                    let evt = ConnectionEvent::InvalidPacket(p);
                    event_sender.send(evt).unwrap();
                }
            }

            match heartbeat {
                Some(ms) => {
                    if last_heartbeat.elapsed() >= Duration::from_millis(ms) {
                        let evt = ConnectionEvent::Heartbeat;
                        event_sender.send(evt).unwrap();
                        last_heartbeat = Instant::now();
                    }
                },
                None => {}
            }

            thread::sleep(Duration::from_millis(250));
        }
        ()
    })
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate getopts;
extern crate rocket;
extern crate serde_json;
#[macro_use] extern crate rocket_contrib;

extern crate pombase;

#[cfg(test)] mod tests;

use std::sync::Mutex;
use std::process;
use std::env;

use getopts::Options;

use rocket_contrib::{JSON, Value};

use pombase::api::query::Query;
use pombase::api::result::Result;
use pombase::api::query_exec::QueryExec;
use pombase::api::server_data::ServerData;

#[post("/query", data="<q>", format = "application/json")]
fn query_post(q: JSON<Query>, state: rocket::State<Mutex<QueryExec>>) -> Option<JSON<Result>> {
    let query_exec = state.lock().expect("failed to lock");
    Some(JSON(query_exec.exec(&q.into_inner())))
}

#[get ("/reload")]
fn reload(state: rocket::State<Mutex<QueryExec>>) {
    let mut query_exec = state.lock().expect("failed to lock");
    print!("reloading ...\n");
    query_exec.reload();
}

#[error(404)]
fn not_found() -> JSON<Value> {
    JSON(json!({
        "status": "error",
        "reason": "Resource was not found."
    }))
}

const PKG_NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    print!("{} v{}\n", PKG_NAME, VERSION);

    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optflag("h", "help", "print this help message");
    opts.optopt("m", "search-maps", "Search data", "MAPS_JSON_FILE");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let program = args[0].clone();

    if matches.opt_present("help") {
        print_usage(&program, opts);
        process::exit(0);
    }

    if !matches.opt_present("search-maps") {
        print!("no --search-maps|-m option\n");
        print_usage(&program, opts);
        process::exit(1);
    }

    let search_maps_filename = matches.opt_str("m").unwrap();
    println!("Reading maps ...");

    let server_data = ServerData::new(&search_maps_filename);
    let query_exec = QueryExec::new(server_data);

    println!("Starting server ...");
    rocket::ignite()
        .mount("/", routes![query_post, reload])
        .catch(errors![not_found])
        .manage(Mutex::new(query_exec))
        .launch();
}
<commit_msg>Fix failing tests<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate getopts;
extern crate rocket;
extern crate serde_json;
#[macro_use] extern crate rocket_contrib;

extern crate pombase;

use std::sync::Mutex;
use std::process;
use std::env;

use getopts::Options;

use rocket_contrib::{JSON, Value};

use pombase::api::query::Query;
use pombase::api::result::Result;
use pombase::api::query_exec::QueryExec;
use pombase::api::server_data::ServerData;

#[post("/query", data="<q>", format = "application/json")]
fn query_post(q: JSON<Query>, state: rocket::State<Mutex<QueryExec>>) -> Option<JSON<Result>> {
    let query_exec = state.lock().expect("failed to lock");
    Some(JSON(query_exec.exec(&q.into_inner())))
}

#[get ("/reload")]
fn reload(state: rocket::State<Mutex<QueryExec>>) {
    let mut query_exec = state.lock().expect("failed to lock");
    print!("reloading ...\n");
    query_exec.reload();
}

#[error(404)]
fn not_found() -> JSON<Value> {
    JSON(json!({
        "status": "error",
        "reason": "Resource was not found."
    }))
}

const PKG_NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    print!("{} v{}\n", PKG_NAME, VERSION);

    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optflag("h", "help", "print this help message");
    opts.optopt("m", "search-maps", "Search data", "MAPS_JSON_FILE");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let program = args[0].clone();

    if matches.opt_present("help") {
        print_usage(&program, opts);
        process::exit(0);
    }

    if !matches.opt_present("search-maps") {
        print!("no --search-maps|-m option\n");
        print_usage(&program, opts);
        process::exit(1);
    }

    let search_maps_filename = matches.opt_str("m").unwrap();
    println!("Reading maps ...");

    let server_data = ServerData::new(&search_maps_filename);
    let query_exec = QueryExec::new(server_data);

    println!("Starting server ...");
    rocket::ignite()
        .mount("/", routes![query_post, reload])
        .catch(errors![not_found])
        .manage(Mutex::new(query_exec))
        .launch();
}
<|endoftext|>


<commit_before>//! Implements a command for showing infos from Sentry.
use std::fs;
use std::io::{BufRead, BufReader};
use std::env;
use std::cmp::min;
use std::path::Path;
use std::collections::HashMap;

use clap::{App, Arg, ArgMatches};
use uuid::{Uuid, UuidVersion};
use regex::Regex;

use prelude::*;
use config::Config;
use event::{Event, Exception, SingleException, Frame, Stacktrace};
use api::Api;

const BASH_SCRIPT: &'static str = include_str!("../bashsupport.sh");
lazy_static! {
    static ref FRAME_RE: Regex = Regex::new(
        r#"^(.*?):(.*):(\d+)$"#).unwrap();
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("Prints out a bash script that does error handling.")
        .arg(Arg::with_name("no_exit")
             .long("no-exit")
             .help("Do not turn on -e (exit immediately) flag automatically"))
        .arg(Arg::with_name("send_event")
            .long("send-event")
            .requires_all(&["traceback", "log"])
            .hidden(true))
        .arg(Arg::with_name("traceback")
            .long("traceback")
            .value_name("PATH")
            .hidden(true))
        .arg(Arg::with_name("log")
            .long("log")
            .value_name("PATH")
            .hidden(true))
}

fn send_event(config: &Config, traceback: &str, logfile: &str) -> Result<()> {
    let mut event = Event::new_prefilled()?;
    event.detect_release();

    let mut cmd = "unknown".to_string();
    let mut exit_code = 1;
    let mut frames = vec![];

    if let Ok(f) = fs::File::open(traceback) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line?;

            // meta info
            if line.starts_with("@") {
                if line.starts_with("@command:") {
                    cmd = line[9..].to_string();
                } else if line.starts_with("@exit_code:") {
                    exit_code = line[11..].parse().unwrap_or(exit_code);
                } else {
                    continue;
                }
            }

            if let Some(cap) = FRAME_RE.captures(&line) {
                match &cap[1] {
                    "_sentry_err_trap" |
                    "_sentry_exit_trap" |
                    "_sentry_traceback" => continue,
                    _ => {}
                }
                frames.push(Frame {
                    filename: cap[2].to_string(),
                    abs_path: Path::new(&cap[2])
                        .canonicalize().map(|x| x.display().to_string()).ok(),
                    function: cap[1].to_string(),
                    lineno: cap[3].parse().ok(),
                    ..Default::default()
                });
            }
        }
    }

    let mut source_caches = HashMap::new();
    for frame in frames.iter_mut() {
        let lineno = match frame.lineno {
            Some(lineno) => lineno as usize,
            None => continue,
        };
        if !source_caches.contains_key(&frame.filename) {
            if let Ok(f) = fs::File::open(&frame.filename) {
                let lines: Vec<_> = BufReader::new(f)
                    .lines()
                    .map(|x| x.unwrap_or_else(|_| "".to_string()))
                    .collect();
                source_caches.insert(frame.filename.clone(), lines);
            } else {
                source_caches.insert(frame.filename.clone(), vec![]);
            }
        }
        let source = source_caches.get(&frame.filename).unwrap();
        frame.context_line = source.get(
            lineno.saturating_sub(1)).map(|x| x.clone());
        if let Some(slice) = source.get(
            lineno.saturating_sub(5)..lineno.saturating_sub(1)) {
            frame.pre_context = Some(slice.iter().map(|x| x.clone()).collect());
        };
        if let Some(slice) = source.get(
            lineno..min(lineno + 5, source.len())) {
            frame.post_context = Some(slice.iter().map(|x| x.clone()).collect());
        };
    }

    event.attach_logfile(logfile, true)?;

    frames.reverse();
    let mut exception = SingleException {
        ty: "BashError".into(),
        value: format!("command {} exited with status {}", cmd, exit_code),
        stacktrace: Some(Stacktrace {
            frames: frames,
        }),
    };
    event.exception = Some(Exception {
        values: vec![exception],
    });

    let dsn = config.get_dsn()?;

    // handle errors here locally so that we do not get the extra "use sentry-cli
    // login" to sign in which would be in appropriate here.
    if let Ok(event_id) = Api::new(config).send_event(&dsn, &event) {
        println!("{}", event_id);
    };

    Ok(())
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    if matches.is_present("send_event") {
        return send_event(config,
                          matches.value_of("traceback").unwrap(),
                          matches.value_of("log").unwrap());
    }

    let path = env::temp_dir();
    let log = path.join(&format!(
        ".sentry-{}.out", Uuid::new(UuidVersion::Random).unwrap().hyphenated().to_string()));
    let traceback = path.join(&format!(
        ".sentry-{}.traceback", Uuid::new(UuidVersion::Random).unwrap().hyphenated().to_string()));
    let mut script = BASH_SCRIPT
        .replace("___SENTRY_TRACEBACK_FILE___", &traceback.display().to_string())
        .replace("___SENTRY_LOG_FILE___", &log.display().to_string())
        .replace("___SENTRY_CLI___", &env::current_exe().unwrap().display().to_string());
    if !matches.is_present("no_exit") {
        script.insert_str(0, "set -e\n\n");
    }
    println!("{}", script);
    Ok(())
}
<commit_msg>fix: Fix a warning in bash code<commit_after>//! Implements a command for showing infos from Sentry.
use std::fs;
use std::io::{BufRead, BufReader};
use std::env;
use std::cmp::min;
use std::path::Path;
use std::collections::HashMap;

use clap::{App, Arg, ArgMatches};
use uuid::{Uuid, UuidVersion};
use regex::Regex;

use prelude::*;
use config::Config;
use event::{Event, Exception, SingleException, Frame, Stacktrace};
use api::Api;

const BASH_SCRIPT: &'static str = include_str!("../bashsupport.sh");
lazy_static! {
    static ref FRAME_RE: Regex = Regex::new(
        r#"^(.*?):(.*):(\d+)$"#).unwrap();
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("Prints out a bash script that does error handling.")
        .arg(Arg::with_name("no_exit")
             .long("no-exit")
             .help("Do not turn on -e (exit immediately) flag automatically"))
        .arg(Arg::with_name("send_event")
            .long("send-event")
            .requires_all(&["traceback", "log"])
            .hidden(true))
        .arg(Arg::with_name("traceback")
            .long("traceback")
            .value_name("PATH")
            .hidden(true))
        .arg(Arg::with_name("log")
            .long("log")
            .value_name("PATH")
            .hidden(true))
}

fn send_event(config: &Config, traceback: &str, logfile: &str) -> Result<()> {
    let mut event = Event::new_prefilled()?;
    event.detect_release();

    let mut cmd = "unknown".to_string();
    let mut exit_code = 1;
    let mut frames = vec![];

    if let Ok(f) = fs::File::open(traceback) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line?;

            // meta info
            if line.starts_with("@") {
                if line.starts_with("@command:") {
                    cmd = line[9..].to_string();
                } else if line.starts_with("@exit_code:") {
                    exit_code = line[11..].parse().unwrap_or(exit_code);
                } else {
                    continue;
                }
            }

            if let Some(cap) = FRAME_RE.captures(&line) {
                match &cap[1] {
                    "_sentry_err_trap" |
                    "_sentry_exit_trap" |
                    "_sentry_traceback" => continue,
                    _ => {}
                }
                frames.push(Frame {
                    filename: cap[2].to_string(),
                    abs_path: Path::new(&cap[2])
                        .canonicalize().map(|x| x.display().to_string()).ok(),
                    function: cap[1].to_string(),
                    lineno: cap[3].parse().ok(),
                    ..Default::default()
                });
            }
        }
    }

    let mut source_caches = HashMap::new();
    for frame in frames.iter_mut() {
        let lineno = match frame.lineno {
            Some(lineno) => lineno as usize,
            None => continue,
        };
        if !source_caches.contains_key(&frame.filename) {
            if let Ok(f) = fs::File::open(&frame.filename) {
                let lines: Vec<_> = BufReader::new(f)
                    .lines()
                    .map(|x| x.unwrap_or_else(|_| "".to_string()))
                    .collect();
                source_caches.insert(frame.filename.clone(), lines);
            } else {
                source_caches.insert(frame.filename.clone(), vec![]);
            }
        }
        let source = source_caches.get(&frame.filename).unwrap();
        frame.context_line = source.get(
            lineno.saturating_sub(1)).map(|x| x.clone());
        if let Some(slice) = source.get(
            lineno.saturating_sub(5)..lineno.saturating_sub(1)) {
            frame.pre_context = Some(slice.iter().map(|x| x.clone()).collect());
        };
        if let Some(slice) = source.get(
            lineno..min(lineno + 5, source.len())) {
            frame.post_context = Some(slice.iter().map(|x| x.clone()).collect());
        };
    }

    event.attach_logfile(logfile, true)?;

    frames.reverse();
    event.exception = Some(Exception {
        values: vec![SingleException {
            ty: "BashError".into(),
            value: format!("command {} exited with status {}", cmd, exit_code),
            stacktrace: Some(Stacktrace {
                frames: frames,
            }),
        }],
    });

    let dsn = config.get_dsn()?;

    // handle errors here locally so that we do not get the extra "use sentry-cli
    // login" to sign in which would be in appropriate here.
    if let Ok(event_id) = Api::new(config).send_event(&dsn, &event) {
        println!("{}", event_id);
    };

    Ok(())
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    if matches.is_present("send_event") {
        return send_event(config,
                          matches.value_of("traceback").unwrap(),
                          matches.value_of("log").unwrap());
    }

    let path = env::temp_dir();
    let log = path.join(&format!(
        ".sentry-{}.out", Uuid::new(UuidVersion::Random).unwrap().hyphenated().to_string()));
    let traceback = path.join(&format!(
        ".sentry-{}.traceback", Uuid::new(UuidVersion::Random).unwrap().hyphenated().to_string()));
    let mut script = BASH_SCRIPT
        .replace("___SENTRY_TRACEBACK_FILE___", &traceback.display().to_string())
        .replace("___SENTRY_LOG_FILE___", &log.display().to_string())
        .replace("___SENTRY_CLI___", &env::current_exe().unwrap().display().to_string());
    if !matches.is_present("no_exit") {
        script.insert_str(0, "set -e\n\n");
    }
    println!("{}", script);
    Ok(())
}
<|endoftext|>


<commit_before>use chrono::Local;
use std::{net::SocketAddr, time::Instant};

use crate::{
    base::{
        ctx::{ctxs, Ctx},
        middleware::MiddleWare,
        Request, Response,
    },
    logger::{current_thread_name, log_enabled_info},
    tools::url_path_decode,
};

#[derive(Debug, Default, Clone, Copy)]
pub struct Logger;

impl MiddleWare for Logger {
    fn before(&self, req: &Request, _addr: &SocketAddr, ctx: &mut Ctx) -> Result<(), Response> {
        let start = Instant::now();
        let method = req.method().clone();
        let uri = req.uri().clone();
        let path = url_path_decode(req.uri().path()).into_owned();

        ctx.insert(start);
        ctx.insert(method);
        ctx.insert(uri);
        ctx.insert(path);

        Ok(())
    }
    fn after(&self, resp: &Response, addr: &SocketAddr, ctx: &mut Ctx) {
        let start = ctx.get::<ctxs::ReqStart>().unwrap();
        let method = ctx.get::<ctxs::ReqMethod>().unwrap();
        let uri = ctx.get::<ctxs::ReqUri>().unwrap();
        let code = resp.status().as_u16();

        let uristr = uri.to_string();
        let uri = url_path_decode(&uristr);

        // info!("[{} {:?}]: {} {} {}", addr, start.elapsed(), method, uri, code);
        if log_enabled_info(module_path!()) {
            println!(
                "{} [{} {} {:?}]: {} {} {}",
                Local::now().format("%Y-%m%d %H:%M:%S"),
                current_thread_name(),
                addr,
                start.elapsed(),
                method,
                uri,
                code
            );
        }
    }
}
<commit_msg>The Logger MiddleWare should show msecs<commit_after>use chrono::Local;
use std::{net::SocketAddr, time::Instant};

use crate::{
    base::{
        ctx::{ctxs, Ctx},
        middleware::MiddleWare,
        Request, Response,
    },
    logger::{current_thread_name, log_enabled_info},
    tools::url_path_decode,
};

#[derive(Debug, Default, Clone, Copy)]
pub struct Logger;

impl MiddleWare for Logger {
    fn before(&self, req: &Request, _addr: &SocketAddr, ctx: &mut Ctx) -> Result<(), Response> {
        let start = Instant::now();
        let method = req.method().clone();
        let uri = req.uri().clone();
        let path = url_path_decode(req.uri().path()).into_owned();

        ctx.insert(start);
        ctx.insert(method);
        ctx.insert(uri);
        ctx.insert(path);

        Ok(())
    }
    fn after(&self, resp: &Response, addr: &SocketAddr, ctx: &mut Ctx) {
        let start = ctx.get::<ctxs::ReqStart>().unwrap();
        let method = ctx.get::<ctxs::ReqMethod>().unwrap();
        let uri = ctx.get::<ctxs::ReqUri>().unwrap();
        let code = resp.status().as_u16();

        let uristr = uri.to_string();
        let uri = url_path_decode(&uristr);

        // info!("[{} {:?}]: {} {} {}", addr, start.elapsed(), method, uri, code);
        if log_enabled_info(module_path!()) {
            println!(
                "{} [{} {} {:?}]: {} {} {}",
                Local::now().format("%Y-%m-%d %H:%M:%S.%3f"),
                current_thread_name(),
                addr,
                start.elapsed(),
                method,
                uri,
                code
            );
        }
    }
}
<|endoftext|>


<commit_before>use super::*;

cpp_class!(pub unsafe struct SBDebugger as "SBDebugger");

unsafe impl Send for SBDebugger {}

impl SBDebugger {
    pub fn initialize() {
        cpp!(unsafe [] {
            SBDebugger::Initialize();
        })
    }
    pub fn terminate() {
        cpp!(unsafe [] {
            SBDebugger::Terminate();
        })
    }
    pub fn create(source_init_files: bool) -> SBDebugger {
        cpp!(unsafe [source_init_files as "bool"] -> SBDebugger as "SBDebugger" {
            return SBDebugger::Create(source_init_files);
        })
    }
    pub fn clear(&self) {
        cpp!(unsafe [self as "SBDebugger*"] {
            return self->Clear();
        })
    }
    pub fn async_mode(&self) -> bool {
        cpp!(unsafe [self as "SBDebugger*"]-> bool as "bool" {
            return self->GetAsync();
        })
    }
    pub fn set_async_mode(&self, is_async: bool) {
        cpp!(unsafe [self as "SBDebugger*", is_async as "bool"] {
            self->SetAsync(is_async);
        })
    }
    pub fn create_target(
        &self, executable: &str, target_triple: Option<&str>, platform_name: Option<&str>, add_dependent_modules: bool,
    ) -> Result<SBTarget, SBError> {
        with_cstr(executable, |executable| {
            with_opt_cstr(target_triple, |target_triple| {
                with_opt_cstr(platform_name, |platform_name| {
                    let mut error = SBError::new();
                    let target = cpp!(unsafe [self as "SBDebugger*", executable as "const char*", target_triple as "const char*",
                                          platform_name as "const char*", add_dependent_modules as "bool", mut error as "SBError"
                                         ] -> SBTarget as "SBTarget" {
                        return self->CreateTarget(executable, target_triple, platform_name, add_dependent_modules, error);
                    });
                    if error.is_success() {
                        Ok(target)
                    } else {
                        Err(error)
                    }
                })
            })
        })
    }
    pub fn selected_target(&self) -> SBTarget {
        cpp!(unsafe [self as "SBDebugger*"] -> SBTarget as "SBTarget" {
            return self->GetSelectedTarget();
        })
    }
    pub fn set_selected_target(&self, target: &SBTarget) {
        cpp!(unsafe [self as "SBDebugger*", target as "SBTarget*"] {
            self->SetSelectedTarget(*target);
        })
    }
    pub fn selected_platform(&self) -> SBPlatform {
        cpp!(unsafe [self as "SBDebugger*"] -> SBPlatform as "SBPlatform" {
            return self->GetSelectedPlatform();
        })
    }
    pub fn set_selected_platform(&self, platform: &SBPlatform) {
        cpp!(unsafe [self as "SBDebugger*", platform as "SBPlatform*"] {
            self->SetSelectedPlatform(*platform);
        })
    }
    pub fn command_interpreter(&self) -> SBCommandInterpreter {
        cpp!(unsafe [self as "SBDebugger*"] -> SBCommandInterpreter as "SBCommandInterpreter" {
            return self->GetCommandInterpreter();
        })
    }
    pub fn instance_name(&self) -> &str {
        let ptr = cpp!(unsafe [self as "SBDebugger*"] ->  *const c_char as "const char*" {
            return self->GetInstanceName();
        });
        assert!(!ptr.is_null());
        unsafe { CStr::from_ptr(ptr).to_str().unwrap() }
    }
    pub fn set_variable(&mut self, var_name: &str, value: &str) -> SBError {
        SBDebugger::set_variable_for(self.instance_name(), var_name, value)
    }
    pub fn set_variable_for(debugger_instance_name: &str, var_name: &str, value: &str) -> SBError {
        with_cstr(debugger_instance_name, |debugger_instance_name| {
            with_cstr(var_name, |var_name| {
                with_cstr(value, |value| {
                    cpp!(unsafe [var_name as "const char*", value as "const char*",
                                 debugger_instance_name as "const char*"] -> SBError as "SBError" {
                        return SBDebugger::SetInternalVariable(var_name, value, debugger_instance_name);
                    })
                })
            })
        })
    }
}

impl IsValid for SBDebugger {
    fn is_valid(&self) -> bool {
        cpp!(unsafe [self as "SBDebugger*"] -> bool as "bool" {
            return self->IsValid();
        })
    }
}

impl fmt::Debug for SBDebugger {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        debug_descr(f, |descr| {
            cpp!(unsafe [self as "SBDebugger*", descr as "SBStream*"] -> bool as "bool" {
                return self->GetDescription(*descr);
            })
        })
    }
}
<commit_msg>SBDebugger::get_variable()<commit_after>use super::*;

cpp_class!(pub unsafe struct SBDebugger as "SBDebugger");

unsafe impl Send for SBDebugger {}

impl SBDebugger {
    pub fn initialize() {
        cpp!(unsafe [] {
            SBDebugger::Initialize();
        })
    }
    pub fn terminate() {
        cpp!(unsafe [] {
            SBDebugger::Terminate();
        })
    }
    pub fn create(source_init_files: bool) -> SBDebugger {
        cpp!(unsafe [source_init_files as "bool"] -> SBDebugger as "SBDebugger" {
            return SBDebugger::Create(source_init_files);
        })
    }
    pub fn clear(&self) {
        cpp!(unsafe [self as "SBDebugger*"] {
            return self->Clear();
        })
    }
    pub fn async_mode(&self) -> bool {
        cpp!(unsafe [self as "SBDebugger*"]-> bool as "bool" {
            return self->GetAsync();
        })
    }
    pub fn set_async_mode(&self, is_async: bool) {
        cpp!(unsafe [self as "SBDebugger*", is_async as "bool"] {
            self->SetAsync(is_async);
        })
    }
    pub fn create_target(
        &self,
        executable: &str,
        target_triple: Option<&str>,
        platform_name: Option<&str>,
        add_dependent_modules: bool,
    ) -> Result<SBTarget, SBError> {
        with_cstr(executable, |executable| {
            with_opt_cstr(target_triple, |target_triple| {
                with_opt_cstr(platform_name, |platform_name| {
                    let mut error = SBError::new();
                    let target = cpp!(unsafe [self as "SBDebugger*", executable as "const char*", target_triple as "const char*",
                                          platform_name as "const char*", add_dependent_modules as "bool", mut error as "SBError"
                                         ] -> SBTarget as "SBTarget" {
                        return self->CreateTarget(executable, target_triple, platform_name, add_dependent_modules, error);
                    });
                    if error.is_success() {
                        Ok(target)
                    } else {
                        Err(error)
                    }
                })
            })
        })
    }
    pub fn selected_target(&self) -> SBTarget {
        cpp!(unsafe [self as "SBDebugger*"] -> SBTarget as "SBTarget" {
            return self->GetSelectedTarget();
        })
    }
    pub fn set_selected_target(&self, target: &SBTarget) {
        cpp!(unsafe [self as "SBDebugger*", target as "SBTarget*"] {
            self->SetSelectedTarget(*target);
        })
    }
    pub fn selected_platform(&self) -> SBPlatform {
        cpp!(unsafe [self as "SBDebugger*"] -> SBPlatform as "SBPlatform" {
            return self->GetSelectedPlatform();
        })
    }
    pub fn set_selected_platform(&self, platform: &SBPlatform) {
        cpp!(unsafe [self as "SBDebugger*", platform as "SBPlatform*"] {
            self->SetSelectedPlatform(*platform);
        })
    }
    pub fn command_interpreter(&self) -> SBCommandInterpreter {
        cpp!(unsafe [self as "SBDebugger*"] -> SBCommandInterpreter as "SBCommandInterpreter" {
            return self->GetCommandInterpreter();
        })
    }
    pub fn instance_name(&self) -> &str {
        let ptr = cpp!(unsafe [self as "SBDebugger*"] ->  *const c_char as "const char*" {
            return self->GetInstanceName();
        });
        assert!(!ptr.is_null());
        unsafe { CStr::from_ptr(ptr).to_str().unwrap() }
    }
    pub fn get_variable(&mut self, var_name: &str) -> SBStringList {
        SBDebugger::get_variable_for(self.instance_name(), var_name)
    }
    pub fn set_variable(&mut self, var_name: &str, value: &str) -> SBError {
        SBDebugger::set_variable_for(self.instance_name(), var_name, value)
    }
    pub fn get_variable_for(debugger_instance_name: &str, var_name: &str) -> SBStringList {
        with_cstr(debugger_instance_name, |debugger_instance_name| {
            with_cstr(var_name, |var_name| {
                cpp!(unsafe [var_name as "const char*", debugger_instance_name as "const char*"] -> SBStringList as "SBStringList" {
                    return SBDebugger::GetInternalVariableValue(var_name, debugger_instance_name);
                })
            })
        })
    }
    pub fn set_variable_for(debugger_instance_name: &str, var_name: &str, value: &str) -> SBError {
        with_cstr(debugger_instance_name, |debugger_instance_name| {
            with_cstr(var_name, |var_name| {
                with_cstr(value, |value| {
                    cpp!(unsafe [var_name as "const char*", value as "const char*",
                                 debugger_instance_name as "const char*"] -> SBError as "SBError" {
                        return SBDebugger::SetInternalVariable(var_name, value, debugger_instance_name);
                    })
                })
            })
        })
    }
}

impl IsValid for SBDebugger {
    fn is_valid(&self) -> bool {
        cpp!(unsafe [self as "SBDebugger*"] -> bool as "bool" {
            return self->IsValid();
        })
    }
}

impl fmt::Debug for SBDebugger {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        debug_descr(f, |descr| {
            cpp!(unsafe [self as "SBDebugger*", descr as "SBStream*"] -> bool as "bool" {
                return self->GetDescription(*descr);
            })
        })
    }
}
<|endoftext|>


<commit_before>// aux-build:unstable_generic_param.rs

extern crate unstable_generic_param;

use unstable_generic_param::*;

struct R;

impl Trait1 for S {
    fn foo() -> () { () } // ok
}

struct S;

impl Trait1<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> usize { 0 }
}

impl Trait1<isize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> isize { 0 }
}

impl Trait2<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> usize { 0 }
}

impl Trait3<usize> for S {
    fn foo() -> usize { 0 } // ok
}

fn main() {
    // let _ = S;

    // let _ = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1 = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1<isize> = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'

    // let _ = STRUCT1; // ok
    // let _: Struct1 = STRUCT1; // ok
    // let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field; // ok
    // let _: usize = STRUCT1.field; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field + 1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field + 1usize; //~ ERROR use of unstable library feature 'unstable_default'

    // let _ = Struct2 { field: 1 }; // ok
    // let _: Struct2 = Struct2 { field: 1 }; // ok
    // let _: Struct2<usize> = Struct2 { field: 1 }; // ok

    // let _ = STRUCT2;
    // let _: Struct2 = STRUCT2; // ok
    // let _: Struct2<usize> = STRUCT2; // ok
    // let _: Struct2<usize> = STRUCT2; // ok
    // let _ = STRUCT2.field; // ok
    // let _: usize = STRUCT2.field; // ok
    // let _ = STRUCT2.field + 1; // ok
    // let _ = STRUCT2.field + 1usize; // ok
}
<commit_msg>ignore-tidy-linelength generic default stab test<commit_after>// ignore-tidy-linelength
// aux-build:unstable_generic_param.rs

extern crate unstable_generic_param;

use unstable_generic_param::*;

struct R;

impl Trait1 for S {
    fn foo() -> () { () } // ok
}

struct S;

impl Trait1<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> usize { 0 }
}

impl Trait1<isize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> isize { 0 }
}

impl Trait2<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
    fn foo() -> usize { 0 }
}

impl Trait3<usize> for S {
    fn foo() -> usize { 0 } // ok
}

fn main() {
    // let _ = S;

    // let _ = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1 = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1<isize> = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'

    // let _ = STRUCT1; // ok
    // let _: Struct1 = STRUCT1; // ok
    // let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field; // ok
    // let _: usize = STRUCT1.field; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field + 1; //~ ERROR use of unstable library feature 'unstable_default'
    // let _ = STRUCT1.field + 1usize; //~ ERROR use of unstable library feature 'unstable_default'

    // let _ = Struct2 { field: 1 }; // ok
    // let _: Struct2 = Struct2 { field: 1 }; // ok
    // let _: Struct2<usize> = Struct2 { field: 1 }; // ok

    // let _ = STRUCT2;
    // let _: Struct2 = STRUCT2; // ok
    // let _: Struct2<usize> = STRUCT2; // ok
    // let _: Struct2<usize> = STRUCT2; // ok
    // let _ = STRUCT2.field; // ok
    // let _: usize = STRUCT2.field; // ok
    // let _ = STRUCT2.field + 1; // ok
    // let _ = STRUCT2.field + 1usize; // ok
}
<|endoftext|>


<commit_before><commit_msg>small refactoring<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{api, Error, Result};
use std::path::Path;

#[derive(Clone)]
pub struct Client {
    server_address: String,
    client: reqwest::Client,
}

impl Default for Client {
    fn default() -> Self {
        Client {
            server_address: "http://localhost:8080".to_string(),
            client: reqwest::Client::new(),
        }
    }
}

impl Client {
    pub fn new(server_address: &str) -> Self {
        Client { server_address: format!("http://{}", server_address), ..Self::default() }
    }

    pub async fn info(&self) -> Result<api::info::Response> {
        let response = self.client.get(&format!("{}/info", self.server_address)).send().await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn probe(&self, custom: Option<String>) -> Result<api::probe::Response> {
        let request = self.client.post(&format!("{}/probe", self.server_address));
        let response = match custom {
            Some(custom_server) => request.json(&api::probe::Request { custom_server }),
            None => request,
        }
        .send()
        .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::ACCEPTED => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn local_install(&self, file: &Path) -> Result<api::info::Response> {
        let response = self
            .client
            .post(&format!("{}/local_install", self.server_address))
            .body(format!("{}", file.display()))
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::UNPROCESSABLE_ENTITY => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn remote_install(&self, url: String) -> Result<api::info::Response> {
        let response = self
            .client
            .post(&format!("{}/remote_install", self.server_address))
            .body(url)
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::UNPROCESSABLE_ENTITY => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn abort_download(&self) -> Result<api::abort_download::Response> {
        let response = self
            .client
            .post(&format!("{}/update/download/abort", self.server_address))
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::BAD_REQUEST => Err(Error::AbortDownloadRefused(
                response.json::<api::abort_download::Refused>().await?,
            )),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn log(&self) -> Result<Vec<api::log::Entry>> {
        let response = self.client.get(&format!("{}/log", self.server_address)).send().await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }
}
<commit_msg>sdk: Fix return type for local_install and remote_install<commit_after>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{api, Error, Result};
use std::path::Path;

#[derive(Clone)]
pub struct Client {
    server_address: String,
    client: reqwest::Client,
}

impl Default for Client {
    fn default() -> Self {
        Client {
            server_address: "http://localhost:8080".to_string(),
            client: reqwest::Client::new(),
        }
    }
}

impl Client {
    pub fn new(server_address: &str) -> Self {
        Client { server_address: format!("http://{}", server_address), ..Self::default() }
    }

    pub async fn info(&self) -> Result<api::info::Response> {
        let response = self.client.get(&format!("{}/info", self.server_address)).send().await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn probe(&self, custom: Option<String>) -> Result<api::probe::Response> {
        let request = self.client.post(&format!("{}/probe", self.server_address));
        let response = match custom {
            Some(custom_server) => request.json(&api::probe::Request { custom_server }),
            None => request,
        }
        .send()
        .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::ACCEPTED => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn local_install(&self, file: &Path) -> Result<api::state::Response> {
        let response = self
            .client
            .post(&format!("{}/local_install", self.server_address))
            .header(reqwest::header::CONTENT_TYPE, "text/plain")
            .body(format!("{}", file.display()))
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::UNPROCESSABLE_ENTITY => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn remote_install(&self, url: String) -> Result<api::state::Response> {
        let response = self
            .client
            .post(&format!("{}/remote_install", self.server_address))
            .header(reqwest::header::CONTENT_TYPE, "text/plain")
            .body(url)
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::UNPROCESSABLE_ENTITY => {
                Err(Error::AgentIsBusy(response.json::<api::state::Response>().await?))
            }
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn abort_download(&self) -> Result<api::abort_download::Response> {
        let response = self
            .client
            .post(&format!("{}/update/download/abort", self.server_address))
            .send()
            .await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            reqwest::StatusCode::BAD_REQUEST => Err(Error::AbortDownloadRefused(
                response.json::<api::abort_download::Refused>().await?,
            )),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }

    pub async fn log(&self) -> Result<Vec<api::log::Entry>> {
        let response = self.client.get(&format!("{}/log", self.server_address)).send().await?;

        match response.status() {
            reqwest::StatusCode::OK => Ok(response.json().await?),
            _ => Err(Error::UnexpectedResponse(response)),
        }
    }
}
<|endoftext|>


<commit_before>// library ~ (core/bundler file)

// Copyright (C) ~ Alex Lyon <arcterus@mail.com>
// Copyright (C) ~ Roy Ivy III <rivy.dev@gmail.com>; MIT license

// * feature-gated external crates (re-shared as public internal modules)
#[cfg(feature = "libc")]
pub extern crate libc;
#[cfg(feature = "winapi")]
pub extern crate winapi;

//## internal modules

mod features; // feature-gated code modules
mod macros; // crate macros (macro_rules-type; exported to `crate::...`)
mod mods; // core cross-platform modules
mod parser; // string parsing modules

pub use uucore_procs::*;

// * cross-platform modules
pub use crate::mods::backup_control;
pub use crate::mods::display;
pub use crate::mods::error;
pub use crate::mods::os;
pub use crate::mods::panic;
pub use crate::mods::quoting_style;
pub use crate::mods::ranges;
pub use crate::mods::version_cmp;

// * string parsing modules
pub use crate::parser::parse_glob;
pub use crate::parser::parse_size;
pub use crate::parser::parse_time;

// * feature-gated modules
#[cfg(feature = "encoding")]
pub use crate::features::encoding;
#[cfg(feature = "fs")]
pub use crate::features::fs;
#[cfg(feature = "fsext")]
pub use crate::features::fsext;
#[cfg(feature = "lines")]
pub use crate::features::lines;
#[cfg(feature = "memo")]
pub use crate::features::memo;
#[cfg(feature = "ringbuffer")]
pub use crate::features::ringbuffer;

// * (platform-specific) feature-gated modules
// ** non-windows (i.e. Unix + Fuchsia)
#[cfg(all(not(windows), feature = "mode"))]
pub use crate::features::mode;
// ** unix-only
#[cfg(all(unix, feature = "entries"))]
pub use crate::features::entries;
#[cfg(all(unix, feature = "perms"))]
pub use crate::features::perms;
#[cfg(all(unix, feature = "pipes"))]
pub use crate::features::pipes;
#[cfg(all(unix, feature = "process"))]
pub use crate::features::process;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub use crate::features::signals;
#[cfg(all(
    unix,
    not(target_os = "android"),
    not(target_os = "fuchsia"),
    not(target_os = "redox"),
    not(target_env = "musl"),
    feature = "utmpx"
))]
pub use crate::features::utmpx;
// ** windows-only
#[cfg(all(windows, feature = "wide"))]
pub use crate::features::wide;

//## core functions

use std::ffi::OsString;
use std::sync::atomic::Ordering;

use once_cell::sync::Lazy;

#[macro_export]
macro_rules! bin {
    ($util:ident) => {
        pub fn main() {
            use std::io::Write;
            uucore::panic::mute_sigpipe_panic(); // suppress extraneous error output for SIGPIPE failures/panics
            let code = $util::uumain(uucore::args_os()); // execute utility code
            std::io::stdout().flush().expect("could not flush stdout"); // (defensively) flush stdout for utility prior to exit; see <https://github.com/rust-lang/rust/issues/23818>
            std::process::exit(code);
        }
    };
}

/// Generate the usage string for clap.
///
/// This function replaces all occurrences of `{}` with the execution phrase
/// and leaks the result to return a `&'static str`. It does **not** support
/// more advanced formatting features such as `{0}`.
pub fn format_usage(s: &str) -> &'static str {
    &*Box::leak(s.replace("{}", crate::execution_phrase()).into_boxed_str())
}

pub fn get_utility_is_second_arg() -> bool {
    crate::macros::UTILITY_IS_SECOND_ARG.load(Ordering::SeqCst)
}

pub fn set_utility_is_second_arg() {
    crate::macros::UTILITY_IS_SECOND_ARG.store(true, Ordering::SeqCst);
}

// args_os() can be expensive to call, it copies all of argv before iterating.
// So if we want only the first arg or so it's overkill. We cache it.
static ARGV: Lazy<Vec<OsString>> = Lazy::new(|| wild::args_os().collect());

static UTIL_NAME: Lazy<String> = Lazy::new(|| {
    if get_utility_is_second_arg() {
        &ARGV[1]
    } else {
        &ARGV[0]
    }
    .to_string_lossy()
    .into_owned()
});

/// Derive the utility name.
pub fn util_name() -> &'static str {
    &UTIL_NAME
}

static EXECUTION_PHRASE: Lazy<String> = Lazy::new(|| {
    if get_utility_is_second_arg() {
        ARGV.iter()
            .take(2)
            .map(|os_str| os_str.to_string_lossy().into_owned())
            .collect::<Vec<_>>()
            .join(" ")
    } else {
        ARGV[0].to_string_lossy().into_owned()
    }
});

/// Derive the complete execution phrase for "usage".
pub fn execution_phrase() -> &'static str {
    &EXECUTION_PHRASE
}

pub trait Args: Iterator<Item = OsString> + Sized {
    /// Collects the iterator into a `Vec<String>`, lossily converting the `OsString`s to `Strings`.
    fn collect_lossy(self) -> Vec<String> {
        self.map(|s| s.to_string_lossy().into_owned()).collect()
    }

    /// Collects the iterator into a `Vec<String>`, removing any elements that contain invalid encoding.
    fn collect_ignore(self) -> Vec<String> {
        self.filter_map(|s| s.into_string().ok()).collect()
    }
}

impl<T: Iterator<Item = OsString> + Sized> Args for T {}

pub fn args_os() -> impl Iterator<Item = OsString> {
    ARGV.iter().cloned()
}

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

    fn make_os_vec(os_str: &OsStr) -> Vec<OsString> {
        vec![
            OsString::from("test"),
            OsString::from("สวัสดี"), // spell-checker:disable-line
            os_str.to_os_string(),
        ]
    }

    #[cfg(any(unix, target_os = "redox"))]
    fn test_invalid_utf8_args_lossy(os_str: &OsStr) {
        // assert our string is invalid utf8
        assert!(os_str.to_os_string().into_string().is_err());
        let test_vec = make_os_vec(os_str);
        let collected_to_str = test_vec.clone().into_iter().collect_lossy();
        // conservation of length - when accepting lossy conversion no arguments may be dropped
        assert_eq!(collected_to_str.len(), test_vec.len());
        // first indices identical
        for index in 0..2 {
            assert_eq!(collected_to_str[index], test_vec[index].to_str().unwrap());
        }
        // lossy conversion for string with illegal encoding is done
        assert_eq!(
            *collected_to_str[2],
            os_str.to_os_string().to_string_lossy()
        );
    }

    #[cfg(any(unix, target_os = "redox"))]
    fn test_invalid_utf8_args_ignore(os_str: &OsStr) {
        // assert our string is invalid utf8
        assert!(os_str.to_os_string().into_string().is_err());
        let test_vec = make_os_vec(os_str);
        let collected_to_str = test_vec.clone().into_iter().collect_ignore();
        // assert that the broken entry is filtered out
        assert_eq!(collected_to_str.len(), test_vec.len() - 1);
        // assert that the unbroken indices are converted as expected
        for index in 0..2 {
            assert_eq!(
                collected_to_str.get(index).unwrap(),
                test_vec.get(index).unwrap().to_str().unwrap()
            );
        }
    }

    #[test]
    fn valid_utf8_encoding_args() {
        // create a vector containing only correct encoding
        let test_vec = make_os_vec(&OsString::from("test2"));
        // expect complete conversion without losses, even when lossy conversion is accepted
        let _ = test_vec.into_iter().collect_lossy();
    }

    #[cfg(any(unix, target_os = "redox"))]
    #[test]
    fn invalid_utf8_args_unix() {
        use std::os::unix::ffi::OsStrExt;

        let source = [0x66, 0x6f, 0x80, 0x6f];
        let os_str = OsStr::from_bytes(&source[..]);
        test_invalid_utf8_args_lossy(os_str);
        test_invalid_utf8_args_ignore(os_str);
    }
}
<commit_msg>uucore: remove string leak in format_usage<commit_after>// library ~ (core/bundler file)

// Copyright (C) ~ Alex Lyon <arcterus@mail.com>
// Copyright (C) ~ Roy Ivy III <rivy.dev@gmail.com>; MIT license

// * feature-gated external crates (re-shared as public internal modules)
#[cfg(feature = "libc")]
pub extern crate libc;
#[cfg(feature = "winapi")]
pub extern crate winapi;

//## internal modules

mod features; // feature-gated code modules
mod macros; // crate macros (macro_rules-type; exported to `crate::...`)
mod mods; // core cross-platform modules
mod parser; // string parsing modules

pub use uucore_procs::*;

// * cross-platform modules
pub use crate::mods::backup_control;
pub use crate::mods::display;
pub use crate::mods::error;
pub use crate::mods::os;
pub use crate::mods::panic;
pub use crate::mods::quoting_style;
pub use crate::mods::ranges;
pub use crate::mods::version_cmp;

// * string parsing modules
pub use crate::parser::parse_glob;
pub use crate::parser::parse_size;
pub use crate::parser::parse_time;

// * feature-gated modules
#[cfg(feature = "encoding")]
pub use crate::features::encoding;
#[cfg(feature = "fs")]
pub use crate::features::fs;
#[cfg(feature = "fsext")]
pub use crate::features::fsext;
#[cfg(feature = "lines")]
pub use crate::features::lines;
#[cfg(feature = "memo")]
pub use crate::features::memo;
#[cfg(feature = "ringbuffer")]
pub use crate::features::ringbuffer;

// * (platform-specific) feature-gated modules
// ** non-windows (i.e. Unix + Fuchsia)
#[cfg(all(not(windows), feature = "mode"))]
pub use crate::features::mode;
// ** unix-only
#[cfg(all(unix, feature = "entries"))]
pub use crate::features::entries;
#[cfg(all(unix, feature = "perms"))]
pub use crate::features::perms;
#[cfg(all(unix, feature = "pipes"))]
pub use crate::features::pipes;
#[cfg(all(unix, feature = "process"))]
pub use crate::features::process;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub use crate::features::signals;
#[cfg(all(
    unix,
    not(target_os = "android"),
    not(target_os = "fuchsia"),
    not(target_os = "redox"),
    not(target_env = "musl"),
    feature = "utmpx"
))]
pub use crate::features::utmpx;
// ** windows-only
#[cfg(all(windows, feature = "wide"))]
pub use crate::features::wide;

//## core functions

use std::ffi::OsString;
use std::sync::atomic::Ordering;

use once_cell::sync::Lazy;

#[macro_export]
macro_rules! bin {
    ($util:ident) => {
        pub fn main() {
            use std::io::Write;
            uucore::panic::mute_sigpipe_panic(); // suppress extraneous error output for SIGPIPE failures/panics
            let code = $util::uumain(uucore::args_os()); // execute utility code
            std::io::stdout().flush().expect("could not flush stdout"); // (defensively) flush stdout for utility prior to exit; see <https://github.com/rust-lang/rust/issues/23818>
            std::process::exit(code);
        }
    };
}

/// Generate the usage string for clap.
///
/// This function replaces all occurrences of `{}` with the execution phrase
/// and returns the resulting `String`. It does **not** support
/// more advanced formatting features such as `{0}`.
pub fn format_usage(s: &str) -> String {
    s.replace("{}", crate::execution_phrase())
}

pub fn get_utility_is_second_arg() -> bool {
    crate::macros::UTILITY_IS_SECOND_ARG.load(Ordering::SeqCst)
}

pub fn set_utility_is_second_arg() {
    crate::macros::UTILITY_IS_SECOND_ARG.store(true, Ordering::SeqCst);
}

// args_os() can be expensive to call, it copies all of argv before iterating.
// So if we want only the first arg or so it's overkill. We cache it.
static ARGV: Lazy<Vec<OsString>> = Lazy::new(|| wild::args_os().collect());

static UTIL_NAME: Lazy<String> = Lazy::new(|| {
    if get_utility_is_second_arg() {
        &ARGV[1]
    } else {
        &ARGV[0]
    }
    .to_string_lossy()
    .into_owned()
});

/// Derive the utility name.
pub fn util_name() -> &'static str {
    &UTIL_NAME
}

static EXECUTION_PHRASE: Lazy<String> = Lazy::new(|| {
    if get_utility_is_second_arg() {
        ARGV.iter()
            .take(2)
            .map(|os_str| os_str.to_string_lossy().into_owned())
            .collect::<Vec<_>>()
            .join(" ")
    } else {
        ARGV[0].to_string_lossy().into_owned()
    }
});

/// Derive the complete execution phrase for "usage".
pub fn execution_phrase() -> &'static str {
    &EXECUTION_PHRASE
}

pub trait Args: Iterator<Item = OsString> + Sized {
    /// Collects the iterator into a `Vec<String>`, lossily converting the `OsString`s to `Strings`.
    fn collect_lossy(self) -> Vec<String> {
        self.map(|s| s.to_string_lossy().into_owned()).collect()
    }

    /// Collects the iterator into a `Vec<String>`, removing any elements that contain invalid encoding.
    fn collect_ignore(self) -> Vec<String> {
        self.filter_map(|s| s.into_string().ok()).collect()
    }
}

impl<T: Iterator<Item = OsString> + Sized> Args for T {}

pub fn args_os() -> impl Iterator<Item = OsString> {
    ARGV.iter().cloned()
}

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

    fn make_os_vec(os_str: &OsStr) -> Vec<OsString> {
        vec![
            OsString::from("test"),
            OsString::from("สวัสดี"), // spell-checker:disable-line
            os_str.to_os_string(),
        ]
    }

    #[cfg(any(unix, target_os = "redox"))]
    fn test_invalid_utf8_args_lossy(os_str: &OsStr) {
        // assert our string is invalid utf8
        assert!(os_str.to_os_string().into_string().is_err());
        let test_vec = make_os_vec(os_str);
        let collected_to_str = test_vec.clone().into_iter().collect_lossy();
        // conservation of length - when accepting lossy conversion no arguments may be dropped
        assert_eq!(collected_to_str.len(), test_vec.len());
        // first indices identical
        for index in 0..2 {
            assert_eq!(collected_to_str[index], test_vec[index].to_str().unwrap());
        }
        // lossy conversion for string with illegal encoding is done
        assert_eq!(
            *collected_to_str[2],
            os_str.to_os_string().to_string_lossy()
        );
    }

    #[cfg(any(unix, target_os = "redox"))]
    fn test_invalid_utf8_args_ignore(os_str: &OsStr) {
        // assert our string is invalid utf8
        assert!(os_str.to_os_string().into_string().is_err());
        let test_vec = make_os_vec(os_str);
        let collected_to_str = test_vec.clone().into_iter().collect_ignore();
        // assert that the broken entry is filtered out
        assert_eq!(collected_to_str.len(), test_vec.len() - 1);
        // assert that the unbroken indices are converted as expected
        for index in 0..2 {
            assert_eq!(
                collected_to_str.get(index).unwrap(),
                test_vec.get(index).unwrap().to_str().unwrap()
            );
        }
    }

    #[test]
    fn valid_utf8_encoding_args() {
        // create a vector containing only correct encoding
        let test_vec = make_os_vec(&OsString::from("test2"));
        // expect complete conversion without losses, even when lossy conversion is accepted
        let _ = test_vec.into_iter().collect_lossy();
    }

    #[cfg(any(unix, target_os = "redox"))]
    #[test]
    fn invalid_utf8_args_unix() {
        use std::os::unix::ffi::OsStrExt;

        let source = [0x66, 0x6f, 0x80, 0x6f];
        let os_str = OsStr::from_bytes(&source[..]);
        test_invalid_utf8_args_lossy(os_str);
        test_invalid_utf8_args_ignore(os_str);
    }
}
<|endoftext|>


<commit_before>extern crate rosc;

use std::env;
use std::net::{UdpSocket, SocketAddrV4};
use std::str::FromStr;
use rosc::OscPacket;

fn main() {
    let args: Vec<String> = env::args().collect();
    let usage = format!("Usage {} IP:PORT", &args[0]);
    let addr = match SocketAddrV4::from_str(&args[1]) {
        Ok(addr) => addr,
        Err(_) => panic!(usage),
    };
    let sock = UdpSocket::bind(addr).unwrap();
    println!("Listening to {}", addr);

    let mut buf = [0u8; rosc::decoder::MTP];

    loop {
        match sock.recv_from(&mut buf) {
            Ok((size, addr)) => {
                println!("Received packet with size {} from: {}", size, addr);
                let packet = rosc::decoder::decode(&mut buf).unwrap();
                handle_packet(packet);
            }
            Err(e) => {
                println!("Error receiving from socket: {}", e);
                break;
            }
        }
    }
}

fn handle_packet(packet: OscPacket) {
    match packet {
        OscPacket::Message(msg) => {
            println!("OSC address: {}", msg.addr);
            match msg.args {
                Some(args) => {
                    println!("OSC arguments: {:?}", args);
                }
                None => println!("No arguments in message."),
            }
        }
        _ => (),
    }
}
<commit_msg>Check number of arguments<commit_after>extern crate rosc;

use std::env;
use std::net::{UdpSocket, SocketAddrV4};
use std::str::FromStr;
use rosc::OscPacket;

fn main() {
    let args: Vec<String> = env::args().collect();
    let usage = format!("Usage {} IP:PORT", &args[0]);
    if args.len() < 2 {
        println!("{}", usage);
        ::std::process::exit(1)
    }
    let addr = match SocketAddrV4::from_str(&args[1]) {
        Ok(addr) => addr,
        Err(_) => panic!(usage),
    };
    let sock = UdpSocket::bind(addr).unwrap();
    println!("Listening to {}", addr);

    let mut buf = [0u8; rosc::decoder::MTP];

    loop {
        match sock.recv_from(&mut buf) {
            Ok((size, addr)) => {
                println!("Received packet with size {} from: {}", size, addr);
                let packet = rosc::decoder::decode(&mut buf).unwrap();
                handle_packet(packet);
            }
            Err(e) => {
                println!("Error receiving from socket: {}", e);
                break;
            }
        }
    }
}

fn handle_packet(packet: OscPacket) {
    match packet {
        OscPacket::Message(msg) => {
            println!("OSC address: {}", msg.addr);
            match msg.args {
                Some(args) => {
                    println!("OSC arguments: {:?}", args);
                }
                None => println!("No arguments in message."),
            }
        }
        _ => (),
    }
}
<|endoftext|>


<commit_before>extern crate polydraw;

use std::cmp::{min, max};

use polydraw::{Application, Renderer, Frame};
use polydraw::draw::RGB;
use polydraw::geom::point::Point;
use polydraw::geom::triangle::Triangle;

struct TriangleRenderer {
   tr: Triangle,
}

impl TriangleRenderer {
   fn new() -> Self {
      let mult = 50;
      let tr = Triangle::new(
         Point::new(2 * mult, 9 * mult),
         Point::new(13 * mult, 12 * mult),
         Point::new(7 * mult, 2 * mult),
      );

      println!("orientation {:?}", orientation(&tr.a, &tr.b, &tr.c));

      TriangleRenderer {
         tr: tr
      }
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      let color = RGB::new(127, 223, 255);

      self.tr.a.x += 1;
      if self.tr.a.x >= frame.width as i64 {
         self.tr.a.x = 0;
      }

      let a = self.tr.a;
      let b = self.tr.b;
      let c = self.tr.c;

      let min_x = max(min3(a.x, b.x, c.x), 0);
      let min_y = max(min3(a.y, b.y, c.y), 0);
      let max_x = min(max3(a.x, b.x, c.x), frame.width as i64 - 1);
      let max_y = min(max3(a.y, b.y, c.y), frame.height as i64 - 1);

      for y in min_y..max_y+1 {
         for x in min_x..max_x+1 {
            let p = Point::new(x, y);
            let w0 = orientation(&b, &c, &p);
            let w1 = orientation(&c, &a, &p);
            let w2 = orientation(&a, &b, &p);

            if w0.signum() == w1.signum() && w0.signum() == w2.signum() {
               frame.put_pixel(x as i32, y as i32, &color);
            }
         }
      }
   }
}

#[inline]
pub fn min3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   min(min(v1, v2), v3)
}

#[inline]
pub fn max3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   max(max(v1, v2), v3)
}

#[inline]
fn orientation(a: &Point, b: &Point, c: &Point) -> i64 {
   (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle")
      .run();
}
<commit_msg>Naive triangle rendering with analytical AA<commit_after>#![feature(test)]

#![allow(dead_code)]

extern crate test;

extern crate polydraw;

use std::cmp::{min, max};
use std::i64;

use polydraw::{Application, Renderer, Frame};
use polydraw::draw::RGB;
use polydraw::geom::point::Point;
use polydraw::geom::triangle::Triangle;
use polydraw::geom::number::NumberOps;
use polydraw::geom::polygon::double_polygon_area;
use polydraw::geom::clip::{h_split, v_split};

const DIV_PER_PIXEL: i64 = 1000;
const HALF_DIV_PER_PIXEL: i64 = DIV_PER_PIXEL / 2;
const DOUBLE_PIXEL_AREA: i64 = DIV_PER_PIXEL * DIV_PER_PIXEL * 2;

#[inline]
fn to_px(v: i64) -> i64 {
   v.rounding_div(DIV_PER_PIXEL)
}

#[inline]
fn from_px(v: i64) -> i64 {
   v as i64 * DIV_PER_PIXEL
}

struct TriangleRenderer {
   tr: Triangle,
   colors: Vec<RGB>
}

impl TriangleRenderer {
   fn new() -> Self {
      let tr = Triangle::new(
         Point::new(from_px(100), from_px(450)),
         Point::new(from_px(600), from_px(600)),
         Point::new(from_px(350), from_px(100)),
      );

      let mut colors = Vec::with_capacity(256);
      for i in 0..256_usize {
         colors.push(
            RGB::new(
               (i * 127 / 255) as u8, (i * 223 / 255) as u8, i as u8
            )
         );
      }

      TriangleRenderer {
         tr: tr,
         colors: colors,
      }
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.tr.a.x += DIV_PER_PIXEL;
      if self.tr.a.x >= from_px(frame.width as i64) {
         self.tr.a.x = 0;
      }

      let a = self.tr.a;
      let b = self.tr.b;
      let c = self.tr.c;

      let min_y = max(to_px(min3(a.y, b.y, c.y)), 0);
      let max_y = min(to_px(max3(a.y, b.y, c.y)), frame.height as i64 - 1);

      let mut up = Vec::with_capacity(100);
      up.push(a); up.push(b); up.push(c);

      let mut left = Vec::with_capacity(100);
      let mut right = Vec::with_capacity(100);

      let mut up_start = 0;
      let mut right_start;

      for y in min_y..max_y+1 {
         let y_split = from_px(y) + HALF_DIV_PER_PIXEL;

         right_start = right.len();
         let up_end = up.len();

         h_split(y_split, up_start, &mut right, &mut up);

         up_start = up_end;

         let (min_x, max_x) = min_max_x(0, &right);

         for x in min_x..max_x {
            let left_start = left.len();
            let right_end = right.len();

            let x_split = from_px(x) + HALF_DIV_PER_PIXEL;

            v_split(x_split, right_start, &mut left, &mut right);

            right_start = right_end;

            plot_poly_pixel(frame, x, y, left_start, &left, &self.colors);
         }

         plot_poly_pixel(frame, max_x, y, right_start, &right, &self.colors);
      }
   }
}

#[inline]
fn print_points(name: &str, start: usize, points: &Vec<Point>) {
   print!("{}: ", name);

   for p in points[start..].iter() {
      print!("({:?}, {:?}) ", p.x, p.y);
   }

   println!("");
}

#[inline]
fn plot_poly_pixel(frame: &mut Frame, x: i64, y: i64, start: usize, points: &Vec<Point>, colors: &Vec<RGB>) {
   let area = double_polygon_area(start, &points);

   assert!(area <= DOUBLE_PIXEL_AREA);

   frame.put_pixel(x as i32, y as i32, &colors[(255 * area / DOUBLE_PIXEL_AREA) as usize]);
}

#[inline]
fn min_max_x(start: usize, points: &Vec<Point>) -> (i64, i64) {
   let mut min_x = i64::MAX;
   let mut max_x = i64::MIN;
   for p in points[start..].iter() {
      if p.x > max_x {
         max_x = p.x;
      }

      if p.x < min_x {
         min_x = p.x;
      }
   }

   (to_px(min_x), to_px(max_x))
}

#[inline]
pub fn min3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   min(min(v1, v2), v3)
}

#[inline]
pub fn max3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   max(max(v1, v2), v3)
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle")
      .run();
}
<|endoftext|>


<commit_before>#![feature(test)]

#![allow(dead_code)]

extern crate test;

extern crate polydraw;

use std::cmp::{min, max};
use std::i64;

use polydraw::{Application, Renderer, Frame};
use polydraw::draw::RGB;
use polydraw::geom::point::Point;
use polydraw::geom::triangle::Triangle;
use polydraw::geom::number::NumberOps;
use polydraw::geom::polygon::double_polygon_area;
use polydraw::geom::clip::{h_split, v_split};

const DIV_PER_PIXEL: i64 = 1000;
const HALF_DIV_PER_PIXEL: i64 = DIV_PER_PIXEL / 2;
const DOUBLE_PIXEL_AREA: i64 = DIV_PER_PIXEL * DIV_PER_PIXEL * 2;

#[inline]
fn to_px(v: i64) -> i64 {
   v.rounding_div(DIV_PER_PIXEL)
}

#[inline]
fn from_px(v: i64) -> i64 {
   v as i64 * DIV_PER_PIXEL
}

struct TriangleRenderer {
   tr: Triangle,
   colors: Vec<RGB>
}

impl TriangleRenderer {
   fn new() -> Self {
      let tr = Triangle::new(
         Point::new(from_px(100), from_px(450)),
         Point::new(from_px(600), from_px(600)),
         Point::new(from_px(350), from_px(100)),
      );

      let mut colors = Vec::with_capacity(256);
      for i in 0..256_usize {
         colors.push(
            RGB::new(
               (i * 127 / 255) as u8, (i * 223 / 255) as u8, i as u8
            )
         );
      }

      TriangleRenderer {
         tr: tr,
         colors: colors,
      }
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.tr.a.x += DIV_PER_PIXEL;
      if self.tr.a.x >= from_px(frame.width as i64) {
         self.tr.a.x = 0;
      }

      let a = self.tr.a;
      let b = self.tr.b;
      let c = self.tr.c;

      let min_y = max(to_px(min3(a.y, b.y, c.y)), 0);
      let max_y = min(to_px(max3(a.y, b.y, c.y)), frame.height as i64 - 1);

      let mut up = Vec::with_capacity(100);
      up.push(a); up.push(b); up.push(c);

      let mut left = Vec::with_capacity(100);
      let mut right = Vec::with_capacity(100);

      let mut up_start = 0;
      let mut right_start;

      for y in min_y..max_y+1 {
         let y_split = from_px(y) + HALF_DIV_PER_PIXEL;

         right_start = right.len();
         let up_end = up.len();

         h_split(y_split, up_start, &mut right, &mut up);

         up_start = up_end;

         let (min_x, max_x) = min_max_x(0, &right);

         for x in min_x..max_x {
            let left_start = left.len();
            let right_end = right.len();

            let x_split = from_px(x) + HALF_DIV_PER_PIXEL;

            v_split(x_split, right_start, &mut left, &mut right);

            right_start = right_end;

            plot_poly_pixel(frame, x, y, left_start, &left, &self.colors);
         }

         plot_poly_pixel(frame, max_x, y, right_start, &right, &self.colors);
      }
   }
}

#[inline]
fn print_points(name: &str, start: usize, points: &Vec<Point>) {
   print!("{}: ", name);

   for p in points[start..].iter() {
      print!("({:?}, {:?}) ", p.x, p.y);
   }

   println!("");
}

#[inline]
fn plot_poly_pixel(frame: &mut Frame, x: i64, y: i64, start: usize, points: &Vec<Point>, colors: &Vec<RGB>) {
   let area = double_polygon_area(start, &points);

   assert!(area <= DOUBLE_PIXEL_AREA);

   frame.put_pixel(x as i32, y as i32, &colors[(255 * area / DOUBLE_PIXEL_AREA) as usize]);
}

#[inline]
fn min_max_x(start: usize, points: &Vec<Point>) -> (i64, i64) {
   let mut min_x = i64::MAX;
   let mut max_x = i64::MIN;
   for p in points[start..].iter() {
      if p.x > max_x {
         max_x = p.x;
      }

      if p.x < min_x {
         min_x = p.x;
      }
   }

   (to_px(min_x), to_px(max_x))
}

#[inline]
pub fn min3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   min(min(v1, v2), v3)
}

#[inline]
pub fn max3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   max(max(v1, v2), v3)
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle")
      .run();
}
<commit_msg>Fix for the triangle example<commit_after>#![feature(test)]

#![allow(dead_code)]

extern crate test;

extern crate polydraw;

use std::cmp::{min, max};
use std::i64;

use polydraw::{Application, Renderer, Frame};
use polydraw::draw::RGB;
use polydraw::geom::point::Point;
use polydraw::geom::triangle::Triangle;
use polydraw::geom::number::NumberOps;
use polydraw::geom::polygon::double_polygon_area;
use polydraw::geom::clip::{h_split, v_split};

const DIV_PER_PIXEL: i64 = 1000;
const HALF_DIV_PER_PIXEL: i64 = DIV_PER_PIXEL / 2;
const DOUBLE_PIXEL_AREA: i64 = DIV_PER_PIXEL * DIV_PER_PIXEL * 2;

#[inline]
fn to_px(v: i64) -> i64 {
   v.rounding_div(DIV_PER_PIXEL)
}

#[inline]
fn from_px(v: i64) -> i64 {
   v as i64 * DIV_PER_PIXEL
}

struct TriangleRenderer {
   tr: Triangle,
   colors: Vec<RGB>
}

impl TriangleRenderer {
   fn new() -> Self {
      let tr = Triangle::new(
         Point::new(from_px(100), from_px(450)),
         Point::new(from_px(600), from_px(600)),
         Point::new(from_px(350), from_px(100)),
      );

      let mut colors = Vec::with_capacity(256);
      for i in 0..256_usize {
         colors.push(
            RGB::new(
               (i * 127 / 255) as u8, (i * 223 / 255) as u8, i as u8
            )
         );
      }

      TriangleRenderer {
         tr: tr,
         colors: colors,
      }
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.tr.a.x += DIV_PER_PIXEL;
      if self.tr.a.x >= from_px(frame.width as i64) {
         self.tr.a.x = 0;
      }

      let a = self.tr.a;
      let b = self.tr.b;
      let c = self.tr.c;

      let min_y = max(to_px(min3(a.y, b.y, c.y)), 0);
      let max_y = min(to_px(max3(a.y, b.y, c.y)), frame.height as i64 - 1);

      let mut up = Vec::with_capacity(100);
      up.push(a); up.push(b); up.push(c);

      let mut left = Vec::with_capacity(100);
      let mut right = Vec::with_capacity(100);

      let mut up_start = 0;
      let mut right_start;

      for y in min_y..max_y+1 {
         let y_split = from_px(y) + HALF_DIV_PER_PIXEL;

         right_start = right.len();
         let up_end = up.len();

         h_split(y_split, up_start, &mut right, &mut up);

         up_start = up_end;

         let (min_x, max_x) = min_max_x(right_start, &right);

         for x in min_x..max_x {
            let left_start = left.len();
            let right_end = right.len();

            let x_split = from_px(x) + HALF_DIV_PER_PIXEL;

            v_split(x_split, right_start, &mut left, &mut right);

            right_start = right_end;

            plot_poly_pixel(frame, x, y, left_start, &left, &self.colors);
         }

         plot_poly_pixel(frame, max_x, y, right_start, &right, &self.colors);
      }
   }
}

#[inline]
fn print_points(name: &str, start: usize, points: &Vec<Point>) {
   print!("{}: ", name);

   for p in points[start..].iter() {
      print!("({:?}, {:?}) ", p.x, p.y);
   }

   println!("");
}

#[inline]
fn plot_poly_pixel(frame: &mut Frame, x: i64, y: i64, start: usize, points: &Vec<Point>, colors: &Vec<RGB>) {
   let area = double_polygon_area(start, &points);

   assert!(area <= DOUBLE_PIXEL_AREA);

   frame.put_pixel(x as i32, y as i32, &colors[(255 * area / DOUBLE_PIXEL_AREA) as usize]);
}

#[inline]
fn min_max_x(start: usize, points: &Vec<Point>) -> (i64, i64) {
   let mut min_x = i64::MAX;
   let mut max_x = i64::MIN;
   for p in points[start..].iter() {
      if p.x > max_x {
         max_x = p.x;
      }

      if p.x < min_x {
         min_x = p.x;
      }
   }

   (to_px(min_x), to_px(max_x))
}

#[inline]
pub fn min3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   min(min(v1, v2), v3)
}

#[inline]
pub fn max3<T: Ord>(v1: T, v2: T, v3: T) -> T {
   max(max(v1, v2), v3)
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle")
      .run();
}
<|endoftext|>