<commit_before>#![feature(type_ascription)]
#![allow(dead_code)]
#![allow(private_in_public)]

extern crate libc;

#[doc(hidden)]
#[macro_export]
macro_rules! counter {
    ($arg:expr) => {{
        1
    }};
    ($arg:expr, $arg2:expr) => {{
        2
    }};
    ($arg:expr, $arg2:expr, $($args:expr),*) => {{
        counter!($($args),*) + 2
    }};
    ($arg:expr, $($args:expr),*) => {{
        counter!($($args),*) + 1
    }}
}

/// This macro is the only thing provided by this crate.
///
/// ## Arguments
///
/// It expects a closure as first argument and then the arguments
/// that'll be used to build the `va_list`.
///
/// ## Example
///
/// ```ignore
/// to_va_list!(|v: va_list::va_list| {
///     vprintf(b"%d %d %s %f\n\0".as_ptr() as *const c_char, v);
/// },
/// 1, 2, b"salut!\0".as_ptr(), 32f32 as c_double);
/// ```
///
/// ## Warning
///
/// It might exist a limit to the number of arguments you can actually pass.
/// A big one, but don't try to send thousands of them at once.
#[macro_export]
macro_rules! to_va_list {
    ($func:expr, $($args:expr),*) => {{
        unsafe extern "C" fn call_func(f: *mut libc::c_void, ap: $crate::va_list) {
            let f: &Box<Fn($crate::va_list) + 'static> = std::mem::transmute(f);
            f(ap);
        }

        #[repr(C)]
        pub struct Wrap {
            pub f: extern "C" fn(*mut libc::c_void, $crate::va_list),
            pub c: *mut libc::c_void,
            pub len: c_uint,
        }

        extern "C" {
            fn create_va_list(w: *mut Wrap, ...);
        }

        unsafe {
            let fu = $func;
            let wrap = Wrap {
                f: std::mem::transmute(call_func as usize),
                c: $crate::convert_closure(fu),
                len: counter!($($args),*),
            };
            create_va_list(Box::into_raw(Box::new(wrap)), $($args),*);
        }
    }}
}

#[doc(hidden)]
pub fn convert_closure<F: Fn(va_list) + 'static>(f: F) -> *mut libc::c_void {
    let f: Box<Box<Fn(va_list) + 'static>> = Box::new(Box::new(f));
    Box::into_raw(f) as *mut _
}

#[doc(hidden)]
#[repr(C)]
struct _va_list;

#[allow(non_camel_case_types)]
pub type va_list = *mut _va_list;
<commit_msg>Remove useless feature<commit_after>#![allow(dead_code)]
#![allow(private_in_public)]

extern crate libc;

#[doc(hidden)]
#[macro_export]
macro_rules! counter {
    ($arg:expr) => {{
        1
    }};
    ($arg:expr, $arg2:expr) => {{
        2
    }};
    ($arg:expr, $arg2:expr, $($args:expr),*) => {{
        counter!($($args),*) + 2
    }};
    ($arg:expr, $($args:expr),*) => {{
        counter!($($args),*) + 1
    }}
}

/// This macro is the only thing provided by this crate.
///
/// ## Arguments
///
/// It expects a closure as first argument and then the arguments
/// that'll be used to build the `va_list`.
///
/// ## Example
///
/// ```ignore
/// to_va_list!(|v: va_list::va_list| {
///     vprintf(b"%d %d %s %f\n\0".as_ptr() as *const c_char, v);
/// },
/// 1, 2, b"salut!\0".as_ptr(), 32f32 as c_double);
/// ```
///
/// ## Warning
///
/// It might exist a limit to the number of arguments you can actually pass.
/// A big one, but don't try to send thousands of them at once.
#[macro_export]
macro_rules! to_va_list {
    ($func:expr, $($args:expr),*) => {{
        unsafe extern "C" fn call_func(f: *mut libc::c_void, ap: $crate::va_list) {
            let f: &Box<Fn($crate::va_list) + 'static> = std::mem::transmute(f);
            f(ap);
        }

        #[repr(C)]
        pub struct Wrap {
            pub f: extern "C" fn(*mut libc::c_void, $crate::va_list),
            pub c: *mut libc::c_void,
            pub len: c_uint,
        }

        extern "C" {
            fn create_va_list(w: *mut Wrap, ...);
        }

        unsafe {
            let fu = $func;
            let wrap = Wrap {
                f: std::mem::transmute(call_func as usize),
                c: $crate::convert_closure(fu),
                len: counter!($($args),*),
            };
            create_va_list(Box::into_raw(Box::new(wrap)), $($args),*);
        }
    }}
}

#[doc(hidden)]
pub fn convert_closure<F: Fn(va_list) + 'static>(f: F) -> *mut libc::c_void {
    let f: Box<Box<Fn(va_list) + 'static>> = Box::new(Box::new(f));
    Box::into_raw(f) as *mut _
}

#[doc(hidden)]
#[repr(C)]
struct _va_list;

#[allow(non_camel_case_types)]
pub type va_list = *mut _va_list;
<|endoftext|>


<commit_before>//! Implementation of the [CoAP Protocol][spec].
//!
//! This library provides both a client interface (`CoAPClient`) and a server interface (`CoAPServer`).
//!
//! [spec]: https://tools.ietf.org/html/rfc7252
//!
//! # Installation
//!
//! First add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! coap = "0.1.0"
//! ```
//!
//! Then, add this to your crate root:
//!
//! ```
//! extern crate coap;
//! ```
//!
//! # Example
//!
//! ## Server:
//! ```no_run
//! extern crate coap;

//! use std::io;
//! use coap::packet::*;
//! use coap::{CoAPServer, CoAPClient};

//! fn request_handler(req: Packet, _resp: CoAPClient) {
//! 	println!("Receive request: {:?}", req);
//! }

//! fn main() {
//! 	let addr = "127.0.0.1:5683";
//!
//! 	let mut server = CoAPServer::new(addr).unwrap();
//! 	server.handle(request_handler).unwrap();
//!
//! 	println!("Server up on {}", addr);
//!     println!("Press any key to stop...");
//!
//! 	io::stdin().read_line(&mut String::new()).unwrap();
//!
//! 	println!("Server shutdown");
//! }
//! ```
//!
//! ## Client:
//! ```no_run
//! extern crate coap;
//!
//! use coap::packet::*;
//! use coap::CoAPClient;
//!
//! fn main() {
//! 	let addr = "127.0.0.1:5683";
//! 	let request = "test";
//!
//! 	let client = CoAPClient::new(addr).unwrap();
//! 	let mut packet = Packet::new();
//! 	packet.header.set_version(1);
//! 	packet.header.set_type(PacketType::Confirmable);
//! 	packet.header.set_code("0.01");
//! 	packet.header.set_message_id(1);
//! 	packet.set_token(vec!(0x51, 0x55, 0x77, 0xE8));
//! 	packet.add_option(OptionType::UriPath, request.to_string().into_bytes());
//! 	client.send(&packet).unwrap();
//! 	println!("Client request: coap://{}/{}", addr, request);
//!
//! 	let response = client.receive().unwrap();
//! 	println!("Server reply: {}", String::from_utf8(response.payload).unwrap());
//! }
//! ```

extern crate bincode;
extern crate rustc_serialize;
extern crate mio;
extern crate threadpool;
extern crate url;
extern crate num;
extern crate rand;

pub use server::CoAPServer;
pub use client::CoAPClient;

pub mod packet;
pub mod client;
pub mod server;<commit_msg>update doc<commit_after>//! Implementation of the [CoAP Protocol][spec].
//!
//! This library provides both a client interface (`CoAPClient`) and a server interface (`CoAPServer`).
//!
//! [spec]: https://tools.ietf.org/html/rfc7252
//!
//! # Installation
//!
//! First add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! coap = "0.2.0"
//! ```
//!
//! Then, add this to your crate root:
//!
//! ```
//! extern crate coap;
//! ```
//!
//! # Example
//!
//! ## Server:
//! ```no_run
//! extern crate coap;

//! use std::io;
//! use coap::packet::*;
//! use coap::{CoAPServer, CoAPClient};

//! fn request_handler(req: Packet, _resp: CoAPClient) {
//! 	println!("Receive request: {:?}", req);
//! }

//! fn main() {
//! 	let addr = "127.0.0.1:5683";
//!
//! 	let mut server = CoAPServer::new(addr).unwrap();
//! 	server.handle(request_handler).unwrap();
//!
//! 	println!("Server up on {}", addr);
//!     println!("Press any key to stop...");
//!
//! 	io::stdin().read_line(&mut String::new()).unwrap();
//!
//! 	println!("Server shutdown");
//! }
//! ```
//!
//! ## Client:
//! ```no_run
//! extern crate coap;
//!
//! use coap::packet::*;
//! use coap::CoAPClient;
//!
//! fn main() {
//! 	let url = "coap://127.0.0.1:5683/Rust";
//! 	println!("Client request: {}", url);
//!
//!	let response: Packet = CoAPClient::request(url).unwrap();
//! 	println!("Server reply: {}", String::from_utf8(response.payload).unwrap());
//! }
//! ```

extern crate bincode;
extern crate rustc_serialize;
extern crate mio;
extern crate threadpool;
extern crate url;
extern crate num;
extern crate rand;

pub use server::CoAPServer;
pub use client::CoAPClient;

pub mod packet;
pub mod client;
pub mod server;<|endoftext|>


<commit_before>extern crate base64;
extern crate envy;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod config;
pub mod http;
pub mod logging;

mod ctapi;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    logging::init();

    debug!("CT_init: Called (ctn {}, pn {})", ctn, pn);

    ctapi::init(config::ctn_or(ctn), config::pn_or(pn))
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_data(ctn: u16,
                               dad: *mut u8,
                               sad: *mut u8,
                               lenc: usize,
                               command: *const u8,
                               lenr: *mut usize,
                               response: *mut u8)
                               -> i8 {
    logging::init();

    debug!("CT_data: Called (ctn {})", ctn);

    ctapi::data(config::ctn_or(ctn), dad, sad, lenc, command, lenr, response)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    logging::init();

    debug!("CT_close: Called (ctn {})", ctn);

    ctapi::close(config::ctn_or(ctn))
}
<commit_msg>adjust log message<commit_after>extern crate base64;
extern crate envy;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod config;
pub mod http;
pub mod logging;

mod ctapi;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    logging::init();

    debug!("CT_init(ctn: {}, pn: {})", ctn, pn);

    ctapi::init(config::ctn_or(ctn), config::pn_or(pn))
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_data(ctn: u16,
                               dad: *mut u8,
                               sad: *mut u8,
                               lenc: usize,
                               command: *const u8,
                               lenr: *mut usize,
                               response: *mut u8)
                               -> i8 {
    logging::init();

    debug!("CT_data(ctn: {})", ctn);

    ctapi::data(config::ctn_or(ctn), dad, sad, lenc, command, lenr, response)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    logging::init();

    debug!("CT_close(ctn: {})", ctn);

    ctapi::close(config::ctn_or(ctn))
}
<|endoftext|>


<commit_before>#![crate_type="lib"]
extern crate byteorder;
pub mod xdr;

#[test]
fn u16_writer_test() {
	let mut x = xdr::XdrWriter::new();
	let wtr = vec![0,0,2,5];

	x.pack(517u16);
	assert_eq!(x.get_buffer(),wtr);
}

#[test]
fn u16_reader_test() {
	let wtr = vec![0,0,2,5];
	let mut x = xdr::XdrReader::new(wtr);

	let v = x.unpack::<u16>().unwrap();
	assert_eq!(v,517u16);
}

#[test]
fn r_w_primitive_test() {
	let mut wr = xdr::XdrWriter::new();
	wr.pack(0xCCu8);
	wr.pack(0xAAAAu16);
	wr.pack(0xDEADBEEFu32);
	wr.pack(-1i8);
	wr.pack(-256i16);
	wr.pack(-20i32);
	wr.pack(100.500f32);
	wr.pack(-100.500e10f64);

	let mut rdr = xdr::XdrReader::new(wr.get_buffer());

	assert_eq!(0xCCu8,rdr.unpack::<u8>().unwrap());
	assert_eq!(0xAAAAu16,rdr.unpack::<u16>().unwrap());
	assert_eq!(0xDEADBEEFu32,rdr.unpack::<u32>().unwrap());
	assert_eq!(-1i8,rdr.unpack::<i8>().unwrap());
	assert_eq!(-256i16,rdr.unpack::<i16>().unwrap());
	assert_eq!(-20i32,rdr.unpack::<i32>().unwrap());
	assert_eq!(100.500f32,rdr.unpack::<f32>().unwrap());
	assert_eq!(-100.500e10f64,rdr.unpack::<f64>().unwrap());
}
<commit_msg>tests: add pack/unpack test for Vec<T:XdrPrimitive><commit_after>#![crate_type="lib"]
extern crate byteorder;
pub mod xdr;

#[test]
fn u16_writer_test() {
	let mut x = xdr::XdrWriter::new();
	let wtr = vec![0,0,2,5];

	x.pack(517u16);
	assert_eq!(x.get_buffer(),wtr);
}

#[test]
fn u16_reader_test() {
	let wtr = vec![0,0,2,5];
	let mut x = xdr::XdrReader::new(wtr);

	let v = x.unpack::<u16>().unwrap();
	assert_eq!(v,517u16);
}

#[test]
fn r_w_primitive_test() {
	let mut wr = xdr::XdrWriter::new();
	wr.pack(0xCCu8);
	wr.pack(0xAAAAu16);
	wr.pack(0xDEADBEEFu32);
	wr.pack(-1i8);
	wr.pack(-256i16);
	wr.pack(-20i32);
	wr.pack(100.500f32);
	wr.pack(-100.500e10f64);

	let mut rdr = xdr::XdrReader::new(wr.get_buffer());

	assert_eq!(0xCCu8,rdr.unpack::<u8>().unwrap());
	assert_eq!(0xAAAAu16,rdr.unpack::<u16>().unwrap());
	assert_eq!(0xDEADBEEFu32,rdr.unpack::<u32>().unwrap());
	assert_eq!(-1i8,rdr.unpack::<i8>().unwrap());
	assert_eq!(-256i16,rdr.unpack::<i16>().unwrap());
	assert_eq!(-20i32,rdr.unpack::<i32>().unwrap());
	assert_eq!(100.500f32,rdr.unpack::<f32>().unwrap());
	assert_eq!(-100.500e10f64,rdr.unpack::<f64>().unwrap());
}

#[test]
fn vec_test() {
	let mut wr = xdr::XdrWriter::new();
	let vec = vec![0u32,1,2,3,4,5];

	wr.pack(vec);

	let mut rdr = xdr::XdrReader::new(wr.get_buffer());

	let res = rdr.unpack::<Vec<u32>>().unwrap();

	assert_eq!(vec![0u32,1,2,3,4,5], res)
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;

extern crate serde;
#[macro_use]
extern crate serde_derive;

#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;

pub use self::arithmetic::{ArithmeticBase, ArithmeticExpression, ArithmeticOperator};
pub use self::common::{FieldDefinitionExpression, FieldValueExpression, Literal,
                       LiteralExpression, Operator, Real, SqlType, TableKey};
pub use self::column::{Column, ColumnConstraint, ColumnSpecification, FunctionExpression};
pub use self::condition::{ConditionBase, ConditionExpression, ConditionTree};
pub use self::create::{CreateTableStatement, CreateViewStatement};
pub use self::delete::DeleteStatement;
pub use self::insert::InsertStatement;
pub use self::join::{JoinConstraint, JoinOperator, JoinRightSide};
pub use self::parser::*;
pub use self::compound_select::{CompoundSelectOperator, CompoundSelectStatement};
pub use self::select::{GroupByClause, JoinClause, LimitClause, SelectStatement};
pub use self::order::{OrderClause, OrderType};
pub use self::table::Table;
pub use self::set::SetStatement;
pub use self::update::UpdateStatement;

pub mod parser;

#[macro_use]
mod keywords;
mod arithmetic;
mod column;
mod common;
mod condition;
mod create;
mod insert;
mod join;
mod select;
mod compound_select;
mod table;
mod delete;
mod drop;
mod update;
mod set;
mod order;
<commit_msg>SelectSpecification needs to be public<commit_after>#[macro_use]
extern crate nom;

extern crate serde;
#[macro_use]
extern crate serde_derive;

#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;

pub use self::arithmetic::{ArithmeticBase, ArithmeticExpression, ArithmeticOperator};
pub use self::common::{FieldDefinitionExpression, FieldValueExpression, Literal,
                       LiteralExpression, Operator, Real, SqlType, TableKey};
pub use self::column::{Column, ColumnConstraint, ColumnSpecification, FunctionExpression};
pub use self::condition::{ConditionBase, ConditionExpression, ConditionTree};
pub use self::create::{CreateTableStatement, CreateViewStatement, SelectSpecification};
pub use self::delete::DeleteStatement;
pub use self::insert::InsertStatement;
pub use self::join::{JoinConstraint, JoinOperator, JoinRightSide};
pub use self::parser::*;
pub use self::compound_select::{CompoundSelectOperator, CompoundSelectStatement};
pub use self::select::{GroupByClause, JoinClause, LimitClause, SelectStatement};
pub use self::order::{OrderClause, OrderType};
pub use self::table::Table;
pub use self::set::SetStatement;
pub use self::update::UpdateStatement;

pub mod parser;

#[macro_use]
mod keywords;
mod arithmetic;
mod column;
mod common;
mod condition;
mod create;
mod insert;
mod join;
mod select;
mod compound_select;
mod table;
mod delete;
mod drop;
mod update;
mod set;
mod order;
<|endoftext|>


<commit_before>#![crate_type="lib"]
#![feature(str_char)]

pub use sys::Window;

pub use button::Button;
pub use cell::{CopyCell, CloneCell};
pub use color::Color;
pub use event::Event;
pub use label::Label;
pub use place::Place;
pub use point::Point;
pub use progress_bar::ProgressBar;
pub use rect::Rect;
pub use renderer::Renderer;
pub use text_box::TextBox;
pub use widget::Widget;

pub mod button;
pub mod cell;
pub mod color;
pub mod event;
pub mod label;
pub mod place;
pub mod point;
pub mod progress_bar;
pub mod rect;
pub mod renderer;
pub mod text_box;
pub mod widget;

use callback::{Click, Enter};
pub mod callback;

#[cfg(target_os = "redox")]
#[path="orbital/mod.rs"]
pub mod sys;

#[cfg(not(target_os = "redox"))]
#[path="sdl2/mod.rs"]
pub mod sys;

pub fn example() {
    let mut window = Window::new(Rect::new(100, 100, 420, 420), "OrbTK");

    let x = 10;
    let mut y = 10;

    let label = Label::new()
                    .position(x, y)
                    .size(400, 16)
                    .text("Test Label")
                    .place(&mut window);

    y += label.rect.get().height as i32 + 10;

    let text_box = TextBox::new()
                       .position(x, y)
                       .size(342, 16)
                       .on_enter(move |text_box: &TextBox| {
                           label.text.set(text_box.text.get());
                       })
                       .place(&mut window);

    let button = Button::new()
                     .position(x + text_box.rect.get().width as i32 + 10, y)
                     .size(48, text_box.rect.get().height)
                     .text("Update")
                     .on_click(move |_button: &Button, _point: Point| {
                         text_box.emit_enter();
                     })
                     .place(&mut window);

    y += button.rect.get().height as i32 + 10;

    let progress_label = Label::new()
                             .text("Progress: 0%")
                             .position(x, y)
                             .size(400, 16)
                             .place(&mut window);

    y += progress_label.rect.get().height as i32 + 10;

    let progress_bar = ProgressBar::new()
                           .position(x, y)
                           .size(400, 16)
                           .on_click(move |progress_bar: &ProgressBar, point: Point| {
                               let progress = point.x * 100 / progress_bar.rect.get().width as i32;
                               progress_label.text.set(format!("Progress: {}%", progress));
                               progress_bar.value.set(progress);
                           })
                           .place(&mut window);

    y += progress_bar.rect.get().height as i32 + 10;

    let multi_line_label = Label::new()
                               .text("Multi-Line Text")
                               .position(x, y)
                               .size(400, 16)
                               .place(&mut window);

    y += multi_line_label.rect.get().height as i32 + 10;

    let multi_line_text_box = TextBox::new()
                                  .position(x, y)
                                  .size(400, 128)
                                  .place(&mut window);

    y += multi_line_text_box.rect.get().height as i32 + 10;

    Label::new()
        .position(x, y)
        .size(400, 256)
        .text("Test Offset")
        .text_offset(50, 50)
        .place(&mut window);

    window.exec();
}
<commit_msg>fixup<commit_after>#![crate_type="lib"]
#![feature(str_char)]

pub use sys::Window;

pub use button::Button;
pub use cell::{CopyCell, CloneCell};
pub use color::Color;
pub use event::Event;
pub use label::Label;
pub use place::Place;
pub use point::Point;
pub use progress_bar::ProgressBar;
pub use rect::Rect;
pub use renderer::Renderer;
pub use text_box::TextBox;
pub use widget::Widget;

pub mod button;
pub mod cell;
pub mod color;
pub mod event;
pub mod label;
pub mod place;
pub mod point;
pub mod progress_bar;
pub mod rect;
pub mod renderer;
pub mod text_box;
pub mod widget;

use callback::{Click, Enter};
pub mod callback;

#[cfg(target_os = "redox")]
#[path="orbital/mod.rs"]
pub mod sys;

#[cfg(not(target_os = "redox"))]
#[path="sdl2/mod.rs"]
pub mod sys;

pub fn example() {
    let mut window = Window::new(Rect::new(100, 100, 420, 420), "OrbTK");

    let x = 10;
    let mut y = 10;

    let label = Label::new()
        .position(x, y)
        .size(400, 16)
        .text("Test Label")
        .place(&mut window);

    y += label.rect.get().height as i32 + 10;

    let text_box = TextBox::new()
        .position(x, y)
        .size(342, 16)
        .on_enter(move |text_box: &TextBox| {
            label.text.set(text_box.text.get());
        })
        .place(&mut window);

    let button = Button::new()
        .position(x + text_box.rect.get().width as i32 + 10, y)
        .size(48, text_box.rect.get().height)
        .text("Update")
        .on_click(move |_button: &Button, _point: Point| {
            text_box.emit_enter();
        })
        .place(&mut window);

    y += button.rect.get().height as i32 + 10;

    let progress_label = Label::new()
        .text("Progress: 0%")
        .position(x, y)
        .size(400, 16)
        .place(&mut window);

    y += progress_label.rect.get().height as i32 + 10;

    let progress_bar = ProgressBar::new()
        .position(x, y)
        .size(400, 16)
        .on_click(move |progress_bar: &ProgressBar, point: Point| {
            let progress = point.x * 100 / progress_bar.rect.get().width as i32;
            progress_label.text.set(format!("Progress: {}%", progress));
            progress_bar.value.set(progress);
        })
        .place(&mut window);

    y += progress_bar.rect.get().height as i32 + 10;

    let multi_line_label = Label::new()
        .text("Multi-Line Text")
        .position(x, y)
        .size(400, 16)
        .place(&mut window);

    y += multi_line_label.rect.get().height as i32 + 10;

    let multi_line_text_box = TextBox::new()
        .position(x, y)
        .size(400, 128)
        .place(&mut window);

    y += multi_line_text_box.rect.get().height as i32 + 10;

    Label::new()
        .position(x, y)
        .size(400, 256)
        .text("Test Offset")
        .text_offset(50, 50)
        .place(&mut window);

    window.exec();
}
<|endoftext|>


<commit_before>#![feature(globs, phase, plugin_registrar, if_let)]

#![allow(unused_imports)]

#[phase(plugin,link)]
extern crate syntax;
#[phase(plugin, link)]
extern crate rustc;

// Only for the compile time checking of paths
extern crate collections;

use rustc::plugin::Registry;
use rustc::lint::LintPassObject;

pub mod types;
pub mod misc;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_lint_pass(box types::TypePass as LintPassObject);
    reg.register_lint_pass(box misc::MiscPass as LintPassObject);
}<commit_msg>rm if_let gate<commit_after>#![feature(globs, phase, plugin_registrar)]

#![allow(unused_imports)]

#[phase(plugin,link)]
extern crate syntax;
#[phase(plugin, link)]
extern crate rustc;

// Only for the compile time checking of paths
extern crate collections;

use rustc::plugin::Registry;
use rustc::lint::LintPassObject;

pub mod types;
pub mod misc;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_lint_pass(box types::TypePass as LintPassObject);
    reg.register_lint_pass(box misc::MiscPass as LintPassObject);
}
<|endoftext|>


<commit_before>extern crate redis;

use std::time::Duration;

use redis::{Connection, RedisError, cmd};

fn duration_to_millis(d: &Duration) -> u64 {
    (d.subsec_nanos() / 1_000_000) as u64 + d.as_secs()
}

macro_rules! option_arg {
    ($disque: expr, $name: expr, $param: expr) => (
        match $param {
            Some(u) => $disque.arg($name).arg(u),
            None => &mut $disque,
        };
    )
}
pub struct Disque {
    connection: Connection,
}

impl Disque {
    pub fn open(url: &str) -> Result<Disque, RedisError> {
        let client = try!(redis::Client::open(url));
        let connection = try!(client.get_connection());
        Ok(Disque { connection: connection })
    }

    pub fn hello(&self) -> Result<Vec<Vec<u8>>, RedisError> {
        cmd("HELLO").query(&self.connection)
    }

    pub fn addjob(&self, queue_name: &[u8], job: &[u8], timeout: Duration,
            replicate: Option<usize>, delay: Option<Duration>,
            retry: Option<Duration>, ttl: Option<Duration>,
            maxlen: Option<usize>, async: bool,
            ) -> Result<String, RedisError> {
        let mut c = cmd("ADDJOB");
        c
            .arg(queue_name)
            .arg(job)
            .arg(duration_to_millis(&timeout));
        option_arg!(c, "REPLICATE", replicate);
        option_arg!(c, "DELAY", delay.map(|x| x.as_secs()));
        option_arg!(c, "RETRY", retry.map(|x| x.as_secs()));
        option_arg!(c, "TTL", ttl.map(|x| x.as_secs()));
        option_arg!(c, "MAXLEN", maxlen);
        if async { c.arg("ASYNC"); }
        c.query(&self.connection)
    }

    pub fn getjob_count(&self, nohang: bool, timeout: Option<Duration>,
            count: usize, withcounters: bool, queues: &[&[u8]]
            ) -> Result<Vec<Vec<Vec<u8>>>, RedisError> {
        let mut c = cmd("GETJOB");
        if nohang { c.arg("NOHANG"); }
        option_arg!(c, "TIMEOUT", timeout.map(|t| duration_to_millis(&t)));
        c.arg("COUNT").arg(count);
        if withcounters { c.arg("WITHCOUNTERS"); }
        c.arg("FROM");
        for queue in queues { c.arg(*queue); }
        c.query(&self.connection)
    }

    pub fn getjob(&self, nohang: bool, timeout: Option<Duration>,
            withcounters: bool, queues: &[&[u8]]
            ) -> Result<Option<Vec<Vec<u8>>>, RedisError> {
        let mut jobs = try!(self.getjob_count(nohang, timeout, 1, withcounters,
                    queues));
        Ok(jobs.pop())
    }

    pub fn ackjob(&self, jobids: &[&[u8]]) -> Result<bool, RedisError> {
        let mut c = cmd("ACKJOB");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn fastack(&self, jobids: &[&[u8]]) -> Result<usize, RedisError> {
        let mut c = cmd("FASTACK");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn working(&self, jobid: &[u8]) -> Result<Duration, RedisError> {
        let retry = try!(cmd("WORKING").arg(jobid).query(&self.connection));
        Ok(Duration::from_secs(retry))
    }

    pub fn nack(&self, jobids: &[&[u8]]) -> Result<usize, RedisError> {
        let mut c = cmd("NACK");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn info(&self) -> Result<Vec<u8>, RedisError> {
        cmd("INFO").query(&self.connection)
    }

    pub fn qlen(&self, queue_name: &[u8]) -> Result<usize, RedisError> {
        cmd("QLEN").arg(queue_name).query(&self.connection)
    }

    pub fn qpeek(&self, queue_name: &[u8], count: i64) -> Result<Vec<Vec<Vec<u8>>>, RedisError> {
        cmd("QPEEK").arg(queue_name).arg(count).query(&self.connection)
    }
}

#[cfg(test)]
fn conn() -> Disque {
    Disque::open("redis://127.0.0.1:7711/").unwrap()
}

#[test]
fn can_connect() {
    conn();
}

#[test]
fn hello() {
    let disque = conn();
    disque.hello().unwrap();
}

#[test]
fn addjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue", b"job", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(jobid.len(), 48);
    assert_eq!(&jobid[..2], "DI");
    assert_eq!(&jobid[46..], "SQ");
}

#[test]
fn getjob_count() {
    let disque = conn();
    let j1 = disque.addjob(b"queue1", b"job1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue2", b"job2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue3", b"job3", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let jobs = disque.getjob_count(false, None, 3, true, &[b"queue1", b"queue2"]).unwrap();
    assert_eq!(jobs.len(), 2);
    assert_eq!(jobs[0][0], b"queue1");
    assert_eq!(jobs[0][1], j1.into_bytes());
    assert_eq!(jobs[0][2], b"job1");
    assert_eq!(jobs[1][0], b"queue2");
    assert_eq!(jobs[1][1], j2.into_bytes());
    assert_eq!(jobs[1][2], b"job2");
}

#[test]
fn getjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue4", b"job4", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let job = disque.getjob(false, None, true, &[b"queue4", b"queue5"]).unwrap().unwrap();
    assert_eq!(job[0], b"queue4");
    assert_eq!(job[1], jobid.into_bytes());
    assert_eq!(job[2], b"job4");
}

#[test]
fn ackjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue6", b"job6", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.ackjob(&[jobid.as_bytes()]).unwrap());
    assert!(!disque.ackjob(&[jobid.as_bytes()]).unwrap());
    assert!(!disque.ackjob(&[jobid.as_bytes()]).unwrap());
}

#[test]
fn fastack() {
    let disque = conn();
    let jobid = disque.addjob(b"queue7", b"job7", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 1);
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 0);
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 0);
}

#[test]
fn working() {
    let disque = conn();
    let jobid = disque.addjob(b"queue8", b"job8", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.working(jobid.as_bytes()).unwrap().as_secs() > 0);
}

#[test]
fn nack() {
    let disque = conn();
    let j1 = disque.addjob(b"queue9", b"job9.1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue9", b"job9.2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j3 = disque.addjob(b"queue9", b"job9.3", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue9"]).unwrap().len(), 3);
    assert_eq!(disque.nack(&[j1.as_bytes(), j2.as_bytes(), j3.as_bytes()]).unwrap(), 3);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue9"]).unwrap().len(), 3);
}

#[test]
fn info() {
    let disque = conn();
    disque.info().unwrap();
}

#[test]
fn qlen() {
    let disque = conn();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.qlen(b"queue10").unwrap(), 3);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue10"]).unwrap().len(), 3);
}

#[test]
fn qpeek() {
    let disque = conn();
    let j1 = disque.addjob(b"queue11", b"job11.1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue11", b"job11.2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.qpeek(b"queue11", 10).unwrap(), vec![
                vec![
                b"queue11".to_vec(),
                j1.as_bytes().to_vec(),
                b"job11.1".to_vec(),
                ],
                vec![
                b"queue11".to_vec(),
                j2.as_bytes().to_vec(),
                b"job11.2".to_vec(),
                ],
            ]);
    assert_eq!(disque.qpeek(b"queue11", -10).unwrap(), vec![
                vec![
                b"queue11".to_vec(),
                j2.as_bytes().to_vec(),
                b"job11.2".to_vec(),
                ],
                vec![
                b"queue11".to_vec(),
                j1.as_bytes().to_vec(),
                b"job11.1".to_vec(),
                ],
            ]);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue11"]).unwrap().len(), 2);
}
<commit_msg>Add ENQUEUE<commit_after>extern crate redis;

use std::time::Duration;

use redis::{Connection, RedisError, cmd};

fn duration_to_millis(d: &Duration) -> u64 {
    (d.subsec_nanos() / 1_000_000) as u64 + d.as_secs()
}

macro_rules! option_arg {
    ($disque: expr, $name: expr, $param: expr) => (
        match $param {
            Some(u) => $disque.arg($name).arg(u),
            None => &mut $disque,
        };
    )
}
pub struct Disque {
    connection: Connection,
}

impl Disque {
    pub fn open(url: &str) -> Result<Disque, RedisError> {
        let client = try!(redis::Client::open(url));
        let connection = try!(client.get_connection());
        Ok(Disque { connection: connection })
    }

    pub fn hello(&self) -> Result<Vec<Vec<u8>>, RedisError> {
        cmd("HELLO").query(&self.connection)
    }

    pub fn addjob(&self, queue_name: &[u8], job: &[u8], timeout: Duration,
            replicate: Option<usize>, delay: Option<Duration>,
            retry: Option<Duration>, ttl: Option<Duration>,
            maxlen: Option<usize>, async: bool,
            ) -> Result<String, RedisError> {
        let mut c = cmd("ADDJOB");
        c
            .arg(queue_name)
            .arg(job)
            .arg(duration_to_millis(&timeout));
        option_arg!(c, "REPLICATE", replicate);
        option_arg!(c, "DELAY", delay.map(|x| x.as_secs()));
        option_arg!(c, "RETRY", retry.map(|x| x.as_secs()));
        option_arg!(c, "TTL", ttl.map(|x| x.as_secs()));
        option_arg!(c, "MAXLEN", maxlen);
        if async { c.arg("ASYNC"); }
        c.query(&self.connection)
    }

    pub fn getjob_count(&self, nohang: bool, timeout: Option<Duration>,
            count: usize, withcounters: bool, queues: &[&[u8]]
            ) -> Result<Vec<Vec<Vec<u8>>>, RedisError> {
        let mut c = cmd("GETJOB");
        if nohang { c.arg("NOHANG"); }
        option_arg!(c, "TIMEOUT", timeout.map(|t| duration_to_millis(&t)));
        c.arg("COUNT").arg(count);
        if withcounters { c.arg("WITHCOUNTERS"); }
        c.arg("FROM");
        for queue in queues { c.arg(*queue); }
        c.query(&self.connection)
    }

    pub fn getjob(&self, nohang: bool, timeout: Option<Duration>,
            withcounters: bool, queues: &[&[u8]]
            ) -> Result<Option<Vec<Vec<u8>>>, RedisError> {
        let mut jobs = try!(self.getjob_count(nohang, timeout, 1, withcounters,
                    queues));
        Ok(jobs.pop())
    }

    pub fn ackjob(&self, jobids: &[&[u8]]) -> Result<bool, RedisError> {
        let mut c = cmd("ACKJOB");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn fastack(&self, jobids: &[&[u8]]) -> Result<usize, RedisError> {
        let mut c = cmd("FASTACK");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn working(&self, jobid: &[u8]) -> Result<Duration, RedisError> {
        let retry = try!(cmd("WORKING").arg(jobid).query(&self.connection));
        Ok(Duration::from_secs(retry))
    }

    pub fn nack(&self, jobids: &[&[u8]]) -> Result<usize, RedisError> {
        let mut c = cmd("NACK");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }

    pub fn info(&self) -> Result<Vec<u8>, RedisError> {
        cmd("INFO").query(&self.connection)
    }

    pub fn qlen(&self, queue_name: &[u8]) -> Result<usize, RedisError> {
        cmd("QLEN").arg(queue_name).query(&self.connection)
    }

    pub fn qpeek(&self, queue_name: &[u8], count: i64) -> Result<Vec<Vec<Vec<u8>>>, RedisError> {
        cmd("QPEEK").arg(queue_name).arg(count).query(&self.connection)
    }

    pub fn enqueue(&self, jobids: &[&[u8]]) -> Result<usize, RedisError> {
        let mut c = cmd("ENQUEUE");
        for jobid in jobids { c.arg(*jobid); }
        c.query(&self.connection)
    }
}

#[cfg(test)]
fn conn() -> Disque {
    Disque::open("redis://127.0.0.1:7711/").unwrap()
}

#[test]
fn can_connect() {
    conn();
}

#[test]
fn hello() {
    let disque = conn();
    disque.hello().unwrap();
}

#[test]
fn addjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue", b"job", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(jobid.len(), 48);
    assert_eq!(&jobid[..2], "DI");
    assert_eq!(&jobid[46..], "SQ");
}

#[test]
fn getjob_count() {
    let disque = conn();
    let j1 = disque.addjob(b"queue1", b"job1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue2", b"job2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue3", b"job3", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let jobs = disque.getjob_count(false, None, 3, true, &[b"queue1", b"queue2"]).unwrap();
    assert_eq!(jobs.len(), 2);
    assert_eq!(jobs[0][0], b"queue1");
    assert_eq!(jobs[0][1], j1.into_bytes());
    assert_eq!(jobs[0][2], b"job1");
    assert_eq!(jobs[1][0], b"queue2");
    assert_eq!(jobs[1][1], j2.into_bytes());
    assert_eq!(jobs[1][2], b"job2");
}

#[test]
fn getjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue4", b"job4", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let job = disque.getjob(false, None, true, &[b"queue4", b"queue5"]).unwrap().unwrap();
    assert_eq!(job[0], b"queue4");
    assert_eq!(job[1], jobid.into_bytes());
    assert_eq!(job[2], b"job4");
}

#[test]
fn ackjob() {
    let disque = conn();
    let jobid = disque.addjob(b"queue6", b"job6", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.ackjob(&[jobid.as_bytes()]).unwrap());
    assert!(!disque.ackjob(&[jobid.as_bytes()]).unwrap());
    assert!(!disque.ackjob(&[jobid.as_bytes()]).unwrap());
}

#[test]
fn fastack() {
    let disque = conn();
    let jobid = disque.addjob(b"queue7", b"job7", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 1);
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 0);
    assert!(disque.fastack(&[jobid.as_bytes()]).unwrap() == 0);
}

#[test]
fn working() {
    let disque = conn();
    let jobid = disque.addjob(b"queue8", b"job8", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert!(disque.working(jobid.as_bytes()).unwrap().as_secs() > 0);
}

#[test]
fn nack() {
    let disque = conn();
    let j1 = disque.addjob(b"queue9", b"job9.1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue9", b"job9.2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j3 = disque.addjob(b"queue9", b"job9.3", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue9"]).unwrap().len(), 3);
    assert_eq!(disque.nack(&[j1.as_bytes(), j2.as_bytes(), j3.as_bytes()]).unwrap(), 3);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue9"]).unwrap().len(), 3);
}

#[test]
fn info() {
    let disque = conn();
    disque.info().unwrap();
}

#[test]
fn qlen() {
    let disque = conn();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    disque.addjob(b"queue10", b"job10", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.qlen(b"queue10").unwrap(), 3);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue10"]).unwrap().len(), 3);
}

#[test]
fn qpeek() {
    let disque = conn();
    let j1 = disque.addjob(b"queue11", b"job11.1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue11", b"job11.2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.qpeek(b"queue11", 10).unwrap(), vec![
                vec![
                b"queue11".to_vec(),
                j1.as_bytes().to_vec(),
                b"job11.1".to_vec(),
                ],
                vec![
                b"queue11".to_vec(),
                j2.as_bytes().to_vec(),
                b"job11.2".to_vec(),
                ],
            ]);
    assert_eq!(disque.qpeek(b"queue11", -10).unwrap(), vec![
                vec![
                b"queue11".to_vec(),
                j2.as_bytes().to_vec(),
                b"job11.2".to_vec(),
                ],
                vec![
                b"queue11".to_vec(),
                j1.as_bytes().to_vec(),
                b"job11.1".to_vec(),
                ],
            ]);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue11"]).unwrap().len(), 2);
}

#[test]
fn enqueue() {
    let disque = conn();
    let j1 = disque.addjob(b"queue12", b"job12.1", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j2 = disque.addjob(b"queue12", b"job12.2", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    let j3 = disque.addjob(b"queue12", b"job12.3", Duration::from_secs(10), None, None, None, None, None, false).unwrap();
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue12"]).unwrap().len(), 3);
    assert_eq!(disque.enqueue(&[j1.as_bytes(), j2.as_bytes(), j3.as_bytes()]).unwrap(), 3);
    assert_eq!(disque.getjob_count(false, None, 100, true, &[b"queue12"]).unwrap().len(), 3);
}
<|endoftext|>


<commit_before>
#[macro_use] extern crate log;

use std::collections::HashMap;

struct BibEntry<'a> {
    entry_type: &'a str,
    cite_key: &'a str,
    fields: HashMap<&'a str, &'a str>
}

impl<'a> BibEntry<'a> {
    pub fn cite_key(&self) -> &str {
        &self.cite_key
    }
    pub fn entry_type(&self) -> &str {
        &self.entry_type
    }
    pub fn field(&self, field: &str) -> &str {
        &self.fields.get(field).expect("No field found")
    }
}

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

    #[test]
    fn getters(){

        let mut h = HashMap::new();
        h.insert("author", "Jack Weinbender");
        h.insert("title", "Remembering Rewritten Bible");
        h.insert("year", "2018");

        let e = BibEntry{
            entry_type: "thesis",
            cite_key: "weinbender2018",
            fields: h,
        };

        assert!(e.cite_key() == "weinbender2018");
        assert!(e.entry_type() == "thesis");
        assert!(e.field("author") == "Jack Weinbender");
        assert!(e.field("title") == "Remembering Rewritten Bible");
        assert!(e.field("year") == "2018");
    }
}
<commit_msg>Basic serialization<commit_after>
#[macro_use]
extern crate log;

use std::cmp::Ordering;

#[derive(Debug, Eq)]
struct Field<'a> (&'a str, &'a str);

impl<'a> Ord for Field<'a>  {
    fn cmp(&self, other: &Field) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<'a> PartialOrd for Field<'a>  {
    fn partial_cmp(&self, other: &Field) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'a> PartialEq for Field<'a> {
    fn eq(&self, other: &Field) -> bool {
        self.0 == other.0
    }
}

#[derive(Debug)]
struct BibEntry<'a> {
    entry_type: &'a str,
    cite_key: &'a str,
    fields: Vec<Field<'a>>,
}

impl<'a> BibEntry<'a> {
    pub fn cite_key(&self) -> &str {
        &self.cite_key
    }
    pub fn entry_type(&self) -> &str {
        &self.entry_type
    }
    pub fn field(&self, field: &str) -> &str {
        let fields = &self.fields;
        let index = fields.iter().position(|x|
            x.0 == field ).expect("No key found.");
        fields[index].1
    }
    pub fn to_string(&mut self) -> String {
        &self.sort();
        let mut entry = String::new();

        entry.push_str("@");
        entry.push_str(&self.entry_type.to_string());
        entry.push_str("{");
        entry.push_str(&self.cite_key.to_string());

        if *&self.fields.is_empty() {
            entry.push_str("}}");
            return entry
        }

        for field in &self.fields {
            entry.push_str(",\n  ");
            entry.push_str(field.0);
            entry.push_str(" = {");
            entry.push_str(field.1);
            entry.push_str("}");
        }

        entry.push_str("}");
        entry

    }
    fn sort(&mut self) {
        &self.fields.sort();
    }
}

mod test{
    use super::*;

    #[test]
    fn getters() {

        let mut h = Vec::new();
        h.push(Field("title", "Remembering Rewritten Bible"));
        h.push(Field("author", "Jack Weinbender"));
        h.push(Field("year", "2018"));

        let mut e = BibEntry {
            entry_type: "thesis",
            cite_key: "weinbender2018",
            fields: h,
        };

        assert_eq!(e.cite_key(), "weinbender2018");
        assert_eq!(e.entry_type(), "thesis");
        assert_eq!(e.field("author"), "Jack Weinbender");
        assert_eq!(e.field("title"), "Remembering Rewritten Bible");
        assert_eq!(e.field("year"), "2018");
        assert_eq!(
            e.to_string(),
r#"@thesis{weinbender2018,
  author = {Jack Weinbender},
  title = {Remembering Rewritten Bible},
  year = {2018}}"#.to_string()
        );
    }
}<|endoftext|>


<commit_before>#![doc(html_root_url = "https://docs.rs/twitter-stream/0.9.0")]
#![recursion_limit = "128"]

/*!
# Twitter Stream

A library for listening on Twitter Streaming API.

## Usage

Add `twitter-stream` to your dependencies in your project's `Cargo.toml`:

```toml
[dependencies]
twitter-stream = "0.9"
```

and this to your crate root:

```rust,no_run
extern crate twitter_stream;
```

## Overview

Here is a basic example that prints public mentions to @Twitter in JSON format:

```rust,no_run
extern crate twitter_stream;

use twitter_stream::{Token, TwitterStreamBuilder};
use twitter_stream::rt::{self, Future, Stream};

# fn main() {
let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");

let future = TwitterStreamBuilder::filter(token)
    .track(Some("@Twitter"))
    .listen()
    .unwrap()
    .flatten_stream()
    .for_each(|json| {
        println!("{}", json);
        Ok(())
    })
    .map_err(|e| println!("error: {}", e));

rt::run(future);
# }
```
*/

extern crate bytes;
extern crate cfg_if;
extern crate futures;
extern crate http;
extern crate hyper;
#[cfg(feature = "tls")]
extern crate hyper_tls;
extern crate libflate;
extern crate oauth1_request as oauth;
extern crate oauth1_request_derive;
#[cfg(feature = "serde")]
extern crate serde;
extern crate static_assertions;
extern crate string;
extern crate tokio_io;
extern crate tokio_timer;

#[macro_use]
mod util;

pub mod error;
#[cfg(feature = "runtime")]
pub mod rt;
pub mod types;

mod gzip;
mod token;

pub use error::Error;
pub use token::Token;

use std::borrow::Borrow;
use std::time::Duration;

use bytes::Bytes;
use futures::{try_ready, Async, Future, Poll, Stream};
use http::response::Parts;
use hyper::body::{Body, Payload};
use hyper::client::connect::Connect;
use hyper::client::{Client, ResponseFuture};
use hyper::header::{
    HeaderValue, ACCEPT_ENCODING, AUTHORIZATION, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TYPE,
};
use hyper::Request;
use oauth::OAuth1Authorize;
use oauth1_request_derive::OAuth1Authorize;
use string::TryFrom;

use gzip::MaybeGzip;
use types::{FilterLevel, RequestMethod, StatusCode, Uri};
use util::*;

/// A builder for `TwitterStream`.
///
/// ## Example
///
/// ```rust,no_run
/// extern crate twitter_stream;
///
/// use twitter_stream::{Token, TwitterStreamBuilder};
/// use twitter_stream::rt::{self, Future, Stream};
///
/// # fn main() {
/// let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");
///
/// let future = TwitterStreamBuilder::sample(token)
///     .timeout(None)
///     .listen()
///     .unwrap()
///     .flatten_stream()
///     .for_each(|json| {
///         println!("{}", json);
///         Ok(())
///     })
///     .map_err(|e| println!("error: {}", e));
///
/// rt::run(future);
/// # }
/// ```
#[derive(Clone, Debug)]
pub struct TwitterStreamBuilder<'a, T = Token> {
    method: RequestMethod,
    endpoint: Uri,
    token: T,
    inner: BuilderInner<'a>,
}

/// A future returned by constructor methods
/// which resolves to a `TwitterStream`.
pub struct FutureTwitterStream {
    response: MaybeTimeout<ResponseFuture>,
}

/// A listener for Twitter Streaming API.
/// It yields JSON strings returned from the API.
pub struct TwitterStream {
    inner: Lines<MaybeGzip<MaybeTimeoutStream<Body>>>,
}

#[derive(Clone, Debug, OAuth1Authorize)]
struct BuilderInner<'a> {
    #[oauth1(skip)]
    timeout: Option<Duration>,
    #[oauth1(skip_if = "not")]
    stall_warnings: bool,
    #[oauth1(option)]
    filter_level: Option<FilterLevel>,
    #[oauth1(option)]
    language: Option<&'a str>,
    #[oauth1(option, encoded, fmt = "fmt_follow")]
    follow: Option<&'a [u64]>,
    #[oauth1(option)]
    track: Option<&'a str>,
    #[oauth1(encoded, option, fmt = "fmt_locations")]
    #[allow(clippy::type_complexity)]
    locations: Option<&'a [((f64, f64), (f64, f64))]>,
    #[oauth1(encoded, option)]
    count: Option<i32>,
}

impl<'a, C, A> TwitterStreamBuilder<'a, Token<C, A>>
where
    C: Borrow<str>,
    A: Borrow<str>,
{
    /// Create a builder for `POST statuses/filter` endpoint.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://dev.twitter.com/streaming/reference/post/statuses/filter
    pub fn filter(token: Token<C, A>) -> Self {
        const URI: &str = "https://stream.twitter.com/1.1/statuses/filter.json";
        Self::custom(RequestMethod::POST, Uri::from_static(URI), token)
    }

    /// Create a builder for `GET statuses/sample` endpoint.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://dev.twitter.com/streaming/reference/get/statuses/sample
    pub fn sample(token: Token<C, A>) -> Self {
        const URI: &str = "https://stream.twitter.com/1.1/statuses/sample.json";
        Self::custom(RequestMethod::GET, Uri::from_static(URI), token)
    }

    /// Constructs a builder for a Stream at a custom endpoint.
    pub fn custom(method: RequestMethod, endpoint: Uri, token: Token<C, A>) -> Self {
        Self {
            method,
            endpoint,
            token,
            inner: BuilderInner {
                timeout: Some(Duration::from_secs(90)),
                stall_warnings: false,
                filter_level: None,
                language: None,
                follow: None,
                track: None,
                locations: None,
                count: None,
            },
        }
    }

    /// Start listening on the Streaming API endpoint, returning a `Future` which resolves
    /// to a `Stream` yielding JSON messages from the API.
    #[cfg(feature = "tls")]
    pub fn listen(&self) -> Result<FutureTwitterStream, error::TlsError> {
        let conn = hyper_tls::HttpsConnector::new(1)?;
        Ok(self.listen_with_client(&Client::builder().build::<_, Body>(conn)))
    }

    /// Same as `listen` except that it uses `client` to make HTTP request to the endpoint.
    pub fn listen_with_client<Conn, B>(&self, client: &Client<Conn, B>) -> FutureTwitterStream
    where
        Conn: Connect + Sync + 'static,
        Conn::Transport: 'static,
        Conn::Future: 'static,
        B: Default + From<Vec<u8>> + Payload + Send + 'static,
        B::Data: Send,
    {
        let mut req = Request::builder();
        req.method(self.method.clone())
            .header(ACCEPT_ENCODING, HeaderValue::from_static("chunked,gzip"));

        let req = if RequestMethod::POST == self.method {
            let oauth::Request {
                authorization,
                data,
            } = self.inner.authorize_form(
                "POST",
                &self.endpoint,
                self.token.consumer_key.borrow(),
                self.token.consumer_secret.borrow(),
                self.token.access_secret.borrow(),
                oauth::HmacSha1,
                &*oauth::Options::new().token(self.token.access_key.borrow()),
            );

            req.uri(self.endpoint.clone())
                .header(AUTHORIZATION, Bytes::from(authorization))
                .header(
                    CONTENT_TYPE,
                    HeaderValue::from_static("application/x-www-form-urlencoded"),
                )
                .header(CONTENT_LENGTH, Bytes::from(data.len().to_string()))
                .body(data.into_bytes().into())
                .unwrap()
        } else {
            let oauth::Request {
                authorization,
                data: uri,
            } = self.inner.authorize(
                self.method.as_ref(),
                &self.endpoint,
                self.token.consumer_key.borrow(),
                self.token.consumer_secret.borrow(),
                self.token.access_secret.borrow(),
                oauth::HmacSha1,
                &*oauth::Options::new().token(self.token.access_key.borrow()),
            );;

            req.uri(uri)
                .header(AUTHORIZATION, Bytes::from(authorization))
                .body(B::default())
                .unwrap()
        };

        let res = client.request(req);
        FutureTwitterStream {
            response: timeout(res, self.inner.timeout),
        }
    }
}

impl<'a, C, A> TwitterStreamBuilder<'a, Token<C, A>> {
    /// Reset the HTTP request method to be used when connecting
    /// to the server.
    pub fn method(&mut self, method: RequestMethod) -> &mut Self {
        self.method = method;
        self
    }

    /// Reset the API endpoint URI to be connected.
    pub fn endpoint(&mut self, endpoint: Uri) -> &mut Self {
        self.endpoint = endpoint;
        self
    }

    /// Reset the token to be used to log into Twitter.
    pub fn token(&mut self, token: Token<C, A>) -> &mut Self {
        self.token = token;
        self
    }

    /// Set a timeout for the stream.
    ///
    /// Passing `None` disables the timeout.
    ///
    /// Default is 90 seconds.
    pub fn timeout(&mut self, timeout: impl Into<Option<Duration>>) -> &mut Self {
        self.inner.timeout = timeout.into();
        self
    }

    /// Set whether to receive messages when in danger of
    /// being disconnected.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#stall-warnings
    pub fn stall_warnings(&mut self, stall_warnings: bool) -> &mut Self {
        self.inner.stall_warnings = stall_warnings;
        self
    }

    /// Set the minimum `filter_level` Tweet attribute to receive.
    /// The default is `FilterLevel::None`.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#filter-level
    pub fn filter_level(&mut self, filter_level: impl Into<Option<FilterLevel>>) -> &mut Self {
        self.inner.filter_level = filter_level.into();
        self
    }

    /// Set a comma-separated language identifiers to receive Tweets
    /// written in the specified languages only.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#language
    pub fn language(&mut self, language: impl Into<Option<&'a str>>) -> &mut Self {
        self.inner.language = language.into();
        self
    }

    /// Set a list of user IDs to receive Tweets from the specified users.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#follow
    pub fn follow(&mut self, follow: impl Into<Option<&'a [u64]>>) -> &mut Self {
        self.inner.follow = follow.into();
        self
    }

    /// A comma separated list of phrases to filter Tweets by.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#track
    pub fn track(&mut self, track: impl Into<Option<&'a str>>) -> &mut Self {
        self.inner.track = track.into();
        self
    }

    /// Set a list of bounding boxes to filter Tweets by,
    /// specified by a pair of coordinates in the form of
    /// `((longitude, latitude), (longitude, latitude))` tuple.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#locations
    pub fn locations(
        &mut self,
        locations: impl Into<Option<&'a [((f64, f64), (f64, f64))]>>,
    ) -> &mut Self {
        self.inner.locations = locations.into();
        self
    }

    /// The `count` parameter.
    /// This parameter requires elevated access to use.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#count
    pub fn count(&mut self, count: impl Into<Option<i32>>) -> &mut Self {
        self.inner.count = count.into();
        self
    }
}

#[cfg(feature = "tls")]
impl TwitterStream {
    /// A shorthand for `TwitterStreamBuilder::filter().listen()`.
    pub fn filter<C, A>(token: Token<C, A>) -> Result<FutureTwitterStream, error::TlsError>
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        TwitterStreamBuilder::filter(token).listen()
    }

    /// A shorthand for `TwitterStreamBuilder::sample().listen()`.
    pub fn sample<C, A>(token: Token<C, A>) -> Result<FutureTwitterStream, error::TlsError>
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        TwitterStreamBuilder::sample(token).listen()
    }
}

impl Future for FutureTwitterStream {
    type Item = TwitterStream;
    type Error = Error;

    fn poll(&mut self) -> Poll<TwitterStream, Error> {
        let res = try_ready!(self.response.poll());
        let (parts, body) = res.into_parts();
        let Parts {
            status, headers, ..
        } = parts;

        if StatusCode::OK != status {
            return Err(Error::Http(status));
        }

        let body = timeout_to_stream(&self.response, body);
        let use_gzip = headers
            .get_all(CONTENT_ENCODING)
            .iter()
            .any(|e| e == "gzip");
        let inner = if use_gzip {
            Lines::new(MaybeGzip::gzip(body))
        } else {
            Lines::new(MaybeGzip::identity(body))
        };

        Ok(TwitterStream { inner }.into())
    }
}

impl Stream for TwitterStream {
    type Item = string::String<Bytes>;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<string::String<Bytes>>, Error> {
        loop {
            match self.inner.poll() {
                Ok(Async::Ready(Some(line))) => {
                    if line.iter().all(|&c| is_json_whitespace(c)) {
                        continue;
                    }

                    // TODO: change the return type to `std::string::String` in v0.10.
                    let line = Bytes::from(line);
                    let line = string::String::<Bytes>::try_from(line).map_err(Error::Utf8)?;
                    return Ok(Async::Ready(Some(line)));
                }
                Ok(Async::Ready(None)) => return Ok(Async::Ready(None)),
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(e) => match *self.inner.get_mut() {
                    Either::A(ref mut gzip) => {
                        if let Some(e) = gzip.get_mut().take_err() {
                            return Err(e);
                        } else {
                            return Err(Error::Gzip(e));
                        }
                    }
                    Either::B(ref mut stream_read) => return Err(stream_read.take_err().unwrap()),
                },
            }
        }
    }
}

fn is_json_whitespace(c: u8) -> bool {
    // RFC7159 §2
    b" \t\n\r".contains(&c)
}
<commit_msg>Minor cleanup<commit_after>#![doc(html_root_url = "https://docs.rs/twitter-stream/0.9.0")]
#![recursion_limit = "128"]

/*!
# Twitter Stream

A library for listening on Twitter Streaming API.

## Usage

Add `twitter-stream` to your dependencies in your project's `Cargo.toml`:

```toml
[dependencies]
twitter-stream = "0.9"
```

and this to your crate root:

```rust,no_run
extern crate twitter_stream;
```

## Overview

Here is a basic example that prints public mentions to @Twitter in JSON format:

```rust,no_run
extern crate twitter_stream;

use twitter_stream::{Token, TwitterStreamBuilder};
use twitter_stream::rt::{self, Future, Stream};

# fn main() {
let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");

let future = TwitterStreamBuilder::filter(token)
    .track(Some("@Twitter"))
    .listen()
    .unwrap()
    .flatten_stream()
    .for_each(|json| {
        println!("{}", json);
        Ok(())
    })
    .map_err(|e| println!("error: {}", e));

rt::run(future);
# }
```
*/

extern crate bytes;
extern crate cfg_if;
extern crate futures;
extern crate http;
extern crate hyper;
#[cfg(feature = "tls")]
extern crate hyper_tls;
extern crate libflate;
extern crate oauth1_request as oauth;
extern crate oauth1_request_derive;
#[cfg(feature = "serde")]
extern crate serde;
extern crate static_assertions;
extern crate string;
extern crate tokio_io;
extern crate tokio_timer;

#[macro_use]
mod util;

pub mod error;
#[cfg(feature = "runtime")]
pub mod rt;
pub mod types;

mod gzip;
mod token;

pub use error::Error;
pub use token::Token;

use std::borrow::Borrow;
use std::time::Duration;

use bytes::Bytes;
use futures::{try_ready, Async, Future, Poll, Stream};
use http::response::Parts;
use hyper::body::{Body, Payload};
use hyper::client::connect::Connect;
use hyper::client::{Client, ResponseFuture};
use hyper::header::{
    HeaderValue, ACCEPT_ENCODING, AUTHORIZATION, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TYPE,
};
use hyper::Request;
use oauth::OAuth1Authorize;
use oauth1_request_derive::OAuth1Authorize;
use string::TryFrom;

use gzip::MaybeGzip;
use types::{FilterLevel, RequestMethod, StatusCode, Uri};
use util::*;

/// A builder for `TwitterStream`.
///
/// ## Example
///
/// ```rust,no_run
/// extern crate twitter_stream;
///
/// use twitter_stream::{Token, TwitterStreamBuilder};
/// use twitter_stream::rt::{self, Future, Stream};
///
/// # fn main() {
/// let token = Token::new("consumer_key", "consumer_secret", "access_key", "access_secret");
///
/// let future = TwitterStreamBuilder::sample(token)
///     .timeout(None)
///     .listen()
///     .unwrap()
///     .flatten_stream()
///     .for_each(|json| {
///         println!("{}", json);
///         Ok(())
///     })
///     .map_err(|e| println!("error: {}", e));
///
/// rt::run(future);
/// # }
/// ```
#[derive(Clone, Debug)]
pub struct TwitterStreamBuilder<'a, T = Token> {
    method: RequestMethod,
    endpoint: Uri,
    token: T,
    inner: BuilderInner<'a>,
}

/// A future returned by constructor methods
/// which resolves to a `TwitterStream`.
pub struct FutureTwitterStream {
    response: MaybeTimeout<ResponseFuture>,
}

/// A listener for Twitter Streaming API.
/// It yields JSON strings returned from the API.
pub struct TwitterStream {
    inner: Lines<MaybeGzip<MaybeTimeoutStream<Body>>>,
}

#[derive(Clone, Debug, OAuth1Authorize)]
struct BuilderInner<'a> {
    #[oauth1(skip)]
    timeout: Option<Duration>,
    #[oauth1(skip_if = "not")]
    stall_warnings: bool,
    #[oauth1(option)]
    filter_level: Option<FilterLevel>,
    #[oauth1(option)]
    language: Option<&'a str>,
    #[oauth1(option, encoded, fmt = "fmt_follow")]
    follow: Option<&'a [u64]>,
    #[oauth1(option)]
    track: Option<&'a str>,
    #[oauth1(encoded, option, fmt = "fmt_locations")]
    #[allow(clippy::type_complexity)]
    locations: Option<&'a [((f64, f64), (f64, f64))]>,
    #[oauth1(encoded, option)]
    count: Option<i32>,
}

impl<'a, C, A> TwitterStreamBuilder<'a, Token<C, A>>
where
    C: Borrow<str>,
    A: Borrow<str>,
{
    /// Create a builder for `POST statuses/filter` endpoint.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://dev.twitter.com/streaming/reference/post/statuses/filter
    pub fn filter(token: Token<C, A>) -> Self {
        const URI: &str = "https://stream.twitter.com/1.1/statuses/filter.json";
        Self::custom(RequestMethod::POST, Uri::from_static(URI), token)
    }

    /// Create a builder for `GET statuses/sample` endpoint.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://dev.twitter.com/streaming/reference/get/statuses/sample
    pub fn sample(token: Token<C, A>) -> Self {
        const URI: &str = "https://stream.twitter.com/1.1/statuses/sample.json";
        Self::custom(RequestMethod::GET, Uri::from_static(URI), token)
    }

    /// Constructs a builder for a Stream at a custom endpoint.
    pub fn custom(method: RequestMethod, endpoint: Uri, token: Token<C, A>) -> Self {
        Self {
            method,
            endpoint,
            token,
            inner: BuilderInner {
                timeout: Some(Duration::from_secs(90)),
                stall_warnings: false,
                filter_level: None,
                language: None,
                follow: None,
                track: None,
                locations: None,
                count: None,
            },
        }
    }

    /// Start listening on the Streaming API endpoint, returning a `Future` which resolves
    /// to a `Stream` yielding JSON messages from the API.
    #[cfg(feature = "tls")]
    pub fn listen(&self) -> Result<FutureTwitterStream, error::TlsError> {
        let conn = hyper_tls::HttpsConnector::new(1)?;
        Ok(self.listen_with_client(&Client::builder().build::<_, Body>(conn)))
    }

    /// Same as `listen` except that it uses `client` to make HTTP request to the endpoint.
    pub fn listen_with_client<Conn, B>(&self, client: &Client<Conn, B>) -> FutureTwitterStream
    where
        Conn: Connect + Sync + 'static,
        Conn::Transport: 'static,
        Conn::Future: 'static,
        B: Default + From<Vec<u8>> + Payload + Send + 'static,
        B::Data: Send,
    {
        let mut req = Request::builder();
        req.method(self.method.clone())
            .header(ACCEPT_ENCODING, HeaderValue::from_static("gzip"));

        let req = if RequestMethod::POST == self.method {
            let oauth::Request {
                authorization,
                data,
            } = self.inner.authorize_form(
                "POST",
                &self.endpoint,
                self.token.consumer_key.borrow(),
                self.token.consumer_secret.borrow(),
                self.token.access_secret.borrow(),
                oauth::HmacSha1,
                &*oauth::Options::new().token(self.token.access_key.borrow()),
            );

            req.uri(self.endpoint.clone())
                .header(AUTHORIZATION, Bytes::from(authorization))
                .header(
                    CONTENT_TYPE,
                    HeaderValue::from_static("application/x-www-form-urlencoded"),
                )
                .header(CONTENT_LENGTH, Bytes::from(data.len().to_string()))
                .body(data.into_bytes().into())
                .unwrap()
        } else {
            let oauth::Request {
                authorization,
                data: uri,
            } = self.inner.authorize(
                self.method.as_ref(),
                &self.endpoint,
                self.token.consumer_key.borrow(),
                self.token.consumer_secret.borrow(),
                self.token.access_secret.borrow(),
                oauth::HmacSha1,
                &*oauth::Options::new().token(self.token.access_key.borrow()),
            );

            req.uri(uri)
                .header(AUTHORIZATION, Bytes::from(authorization))
                .body(B::default())
                .unwrap()
        };

        let res = client.request(req);
        FutureTwitterStream {
            response: timeout(res, self.inner.timeout),
        }
    }
}

impl<'a, C, A> TwitterStreamBuilder<'a, Token<C, A>> {
    /// Reset the HTTP request method to be used when connecting
    /// to the server.
    pub fn method(&mut self, method: RequestMethod) -> &mut Self {
        self.method = method;
        self
    }

    /// Reset the API endpoint URI to be connected.
    pub fn endpoint(&mut self, endpoint: Uri) -> &mut Self {
        self.endpoint = endpoint;
        self
    }

    /// Reset the token to be used to log into Twitter.
    pub fn token(&mut self, token: Token<C, A>) -> &mut Self {
        self.token = token;
        self
    }

    /// Set a timeout for the stream.
    ///
    /// Passing `None` disables the timeout.
    ///
    /// Default is 90 seconds.
    pub fn timeout(&mut self, timeout: impl Into<Option<Duration>>) -> &mut Self {
        self.inner.timeout = timeout.into();
        self
    }

    /// Set whether to receive messages when in danger of
    /// being disconnected.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#stall-warnings
    pub fn stall_warnings(&mut self, stall_warnings: bool) -> &mut Self {
        self.inner.stall_warnings = stall_warnings;
        self
    }

    /// Set the minimum `filter_level` Tweet attribute to receive.
    /// The default is `FilterLevel::None`.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#filter-level
    pub fn filter_level(&mut self, filter_level: impl Into<Option<FilterLevel>>) -> &mut Self {
        self.inner.filter_level = filter_level.into();
        self
    }

    /// Set a comma-separated language identifiers to receive Tweets
    /// written in the specified languages only.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#language
    pub fn language(&mut self, language: impl Into<Option<&'a str>>) -> &mut Self {
        self.inner.language = language.into();
        self
    }

    /// Set a list of user IDs to receive Tweets from the specified users.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#follow
    pub fn follow(&mut self, follow: impl Into<Option<&'a [u64]>>) -> &mut Self {
        self.inner.follow = follow.into();
        self
    }

    /// A comma separated list of phrases to filter Tweets by.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#track
    pub fn track(&mut self, track: impl Into<Option<&'a str>>) -> &mut Self {
        self.inner.track = track.into();
        self
    }

    /// Set a list of bounding boxes to filter Tweets by,
    /// specified by a pair of coordinates in the form of
    /// `((longitude, latitude), (longitude, latitude))` tuple.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#locations
    pub fn locations(
        &mut self,
        locations: impl Into<Option<&'a [((f64, f64), (f64, f64))]>>,
    ) -> &mut Self {
        self.inner.locations = locations.into();
        self
    }

    /// The `count` parameter.
    /// This parameter requires elevated access to use.
    ///
    /// See the [Twitter Developer Documentation][1] for more information.
    ///
    /// [1]: https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters#count
    pub fn count(&mut self, count: impl Into<Option<i32>>) -> &mut Self {
        self.inner.count = count.into();
        self
    }
}

#[cfg(feature = "tls")]
impl TwitterStream {
    /// A shorthand for `TwitterStreamBuilder::filter().listen()`.
    pub fn filter<C, A>(token: Token<C, A>) -> Result<FutureTwitterStream, error::TlsError>
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        TwitterStreamBuilder::filter(token).listen()
    }

    /// A shorthand for `TwitterStreamBuilder::sample().listen()`.
    pub fn sample<C, A>(token: Token<C, A>) -> Result<FutureTwitterStream, error::TlsError>
    where
        C: Borrow<str>,
        A: Borrow<str>,
    {
        TwitterStreamBuilder::sample(token).listen()
    }
}

impl Future for FutureTwitterStream {
    type Item = TwitterStream;
    type Error = Error;

    fn poll(&mut self) -> Poll<TwitterStream, Error> {
        let res = try_ready!(self.response.poll());
        let (parts, body) = res.into_parts();
        let Parts {
            status, headers, ..
        } = parts;

        if StatusCode::OK != status {
            return Err(Error::Http(status));
        }

        let body = timeout_to_stream(&self.response, body);
        let use_gzip = headers
            .get_all(CONTENT_ENCODING)
            .iter()
            .any(|e| e == "gzip");
        let inner = if use_gzip {
            Lines::new(MaybeGzip::gzip(body))
        } else {
            Lines::new(MaybeGzip::identity(body))
        };

        Ok(TwitterStream { inner }.into())
    }
}

impl Stream for TwitterStream {
    type Item = string::String<Bytes>;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<string::String<Bytes>>, Error> {
        loop {
            match self.inner.poll() {
                Ok(Async::Ready(Some(line))) => {
                    if line.iter().all(|&c| is_json_whitespace(c)) {
                        continue;
                    }

                    // TODO: change the return type to `std::string::String` in v0.10.
                    let line = Bytes::from(line);
                    let line = string::String::<Bytes>::try_from(line).map_err(Error::Utf8)?;
                    return Ok(Async::Ready(Some(line)));
                }
                Ok(Async::Ready(None)) => return Ok(Async::Ready(None)),
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Err(e) => match *self.inner.get_mut() {
                    Either::A(ref mut gzip) => {
                        if let Some(e) = gzip.get_mut().take_err() {
                            return Err(e);
                        } else {
                            return Err(Error::Gzip(e));
                        }
                    }
                    Either::B(ref mut stream_read) => return Err(stream_read.take_err().unwrap()),
                },
            }
        }
    }
}

fn is_json_whitespace(c: u8) -> bool {
    // RFC7159 §2
    b" \t\n\r".contains(&c)
}
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]
#![feature(unboxed_closures, phase)]
#![experimental]

//! # Handlebars
//! Handlebars is a modern and extensible templating solution originally created in the JavaScript world. It's used by many popular frameworks like [Ember.js](http://emberjs.com) and Chaplin. It's also ported to some other platforms such as [Java](https://github.com/jknack/handlebars.java).
//!
//! And this is handlebars Rust implementation, designed for server-side page generation. It's a general-purpose library so you use it for any kind of text generation.
//!
//! ## Handlebars spec
//!
//! ### Base
//!
//! You can go to [Handlebars.js](http://handlebarsjs.com/) website for its syntax. This implementation should be compatible with most parts of the spec, except:
//!
//! * raw helper syntax `{{{raw-helper}}}...{{{/raw-helper}}}` is implemented as block helper raw.
//! * configurable logging (hard-coded to rust native logging, with fixed level `INFO`)
//!
//! ### Extensions
//!
//! We have template reuse facilities supported via built-in helpers `>`, `partial` and `block`.
//!
//! There are two ways to reuse a template:
//!
//! * include (using `>`)
//! * inheritance (using `>` together with `block` and `partial`)
//!
//! Consult [Handlebar.java document about template inheritance](http://jknack.github.io/handlebars.java/reuse.html).
//!
//! ## Usage
//!
//! ### Template Creation
//!
//! Templates are created from String.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::Template;
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string).unwrap();
//! }
//! ```
//!
//! ### Registration
//!
//! All the templates and helpers have to be registered into Registry, so they can look up each other by name.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::{Template, Registry};
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string).unwrap();
//!
//!   let mut handlebars = Registry::new();
//!   handlebars.register_template("hello_world", &tpl);
//! }
//! ```
//!
//! ### Rendering Something
//!
//! I should say that rendering is a little tricky. Since handlebars is originally a JavaScript templating framework. It supports dynamic features like duck-typing, truthy/falsy values. But for a static language like Rust, this is a little difficult. As a solution, I'm using the `serialize::json::Json` internally for data rendering, which seems good by far.
//!
//! That means, if you want to render something, you have to ensure that it implements the `serialize::json::ToJson` trait. Luckily, most built-in types already have trait. However, if you want to render your custom struct, you need to implement this trait manually. (Rust has a deriving facility, but it's just for selected types. Maybe I will add some syntax extensions or macros to simplify this process.)
//!
//! ```
//! extern crate handlebars;
//!
//! use serialize::json::ToJson;
//! use std.collections::BTreeMap;
//!
//! use handlebars::{Template, Registry};
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string).unwrap();
//!
//!   let mut handlebars = Registry::new();
//!   handlebars.register_template("hello_world", &tpl);
//!
//!   let mut data = BTreeMap::new();
//!   data.insert("world", "world".to_json());
//!   let result = handlebars.render("hello_world", &data);
//! }
//! ```
//!
//! ### Custom Helper
//!
//! Handlebars is nothing without helpers. You can also create your own helpers with rust. Helpers in handlebars-rust are custom struct implements the `HelperDef` trait, concretely, the `resolve` function.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::{Registry, HelperDef, RenderError, RenderContext, Helper, Context};
//!
//! #[deriving(Copy)]
//! struct SimpleHelper;
//!
//! impl HelperDef for SimpleHelper {
//!   fn resolve(&self, c: &Context, h: &Helper, _: &Registry, rc: &mut RenderContext) -> Result<String, RenderError> {
//!     let param = h.params().get(0).unwrap();
//!
//!     // get value from context data
//!     // rc.get_path() is current json parent path, you should always use it like this
//!     // param is the key of value you want to display
//!     let value = c.navigate(rc.get_path(), param);
//!     Ok(format!("My helper dumps: {} ", value))
//!   }
//! }
//!
//! // create an instance
//! static MY_HELPER: SimpleHelper = SimpleHelper;
//!
//! fn main() {
//!   let mut handlebars = Registry::new();
//!   handlebars.register_helper("simple-helper", box MY_HELPER);
//!
//!   //...
//! }
//! ```
//!
//! You can get data from the `Helper` argument about the template information:
//!
//! * `name()` for the helper name. This is known to you for most situation but if you are defining `helperMissing` or `blockHelperMissing`, this is important.
//! * `params()` is a vector of String as params in helper, like `{{#somehelper param1 param2 param3}}`.
//! * `hash()` is a map of String key and Json value, defined in helper as `{{@somehelper a=1 b="2" c=true}}`.
//! * `template()` gives you the nested template of block helper.
//! * `inverse()` gives you the inversed template of it, inversed template is the template behind `{{else}}`.
//!
//! You can learn more about helpers by looking into source code of built-in helpers.
//!
//! ## TODO
//!
//! * More friendly ToJson
//! * Better error report
//!

extern crate serialize;
extern crate regex;
#[phase(plugin)]
extern crate regex_macros;

#[phase(plugin, link)]
extern crate log;

pub use self::template::{Template, Helper};
pub use self::registry::{Registry};
pub use self::render::{Renderable, RenderError, RenderContext};
pub use self::helpers::{HelperDef};
pub use self::context::{Context, JsonRender, JsonTruthy};

mod template;
mod registry;
mod render;
mod helpers;
mod context;
<commit_msg>fixed doctests.<commit_after>#![allow(dead_code, unused_variables)]
#![feature(unboxed_closures, phase)]
#![experimental]

//! # Handlebars
//! Handlebars is a modern and extensible templating solution originally created in the JavaScript world. It's used by many popular frameworks like [Ember.js](http://emberjs.com) and Chaplin. It's also ported to some other platforms such as [Java](https://github.com/jknack/handlebars.java).
//!
//! And this is handlebars Rust implementation, designed for server-side page generation. It's a general-purpose library so you use it for any kind of text generation.
//!
//! ## Handlebars spec
//!
//! ### Base
//!
//! You can go to [Handlebars.js](http://handlebarsjs.com/) website for its syntax. This implementation should be compatible with most parts of the spec, except:
//!
//! * raw helper syntax `{{{raw-helper}}}...{{{/raw-helper}}}` is implemented as block helper raw.
//! * configurable logging (hard-coded to rust native logging, with fixed level `INFO`)
//!
//! ### Extensions
//!
//! We have template reuse facilities supported via built-in helpers `>`, `partial` and `block`.
//!
//! There are two ways to reuse a template:
//!
//! * include (using `>`)
//! * inheritance (using `>` together with `block` and `partial`)
//!
//! Consult [Handlebar.java document about template inheritance](http://jknack.github.io/handlebars.java/reuse.html).
//!
//! ## Usage
//!
//! ### Template Creation
//!
//! Templates are created from String.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::Template;
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string()).unwrap();
//! }
//! ```
//!
//! ### Registration
//!
//! All the templates and helpers have to be registered into Registry, so they can look up each other by name.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::{Template, Registry};
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string()).unwrap();
//!
//!   let mut handlebars = Registry::new();
//!   handlebars.register_template("hello_world", &tpl);
//! }
//! ```
//!
//! ### Rendering Something
//!
//! I should say that rendering is a little tricky. Since handlebars is originally a JavaScript templating framework. It supports dynamic features like duck-typing, truthy/falsy values. But for a static language like Rust, this is a little difficult. As a solution, I'm using the `serialize::json::Json` internally for data rendering, which seems good by far.
//!
//! That means, if you want to render something, you have to ensure that it implements the `serialize::json::ToJson` trait. Luckily, most built-in types already have trait. However, if you want to render your custom struct, you need to implement this trait manually. (Rust has a deriving facility, but it's just for selected types. Maybe I will add some syntax extensions or macros to simplify this process.)
//!
//! ```
//! extern crate serialize;
//! extern crate handlebars;
//!
//! use serialize::json::{Json, ToJson};
//! use std::collections::BTreeMap;
//!
//! use handlebars::{Template, Registry};
//!
//! struct Person {
//!   name: String,
//!   age: i16,
//! }
//!
//! impl ToJson for Person {
//!   fn to_json(&self) -> Json {
//!     let mut m = BTreeMap::new();
//!     m.insert("name".to_string(), self.name.to_json());
//!     m.insert("age".to_string(), self.age.to_json());
//!     Json::Object(m)
//!   }
//! }
//!
//!
//! fn main() {
//!   let source = "hello {{world}}";
//!   //compile returns an Option, we use unwrap() to deref it directly here
//!   let tpl = Template::compile(source.to_string()).unwrap();
//!
//!   let mut handlebars = Registry::new();
//!   handlebars.register_template("hello_world", &tpl);
//!
//!   let mut data = Person {
//!       name: "Ning Sun".to_string(),
//!       age: 27
//!   };
//!   let result = handlebars.render("hello_world", &data);
//! }
//! ```
//!
//! ### Custom Helper
//!
//! Handlebars is nothing without helpers. You can also create your own helpers with rust. Helpers in handlebars-rust are custom struct implements the `HelperDef` trait, concretely, the `resolve` function.
//!
//! ```
//! extern crate handlebars;
//!
//! use handlebars::{Registry, HelperDef, RenderError, RenderContext, Helper, Context};
//!
//! #[deriving(Copy)]
//! struct SimpleHelper;
//!
//! impl HelperDef for SimpleHelper {
//!   fn resolve(&self, c: &Context, h: &Helper, _: &Registry, rc: &mut RenderContext) -> Result<String, RenderError> {
//!     let param = h.params().get(0).unwrap();
//!
//!     // get value from context data
//!     // rc.get_path() is current json parent path, you should always use it like this
//!     // param is the key of value you want to display
//!     let value = c.navigate(rc.get_path(), param);
//!     Ok(format!("My helper dumps: {} ", value))
//!   }
//! }
//!
//! // create an instance
//! static MY_HELPER: SimpleHelper = SimpleHelper;
//!
//! fn main() {
//!   let mut handlebars = Registry::new();
//!   handlebars.register_helper("simple-helper", box MY_HELPER);
//!
//!   //...
//! }
//! ```
//!
//! You can get data from the `Helper` argument about the template information:
//!
//! * `name()` for the helper name. This is known to you for most situation but if you are defining `helperMissing` or `blockHelperMissing`, this is important.
//! * `params()` is a vector of String as params in helper, like `{{#somehelper param1 param2 param3}}`.
//! * `hash()` is a map of String key and Json value, defined in helper as `{{@somehelper a=1 b="2" c=true}}`.
//! * `template()` gives you the nested template of block helper.
//! * `inverse()` gives you the inversed template of it, inversed template is the template behind `{{else}}`.
//!
//! You can learn more about helpers by looking into source code of built-in helpers.
//!
//! ## TODO
//!
//! * More friendly ToJson
//! * Better error report
//!

extern crate serialize;
extern crate regex;
#[phase(plugin)]
extern crate regex_macros;

#[phase(plugin, link)]
extern crate log;

pub use self::template::{Template, Helper};
pub use self::registry::{Registry};
pub use self::render::{Renderable, RenderError, RenderContext};
pub use self::helpers::{HelperDef};
pub use self::context::{Context, JsonRender, JsonTruthy};

mod template;
mod registry;
mod render;
mod helpers;
mod context;
<|endoftext|>


<commit_before>

pub mod graph {
    use std::collections::HashMap;
    use std::ops::Deref;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, *mut Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, *mut Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;

            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, ptr);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64)  {
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,

        // pointers on both sides, yay
        pub out_edges: Vec<*mut Edge>,
        pub in_edges:  Vec<*mut Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            // in edges
            let in_edges : Vec<*mut Edge> = Vec::new();
            let out_edges: Vec<*mut Edge> = Vec::new();

            Box::new(Vertex{id:id,
                            out_edges: out_edges,
                            in_edges:in_edges})
        }

        pub fn add_out_edge(&mut self, edge: &mut Edge ) {
            let edge_p: *mut Edge = edge;
            self.out_edges.push(edge_p);
        }

        pub fn add_in_edge() {

        }

    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(&mut e);
        }
        pub fn query(self) {

        }
    }

    impl Deref for VertexProxy {
        type Target = &Box<Vertex>;

        fn deref<'a>(&'a self) -> &'a Box<Vertex> {
            *(self.v)
        }
    }

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        println!("here I am");
        assert!(v1.id == 1);

        unsafe {
            let vertex: &mut Box<Vertex> = &mut *(v1.v);
            assert!(vertex.id == 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);

    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<commit_msg>deref support<commit_after>

pub mod graph {
    use std::collections::HashMap;
    use std::ops::Deref;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, *mut Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, *mut Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;

            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, ptr);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64)  {
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,

        // pointers on both sides, yay
        pub out_edges: Vec<*mut Edge>,
        pub in_edges:  Vec<*mut Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            // in edges
            let in_edges : Vec<*mut Edge> = Vec::new();
            let out_edges: Vec<*mut Edge> = Vec::new();

            Box::new(Vertex{id:id,
                            out_edges: out_edges,
                            in_edges:in_edges})
        }

        pub fn add_out_edge(&mut self, edge: &mut Edge ) {
            let edge_p: *mut Edge = edge;
            self.out_edges.push(edge_p);
        }

        pub fn add_in_edge() {

        }

    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(&mut e);
        }
        pub fn query(self) {

        }
    }

    impl Deref for VertexProxy {
        type Target = Box<Vertex>;

        fn deref<'a>(&'a self) -> &'a Box<Vertex> {
            unsafe {
                &*(self.v)
            }
        }
    }

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        println!("here I am");
        assert!(v1.id == 1);

        unsafe {
            let vertex: &mut Box<Vertex> = &mut *(v1.v);
            assert!(vertex.id == 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);

    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<|endoftext|>