<commit_before>extern crate env_logger;
extern crate lapin_async as lapin;

use std::net::TcpStream;
use std::{thread,time};

use lapin::types::*;
use lapin::connection::*;
use lapin::buffer::Buffer;
use lapin::generated::basic;

#[test]
fn connection() {
      env_logger::init();

      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();
      stream.set_nonblocking(true).unwrap();

      let capacity = 8192;
      let mut send_buffer    = Buffer::with_capacity(capacity as usize);
      let mut receive_buffer = Buffer::with_capacity(capacity as usize);

      let mut conn: Connection = Connection::new();
      conn.set_frame_max(capacity);
      assert_eq!(conn.connect().unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));
      loop {
        match conn.run(&mut stream, &mut send_buffer, &mut receive_buffer) {
          Err(e) => panic!("could not connect: {:?}", e),
          Ok(ConnectionState::Connected) => break,
          Ok(state) => println!("now at state {:?}, continue", state),
        }
        thread::sleep(time::Duration::from_millis(100));
      }
      println!("CONNECTED");

      //now connected

      let frame_max = conn.configuration.frame_max;
      if frame_max > capacity {
        send_buffer.grow(frame_max as usize);
        receive_buffer.grow(frame_max as usize);
      }

      let channel_a: u16 = conn.create_channel().unwrap();
      let channel_b: u16 = conn.create_channel().unwrap();
      //send channel
      conn.channel_open(channel_a, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //receive channel
      conn.channel_open(channel_b, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //create the hello queue
      conn.queue_declare(channel_a, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //purge the hello queue in case it already exists with contents in it
      conn.queue_purge(channel_a, 0, "hello-async".to_string(), false).expect("queue_purge");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      conn.queue_declare(channel_b, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will consume");
      conn.basic_consume(channel_b, 0, "hello-async".to_string(), "my_consumer".to_string(), false, true, false, false, FieldTable::new()).expect("basic_consume");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will publish");
      conn.basic_publish(channel_a, 0, "".to_string(), "hello-async".to_string(), false, false).expect("basic_publish");
      let payload = b"Hello world!";
      conn.send_content_frames(channel_a, 60, payload, basic::Properties::default());
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      let msg = conn.next_delivery(channel_b, "hello-async", "my_consumer").unwrap();
      println!("received message: {:?}", msg);
      println!("data: {}", std::str::from_utf8(&msg.data).unwrap());

      assert_eq!(msg.data, b"Hello world!");
}
<commit_msg>test: add debug log<commit_after>extern crate env_logger;
extern crate lapin_async as lapin;

use std::net::TcpStream;
use std::{thread,time};

use lapin::types::*;
use lapin::connection::*;
use lapin::buffer::Buffer;
use lapin::generated::basic;

#[test]
fn connection() {
      env_logger::init();

      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();
      stream.set_nonblocking(true).unwrap();

      let capacity = 8192;
      let mut send_buffer    = Buffer::with_capacity(capacity as usize);
      let mut receive_buffer = Buffer::with_capacity(capacity as usize);

      let mut conn: Connection = Connection::new();
      conn.set_frame_max(capacity);
      assert_eq!(conn.connect().unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));
      loop {
        match conn.run(&mut stream, &mut send_buffer, &mut receive_buffer) {
          Err(e) => panic!("could not connect: {:?}", e),
          Ok(ConnectionState::Connected) => break,
          Ok(state) => println!("now at state {:?}, continue", state),
        }
        thread::sleep(time::Duration::from_millis(100));
      }
      println!("CONNECTED with configuration: {:?}", conn.configuration);

      //now connected

      let frame_max = conn.configuration.frame_max;
      if frame_max > capacity {
        send_buffer.grow(frame_max as usize);
        receive_buffer.grow(frame_max as usize);
      }

      let channel_a: u16 = conn.create_channel().unwrap();
      let channel_b: u16 = conn.create_channel().unwrap();
      //send channel
      conn.channel_open(channel_a, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //receive channel
      conn.channel_open(channel_b, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //create the hello queue
      conn.queue_declare(channel_a, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //purge the hello queue in case it already exists with contents in it
      conn.queue_purge(channel_a, 0, "hello-async".to_string(), false).expect("queue_purge");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      conn.queue_declare(channel_b, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will consume");
      conn.basic_consume(channel_b, 0, "hello-async".to_string(), "my_consumer".to_string(), false, true, false, false, FieldTable::new()).expect("basic_consume");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will publish");
      conn.basic_publish(channel_a, 0, "".to_string(), "hello-async".to_string(), false, false).expect("basic_publish");
      let payload = b"Hello world!";
      conn.send_content_frames(channel_a, 60, payload, basic::Properties::default());
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      let msg = conn.next_delivery(channel_b, "hello-async", "my_consumer").unwrap();
      println!("received message: {:?}", msg);
      println!("data: {}", std::str::from_utf8(&msg.data).unwrap());

      assert_eq!(msg.data, b"Hello world!");
}
<|endoftext|>


<commit_before>//! Common types for other ruma crates.

#![warn(missing_docs)]

pub mod presence;
pub mod push;
mod raw;

pub use self::raw::Raw;
<commit_msg>Set warn(missing_debug_implementations) in ruma-common<commit_after>//! Common types for other ruma crates.

#![warn(missing_docs, missing_debug_implementations)]

pub mod presence;
pub mod push;
mod raw;

pub use self::raw::Raw;
<|endoftext|>


<commit_before>#[macro_use]
extern crate const_cstr;
extern crate dlopen;
extern crate rand;
extern crate test_server;

use dlopen::raw::Library;
use std::{env, str};
use std::u16::MAX;
use test_server::hyper;

#[cfg(target_os = "windows")]
const LIB_PATH: &str = "../../target/debug/ctehxk2.dll";
#[cfg(target_os = "linux")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.so";
#[cfg(target_os = "macos")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.dylib";

#[test]
fn has_ct_api_functions() {
    let lib = Library::open(LIB_PATH).expect("Could not open library");

    let init: unsafe extern "C" fn(u16, u16) -> i8 =
        unsafe { lib.symbol_cstr(const_cstr!("CT_init").as_cstr()) }.unwrap();

    let data: unsafe extern "C" fn(u16, *mut u8, *mut u8, u16, *const u8, *mut u16, *mut u8)
        -> i8 = unsafe { lib.symbol_cstr(const_cstr!("CT_data").as_cstr()) }.unwrap();

    let close: unsafe extern "C" fn(u16) -> i8 =
        unsafe { lib.symbol_cstr(const_cstr!("CT_close").as_cstr()) }.unwrap();

    let ctn = rand::random::<u16>();
    let pn = rand::random::<u16>();
    let mut dad = rand::random::<u8>();
    let mut sad = rand::random::<u8>();

    let commands: [u8; 1] = [rand::random::<u8>(); 1];
    let commands_ptr: *const u8 = &commands[0];
    let lenc: u16 = commands.len() as u16;

    let mut response: [u8; MAX as usize] = [rand::random::<u8>(); MAX as usize];
    let response_ptr: *mut u8 = &mut response[0];
    let mut lenr: u16 = response.len() as u16;

    let server = test_server::serve(Some(String::from("127.0.0.1:65432")));
    env::set_var("K2_BASE_URL", "http://127.0.0.1:65432");

    server.reply().status(hyper::Ok).body("0");
    assert_eq!(0, unsafe { init(ctn, pn) });

    server
        .reply()
        .status(hyper::Ok)
        .body("{\"dad\":1,\"sad\":1,\"lenr\":5,\"response\":\"AQIDBAU=\",\"responseCode\":0}");
    assert_eq!(0, unsafe {
        data(
            ctn,
            &mut dad,
            &mut sad,
            lenc,
            commands_ptr,
            &mut lenr,
            response_ptr,
        )
    });

    server.reply().status(hyper::Ok).body("0");
    assert_eq!(0, unsafe { close(ctn) });
}
<commit_msg>use latest test-server in use-library example<commit_after>#[macro_use]
extern crate const_cstr;
extern crate dlopen;
extern crate rand;
extern crate test_server;

use dlopen::raw::Library;
use std::{env, str};
use std::u16::MAX;
use test_server::http::StatusCode;

#[cfg(target_os = "windows")]
const LIB_PATH: &str = "../../target/debug/ctehxk2.dll";
#[cfg(target_os = "linux")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.so";
#[cfg(target_os = "macos")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.dylib";

#[test]
fn has_ct_api_functions() {
    let lib = Library::open(LIB_PATH).expect("Could not open library");

    let init: unsafe extern "system" fn(u16, u16) -> i8 =
        unsafe { lib.symbol_cstr(const_cstr!("CT_init").as_cstr()) }.unwrap();

    let data: unsafe extern "system" fn(
        u16,
        *mut u8,
        *mut u8,
        u16,
        *const u8,
        *mut u16,
        *mut u8,
    ) -> i8 = unsafe { lib.symbol_cstr(const_cstr!("CT_data").as_cstr()) }.unwrap();

    let close: unsafe extern "system" fn(u16) -> i8 =
        unsafe { lib.symbol_cstr(const_cstr!("CT_close").as_cstr()) }.unwrap();

    let ctn = rand::random::<u16>();
    let pn = rand::random::<u16>();
    let mut dad = rand::random::<u8>();
    let mut sad = rand::random::<u8>();

    let commands: [u8; 1] = [rand::random::<u8>(); 1];
    let commands_ptr: *const u8 = &commands[0];
    let lenc: u16 = commands.len() as u16;

    let mut response: [u8; MAX as usize] = [rand::random::<u8>(); MAX as usize];
    let response_ptr: *mut u8 = &mut response[0];
    let mut lenr: u16 = response.len() as u16;

    let server = test_server::serve(Some(String::from("127.0.0.1:65432")));
    env::set_var("K2_BASE_URL", "http://127.0.0.1:65432");

    server.reply().status(StatusCode::OK).body("0");
    assert_eq!(0, unsafe { init(ctn, pn) });

    server
        .reply()
        .status(StatusCode::OK)
        .body("{\"dad\":1,\"sad\":1,\"lenr\":5,\"response\":\"AQIDBAU=\",\"responseCode\":0}");
    assert_eq!(0, unsafe {
        data(
            ctn,
            &mut dad,
            &mut sad,
            lenc,
            commands_ptr,
            &mut lenr,
            response_ptr,
        )
    });

    server.reply().status(StatusCode::OK).body("0");
    assert_eq!(0, unsafe { close(ctn) });
}
<|endoftext|>


<commit_before>use crate::term2;
use rustup::dist::Notification as In;
use rustup::utils::tty;
use rustup::utils::Notification as Un;
use rustup::Notification;
use std::collections::VecDeque;
use std::fmt;
use std::io::Write;
use term::Terminal;
use time::precise_time_s;

/// Keep track of this many past download amounts
const DOWNLOAD_TRACK_COUNT: usize = 5;

/// Tracks download progress and displays information about it to a terminal.
pub struct DownloadTracker {
    /// Content-Length of the to-be downloaded object.
    content_len: Option<usize>,
    /// Total data downloaded in bytes.
    total_downloaded: usize,
    /// Data downloaded this second.
    downloaded_this_sec: usize,
    /// Keeps track of amount of data downloaded every last few secs.
    /// Used for averaging the download speed. NB: This does not necessarily
    /// represent adjacent seconds; thus it may not show the average at all.
    downloaded_last_few_secs: VecDeque<usize>,
    /// Time stamp of the last second
    last_sec: Option<f64>,
    /// Time stamp of the start of the download
    start_sec: f64,
    /// The terminal we write the information to.
    /// XXX: Could be a term trait, but with #1818 on the horizon that
    ///      is a pointless change to make - better to let that transition
    ///      happen and take stock after that.
    term: term2::StdoutTerminal,
    /// Whether we displayed progress for the download or not.
    ///
    /// If the download is quick enough, we don't have time to
    /// display the progress info.
    /// In that case, we do not want to do some cleanup stuff we normally do.
    ///
    /// If we have displayed progress, this is the number of characters we
    /// rendered, so we can erase it cleanly.
    displayed_charcount: Option<usize>,
    /// What units to show progress in
    units: Vec<String>,
}

impl DownloadTracker {
    /// Creates a new DownloadTracker.
    pub fn new() -> Self {
        DownloadTracker {
            content_len: None,
            total_downloaded: 0,
            downloaded_this_sec: 0,
            downloaded_last_few_secs: VecDeque::with_capacity(DOWNLOAD_TRACK_COUNT),
            start_sec: precise_time_s(),
            last_sec: None,
            term: term2::stdout(),
            displayed_charcount: None,
            units: vec!["B".into(); 1],
        }
    }

    pub fn handle_notification(&mut self, n: &Notification<'_>) -> bool {
        match *n {
            Notification::Install(In::Utils(Un::DownloadContentLengthReceived(content_len))) => {
                self.content_length_received(content_len);

                true
            }
            Notification::Install(In::Utils(Un::DownloadDataReceived(data))) => {
                if tty::stdout_isatty() {
                    self.data_received(data.len());
                }
                true
            }
            Notification::Install(In::Utils(Un::DownloadFinished)) => {
                self.download_finished();
                true
            }
            Notification::Install(In::Utils(Un::DownloadPushUnits(units))) => {
                self.push_units(units.into());
                true
            }
            Notification::Install(In::Utils(Un::DownloadPopUnits)) => {
                self.pop_units();
                true
            }

            _ => false,
        }
    }

    /// Notifies self that Content-Length information has been received.
    pub fn content_length_received(&mut self, content_len: u64) {
        self.content_len = Some(content_len as usize);
    }

    /// Notifies self that data of size `len` has been received.
    pub fn data_received(&mut self, len: usize) {
        self.total_downloaded += len;
        self.downloaded_this_sec += len;

        let current_time = precise_time_s();

        match self.last_sec {
            None => self.last_sec = Some(current_time),
            Some(prev) => {
                let elapsed = current_time - prev;
                if elapsed >= 1.0 {
                    self.display();
                    self.last_sec = Some(current_time);
                    if self.downloaded_last_few_secs.len() == DOWNLOAD_TRACK_COUNT {
                        self.downloaded_last_few_secs.pop_back();
                    }
                    self.downloaded_last_few_secs
                        .push_front(self.downloaded_this_sec);
                    self.downloaded_this_sec = 0;
                }
            }
        }
    }
    /// Notifies self that the download has finished.
    pub fn download_finished(&mut self) {
        if self.displayed_charcount.is_some() {
            // Display the finished state
            self.display();
            let _ = writeln!(self.term);
        }
        self.prepare_for_new_download();
    }
    // we're doing modular arithmetic, treat as integer
    pub fn from_seconds(sec: u32) -> (u32, u32, u32, u32) {
        let d = sec / (24 * 3600);
        let h = sec % (24 * 3600) / 3600;
        let min = sec % 3600 / 60;
        let sec = sec % 60;

        (d, h, min, sec)
    }
    /// Resets the state to be ready for a new download.
    fn prepare_for_new_download(&mut self) {
        self.content_len = None;
        self.total_downloaded = 0;
        self.downloaded_this_sec = 0;
        self.downloaded_last_few_secs.clear();
        self.start_sec = precise_time_s();
        self.last_sec = None;
        self.displayed_charcount = None;
    }
    /// Display the tracked download information to the terminal.
    fn display(&mut self) {
        // Panic if someone pops the default bytes unit...
        let units = &self.units.last().unwrap();
        let total_h = Size(self.total_downloaded, units);
        let sum: usize = self.downloaded_last_few_secs.iter().sum();
        let len = self.downloaded_last_few_secs.len();
        let speed = if len > 0 { sum / len } else { 0 };
        let speed_h = Size(speed, units);
        let elapsed_h = Duration(precise_time_s() - self.start_sec);

        // First, move to the start of the current line and clear it.
        let _ = self.term.carriage_return();
        // We'd prefer to use delete_line() but on Windows it seems to
        // sometimes do unusual things
        // let _ = self.term.as_mut().unwrap().delete_line();
        // So instead we do:
        if let Some(n) = self.displayed_charcount {
            // This is not ideal as very narrow terminals might mess up,
            // but it is more likely to succeed until term's windows console
            // fixes whatever's up with delete_line().
            let _ = write!(self.term, "{}", " ".repeat(n));
            let _ = self.term.flush();
            let _ = self.term.carriage_return();
        }

        let output = match self.content_len {
            Some(content_len) => {
                let content_len_h = Size(content_len, units);
                let content_len = content_len as f64;
                let percent = (self.total_downloaded as f64 / content_len) * 100.;
                let remaining = content_len - self.total_downloaded as f64;
                let eta_h = Duration(remaining / speed as f64);
                format!(
                    "{} / {} ({:3.0} %) {}/s in {} ETA: {}",
                    total_h, content_len_h, percent, speed_h, elapsed_h, eta_h
                )
            }
            None => format!(
                "Total: {} Speed: {}/s Elapsed: {}",
                total_h, speed_h, elapsed_h
            ),
        };

        let _ = write!(self.term, "{}", output);
        // Since stdout is typically line-buffered and we don't print a newline, we manually flush.
        let _ = self.term.flush();
        self.displayed_charcount = Some(output.chars().count());
    }

    pub fn push_units(&mut self, new_units: String) {
        self.units.push(new_units);
    }

    pub fn pop_units(&mut self) {
        self.units.pop();
    }
}

/// Human readable representation of duration(seconds).
struct Duration(f64);

impl fmt::Display for Duration {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // repurposing the alternate mode for ETA
        let sec = self.0;

        if sec.is_infinite() {
            write!(f, "Unknown")
        } else {
            match DownloadTracker::from_seconds(sec as u32) {
                (d, h, m, s) if d > 0 => write!(f, "{:3.0}d {:2.0}h {:2.0}m {:2.0}s", d, h, m, s),
                (0, h, m, s) if h > 0 => write!(f, "{:2.0}h {:2.0}m {:2.0}s", h, m, s),
                (0, 0, m, s) if m > 0 => write!(f, "{:2.0}m {:2.0}s", m, s),
                (_, _, _, s) => write!(f, "{:2.0}s", s),
            }
        }
    }
}

/// Human readable size (some units)
struct Size<'a>(usize, &'a str);

impl<'a> fmt::Display for Size<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        const KI: f64 = 1024.0;
        const MI: f64 = KI * KI;
        let size = self.0 as f64;

        if size >= MI {
            write!(f, "{:5.1} Mi{}", size / MI, self.1) // XYZ.P Mi
        } else if size >= KI {
            write!(f, "{:5.1} Ki{}", size / KI, self.1)
        } else {
            write!(f, "{:3.0} {}", size, self.1)
        }
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn download_tracker_from_seconds_test() {
        use crate::download_tracker::DownloadTracker;
        assert_eq!(DownloadTracker::from_seconds(2), (0, 0, 0, 2));

        assert_eq!(DownloadTracker::from_seconds(60), (0, 0, 1, 0));

        assert_eq!(DownloadTracker::from_seconds(3_600), (0, 1, 0, 0));

        assert_eq!(DownloadTracker::from_seconds(3_600 * 24), (1, 0, 0, 0));

        assert_eq!(DownloadTracker::from_seconds(52_292), (0, 14, 31, 32));

        assert_eq!(DownloadTracker::from_seconds(222_292), (2, 13, 44, 52));
    }

}
<commit_msg>Fix clippy: Disable warning many_single_char_names<commit_after>use crate::term2;
use rustup::dist::Notification as In;
use rustup::utils::tty;
use rustup::utils::Notification as Un;
use rustup::Notification;
use std::collections::VecDeque;
use std::fmt;
use std::io::Write;
use term::Terminal;
use time::precise_time_s;

/// Keep track of this many past download amounts
const DOWNLOAD_TRACK_COUNT: usize = 5;

/// Tracks download progress and displays information about it to a terminal.
pub struct DownloadTracker {
    /// Content-Length of the to-be downloaded object.
    content_len: Option<usize>,
    /// Total data downloaded in bytes.
    total_downloaded: usize,
    /// Data downloaded this second.
    downloaded_this_sec: usize,
    /// Keeps track of amount of data downloaded every last few secs.
    /// Used for averaging the download speed. NB: This does not necessarily
    /// represent adjacent seconds; thus it may not show the average at all.
    downloaded_last_few_secs: VecDeque<usize>,
    /// Time stamp of the last second
    last_sec: Option<f64>,
    /// Time stamp of the start of the download
    start_sec: f64,
    /// The terminal we write the information to.
    /// XXX: Could be a term trait, but with #1818 on the horizon that
    ///      is a pointless change to make - better to let that transition
    ///      happen and take stock after that.
    term: term2::StdoutTerminal,
    /// Whether we displayed progress for the download or not.
    ///
    /// If the download is quick enough, we don't have time to
    /// display the progress info.
    /// In that case, we do not want to do some cleanup stuff we normally do.
    ///
    /// If we have displayed progress, this is the number of characters we
    /// rendered, so we can erase it cleanly.
    displayed_charcount: Option<usize>,
    /// What units to show progress in
    units: Vec<String>,
}

impl DownloadTracker {
    /// Creates a new DownloadTracker.
    pub fn new() -> Self {
        DownloadTracker {
            content_len: None,
            total_downloaded: 0,
            downloaded_this_sec: 0,
            downloaded_last_few_secs: VecDeque::with_capacity(DOWNLOAD_TRACK_COUNT),
            start_sec: precise_time_s(),
            last_sec: None,
            term: term2::stdout(),
            displayed_charcount: None,
            units: vec!["B".into(); 1],
        }
    }

    pub fn handle_notification(&mut self, n: &Notification<'_>) -> bool {
        match *n {
            Notification::Install(In::Utils(Un::DownloadContentLengthReceived(content_len))) => {
                self.content_length_received(content_len);

                true
            }
            Notification::Install(In::Utils(Un::DownloadDataReceived(data))) => {
                if tty::stdout_isatty() {
                    self.data_received(data.len());
                }
                true
            }
            Notification::Install(In::Utils(Un::DownloadFinished)) => {
                self.download_finished();
                true
            }
            Notification::Install(In::Utils(Un::DownloadPushUnits(units))) => {
                self.push_units(units.into());
                true
            }
            Notification::Install(In::Utils(Un::DownloadPopUnits)) => {
                self.pop_units();
                true
            }

            _ => false,
        }
    }

    /// Notifies self that Content-Length information has been received.
    pub fn content_length_received(&mut self, content_len: u64) {
        self.content_len = Some(content_len as usize);
    }

    /// Notifies self that data of size `len` has been received.
    pub fn data_received(&mut self, len: usize) {
        self.total_downloaded += len;
        self.downloaded_this_sec += len;

        let current_time = precise_time_s();

        match self.last_sec {
            None => self.last_sec = Some(current_time),
            Some(prev) => {
                let elapsed = current_time - prev;
                if elapsed >= 1.0 {
                    self.display();
                    self.last_sec = Some(current_time);
                    if self.downloaded_last_few_secs.len() == DOWNLOAD_TRACK_COUNT {
                        self.downloaded_last_few_secs.pop_back();
                    }
                    self.downloaded_last_few_secs
                        .push_front(self.downloaded_this_sec);
                    self.downloaded_this_sec = 0;
                }
            }
        }
    }
    /// Notifies self that the download has finished.
    pub fn download_finished(&mut self) {
        if self.displayed_charcount.is_some() {
            // Display the finished state
            self.display();
            let _ = writeln!(self.term);
        }
        self.prepare_for_new_download();
    }
    // we're doing modular arithmetic, treat as integer
    pub fn from_seconds(sec: u32) -> (u32, u32, u32, u32) {
        let d = sec / (24 * 3600);
        let h = sec % (24 * 3600) / 3600;
        let min = sec % 3600 / 60;
        let sec = sec % 60;

        (d, h, min, sec)
    }
    /// Resets the state to be ready for a new download.
    fn prepare_for_new_download(&mut self) {
        self.content_len = None;
        self.total_downloaded = 0;
        self.downloaded_this_sec = 0;
        self.downloaded_last_few_secs.clear();
        self.start_sec = precise_time_s();
        self.last_sec = None;
        self.displayed_charcount = None;
    }
    /// Display the tracked download information to the terminal.
    fn display(&mut self) {
        // Panic if someone pops the default bytes unit...
        let units = &self.units.last().unwrap();
        let total_h = Size(self.total_downloaded, units);
        let sum: usize = self.downloaded_last_few_secs.iter().sum();
        let len = self.downloaded_last_few_secs.len();
        let speed = if len > 0 { sum / len } else { 0 };
        let speed_h = Size(speed, units);
        let elapsed_h = Duration(precise_time_s() - self.start_sec);

        // First, move to the start of the current line and clear it.
        let _ = self.term.carriage_return();
        // We'd prefer to use delete_line() but on Windows it seems to
        // sometimes do unusual things
        // let _ = self.term.as_mut().unwrap().delete_line();
        // So instead we do:
        if let Some(n) = self.displayed_charcount {
            // This is not ideal as very narrow terminals might mess up,
            // but it is more likely to succeed until term's windows console
            // fixes whatever's up with delete_line().
            let _ = write!(self.term, "{}", " ".repeat(n));
            let _ = self.term.flush();
            let _ = self.term.carriage_return();
        }

        let output = match self.content_len {
            Some(content_len) => {
                let content_len_h = Size(content_len, units);
                let content_len = content_len as f64;
                let percent = (self.total_downloaded as f64 / content_len) * 100.;
                let remaining = content_len - self.total_downloaded as f64;
                let eta_h = Duration(remaining / speed as f64);
                format!(
                    "{} / {} ({:3.0} %) {}/s in {} ETA: {}",
                    total_h, content_len_h, percent, speed_h, elapsed_h, eta_h
                )
            }
            None => format!(
                "Total: {} Speed: {}/s Elapsed: {}",
                total_h, speed_h, elapsed_h
            ),
        };

        let _ = write!(self.term, "{}", output);
        // Since stdout is typically line-buffered and we don't print a newline, we manually flush.
        let _ = self.term.flush();
        self.displayed_charcount = Some(output.chars().count());
    }

    pub fn push_units(&mut self, new_units: String) {
        self.units.push(new_units);
    }

    pub fn pop_units(&mut self) {
        self.units.pop();
    }
}

/// Human readable representation of duration(seconds).
struct Duration(f64);

impl fmt::Display for Duration {
    #[allow(clippy::many_single_char_names)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // repurposing the alternate mode for ETA
        let sec = self.0;

        if sec.is_infinite() {
            write!(f, "Unknown")
        } else {
            match DownloadTracker::from_seconds(sec as u32) {
                (d, h, m, s) if d > 0 => write!(f, "{:3.0}d {:2.0}h {:2.0}m {:2.0}s", d, h, m, s),
                (0, h, m, s) if h > 0 => write!(f, "{:2.0}h {:2.0}m {:2.0}s", h, m, s),
                (0, 0, m, s) if m > 0 => write!(f, "{:2.0}m {:2.0}s", m, s),
                (_, _, _, s) => write!(f, "{:2.0}s", s),
            }
        }
    }
}

/// Human readable size (some units)
struct Size<'a>(usize, &'a str);

impl<'a> fmt::Display for Size<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        const KI: f64 = 1024.0;
        const MI: f64 = KI * KI;
        let size = self.0 as f64;

        if size >= MI {
            write!(f, "{:5.1} Mi{}", size / MI, self.1) // XYZ.P Mi
        } else if size >= KI {
            write!(f, "{:5.1} Ki{}", size / KI, self.1)
        } else {
            write!(f, "{:3.0} {}", size, self.1)
        }
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn download_tracker_from_seconds_test() {
        use crate::download_tracker::DownloadTracker;
        assert_eq!(DownloadTracker::from_seconds(2), (0, 0, 0, 2));

        assert_eq!(DownloadTracker::from_seconds(60), (0, 0, 1, 0));

        assert_eq!(DownloadTracker::from_seconds(3_600), (0, 1, 0, 0));

        assert_eq!(DownloadTracker::from_seconds(3_600 * 24), (1, 0, 0, 0));

        assert_eq!(DownloadTracker::from_seconds(52_292), (0, 14, 31, 32));

        assert_eq!(DownloadTracker::from_seconds(222_292), (2, 13, 44, 52));
    }

}
<|endoftext|>


<commit_before>use ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods};
use ir::context::BindgenContext;
use ir::derive::CanTriviallyDeriveDebug;
use ir::item::{IsOpaque, Item, ItemCanonicalName};
use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
use syntax::ast;
use syntax::codemap::DUMMY_SP;
use syntax::parse::token::Token;

use syntax::tokenstream::TokenTree;

pub fn gen_debug_impl(
    ctx: &BindgenContext,
    fields: &[Field],
    item: &Item,
    kind: CompKind,
) -> Vec<ast::ImplItem> {
    let struct_name = item.canonical_name(ctx);
    let mut format_string = format!("{} {{{{ ", struct_name);
    let mut tokens: Vec<TokenTree> = Vec::new();

    if item.is_opaque(ctx, &()) {
        format_string.push_str("opaque");
    } else {
        match kind {
            CompKind::Union => {
                format_string.push_str("union");
            }
            CompKind::Struct => {
                let processed_fields = fields.iter().filter_map(|f| match f {
                    &Field::DataMember(ref fd) => {
                        gen_field_data_debug_impl(ctx, fd)
                    }
                    &Field::Bitfields(ref bu) => {
                        gen_bitfield_unit_debug_impl(ctx, bu)
                    }
                });

                for (i, (fstring, token)) in processed_fields.enumerate() {
                    if i > 0 {
                        format_string.push_str(", ");
                    }
                    if !token.is_empty() {
                        tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
                        tokens.extend(token);
                    }
                    format_string.push_str(&fstring);
                }
            }
        }
    }

    format_string.push_str(" }}");

    let impl_ = quote_item!(ctx.ext_cx(),
                            impl X {
                                fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                                    write!(f, $format_string $tokens)
                                }
                            });

    match impl_.unwrap().node {
        ast::ItemKind::Impl(_, _, _, _, _, ref items) => items.clone(),
        _ => unreachable!(),
    }
}

fn gen_field_data_debug_impl(
    ctx: &BindgenContext,
    data: &FieldData,
) -> Option<(String, Vec<TokenTree>)> {
    if let Some(name) = data.name() {
        gen_item_debug_impl(ctx, ctx.resolve_item(data.ty()), name)
    } else {
        None
    }
}

fn gen_bitfield_unit_debug_impl(
    ctx: &BindgenContext,
    data: &BitfieldUnit,
) -> Option<(String, Vec<TokenTree>)> {
    let mut format_string = String::new();
    let mut tokens = Vec::new();
    for (i, bu) in data.bitfields().iter().enumerate() {
        if i > 0 {
            format_string.push_str(", ");
            tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
        }
        format_string.push_str(&format!("{} : {{:?}}", bu.name()));
        let name_ident = ctx.rust_ident_raw(bu.name());
        tokens.extend(quote_tokens!(ctx.ext_cx(), self.$name_ident()));
    }

    Some((format_string, tokens))
}

fn gen_item_debug_impl(
    ctx: &BindgenContext,
    item: &Item,
    name: &str,
) -> Option<(String, Vec<TokenTree>)> {
    let name_ident = ctx.rust_ident_raw(name);

    let ty = match item.as_type() {
        Some(ty) => ty,
        None => {
            return None;
        }
    };

    fn debug_print(
        ctx: &BindgenContext,
        name: &str,
        name_ident: ast::Ident,
    ) -> Option<(String, Vec<TokenTree>)> {
        Some((
            format!("{}: {{:?}}", name),
            quote_tokens!(ctx.ext_cx(), self.$name_ident),
        ))
    }

    match *ty.kind() {
        // Handle the simple cases.
        TypeKind::Void |
        TypeKind::NullPtr |
        TypeKind::Int(..) |
        TypeKind::Float(..) |
        TypeKind::Complex(..) |
        TypeKind::Function(..) |
        TypeKind::Enum(..) |
        TypeKind::Reference(..) |
        TypeKind::BlockPointer |
        TypeKind::UnresolvedTypeRef(..) |
        TypeKind::ObjCInterface(..) |
        TypeKind::ObjCId |
        TypeKind::Comp(..) |
        TypeKind::ObjCSel => debug_print(ctx, name, name_ident),

        TypeKind::TemplateInstantiation(ref inst) => {
            if inst.is_opaque(ctx, item) {
                Some((format!("{}: opaque", name), vec![]))
            } else {
                debug_print(ctx, name, name_ident)
            }
        }

        // The generic is not required to implement Debug, so we can not debug print that type
        TypeKind::Named => {
            Some((format!("{}: Non-debuggable generic", name), vec![]))
        }

        TypeKind::Array(_, len) => {
            // Generics are not required to implement Debug
            if ctx.lookup_item_id_has_type_param_in_array(&item.id()) {
                Some((format!("{}: Array with length {}", name, len), vec![]))
            } else if len < RUST_DERIVE_IN_ARRAY_LIMIT {
                // The simple case
                debug_print(ctx, name, name_ident)
            } else {
                // Let's implement our own print function
                Some((
                    format!("{}: [{{}}]", name),
                    quote_tokens!(
                        ctx.ext_cx(),
                        self.$name_ident
                            .iter()
                            .enumerate()
                            .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
                            .collect::<String>()),
                ))
            }
        }

        TypeKind::ResolvedTypeRef(t) |
        TypeKind::TemplateAlias(t, _) |
        TypeKind::Alias(t) => {
            // We follow the aliases
            gen_item_debug_impl(ctx, ctx.resolve_item(t), name)
        }

        TypeKind::Pointer(inner) => {
            let inner_type = ctx.resolve_type(inner).canonical_type(ctx);
            match *inner_type.kind() {
                TypeKind::Function(ref sig)
                    if !sig.can_trivially_derive_debug() =>
                {
                    Some((format!("{}: FunctionPointer", name), vec![]))
                }
                _ => debug_print(ctx, name, name_ident),
            }
        }

        TypeKind::Opaque => None,
    }
}
<commit_msg>Adds ImplDebug trait for creating the Debug trait implementations<commit_after>use ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods};
use ir::context::BindgenContext;
use ir::derive::CanTriviallyDeriveDebug;
use ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName};
use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
use syntax::ast;
use syntax::codemap::DUMMY_SP;
use syntax::parse::token::Token;

use syntax::tokenstream::TokenTree;

pub fn gen_debug_impl(
    ctx: &BindgenContext,
    fields: &[Field],
    item: &Item,
    kind: CompKind,
) -> Vec<ast::ImplItem> {
    let struct_name = item.canonical_name(ctx);
    let mut format_string = format!("{} {{{{ ", struct_name);
    let mut tokens: Vec<TokenTree> = Vec::new();

    if item.is_opaque(ctx, &()) {
        format_string.push_str("opaque");
    } else {
        match kind {
            CompKind::Union => {
                format_string.push_str("union");
            }
            CompKind::Struct => {
                let processed_fields = fields.iter().filter_map(|f| match f {
                    &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()),
                    &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()),
                });

                for (i, (fstring, token)) in processed_fields.enumerate() {
                    if i > 0 {
                        format_string.push_str(", ");
                    }
                    if !token.is_empty() {
                        tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
                        tokens.extend(token);
                    }
                    format_string.push_str(&fstring);
                }
            }
        }
    }

    format_string.push_str(" }}");

    let impl_ = quote_item!(ctx.ext_cx(),
                            impl X {
                                fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                                    write!(f, $format_string $tokens)
                                }
                            });

    match impl_.unwrap().node {
        ast::ItemKind::Impl(_, _, _, _, _, ref items) => items.clone(),
        _ => unreachable!(),
    }
}

/// A trait for the things which we can codegen tokens that contribute towards a
/// generated `impl Debug`.
pub trait ImplDebug<'a> {
    /// Any extra parameter required by this a particular `ImplDebug` implementation.
    type Extra;

    /// Generate a format string snippet to be included in the larger `impl Debug`
    /// format string, and the code to get the format string's interpolation values.
    fn impl_debug(
        &self,
        ctx: &BindgenContext,
        extra: Self::Extra,
    ) -> Option<(String, Vec<TokenTree>)>;
}

impl<'a> ImplDebug<'a> for FieldData {
    type Extra = ();

    fn impl_debug(
        &self,
        ctx: &BindgenContext,
        _: Self::Extra,
    ) -> Option<(String, Vec<TokenTree>)> {
        if let Some(name) = self.name() {
            ctx.resolve_item(self.ty()).impl_debug(ctx, name)
        } else {
            None
        }
    }
}

impl<'a> ImplDebug<'a> for BitfieldUnit {
    type Extra = ();

    fn impl_debug(
        &self,
        ctx: &BindgenContext,
        _: Self::Extra,
    ) -> Option<(String, Vec<TokenTree>)> {
        let mut format_string = String::new();
        let mut tokens = Vec::new();
        for (i, bu) in self.bitfields().iter().enumerate() {
            if i > 0 {
                format_string.push_str(", ");
                tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
            }
            format_string.push_str(&format!("{} : {{:?}}", bu.name()));
            let name_ident = ctx.rust_ident_raw(bu.name());
            tokens.extend(quote_tokens!(ctx.ext_cx(), self.$name_ident()));
        }

        Some((format_string, tokens))
    }
}

impl<'a> ImplDebug<'a> for Item {
    type Extra = &'a str;

    fn impl_debug(
        &self,
        ctx: &BindgenContext,
        name: Self::Extra,
    ) -> Option<(String, Vec<TokenTree>)> {
        let name_ident = ctx.rust_ident_raw(name);

        let ty = match self.as_type() {
            Some(ty) => ty,
            None => {
                return None;
            }
        };

        fn debug_print(
            ctx: &BindgenContext,
            name: &str,
            name_ident: ast::Ident,
        ) -> Option<(String, Vec<TokenTree>)> {
            Some((
                format!("{}: {{:?}}", name),
                quote_tokens!(ctx.ext_cx(), self.$name_ident),
            ))
        }

        match *ty.kind() {
            // Handle the simple cases.
            TypeKind::Void |
            TypeKind::NullPtr |
            TypeKind::Int(..) |
            TypeKind::Float(..) |
            TypeKind::Complex(..) |
            TypeKind::Function(..) |
            TypeKind::Enum(..) |
            TypeKind::Reference(..) |
            TypeKind::BlockPointer |
            TypeKind::UnresolvedTypeRef(..) |
            TypeKind::ObjCInterface(..) |
            TypeKind::ObjCId |
            TypeKind::Comp(..) |
            TypeKind::ObjCSel => debug_print(ctx, name, name_ident),

            TypeKind::TemplateInstantiation(ref inst) => {
                if inst.is_opaque(ctx, self) {
                    Some((format!("{}: opaque", name), vec![]))
                } else {
                    debug_print(ctx, name, name_ident)
                }
            }

            // The generic is not required to implement Debug, so we can not debug print that type
            TypeKind::Named => {
                Some((format!("{}: Non-debuggable generic", name), vec![]))
            }

            TypeKind::Array(_, len) => {
                // Generics are not required to implement Debug
                if self.has_type_param_in_array(ctx) {
                    Some((
                        format!("{}: Array with length {}", name, len),
                        vec![],
                    ))
                } else if len < RUST_DERIVE_IN_ARRAY_LIMIT {
                    // The simple case
                    debug_print(ctx, name, name_ident)
                } else {
                    // Let's implement our own print function
                    Some((
                        format!("{}: [{{}}]", name),
                        quote_tokens!(
                        ctx.ext_cx(),
                        self.$name_ident
                            .iter()
                            .enumerate()
                            .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
                            .collect::<String>()),
                    ))
                }
            }

            TypeKind::ResolvedTypeRef(t) |
            TypeKind::TemplateAlias(t, _) |
            TypeKind::Alias(t) => {
                // We follow the aliases
                ctx.resolve_item(t).impl_debug(ctx, name)
            }

            TypeKind::Pointer(inner) => {
                let inner_type = ctx.resolve_type(inner).canonical_type(ctx);
                match *inner_type.kind() {
                    TypeKind::Function(ref sig)
                        if !sig.can_trivially_derive_debug() =>
                    {
                        Some((format!("{}: FunctionPointer", name), vec![]))
                    }
                    _ => debug_print(ctx, name, name_ident),
                }
            }

            TypeKind::Opaque => None,
        }
    }
}
<|endoftext|>


<commit_before>extern crate raft;
mod new;

use std::collections::HashSet;
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::mpsc;

use raft::Raft;
use raft::store::MemStore;
use raft::state_machine::ChannelStateMachine;

use new::new_cluster;

fn hello() {
    let mut nodes = new_cluster(3);
    let sent_command = b"Hello";
    // Push
    nodes[0].0.append(sent_command)
        .ok().expect("Couldn't append.");
    // Retrieve.
    let recieved_command = nodes[0].1.recv()
        .ok().expect("Couldn't recv.");
    assert_eq!(sent_command, recieved_command);
}
<commit_msg>Fix more warnings<commit_after>extern crate raft;
mod new;

use new::new_cluster;

#[test]
fn hello() {
    let mut nodes = new_cluster(3);
    let sent_command = b"Hello";
    // Push
    nodes[0].0.append(sent_command)
        .ok().expect("Couldn't append.");
    // Retrieve.
    let recieved_command = nodes[0].1.recv()
        .ok().expect("Couldn't recv.");
    assert_eq!(sent_command, recieved_command);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 University of Glasgow
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::io::Result;
use std::net::ToSocketAddrs;
use std::time::{Duration, Instant};

trait TimedDatagramProtocolSend {
  fn send_datagram<A : ToSocketAddrs>(&self, buf : &[u8], addr : A) -> Result<usize>;
  fn  start_timer(&self, timeout : Duration, id : u32);
  fn cancel_timer(&self, id : u32);
}

trait TimedDatagramProtocolRecv {
  fn recv_datagram<A : ToSocketAddrs>(&self, now : Instant, buf : &[u8], addr : A);
  fn timeout(&self, now : Instant, id : u32);
}

<commit_msg>Fix visibility<commit_after>// Copyright (c) 2016 University of Glasgow
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::io::Result;
use std::net::ToSocketAddrs;
use std::time::{Duration, Instant};

pub trait TimedDatagramProtocolSend {
  fn send_datagram<A : ToSocketAddrs>(&self, buf : &[u8], addr : A) -> Result<usize>;
  fn  start_timer(&self, timeout : Duration, id : u32);
  fn cancel_timer(&self, id : u32);
}

pub trait TimedDatagramProtocolRecv {
  fn recv_datagram<A : ToSocketAddrs>(&self, now : Instant, buf : &[u8], addr : A);
  fn timeout(&self, now : Instant, id : u32);
}

<|endoftext|>


<commit_before>extern crate serde;
#[macro_use] extern crate serde_derive;
extern crate serde_json;

use std::collections::HashMap;

/* Fields with a custom rename are for deserializing
 * the secifications json file in amq-protocol-codegen
 */
#[derive(Debug, Deserialize, Serialize)]
pub enum AMQPType {
    #[serde(rename="bit")]
    Boolean,
    #[serde(rename="octet")]
    ShortShortInt,
    ShortShortUInt,
    #[serde(rename="short")]
    ShortInt,
    ShortUInt,
    #[serde(rename="long")]
    LongInt,
    LongUInt,
    #[serde(rename="longlong")]
    LongLongInt,
    LongLongUInt,
    Float,
    Double,
    DecimalValue,
    #[serde(rename="shortstr")]
    ShortString,
    #[serde(rename="longstr")]
    LongString,
    FieldArray,
    #[serde(rename="timestamp")]
    TimeStamp,
    #[serde(rename="table")]
    FieldTable,
    Void,
}

impl AMQPType {
    pub fn from_id(id: char) -> AMQPType {
        match id {
            't' => AMQPType::Boolean,
            'b' => AMQPType::ShortShortInt,
            'B' => AMQPType::ShortShortUInt,
            'U' => AMQPType::ShortInt,
            'u' => AMQPType::ShortUInt,
            'I' => AMQPType::LongInt,
            'i' => AMQPType::LongUInt,
            'L' => AMQPType::LongLongInt,
            'l' => AMQPType::LongLongUInt,
            'f' => AMQPType::Float,
            'd' => AMQPType::Double,
            'D' => AMQPType::DecimalValue,
            's' => AMQPType::ShortString,
            'S' => AMQPType::LongString,
            'A' => AMQPType::FieldArray,
            'T' => AMQPType::TimeStamp,
            'F' => AMQPType::FieldTable,
            'V' => AMQPType::Void,
            _ => panic!("Unknown type id {}", id), /*FIXME: don't panic*/
        }
    }

    pub fn get_id(&self) -> char {
        match *self {
            AMQPType::Boolean => 't',
            AMQPType::ShortShortInt => 'b',
            AMQPType::ShortShortUInt => 'B',
            AMQPType::ShortInt => 'U',
            AMQPType::ShortUInt => 'u',
            AMQPType::LongInt => 'I',
            AMQPType::LongUInt => 'i',
            AMQPType::LongLongInt => 'L',
            AMQPType::LongLongUInt => 'l',
            AMQPType::Float => 'f',
            AMQPType::Double => 'd',
            AMQPType::DecimalValue => 'D',
            AMQPType::ShortString => 's',
            AMQPType::LongString => 'S',
            AMQPType::FieldArray => 'A',
            AMQPType::TimeStamp => 'T',
            AMQPType::FieldTable => 'F',
            AMQPType::Void => 'V',
        }
    }
}

pub type Boolean        = bool;
pub type ShortShortInt  = i8;
pub type ShortShortUInt = u8;
pub type ShortInt       = i16;
pub type ShortUInt      = u16;
pub type LongInt        = i32;
pub type LongUInt       = u32;
pub type LongLongInt    = i64;
pub type LongLongUInt   = u64;
pub type Float          = f32;
pub type Double         = f64;
pub type DecimalValue   = i64;    /* FIXME: find out what this is exactly */
pub type ShortString    = String; /* TODO: don't allow size >= 255 */
pub type LongString     = String;
pub type FieldArray     = Vec<AMQPValue>;
pub type TimeStamp      = u64;
pub type FieldTable     = HashMap<String, AMQPValue>;
pub type Void           = ();

pub enum AMQPValue {
    Boolean(Boolean),
    ShortShortInt(ShortShortInt),
    ShortShortUInt(ShortShortUInt),
    ShortInt(ShortInt),
    ShortUInt(ShortUInt),
    LongInt(LongInt),
    LongUInt(LongUInt),
    LongLongInt(LongLongInt),
    LongLongUInt(LongLongUInt),
    Float(Float),
    Double(Double),
    DecimalValue(DecimalValue),
    ShortString(ShortString),
    LongString(LongString),
    FieldArray(FieldArray),
    TimeStamp(TimeStamp),
    FieldTable(FieldTable),
    Void(Void),
}
<commit_msg>types: add to_string()<commit_after>extern crate serde;
#[macro_use] extern crate serde_derive;
extern crate serde_json;

use std::collections::HashMap;

/* Fields with a custom rename are for deserializing
 * the secifications json file in amq-protocol-codegen
 */
#[derive(Debug, Deserialize, Serialize)]
pub enum AMQPType {
    #[serde(rename="bit")]
    Boolean,
    #[serde(rename="octet")]
    ShortShortInt,
    ShortShortUInt,
    #[serde(rename="short")]
    ShortInt,
    ShortUInt,
    #[serde(rename="long")]
    LongInt,
    LongUInt,
    #[serde(rename="longlong")]
    LongLongInt,
    LongLongUInt,
    Float,
    Double,
    DecimalValue,
    #[serde(rename="shortstr")]
    ShortString,
    #[serde(rename="longstr")]
    LongString,
    FieldArray,
    #[serde(rename="timestamp")]
    TimeStamp,
    #[serde(rename="table")]
    FieldTable,
    Void,
}

impl AMQPType {
    pub fn from_id(id: char) -> AMQPType {
        match id {
            't' => AMQPType::Boolean,
            'b' => AMQPType::ShortShortInt,
            'B' => AMQPType::ShortShortUInt,
            'U' => AMQPType::ShortInt,
            'u' => AMQPType::ShortUInt,
            'I' => AMQPType::LongInt,
            'i' => AMQPType::LongUInt,
            'L' => AMQPType::LongLongInt,
            'l' => AMQPType::LongLongUInt,
            'f' => AMQPType::Float,
            'd' => AMQPType::Double,
            'D' => AMQPType::DecimalValue,
            's' => AMQPType::ShortString,
            'S' => AMQPType::LongString,
            'A' => AMQPType::FieldArray,
            'T' => AMQPType::TimeStamp,
            'F' => AMQPType::FieldTable,
            'V' => AMQPType::Void,
            _ => panic!("Unknown type id {}", id), /*FIXME: don't panic*/
        }
    }

    pub fn get_id(&self) -> char {
        match *self {
            AMQPType::Boolean => 't',
            AMQPType::ShortShortInt => 'b',
            AMQPType::ShortShortUInt => 'B',
            AMQPType::ShortInt => 'U',
            AMQPType::ShortUInt => 'u',
            AMQPType::LongInt => 'I',
            AMQPType::LongUInt => 'i',
            AMQPType::LongLongInt => 'L',
            AMQPType::LongLongUInt => 'l',
            AMQPType::Float => 'f',
            AMQPType::Double => 'd',
            AMQPType::DecimalValue => 'D',
            AMQPType::ShortString => 's',
            AMQPType::LongString => 'S',
            AMQPType::FieldArray => 'A',
            AMQPType::TimeStamp => 'T',
            AMQPType::FieldTable => 'F',
            AMQPType::Void => 'V',
        }
    }

    pub fn to_string(&self) -> String {
        format!("{:?}", self)
    }
}

pub type Boolean        = bool;
pub type ShortShortInt  = i8;
pub type ShortShortUInt = u8;
pub type ShortInt       = i16;
pub type ShortUInt      = u16;
pub type LongInt        = i32;
pub type LongUInt       = u32;
pub type LongLongInt    = i64;
pub type LongLongUInt   = u64;
pub type Float          = f32;
pub type Double         = f64;
pub type DecimalValue   = i64;    /* FIXME: find out what this is exactly */
pub type ShortString    = String; /* TODO: don't allow size >= 255 */
pub type LongString     = String;
pub type FieldArray     = Vec<AMQPValue>;
pub type TimeStamp      = u64;
pub type FieldTable     = HashMap<String, AMQPValue>;
pub type Void           = ();

pub enum AMQPValue {
    Boolean(Boolean),
    ShortShortInt(ShortShortInt),
    ShortShortUInt(ShortShortUInt),
    ShortInt(ShortInt),
    ShortUInt(ShortUInt),
    LongInt(LongInt),
    LongUInt(LongUInt),
    LongLongInt(LongLongInt),
    LongLongUInt(LongLongUInt),
    Float(Float),
    Double(Double),
    DecimalValue(DecimalValue),
    ShortString(ShortString),
    LongString(LongString),
    FieldArray(FieldArray),
    TimeStamp(TimeStamp),
    FieldTable(FieldTable),
    Void(Void),
}
<|endoftext|>


<commit_before>//! The [glyph-definition table][1].
//!
//! [1]: https://www.microsoft.com/typography/otspec/GDEF.htm

use truetype::{Result, Tape, Value};

use layout::Class;

mod element;

pub use self::element::*;

table! {
    @position
    #[doc = "A glyph-definition table."]
    pub GlyphDefinition {
        header (Header),

        glyph_class (Option<Class>) |this, tape, position| {
            jump_take_maybe!(tape, position, match this.header {
                Header::Version1(ref header) => header.glyph_class_offset,
                Header::Version12(ref header) => header.glyph_class_offset,
                Header::Version13(ref header) => header.glyph_class_offset,
            })
        },

        attachments (Option<Attachments>) |this, tape, position| {
            jump_take_maybe!(tape, position, match this.header {
                Header::Version1(ref header) => header.attachments_offset,
                Header::Version12(ref header) => header.attachments_offset,
                Header::Version13(ref header) => header.attachments_offset,
            })
        },

        ligatures (Option<Ligatures>) |this, tape, position| {
            jump_take_maybe!(tape, position, match this.header {
                Header::Version1(ref header) => header.ligatures_offset,
                Header::Version12(ref header) => header.ligatures_offset,
                Header::Version13(ref header) => header.ligatures_offset,
            })
        },

        mark_class (Option<Class>) |this, tape, position| {
            jump_take_maybe!(tape, position, match this.header {
                Header::Version1(ref header) => header.mark_class_offset,
                Header::Version12(ref header) => header.mark_class_offset,
                Header::Version13(ref header) => header.mark_class_offset,
            })
        },

        marks (Option<Marks>) |this, tape, position| {
            jump_take_maybe!(tape, position, match this.header {
                Header::Version12(ref header) => header.marks_offset,
                Header::Version13(ref header) => header.marks_offset,
                _ => 0,
            })
        },
    }
}

/// The header of a glyph-definition table.
#[derive(Clone, Debug)]
pub enum Header {
    /// Version 1.0.
    Version1(Header1),
    /// Version 1.2.
    Version12(Header12),
    /// Version 1.3.
    Version13(Header13),
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.0."]
    #[derive(Copy)]
    pub Header1 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 0 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
    }
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.2."]
    #[derive(Copy)]
    pub Header12 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 2 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
        marks_offset       (u16), // MarkGlyphSetsDef
    }
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.3."]
    #[derive(Copy)]
    pub Header13 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 3 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
        marks_offset       (u16), // MarkGlyphSetsDef
        variations_offset  (u32), // ItemVarStore
    }
}

impl Value for Header {
    fn read<T: Tape>(tape: &mut T) -> Result<Self> {
        Ok(match try!(tape.peek::<u32>()) {
            0x00010000 => Header::Version1(try!(tape.take())),
            0x00010002 => Header::Version12(try!(tape.take())),
            0x00010003 => Header::Version13(try!(tape.take())),
            _ => raise!("found an unknown format of the glyph-definition table"),
        })
    }
}
<commit_msg>Refactor the parsing of GlyphDefinition<commit_after>//! The [glyph-definition table][1].
//!
//! [1]: https://www.microsoft.com/typography/otspec/GDEF.htm

use truetype::{Result, Tape, Value};

use layout::Class;

mod element;

pub use self::element::*;

macro_rules! field(
    ($table:expr => $field:ident, $enumeration:ident::{$($variant:ident),*}) => (
        match $table {
            $($enumeration::$variant(ref table) => table.$field,)*
        }
    );
    ($table:expr => $field:ident($default:expr), $enumeration:ident::{$($variant:ident),*}) => (
        match $table {
            $($enumeration::$variant(ref table) => table.$field,)*
            _ => $default,
        }
    );
);

table! {
    @position
    #[doc = "A glyph-definition table."]
    pub GlyphDefinition {
        header (Header),

        glyph_class (Option<Class>) |this, tape, position| {
            jump_take_maybe!(tape, position, field!(this.header => glyph_class_offset,
                                                    Header::{Version1, Version12, Version13}))
        },

        attachments (Option<Attachments>) |this, tape, position| {
            jump_take_maybe!(tape, position, field!(this.header => attachments_offset,
                                                    Header::{Version1, Version12, Version13}))
        },

        ligatures (Option<Ligatures>) |this, tape, position| {
            jump_take_maybe!(tape, position, field!(this.header => ligatures_offset,
                                                    Header::{Version1, Version12, Version13}))
        },

        mark_class (Option<Class>) |this, tape, position| {
            jump_take_maybe!(tape, position, field!(this.header => mark_class_offset,
                                                    Header::{Version1, Version12, Version13}))
        },

        marks (Option<Marks>) |this, tape, position| {
            jump_take_maybe!(tape, position, field!(this.header => marks_offset(0),
                                                    Header::{Version12, Version13}))
        },
    }
}

/// The header of a glyph-definition table.
#[derive(Clone, Debug)]
pub enum Header {
    /// Version 1.0.
    Version1(Header1),
    /// Version 1.2.
    Version12(Header12),
    /// Version 1.3.
    Version13(Header13),
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.0."]
    #[derive(Copy)]
    pub Header1 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 0 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
    }
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.2."]
    #[derive(Copy)]
    pub Header12 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 2 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
        marks_offset       (u16), // MarkGlyphSetsDef
    }
}

table! {
    #[doc = "The header of a glyph-definition table of version 1.3."]
    #[derive(Copy)]
    pub Header13 {
        major_version      (u16) = { 1 }, // MajorVersion
        minor_version      (u16) = { 3 }, // MinorVersion
        glyph_class_offset (u16), // GlyphClassDef
        attachments_offset (u16), // AttachList
        ligatures_offset   (u16), // LigCaretList
        mark_class_offset  (u16), // MarkAttachClassDef
        marks_offset       (u16), // MarkGlyphSetsDef
        variations_offset  (u32), // ItemVarStore
    }
}

impl Value for Header {
    fn read<T: Tape>(tape: &mut T) -> Result<Self> {
        Ok(match try!(tape.peek::<u32>()) {
            0x00010000 => Header::Version1(try!(tape.take())),
            0x00010002 => Header::Version12(try!(tape.take())),
            0x00010003 => Header::Version13(try!(tape.take())),
            _ => raise!("found an unknown format of the glyph-definition table"),
        })
    }
}
<|endoftext|>


<commit_before>use header::{Header, HeaderFormat};
use std::fmt;
use std::str::from_utf8;

use cookie::Cookie as CookiePair;
use cookie::CookieJar;

/// The `Cookie` header. Defined in [RFC6265](tools.ietf.org/html/rfc6265#section-5.4):
///
/// > If the user agent does attach a Cookie header field to an HTTP
/// > request, the user agent must send the cookie-string
/// > as the value of the header field.
///
/// > When the user agent generates an HTTP request, the user agent MUST NOT
/// > attach more than one Cookie header field.
#[derive(Clone, PartialEq, Debug)]
pub struct Cookie(pub Vec<CookiePair>);

deref!(Cookie => Vec<CookiePair>);

impl Header for Cookie {
    fn header_name() -> &'static str {
        "Cookie"
    }

    fn parse_header(raw: &[Vec<u8>]) -> Option<Cookie> {
        let mut cookies = Vec::with_capacity(raw.len());
        for cookies_raw in raw.iter() {
            match from_utf8(&cookies_raw[..]) {
                Ok(cookies_str) => {
                    for cookie_str in cookies_str.split(';') {
                        match cookie_str.trim().parse() {
                            Ok(cookie) => cookies.push(cookie),
                            Err(_) => return None
                        }
                    }
                },
                Err(_) => return None
            };
        }

        if !cookies.is_empty() {
            Some(Cookie(cookies))
        } else {
            None
        }
    }
}

impl HeaderFormat for Cookie {
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let cookies = &self.0;
        let last = cookies.len() - 1;
        for (i, cookie) in cookies.iter().enumerate() {
            try!(write!(fmt, "{}", cookie.pair()));
            if i < last {
                try!(fmt.write_str("; "));
            }
        }
        Ok(())
    }
}

impl Cookie {
    /// This method can be used to create CookieJar that can be used
    /// to manipulate cookies and create a corresponding `SetCookie` header afterwards.
    pub fn to_cookie_jar(&self, key: &[u8]) -> CookieJar<'static> {
        let mut jar = CookieJar::new(key);
        for cookie in self.iter() {
            jar.add_original(cookie.clone());
        }
        jar
    }

    /// Extracts all cookies from `CookieJar` and creates Cookie header.
    /// Useful for clients.
    pub fn from_cookie_jar(jar: &CookieJar) -> Cookie {
        Cookie(jar.iter().collect())
    }
}

#[test]
fn test_parse() {
    let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][..]);
    let c1 = CookiePair::new("foo".to_string(), "bar".to_string());
    let c2 = CookiePair::new("baz".to_string(), "quux".to_string());
    assert_eq!(h, Some(Cookie(vec![c1, c2])));
}

#[test]
fn test_fmt() {
    use header::Headers;

    let mut cookie_pair = CookiePair::new("foo".to_string(), "bar".to_string());
    cookie_pair.httponly = true;
    cookie_pair.path = Some("/p".to_string());
    let cookie_header = Cookie(vec![cookie_pair, CookiePair::new("baz".to_string(), "quux".to_string())]);
    let mut headers = Headers::new();
    headers.set(cookie_header);

    assert_eq!(&headers.to_string()[..], "Cookie: foo=bar; baz=quux\r\n");
}

#[test]
fn cookie_jar() {
    let cookie_pair = CookiePair::new("foo".to_string(), "bar".to_string());
    let cookie_header = Cookie(vec![cookie_pair]);
    let jar = cookie_header.to_cookie_jar(&[]);
    let new_cookie_header = Cookie::from_cookie_jar(&jar);

    assert_eq!(cookie_header, new_cookie_header);
}

bench_header!(bench, Cookie, { vec![b"foo=bar; baz=quux".to_vec()] });
<commit_msg>fix(headers): Fix overflow with empty cookies<commit_after>use header::{Header, HeaderFormat};
use std::fmt;
use std::str::from_utf8;

use cookie::Cookie as CookiePair;
use cookie::CookieJar;

/// The `Cookie` header. Defined in [RFC6265](tools.ietf.org/html/rfc6265#section-5.4):
///
/// > If the user agent does attach a Cookie header field to an HTTP
/// > request, the user agent must send the cookie-string
/// > as the value of the header field.
///
/// > When the user agent generates an HTTP request, the user agent MUST NOT
/// > attach more than one Cookie header field.
#[derive(Clone, PartialEq, Debug)]
pub struct Cookie(pub Vec<CookiePair>);

deref!(Cookie => Vec<CookiePair>);

impl Header for Cookie {
    fn header_name() -> &'static str {
        "Cookie"
    }

    fn parse_header(raw: &[Vec<u8>]) -> Option<Cookie> {
        let mut cookies = Vec::with_capacity(raw.len());
        for cookies_raw in raw.iter() {
            match from_utf8(&cookies_raw[..]) {
                Ok(cookies_str) => {
                    for cookie_str in cookies_str.split(';') {
                        match cookie_str.trim().parse() {
                            Ok(cookie) => cookies.push(cookie),
                            Err(_) => return None
                        }
                    }
                },
                Err(_) => return None
            };
        }

        if !cookies.is_empty() {
            Some(Cookie(cookies))
        } else {
            None
        }
    }
}

impl HeaderFormat for Cookie {
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let cookies = &self.0;
        for (i, cookie) in cookies.iter().enumerate() {
            if i != 0 {
                try!(fmt.write_str("; "));
            }
            try!(write!(fmt, "{}", cookie.pair()));
        }
        Ok(())
    }
}

impl Cookie {
    /// This method can be used to create CookieJar that can be used
    /// to manipulate cookies and create a corresponding `SetCookie` header afterwards.
    pub fn to_cookie_jar(&self, key: &[u8]) -> CookieJar<'static> {
        let mut jar = CookieJar::new(key);
        for cookie in self.iter() {
            jar.add_original(cookie.clone());
        }
        jar
    }

    /// Extracts all cookies from `CookieJar` and creates Cookie header.
    /// Useful for clients.
    pub fn from_cookie_jar(jar: &CookieJar) -> Cookie {
        Cookie(jar.iter().collect())
    }
}

#[test]
fn test_parse() {
    let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][..]);
    let c1 = CookiePair::new("foo".to_string(), "bar".to_string());
    let c2 = CookiePair::new("baz".to_string(), "quux".to_string());
    assert_eq!(h, Some(Cookie(vec![c1, c2])));
}

#[test]
fn test_fmt() {
    use header::Headers;

    let mut cookie_pair = CookiePair::new("foo".to_string(), "bar".to_string());
    cookie_pair.httponly = true;
    cookie_pair.path = Some("/p".to_string());
    let cookie_header = Cookie(vec![cookie_pair, CookiePair::new("baz".to_string(), "quux".to_string())]);
    let mut headers = Headers::new();
    headers.set(cookie_header);

    assert_eq!(&headers.to_string()[..], "Cookie: foo=bar; baz=quux\r\n");
}

#[test]
fn cookie_jar() {
    let cookie_pair = CookiePair::new("foo".to_string(), "bar".to_string());
    let cookie_header = Cookie(vec![cookie_pair]);
    let jar = cookie_header.to_cookie_jar(&[]);
    let new_cookie_header = Cookie::from_cookie_jar(&jar);

    assert_eq!(cookie_header, new_cookie_header);
}

bench_header!(bench, Cookie, { vec![b"foo=bar; baz=quux".to_vec()] });
<|endoftext|>


<commit_before>extern crate gcc;
extern crate pkg_config;

use std::env;

fn main() {
    match pkg_config::find_library("mad") {
        Ok(_) => return,
        Err(..) => {}
    };

    let target = env::var("TARGET").unwrap();
    let fpm = if target.contains("i686") {
        "FPM_INTEL"
    } else if target.contains("x86_64") {
        "FPM_64BIT"
    } else if target.contains("arm") {
        "FPM_ARM"
    } else if target.contains("mips") {
        "FPM_MIPS"
    } else if target.contains("sparc") {
        "FPM_SPARC"
    } else if target.contains("ppc") || target.contains("powerpc") {
        "FPM_PPC"
    } else {
        "FPM_DEFAULT"
    };

    gcc::Config::new()
                .include("libmad-src")
                .define(&fpm, None)
                .file("libmad-src/version.c")
                .file("libmad-src/fixed.c")
                .file("libmad-src/bit.c")
                .file("libmad-src/timer.c")
                .file("libmad-src/stream.c")
                .file("libmad-src/frame.c")
                .file("libmad-src/synth.c")
                .file("libmad-src/decoder.c")
                .file("libmad-src/layer12.c")
                .file("libmad-src/layer3.c")
                .file("libmad-src/huffman.c")
                .compile("libmad.a");  // the official name is `libmad.la` but gcc-rs forbids that
}
<commit_msg>Add architecture specific optimizations<commit_after>extern crate gcc;
extern crate pkg_config;

use std::env;

fn main() {
    match pkg_config::find_library("mad") {
        Ok(_) => return,
        Err(..) => {}
    };

    // attempt to compile libmad manually
    let mut gcc = gcc::Config::new();
    gcc.include("libmad-src");

    let target = env::var("TARGET").unwrap();

    if target.contains("i686") {
        gcc.define("FPM_INTEL", None);
        gcc.define("ASO_ZEROCHECK", None);

    } else if target.contains("x86_64") {
        gcc.define("FPM_64BIT", None);

    } else if target.contains("arm") {
        gcc.define("FPM_ARM", None);
        // TODO: I'm not sure if compiling assembly works
        //gcc.define("ASO_INTERLEAVE1", None);
        //gcc.define("ASO_IMDCT", None);
        //gcc.file("libmad-src/imdct_l_arm.S");

    } else if target.contains("mips") {
        gcc.define("FPM_MIPS", None);
        gcc.define("ASO_INTERLEAVE2", None);
        gcc.define("ASO_ZEROCHECK", None);

    } else if target.contains("sparc") {
        gcc.define("FPM_SPARC", None);

    } else if target.contains("ppc") || target.contains("powerpc") {
        gcc.define("FPM_PPC", None);

    } else {
        gcc.define("FPM_DEFAULT", None);
    };

    gcc.file("libmad-src/version.c")
       .file("libmad-src/fixed.c")
       .file("libmad-src/bit.c")
       .file("libmad-src/timer.c")
       .file("libmad-src/stream.c")
       .file("libmad-src/frame.c")
       .file("libmad-src/synth.c")
       .file("libmad-src/decoder.c")
       .file("libmad-src/layer12.c")
       .file("libmad-src/layer3.c")
       .file("libmad-src/huffman.c")
       .compile("libmad.a");  // the official name is `libmad.la` but gcc-rs forbids that
}
<|endoftext|>


<commit_before><commit_msg>Replace wrapping shl/shr with regular <</>><commit_after><|endoftext|>


<commit_before>use protobuf::well_known_types::*;

use protobuf_test_common::*;

use super::test_fmt_json_well_known_pb::*;

#[test]
fn test_duration() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    let mut d = Duration::new();
    d.set_seconds(1);
    d.set_nanos(340012);
    m.set_duration(d);
    test_json_print_parse_message("{duration: \"1.000340012s\"}", &m);

    let mut m = TestFmtJsonWellKnownTypes::new();
    let mut d = Duration::new();
    d.set_seconds(1);
    m.set_duration(d);
    test_json_parse_message("{duration: \"1s\"}", &m);
}

#[test]
fn test_null_value() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.set_null_values(vec![NullValue::NULL_VALUE]);
    test_json_print_parse_message("{nullValues: [null]}", &m);
}

#[test]
fn test_value() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_value().set_bool_value(true);
    test_json_print_parse_message("{value: true}", &m);
    m.mut_value().set_number_value(12.0);
    test_json_print_parse_message("{value: 12.0}", &m);
    m.mut_value().set_string_value("ab".to_owned());
    test_json_print_parse_message("{value: \"ab\"}", &m);
    m.mut_value().set_null_value(NullValue::NULL_VALUE);
    test_json_print_parse_message("{value: null}", &m);
    // TODO: list
    // TODO: struct
}

#[test]
fn test_wrappers() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_double_value().value = 10.0;
    test_json_print_parse_message("{doubleValue: 10.0}", &m);
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_float_value().value = 12.0;
    test_json_print_parse_message("{floatValue: 12.0}", &m);

    // TODO
    // int64_value
    // uint64_value
    // int32_value
    // uint32_value
    // bool_value
    // string_value
    // bytes_value
}
<commit_msg>TODO well known types JSON<commit_after>use protobuf::well_known_types::*;

use protobuf_test_common::*;

use super::test_fmt_json_well_known_pb::*;

#[test]
fn test_duration() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    let mut d = Duration::new();
    d.set_seconds(1);
    d.set_nanos(340012);
    m.set_duration(d);
    test_json_print_parse_message("{duration: \"1.000340012s\"}", &m);

    let mut m = TestFmtJsonWellKnownTypes::new();
    let mut d = Duration::new();
    d.set_seconds(1);
    m.set_duration(d);
    test_json_parse_message("{duration: \"1s\"}", &m);
}

#[test]
fn test_timestamp() {
    // TODO
}

#[test]
fn test_null_value() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.set_null_values(vec![NullValue::NULL_VALUE]);
    test_json_print_parse_message("{nullValues: [null]}", &m);
}

#[test]
fn test_value() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_value().set_bool_value(true);
    test_json_print_parse_message("{value: true}", &m);
    m.mut_value().set_number_value(12.0);
    test_json_print_parse_message("{value: 12.0}", &m);
    m.mut_value().set_string_value("ab".to_owned());
    test_json_print_parse_message("{value: \"ab\"}", &m);
    m.mut_value().set_null_value(NullValue::NULL_VALUE);
    test_json_print_parse_message("{value: null}", &m);
    // TODO: list
    // TODO: struct
}

#[test]
fn test_list_value() {
    // TODO
}

#[test]
fn test_struct() {
    // TODO
}

#[test]
fn test_wrappers() {
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_double_value().value = 10.0;
    test_json_print_parse_message("{doubleValue: 10.0}", &m);
    let mut m = TestFmtJsonWellKnownTypes::new();
    m.mut_float_value().value = 12.0;
    test_json_print_parse_message("{floatValue: 12.0}", &m);

    // TODO
    // int64_value
    // uint64_value
    // int32_value
    // uint32_value
    // bool_value
    // string_value
    // bytes_value
}

#[test]
fn test_any() {
    // TODO
}

#[test]
fn test_field_mask() {
    // TODO
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]
#![feature(cell_update)]
#![feature(copied)]
#![feature(core_private_bignum)]
#![feature(core_private_diy_float)]
#![feature(dec2flt)]
#![feature(euclidean_division)]
#![feature(exact_size_is_empty)]
#![feature(fixed_size_array)]
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(hashmap_internals)]
#![feature(is_sorted)]
#![feature(iter_copied)]
#![feature(iter_nth_back)]
#![feature(iter_once_with)]
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]
#![feature(refcell_map_split)]
#![feature(refcell_replace_swap)]
#![feature(slice_patterns)]
#![feature(sort_internals)]
#![feature(specialization)]
#![feature(step_trait)]
#![feature(str_internals)]
#![feature(test)]
#![feature(trusted_len)]
#![feature(try_from)]
#![feature(try_trait)]
#![feature(align_offset)]
#![feature(reverse_bits)]
#![feature(inner_deref)]
#![feature(slice_internals)]
#![feature(slice_partition_dedup)]
#![feature(copy_within)]

extern crate core;
extern crate test;
extern crate rand;

mod any;
mod array;
mod ascii;
mod atomic;
mod cell;
mod char;
mod clone;
mod cmp;
mod fmt;
mod hash;
mod intrinsics;
mod iter;
mod manually_drop;
mod mem;
mod nonzero;
mod num;
mod ops;
mod option;
mod pattern;
mod ptr;
mod result;
mod slice;
mod str;
mod str_lossy;
mod time;
mod tuple;
<commit_msg>add feature flag to test<commit_after>#![feature(box_syntax)]
#![feature(cell_update)]
#![feature(copied)]
#![feature(core_private_bignum)]
#![feature(core_private_diy_float)]
#![feature(dec2flt)]
#![feature(euclidean_division)]
#![feature(exact_size_is_empty)]
#![feature(fixed_size_array)]
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(hashmap_internals)]
#![feature(is_sorted)]
#![feature(iter_copied)]
#![feature(iter_nth_back)]
#![feature(iter_once_with)]
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]
#![feature(refcell_map_split)]
#![feature(refcell_replace_swap)]
#![feature(slice_patterns)]
#![feature(sort_internals)]
#![feature(specialization)]
#![feature(step_trait)]
#![feature(str_internals)]
#![feature(test)]
#![feature(trusted_len)]
#![feature(try_from)]
#![feature(try_trait)]
#![feature(align_offset)]
#![feature(reverse_bits)]
#![feature(inner_deref)]
#![feature(slice_internals)]
#![feature(slice_partition_dedup)]
#![feature(copy_within)]
#![feature(int_error_matching)]

extern crate core;
extern crate test;
extern crate rand;

mod any;
mod array;
mod ascii;
mod atomic;
mod cell;
mod char;
mod clone;
mod cmp;
mod fmt;
mod hash;
mod intrinsics;
mod iter;
mod manually_drop;
mod mem;
mod nonzero;
mod num;
mod ops;
mod option;
mod pattern;
mod ptr;
mod result;
mod slice;
mod str;
mod str_lossy;
mod time;
mod tuple;
<|endoftext|>


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

//! iOS-specific raw type definitions

use os::raw::c_long;
use os::unix::raw::{uid_t, gid_t, pid_t};

pub type blkcnt_t = i64;
pub type blksize_t = i32;
pub type dev_t = i32;
pub type ino_t = u64;
pub type mode_t = u16;
pub type nlink_t = u16;
pub type off_t = i64;
pub type time_t = c_long;

#[repr(C)]
pub struct stat {
    pub st_dev: dev_t,
    pub st_mode: mode_t,
    pub st_nlink: nlink_t,
    pub st_ino: ino_t,
    pub st_uid: uid_t,
    pub st_gid: gid_t,
    pub st_rdev: dev_t,
    pub st_atime: time_t,
    pub st_atime_nsec: c_long,
    pub st_mtime: time_t,
    pub st_mtime_nsec: c_long,
    pub st_ctime: time_t,
    pub st_ctime_nsec: c_long,
    pub st_birthtime: time_t,
    pub st_birthtime_nsec: c_long,
    pub st_size: off_t,
    pub st_blocks: blkcnt_t,
    pub st_blksize: blksize_t,
    pub st_flags: u32,
    pub st_gen: u32,
    pub st_lspare: i32,
    pub st_qspare: [i64; 2],
}
<commit_msg>Rollup merge of #24983 - vhbit:ios-raw, r=sanxiyn<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! iOS-specific raw type definitions

use os::raw::c_long;
use os::unix::raw::{uid_t, gid_t};

pub type blkcnt_t = i64;
pub type blksize_t = i32;
pub type dev_t = i32;
pub type ino_t = u64;
pub type mode_t = u16;
pub type nlink_t = u16;
pub type off_t = i64;
pub type time_t = c_long;

#[repr(C)]
pub struct stat {
    pub st_dev: dev_t,
    pub st_mode: mode_t,
    pub st_nlink: nlink_t,
    pub st_ino: ino_t,
    pub st_uid: uid_t,
    pub st_gid: gid_t,
    pub st_rdev: dev_t,
    pub st_atime: time_t,
    pub st_atime_nsec: c_long,
    pub st_mtime: time_t,
    pub st_mtime_nsec: c_long,
    pub st_ctime: time_t,
    pub st_ctime_nsec: c_long,
    pub st_birthtime: time_t,
    pub st_birthtime_nsec: c_long,
    pub st_size: off_t,
    pub st_blocks: blkcnt_t,
    pub st_blksize: blksize_t,
    pub st_flags: u32,
    pub st_gen: u32,
    pub st_lspare: i32,
    pub st_qspare: [i64; 2],
}
<|endoftext|>