<commit_before>#![deny(missing_docs, warnings)]

//! Request logging middleware for Iron

extern crate iron;
#[macro_use] extern crate log;
extern crate time;

use iron::{AfterMiddleware, BeforeMiddleware, IronResult, IronError, Request, Response};
use iron::typemap::Key;

use format::FormatText::{Str, Method, URI, Status, ResponseTime, RemoteAddr, RequestTime};
use format::{FormatText};

use std::fmt::Formatter;

mod format;
pub use format::Format;

/// `Middleware` for logging request and response info to the terminal.
pub struct Logger {
    format: Format,
}

impl Logger {
    /// Create a pair of `Logger` middlewares with the specified `format`. If a `None` is passed in, uses the default format:
    ///
    /// ```ignore
    /// {method} {uri} -> {status} ({response-time} ms)
    /// ```
    ///
    /// While the returned value can be passed straight to `Chain::link`, consider making the logger `BeforeMiddleware`
    /// the first in your chain and the logger `AfterMiddleware` the last by doing something like this:
    ///
    /// ```ignore
    /// let mut chain = Chain::new(handler);
    /// let (logger_before, logger_after) = Logger::new(None);
    /// chain.link_before(logger_before);
    /// // link other middlewares here...
    /// chain.link_after(logger_after);
    /// ```
    pub fn new(format: Option<Format>) -> (Logger, Logger) {
        let format = format.unwrap_or_default();
        (Logger { format: format.clone() }, Logger { format: format })
    }
}

struct StartTime;
impl Key for StartTime { type Value = time::Tm; }

impl Logger {
    fn initialise(&self, req: &mut Request) {
        req.extensions.insert::<StartTime>(time::now());
    }

    fn log(&self, req: &mut Request, res: &Response) -> IronResult<()> {
        let entry_time = *req.extensions.get::<StartTime>().unwrap();

        let response_time = time::now() - entry_time;
        let response_time_ms = (response_time.num_seconds() * 1000) as f64 + (response_time.num_nanoseconds().unwrap_or(0) as f64) / 1000000.0;

        {
            let render = |fmt: &mut Formatter, text: &FormatText| {
                match *text {
                    Str(ref string) => fmt.write_str(string),
                    Method => fmt.write_fmt(format_args!("{}", req.method)),
                    URI => fmt.write_fmt(format_args!("{}", req.url)),
                    Status => match res.status {
                        Some(status) => fmt.write_fmt(format_args!("{}", status)),
                        None => fmt.write_str("<missing status code>"),
                    },
                    ResponseTime => fmt.write_fmt(format_args!("{} ms", response_time_ms)),
                    RemoteAddr => fmt.write_fmt(format_args!("{}", req.remote_addr)),
                    RequestTime => {
                        fmt.write_fmt(format_args!("{}",
                                                   entry_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ%z")
                                                   .unwrap()))
                    },
                }
            };

            info!("{}", format::display_with(&self.format, &render));
        }

        Ok(())
    }
}

impl BeforeMiddleware for Logger {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        self.initialise(req);
        Ok(())
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        self.initialise(req);
        Err(err)
    }
}

impl AfterMiddleware for Logger {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        try!(self.log(req, &res));
        Ok(res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        try!(self.log(req, &err.response));
        Err(err)
    }
}
<commit_msg>Call `Display::fmt` directly, rather than using `format_args!`.<commit_after>#![deny(missing_docs, warnings)]

//! Request logging middleware for Iron

extern crate iron;
#[macro_use] extern crate log;
extern crate time;

use iron::{AfterMiddleware, BeforeMiddleware, IronResult, IronError, Request, Response};
use iron::typemap::Key;

use format::FormatText::{Str, Method, URI, Status, ResponseTime, RemoteAddr, RequestTime};
use format::{FormatText};

use std::fmt::{Display, Formatter};

mod format;
pub use format::Format;

/// `Middleware` for logging request and response info to the terminal.
pub struct Logger {
    format: Format,
}

impl Logger {
    /// Create a pair of `Logger` middlewares with the specified `format`. If a `None` is passed in, uses the default format:
    ///
    /// ```ignore
    /// {method} {uri} -> {status} ({response-time} ms)
    /// ```
    ///
    /// While the returned value can be passed straight to `Chain::link`, consider making the logger `BeforeMiddleware`
    /// the first in your chain and the logger `AfterMiddleware` the last by doing something like this:
    ///
    /// ```ignore
    /// let mut chain = Chain::new(handler);
    /// let (logger_before, logger_after) = Logger::new(None);
    /// chain.link_before(logger_before);
    /// // link other middlewares here...
    /// chain.link_after(logger_after);
    /// ```
    pub fn new(format: Option<Format>) -> (Logger, Logger) {
        let format = format.unwrap_or_default();
        (Logger { format: format.clone() }, Logger { format: format })
    }
}

struct StartTime;
impl Key for StartTime { type Value = time::Tm; }

impl Logger {
    fn initialise(&self, req: &mut Request) {
        req.extensions.insert::<StartTime>(time::now());
    }

    fn log(&self, req: &mut Request, res: &Response) -> IronResult<()> {
        let entry_time = *req.extensions.get::<StartTime>().unwrap();

        let response_time = time::now() - entry_time;
        let response_time_ms = (response_time.num_seconds() * 1000) as f64 + (response_time.num_nanoseconds().unwrap_or(0) as f64) / 1000000.0;

        {
            let render = |fmt: &mut Formatter, text: &FormatText| {
                match *text {
                    Str(ref string) => fmt.write_str(string),
                    Method => req.method.fmt(fmt),
                    URI => req.url.fmt(fmt),
                    Status => {
                        match res.status {
                            Some(status) => status.fmt(fmt),
                            None => fmt.write_str("<missing status code>"),
                        }
                    }
                    ResponseTime => fmt.write_fmt(format_args!("{} ms", response_time_ms)),
                    RemoteAddr => req.remote_addr.fmt(fmt),
                    RequestTime => {
                        entry_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ%z")
                            .unwrap()
                            .fmt(fmt)
                    }
                }
            };

            info!("{}", format::display_with(&self.format, &render));
        }

        Ok(())
    }
}

impl BeforeMiddleware for Logger {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        self.initialise(req);
        Ok(())
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        self.initialise(req);
        Err(err)
    }
}

impl AfterMiddleware for Logger {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        try!(self.log(req, &res));
        Ok(res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        try!(self.log(req, &err.response));
        Err(err)
    }
}
<|endoftext|>


<commit_before>extern crate nalgebra;

use nalgebra::{DMat, Zero, Indexable};
use std::ops::{Add, Sub};
use std::fmt::{Display};

pub trait SourceValue<T>: Display + Zero + Clone + Copy + Add<T,Output=T> + Sub<T,Output=T> {
}

pub trait SummedAreaTableSource<T: SourceValue<T>>{

	fn get_values(&self) -> &DMat<T>;

	fn calculate_summed_area_table(&self) -> SummedAreaTable<T>{
		let vals = self.get_values();
		let mut table = DMat::new_zeros(vals.nrows(),vals.ncols());

		for row in (0 ..vals.nrows()) {
			for col in (0 ..vals.ncols()) {
				let mut sum = vals.at((row, col));

				if row>0 {
					sum = sum+ table.at((row-1, col));
				}
				if col>0 {
					sum = sum+ table.at((row, col-1));
				}
				if row>0 && col>0 {
					sum = sum - table.at((row-1, col-1));
				}
				table.set((row,col), sum);
			}
		}

		SummedAreaTable::<T>{table: table}
	}
}

pub struct SummedAreaTable<T: SourceValue<T>> {
	table: DMat<T>,
}

impl <T: SourceValue<T>>SummedAreaTable<T> {
	fn get_sum(&self, from: (usize,usize), to: (usize,usize)) -> T{
		let (x1, y1) = from;
		let (x2, y2) = to;

		let mut sum = self.table.at((x2,y2));

		if x1 > 0 {
			sum = sum - self.table.at((x1-1,y2));
		}
		if y1 > 0 {
			sum = sum - self.table.at((x2,y1-1));
		}
		if x1 > 0 && y1 > 0 {
			sum = sum + self.table.at((x1-1,y1-1));
		}
		sum
	}
}

impl SourceValue<usize> for usize {
}

impl SummedAreaTableSource<usize> for DMat<usize>{
	fn get_values(&self) -> &DMat<usize> {
		self
	}
}

#[test]
fn zeros() {
	let src: DMat<usize> = DMat::new_zeros(100,100);
	let table = src.calculate_summed_area_table();
	assert_eq!(0, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(10000, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones_without_first_col_row() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(10000-199, table.get_sum((1,1),(99,99)));
}

#[test]
fn twos() {
	let src: DMat<usize> = DMat::from_elem(100,100,2);
	let table = src.calculate_summed_area_table();
	assert_eq!(20000, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones_quartered() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(2500, table.get_sum((0,0),(49,49)));
	assert_eq!(2500, table.get_sum((50,50),(99,99)));
	assert_eq!(2500, table.get_sum((50,0),(99,49)));
	assert_eq!(2500, table.get_sum((0,50),(49,99)));
}

#[test]
fn twos_quartered() {
	let src: DMat<usize> = DMat::from_elem(100,100,2);
	let table = src.calculate_summed_area_table();
	assert_eq!(5000, table.get_sum((0,0),(49,49)));
	assert_eq!(5000, table.get_sum((50,50),(99,99)));
	assert_eq!(5000, table.get_sum((50,0),(99,49)));
	assert_eq!(5000, table.get_sum((0,50),(49,99)));
}

<commit_msg>added some comments<commit_after>extern crate nalgebra;

use nalgebra::{DMat, Zero, Indexable};
use std::ops::{Add, Sub};
use std::fmt::{Display};

/// This trait describes the type of values within a summed area table source.
/// Implementing this trait for your type allows it to become a value within a source.
pub trait SourceValue<T>: Display + Zero + Clone + Copy + Add<T,Output=T> + Sub<T,Output=T> {
}

/// This trait describes a generic source for a summed area table.
/// Implementing this trait for your type allows it to become the source for a summed area table calculation.
pub trait SummedAreaTableSource<T: SourceValue<T>>{

	/// Returns a matrix of source values of type T.
	/// The calculated summed area table will be based on these values.
	fn get_values(&self) -> &DMat<T>;

	/// Calculates and returns the summed area table for the source matrix.
	fn calculate_summed_area_table(&self) -> SummedAreaTable<T>{
		let vals = self.get_values();
		let mut table = DMat::new_zeros(vals.nrows(),vals.ncols());

		for row in (0 ..vals.nrows()) {
			for col in (0 ..vals.ncols()) {
				let mut sum = vals.at((row, col));

				if row>0 {
					sum = sum+ table.at((row-1, col));
				}
				if col>0 {
					sum = sum+ table.at((row, col-1));
				}
				if row>0 && col>0 {
					sum = sum - table.at((row-1, col-1));
				}
				table.set((row,col), sum);
			}
		}

		SummedAreaTable::<T>{table: table}
	}
}

/// This struct is the result of a summed area table calculation.
pub struct SummedAreaTable<T: SourceValue<T>> {
	table: DMat<T>,
}

impl <T: SourceValue<T>>SummedAreaTable<T> {

	/// Returns the sum for a given area.
	/// That is described by its upper left and lower right point.
	/// `from` is a x/y coordinate tuple for the upper left point (inclusive)
	/// `to` is a x/y coordinate tuple for the lower right point (inclusive)
	fn get_sum(&self, from: (usize,usize), to: (usize,usize)) -> T{
		let (x1, y1) = from;
		let (x2, y2) = to;

		let mut sum = self.table.at((x2,y2));

		if x1 > 0 {
			sum = sum - self.table.at((x1-1,y2));
		}
		if y1 > 0 {
			sum = sum - self.table.at((x2,y1-1));
		}
		if x1 > 0 && y1 > 0 {
			sum = sum + self.table.at((x1-1,y1-1));
		}
		sum
	}
}

impl SourceValue<usize> for usize {
}

impl SummedAreaTableSource<usize> for DMat<usize>{
	fn get_values(&self) -> &DMat<usize> {
		self
	}
}

#[test]
fn zeros() {
	let src: DMat<usize> = DMat::new_zeros(100,100);
	let table = src.calculate_summed_area_table();
	assert_eq!(0, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(10000, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones_without_first_col_row() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(10000-199, table.get_sum((1,1),(99,99)));
}

#[test]
fn twos() {
	let src: DMat<usize> = DMat::from_elem(100,100,2);
	let table = src.calculate_summed_area_table();
	assert_eq!(20000, table.get_sum((0,0),(99,99)));
}

#[test]
fn ones_quartered() {
	let src: DMat<usize> = DMat::from_elem(100,100,1);
	let table = src.calculate_summed_area_table();
	assert_eq!(2500, table.get_sum((0,0),(49,49)));
	assert_eq!(2500, table.get_sum((50,50),(99,99)));
	assert_eq!(2500, table.get_sum((50,0),(99,49)));
	assert_eq!(2500, table.get_sum((0,50),(49,99)));
}

#[test]
fn twos_quartered() {
	let src: DMat<usize> = DMat::from_elem(100,100,2);
	let table = src.calculate_summed_area_table();
	assert_eq!(5000, table.get_sum((0,0),(49,49)));
	assert_eq!(5000, table.get_sum((50,50),(99,99)));
	assert_eq!(5000, table.get_sum((50,0),(99,49)));
	assert_eq!(5000, table.get_sum((0,50),(49,99)));
}

<|endoftext|>


<commit_before>
enum Order {
  Ascending,
  Descending,
  Ignore
}

enum Type<'a> {
  Null,
  Boolean,
  Int,
  Long,
  Float,
  Double,
  Bytes,
  String,
  Record(Record<'a>),
  Enum(Enum<'a>),
  Array(Array<'a>),
  Map(Map<'a>),
  Union(&'a[Box<Type<'a>>]),
  Fixed(Fixed<'a>)
}

struct Field<'a> {
  name: &'a str,
  doc: Option<&'a str>,
  av_type: Type<'a>,
  default: &'a str,
  order: Option<Order>
}

struct Record<'a> {
    name: &'a str,
    namespace: Option<&'a str>,
    doc: Option<&'a str>,
    aliases: Option<&'a[&'a str]>,
    fields: &'a[Field<'a>]
}

struct Enum<'a> {
    name: &'a str,
    namespace: Option<&'a str>,
    doc: Option<&'a str>,
    aliases: Option<&'a[&'a str]>,
    symbols: &'a[&'a str]
}

struct Array<'a> {
  items: Box<Type<'a>>
}

struct Map<'a> {
  values: &'a[&'a str]
}

struct Fixed<'a> {
  name: &'a str,
  namespace: Option<&'a str>,
  aliases: Option<&'a[&'a str]>,
  size: i32
}

trait Valid {
  fn valid(&self) -> bool;
}

trait ToType {
  fn to_type(&self) -> Type;
}

impl <'a>ToType for &'a str {
  fn to_type(&self) -> Type {
    return Type::Null;
  }
}

impl <'a>Valid for Field<'a> {
  fn valid(&self) -> bool {
    match &self.av_type {
      _ => false
    }
  }
}

impl <'a>Valid for Record<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Enum<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Array<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Map<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Fixed<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

#[test]
#[should_panic]
fn it_works() {
  let arr: Array = Array {
    items: Box::new(Type::Null)
  };
  let field: Field = Field {
    name: "null_array",
    doc: None,
    av_type: Type::Array(arr),
    default: "null",
    order: Some(Order::Ascending)
  };
  let record: Record = Record {
    name: "record",
    namespace: None,
    doc: None,
    aliases: None,
    fields: &[field]
  };
  println!("hello world");
  assert!(false)
}
<commit_msg>more stubbing out methods<commit_after>use std::str::FromStr;
use std::error::Error;
use std::fmt;

enum Order {
  Ascending,
  Descending,
  Ignore
}

enum Type<'a> {
  Null,
  Boolean,
  Int,
  Long,
  Float,
  Double,
  Bytes,
  String,
  Record(Record<'a>),
  Enum(Enum<'a>),
  Array(Array<'a>),
  Map(Map<'a>),
  Union(&'a[Box<Type<'a>>]),
  Fixed(Fixed<'a>)
}

struct Field<'a> {
  name: &'a str,
  doc: Option<&'a str>,
  av_type: Type<'a>,
  default: &'a str,
  order: Option<Order>
}

struct Record<'a> {
    name: &'a str,
    namespace: Option<&'a str>,
    doc: Option<&'a str>,
    aliases: Option<&'a[&'a str]>,
    fields: &'a[Field<'a>]
}

struct Enum<'a> {
    name: &'a str,
    namespace: Option<&'a str>,
    doc: Option<&'a str>,
    aliases: Option<&'a[&'a str]>,
    symbols: &'a[&'a str]
}

struct Array<'a> {
  items: Box<Type<'a>>
}

struct Map<'a> {
  values: &'a[&'a str]
}

struct Fixed<'a> {
  name: &'a str,
  namespace: Option<&'a str>,
  aliases: Option<&'a[&'a str]>,
  size: i32
}

trait Valid {
  fn valid(&self) -> bool;
}

// trait ToType {
//   fn to_type(&self) -> Option<Type>;
// }

// impl <'a>ToType for &'a str {
//   fn to_type(&self) -> Option<Type> {
//     match &self.as_ref() {
//       "null" => Type::Null,
//       _     => Type::Null

//     }
//   }
// }

struct ParseTypeError<'a> {
  cause: Option<&'a Error>
}

impl <'a>fmt::Debug for ParseTypeError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hi")
    }
}

impl <'a> fmt::Display for ParseTypeError<'a> {
      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hi")
    }
}

impl <'a>Error for ParseTypeError<'a> {

  fn description(&self) -> &str {
    "hi"
  }
}

impl <'a>FromStr for Type<'a> {
  type Err = ParseTypeError<'a>;
  fn from_str(s: &str) -> Result<Self, Self::Err> {
    Ok(Type::Null)
  }
}

impl <'a>Valid for Field<'a> {
  fn valid(&self) -> bool {
    match &self.av_type {
      _ => false
    }
  }
}

impl <'a>Valid for Record<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Enum<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Array<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Map<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

impl <'a>Valid for Fixed<'a> {
  fn valid(&self) -> bool {
    return true;
  }
}

#[test]
#[should_panic]
fn it_works() {
  let arr: Array = Array {
    items: Box::new(Type::Null)
  };
  let field: Field = Field {
    name: "null_array",
    doc: None,
    av_type: Type::Array(arr),
    default: "null",
    order: Some(Order::Ascending)
  };
  let record: Record = Record {
    name: "record",
    namespace: None,
    doc: None,
    aliases: None,
    fields: &[field]
  };
  println!("hello world");
  assert!(false)
}
<|endoftext|>


<commit_before>//! In this example, you will be shown various ways of sharing data between events and commands.
//! And how to use locks correctly to avoid deadlocking the bot.

use std::{
    collections::HashMap,
    env,
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};

use serenity::{
    async_trait,
    framework::standard::{
        macros::{command, group, hook},
        Args,
        CommandResult,
        StandardFramework,
    },
    model::{channel::Message, gateway::Ready},
    prelude::*,
};
use tokio::sync::RwLock;

// A container type is created for inserting into the Client's `data`, which
// allows for data to be accessible across all events and framework commands, or
// anywhere else that has a copy of the `data` Arc.
// These places are usually where either Context or Client is present.
//
// Documentation about TypeMap can be found here:
// https://docs.rs/typemap_rev/0.1/typemap_rev/struct.TypeMap.html
struct CommandCounter;

impl TypeMapKey for CommandCounter {
    type Value = Arc<RwLock<HashMap<String, u64>>>;
}

struct MessageCount;

impl TypeMapKey for MessageCount {
    // While you will be using RwLock or Mutex most of the time you want to modify data,
    // sometimes it's not required; like for example, with static data, or if you are using other
    // kinds of atomic operators.
    //
    // Arc should stay, to allow for the data lock to be closed early.
    type Value = Arc<AtomicUsize>;
}

#[group]
#[commands(ping, command_usage, owo_count)]
struct General;

#[hook]
async fn before(ctx: &Context, msg: &Message, command_name: &str) -> bool {
    println!("Running command '{}' invoked by '{}'", command_name, msg.author.tag());

    let counter_lock = {
        // While data is a RwLock, it's recommended that you always open the lock as read.
        // This is mainly done to avoid Deadlocks for having a possible writer waiting for multiple
        // readers to close.
        let data_read = ctx.data.read().await;

        // Since the CommandCounter Value is wrapped in an Arc, cloning will not duplicate the
        // data, instead the reference is cloned.
        // We wap every value on in an Arc, as to keep the data lock open for the least time possible,
        // to again, avoid deadlocking it.
        data_read.get::<CommandCounter>().expect("Expected CommandCounter in TypeMap.").clone()
    };

    // Just like with client.data in main, we want to keep write locks open the least time
    // possible, so we wrap them on a block so they get automatically closed at the end.
    {
        // The HashMap of CommandCounter is wrapped in an RwLock; since we want to write to it, we will
        // open the lock in write mode.
        let mut counter = counter_lock.write().await;

        // And we write the amount of times the command has been called to it.
        let entry = counter.entry(command_name.to_string()).or_insert(0);
        *entry += 1;
    }

    true
}

struct Handler;

#[async_trait]
impl EventHandler for Handler {
    async fn message(&self, ctx: Context, msg: Message) {
        if msg.content.to_lowercase().contains("owo") {
            // Since data is located in Context, this means you are also able to use it within events!
            let count = {
                let data_read = ctx.data.read().await;
                data_read.get::<MessageCount>().expect("Expected MessageCount in TypeMap.").clone()
            };

            // Atomic operations with ordering do not require mut to be modified.
            // In this case, we want to increase the message count by 1.
            // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_add
            count.fetch_add(1, Ordering::SeqCst);
        }
    }

    async fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
    }
}

#[tokio::main]
async fn main() {
    let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");

    let framework = StandardFramework::new()
        .configure(|c| c.with_whitespace(true).prefix("~"))
        .before(before)
        .group(&GENERAL_GROUP);

    let mut client = Client::builder(&token)
        .event_handler(Handler)
        .framework(framework)
        .await
        .expect("Err creating client");

    // This is where we can initially insert the data we desire into the "global" data TypeMap.
    // client.data is wrapped on a RwLock, and since we want to insert to it, we have to open it in
    // write mode, but there's a small thing catch:
    // There can only be a single writer to a given lock open in the entire application, this means
    // you can't open a new write lock until the previous write lock has closed.
    // This is not the case with read locks, read locks can be open indefinitely, BUT as soon as
    // you need to open the lock in write mode, all the read locks must be closed.
    //
    // You can find more information about deadlocks in the Rust Book, ch16-03:
    // https://doc.rust-lang.org/book/ch16-03-shared-state.html
    //
    // All of this means that we have to keep locks open for the least time possible, so we put
    // them inside a block, so they get closed automatically when droped.
    // If we don't do this, we would never be able to open the data lock anywhere else.
    //
    // Alternatively, you can also use `ClientBuilder::type_map_insert` or
    // `ClientBuilder::type_map` to populate the global TypeMap without dealing with the RwLock.
    {
        // Open the data lock in write mode, so keys can be inserted to it.
        let mut data = client.data.write().await;

        // The CommandCounter Value has the following type:
        // Arc<RwLock<HashMap<String, u64>>>
        // So, we have to insert the same type to it.
        data.insert::<CommandCounter>(Arc::new(RwLock::new(HashMap::default())));

        data.insert::<MessageCount>(Arc::new(AtomicUsize::new(0)));
    }

    if let Err(why) = client.start().await {
        eprintln!("Client error: {:?}", why);
    }
}

#[command]
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
    msg.reply(ctx, "Pong!").await?;

    Ok(())
}

/// Usage: `~command_usage <command_name>`
/// Example: `~command_usage ping`
#[command]
async fn command_usage(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
    let command_name = match args.single_quoted::<String>() {
        Ok(x) => x,
        Err(_) => {
            msg.reply(ctx, "I require an argument to run this command.").await?;
            return Ok(());
        },
    };

    // Yet again, we want to keep the locks open for the least time possible.
    let amount = {
        // Since we only want to read the data and not write to it, we open it in read mode,
        // and since this is open in read mode, it means that there can be multiple locks open at
        // the same time, and as mentioned earlier, it's heavily recommended that you only open
        // the data lock in read mode, as it will avoid a lot of possible deadlocks.
        let data_read = ctx.data.read().await;

        // Then we obtain the value we need from data, in this case, we want the command counter.
        // The returned value from get() is an Arc, so the reference will be cloned, rather than
        // the data.
        let command_counter_lock =
            data_read.get::<CommandCounter>().expect("Expected CommandCounter in TypeMap.").clone();

        let command_counter = command_counter_lock.read().await;
        // And we return a usable value from it.
        // This time, the value is not Arc, so the data will be cloned.
        command_counter.get(&command_name).map_or(0, |x| *x)
    };

    if amount == 0 {
        msg.reply(ctx, format!("The command `{}` has not yet been used.", command_name)).await?;
    } else {
        msg.reply(
            ctx,
            format!("The command `{}` has been used {} time/s this session!", command_name, amount),
        )
        .await?;
    }

    Ok(())
}

#[command]
async fn owo_count(ctx: &Context, msg: &Message) -> CommandResult {
    let raw_count = {
        let data_read = ctx.data.read().await;
        data_read.get::<MessageCount>().expect("Expected MessageCount in TypeMap.").clone()
    };

    let count = raw_count.load(Ordering::Relaxed);

    if count == 1 {
        msg.reply(
            ctx,
            "You are the first one to say owo this session! *because it's on the command name* :P",
        )
        .await?;
    } else {
        msg.reply(ctx, format!("OWO Has been said {} times!", count)).await?;
    }

    Ok(())
}
<commit_msg>Fix a typo in example 12 (#1679)<commit_after>//! In this example, you will be shown various ways of sharing data between events and commands.
//! And how to use locks correctly to avoid deadlocking the bot.

use std::{
    collections::HashMap,
    env,
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};

use serenity::{
    async_trait,
    framework::standard::{
        macros::{command, group, hook},
        Args,
        CommandResult,
        StandardFramework,
    },
    model::{channel::Message, gateway::Ready},
    prelude::*,
};
use tokio::sync::RwLock;

// A container type is created for inserting into the Client's `data`, which
// allows for data to be accessible across all events and framework commands, or
// anywhere else that has a copy of the `data` Arc.
// These places are usually where either Context or Client is present.
//
// Documentation about TypeMap can be found here:
// https://docs.rs/typemap_rev/0.1/typemap_rev/struct.TypeMap.html
struct CommandCounter;

impl TypeMapKey for CommandCounter {
    type Value = Arc<RwLock<HashMap<String, u64>>>;
}

struct MessageCount;

impl TypeMapKey for MessageCount {
    // While you will be using RwLock or Mutex most of the time you want to modify data,
    // sometimes it's not required; like for example, with static data, or if you are using other
    // kinds of atomic operators.
    //
    // Arc should stay, to allow for the data lock to be closed early.
    type Value = Arc<AtomicUsize>;
}

#[group]
#[commands(ping, command_usage, owo_count)]
struct General;

#[hook]
async fn before(ctx: &Context, msg: &Message, command_name: &str) -> bool {
    println!("Running command '{}' invoked by '{}'", command_name, msg.author.tag());

    let counter_lock = {
        // While data is a RwLock, it's recommended that you always open the lock as read.
        // This is mainly done to avoid Deadlocks for having a possible writer waiting for multiple
        // readers to close.
        let data_read = ctx.data.read().await;

        // Since the CommandCounter Value is wrapped in an Arc, cloning will not duplicate the
        // data, instead the reference is cloned.
        // We wrap every value on in an Arc, as to keep the data lock open for the least time possible,
        // to again, avoid deadlocking it.
        data_read.get::<CommandCounter>().expect("Expected CommandCounter in TypeMap.").clone()
    };

    // Just like with client.data in main, we want to keep write locks open the least time
    // possible, so we wrap them on a block so they get automatically closed at the end.
    {
        // The HashMap of CommandCounter is wrapped in an RwLock; since we want to write to it, we will
        // open the lock in write mode.
        let mut counter = counter_lock.write().await;

        // And we write the amount of times the command has been called to it.
        let entry = counter.entry(command_name.to_string()).or_insert(0);
        *entry += 1;
    }

    true
}

struct Handler;

#[async_trait]
impl EventHandler for Handler {
    async fn message(&self, ctx: Context, msg: Message) {
        if msg.content.to_lowercase().contains("owo") {
            // Since data is located in Context, this means you are also able to use it within events!
            let count = {
                let data_read = ctx.data.read().await;
                data_read.get::<MessageCount>().expect("Expected MessageCount in TypeMap.").clone()
            };

            // Atomic operations with ordering do not require mut to be modified.
            // In this case, we want to increase the message count by 1.
            // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_add
            count.fetch_add(1, Ordering::SeqCst);
        }
    }

    async fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
    }
}

#[tokio::main]
async fn main() {
    let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");

    let framework = StandardFramework::new()
        .configure(|c| c.with_whitespace(true).prefix("~"))
        .before(before)
        .group(&GENERAL_GROUP);

    let mut client = Client::builder(&token)
        .event_handler(Handler)
        .framework(framework)
        .await
        .expect("Err creating client");

    // This is where we can initially insert the data we desire into the "global" data TypeMap.
    // client.data is wrapped on a RwLock, and since we want to insert to it, we have to open it in
    // write mode, but there's a small thing catch:
    // There can only be a single writer to a given lock open in the entire application, this means
    // you can't open a new write lock until the previous write lock has closed.
    // This is not the case with read locks, read locks can be open indefinitely, BUT as soon as
    // you need to open the lock in write mode, all the read locks must be closed.
    //
    // You can find more information about deadlocks in the Rust Book, ch16-03:
    // https://doc.rust-lang.org/book/ch16-03-shared-state.html
    //
    // All of this means that we have to keep locks open for the least time possible, so we put
    // them inside a block, so they get closed automatically when droped.
    // If we don't do this, we would never be able to open the data lock anywhere else.
    //
    // Alternatively, you can also use `ClientBuilder::type_map_insert` or
    // `ClientBuilder::type_map` to populate the global TypeMap without dealing with the RwLock.
    {
        // Open the data lock in write mode, so keys can be inserted to it.
        let mut data = client.data.write().await;

        // The CommandCounter Value has the following type:
        // Arc<RwLock<HashMap<String, u64>>>
        // So, we have to insert the same type to it.
        data.insert::<CommandCounter>(Arc::new(RwLock::new(HashMap::default())));

        data.insert::<MessageCount>(Arc::new(AtomicUsize::new(0)));
    }

    if let Err(why) = client.start().await {
        eprintln!("Client error: {:?}", why);
    }
}

#[command]
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
    msg.reply(ctx, "Pong!").await?;

    Ok(())
}

/// Usage: `~command_usage <command_name>`
/// Example: `~command_usage ping`
#[command]
async fn command_usage(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
    let command_name = match args.single_quoted::<String>() {
        Ok(x) => x,
        Err(_) => {
            msg.reply(ctx, "I require an argument to run this command.").await?;
            return Ok(());
        },
    };

    // Yet again, we want to keep the locks open for the least time possible.
    let amount = {
        // Since we only want to read the data and not write to it, we open it in read mode,
        // and since this is open in read mode, it means that there can be multiple locks open at
        // the same time, and as mentioned earlier, it's heavily recommended that you only open
        // the data lock in read mode, as it will avoid a lot of possible deadlocks.
        let data_read = ctx.data.read().await;

        // Then we obtain the value we need from data, in this case, we want the command counter.
        // The returned value from get() is an Arc, so the reference will be cloned, rather than
        // the data.
        let command_counter_lock =
            data_read.get::<CommandCounter>().expect("Expected CommandCounter in TypeMap.").clone();

        let command_counter = command_counter_lock.read().await;
        // And we return a usable value from it.
        // This time, the value is not Arc, so the data will be cloned.
        command_counter.get(&command_name).map_or(0, |x| *x)
    };

    if amount == 0 {
        msg.reply(ctx, format!("The command `{}` has not yet been used.", command_name)).await?;
    } else {
        msg.reply(
            ctx,
            format!("The command `{}` has been used {} time/s this session!", command_name, amount),
        )
        .await?;
    }

    Ok(())
}

#[command]
async fn owo_count(ctx: &Context, msg: &Message) -> CommandResult {
    let raw_count = {
        let data_read = ctx.data.read().await;
        data_read.get::<MessageCount>().expect("Expected MessageCount in TypeMap.").clone()
    };

    let count = raw_count.load(Ordering::Relaxed);

    if count == 1 {
        msg.reply(
            ctx,
            "You are the first one to say owo this session! *because it's on the command name* :P",
        )
        .await?;
    } else {
        msg.reply(ctx, format!("OWO Has been said {} times!", count)).await?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::rc::Rc;

use super::super::errors::VmError;
use super::super::gc::GcTrace;
use super::super::value::Value;

struct InnerClosure {
    locals: HashMap<String, Option<Value>>,
    parent: Option<Closure>,
    /// The builtins closure cannot be written to after it's created.
    builtins: bool,
    /// If this closure is for a REPL. It allows us to set new variables at
    /// will rather than being restricted to the established bindings.
    repl: bool,
}

#[derive(Clone)]
pub struct Closure(Rc<RefCell<InnerClosure>>);

impl Closure {
    pub fn new(bindings: Option<HashSet<String>>, parent: Option<Closure>) -> Self {
        let mut locals = HashMap::<String, Option<Value>>::new();
        if let Some(bindings) = bindings {
            for binding in bindings.iter() {
                locals.insert(binding.clone(), None);
            }
        };
        Self(Rc::new(RefCell::new(InnerClosure {
            locals,
            parent,
            builtins: false,
            repl: false,
        })))
    }

    pub fn new_builtins() -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: None,
            builtins: true,
            repl: false,
        })))
    }

    pub fn new_repl(builtins_closure: Closure) -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: Some(builtins_closure),
            builtins: false,
            repl: true,
        })))
    }

    pub fn new_static(builtins_closure: Option<Closure>) -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: builtins_closure,
            builtins: false,
            repl: false,
        })))
    }

    pub fn get(&self, name: &String) -> Result<Value, VmError> {
        let inner = &self.0.borrow();
        if let Some(value) = inner.locals.get(name) {
            return match value {
                Some(initialized) => Ok(initialized.clone()),
                None => unreachable!("ERROR: Uninitialized closure variable: {}", name),
            };
        }
        if let Some(parent) = &inner.parent {
            return parent.get(name);
        }
        Err(VmError::new_undefined_name(name.clone()))
    }

    /// Returns true if it found a closure in which to set the variable,
    /// false if not.
    pub fn try_set(&self, name: String, value: Value) -> bool {
        let inner = &mut self.0.borrow_mut();
        // If the builtins flag is set then it cannot be mutated.
        if inner.builtins {
            return false;
        }
        if let Some(exists) = inner.locals.get_mut(&name) {
            *exists = Some(value);
            return true;
        }
        // If it's for a REPL then we can create new locals at will.
        if inner.repl {
            inner.locals.insert(name, Some(value));
            return true;
        }
        if let Some(parent) = &inner.parent {
            return parent.try_set(name.clone(), value);
        }
        return false;
    }

    /// Set a local directly into this exact closure. This should only be used
    /// by the VM when:
    ///   - Setting imports into a module's static closure.
    ///   - Setting up the builtins closure.
    pub fn set_directly(&self, name: String, value: Value) {
        let inner = &mut self.0.borrow_mut();
        inner.locals.insert(name, Some(value));
    }
}

impl GcTrace for Closure {
    fn trace(&self) -> () {
        let inner = self.0.borrow();
        for value in inner.locals.values() {
            if let Some(value) = value {
                value.trace();
            }
        }
    }
}

impl fmt::Debug for Closure {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        let inner = &*self.0.borrow();
        let locals = inner
            .locals
            .keys()
            .map(|k| k.to_owned())
            .collect::<Vec<String>>();
        write!(
            f,
            "Closure {{ locals: {:?}, parent: {:?}, repl: {:?} }}",
            locals, inner.parent, inner.repl
        )
    }
}
<commit_msg>Remove unnecessary `return` statement<commit_after>use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::rc::Rc;

use super::super::errors::VmError;
use super::super::gc::GcTrace;
use super::super::value::Value;

struct InnerClosure {
    locals: HashMap<String, Option<Value>>,
    parent: Option<Closure>,
    /// The builtins closure cannot be written to after it's created.
    builtins: bool,
    /// If this closure is for a REPL. It allows us to set new variables at
    /// will rather than being restricted to the established bindings.
    repl: bool,
}

#[derive(Clone)]
pub struct Closure(Rc<RefCell<InnerClosure>>);

impl Closure {
    pub fn new(bindings: Option<HashSet<String>>, parent: Option<Closure>) -> Self {
        let mut locals = HashMap::<String, Option<Value>>::new();
        if let Some(bindings) = bindings {
            for binding in bindings.iter() {
                locals.insert(binding.clone(), None);
            }
        };
        Self(Rc::new(RefCell::new(InnerClosure {
            locals,
            parent,
            builtins: false,
            repl: false,
        })))
    }

    pub fn new_builtins() -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: None,
            builtins: true,
            repl: false,
        })))
    }

    pub fn new_repl(builtins_closure: Closure) -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: Some(builtins_closure),
            builtins: false,
            repl: true,
        })))
    }

    pub fn new_static(builtins_closure: Option<Closure>) -> Self {
        Self(Rc::new(RefCell::new(InnerClosure {
            locals: HashMap::new(),
            parent: builtins_closure,
            builtins: false,
            repl: false,
        })))
    }

    pub fn get(&self, name: &String) -> Result<Value, VmError> {
        let inner = &self.0.borrow();
        if let Some(value) = inner.locals.get(name) {
            return match value {
                Some(initialized) => Ok(initialized.clone()),
                None => unreachable!("ERROR: Uninitialized closure variable: {}", name),
            };
        }
        if let Some(parent) = &inner.parent {
            return parent.get(name);
        }
        Err(VmError::new_undefined_name(name.clone()))
    }

    /// Returns true if it found a closure in which to set the variable,
    /// false if not.
    pub fn try_set(&self, name: String, value: Value) -> bool {
        let inner = &mut self.0.borrow_mut();
        // If the builtins flag is set then it cannot be mutated.
        if inner.builtins {
            return false;
        }
        if let Some(exists) = inner.locals.get_mut(&name) {
            *exists = Some(value);
            return true;
        }
        // If it's for a REPL then we can create new locals at will.
        if inner.repl {
            inner.locals.insert(name, Some(value));
            return true;
        }
        if let Some(parent) = &inner.parent {
            return parent.try_set(name.clone(), value);
        }
        false
    }

    /// Set a local directly into this exact closure. This should only be used
    /// by the VM when:
    ///   - Setting imports into a module's static closure.
    ///   - Setting up the builtins closure.
    pub fn set_directly(&self, name: String, value: Value) {
        let inner = &mut self.0.borrow_mut();
        inner.locals.insert(name, Some(value));
    }
}

impl GcTrace for Closure {
    fn trace(&self) -> () {
        let inner = self.0.borrow();
        for value in inner.locals.values() {
            if let Some(value) = value {
                value.trace();
            }
        }
    }
}

impl fmt::Debug for Closure {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        let inner = &*self.0.borrow();
        let locals = inner
            .locals
            .keys()
            .map(|k| k.to_owned())
            .collect::<Vec<String>>();
        write!(
            f,
            "Closure {{ locals: {:?}, parent: {:?}, repl: {:?} }}",
            locals, inner.parent, inner.repl
        )
    }
}
<|endoftext|>


<commit_before>#![feature(core)]
extern crate core;
use core::fmt::Debug;
use std::marker::PhantomData;

pub struct Expectation<Lhs: Debug>(Lhs);

pub struct To<Lhs: Debug>(Lhs);

pub trait Matcher<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool;
    fn fail_msg(&self, rhs: &Lhs) -> String;
}

pub trait WithLen {
    fn match_len(&self) -> usize;
}

impl<T> WithLen for Vec<T> {
    fn match_len(&self) -> usize { self.len() }
}

impl WithLen for String {
    fn match_len(&self) -> usize { self.chars().count() }
}

impl<'a> WithLen for &'a str {
    fn match_len(&self) -> usize { self.chars().count() }
}

pub struct Contains<T>(T);

impl<T: Debug + PartialEq> Matcher<Vec<T>> for Contains<T> {
    fn matches(&self, lhs: &Vec<T>) -> bool {
        lhs.iter().any(|i| *i == self.0)
    }

    fn fail_msg(&self, lhs: &Vec<T>) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

impl Matcher<String> for Contains<char> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.chars().any(|i| i == self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

pub struct Empty;

impl<Lhs: Debug + WithLen> Matcher<Lhs> for Empty {
    fn matches(&self, rhs: &Lhs) -> bool {
        rhs.match_len() == 0
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to be empty", rhs)
    }
}

pub struct Equal<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialEq> Matcher<Lhs> for Equal<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        &self.0 == rhs
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to equal {:?}", rhs, self.0)
    }
}

pub struct Not<A, M>(M, PhantomData<A>) where A: Debug, M: Matcher<A>;

impl<Lhs: Debug, M: Matcher<Lhs>> Matcher<Lhs> for Not<Lhs, M> {
    fn matches(&self, rhs: &Lhs) -> bool {
        !self.0.matches(rhs)
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("not {}", self.0.fail_msg(rhs))
    }
}

impl<Lhs: Debug> Expectation<Lhs> {
    pub fn is<T>(&self, matcher: T) where T: Matcher<Lhs> {
        self.to(matcher)
    }

    pub fn to<T>(&self, matcher: T) where T: Matcher<Lhs> {
        if !matcher.matches(&self.0) {
            panic!(matcher.fail_msg(&self.0))
        }
    }
}

pub fn expect<T: Debug>(lhs: T) -> Expectation<T> {
    Expectation(lhs)
}

pub fn equal<T: Debug>(rhs: T) -> Equal<T> {
    Equal(rhs)
}

pub fn not<T: Debug, M: Matcher<T>>(rhs: M) -> Not<T, M> {
    Not(rhs, PhantomData)
}

pub fn empty() -> Empty {
    Empty
}

pub fn contain<T: Debug>(rhs: T) -> Contains<T> {
    Contains(rhs)
}

#[cfg(test)]
mod test {
    use super::{expect, equal, not, empty, contain};

    #[test]
    fn test_expect_equality() {
        expect(1).to(equal(1));
    }

    #[test]
    #[should_panic(expected="expected 1 to equal 2")]
    fn test_expect_not_equality_to_fail() {
        expect(1).to(equal(2));
    }

    #[test]
    fn test_partial_eq_equality() {
        #[derive(PartialEq, Debug)]
        struct Foo { a: u16, b: String }

        expect(Foo{ a: 10u16, b: "Hello".to_string()})
            .to(equal(Foo{ a: 10u16, b: "Hello".to_string()}));
    }

    #[test]
    fn test_invert_equality() {
        expect(1).to(not(equal(2)));
    }

    #[test]
    fn test_invert_invert_equality() {
        expect(1).to(not(not(equal(1))));
    }

    #[test]
    #[should_panic(expected="not expected 1 to equal 1")]
    fn test_invert_equality_equal_to_fail() {
        expect(1).to(not(equal(1)));
    }

    #[test]
    fn test_empty() {
        let v: Vec<usize> = Vec::new();
        expect(v).is(empty());
    }

    #[test]
    fn test_not_empty() {
        let v = vec![1, 2, 3];
        expect(v).is(not(empty()));
    }

    #[test]
    fn test_empty_string() {
        expect("".to_string()).is(empty());
    }

    #[test]
    fn test_not_empty_string() {
        expect("not-empty".to_string()).is(not(empty()));
    }

    #[test]
    fn test_empty_str() {
        expect("").is(empty());
    }

    #[test]
    fn test_not_empty_str() {
        expect("not-empty").is(not(empty()));
    }

    #[test]
    fn test_contains() {
        expect(vec![1, 2, 3]).to(contain(1));
    }

    #[test]
    fn test_not_contains() {
        expect(vec![1, 2, 3]).to(not(contain(10)));
    }

    #[test]
    fn test_contains_string_char() {
        expect("Hello, world!".to_string()).to(contain('H'));
    }

    #[test]
    fn test_not_contains_string_char() {
        expect("Hello, world!".to_string()).to(not(contain('Z')));
    }
}
<commit_msg>Add `contain` impl for substrings<commit_after>#![feature(core)]
extern crate core;
use core::fmt::Debug;
use std::marker::PhantomData;

pub struct Expectation<Lhs: Debug>(Lhs);

pub struct To<Lhs: Debug>(Lhs);

pub trait Matcher<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool;
    fn fail_msg(&self, rhs: &Lhs) -> String;
}

pub trait WithLen {
    fn match_len(&self) -> usize;
}

impl<T> WithLen for Vec<T> {
    fn match_len(&self) -> usize { self.len() }
}

impl WithLen for String {
    fn match_len(&self) -> usize { self.chars().count() }
}

impl<'a> WithLen for &'a str {
    fn match_len(&self) -> usize { self.chars().count() }
}

pub struct Contains<T>(T);

impl<T: Debug + PartialEq> Matcher<Vec<T>> for Contains<T> {
    fn matches(&self, lhs: &Vec<T>) -> bool {
        lhs.iter().any(|i| *i == self.0)
    }

    fn fail_msg(&self, lhs: &Vec<T>) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

impl Matcher<String> for Contains<char> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.chars().any(|i| i == self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected \"{:?}\" to contain '{:?}'", lhs, self.0)
    }
}

impl Matcher<String> for Contains<String> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.contains(&*self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected \"{:?}\" to contain \"{:?}\"", lhs, self.0)
    }
}

pub struct Empty;

impl<Lhs: Debug + WithLen> Matcher<Lhs> for Empty {
    fn matches(&self, rhs: &Lhs) -> bool {
        rhs.match_len() == 0
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to be empty", rhs)
    }
}

pub struct Equal<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialEq> Matcher<Lhs> for Equal<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        &self.0 == rhs
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to equal {:?}", rhs, self.0)
    }
}

pub struct Not<A, M>(M, PhantomData<A>) where A: Debug, M: Matcher<A>;

impl<Lhs: Debug, M: Matcher<Lhs>> Matcher<Lhs> for Not<Lhs, M> {
    fn matches(&self, rhs: &Lhs) -> bool {
        !self.0.matches(rhs)
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("not {}", self.0.fail_msg(rhs))
    }
}

impl<Lhs: Debug> Expectation<Lhs> {
    pub fn is<T>(&self, matcher: T) where T: Matcher<Lhs> {
        self.to(matcher)
    }

    pub fn to<T>(&self, matcher: T) where T: Matcher<Lhs> {
        if !matcher.matches(&self.0) {
            panic!(matcher.fail_msg(&self.0))
        }
    }
}

pub fn expect<T: Debug>(lhs: T) -> Expectation<T> {
    Expectation(lhs)
}

pub fn equal<T: Debug>(rhs: T) -> Equal<T> {
    Equal(rhs)
}

pub fn not<T: Debug, M: Matcher<T>>(rhs: M) -> Not<T, M> {
    Not(rhs, PhantomData)
}

pub fn empty() -> Empty {
    Empty
}

pub fn contain<T: Debug>(rhs: T) -> Contains<T> {
    Contains(rhs)
}

#[cfg(test)]
mod test {
    use super::{expect, equal, not, empty, contain};

    #[test]
    fn test_expect_equality() {
        expect(1).to(equal(1));
    }

    #[test]
    #[should_panic(expected="expected 1 to equal 2")]
    fn test_expect_not_equality_to_fail() {
        expect(1).to(equal(2));
    }

    #[test]
    fn test_partial_eq_equality() {
        #[derive(PartialEq, Debug)]
        struct Foo { a: u16, b: String }

        expect(Foo{ a: 10u16, b: "Hello".to_string()})
            .to(equal(Foo{ a: 10u16, b: "Hello".to_string()}));
    }

    #[test]
    fn test_invert_equality() {
        expect(1).to(not(equal(2)));
    }

    #[test]
    fn test_invert_invert_equality() {
        expect(1).to(not(not(equal(1))));
    }

    #[test]
    #[should_panic(expected="not expected 1 to equal 1")]
    fn test_invert_equality_equal_to_fail() {
        expect(1).to(not(equal(1)));
    }

    #[test]
    fn test_empty() {
        let v: Vec<usize> = Vec::new();
        expect(v).is(empty());
    }

    #[test]
    fn test_not_empty() {
        let v = vec![1, 2, 3];
        expect(v).is(not(empty()));
    }

    #[test]
    fn test_empty_string() {
        expect("".to_string()).is(empty());
    }

    #[test]
    fn test_not_empty_string() {
        expect("not-empty".to_string()).is(not(empty()));
    }

    #[test]
    fn test_empty_str() {
        expect("").is(empty());
    }

    #[test]
    fn test_not_empty_str() {
        expect("not-empty").is(not(empty()));
    }

    #[test]
    fn test_contains() {
        expect(vec![1, 2, 3]).to(contain(1));
    }

    #[test]
    fn test_not_contains() {
        expect(vec![1, 2, 3]).to(not(contain(10)));
    }

    #[test]
    fn test_contains_string_char() {
        expect("Hello, world!".to_string()).to(contain('H'));
    }

    #[test]
    fn test_not_contains_string_char() {
        expect("Hello, world!".to_string()).to(not(contain('Z')));
    }

    #[test]
    fn test_contains_string_substring() {
        expect("Hello, world!".to_string()).to(contain("Hello".to_string()));
    }

    #[test]
    fn test_not_contains_string_substring() {
        expect("Hello, world!".to_string()).to(not(contain("not-in-there".to_string())));
    }
}
<|endoftext|>


<commit_before>pub extern crate find_folder;
pub extern crate glium;
pub extern crate rand;

use event::LoopEvent;
use glium::glutin;
use std::cell::RefCell;
use std::time::Instant;

pub use app::{App, LoopMode};
pub use glium::glutin::{ContextBuilder, CursorState, ElementState, MonitorId, MouseCursor,
                        WindowBuilder, WindowEvent, VirtualKeyCode};
pub use self::event::Event;
pub use self::frame::Frame;
pub use self::ui::Ui;

pub mod app;
pub mod audio;
pub mod color;
pub mod event;
mod frame;
pub mod window;
pub mod image;
pub mod math;
pub mod osc;
pub mod prelude;
pub mod ui;

pub type ModelFn<Model> = fn(&App) -> Model;
pub type UpdateFn<Model, Event> = fn(&App, Model, Event) -> Model;
pub type DrawFn<Model> = fn(&App, &Model, Frame) -> Frame;

/// Runs the nannou application!
pub fn run<M, E>(model: ModelFn<M>, update: UpdateFn<M, E>, draw: DrawFn<M>)
    where E: LoopEvent,
{
    let events_loop = glutin::EventsLoop::new();
    let app = App::new(events_loop);
    let model = model(&app);
    run_loop(app, model, update, draw)
}

fn run_loop<M, E>(mut app: App, mut model: M, update_fn: UpdateFn<M, E>, draw_fn: DrawFn<M>)
    where E: LoopEvent,
{
    // A function to re-use when drawing for each of the loop modes.
    fn draw<M>(app: &App, model: &M, draw_fn: DrawFn<M>) -> Result<(), glium::SwapBuffersError> {
        // Draw the state of the model to the screen.
        let gl_frames = app.windows
            .borrow()
            .iter()
            .map(|(&id, window)| {
                let gl_frame = RefCell::new(frame::GlFrame::new(window.display.draw()));
                (id, gl_frame)
            })
            .collect();
        let frame = draw_fn(&app, &model, frame::new(gl_frames));
        frame::finish(frame)
    }

    // A function to simplify the creation of an `Update` event.
    //
    // Also updates the given `last_update` instant to `Instant::now()`.
    fn update_event(loop_start: Instant, last_update: &mut Instant) -> event::Update {
        // Emit an update event.
        let now = Instant::now();
        let since_last = now.duration_since(*last_update);
        let since_start = now.duration_since(loop_start);
        let update = event::Update { since_last, since_start };
        *last_update = now;
        update
    };

    // Event handling boilerplate shared between the `Rate` and `Wait` loop modes.
    //
    // 1. Checks for exit on escape.
    // 2. Removes closed windows from app.
    // 3. Emits event via `update_fn`.
    // 4. Returns whether or not we should break from the loop.
    fn process_and_emit_glutin_event<M, E>(
        app: &App,
        mut model: M,
        update_fn: UpdateFn<M, E>,
        glutin_event: glutin::Event,
    ) -> (M, bool)
    where
        E: LoopEvent,
    {
        // Inspect the event to see if it would require closing the App.
        let mut exit_on_escape = false;
        if let glutin::Event::WindowEvent { window_id, ref event } = glutin_event {

            // If we should exit the app on escape, check for the escape key.
            if app.exit_on_escape.get() {
                if let glutin::WindowEvent::KeyboardInput { input, .. } = *event {
                    if let Some(VirtualKeyCode::Escape) = input.virtual_keycode {
                        exit_on_escape = true;
                    }
                }
            }

            // If a window was closed, remove it from the display map.
            if let glutin::WindowEvent::Closed = *event {
                app.windows.borrow_mut().remove(&window_id);
            } else {

                // See if the event could be interpreted as a `ui::Input`. If so, submit it to the
                // `Ui`s associated with this window.
                if let Some(window) = app.windows.borrow().get(&window_id) {
                    if let Some(input) = ui::glutin_window_event_to_input(event.clone(), window) {
                        if let Some(handles) = app.ui.windows.borrow().get(&window_id) {
                            for handle in handles {
                                if let Some(ref tx) = handle.input_tx {
                                    tx.try_send(input.clone()).ok();
                                }
                            }
                        }
                    }
                }
            }
        }

        // If the glutin::Event could be interpreted as some event `E`, use it to update the model.
        if let Some(event) = E::from_glutin_event(glutin_event, app) {
            model = update_fn(&app, model, event);
        }

        // If exit on escape was triggered, we're done.
        let exit = if exit_on_escape || app.windows.borrow().is_empty() {
            true
        } else {
            false
        };

        (model, exit)
    }

    let loop_start = Instant::now();

    // A vec for collecting events.
    let mut glutin_events = Vec::new();

    // Begin looping.
    let mut last_update = loop_start;
    let mut last_loop_end = loop_start;
    let mut updates_remaining = LoopMode::DEFAULT_UPDATES_FOLLOWING_EVENT;
    let mut loop_mode = None;

    // Begin looping.
    'main: loop {

        // See if the loop mode has changed.
        let new_loop_mode = app.loop_mode();
        let loop_mode_has_changed = loop_mode != Some(new_loop_mode);
        loop_mode = Some(new_loop_mode);

        // The kind of iteration to perform will depend on the loop mode.
        match loop_mode {

            Some(LoopMode::Rate { update_interval }) => {
                // If the loop mode has changed since the last iteration, initialise the necessary
                // `Rate` state.
                if loop_mode_has_changed {
                }

                // First handle any pending window events.
                app.events_loop.poll_events(|event| glutin_events.push(event));
                for glutin_event in glutin_events.drain(..) {
                    let (new_model, exit) = process_and_emit_glutin_event(&app, model, update_fn, glutin_event);
                    model = new_model;
                    if exit {
                        break 'main;
                    }
                }

                // Emit an update event.
                let event = E::from(update_event(loop_start, &mut last_update));
                model = update_fn(&app, model, event);

                // Draw the state of the model to the screen.
                draw(&app, &model, draw_fn).unwrap();

                // Sleep if there's still some time left within the interval.
                let now = Instant::now();
                let since_last_loop_end = now.duration_since(last_loop_end);
                if since_last_loop_end < update_interval {
                    std::thread::sleep(update_interval - since_last_loop_end);
                }
                last_loop_end = Instant::now();
            },

            Some(LoopMode::Wait { updates_following_event, update_interval }) => {
                // If the loop mode has changed, initialise the necessary `Rate` state.
                if loop_mode_has_changed {
                    updates_remaining = updates_following_event;
                }

                // First collect any pending window events.
                app.events_loop.poll_events(|event| glutin_events.push(event));

                // If there are no events and the `Ui` does not need updating,
                // wait for the next event.
                if glutin_events.is_empty() && updates_remaining == 0 {
                    app.events_loop.run_forever(|event| {
                        glutin_events.push(event);
                        glium::glutin::ControlFlow::Break
                    });
                }

                // If there are some glutin events to process, reset the updates-remaining count.
                if !glutin_events.is_empty() {
                    updates_remaining = updates_following_event;
                }

                for glutin_event in glutin_events.drain(..) {
                    let (new_model, exit) = process_and_emit_glutin_event(&app, model, update_fn, glutin_event);
                    model = new_model;
                    if exit {
                        break 'main;
                    }
                }

                // Emit an update event.
                let event = E::from(update_event(loop_start, &mut last_update));
                model = update_fn(&app, model, event);
                updates_remaining -= 1;

                // Draw the state of the model to the screen.
                draw(&app, &model, draw_fn).unwrap();

                // Sleep if there's still some time left within the interval.
                let now = Instant::now();
                let since_last_loop_end = now.duration_since(last_loop_end);
                if since_last_loop_end < update_interval {
                    std::thread::sleep(update_interval - since_last_loop_end);
                }
                last_loop_end = Instant::now();
            },

            // Loop mode is always `Some` after the beginning of the `'main` loop.
            None => unreachable!(),
        }
    }
}
<commit_msg>Add optional exit function for consuming model on application exit<commit_after>pub extern crate find_folder;
pub extern crate glium;
pub extern crate rand;

use event::LoopEvent;
use glium::glutin;
use std::cell::RefCell;
use std::time::Instant;

pub use app::{App, LoopMode};
pub use glium::glutin::{ContextBuilder, CursorState, ElementState, MonitorId, MouseCursor,
                        WindowBuilder, WindowEvent, VirtualKeyCode};
pub use self::event::Event;
pub use self::frame::Frame;
pub use self::ui::Ui;

pub mod app;
pub mod audio;
pub mod color;
pub mod event;
mod frame;
pub mod window;
pub mod image;
pub mod math;
pub mod osc;
pub mod prelude;
pub mod ui;

pub type ModelFn<Model> = fn(&App) -> Model;
pub type UpdateFn<Model, Event> = fn(&App, Model, Event) -> Model;
pub type DrawFn<Model> = fn(&App, &Model, Frame) -> Frame;
pub type ExitFn<Model> = fn(&App, Model);

/// Begin building a nannou App.
///
/// Every nannou App must have `model`, `update` and `draw` functions.
///
/// An `exit` function can be optionally specified using the `exit` builder method.
pub fn app<M, E>(model: ModelFn<M>, update: UpdateFn<M, E>, draw: DrawFn<M>) -> Builder<M, E>
    where E: LoopEvent,
{
    let exit = None;
    Builder { model, update, draw, exit }
}

/// A nannou application builder.
pub struct Builder<M, E> {
    model: ModelFn<M>,
    update: UpdateFn<M, E>,
    draw: DrawFn<M>,
    exit: Option<ExitFn<M>>,
}

impl<M, E> Builder<M, E>
    where E: LoopEvent,
{
    /// Specify an `exit` function to be called when the application exits.
    ///
    /// The exit function gives ownership of the model back to the user.
    pub fn exit(mut self, exit: ExitFn<M>) -> Self {
        self.exit = Some(exit);
        self
    }

    /// Creates and runs the nannou `App`.
    pub fn run(self) {
        let Builder { model, update, draw, exit } = self;
        let events_loop = glutin::EventsLoop::new();
        let app = App::new(events_loop);
        let model = model(&app);
        run_loop(app, model, update, draw, exit)
    }
}

/// A simple function for creating and running a nannou `App`!
///
/// Calling this is just like calling `nannou::app(model, update, draw).run()`.
pub fn run<M, E>(model: ModelFn<M>, update: UpdateFn<M, E>, draw: DrawFn<M>)
    where E: LoopEvent,
{
    app(model, update, draw).run()
}

fn run_loop<M, E>(
    mut app: App,
    mut model: M,
    update_fn: UpdateFn<M, E>,
    draw_fn: DrawFn<M>,
    exit_fn: Option<ExitFn<M>>,
)
where
    E: LoopEvent,
{
    // A function to re-use when drawing for each of the loop modes.
    fn draw<M>(app: &App, model: &M, draw_fn: DrawFn<M>) -> Result<(), glium::SwapBuffersError> {
        // Draw the state of the model to the screen.
        let gl_frames = app.windows
            .borrow()
            .iter()
            .map(|(&id, window)| {
                let gl_frame = RefCell::new(frame::GlFrame::new(window.display.draw()));
                (id, gl_frame)
            })
            .collect();
        let frame = draw_fn(&app, &model, frame::new(gl_frames));
        frame::finish(frame)
    }

    // A function to simplify the creation of an `Update` event.
    //
    // Also updates the given `last_update` instant to `Instant::now()`.
    fn update_event(loop_start: Instant, last_update: &mut Instant) -> event::Update {
        // Emit an update event.
        let now = Instant::now();
        let since_last = now.duration_since(*last_update);
        let since_start = now.duration_since(loop_start);
        let update = event::Update { since_last, since_start };
        *last_update = now;
        update
    };

    // Event handling boilerplate shared between the `Rate` and `Wait` loop modes.
    //
    // 1. Checks for exit on escape.
    // 2. Removes closed windows from app.
    // 3. Emits event via `update_fn`.
    // 4. Returns whether or not we should break from the loop.
    fn process_and_emit_glutin_event<M, E>(
        app: &App,
        mut model: M,
        update_fn: UpdateFn<M, E>,
        glutin_event: glutin::Event,
    ) -> (M, bool)
    where
        E: LoopEvent,
    {
        // Inspect the event to see if it would require closing the App.
        let mut exit_on_escape = false;
        if let glutin::Event::WindowEvent { window_id, ref event } = glutin_event {

            // If we should exit the app on escape, check for the escape key.
            if app.exit_on_escape.get() {
                if let glutin::WindowEvent::KeyboardInput { input, .. } = *event {
                    if let Some(VirtualKeyCode::Escape) = input.virtual_keycode {
                        exit_on_escape = true;
                    }
                }
            }

            // If a window was closed, remove it from the display map.
            if let glutin::WindowEvent::Closed = *event {
                app.windows.borrow_mut().remove(&window_id);
            } else {

                // See if the event could be interpreted as a `ui::Input`. If so, submit it to the
                // `Ui`s associated with this window.
                if let Some(window) = app.windows.borrow().get(&window_id) {
                    if let Some(input) = ui::glutin_window_event_to_input(event.clone(), window) {
                        if let Some(handles) = app.ui.windows.borrow().get(&window_id) {
                            for handle in handles {
                                if let Some(ref tx) = handle.input_tx {
                                    tx.try_send(input.clone()).ok();
                                }
                            }
                        }
                    }
                }
            }
        }

        // If the glutin::Event could be interpreted as some event `E`, use it to update the model.
        if let Some(event) = E::from_glutin_event(glutin_event, app) {
            model = update_fn(&app, model, event);
        }

        // If exit on escape was triggered, we're done.
        let exit = if exit_on_escape || app.windows.borrow().is_empty() {
            true
        } else {
            false
        };

        (model, exit)
    }

    let loop_start = Instant::now();

    // A vec for collecting events.
    let mut glutin_events = Vec::new();

    // Begin looping.
    let mut last_update = loop_start;
    let mut last_loop_end = loop_start;
    let mut updates_remaining = LoopMode::DEFAULT_UPDATES_FOLLOWING_EVENT;
    let mut loop_mode = None;

    // Begin looping.
    'main: loop {

        // See if the loop mode has changed.
        let new_loop_mode = app.loop_mode();
        let loop_mode_has_changed = loop_mode != Some(new_loop_mode);
        loop_mode = Some(new_loop_mode);

        // The kind of iteration to perform will depend on the loop mode.
        match loop_mode {

            Some(LoopMode::Rate { update_interval }) => {
                // If the loop mode has changed since the last iteration, initialise the necessary
                // `Rate` state.
                if loop_mode_has_changed {
                }

                // First handle any pending window events.
                app.events_loop.poll_events(|event| glutin_events.push(event));
                for glutin_event in glutin_events.drain(..) {
                    let (new_model, exit) = process_and_emit_glutin_event(&app, model, update_fn, glutin_event);
                    model = new_model;
                    if exit {
                        break 'main;
                    }
                }

                // Emit an update event.
                let event = E::from(update_event(loop_start, &mut last_update));
                model = update_fn(&app, model, event);

                // Draw the state of the model to the screen.
                draw(&app, &model, draw_fn).unwrap();

                // Sleep if there's still some time left within the interval.
                let now = Instant::now();
                let since_last_loop_end = now.duration_since(last_loop_end);
                if since_last_loop_end < update_interval {
                    std::thread::sleep(update_interval - since_last_loop_end);
                }
                last_loop_end = Instant::now();
            },

            Some(LoopMode::Wait { updates_following_event, update_interval }) => {
                // If the loop mode has changed, initialise the necessary `Rate` state.
                if loop_mode_has_changed {
                    updates_remaining = updates_following_event;
                }

                // First collect any pending window events.
                app.events_loop.poll_events(|event| glutin_events.push(event));

                // If there are no events and the `Ui` does not need updating,
                // wait for the next event.
                if glutin_events.is_empty() && updates_remaining == 0 {
                    app.events_loop.run_forever(|event| {
                        glutin_events.push(event);
                        glium::glutin::ControlFlow::Break
                    });
                }

                // If there are some glutin events to process, reset the updates-remaining count.
                if !glutin_events.is_empty() {
                    updates_remaining = updates_following_event;
                }

                for glutin_event in glutin_events.drain(..) {
                    let (new_model, exit) = process_and_emit_glutin_event(&app, model, update_fn, glutin_event);
                    model = new_model;
                    if exit {
                        break 'main;
                    }
                }

                // Emit an update event.
                let event = E::from(update_event(loop_start, &mut last_update));
                model = update_fn(&app, model, event);
                updates_remaining -= 1;

                // Draw the state of the model to the screen.
                draw(&app, &model, draw_fn).unwrap();

                // Sleep if there's still some time left within the interval.
                let now = Instant::now();
                let since_last_loop_end = now.duration_since(last_loop_end);
                if since_last_loop_end < update_interval {
                    std::thread::sleep(update_interval - since_last_loop_end);
                }
                last_loop_end = Instant::now();
            },

            // Loop mode is always `Some` after the beginning of the `'main` loop.
            None => unreachable!(),
        }
    }

    // Emit an application exit event.
    if let Some(exit_fn) = exit_fn {
        exit_fn(&app, model);
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
extern crate libc;

use std::fmt;
use std::ptr;

type HttpCallback = extern fn(*mut HttpParser) -> *mut libc::c_int;
type HttpDataCallback = extern fn(*mut HttpParser, *const u32, libc::size_t) -> *mut libc::c_int;

#[repr(C)]
enum HttpParserType {
    HttpRequest,
    HttpResponse,
    HttpBoth
}

#[repr(C)]
struct HttpParser {
    // Private Interface
    internal_state: u32,
    nread: u32,
    content_length: u64,

    // Read-Only
    http_major: libc::c_ushort,
    http_minor: libc::c_ushort,
    extended_status: u32,

    // Public Interface
    data: *mut libc::c_void
}

#[repr(C)]
struct HttpParserSettings {
    on_message_begin: HttpCallback,
    on_url: HttpDataCallback,
    on_status: HttpDataCallback,
    on_header_field: HttpDataCallback,
    on_header_value: HttpDataCallback,
    on_headers_complete: HttpCallback,
    on_body: HttpDataCallback,
    on_message_complete: HttpCallback,
    on_chunk_header: HttpCallback,
    on_chunk_complete: HttpCallback
}

#[inline]
unsafe fn unwrap_parser<'a>(http: *mut HttpParser) -> &'a mut Parser<'a> {
    return &mut *((*http).data as *mut Parser);
}

macro_rules! notify_fn_wrapper {
    ( $callback:ident ) => ({
        extern "C" fn $callback(http: *mut HttpParser) -> *mut libc::c_int {
            unsafe {
                unwrap_parser(http).handler.$callback();
            };
            return 0 as *mut libc::c_int;
        };
        $callback
    });
}

macro_rules! data_fn_wrapper {
    ( $callback:ident ) => ({
        extern "C" fn $callback(http: *mut HttpParser, data: *const u32, size: libc::size_t) -> *mut libc::c_int {
            unsafe {
                let mut dst = Vec::<u8>::with_capacity(size as usize);
                dst.set_len(size as usize);
                ptr::copy(data as *const u8, dst.as_mut_ptr(), size as usize);

                let data = String::from_utf8(dst).unwrap();

                unwrap_parser(http).handler.$callback(&data);
            };
            return 0 as *mut libc::c_int;
        };

        $callback
    });
}

static CALLBACK_WRAPPERS: HttpParserSettings = HttpParserSettings {
    on_url: data_fn_wrapper!(on_url),
    on_message_begin: notify_fn_wrapper!(on_message_begin),
    on_status: data_fn_wrapper!(on_status),
    on_header_field: data_fn_wrapper!(on_header_field),
    on_header_value: data_fn_wrapper!(on_header_value),
    on_headers_complete: notify_fn_wrapper!(on_headers_complete),
    on_body: data_fn_wrapper!(on_body),
    on_message_complete: notify_fn_wrapper!(on_message_complete),
    on_chunk_header: notify_fn_wrapper!(on_chunk_header),
    on_chunk_complete: notify_fn_wrapper!(on_chunk_complete)
};

extern "C" {
    fn http_parser_version() -> u32;
    fn http_parser_init(parser: *mut HttpParser, parser_type: HttpParserType);
    fn http_parser_settings_init(settings: *mut HttpParserSettings);
    fn http_parser_execute(parser: *mut HttpParser, settings: *const HttpParserSettings, data: *const u8, len: libc::size_t) -> libc::size_t;
    // fn http_method_str(m: HttpMethod);
}

// Rust Interface
pub trait ParserHandler {
    fn on_url(&self, &String) { }
    fn on_status(&self, &String) { }
    fn on_header_field(&self, &String) { }
    fn on_header_value(&self, &String) { }
    fn on_body(&self, &String) { }
    fn on_message_begin(&self) { }
    fn on_headers_complete(&self) { }
    fn on_message_complete(&self) { }
    fn on_chunk_header(&self) { }
    fn on_chunk_complete(&self) { }
}

pub struct Parser<'a> {
    handler: &'a ParserHandler,
    state: HttpParser
}

impl<'a> Parser<'a> {
    pub fn new(handler: &'a ParserHandler) -> Parser<'a> {
        Parser {
            handler: handler,
            state: HttpParser {
                internal_state: 0,
                nread: 0,
                content_length: 0,
                http_major: 0,
                http_minor: 0,
                extended_status: 0,
                data: 0 as *mut libc::c_void
            }
        }
    }
}

pub fn parse(pars: &mut Parser, data: &[u8]) -> usize {
    unsafe {
        http_parser_init(&mut pars.state as *mut _, HttpParserType::HttpRequest);

        pars.state.data = &mut (*pars) as *mut _ as *mut libc::c_void;

        let parsed = http_parser_execute(&mut pars.state as *mut _,
                                         &CALLBACK_WRAPPERS as *const _,
                                         data.as_ptr(),
                                         data.len() as u64);

        return parsed as usize;
    }
}

pub fn version() -> String {
    unsafe {
        let v = http_parser_version();

        let major = (v >> 16) & 255;
        let minor = (v >> 8) & 255;
        let patch = v & 255;

        return fmt::format(format_args!("{}.{}.{}", major, minor, patch));
    }
}

#[test]
fn test_version() {
    assert_eq!("2.5.0", version());
}

struct TestParserImpl;
impl ParserHandler for TestParserImpl {
    fn on_url(&self, url: &String) {
        println!("{}", url);
    }
    fn on_status(&self, url: &String) {
        println!("{}", url);
    }
}

#[test]
fn request_parser() {
    struct TestParserImpl;
    impl ParserHandler for TestParserImpl {
        fn on_url(&self, url: &String) { assert_eq!("/hello", url); }
        fn on_header_field(&self, hdr: &String) { assert_eq!("Host", hdr); }
        fn on_header_value(&self, val: &String) { assert_eq!("localhost.localdomain", val); }
    }
    let req = "GET /hello HTTP/1.0\r\nHost: localhost.localdomain\r\n\r\n";
    let parsed = parse(&mut Parser::new(&TestParserImpl), req.as_bytes());
    assert!(parsed > 0);

    // assert_eq!(parser.http_major, 1);
    // assert_eq!(parser.http_minor, 0);
}

#[test]
fn response_parser() {
}
<commit_msg>Removed old code<commit_after>#![allow(dead_code)]
extern crate libc;

use std::fmt;
use std::ptr;

type HttpCallback = extern fn(*mut HttpParser) -> *mut libc::c_int;
type HttpDataCallback = extern fn(*mut HttpParser, *const u32, libc::size_t) -> *mut libc::c_int;

#[repr(C)]
enum HttpParserType {
    HttpRequest,
    HttpResponse,
    HttpBoth
}

#[repr(C)]
struct HttpParser {
    // Private Interface
    internal_state: u32,
    nread: u32,
    content_length: u64,

    // Read-Only
    http_major: libc::c_ushort,
    http_minor: libc::c_ushort,
    extended_status: u32,

    // Public Interface
    data: *mut libc::c_void
}

#[repr(C)]
struct HttpParserSettings {
    on_message_begin: HttpCallback,
    on_url: HttpDataCallback,
    on_status: HttpDataCallback,
    on_header_field: HttpDataCallback,
    on_header_value: HttpDataCallback,
    on_headers_complete: HttpCallback,
    on_body: HttpDataCallback,
    on_message_complete: HttpCallback,
    on_chunk_header: HttpCallback,
    on_chunk_complete: HttpCallback
}

#[inline]
unsafe fn unwrap_parser<'a>(http: *mut HttpParser) -> &'a mut Parser<'a> {
    return &mut *((*http).data as *mut Parser);
}

macro_rules! notify_fn_wrapper {
    ( $callback:ident ) => ({
        extern "C" fn $callback(http: *mut HttpParser) -> *mut libc::c_int {
            unsafe {
                unwrap_parser(http).handler.$callback();
            };
            return 0 as *mut libc::c_int;
        };
        $callback
    });
}

macro_rules! data_fn_wrapper {
    ( $callback:ident ) => ({
        extern "C" fn $callback(http: *mut HttpParser, data: *const u32, size: libc::size_t) -> *mut libc::c_int {
            unsafe {
                let mut dst = Vec::<u8>::with_capacity(size as usize);
                dst.set_len(size as usize);
                ptr::copy(data as *const u8, dst.as_mut_ptr(), size as usize);

                let data = String::from_utf8(dst).unwrap();

                unwrap_parser(http).handler.$callback(&data);
            };
            return 0 as *mut libc::c_int;
        };

        $callback
    });
}

static CALLBACK_WRAPPERS: HttpParserSettings = HttpParserSettings {
    on_url: data_fn_wrapper!(on_url),
    on_message_begin: notify_fn_wrapper!(on_message_begin),
    on_status: data_fn_wrapper!(on_status),
    on_header_field: data_fn_wrapper!(on_header_field),
    on_header_value: data_fn_wrapper!(on_header_value),
    on_headers_complete: notify_fn_wrapper!(on_headers_complete),
    on_body: data_fn_wrapper!(on_body),
    on_message_complete: notify_fn_wrapper!(on_message_complete),
    on_chunk_header: notify_fn_wrapper!(on_chunk_header),
    on_chunk_complete: notify_fn_wrapper!(on_chunk_complete)
};

extern "C" {
    fn http_parser_version() -> u32;
    fn http_parser_init(parser: *mut HttpParser, parser_type: HttpParserType);
    fn http_parser_settings_init(settings: *mut HttpParserSettings);
    fn http_parser_execute(parser: *mut HttpParser, settings: *const HttpParserSettings, data: *const u8, len: libc::size_t) -> libc::size_t;
    // fn http_method_str(m: HttpMethod);
}

// Rust Interface
pub trait ParserHandler {
    fn on_url(&self, &String) { }
    fn on_status(&self, &String) { }
    fn on_header_field(&self, &String) { }
    fn on_header_value(&self, &String) { }
    fn on_body(&self, &String) { }
    fn on_message_begin(&self) { }
    fn on_headers_complete(&self) { }
    fn on_message_complete(&self) { }
    fn on_chunk_header(&self) { }
    fn on_chunk_complete(&self) { }
}

pub struct Parser<'a> {
    handler: &'a ParserHandler,
    state: HttpParser
}

impl<'a> Parser<'a> {
    pub fn new(handler: &'a ParserHandler) -> Parser<'a> {
        Parser {
            handler: handler,
            state: HttpParser {
                internal_state: 0,
                nread: 0,
                content_length: 0,
                http_major: 0,
                http_minor: 0,
                extended_status: 0,
                data: 0 as *mut libc::c_void
            }
        }
    }
}

pub fn parse(pars: &mut Parser, data: &[u8]) -> usize {
    unsafe {
        http_parser_init(&mut pars.state as *mut _, HttpParserType::HttpRequest);

        pars.state.data = &mut (*pars) as *mut _ as *mut libc::c_void;

        let parsed = http_parser_execute(&mut pars.state as *mut _,
                                         &CALLBACK_WRAPPERS as *const _,
                                         data.as_ptr(),
                                         data.len() as u64);

        return parsed as usize;
    }
}

pub fn version() -> String {
    unsafe {
        let v = http_parser_version();

        let major = (v >> 16) & 255;
        let minor = (v >> 8) & 255;
        let patch = v & 255;

        return fmt::format(format_args!("{}.{}.{}", major, minor, patch));
    }
}

#[test]
fn test_version() {
    assert_eq!("2.5.0", version());
}

#[test]
fn request_parser() {
    struct TestParserImpl;
    impl ParserHandler for TestParserImpl {
        fn on_url(&self, url: &String) { assert_eq!("/hello", url); }
        fn on_header_field(&self, hdr: &String) { assert_eq!("Host", hdr); }
        fn on_header_value(&self, val: &String) { assert_eq!("localhost.localdomain", val); }
    }
    let req = "GET /hello HTTP/1.0\r\nHost: localhost.localdomain\r\n\r\n";
    let parsed = parse(&mut Parser::new(&TestParserImpl), req.as_bytes());
    assert!(parsed > 0);

    // assert_eq!(parser.http_major, 1);
    // assert_eq!(parser.http_minor, 0);
}

#[test]
fn response_parser() {
}
<|endoftext|>


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

#![crate_name = "geom"]
#![crate_type = "rlib"]

#![feature(asm, simd)]

#[macro_use]
extern crate log;
extern crate "serialize" as rustc_serialize;

extern crate rand;
extern crate test;

pub use matrix::Matrix4;
pub use matrix2d::Matrix2D;
pub use point::Point2D;
pub use rect::Rect;
pub use side_offsets::SideOffsets2D;
pub use side_offsets::SideOffsets2DSimdI32;
pub use size::Size2D;

pub mod approxeq;
pub mod length;
pub mod matrix;
pub mod matrix2d;
pub mod num;
pub mod point;
pub mod rect;
pub mod scale_factor;
pub mod side_offsets;
pub mod size;
<commit_msg>Silence unstable warnings<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "geom"]
#![crate_type = "rlib"]

#![feature(asm, simd)]
#![allow(unstable)]

#[macro_use]
extern crate log;
extern crate "serialize" as rustc_serialize;

extern crate rand;
extern crate test;

pub use matrix::Matrix4;
pub use matrix2d::Matrix2D;
pub use point::Point2D;
pub use rect::Rect;
pub use side_offsets::SideOffsets2D;
pub use side_offsets::SideOffsets2DSimdI32;
pub use size::Size2D;

pub mod approxeq;
pub mod length;
pub mod matrix;
pub mod matrix2d;
pub mod num;
pub mod point;
pub mod rect;
pub mod scale_factor;
pub mod side_offsets;
pub mod size;
<|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! libc - Raw FFI bindings to platforms' system libraries
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))]
#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core)
)]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![no_std]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]

#[cfg(feature = "use_std")]
extern crate std;

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "redox")] {
        mod redox;
        pub use redox::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod switch;
        pub use switch::*;
    } else if #[cfg(unix)] {
        mod unix;
        pub use unix::*;
    } else if #[cfg(target_env = "sgx")] {
        mod sgx;
        pub use sgx::*;
    }  else {
        // non-supported targets: empty...
    }
}
<commit_msg>Auto merge of #1269 - gnzlbg:fix_cp_pub, r=gnzlbg<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! libc - Raw FFI bindings to platforms' system libraries
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))]
#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core)
)]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![no_std]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]

#[cfg(feature = "use_std")]
extern crate std;

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "redox")] {
        mod redox;
        pub use redox::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod switch;
        pub use switch::*;
    } else if #[cfg(unix)] {
        mod unix;
        pub use unix::*;
    } else if #[cfg(target_env = "sgx")] {
        mod sgx;
        pub use sgx::*;
    }  else {
        // non-supported targets: empty...
    }
}
<|endoftext|>