<commit_before>#![feature(i128_type)]

extern crate rand;
extern crate byteorder;
extern crate secp256k1;
extern crate bytes;
extern crate tokio_io;
extern crate tokio_serde_bincode;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate vec_map;
extern crate futures;
#[macro_use]
extern crate lazy_static;

use secp256k1::Secp256k1;

mod solver;
mod rng;
mod field;
mod messages;

type SymmetricKey = [u8; 32];
type PeerIndex = u32;
type SequenceNum = u32;

// FIXME We store the peer ID in two [u8; 32], as this allows us to derive various traits.
// This can be resolved in the future using const generics, see the corresponding Rust RFC:
// https://github.com/rust-lang/rfcs/pull/2000/files
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct PeerId([u8; 32], [u8; 32]);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct SessionId([u8; 32]);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
enum ConfirmationVariant {
    EcdsaSignatures,
    ValueShuffle,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Options {
    confirmation: ConfirmationVariant,
    num_dc_xor: usize,
    num_dc_add_secp251k1_scalar: usize,
}

impl Options {
    fn new_simple() -> Self {
        Self {
            confirmation: EcdsaSignatures,
            num_dc_xor: 1,
            num_dc_add_secp251k1_scalar: 0,
        }
    }

    fn new_valueshuffle() -> Self {
        Self {
            confirmation_variant: ValueShuffle,
            num_dc_xor: 1,
            num_dc_add_secp251k1_scalar: 1,
        }
    }

    fn confirmation(&self) -> ConfirmationVariant {
        self.confirmation
    }

    fn num_dc_xor(&self) -> usize {
        self.num_dc_xor
    }

    fn num_dc_add_secp251k1_scalar(&self) -> usize {
        self.num_dc_add_secp251k1_scalar
    }
}

lazy_static! {
    pub static ref SECP256K1: Secp256k1 = Secp256k1::new();
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Fix compilation<commit_after>#![feature(i128_type)]

extern crate rand;
extern crate byteorder;
extern crate secp256k1;
extern crate bytes;
extern crate tokio_io;
extern crate tokio_serde_bincode;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate vec_map;
extern crate futures;
#[macro_use]
extern crate lazy_static;

use secp256k1::Secp256k1;

mod solver;
mod rng;
mod field;
mod messages;

lazy_static! {
    pub static ref SECP256K1: Secp256k1 = Secp256k1::new();
}

type SymmetricKey = [u8; 32];
type PeerIndex = u32;
type SequenceNum = u32;

// FIXME We store the peer ID in two [u8; 32], as this allows us to derive various traits.
// This can be resolved in the future using const generics, see the corresponding Rust RFC:
// https://github.com/rust-lang/rfcs/pull/2000/files
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct PeerId([u8; 32], [u8; 32]);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
struct SessionId([u8; 32]);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
enum ConfirmationVariant {
    EcdsaSignatures,
    ValueShuffle,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Options {
    confirmation: ConfirmationVariant,
    num_dc_xor: usize,
    num_dc_add_secp251k1_scalar: usize,
}

impl Options {
    fn new_simple() -> Self {
        Self {
            confirmation: ConfirmationVariant::EcdsaSignatures,
            num_dc_xor: 1,
            num_dc_add_secp251k1_scalar: 0,
        }
    }

    fn new_valueshuffle() -> Self {
        Self {
            confirmation: ConfirmationVariant::ValueShuffle,
            num_dc_xor: 1,
            num_dc_add_secp251k1_scalar: 1,
        }
    }

    fn confirmation(&self) -> ConfirmationVariant {
        self.confirmation
    }

    fn num_dc_xor(&self) -> usize {
        self.num_dc_xor
    }

    fn num_dc_add_secp251k1_scalar(&self) -> usize {
        self.num_dc_add_secp251k1_scalar
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>extern crate curl;
extern crate url;
extern crate rustc_serialize;

mod util;

use std::str;
use std::collections::HashMap;
use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;

use curl::http;
use url::Url;

pub use rustc_serialize::json::{Json, BuilderError};

#[derive(Clone)]
pub struct Firebase {
    url: Arc<Url>,
}

impl Firebase {
    pub fn new(url: &str) -> Result<Self, ParseError> {
        let url = util::add_https(&url);
        let url = try!( parse(&url) );
        try!( unwrap_path(&url) );

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn from_url(url: &Url) -> Result<Self, ParseError> {
        let url = url.clone();
        try!( unwrap_path(&url) );

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn authed(url: &str, auth_token: &str) -> Result<Self, ParseError> {
        let url = util::add_https(&url);
        let mut url = try!( parse(&url) );
        try!( unwrap_path(&url) );

        let opts = vec![ (AUTH, auth_token) ];
        url.set_query_from_pairs(opts.into_iter());

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn at(&self, add_path: &str) -> Result<Self, ParseError> {
        let mut url = (*self.url).clone();

        { // Add path to original path, already checked for path.
            let mut path = url.path_mut().unwrap();
            // Remove .json from the old path's end.
            if let Some(end) = path.pop() {
                let new_end = util::trim_right(&end, ".json").to_string();
                path.push(new_end);
            }
            let add_path = util::trim_right(add_path, "/");
            let add_path = util::trim_left(add_path, "/");
            let add_path = util::add_right(add_path, ".json");

            for component in add_path.split("/").into_iter() {
                path.push(component.to_string());
            }
        }

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn ops(&self, opts: &FbOps) -> FirebaseParams {
        FirebaseParams::from_ops(&self.url, opts)
    }

    fn with_params<T: ToString>(&self, key: &'static str, value: T) -> FirebaseParams {
        FirebaseParams::new(&self.url, key, value)
    }

    pub fn get(&self) -> Result<Response, ReqErr> {
        self.request(Method::GET, None)
    }

    pub fn set(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::PUT, Some(data))
    }

    pub fn push(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::POST, Some(data))
    }

    pub fn update(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::PATCH, Some(data))
    }

    pub fn remove(&self) -> Result<Response, ReqErr> {
        self.request(Method::DELETE, None)
    }

    pub fn get_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::GET, None, callback)
    }

    pub fn set_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::PUT, Some(data.into()), callback)
    }

    pub fn push_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::POST, Some(data.into()), callback)
    }

    pub fn update_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::PATCH, Some(data.into()), callback)
    }

    pub fn remove_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::DELETE, None, callback)
    }

    pub fn order_by(&self, key: &str) -> FirebaseParams {
        self.with_params(ORDER_BY, key)
    }

    pub fn limit_to_first(&self, count: u32) -> FirebaseParams {
        self.with_params(LIMIT_TO_FIRST, count)
    }

    pub fn limit_to_last(&self, count: u32) -> FirebaseParams {
        self.with_params(LIMIT_TO_LAST, count)
    }

    pub fn start_at(&self, index: u32) -> FirebaseParams {
        self.with_params(START_AT, index)
    }

    pub fn end_at(&self, index: u32) -> FirebaseParams {
        self.with_params(END_AT, index)
    }

    pub fn equal_to(&self, value: u32) -> FirebaseParams {
        self.with_params(EQUAL_TO, value)
    }

    pub fn shallow(&self, flag: bool) -> FirebaseParams {
        self.with_params(SHALLOW, flag)
    }

    pub fn format(&self) -> FirebaseParams {
        self.with_params(FORMAT, EXPORT)
    }

    pub fn get_url(&self) -> String {
        self.url.serialize()
    }

    #[inline]
    fn request(&self, method: Method, data: Option<&str>) -> Result<Response, ReqErr> {
        Firebase::request_url(&self.url, method, data)
    }

    fn request_url(url: &Url, method: Method, data: Option<&str>) -> Result<Response, ReqErr> {
        let mut handler = http::handle();

        let req = match method {
            Method::GET     => handler.get(   url),
            Method::POST    => handler.post(  url, data.unwrap()),
            Method::PUT     => handler.put(   url, data.unwrap()),
            Method::PATCH   => handler.patch( url, data.unwrap()),
            Method::DELETE  => handler.delete(url),
        };

        let res = match req.exec() {
            Ok(r)  => r,
            Err(e) => return Err(ReqErr::NetworkErr(e)),
        };

        let body = match str::from_utf8(res.get_body()) {
            Ok(b)  => b,
            Err(e) => return Err(ReqErr::RespNotUTF8(e)),
        };

        Ok(Response {
            body: body.to_string(),
            code: res.get_code(),
        })
    }

    fn request_url_async<F>(url: &Arc<Url>, method: Method, data: Option<String>, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        // Fast, because its in an arc.
        let url = url.clone();

        thread::spawn(move || {
            callback(Firebase::request_url(&url, method, data.as_ref().map(|s| s as &str)));
        })
    }
}

#[derive(Clone)]
pub struct FirebaseParams {
    url: Arc<Url>,
    params: HashMap<&'static str, String>,
}

impl FirebaseParams {
    pub fn get(&self) -> Result<Response, ReqErr> {
        Firebase::request_url(&self.url, Method::GET, None)
    }

    pub fn get_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::GET, None, callback)
    }

    pub fn order_by(self, key: &str) -> Self {
        self.add_param(ORDER_BY, key)
    }

    pub fn limit_to_first(self, count: u32) -> Self {
        self.add_param(LIMIT_TO_FIRST, count)
    }

    pub fn limit_to_last(self, count: u32) -> Self {
        self.add_param(LIMIT_TO_LAST, count)
    }

    pub fn start_at(self, index: u32) -> Self {
        self.add_param(START_AT, index)
    }

    pub fn end_at(self, index: u32) -> Self {
        self.add_param(END_AT, index)
    }

    pub fn equal_to(self, value: u32) -> Self {
        self.add_param(EQUAL_TO, value)
    }

    pub fn shallow(self, flag: bool) -> Self {
        self.add_param(SHALLOW, flag)
    }

    pub fn format(self) -> Self {
        self.add_param(FORMAT, EXPORT)
    }

    pub fn get_url(&self) -> String {
        self.url.serialize()
    }

    fn add_param<T: ToString>(mut self, key: &'static str, value: T) -> Self {
        let value = value.to_string();
        self.params.insert(key, value);
        self.set_params();
        self
    }

    fn set_params(&mut self) {
        // Only clones the url when edited. This is CoW
        // Many threads can run requests without ever cloning the url.
        let mut url = (*self.url).clone();
        url.set_query_from_pairs(self.params.iter().map(|(&k, v)| (k, v as &str)));
        self.url = Arc::new(url);
    }

    fn get_auth(url: &Url) -> HashMap<&'static str, String> {
        let mut pair: HashMap<&'static str, String> = HashMap::new();

        if let Some(queries) = url.query_pairs() {
            for &(ref k, ref v) in queries.iter() {
                if k == AUTH {
                    pair.insert(AUTH, v.to_string());
                }
            }
        }
        pair
    }

    fn new<T: ToString>(url: &Url, key: &'static str, value: T) -> Self {
        let me = FirebaseParams {
            url: Arc::new(url.clone()),
            params: FirebaseParams::get_auth(&url),
        };
        me.add_param(key, value)
    }

    fn from_ops(url: &Url, opts: &FbOps) -> Self {
        let mut me = FirebaseParams {
            url: Arc::new(url.clone()),
            params: FirebaseParams::get_auth(&url),
        };
        if let Some(order) = opts.order_by {
            me.params.insert(ORDER_BY, order.to_string());
        }
        if let Some(first) = opts.limit_to_first {
            me.params.insert(LIMIT_TO_FIRST, first.to_string());
        }
        if let Some(last) = opts.limit_to_last {
            me.params.insert(LIMIT_TO_LAST, last.to_string());
        }
        if let Some(start) = opts.start_at {
            me.params.insert(START_AT, start.to_string());
        }
        if let Some(end) = opts.end_at {
            me.params.insert(END_AT, end.to_string());
        }
        if let Some(equal) = opts.equal_to {
            me.params.insert(EQUAL_TO, equal.to_string());
        }
        if let Some(shallow) = opts.shallow {
            me.params.insert(SHALLOW, shallow.to_string());
        }
        if let Some(format) = opts.format {
            if format {
                me.params.insert(FORMAT, EXPORT.to_string());
            }
        }
        // Copy all of the params into the url.
        me.set_params();
        me
    }
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

const ORDER_BY:       &'static str = "orderBy";
const LIMIT_TO_FIRST: &'static str = "limitToFirst";
const LIMIT_TO_LAST:  &'static str = "limitToLast";
const START_AT:       &'static str = "startAt";
const END_AT:         &'static str = "endAt";
const EQUAL_TO:       &'static str = "equalTo";
const SHALLOW:        &'static str = "shallow";
const FORMAT:         &'static str = "format";
const EXPORT:         &'static str = "export";
const AUTH:           &'static str = "auth";

#[derive(Debug)]
pub struct FbOps<'l> {
    pub order_by:       Option<&'l str>,
    pub limit_to_first: Option<u32>,
    pub limit_to_last:  Option<u32>,
    pub start_at:       Option<u32>,
    pub end_at:         Option<u32>,
    pub equal_to:       Option<u32>,
    pub shallow:        Option<bool>,
    pub format:         Option<bool>,
}

impl<'l> Default for FbOps<'l> {
    fn default() -> Self {
        FbOps {
            order_by:       None,
            limit_to_first: None,
            limit_to_last:  None,
            start_at:       None,
            end_at:         None,
            equal_to:       None,
            shallow:        None,
            format:         None,
        }
    }
}

#[derive(Debug)]
pub enum ReqErr {
    RespNotUTF8(str::Utf8Error),
    NetworkErr(curl::ErrCode),
}

#[derive(Debug)]
pub enum ParseError {
    UrlHasNoPath,
    Parser(url::ParseError),
}

#[derive(Debug)]
pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        self.code < 400
    }

    pub fn to_json(&self) -> Result<Json, BuilderError> {
        Json::from_str(&self.body)
    }
}

fn parse(url: &str) -> Result<Url, ParseError> {
    match Url::parse(&url) {
        Ok(u)  => Ok(u),
        Err(e) => Err(ParseError::Parser(e)),
    }
}

fn unwrap_path(url: &Url) -> Result<&[String], ParseError> {
    match url.path() {
        None    => return Err(ParseError::UrlHasNoPath),
        Some(p) => return Ok(p),
    }
}
<commit_msg>Added parsing into struct for responses<commit_after>extern crate curl;
extern crate url;
extern crate rustc_serialize;

mod util;

use std::str;
use std::collections::HashMap;
use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;

use curl::http;
use url::Url;

use rustc_serialize::Decodable;
use rustc_serialize::json;
pub use rustc_serialize::json::{Json, BuilderError, DecoderError};

#[derive(Clone)]
pub struct Firebase {
    url: Arc<Url>,
}

impl Firebase {
    pub fn new(url: &str) -> Result<Self, ParseError> {
        let url = util::add_https(&url);
        let url = try!( parse(&url) );
        try!( unwrap_path(&url) );

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn from_url(url: &Url) -> Result<Self, ParseError> {
        let url = url.clone();
        try!( unwrap_path(&url) );

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn authed(url: &str, auth_token: &str) -> Result<Self, ParseError> {
        let url = util::add_https(&url);
        let mut url = try!( parse(&url) );
        try!( unwrap_path(&url) );

        let opts = vec![ (AUTH, auth_token) ];
        url.set_query_from_pairs(opts.into_iter());

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn at(&self, add_path: &str) -> Result<Self, ParseError> {
        let mut url = (*self.url).clone();

        { // Add path to original path, already checked for path.
            let mut path = url.path_mut().unwrap();
            // Remove .json from the old path's end.
            if let Some(end) = path.pop() {
                let new_end = util::trim_right(&end, ".json").to_string();
                path.push(new_end);
            }
            let add_path = util::trim_right(add_path, "/");
            let add_path = util::trim_left(add_path, "/");
            let add_path = util::add_right(add_path, ".json");

            for component in add_path.split("/").into_iter() {
                path.push(component.to_string());
            }
        }

        Ok(Firebase {
            url: Arc::new(url),
        })
    }

    pub fn ops(&self, opts: &FbOps) -> FirebaseParams {
        FirebaseParams::from_ops(&self.url, opts)
    }

    fn with_params<T: ToString>(&self, key: &'static str, value: T) -> FirebaseParams {
        FirebaseParams::new(&self.url, key, value)
    }

    pub fn get(&self) -> Result<Response, ReqErr> {
        self.request(Method::GET, None)
    }

    pub fn set(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::PUT, Some(data))
    }

    pub fn push(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::POST, Some(data))
    }

    pub fn update(&self, data: &str) -> Result<Response, ReqErr> {
        self.request(Method::PATCH, Some(data))
    }

    pub fn remove(&self) -> Result<Response, ReqErr> {
        self.request(Method::DELETE, None)
    }

    pub fn get_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::GET, None, callback)
    }

    pub fn set_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::PUT, Some(data.into()), callback)
    }

    pub fn push_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::POST, Some(data.into()), callback)
    }

    pub fn update_async<S, F>(&self, data: S, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static, S: Into<String> {
        Firebase::request_url_async(&self.url, Method::PATCH, Some(data.into()), callback)
    }

    pub fn remove_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::DELETE, None, callback)
    }

    pub fn order_by(&self, key: &str) -> FirebaseParams {
        self.with_params(ORDER_BY, key)
    }

    pub fn limit_to_first(&self, count: u32) -> FirebaseParams {
        self.with_params(LIMIT_TO_FIRST, count)
    }

    pub fn limit_to_last(&self, count: u32) -> FirebaseParams {
        self.with_params(LIMIT_TO_LAST, count)
    }

    pub fn start_at(&self, index: u32) -> FirebaseParams {
        self.with_params(START_AT, index)
    }

    pub fn end_at(&self, index: u32) -> FirebaseParams {
        self.with_params(END_AT, index)
    }

    pub fn equal_to(&self, value: u32) -> FirebaseParams {
        self.with_params(EQUAL_TO, value)
    }

    pub fn shallow(&self, flag: bool) -> FirebaseParams {
        self.with_params(SHALLOW, flag)
    }

    pub fn format(&self) -> FirebaseParams {
        self.with_params(FORMAT, EXPORT)
    }

    pub fn get_url(&self) -> String {
        self.url.serialize()
    }

    #[inline]
    fn request(&self, method: Method, data: Option<&str>) -> Result<Response, ReqErr> {
        Firebase::request_url(&self.url, method, data)
    }

    fn request_url(url: &Url, method: Method, data: Option<&str>) -> Result<Response, ReqErr> {
        let mut handler = http::handle();

        let req = match method {
            Method::GET     => handler.get(   url),
            Method::POST    => handler.post(  url, data.unwrap()),
            Method::PUT     => handler.put(   url, data.unwrap()),
            Method::PATCH   => handler.patch( url, data.unwrap()),
            Method::DELETE  => handler.delete(url),
        };

        let res = match req.exec() {
            Ok(r)  => r,
            Err(e) => return Err(ReqErr::NetworkErr(e)),
        };

        let body = match str::from_utf8(res.get_body()) {
            Ok(b)  => b,
            Err(e) => return Err(ReqErr::RespNotUTF8(e)),
        };

        Ok(Response {
            body: body.to_string(),
            code: res.get_code(),
        })
    }

    fn request_url_async<F>(url: &Arc<Url>, method: Method, data: Option<String>, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        // Fast, because its in an arc.
        let url = url.clone();

        thread::spawn(move || {
            callback(Firebase::request_url(&url, method, data.as_ref().map(|s| s as &str)));
        })
    }
}

#[derive(Clone)]
pub struct FirebaseParams {
    url: Arc<Url>,
    params: HashMap<&'static str, String>,
}

impl FirebaseParams {
    pub fn get(&self) -> Result<Response, ReqErr> {
        Firebase::request_url(&self.url, Method::GET, None)
    }

    pub fn get_async<F>(&self, callback: F) -> JoinHandle<()>
    where F: Fn(Result<Response, ReqErr>) + Send + 'static {
        Firebase::request_url_async(&self.url, Method::GET, None, callback)
    }

    pub fn order_by(self, key: &str) -> Self {
        self.add_param(ORDER_BY, key)
    }

    pub fn limit_to_first(self, count: u32) -> Self {
        self.add_param(LIMIT_TO_FIRST, count)
    }

    pub fn limit_to_last(self, count: u32) -> Self {
        self.add_param(LIMIT_TO_LAST, count)
    }

    pub fn start_at(self, index: u32) -> Self {
        self.add_param(START_AT, index)
    }

    pub fn end_at(self, index: u32) -> Self {
        self.add_param(END_AT, index)
    }

    pub fn equal_to(self, value: u32) -> Self {
        self.add_param(EQUAL_TO, value)
    }

    pub fn shallow(self, flag: bool) -> Self {
        self.add_param(SHALLOW, flag)
    }

    pub fn format(self) -> Self {
        self.add_param(FORMAT, EXPORT)
    }

    pub fn get_url(&self) -> String {
        self.url.serialize()
    }

    fn add_param<T: ToString>(mut self, key: &'static str, value: T) -> Self {
        let value = value.to_string();
        self.params.insert(key, value);
        self.set_params();
        self
    }

    fn set_params(&mut self) {
        // Only clones the url when edited. This is CoW
        // Many threads can run requests without ever cloning the url.
        let mut url = (*self.url).clone();
        url.set_query_from_pairs(self.params.iter().map(|(&k, v)| (k, v as &str)));
        self.url = Arc::new(url);
    }

    fn get_auth(url: &Url) -> HashMap<&'static str, String> {
        let mut pair: HashMap<&'static str, String> = HashMap::new();

        if let Some(queries) = url.query_pairs() {
            for &(ref k, ref v) in queries.iter() {
                if k == AUTH {
                    pair.insert(AUTH, v.to_string());
                }
            }
        }
        pair
    }

    fn new<T: ToString>(url: &Url, key: &'static str, value: T) -> Self {
        let me = FirebaseParams {
            url: Arc::new(url.clone()),
            params: FirebaseParams::get_auth(&url),
        };
        me.add_param(key, value)
    }

    fn from_ops(url: &Url, opts: &FbOps) -> Self {
        let mut me = FirebaseParams {
            url: Arc::new(url.clone()),
            params: FirebaseParams::get_auth(&url),
        };
        if let Some(order) = opts.order_by {
            me.params.insert(ORDER_BY, order.to_string());
        }
        if let Some(first) = opts.limit_to_first {
            me.params.insert(LIMIT_TO_FIRST, first.to_string());
        }
        if let Some(last) = opts.limit_to_last {
            me.params.insert(LIMIT_TO_LAST, last.to_string());
        }
        if let Some(start) = opts.start_at {
            me.params.insert(START_AT, start.to_string());
        }
        if let Some(end) = opts.end_at {
            me.params.insert(END_AT, end.to_string());
        }
        if let Some(equal) = opts.equal_to {
            me.params.insert(EQUAL_TO, equal.to_string());
        }
        if let Some(shallow) = opts.shallow {
            me.params.insert(SHALLOW, shallow.to_string());
        }
        if let Some(format) = opts.format {
            if format {
                me.params.insert(FORMAT, EXPORT.to_string());
            }
        }
        // Copy all of the params into the url.
        me.set_params();
        me
    }
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

const ORDER_BY:       &'static str = "orderBy";
const LIMIT_TO_FIRST: &'static str = "limitToFirst";
const LIMIT_TO_LAST:  &'static str = "limitToLast";
const START_AT:       &'static str = "startAt";
const END_AT:         &'static str = "endAt";
const EQUAL_TO:       &'static str = "equalTo";
const SHALLOW:        &'static str = "shallow";
const FORMAT:         &'static str = "format";
const EXPORT:         &'static str = "export";
const AUTH:           &'static str = "auth";

#[derive(Debug)]
pub struct FbOps<'l> {
    pub order_by:       Option<&'l str>,
    pub limit_to_first: Option<u32>,
    pub limit_to_last:  Option<u32>,
    pub start_at:       Option<u32>,
    pub end_at:         Option<u32>,
    pub equal_to:       Option<u32>,
    pub shallow:        Option<bool>,
    pub format:         Option<bool>,
}

impl<'l> Default for FbOps<'l> {
    fn default() -> Self {
        FbOps {
            order_by:       None,
            limit_to_first: None,
            limit_to_last:  None,
            start_at:       None,
            end_at:         None,
            equal_to:       None,
            shallow:        None,
            format:         None,
        }
    }
}

#[derive(Debug)]
pub enum ReqErr {
    RespNotUTF8(str::Utf8Error),
    NetworkErr(curl::ErrCode),
}

#[derive(Debug)]
pub enum ParseError {
    UrlHasNoPath,
    Parser(url::ParseError),
}

#[derive(Debug)]
pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        self.code == 200
    }

    pub fn json(&self) -> Result<Json, BuilderError> {
        Json::from_str(&self.body)
    }

    pub fn parse<D>(&self) -> Result<D, DecoderError> where D: Decodable {
        json::decode(&self.body)
    }
}

fn parse(url: &str) -> Result<Url, ParseError> {
    match Url::parse(&url) {
        Ok(u)  => Ok(u),
        Err(e) => Err(ParseError::Parser(e)),
    }
}

fn unwrap_path(url: &Url) -> Result<&[String], ParseError> {
    match url.path() {
        None    => return Err(ParseError::UrlHasNoPath),
        Some(p) => return Ok(p),
    }
}
<|endoftext|>


<commit_before>use files;

pub struct ObjectData
{
    pub verts: Vec<[f32; 3]>,
    pub normals: Vec<[f32; 3]>,
    pub uvs: Vec<[f32; 3]>,
    pub faces: Vec<u8>,
}

fn add_vertex(vert: [f32; 3], obj_data: &mut ObjectData)
{
    obj_data.verts.push(vert);
    obj_data.normals.push([0.0, 0.0, 0.0]);
}

fn parse_coord_line(coord_strs: &Vec<&str>) -> [f32; 3]
{
    const COORD_AMOUNT :usize = 3;
    let mut curr_index = 0;
    let mut coords: [f32; COORD_AMOUNT] = [0.0; COORD_AMOUNT];
    //Iterate over all the coordinates in the vertex and add them to the object data
    for coord_str in coord_strs
    {
        if curr_index < COORD_AMOUNT
        {
            match coord_str.parse::<f32>()
            {
                Ok(val) => coords[curr_index] = val,
                Err(e) => panic!("failed to load .obj file, malformed coordinates: {} \n{}", coord_str, e)
            }
        }
        curr_index += 1;
    }

    return coords;
}
fn parse_face_line(face_strs: &Vec<&str>, obj_data: &mut ObjectData)
{

}

pub fn load_obj_file(path :&String) -> ObjectData
{
    let mut obj_data = ObjectData{verts: vec!(), normals: vec!(), uvs: vec!(), faces: vec!()};
    let mut normal_list: Vec<[f32; 3]> = vec!();

    let file_content: String = files::load_whole_file(path);

    //Split the file  into individual lines
    let file_lines: Vec<&str> = file_content.split("\n").collect();

    for line in file_lines
    {
        //split the line at spaces
        let segments: Vec<&str> = line.split(" ").collect();

        //Skipping empty lines or comments
        if segments.len() == 0
        {
            continue;
        }

        let first_char = segments[0].chars().nth(0);
        match first_char
        {
            Some(t) => if t == '#' {continue},
            None => continue
        }

        //let rest_of_line = segments[1..];==> No kernel 4.5.1-1-ARCH headers. You must install them to use DKMS!
        let mut rest_of_line: Vec<&str> = Vec::new();
        rest_of_line.clone_from_slice(&(segments[1..]));

        match segments[0]
        {
            "v" => obj_data.verts.push(parse_coord_line(&rest_of_line)),
            "vn" => normal_list.push(parse_coord_line(&rest_of_line)),
            "f" => parse_face_line(&rest_of_line, &mut obj_data),
            _ => println!("Unknown obj file part: {} when loading {}", segments[0], path)
        }
    }

    return obj_data;
}
<commit_msg>Work on obj loader<commit_after>use files;

pub struct ObjectData
{
    pub verts: Vec<[f32; 3]>,
    pub normals: Vec<[f32; 3]>,
    pub uvs: Vec<[f32; 3]>,
    pub faces: Vec<u32>,
}

fn add_vertex(vert: [f32; 3], obj_data: &mut ObjectData)
{
    obj_data.verts.push(vert);
    obj_data.normals.push([0.0, 0.0, 0.0]);
}

fn parse_coord_line(coord_strs: &Vec<&str>) -> [f32; 3]
{
    const COORD_AMOUNT :usize = 3;
    let mut curr_index = 0;
    let mut coords: [f32; COORD_AMOUNT] = [0.0; COORD_AMOUNT];
    //Iterate over all the coordinates in the vertex and add them to the object data
    for coord_str in coord_strs
    {
        if curr_index < COORD_AMOUNT
        {
            match coord_str.parse::<f32>()
            {
                Ok(val) => coords[curr_index] = val,
                Err(e) => panic!("failed to load .obj file, malformed coordinates: {} \n{}", coord_str, e)
            }
        }
        curr_index += 1;
    }

    return coords;
}
fn parse_face_line(face_strs: &Vec<&str>, obj_data: &mut ObjectData, normal_list: &Vec<[f32; 3]>)
{
    for face in face_strs
    {
        let face_params: Vec<&str> = face_strs.split("/").collect();

        if segments.len() == 3
        {
            let mut face_index = 0;
            let mut normal_index = 0;

            match face_params[0].parse::<u32>()
            {
                Ok(val) => face_index = val,
                Err(e) => panic!("Failed to load .obj file, malformed vertex index in face. {}\n{}", face_params[0], e)
            }
            match face_params[0].parse::<u32>()
            {
                Ok(val) => normal_index = val,
                Err(e) => panic!("Failed to load .obj file, malformed normal index in face. {}\n{}", face_params[0], e)
            }

            //We have loaded all the index data, add it to the model.
            let added_normal = normal_list[normal_index];

            obj_data.normals[added_normal] += added_normal;
        }
        else
        {
            panic!("Wrong amount of arguments in 'face' part of .obj file. Should be vertex/uv/normal");
        }
    }
}

pub fn load_obj_file(path :&String) -> ObjectData
{
    let mut obj_data = ObjectData{verts: vec!(), normals: vec!(), uvs: vec!(), faces: vec!()};
    let mut normal_list: Vec<[f32; 3]> = vec!();

    let file_content: String = files::load_whole_file(path);

    //Split the file  into individual lines
    let file_lines: Vec<&str> = file_content.split("\n").collect();

    for line in file_lines
    {
        //split the line at spaces
        let segments: Vec<&str> = line.split(" ").collect();

        //Skipping empty lines or comments
        if segments.len() == 0
        {
            continue;
        }

        let first_char = segments[0].chars().nth(0);
        match first_char
        {
            Some(t) => if t == '#' {continue},
            None => continue
        }

        //let rest_of_line = segments[1..];==> No kernel 4.5.1-1-ARCH headers. You must install them to use DKMS!
        let mut rest_of_line: Vec<&str> = Vec::new();
        rest_of_line.clone_from_slice(&(segments[1..]));

        match segments[0]
        {
            "v" => obj_data.verts.push(parse_coord_line(&rest_of_line)),
            "vn" => normal_list.push(parse_coord_line(&rest_of_line)),
            "f" => parse_face_line(&rest_of_line, &mut obj_data),
            _ => println!("Unknown obj file part: {} when loading {}", segments[0], path)
        }
    }

    return obj_data;
}
<|endoftext|>


<commit_before>
/// Actions are just boxed immutable functions that take an argument of the event that triggered them
pub type Action<S, E> = Box<Fn(&S,&E)>;

/// Predicates are used to filter down whether a transition can occur
pub type Predicate<S, E> = Box<Fn(&S,&E) -> bool>;

/// Trait that should be trivially implementable for any Enum type
pub trait EnumTag {
	/// returns the discriminator tag for the enum (some_value as usize)
	fn tag_number(&self) -> usize;
	/// returns the highest discriminator tag for this enum
	fn max_tag_number() -> usize;
	/// returns an instance of the enum from a tag number
	fn from_tag(tag: usize) -> Self;
}

/// The Transition records, for a given current state, what event type triggers it to move to
/// what state, performing a specific action on the transition, filterable by a predicate function
struct Transition<S: EnumTag, E: EnumTag> {
	predicate: Option<Predicate<S, E>>,
	next_state: S,
	action: Action<S, E>,
}

/// The EdgeTransitions record all the Transitions for a given event type
struct EventTransitions<S: EnumTag, E: EnumTag> {
	transitions: Vec<Transition<S, E>>,
}

/// The StateTransition records all Transitions for a given state
struct StateTransitions<S: EnumTag, E: EnumTag> {
	edges: Vec<EventTransitions<S, E>>,
}

/// The Machine is the Finite State Machine, which has a current state and set of all valid
/// transitions
pub struct Machine<S: EnumTag, E: EnumTag> {
	state: usize,
	transitions: Vec<StateTransitions<S, E>>,
}

impl<S: EnumTag, E: EnumTag> Machine<S, E> {
	/// Constructs a new FSM with a given initial state
	pub fn new(initial_state: S) -> Machine<S, E> {
		let mut transitions = Vec::with_capacity(S::max_tag_number());

		for _ in 0..S::max_tag_number() + 1 {
			let mut edges = Vec::with_capacity(E::max_tag_number());

			for _ in 0..E::max_tag_number() + 1 {
				edges.push(EventTransitions {
					transitions: Vec::new(),
				});
			}

			transitions.push(StateTransitions {
				edges: edges,
			});
		}

		Machine {
			state: initial_state.tag_number(),
			transitions: transitions,
		}
	}

	/// Registers a new valid transition with the FSM
	pub fn add_transition(&mut self, in_state: S, on_event: E, next_state: S, action: Action<S, E>) {
		let transition = &mut self.transitions[in_state.tag_number()];

		let edge = &mut transition.edges[on_event.tag_number()];

		edge.transitions.push(Transition {
			predicate: None,
			action: action,
			next_state: next_state,
		});
	}

	/// Retrieves a reference to the current state
	pub fn current_state(&self) -> S {
		S::from_tag(self.state)
	}

	/// Tick the State Machine with an Event
	pub fn on_event(&mut self, event_type: E) {
		let transition = &self.transitions[self.state];
		let edge = &transition.edges[event_type.tag_number()];

		for transition in edge.transitions.iter() {
			let valid = match &transition.predicate {
				&Some(ref p) => (*p)(&self.current_state(), &event_type),
				&None => true,
			};

			if valid {
				(*transition.action)(&self.current_state(), &event_type);
				self.state = transition.next_state.tag_number();
				break;
			}
		}
	}
}

#[cfg(test)]
mod test {
	use super::*;

	#[derive(Debug, Eq, PartialEq)]
	enum TurnStyleState {
		Locked,
		Unlocked,
	}

	#[derive(Debug, Eq, PartialEq)]
	enum TurnStyleEvent {
		Push,
		InsertCoin,
	}

	impl EnumTag for TurnStyleState {
		fn tag_number(&self) -> usize {
			match self {
				&TurnStyleState::Locked => 0,
				&TurnStyleState::Unlocked => 1
			}
		}
		fn max_tag_number() -> usize {
			TurnStyleState::Unlocked as usize
		}
		fn from_tag(tag: usize) -> TurnStyleState {
			match tag {
				0 => TurnStyleState::Locked,
				1 => TurnStyleState::Unlocked,
				_ => panic!("invalid tag number")
			}
		}
	}

	impl EnumTag for TurnStyleEvent {
		fn tag_number(&self) -> usize {
			match self {
				&TurnStyleEvent::Push => 0,
				&TurnStyleEvent::InsertCoin => 1
			}
		}
		fn max_tag_number() -> usize {
			TurnStyleEvent::InsertCoin as usize
		}
		fn from_tag(tag: usize) -> TurnStyleEvent {
			match tag {
				0 => TurnStyleEvent::Push,
				1 => TurnStyleEvent::InsertCoin,
				_ => panic!("invalid tag number")
			}
		}
	}

	#[test]
	fn test_machine() {
		let mut machine = Machine::new(TurnStyleState::Locked);
		machine.add_transition(
			TurnStyleState::Locked, TurnStyleEvent::InsertCoin,
			TurnStyleState::Unlocked, Box::new(|_,_| println!("unlocked"))
		);
		machine.add_transition(
			TurnStyleState::Unlocked, TurnStyleEvent::Push,
			TurnStyleState::Locked, Box::new(|_,_| println!("locked"))
		);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
	}
}
<commit_msg>gave up and added constraint of needing Copy, to enforce simple CLike enums as state and events<commit_after>
/// Actions are just boxed immutable functions that take an argument of the event that triggered them
pub type Action<S, E> = Box<Fn(&S,&E)>;

/// Predicates are used to filter down whether a transition can occur
pub type Predicate<S, E> = Box<Fn(&S,&E) -> bool>;

/// Trait that should be trivially implementable for any C-Like Enum type
pub trait EnumTag: Copy {
	/// returns the discriminator tag for the enum (some_value as usize)
	fn tag_number(&self) -> usize;
	/// returns the highest discriminator tag for this enum
	fn max_tag_number() -> usize;
}

/// The Transition records, for a given current state, what event type triggers it to move to
/// what state, performing a specific action on the transition, filterable by a predicate function
struct Transition<S: EnumTag, E: EnumTag> {
	predicate: Option<Predicate<S, E>>,
	next_state: S,
	action: Action<S, E>,
}

/// The EdgeTransitions record all the Transitions for a given event type
struct EventTransitions<S: EnumTag, E: EnumTag> {
	transitions: Vec<Transition<S, E>>,
}

/// The StateTransition records all Transitions for a given state
struct StateTransitions<S: EnumTag, E: EnumTag> {
	edges: Vec<EventTransitions<S, E>>,
}

/// The Machine is the Finite State Machine, which has a current state and set of all valid
/// transitions
pub struct Machine<S: EnumTag, E: EnumTag> {
	state: S,
	transitions: Vec<StateTransitions<S, E>>,
}

impl<S: EnumTag, E: EnumTag> Machine<S, E> {
	/// Constructs a new FSM with a given initial state
	pub fn new(initial_state: S) -> Machine<S, E> {
		let mut transitions = Vec::with_capacity(S::max_tag_number());

		for _ in 0..S::max_tag_number() + 1 {
			let mut edges = Vec::with_capacity(E::max_tag_number());

			for _ in 0..E::max_tag_number() + 1 {
				edges.push(EventTransitions {
					transitions: Vec::new(),
				});
			}

			transitions.push(StateTransitions {
				edges: edges,
			});
		}

		Machine {
			state: initial_state,
			transitions: transitions,
		}
	}

	/// Registers a new valid transition with the FSM
	pub fn add_transition(&mut self, in_state: S, on_event: E, next_state: S, action: Action<S, E>) {
		let transition = &mut self.transitions[in_state.tag_number()];

		let edge = &mut transition.edges[on_event.tag_number()];

		edge.transitions.push(Transition {
			predicate: None,
			action: action,
			next_state: next_state,
		});
	}

	/// Retrieves a reference to the current state
	pub fn current_state(&self) -> S {
		self.state
	}

	/// Tick the State Machine with an Event
	pub fn on_event(&mut self, event_type: E) {
		let transition = &self.transitions[self.state.tag_number()];
		let edge = &transition.edges[event_type.tag_number()];

		for transition in edge.transitions.iter() {
			let valid = match &transition.predicate {
				&Some(ref p) => (*p)(&self.current_state(), &event_type),
				&None => true,
			};

			if valid {
				(*transition.action)(&self.state, &event_type);
				self.state = transition.next_state;
				break;
			}
		}
	}
}

#[cfg(test)]
mod test {
	use super::*;

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleState {
		Locked,
		Unlocked,
	}

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleEvent {
		Push,
		InsertCoin,
	}

	impl EnumTag for TurnStyleState {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleState::Unlocked as usize
		}
	}

	impl EnumTag for TurnStyleEvent {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleEvent::InsertCoin as usize
		}
	}

	#[test]
	fn test_machine() {
		let mut machine = Machine::new(TurnStyleState::Locked);
		machine.add_transition(
			TurnStyleState::Locked, TurnStyleEvent::InsertCoin,
			TurnStyleState::Unlocked, Box::new(|_,_| println!("unlocked"))
		);
		machine.add_transition(
			TurnStyleState::Unlocked, TurnStyleEvent::Push,
			TurnStyleState::Locked, Box::new(|_,_| println!("locked"))
		);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
	}
}
<|endoftext|>


<commit_before>#![feature(globs)]

extern crate serialize;

extern crate conduit;
extern crate middleware = "conduit-middleware";
extern crate utils = "conduit-utils";

use std::fmt;
use std::fmt::{Show, Formatter};
use serialize::{Decodable, json};

use conduit::Request;
use utils::RequestDelegator;
use middleware::Middleware;

pub struct BodyReader<T>;

trait JsonDecodable : Decodable<json::Decoder, json::DecoderError> {}
impl<T: Decodable<json::Decoder, json::DecoderError>> JsonDecodable for T {}

impl<T: JsonDecodable + 'static> Middleware for BodyReader<T> {
    fn before(&self, req: &mut Request) -> Result<(), Box<Show>> {
        let json: T = try!(decode::<T>(req.body()).map_err(|err| {
            box format!("Couldn't parse JSON: {}", show(err)) as Box<Show>
        }));

        req.mut_extensions().insert(json);
        Ok(())
    }
}

// Hack around the lack of impl Show for Box<Show>
struct Shower<'a> {
    inner: &'a Show
}

impl<'a> Show for Shower<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

fn show<'a>(s: &'a Show) -> Shower<'a> {
    Shower { inner: s }
}

fn decode<T: JsonDecodable + 'static>(reader: &mut Reader) -> Result<T, Box<Show>> {
    let j = try!(json::from_reader(reader).map_err(|e| box e as Box<Show>));
    let mut decoder = json::Decoder::new(j);
    Decodable::decode(&mut decoder).map_err(|e| box e as Box<Show>)
}

pub fn json_params<'a, T: JsonDecodable + 'static>(req: &'a Request) -> Option<&'a T> {
    req.extensions().find::<T>()
}

#[cfg(test)]
mod tests {
    extern crate conduit_test = "conduit-test";

    use {json_params, BodyReader};

    use std::collections::HashMap;
    use std::io::MemReader;
    use serialize::json;

    use conduit;
    use conduit::{Request, Response, Handler};
    use middleware::MiddlewareBuilder;

    #[deriving(PartialEq, Decodable, Encodable, Show)]
    struct Person {
        name: String,
        location: String
    }

    fn handler(req: &mut Request) -> Result<Response, ()> {
        let person = json_params::<Person>(req);
        let out = person.map(|p| json::encode(p)).expect("No JSON");

        Ok(Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(out.into_bytes()) as Box<Reader + Send>
        })
    }

    #[test]
    fn test_body_params() {
        let mut req = conduit_test::MockRequest::new(conduit::Get, "/");
        req.with_body(r#"{ "name": "Alex Crichton", "location": "San Francisco" }"#);

        let mut middleware = MiddlewareBuilder::new(handler);
        middleware.add(BodyReader::<Person>);

        let mut res = middleware.call(&mut req).ok().expect("No response");
        let person = super::decode::<Person>(res.body).ok().expect("No JSON response");
        assert_eq!(person, Person {
            name: "Alex Crichton".to_string(),
            location: "San Francisco".to_string()
        });
    }
}
<commit_msg>Update to master<commit_after>#![feature(globs)]

extern crate serialize;

extern crate conduit;
extern crate middleware = "conduit-middleware";
extern crate utils = "conduit-utils";

use std::fmt;
use std::fmt::{Show, Formatter};
use serialize::{Decodable, json};

use conduit::Request;
use utils::RequestDelegator;
use middleware::Middleware;

pub struct BodyReader<T>;

trait JsonDecodable : Decodable<json::Decoder, json::DecoderError> {}
impl<T: Decodable<json::Decoder, json::DecoderError>> JsonDecodable for T {}

impl<T: JsonDecodable + 'static> Middleware for BodyReader<T> {
    fn before(&self, req: &mut Request) -> Result<(), Box<Show + 'static>> {
        let json: T = try!(decode::<T>(req.body()).map_err(|err| {
            box format!("Couldn't parse JSON: {}", show(err)) as Box<Show>
        }));

        req.mut_extensions().insert(json);
        Ok(())
    }
}

// Hack around the lack of impl Show for Box<Show>
struct Shower<'a> {
    inner: &'a Show + 'a
}

impl<'a> Show for Shower<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

fn show<'a>(s: &'a Show) -> Shower<'a> {
    Shower { inner: s }
}

fn decode<T: JsonDecodable + 'static>(reader: &mut Reader) -> Result<T, Box<Show>> {
    let j = try!(json::from_reader(reader).map_err(|e| box e as Box<Show>));
    let mut decoder = json::Decoder::new(j);
    Decodable::decode(&mut decoder).map_err(|e| box e as Box<Show>)
}

pub fn json_params<'a, T: JsonDecodable + 'static>(req: &'a Request) -> Option<&'a T> {
    req.extensions().find::<T>()
}

#[cfg(test)]
mod tests {
    extern crate conduit_test = "conduit-test";

    use {json_params, BodyReader};

    use std::collections::HashMap;
    use std::io::MemReader;
    use serialize::json;

    use conduit;
    use conduit::{Request, Response, Handler};
    use middleware::MiddlewareBuilder;

    #[deriving(PartialEq, Decodable, Encodable, Show)]
    struct Person {
        name: String,
        location: String
    }

    fn handler(req: &mut Request) -> Result<Response, ()> {
        let person = json_params::<Person>(req);
        let out = person.map(|p| json::encode(p)).expect("No JSON");

        Ok(Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(out.into_bytes()) as Box<Reader + Send>
        })
    }

    #[test]
    fn test_body_params() {
        let mut req = conduit_test::MockRequest::new(conduit::Get, "/");
        req.with_body(r#"{ "name": "Alex Crichton", "location": "San Francisco" }"#);

        let mut middleware = MiddlewareBuilder::new(handler);
        middleware.add(BodyReader::<Person>);

        let mut res = middleware.call(&mut req).ok().expect("No response");
        let person = super::decode::<Person>(res.body).ok().expect("No JSON response");
        assert_eq!(person, Person {
            name: "Alex Crichton".to_string(),
            location: "San Francisco".to_string()
        });
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]

extern crate "boxdraw-rs" as boxdraw;

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

use boxdraw::{Undraw, Script};
use boxdraw::grid::Grid;

use std::char::from_u32;

pub struct SimpleSearch;

impl Undraw for SimpleSearch {
    fn undraw(&self, picture: &str) -> Script {
        debug!("undraw:\n{}", picture);

        let unused_char = self.find_unused_char(picture);

        let mut grid = Grid::from_str(picture).unwrap();
        let w = grid.width();
        let h = grid.height();

        let mut s = Script::new(w, h);

        // We find the commands in reverse order.
        let mut rev_commands = vec![];
        let mut cleared_some;
        loop {
            cleared_some = false;
            for y in range(0, h) {
                for x in range(0, w) {

                    match self.try_upper_left(&grid, unused_char, x, y) {
                        Some(cmd) => {
                            rev_commands.push(cmd);

                            // Now, clear the matched area.
                            debug!("clearing matched area ({},{}) of w:{} h:{}",
                                   x, y, cmd.w, cmd.h);
                            for i in range(x, x+cmd.w) {
                                for j in range(y, y+cmd.h) {
                                    grid.set(i, j, unused_char);
                                    cleared_some = true;
                                }
                            }
                        }

                        None => {
                            continue;
                        }
                    }

                }
            }
            if !cleared_some {
                break;
            }
        }
        let commands = {
            rev_commands.as_mut_slice().reverse();
            rev_commands
        };

        for cmd in commands.into_iter() {
            s.add_end_command(cmd);
        }

        s
    }
}

#[deriving(Show)]
enum MatchBox {
    ExactMatch(boxdraw::Command),
    PartialMatch,

    NonMatch(WhyNonMatch),
}

#[deriving(PartialEq, Show)]
struct WhyNonMatch {
    reason: String,
}

fn non_match(why: String) -> MatchBox {
    NonMatch(WhyNonMatch { reason: why })
}

impl PartialEq for MatchBox {
    fn eq(&self, that: &MatchBox) -> bool {
        match (self, that) {
            (&ExactMatch(c1), &ExactMatch(c2)) => {
                c1.x == c2.x &&
                    c1.y == c2.y &&
                    c1.w == c2.w &&
                    c1.h == c2.h &&
                    c1.fill == c2.fill
            }
            (&PartialMatch, &PartialMatch) => true,
            (&NonMatch(_), &NonMatch(_)) => true,
            _ => false
        }
    }
}

impl SimpleSearch {
    fn find_unused_char(&self, picture: &str) -> char {
        static AVOID : [char, ..5] = ['.', '+', '-', '|', '\n'];
        let mut guess = '?' as u32;
        loop {
            match from_u32(guess) {
                Some(char_guess) if !AVOID.contains(&char_guess) && !picture.contains_char(char_guess) => {
                    return char_guess;
                }
                _ => {
                    guess += 1;
                }
            }
        }
    }

    /// Attempts to match a box at `(x,y)`, using `hidden` as a marker
    /// for spaces that were overwritten by a later command.
    fn try_upper_left(&self, grid: &Grid, hidden: char, x: u32, y: u32) -> Option<boxdraw::Command> {

        let w = grid.width();
        let h = grid.height();

        // Found a left-corner; find the extent of the box.
        // println!("inspecting ({},{})", x, y);
        // println!("char at: ({},{}): '{}'", x, y, grid.get(x, y));

        let mut saw_partial = false;
        assert!(x < w); assert!(y < h);
        let c = grid.get(x,y);
        if c == '+' {
            'next_width:
            for i in range(x+1, w) {
                for j in range(y+1, h) {
                    let match_at = TryMatchAt {
                        grid: grid,
                        hidden: hidden,
                        x: x,
                        y: y,
                    };
                    match match_at.try(i, j) {
                        ExactMatch(cmd) => return Some(cmd),
                        PartialMatch => {
                            saw_partial = true;
                            continue;
                        }
                        NonMatch(ref why) => {
                            if saw_partial {
                                debug!("nonmatch for {}-{} because {}", (x,y), (i,j), why.reason);
                            }
                            continue 'next_width;
                        }
                    }
                }
            }
            None
        } else {
            None
        }
    }
}

struct TryMatchAt<'a> {
    grid: &'a Grid,
    hidden: char,
    x: u32,
    y: u32,
}

impl<'a> TryMatchAt<'a> {

    /// Attempts to match a box at `(self.x, self.y)` extending to `(right, below)`
    /// using `self.hidden` as a marker for spaces
    /// that were overwritten by a later command.
    fn try(&self, right: u32, below: u32) -> MatchBox {
        let x = self.x;
        let y = self.y;
        let grid = self.grid;
        let w = grid.width();
        let h = grid.height();

        let box_w = right - x + 1;
        let box_h = below - y + 1;

        let trial = (x, y, box_w, box_h);

        debug!("try: x {} y {} box_w {} box_h {} right {} below {} w {} h {}",
               x, y, box_w, box_h, right, below, w, h);

        assert!(x < w); assert!(y < h);
        let upper_left = grid.get(x, y);
        assert!(x < w); assert!(below < h);
        let lower_left = grid.get(x, below);
        assert!(right < w); assert!(y < h);
        let upper_right = grid.get(right, y);
        assert!(right < w); assert!(below < h);
        let lower_right = grid.get(right, below);

        let mut extends_right = false;
        let mut extends_down = false;

        // Tracks the character to use for the box interior, which we
        // do not necessarily know until scanning deep into the box.
        let mut interior = None;

        if !self.matches_corner(upper_left) {
            return non_match(format!("failed to match upper_left corner: {}", upper_left));
        }
        if !self.matches_corner(lower_left) {
            if lower_left == '|' {
                extends_down = true;
            } else {
                return non_match(format!("failed to match lower_left corner: {}", lower_left));
            }
        }

        if !self.matches_corner(upper_right) {
            if upper_right == '-' {
                extends_right = true;
            } else {
                return non_match(format!("failed to match upper_right corner: {}", upper_right));
            }
        }

        if !self.matches_corner(lower_right) {
            if extends_down && lower_right == '|' {
                // okay
            } else if extends_right && lower_right == '-' {
                // okay
            } else if extends_down && extends_right {
                if lower_right != self.hidden {
                    interior = Some(lower_right);
                }
            } else {
                return non_match(format!("failed to match lower_right corner: {}", lower_right));
            }
        }

        // Check that walls of box are in place.
        for i in range(x + 1, right) { // across
            assert!(i < w); assert!(y < h);
            let c = grid.get(i, y);
            if !self.matches_horizontal_wall(c) {
                return non_match(format!("failed to match top horizontal wall at {}: {}", (i, y), c));
            }
            assert!(i < w); assert!(below < h);
            let c = grid.get(i, below);
            if !extends_down {
                if !self.matches_horizontal_wall(c) {
                    return non_match(format!("failed to match bot horizontal wall at {}: {}", (i, below), c));
                }
            } else if c == self.hidden {
                // keep going
            } else {
                if interior.is_none() {
                    interior = Some(c);
                }
                if interior.is_some() && Some(c) != interior {
                    return non_match(format!("failed to match bot interior {} at {}: {}", interior, (i, below), c));
                }
            }
        }
        for j in range(y + 1, below) { // down
            assert!(x < w); assert!(j < h);
            let c = grid.get(x, j);
            if !self.matches_vertical_wall(c) {
                return non_match(format!("failed to match left vertical wall at {}: {}", (x, j), c));
            }
            assert!(right < w); assert!(j < h);
            let c = grid.get(right, j);
            if !extends_right {
                if !self.matches_vertical_wall(c) {
                    return non_match(format!("failed to match right vertical wall at {}: {}", (right, j), c));
                }
            } else if c == self.hidden {
                // keep going
            } else {
                if interior.is_none() {
                    interior = Some(c);
                }
                if interior.is_some() && Some(c) != interior {
                    return non_match(format!("failed to match right interior {} at {}: {}", interior, (right, j), c));
                }
            }
        }

        // Check that the interior is sound
        for i in range(x + 1, right) {
            for j in range(y + 1, below) {
                assert!(i < w); assert!(j < h);
                match (interior, grid.get(i, j)) {
                    (None, c) => {
                        if c == self.hidden {
                            // Okay, clean match and we still do not know
                            // what the interior is.
                            continue;
                        } else {
                            // finally, a non-hidden marker.  Assume
                            // that this is the interior.
                            interior = Some(c);
                            continue;
                        }
                    }
                    (Some(c1), c2) => {
                        if c1 == c2 || c2 == self.hidden {
                            // the color c2 matches the interior c1; keep
                            // going.
                            continue;
                        } else {
                            return non_match(format!("failed to match interior {} at {}: {}", c1, (i, j), c2));
                        }
                    }
                }
            }
        }

        // got this far; return either full or partial box, as
        // appropriate.

        if extends_down || extends_right {
            debug!("partial match {} interior: {}", trial, interior);
            PartialMatch
        } else {
            assert!(x+1 < w); assert!(y+1 < h);
            let fill = grid.get(x+1, y+1);
            let cmd = boxdraw::rect(x, y, box_w, box_h, fill);

            debug!("exact match: {}", cmd);
            ExactMatch(cmd)
        }
    }

    fn matches_corner(&self, c: char) -> bool {
        c == '+' || c == self.hidden
    }

    fn matches_horizontal_wall(&self, c: char) -> bool {
        c == '-' || c == self.hidden
    }

    fn matches_vertical_wall(&self, c: char) -> bool {
        c == '|' || c == self.hidden
    }
}

#[cfg(test)]
mod tests;
#[cfg(test)]
mod exercises;
<commit_msg>Slightly refactor and document the code.<commit_after>#![feature(phase)]

extern crate "boxdraw-rs" as boxdraw;

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

use boxdraw::{Undraw, Script, Command};
use boxdraw::grid::Grid;

use std::char::from_u32;

pub struct SimpleSearch;

impl Undraw for SimpleSearch {
    fn undraw(&self, picture: &str) -> Script {
        debug!("undraw:\n{}", picture);

        let unused_char = self.find_unused_char(picture);

        let mut grid = Grid::from_str(picture).unwrap();
        let w = grid.width();
        let h = grid.height();

        let mut s = Script::new(w, h);

        // We find the commands in reverse order.
        let mut rev_commands = vec![];
        let mut cleared_some;
        loop {
            cleared_some = false;
            for y in range(0, h) {
                for x in range(0, w) {

                    match self.try_upper_left(&grid, unused_char, x, y) {
                        Some(cmd) => {
                            // Save the command for a box at (x,y),
                            // and record the effects it will have on
                            // the board (by clearing the area it
                            // covers).
                            rev_commands.push(cmd);
                            self.clear_area_drawn_by_cmd(&mut grid,
                                                         cmd,
                                                         unused_char);
                            cleared_some = true;
                        }

                        None => {
                            continue;
                        }
                    }

                }
            }

            // If we managed to clear *any* of the areas, then we
            // should go back and look to see if we can now find
            // matches for boxes that were previously obscured by the
            // boxes that were on top of them.
            if !cleared_some {
                break;
            }
        }

        // Done accumulating commands; now put them into a proper
        // script.
        let commands = {
            rev_commands.as_mut_slice().reverse();
            rev_commands
        };

        for cmd in commands.into_iter() {
            s.add_end_command(cmd);
        }

        return s;
    }
}

#[deriving(Show)]
enum MatchBox {
    ExactMatch(boxdraw::Command),
    PartialMatch,

    NonMatch(WhyNonMatch),
}

#[deriving(PartialEq, Show)]
struct WhyNonMatch {
    reason: String,
}

fn non_match(why: String) -> MatchBox {
    NonMatch(WhyNonMatch { reason: why })
}

impl PartialEq for MatchBox {
    fn eq(&self, that: &MatchBox) -> bool {
        match (self, that) {
            (&ExactMatch(c1), &ExactMatch(c2)) => {
                c1.x == c2.x &&
                    c1.y == c2.y &&
                    c1.w == c2.w &&
                    c1.h == c2.h &&
                    c1.fill == c2.fill
            }
            (&PartialMatch, &PartialMatch) => true,
            (&NonMatch(_), &NonMatch(_)) => true,
            _ => false
        }
    }
}

impl SimpleSearch {
    fn clear_area_drawn_by_cmd(&self,
                               grid: &mut Grid,
                               cmd: Command,
                               unused_char: char) {
        let Command { x, y, w, h, fill: _ } = cmd;
        debug!("clearing matched area ({},{}) of w:{} h:{}",
               x, y, w, h);
        for i in range(x, x+w) {
            for j in range(y, y+h) {
                grid.set(i, j, unused_char);
            }
        }
    }

    fn find_unused_char(&self, picture: &str) -> char {
        static AVOID : [char, ..5] = ['.', '+', '-', '|', '\n'];
        let mut guess = '?' as u32;
        loop {
            match from_u32(guess) {
                Some(char_guess) if !AVOID.contains(&char_guess) && !picture.contains_char(char_guess) => {
                    return char_guess;
                }
                _ => {
                    guess += 1;
                }
            }
        }
    }

    /// Attempts to match a box at `(x,y)`, using `hidden` as a marker
    /// for spaces that were overwritten by a later command.
    fn try_upper_left(&self, grid: &Grid, hidden: char, x: u32, y: u32) -> Option<boxdraw::Command> {

        let w = grid.width();
        let h = grid.height();

        // Found a left-corner; find the extent of the box.
        // println!("inspecting ({},{})", x, y);
        // println!("char at: ({},{}): '{}'", x, y, grid.get(x, y));

        let mut saw_partial = false;
        assert!(x < w); assert!(y < h);
        let c = grid.get(x,y);
        if c == '+' {
            'next_width:
            for i in range(x+1, w) {
                for j in range(y+1, h) {
                    let match_at = TryMatchAt {
                        grid: grid,
                        hidden: hidden,
                        x: x,
                        y: y,
                    };
                    match match_at.try(i, j) {
                        ExactMatch(cmd) => return Some(cmd),
                        PartialMatch => {
                            saw_partial = true;
                            continue;
                        }
                        NonMatch(ref why) => {
                            if saw_partial {
                                debug!("nonmatch for {}-{} because {}", (x,y), (i,j), why.reason);
                            }
                            continue 'next_width;
                        }
                    }
                }
            }
        }

        // if we fell through to here, then we were not able to find a
        // box at `(x,y)` on this attempt.
        return None;
    }
}

struct TryMatchAt<'a> {
    grid: &'a Grid,
    hidden: char,
    x: u32,
    y: u32,
}

impl<'a> TryMatchAt<'a> {

    /// Attempts to match a box at `(self.x, self.y)` extending to
    /// `(right, below)` using `self.hidden` as a marker for spaces
    /// that were overwritten by a later command.
    fn try(&self, right: u32, below: u32) -> MatchBox {
        let x = self.x;
        let y = self.y;
        let grid = self.grid;
        let w = grid.width();
        let h = grid.height();

        let box_w = right - x + 1;
        let box_h = below - y + 1;

        let trial = (x, y, box_w, box_h);

        debug!("try: x {} y {} box_w {} box_h {} right {} below {} w {} h {}",
               x, y, box_w, box_h, right, below, w, h);

        assert!(x < w); assert!(y < h);
        let upper_left = grid.get(x, y);
        assert!(x < w); assert!(below < h);
        let lower_left = grid.get(x, below);
        assert!(right < w); assert!(y < h);
        let upper_right = grid.get(right, y);
        assert!(right < w); assert!(below < h);
        let lower_right = grid.get(right, below);

        fn fail(wanted: &str, loc: (u32,u32), value: char) -> MatchBox {
            let msg = format!("failed to match {} at {}: {}",
                              wanted, loc, value);
            non_match(msg)
        };
        let upper_left_fail = || fail("upper_left corner", (x,y), upper_left);
        let lower_left_fail = || {
            fail("lower_left corner", (x,below), lower_left)
        };
        let upper_right_fail = || {
            fail("upper_right corner", (right,y), upper_right)
        };
        let lower_right_fail = || {
            fail("lower_right corner", (right,below), lower_right)
        };

        let mut extends_right = false;
        let mut extends_down = false;

        // Tracks the character to use for the box interior, which we
        // do not necessarily know until scanning deep into the box.
        let mut interior = None;

        // First, check the four corners.
        //
        // We want either:
        //
        // 1. '+', meaning this is (probably) a real corner, and worth trying to match
        //
        // 2. self.hidden, meaning that this could be a corner that
        //    was hidden by another box above it, and so we can
        //    speculatively try to match it, or
        //
        // 3. a wall ('|' or '-'), meaning that this is not the
        //    corner, but we might successfully find the corner if we
        //    keep looking (and thus we should return `PartialMatch`)

        if !self.matches_corner(upper_left) {
            return upper_left_fail();
        }
        if !self.matches_corner(lower_left) {
            if lower_left == '|' {
                extends_down = true;
            } else {
                return lower_left_fail();
            }
        }

        if !self.matches_corner(upper_right) {
            if upper_right == '-' {
                extends_right = true;
            } else {
                return upper_right_fail();
            }
        }

        if !self.matches_corner(lower_right) {
            if extends_down && lower_right == '|' {
                // okay
            } else if extends_right && lower_right == '-' {
                // okay
            } else if extends_down && extends_right {
                if lower_right != self.hidden {
                    interior = Some(lower_right);
                }
            } else {
                return lower_right_fail();
            }
        }

        // Second: Okay, at this point we have either seen all four
        // corners, or we saw walls where we expected corners, and
        // thus might hope to extend the box.
        //
        // Given the above, check that walls of box are in place.

        for i in range(x + 1, right) { // across
            assert!(i < w); assert!(y < h);
            let c = grid.get(i, y);
            if !self.matches_horizontal_wall(c) {
                return fail("top horizontal_wall", (i,y), c);
            }
            assert!(i < w); assert!(below < h);
            let c = grid.get(i, below);
            if !extends_down {
                if !self.matches_horizontal_wall(c) {
                    return fail("bot horizontal_wall", (i,below), c);
                }
            } else if c == self.hidden {
                // keep going
            } else {
                if interior.is_none() {
                    interior = Some(c);
                }
                if interior.is_some() && Some(c) != interior {
                    return fail("bot interior", (i,below), c);
                }
            }
        }
        for j in range(y + 1, below) { // down
            assert!(x < w); assert!(j < h);
            let c = grid.get(x, j);
            if !self.matches_vertical_wall(c) {
                return fail("left vertical wall", (x,j), c);
            }
            assert!(right < w); assert!(j < h);
            let c = grid.get(right, j);
            if !extends_right {
                if !self.matches_vertical_wall(c) {
                    return fail("right vertical wall", (right,j), c);
                }
            } else if c == self.hidden {
                // keep going
            } else {
                if interior.is_none() {
                    interior = Some(c);
                }
                if interior.is_some() && Some(c) != interior {
                    return fail("right interior", (right,j), c);
                }
            }
        }

        // Third: We have corners and walls; check that the interior
        // is sound.

        for i in range(x + 1, right) {
            for j in range(y + 1, below) {
                assert!(i < w); assert!(j < h);
                match (interior, grid.get(i, j)) {
                    (None, c) => {
                        if c == self.hidden {
                            // Okay, clean match and we still do not know
                            // what the interior is.
                            continue;
                        } else {
                            // finally, a non-hidden marker.  Assume
                            // that this is the interior.
                            interior = Some(c);
                            continue;
                        }
                    }
                    (Some(c1), c2) => {
                        if c1 == c2 || c2 == self.hidden {
                            // the color c2 matches the interior c1; keep
                            // going.
                            continue;
                        } else {
                            return fail("interior", (i,j), c2);
                        }
                    }
                }
            }
        }

        // Got this far; return either full or partial box, as
        // appropriate.

        if extends_down || extends_right {
            debug!("partial match {} interior: {}", trial, interior);
            PartialMatch
        } else {
            assert!(x+1 < w); assert!(y+1 < h);
            let fill = grid.get(x+1, y+1);
            let cmd = boxdraw::rect(x, y, box_w, box_h, fill);

            debug!("exact match: {}", cmd);
            ExactMatch(cmd)
        }
    }

    fn matches_corner(&self, c: char) -> bool {
        c == '+' || c == self.hidden
    }

    fn matches_horizontal_wall(&self, c: char) -> bool {
        c == '-' || c == self.hidden
    }

    fn matches_vertical_wall(&self, c: char) -> bool {
        c == '|' || c == self.hidden
    }
}

#[cfg(test)]
mod tests;
#[cfg(test)]
mod exercises;
<|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 = "fontconfig"]
#![crate_type = "lib"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

extern crate libc;

pub mod fontconfig;
<commit_msg>Auto merge of #29 - larsbergstrom:remove_hacks, r=metajack<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 = "fontconfig"]
#![crate_type = "lib"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

extern crate libc;
extern crate fontconfig_sys;

pub mod fontconfig;
<|endoftext|>