<commit_before>use geojson::Geometry;
use serde_json::json;

use super::{filters, settings};

pub fn build_query(
    q: &str,
    filters: filters::Filters,
    _langs: &[&str],
    settings: &settings::QuerySettings,
) -> serde_json::Value {
    let string_query = build_string_query(q, &settings.string_query);
    let importance_query = build_importance_query(q, settings);

    let filters::Filters {
        coord: _,
        shape,
        datasets: _,
        zone_types: _,
        poi_types: _,
    } = filters;

    let geoshape_filter = shape.map(|(geometry, scope)| build_shape_query(geometry, scope));
    let filters: Vec<_> = vec![geoshape_filter]
        .into_iter()
        .filter_map(|f| f)
        .collect();

    if filters.is_empty() {
        json!({
            "query": {
                "bool": {
                    "must": [ string_query ],
                    "should": importance_query,
                }
            }
        })
    } else {
        json!({
            "query": {
                "bool": {
                    "must": [ string_query ],
                    "should": importance_query,
                    "filter": filters
                }
            }
        })
    }
}

fn build_string_query(q: &str, settings: &settings::StringQuery) -> serde_json::Value {
    json!({
        "bool": {
            "boost": settings.global,
            "should": [
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["name"],
                        "boost": settings.boosts.name
                    }
                },
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["label"],
                        "boost": settings.boosts.label
                    }
                },
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["label.prefix"],
                        "boost": settings.boosts.label_prefix
                    }
                }
            ]
        }
    })
}

fn build_importance_query(_q: &str, settings: &settings::QuerySettings) -> serde_json::Value {
    // TODO: in production, admins are boosted by their weight only in prefix mode.
    json!([build_admin_weight_query(&settings.importance_query)])
}

fn build_admin_weight_query(settings: &settings::ImportanceQueryBoosts) -> serde_json::Value {
    json!({
        "function_score": {
            "query": { "term": { "type": "admin" } },
            "boost_mode": "replace",
            "functions": [
                {
                    "field_value_factor": {
                        "field": "weight",
                        "factor": 1e6,
                        "modifier": "log1p",
                        "missing": 0
                    }
                },
                {
                    // TODO: in production, this weight depends of the focus radius
                    "weight": settings.weights.max_radius.admin
                }
            ]
        }
    })
}

// fn build_coverage_condition(datasets: &[&str]) -> serde_json::Value {
//     json!({
//         "bool": {
//             "should": [
//                 { "bool": { "must_not": { "exists": { "field": "coverages" } } } },
//                 { "terms": { "coverages": datasets } }
//             ]
//         }
//     })
// }
//
// #[derive(Debug)]
// enum DecayFn {
//     Gauss,
//     Exp,
//     Linear,
// }
//
// impl std::fmt::Display for DecayFn {
//     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
//         write!(f, "{:?}", self)
//     }kkkkkkkkkkkkkkk
// }
//
// #[derive(Debug)]
// struct DecayFnParam {
//     pub func: DecayFn,
//     pub scale: f32,
//     pub offset: f32,
//     pub decay: f32,
// }

// // The decay function takes 4 parameters:
// // - origin: Here the origin is a geo-point, so we can express it as an object:
// //    { "location": { "lat": ..., "lon": ... } }
// // - scale
// // - offset
// // - decay
// // FIXME Probably use something like Into<Coord>
// fn build_proximity_with_boost(coord: Coord, decay_fn_param: DecayFnParam) -> String {
//     format!(
//         r#"{{
//             "function_score": {{
//                 "{func}": {{
//                     "coord": {{
//                         "origin": {{
//                             "location": {{
//                                 "lat": {lat},
//                                 "lon": {lon}
//                             }}
//                         }},
//                         "scale": "{scale}km",
//                         "offset": "{offset}km",
//                         "decay": {decay}
//                     }}
//                 }}
//             }}
//         }}"#,
//         lat = coord.lat,
//         lon = coord.lon,
//         func = decay_fn_param.func,
//         scale = decay_fn_param.scale,
//         offset = decay_fn_param.offset,
//         decay = decay_fn_param.decay
//     )
// }

pub fn build_reverse_query(distance: &str, lat: f64, lon: f64) -> serde_json::Value {
    json!({
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "geo_distance": {
                    "distance": distance,
                    "coord": {
                        "lat": lat,
                        "lon": lon
                    }
                }
            }
        }
    },
    "sort": [{
         "_geo_distance": {
             "coord": {
                 "lat": lat,
                 "lon": lon
             },
             "order": "asc",
             "unit": "m",
             "mode": "min",
             "distance_type": "arc",
             "ignore_unmapped": true
         }
     }]
    })
}

// If there is a shape, all the places listed in shape_scope are restricted to the shape.
// and the places that are not listed are not restricted.
// So if shape_scope = {A, B}, we should end up with something like
// should [
//   must {               => filwer_w_shape
//     term: _type in {A, B}
//     filter: geoshape
//   },
//   must_not {            => filter_wo_shape
//      term: _type in {A, B}
//   }
// ]
//
pub fn build_shape_query(shape: Geometry, scope: Vec<String>) -> serde_json::Value {
    json!({
        "query": {
            "bool": {
                "should": [
                {
                    "bool": {
                        "must": {
                            "terms": {
                                "_type": scope
                            }
                        },
                        "filter": {
                            "geo_shape": {
                                "location": {
                                    "shape": shape,
                                    "relation": "intersects"
                                }
                            }
                        }
                    }
                },
                {
                    "bool": {
                        "must_not": {
                            "terms": {
                                "_type": scope
                            }
                        }
                    }
                }
                ]
            }
        }
    })
}

#[cfg(test)]
mod tests {
    use geojson::GeoJson;

    use super::*;

    const GEOJSON_STR: &str = "{\"coordinates\":[7.428959,1.513394],\"type\":\"Point\"}";

    #[test]
    fn should_correctly_build_shape_query() {
        let geometry = match GEOJSON_STR.parse::<GeoJson>() {
            Ok(GeoJson::Geometry(g)) => g,
            _ => return,
        };

        let json = build_shape_query(geometry, vec![String::from("foo"), String::from("bar")]);

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }

    #[test]
    fn should_correctly_build_query_with_shape_filter() {
        let geometry = match GEOJSON_STR.parse::<GeoJson>() {
            Ok(GeoJson::Geometry(g)) => g,
            _ => return,
        };

        let json = build_query(
            "chatelet",
            filters::Filters {
                shape: Some((geometry, vec![String::from("foo"), String::from("bar")])),
                ..Default::default()
            },
            &[],
            &settings::QuerySettings::default(),
        );

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }

    #[test]
    fn should_correctly_build_query_without_filter() {
        let json = build_query(
            "chatelet",
            filters::Filters {
                ..Default::default()
            },
            &[],
            &settings::QuerySettings::default(),
        );

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }
}
<commit_msg>Shoulda run make check<commit_after>use geojson::Geometry;
use serde_json::json;

use super::{filters, settings};

pub fn build_query(
    q: &str,
    filters: filters::Filters,
    _langs: &[&str],
    settings: &settings::QuerySettings,
) -> serde_json::Value {
    let string_query = build_string_query(q, &settings.string_query);
    let importance_query = build_importance_query(q, settings);

    let filters::Filters {
        coord: _,
        shape,
        datasets: _,
        zone_types: _,
        poi_types: _,
    } = filters;

    let geoshape_filter = shape.map(|(geometry, scope)| build_shape_query(geometry, scope));
    let filters: Vec<_> = vec![geoshape_filter].into_iter().flatten().collect();

    if filters.is_empty() {
        json!({
            "query": {
                "bool": {
                    "must": [ string_query ],
                    "should": importance_query,
                }
            }
        })
    } else {
        json!({
            "query": {
                "bool": {
                    "must": [ string_query ],
                    "should": importance_query,
                    "filter": filters
                }
            }
        })
    }
}

fn build_string_query(q: &str, settings: &settings::StringQuery) -> serde_json::Value {
    json!({
        "bool": {
            "boost": settings.global,
            "should": [
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["name"],
                        "boost": settings.boosts.name
                    }
                },
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["label"],
                        "boost": settings.boosts.label
                    }
                },
                {
                    "multi_match": {
                        "query": q,
                        "fields": ["label.prefix"],
                        "boost": settings.boosts.label_prefix
                    }
                }
            ]
        }
    })
}

fn build_importance_query(_q: &str, settings: &settings::QuerySettings) -> serde_json::Value {
    // TODO: in production, admins are boosted by their weight only in prefix mode.
    json!([build_admin_weight_query(&settings.importance_query)])
}

fn build_admin_weight_query(settings: &settings::ImportanceQueryBoosts) -> serde_json::Value {
    json!({
        "function_score": {
            "query": { "term": { "type": "admin" } },
            "boost_mode": "replace",
            "functions": [
                {
                    "field_value_factor": {
                        "field": "weight",
                        "factor": 1e6,
                        "modifier": "log1p",
                        "missing": 0
                    }
                },
                {
                    // TODO: in production, this weight depends of the focus radius
                    "weight": settings.weights.max_radius.admin
                }
            ]
        }
    })
}

// fn build_coverage_condition(datasets: &[&str]) -> serde_json::Value {
//     json!({
//         "bool": {
//             "should": [
//                 { "bool": { "must_not": { "exists": { "field": "coverages" } } } },
//                 { "terms": { "coverages": datasets } }
//             ]
//         }
//     })
// }
//
// #[derive(Debug)]
// enum DecayFn {
//     Gauss,
//     Exp,
//     Linear,
// }
//
// impl std::fmt::Display for DecayFn {
//     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
//         write!(f, "{:?}", self)
//     }kkkkkkkkkkkkkkk
// }
//
// #[derive(Debug)]
// struct DecayFnParam {
//     pub func: DecayFn,
//     pub scale: f32,
//     pub offset: f32,
//     pub decay: f32,
// }

// // The decay function takes 4 parameters:
// // - origin: Here the origin is a geo-point, so we can express it as an object:
// //    { "location": { "lat": ..., "lon": ... } }
// // - scale
// // - offset
// // - decay
// // FIXME Probably use something like Into<Coord>
// fn build_proximity_with_boost(coord: Coord, decay_fn_param: DecayFnParam) -> String {
//     format!(
//         r#"{{
//             "function_score": {{
//                 "{func}": {{
//                     "coord": {{
//                         "origin": {{
//                             "location": {{
//                                 "lat": {lat},
//                                 "lon": {lon}
//                             }}
//                         }},
//                         "scale": "{scale}km",
//                         "offset": "{offset}km",
//                         "decay": {decay}
//                     }}
//                 }}
//             }}
//         }}"#,
//         lat = coord.lat,
//         lon = coord.lon,
//         func = decay_fn_param.func,
//         scale = decay_fn_param.scale,
//         offset = decay_fn_param.offset,
//         decay = decay_fn_param.decay
//     )
// }

pub fn build_reverse_query(distance: &str, lat: f64, lon: f64) -> serde_json::Value {
    json!({
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "geo_distance": {
                    "distance": distance,
                    "coord": {
                        "lat": lat,
                        "lon": lon
                    }
                }
            }
        }
    },
    "sort": [{
         "_geo_distance": {
             "coord": {
                 "lat": lat,
                 "lon": lon
             },
             "order": "asc",
             "unit": "m",
             "mode": "min",
             "distance_type": "arc",
             "ignore_unmapped": true
         }
     }]
    })
}

// If there is a shape, all the places listed in shape_scope are restricted to the shape.
// and the places that are not listed are not restricted.
// So if shape_scope = {A, B}, we should end up with something like
// should [
//   must {               => filwer_w_shape
//     term: _type in {A, B}
//     filter: geoshape
//   },
//   must_not {            => filter_wo_shape
//      term: _type in {A, B}
//   }
// ]
//
pub fn build_shape_query(shape: Geometry, scope: Vec<String>) -> serde_json::Value {
    json!({
        "query": {
            "bool": {
                "should": [
                {
                    "bool": {
                        "must": {
                            "terms": {
                                "_type": scope
                            }
                        },
                        "filter": {
                            "geo_shape": {
                                "location": {
                                    "shape": shape,
                                    "relation": "intersects"
                                }
                            }
                        }
                    }
                },
                {
                    "bool": {
                        "must_not": {
                            "terms": {
                                "_type": scope
                            }
                        }
                    }
                }
                ]
            }
        }
    })
}

#[cfg(test)]
mod tests {
    use geojson::GeoJson;

    use super::*;

    const GEOJSON_STR: &str = "{\"coordinates\":[7.428959,1.513394],\"type\":\"Point\"}";

    #[test]
    fn should_correctly_build_shape_query() {
        let geometry = match GEOJSON_STR.parse::<GeoJson>() {
            Ok(GeoJson::Geometry(g)) => g,
            _ => return,
        };

        let json = build_shape_query(geometry, vec![String::from("foo"), String::from("bar")]);

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }

    #[test]
    fn should_correctly_build_query_with_shape_filter() {
        let geometry = match GEOJSON_STR.parse::<GeoJson>() {
            Ok(GeoJson::Geometry(g)) => g,
            _ => return,
        };

        let json = build_query(
            "chatelet",
            filters::Filters {
                shape: Some((geometry, vec![String::from("foo"), String::from("bar")])),
                ..Default::default()
            },
            &[],
            &settings::QuerySettings::default(),
        );

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }

    #[test]
    fn should_correctly_build_query_without_filter() {
        let json = build_query(
            "chatelet",
            filters::Filters {
                ..Default::default()
            },
            &[],
            &settings::QuerySettings::default(),
        );

        println!("{}", serde_json::to_string_pretty(&json).unwrap());
    }
}
<|endoftext|>


<commit_before>#![crate_id = "uusync#1.0.0"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alexander Fomin <xander.fomin@ya.ru>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

 /* Last synced with: sync (GNU coreutils) 8.13 */

extern crate getopts;
extern crate libc;

use std::os;
use getopts::{optflag, getopts, usage};

extern {
    fn sync() -> libc::c_void;
}

#[allow(dead_code)]
fn main () { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optflag("h", "help", "display this help and exit"),
        optflag("V", "version", "output version information and exit")
    ];

    let matches = match getopts(args.tail(), options) {
        Ok(m) => { m }
        _ => { help(program.as_slice(), options); return 0 }
    };

    if matches.opt_present("h") {
        help(program.as_slice(), options);
        return 0
    }

    if matches.opt_present("V") {
        version();
        return 0
    }

    unsafe {
        sync()
    };

    0
}

fn version() {
    println!("sync (uutils) 1.0.0");
    println!("The MIT License");
    println!("");
    println!("Author -- Alexander Fomin.");
}

fn help(program: &str, options: &[getopts::OptGroup]) {
    println!("Usage: {:s} [OPTION]", program);
    print!("{:s}", usage("Force changed blocks to disk, update the super block.", options));
}
<commit_msg>sync for Windows implementation<commit_after>#![crate_id(name="uusync", vers="1.0.0", author="Alexander Fomin")]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Alexander Fomin <xander.fomin@ya.ru>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

 /* Last synced with: sync (GNU coreutils) 8.13 */

 #![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::os;
use getopts::{optflag, getopts, usage};

#[path = "../common/util.rs"] mod util;

#[cfg(unix)]
mod platform {
    use super::libc;

    extern {
        fn sync() -> libc::c_void;
    }

    pub unsafe fn do_sync() -> int {
        sync();
        0
    }
}

#[cfg(windows)]
mod platform {
    pub use super::libc;
    use std::{mem, str};

    extern "system" {
        fn CreateFileA(lpFileName: *libc::c_char,
                      dwDesiredAccess: libc::uint32_t,
                      dwShareMode: libc::uint32_t,
                      lpSecurityAttributes: *libc::c_void, // *LPSECURITY_ATTRIBUTES
                      dwCreationDisposition: libc::uint32_t,
                      dwFlagsAndAttributes: libc::uint32_t,
                      hTemplateFile: *libc::c_void) -> *libc::c_void;
        fn GetDriveTypeA(lpRootPathName: *libc::c_char) -> libc::c_uint;
        fn GetLastError() -> libc::uint32_t;
        fn FindFirstVolumeA(lpszVolumeName: *libc::c_char,
                            cchBufferLength: libc::uint32_t) -> *libc::c_void;
        fn FindNextVolumeA(hFindVolume: *libc::c_void,
                           lpszVolumeName: *libc::c_char,
                           cchBufferLength: libc::uint32_t) -> libc::c_int;
        fn FindVolumeClose(hFindVolume: *libc::c_void) -> libc::c_int;
        fn FlushFileBuffers(hFile: *libc::c_void) -> libc::c_int;
    }

    #[allow(unused_unsafe)]
    unsafe fn flush_volume(name: &str) {
        name.to_c_str().with_ref(|name_buffer| {
            if 0x00000003 == GetDriveTypeA(name_buffer) { // DRIVE_FIXED
                let sliced_name = name.slice_to(name.len() - 1); // eliminate trailing backslash
                sliced_name.to_c_str().with_ref(|sliced_name_buffer| {
                    match CreateFileA(sliced_name_buffer,
                                      0xC0000000, // GENERIC_WRITE
                                      0x00000003, // FILE_SHARE_WRITE,
                                      0 as *libc::c_void,
                                      0x00000003, // OPEN_EXISTING
                                      0,
                                      0 as *libc::c_void) {
                        _x if _x == -1 as *libc::c_void => { // INVALID_HANDLE_VALUE
                            crash!(GetLastError(), "failed to create volume handle");
                        }
                        handle @ _ => {
                            if FlushFileBuffers(handle) == 0 {
                                crash!(GetLastError(), "failed to flush file buffer");
                            }
                        }
                    }
                });
            }
        });
    }

    #[allow(unused_unsafe)]
    unsafe fn find_first_volume() -> (String, *libc::c_void) {
        let name: [libc::c_char, ..260] = mem::uninitialized(); // MAX_PATH
        match FindFirstVolumeA(name.as_ptr(), name.len() as libc::uint32_t) {
            _x if _x == -1 as *libc::c_void => { // INVALID_HANDLE_VALUE
                crash!(GetLastError(), "failed to find first volume");
            }
            handle @ _ => {
                (str::raw::from_c_str(name.as_ptr()), handle)
            }
        }
    }

    #[allow(unused_unsafe)]
    unsafe fn find_all_volumes() -> Vec<String> {
        match find_first_volume() {
            (first_volume, next_volume_handle) => {
                let mut volumes = Vec::from_elem(1, first_volume);
                loop {
                    let name: [libc::c_char, ..260] = mem::uninitialized(); // MAX_PATH
                    match FindNextVolumeA(next_volume_handle, name.as_ptr(), name.len() as libc::uint32_t) {
                        0 => {
                            match GetLastError() {
                                0x12 => { // ERROR_NO_MORE_FILES
                                    FindVolumeClose(next_volume_handle); // ignore FindVolumeClose() failures
                                    break;
                                }
                                err @ _ => {
                                    crash!(err, "failed to find next volume");
                                }
                            }
                        }
                        _ => {
                            volumes.push(str::raw::from_c_str(name.as_ptr()));
                        }
                    }
                }
                volumes
            }
        }
    }

    pub unsafe fn do_sync() -> int {
        let volumes = find_all_volumes();
        for vol in volumes.iter() {
            flush_volume(vol.as_slice());
        }
        0
    }
}

static NAME: &'static str = "sync";

#[allow(dead_code)]
fn main () { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optflag("h", "help", "display this help and exit"),
        optflag("V", "version", "output version information and exit")
    ];

    let matches = match getopts(args.tail(), options) {
        Ok(m) => { m }
        _ => { help(program.as_slice(), options); return 0 }
    };

    if matches.opt_present("h") {
        help(program.as_slice(), options);
        return 0
    }

    if matches.opt_present("V") {
        version();
        return 0
    }

    uusync();
    0
}

fn version() {
    println!("uusync (uutils) 1.0.0");
    println!("The MIT License");
    println!("");
    println!("Author -- Alexander Fomin.");
}

fn help(program: &str, options: &[getopts::OptGroup]) {
    println!("Usage: {:s} [OPTION]", program);
    print!("{:s}", usage("Force changed blocks to disk, update the super block.", options));
}

fn uusync() -> int {
    unsafe {
        platform::do_sync()
    }
}<|endoftext|>


<commit_before>use crate::convert::*;
use std::hash::{Hasher};
use std::intrinsics::assume;

///Just a simple bit pattern.
const PAD : u128 = 0xF0E1_D2C3_B4A5_9687_7869_5A4B_3C2D_1E0F;

/// A `Hasher` for hashing an arbitrary stream of bytes.
///
/// Instances of [AHasher] represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided keys.
    /// # Example
    ///
    /// ```
    /// use std::hash::Hasher;
    /// use ahash::AHasher;
    ///
    /// let mut hasher = AHasher::new_with_keys(123, 456);
    ///
    /// hasher.write_u32(1989);
    /// hasher.write_u8(11);
    /// hasher.write_u8(9);
    /// hasher.write(b"Huh?");
    ///
    /// println!("Hash is {:x}!", hasher.finish());
    /// ```
    #[inline]
    pub(crate) fn new_with_keys(key0: u64, key1: u64) -> AHasher {
        AHasher { buffer: [key0, key1] }
    }
}

#[inline(never)]
#[no_mangle]
fn hash_test_aes(input: &[u8]) -> u64 {
    let mut a = AHasher::new_with_keys(67, 87);
    a.write(input);
    a.finish()
}

/// Provides methods to hash all of the primitive types.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        self.buffer = aeshash(self.buffer.convert(),i).convert();
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //This will be scrambled by the first AES round in any branch.
        self.buffer[1] ^= length;
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 16 {
                if data.len() > 128 {
                    let mut par_block: u128 = self.buffer.convert();
                    while data.len() > 128 {
                        let (b1, rest) = data.read_u128();
                        par_block = aeshash(par_block, b1);
                        data = rest;
                        let (b2, rest) = data.read_u128();
                        self.buffer = aeshash(self.buffer.convert(), b2).convert();
                        data = rest;
                    }
                    self.buffer = aeshash(self.buffer.convert(), par_block).convert();
                }
                while data.len() > 32 {
                    //len 33-128
                    let (block, rest) = data.read_u128();
                    self.buffer = aeshash(self.buffer.convert(), block).convert();
                    data = rest;
                }
                unsafe{assume(data.len() > 16)} //This is always true because of the loop conditional above
                //len 17-32
                let (block, _) = data.read_u128();
                self.buffer = aeshash(self.buffer.convert(), block).convert();
                let block = data.read_last_u128();
                self.buffer = aeshash(self.buffer.convert(), block).convert();
            } else {
                //len 9-16
                self.buffer = aeshash(self.buffer.convert(),data.read_u64().0 as u128).convert();
                self.buffer = aeshash(self.buffer.convert(),data.read_last_u64() as u128).convert();
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    //len 4-8
                    self.buffer = aeshash(self.buffer.convert(),data.read_u32().0 as u128).convert();
                    self.buffer = aeshash(self.buffer.convert(),data.read_last_u32() as u128).convert();
                } else {
                    //len 2-3
                    self.buffer = aeshash(self.buffer.convert(),data.read_u16().0 as u128).convert();
                    self.buffer = aeshash(self.buffer.convert(),data.read_last_u16() as u128).convert();
                }
            } else {
                if data.len() > 0 {
                    //len 1
                    self.buffer = aeshash(self.buffer.convert(), data[0] as u128).convert();
                }
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let result: [u64; 2] = aeshash(aeshash(self.buffer.convert(), PAD), PAD).convert();
        result[0]//.wrapping_add(result[1])
    }
}

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
#[inline(always)]
fn aeshash(value: u128, xor: u128) -> u128 {
    use std::mem::transmute;
    #[cfg(target_arch = "x86")]
    use core::arch::x86::*;
    #[cfg(target_arch = "x86_64")]
    use std::arch::x86_64::*;
    unsafe {
        let value = transmute(value);
        transmute(_mm_aesdec_si128(value, transmute(xor)))
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::hash::{BuildHasherDefault};
    use crate::convert::Convert;
    use crate::aes_hash::*;

    #[test]
    fn test_builder() {
        let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
        map.insert(1, 3);
    }

    #[test]
    fn test_default() {
        let hasher_a = AHasher::default();
        assert_ne!(0, hasher_a.buffer[0]);
        assert_ne!(0, hasher_a.buffer[1]);
        assert_ne!(hasher_a.buffer[0], hasher_a.buffer[1]);
        let hasher_b = AHasher::default();
        assert_eq!(hasher_a.buffer[0], hasher_b.buffer[0]);
        assert_eq!(hasher_a.buffer[1], hasher_b.buffer[1]);
    }

    #[test]
    fn test_hash() {
        let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210];
        result = aeshash(value.convert(), result.convert()).convert();
        result = aeshash(result.convert(), result.convert()).convert();
        let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value2: [u64; 2] = [1, 0xFEDCBA9876543210];
        result2 = aeshash(value2.convert(), result2.convert()).convert();
        result2 = aeshash(result2.convert(), result.convert()).convert();
        let result: [u8; 16] = result.convert();
        let result2: [u8; 16] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }

    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }
}
<commit_msg>Speed up 16-128 byte strings a bit.<commit_after>use crate::convert::*;
use std::hash::{Hasher};
use std::intrinsics::assume;

///Just a simple bit pattern.
const PAD : u128 = 0xF0E1_D2C3_B4A5_9687_7869_5A4B_3C2D_1E0F;

/// A `Hasher` for hashing an arbitrary stream of bytes.
///
/// Instances of [AHasher] represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided keys.
    /// # Example
    ///
    /// ```
    /// use std::hash::Hasher;
    /// use ahash::AHasher;
    ///
    /// let mut hasher = AHasher::new_with_keys(123, 456);
    ///
    /// hasher.write_u32(1989);
    /// hasher.write_u8(11);
    /// hasher.write_u8(9);
    /// hasher.write(b"Huh?");
    ///
    /// println!("Hash is {:x}!", hasher.finish());
    /// ```
    #[inline]
    pub(crate) fn new_with_keys(key0: u64, key1: u64) -> AHasher {
        AHasher { buffer: [key0, key1] }
    }
}

#[inline(never)]
#[no_mangle]
fn hash_test_aes(input: &[u8]) -> u64 {
    let mut a = AHasher::new_with_keys(67, 87);
    a.write(input);
    a.finish()
}

/// Provides methods to hash all of the primitive types.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        self.buffer = aeshash(self.buffer.convert(),i).convert();
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.write_u128(i as u128);
    }

    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //This will be scrambled by the first AES round in any branch.
        self.buffer[1] ^= length;
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 32 {
                if data.len() > 64 {
                    let mut par_block: u128 = self.buffer.convert();
                    while data.len() > 64 {
                        let (b1, rest) = data.read_u128();
                        par_block = aeshash(par_block, b1);
                        data = rest;
                        let (b2, rest) = data.read_u128();
                        self.buffer = aeshash(self.buffer.convert(), b2).convert();
                        data = rest;
                    }
                    self.buffer = aeshash(self.buffer.convert(), par_block).convert();
                }
                //len 33-64
                let (firstHalf, secondHalf) = data.split_at(data.len()/2);
                unsafe{assume(firstHalf.len() >= 16)}
                unsafe{assume(secondHalf.len() >= 16)}
                self.buffer = aeshash(self.buffer.convert(), firstHalf.read_u128().0).convert();
                self.buffer = aeshash(self.buffer.convert(), firstHalf.read_last_u128()).convert();
                self.buffer = aeshash(self.buffer.convert(), secondHalf.read_u128().0).convert();
                self.buffer = aeshash(self.buffer.convert(), secondHalf.read_last_u128()).convert();
            } else {
                if data.len() > 16 {
                    //len 17-32
                    self.buffer = aeshash(self.buffer.convert(), data.read_u128().0).convert();
                    self.buffer = aeshash(self.buffer.convert(), data.read_last_u128()).convert();
                } else {
                    //len 9-16
                    self.buffer = aeshash(self.buffer.convert(), data.read_u64().0 as u128).convert();
                    self.buffer = aeshash(self.buffer.convert(), data.read_last_u64() as u128).convert();
                }
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    //len 4-8
                    self.buffer = aeshash(self.buffer.convert(),data.read_u32().0 as u128).convert();
                    self.buffer = aeshash(self.buffer.convert(),data.read_last_u32() as u128).convert();
                } else {
                    //len 2-3
                    self.buffer = aeshash(self.buffer.convert(),data.read_u16().0 as u128).convert();
                    self.buffer = aeshash(self.buffer.convert(),data.read_last_u16() as u128).convert();
                }
            } else {
                if data.len() > 0 {
                    //len 1
                    self.buffer = aeshash(self.buffer.convert(), data[0] as u128).convert();
                }
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let result: [u64; 2] = aeshash(aeshash(self.buffer.convert(), PAD), PAD).convert();
        result[0]//.wrapping_add(result[1])
    }
}

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
#[inline(always)]
fn aeshash(value: u128, xor: u128) -> u128 {
    use std::mem::transmute;
    #[cfg(target_arch = "x86")]
    use core::arch::x86::*;
    #[cfg(target_arch = "x86_64")]
    use std::arch::x86_64::*;
    unsafe {
        let value = transmute(value);
        transmute(_mm_aesdec_si128(value, transmute(xor)))
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::hash::{BuildHasherDefault};
    use crate::convert::Convert;
    use crate::aes_hash::*;

    #[test]
    fn test_builder() {
        let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
        map.insert(1, 3);
    }

    #[test]
    fn test_default() {
        let hasher_a = AHasher::default();
        assert_ne!(0, hasher_a.buffer[0]);
        assert_ne!(0, hasher_a.buffer[1]);
        assert_ne!(hasher_a.buffer[0], hasher_a.buffer[1]);
        let hasher_b = AHasher::default();
        assert_eq!(hasher_a.buffer[0], hasher_b.buffer[0]);
        assert_eq!(hasher_a.buffer[1], hasher_b.buffer[1]);
    }

    #[test]
    fn test_hash() {
        let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210];
        result = aeshash(value.convert(), result.convert()).convert();
        result = aeshash(result.convert(), result.convert()).convert();
        let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value2: [u64; 2] = [1, 0xFEDCBA9876543210];
        result2 = aeshash(value2.convert(), result2.convert()).convert();
        result2 = aeshash(result2.convert(), result.convert()).convert();
        let result: [u8; 16] = result.convert();
        let result2: [u8; 16] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }

    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }
}
<|endoftext|>


<commit_before>//! The `pact_verifier` crate provides a number of exported functions using C bindings for
//! controlling the pact verification process. These can be used in any language that supports C bindings.

#![warn(missing_docs)]

use std::ffi::{CStr, CString};
use std::panic::catch_unwind;

use anyhow::Context;
use libc::{c_char, c_int, c_ushort, EXIT_FAILURE};
use log::*;
use std::env;

use crate::{as_mut, ffi_fn, safe_str};
use crate::util::*;
use crate::util::string::if_null;
use serde::Serialize;
use std::any::Any;
use clap::{Arg, ArgSettings};

mod args;
pub mod verifier;
pub mod handle;

/// External interface to verifier a provider
///
/// * `args` - the same as the CLI interface, except newline delimited
///
/// # Errors
///
/// Errors are returned as non-zero numeric values.
///
/// | Error | Description |
/// |-------|-------------|
/// | 1 | The verification process failed, see output for errors |
/// | 2 | A null pointer was received |
/// | 3 | The method panicked |
/// | 4 | Invalid arguments were provided to the verification process |
///
/// # Safety
///
/// Exported functions are inherently unsafe. Deal.
#[no_mangle]
pub unsafe extern fn pactffi_verify(args: *const c_char) -> i32 {
  if args.is_null() {
    return 2;
  }

  let result = catch_unwind(|| {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.block_on(async {
      let args_raw = CStr::from_ptr(args).to_string_lossy().into_owned();
      let args: Vec<String> = args_raw.lines().map(|s| s.to_string()).collect();
      let result = verifier::handle_args(args).await;

      match result {
        Ok(_) => 0,
        Err(e) => e
      }
    })
  });

  match result {
    Ok(val) => val,
    Err(cause) => {
      log::error!("Caught a general panic: {:?}", cause);
      3
    }
  }
}

ffi_fn! {
    /// Get a Handle to a newly created verifier. You should call `pactffi_verifier_shutdown` when
    /// done with the verifier to free all allocated resources
    ///
    /// # Safety
    ///
    /// This function is safe.
    ///
    /// # Error Handling
    ///
    /// Returns NULL on error.
    fn pactffi_verifier_new() -> *mut handle::VerifierHandle {
        let handle = handle::VerifierHandle::new();
        ptr::raw_to(handle)
    } {
        ptr::null_mut_to::<handle::VerifierHandle>()
    }
}

ffi_fn! {
    /// Shutdown the verifier and release all resources
    fn pactffi_verifier_shutdown(handle: *mut handle::VerifierHandle) {
        ptr::drop_raw(handle);
    }
}

ffi_fn! {
    /// Set the provider details for the Pact verifier. Passing a NULL for any field will
    /// use the default value for that field.
    ///
    /// # Safety
    ///
    /// All string fields must contain valid UTF-8. Invalid UTF-8
    /// will be replaced with U+FFFD REPLACEMENT CHARACTER.
    ///
    fn pactffi_verifier_set_provider_info(
      handle: *mut handle::VerifierHandle,
      name: *const c_char,
      scheme: *const c_char,
      host: *const c_char,
      port: c_ushort,
      path: *const c_char
    ) {
      let handle = as_mut!(handle);
      let name = if_null(name, "provider");
      let scheme = if_null(scheme, "http");
      let host = if_null(host, "localhost");
      let path = if_null(path, "/");

      handle.update_provider_info(name, scheme, host, port as u16, path);
    }
}

ffi_fn! {
    /// Adds a Pact file as a source to verify.
    ///
    /// # Safety
    ///
    /// All string fields must contain valid UTF-8. Invalid UTF-8
    /// will be replaced with U+FFFD REPLACEMENT CHARACTER.
    ///
    fn pactffi_verifier_add_file_source(
      handle: *mut handle::VerifierHandle,
      file: *const c_char
    ) {
      let handle = as_mut!(handle);
      let file = safe_str!(file);

      handle.add_file_source(file);
    }
}

ffi_fn! {
    /// Runs the verification.
    ///
    /// # Error Handling
    ///
    /// Errors will be reported with a non-zero return value.
    fn pactffi_verifier_execute(handle: *mut handle::VerifierHandle) -> c_int {
      let handle = as_mut!(handle);

      handle.execute()
    } {
      EXIT_FAILURE
    }
}

#[derive(Serialize)]
struct Argument {
    name: Option<String>,
    short: Option<String>,
    long: Option<String>,
    help: Option<String>,
    possible_values: Option<Vec<String>>,
    default_value: Option<String>,
    multiple: Option<bool>
}

// #[derive(Serialize)]
// struct ArgumentsFlags {
//     arguments: Vec<Argument>,
//     flags: Vec<Argument>
// }

/// External interface to retrieve the options and arguments available when calling the CLI interface,
/// returning them as a JSON string.
///
/// The purpose is to then be able to use in other languages which wrap the FFI library, to implement
/// the same CLI functionality automatically without manual maintenance of arguments, help descriptions
/// etc.
///
/// # Example structure
/// ```json
/// [
///     {
///         "name": "broker-url",
///         "short": "b",
///         "long": "broker-url",
///         "help": "URL of the pact broker to fetch pacts from to verify (requires the provider name parameter)"
///     },
///     {
///         "name": "port",
///         "short": "p",
///         "long": "port",
///         "help": "Provider port (defaults to protocol default 80/443)"
///     },
///     {
///         "name": "user",
///         "short": null,
///         "long": "user",
///         "help": "Username to use when fetching pacts from URLS"
///     }
/// ]
/// ```
///
/// # Safety
///
/// Exported functions are inherently unsafe.
#[no_mangle]
pub extern "C" fn pactffi_verifier_cli_args() -> *const c_char {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let app = args::setup_app(program, clap::crate_version!());

    // Iterate through the args, extracting info from each to then add to a Vector of args
    let mut arguments: Vec<Argument> = Vec::new();
    // let mut flags: Vec<Argument> = Vec::new();
    // let mut args_flags = ArgumentsFlags { arguments:arguments, flags: flags};

    for opt in app.p.opts.iter() {
        let mut arg = Argument { name: None, short: None, long: None, help: None, possible_values: None, default_value: None, multiple: Some(false) };

        // Name
        // TODO: Maybe superfluous as this is always the same as the long
        let arg_name = opt.b.name;
        arg.name = Some(arg_name.to_string());

        // Short
        match opt.s.short {
            None => {}
            Some(_val) => {
                let c_str = CString::new(_val.to_string()).unwrap();
                let short = c_str.to_str().unwrap();
                arg.short = Some(short.to_string());
            }
        }

        // Long
        match opt.s.long {
            None => {}
            Some(_val) => {
                let c_str = CString::new(_val.to_string()).unwrap();
                let long = c_str.to_str().unwrap();
                arg.long = Some(long.to_string());
            }
        }

        // Help
        match opt.b.help {
            None => {}
            Some(_val) => {
                let c_str = CString::new(_val.to_string()).unwrap();
                let help = c_str.to_str().unwrap();
                arg.help = Some(help.to_string());
            }
        }

        // Possible values
        match opt.v.possible_vals {
            None => {}
            Some(_) => {
                let mut possible_vals: Vec<String> = Vec::new();
                let possible_values = opt.v.possible_vals.clone().unwrap();
                for possible_val in possible_values.iter() {
                    possible_vals.push(possible_val.to_string())
                }
                arg.possible_values = Some(possible_vals);
            }
        }

        // Multiple
        if opt.b.settings.is_set(ArgSettings::Multiple) {
            arg.multiple = Some(true);
        }

        arguments.push(arg);
    }

    // TODO: Also need to handle hopefully app.p.flags, where the takes_value(false) ones go

    let json = serde_json::to_string(&arguments).unwrap();
    let c_str = CString::new(json).unwrap();
    c_str.into_raw() as *const c_char
}<commit_msg>feat(ffi verifier cli): split out flags and options<commit_after>//! The `pact_verifier` crate provides a number of exported functions using C bindings for
//! controlling the pact verification process. These can be used in any language that supports C bindings.

#![warn(missing_docs)]

use std::ffi::{CStr, CString, OsStr};
use std::panic::catch_unwind;

use anyhow::Context;
use libc::{c_char, c_int, c_ushort, EXIT_FAILURE};
use log::*;
use std::env;

use crate::{as_mut, ffi_fn, safe_str};
use crate::util::*;
use crate::util::string::if_null;
use serde::Serialize;
use std::any::Any;
use clap::{Arg, ArgSettings};

mod args;
pub mod verifier;
pub mod handle;

/// External interface to verifier a provider
///
/// * `args` - the same as the CLI interface, except newline delimited
///
/// # Errors
///
/// Errors are returned as non-zero numeric values.
///
/// | Error | Description |
/// |-------|-------------|
/// | 1 | The verification process failed, see output for errors |
/// | 2 | A null pointer was received |
/// | 3 | The method panicked |
/// | 4 | Invalid arguments were provided to the verification process |
///
/// # Safety
///
/// Exported functions are inherently unsafe. Deal.
#[no_mangle]
pub unsafe extern fn pactffi_verify(args: *const c_char) -> i32 {
  if args.is_null() {
    return 2;
  }

  let result = catch_unwind(|| {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.block_on(async {
      let args_raw = CStr::from_ptr(args).to_string_lossy().into_owned();
      let args: Vec<String> = args_raw.lines().map(|s| s.to_string()).collect();
      let result = verifier::handle_args(args).await;

      match result {
        Ok(_) => 0,
        Err(e) => e
      }
    })
  });

  match result {
    Ok(val) => val,
    Err(cause) => {
      log::error!("Caught a general panic: {:?}", cause);
      3
    }
  }
}

ffi_fn! {
    /// Get a Handle to a newly created verifier. You should call `pactffi_verifier_shutdown` when
    /// done with the verifier to free all allocated resources
    ///
    /// # Safety
    ///
    /// This function is safe.
    ///
    /// # Error Handling
    ///
    /// Returns NULL on error.
    fn pactffi_verifier_new() -> *mut handle::VerifierHandle {
        let handle = handle::VerifierHandle::new();
        ptr::raw_to(handle)
    } {
        ptr::null_mut_to::<handle::VerifierHandle>()
    }
}

ffi_fn! {
    /// Shutdown the verifier and release all resources
    fn pactffi_verifier_shutdown(handle: *mut handle::VerifierHandle) {
        ptr::drop_raw(handle);
    }
}

ffi_fn! {
    /// Set the provider details for the Pact verifier. Passing a NULL for any field will
    /// use the default value for that field.
    ///
    /// # Safety
    ///
    /// All string fields must contain valid UTF-8. Invalid UTF-8
    /// will be replaced with U+FFFD REPLACEMENT CHARACTER.
    ///
    fn pactffi_verifier_set_provider_info(
      handle: *mut handle::VerifierHandle,
      name: *const c_char,
      scheme: *const c_char,
      host: *const c_char,
      port: c_ushort,
      path: *const c_char
    ) {
      let handle = as_mut!(handle);
      let name = if_null(name, "provider");
      let scheme = if_null(scheme, "http");
      let host = if_null(host, "localhost");
      let path = if_null(path, "/");

      handle.update_provider_info(name, scheme, host, port as u16, path);
    }
}

ffi_fn! {
    /// Adds a Pact file as a source to verify.
    ///
    /// # Safety
    ///
    /// All string fields must contain valid UTF-8. Invalid UTF-8
    /// will be replaced with U+FFFD REPLACEMENT CHARACTER.
    ///
    fn pactffi_verifier_add_file_source(
      handle: *mut handle::VerifierHandle,
      file: *const c_char
    ) {
      let handle = as_mut!(handle);
      let file = safe_str!(file);

      handle.add_file_source(file);
    }
}

ffi_fn! {
    /// Runs the verification.
    ///
    /// # Error Handling
    ///
    /// Errors will be reported with a non-zero return value.
    fn pactffi_verifier_execute(handle: *mut handle::VerifierHandle) -> c_int {
      let handle = as_mut!(handle);

      handle.execute()
    } {
      EXIT_FAILURE
    }
}

#[derive(Serialize)]
struct Argument {
    long: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    short: Option<String>,
    help: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    possible_values: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    default_value: Option<String>,
    multiple: Option<bool>
}

#[derive(Serialize)]
struct OptionsFlags {
    options: Vec<Argument>,
    flags: Vec<Argument>
}

/// External interface to retrieve the options and arguments available when calling the CLI interface,
/// returning them as a JSON string.
///
/// The purpose is to then be able to use in other languages which wrap the FFI library, to implement
/// the same CLI functionality automatically without manual maintenance of arguments, help descriptions
/// etc.
///
/// # Example structure
/// ```json
/// {
///   "options": [
///     {
///       "long": "scheme",
///       "help": "Provider URI scheme (defaults to http)",
///       "possible_values": [
///         "http",
///         "https"
///       ],
///       "default_value": "http"
///       "multiple": false,
///     },
///     {
///       "long": "file",
///       "short": "f",
///       "help": "Pact file to verify (can be repeated)",
///       "multiple": true
///     },
///     {
///       "long": "user",
///       "help": "Username to use when fetching pacts from URLS",
///       "multiple": false
///     }
///   ],
///   "flags": [
///     {
///       "long": "disable-ssl-verification",
///       "help": "Disables validation of SSL certificates",
///       "multiple": false
///     }
///   ]
/// }
/// ```
///
/// # Safety
///
/// Exported functions are inherently unsafe.
#[no_mangle]
pub extern "C" fn pactffi_verifier_cli_args() -> *const c_char {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let app = args::setup_app(program, clap::crate_version!());

    // Iterate through the args, extracting info from each to then add to a Vector of args
    let mut options: Vec<Argument> = Vec::new();
    let mut flags: Vec<Argument> = Vec::new();

    for opt in app.p.opts.iter() {
        let arg = parse_argument(opt.s.long, opt.s.short, opt.b.help, opt.v.possible_vals.clone(),opt.v.default_val, opt.b.settings.is_set(ArgSettings::Multiple));
        options.push(arg);
    }

    for opt in app.p.flags.iter() {
        let arg = parse_argument(opt.s.long, opt.s.short, opt.b.help, None, None,opt.b.settings.is_set(ArgSettings::Multiple));
        flags.push(arg);
    }

    let opts_flags = OptionsFlags { options:options, flags: flags};
    let json = serde_json::to_string(&opts_flags).unwrap();
    let c_str = CString::new(json).unwrap();
    c_str.into_raw() as *const c_char
}

fn parse_argument(long: Option<&str>, short: Option<char>, help: Option<&str>, possible_values: Option<Vec<&str>>, default_value: Option<&OsStr>, multiple: bool) -> Argument {
    let mut arg = Argument { short: None, long: None, help: None, possible_values: None, default_value: None, multiple: Some(false) };

    // Long
    match long {
        None => {}
        Some(_val) => {
            let c_str = CString::new(_val.to_string()).unwrap();
            let long = c_str.to_str().unwrap();
            arg.long = Some(long.to_string());
        }
    }

    // Short
    match short {
        None => {}
        Some(_val) => {
            let c_str = CString::new(_val.to_string()).unwrap();
            let short = c_str.to_str().unwrap();
            arg.short = Some(short.to_string());
        }
    }

    // Help
    match help {
        None => {}
        Some(_val) => {
            let c_str = CString::new(_val.to_string()).unwrap();
            let help = c_str.to_str().unwrap();
            arg.help = Some(help.to_string());
        }
    }

    // Possible values
    match possible_values {
        None => {}
        Some(_) => {
            let mut possible_vals: Vec<String> = Vec::new();
            for possible_val in possible_values.unwrap().iter() {
                possible_vals.push(possible_val.to_string())
            }
            arg.possible_values = Some(possible_vals);
        }
    }

    // Default value
    match default_value {
        None => {}
        Some(_val) =>
            {
                let x = _val.to_os_string().into_string().unwrap();
                let c_str = CString::new(x).unwrap();
                let default_val = c_str.to_str().unwrap();
                arg.default_value = Some(default_val.to_string());
            }
    }

    // Multiple
    if multiple {
        arg.multiple = Some(true);
    }

    arg
}
<|endoftext|>


<commit_before>extern crate skeptic;
extern crate version_check;

use std::{env, fs};

#[cfg(unix)]
fn main() {
    let f = env::var("OUT_DIR").unwrap() + "/skeptic-tests.rs";
    if env::var("USE_SKEPTIC").is_ok() {
        let _ = fs::remove_file(f);
        // generates doc tests for `README.md`.
        skeptic::generate_doc_tests(
            &["README.md",
              "guide/src/qs_1.md",
              "guide/src/qs_2.md",
              "guide/src/qs_3.md",
              "guide/src/qs_3_5.md",
              "guide/src/qs_4.md",
              "guide/src/qs_4_5.md",
              "guide/src/qs_5.md",
              "guide/src/qs_7.md",
              "guide/src/qs_8.md",
              "guide/src/qs_9.md",
              "guide/src/qs_10.md",
              "guide/src/qs_12.md",
              "guide/src/qs_13.md",
              "guide/src/qs_14.md",
            ]);
    } else {
        let _ = fs::File::create(f);
    }

    match version_check::is_nightly() {
        Some(true) => println!("cargo:rustc-cfg=actix_nightly"),
        Some(false) => (),
        None => (),
    };
}

#[cfg(not(unix))]
fn main() {
    match version_check::is_nightly() {
        Some(true) => println!("cargo:rustc-cfg=actix_nightly"),
        Some(false) => (),
        None => (),
    };
}
<commit_msg>rerun build if USE_SKEPTIC env var changed<commit_after>extern crate skeptic;
extern crate version_check;

use std::{env, fs};

#[cfg(unix)]
fn main() {
    println!("cargo:rerun-if-env-changed=USE_SKEPTIC");
    let f = env::var("OUT_DIR").unwrap() + "/skeptic-tests.rs";
    if env::var("USE_SKEPTIC").is_ok() {
        let _ = fs::remove_file(f);
        // generates doc tests for `README.md`.
        skeptic::generate_doc_tests(
            &["README.md",
              "guide/src/qs_1.md",
              "guide/src/qs_2.md",
              "guide/src/qs_3.md",
              "guide/src/qs_3_5.md",
              "guide/src/qs_4.md",
              "guide/src/qs_4_5.md",
              "guide/src/qs_5.md",
              "guide/src/qs_7.md",
              "guide/src/qs_8.md",
              "guide/src/qs_9.md",
              "guide/src/qs_10.md",
              "guide/src/qs_12.md",
              "guide/src/qs_13.md",
              "guide/src/qs_14.md",
            ]);
    } else {
        let _ = fs::File::create(f);
    }

    match version_check::is_nightly() {
        Some(true) => println!("cargo:rustc-cfg=actix_nightly"),
        Some(false) => (),
        None => (),
    };
}

#[cfg(not(unix))]
fn main() {
    match version_check::is_nightly() {
        Some(true) => println!("cargo:rustc-cfg=actix_nightly"),
        Some(false) => (),
        None => (),
    };
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::process::Command;
use std::env;

#[cfg(target_os="macos")]
fn print_lib_dir() {
    println!("cargo:rustc-flags=-L /usr/local/opt/gettext/lib/");
}

#[cfg(not(target_os="macos"))]
fn print_lib_dir() {
}

fn main() {
    let curr_dir_str = env::var("CARGO_MANIFEST_DIR").unwrap();
    let curr_dir = Path::new(&curr_dir_str);
    Command::new("git").arg("submodule").arg("update").arg("--init")
        .current_dir(&curr_dir).status().unwrap();

    let nvim_dir = curr_dir.join("neovim");
    Command::new("make").arg("deps").current_dir(&nvim_dir).status().unwrap();
    Command::new("make").arg("libnvim").current_dir(&nvim_dir).status().unwrap();

    let nvim_lib_dir = nvim_dir.join("build").join("lib");
    let deps_lib_dir = nvim_dir.join(".deps").join("usr").join("lib");
    println!("cargo:rustc-flags=-L {} -L {} -l nvim:static",
        nvim_lib_dir.to_str().unwrap(),
        deps_lib_dir.to_str().unwrap());

    print_lib_dir();
}
<commit_msg>Remove :static from build syntax<commit_after>use std::path::Path;
use std::process::Command;
use std::env;

#[cfg(target_os="macos")]
fn print_lib_dir() {
    println!("cargo:rustc-flags=-L /usr/local/opt/gettext/lib/");
}

#[cfg(not(target_os="macos"))]
fn print_lib_dir() {
}

fn main() {
    let curr_dir_str = env::var("CARGO_MANIFEST_DIR").unwrap();
    let curr_dir = Path::new(&curr_dir_str);
    Command::new("git").arg("submodule").arg("update").arg("--init")
        .current_dir(&curr_dir).status().unwrap();

    let nvim_dir = curr_dir.join("neovim");
    Command::new("make").arg("deps").current_dir(&nvim_dir).status().unwrap();
    Command::new("make").arg("libnvim").current_dir(&nvim_dir).status().unwrap();

    let nvim_lib_dir = nvim_dir.join("build").join("lib");
    let deps_lib_dir = nvim_dir.join(".deps").join("usr").join("lib");
    println!("cargo:rustc-flags=-L {} -L {} -l nvim",
        nvim_lib_dir.to_str().unwrap(),
        deps_lib_dir.to_str().unwrap());

    print_lib_dir();
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use graphics::{ Context, DrawState, Graphics };
use graphics::BACK_END_MAX_VERTEX_COUNT as BUFFER_SIZE;
use { Texture, shaders };
use gfx_lib as gfx;

const POS_COMPONENTS: usize = 2;
const UV_COMPONENTS: usize = 2;

// Boiler plate for automatic attribute construction.
// Needs to be improved on gfx-rs side.
// For some reason, using ``*_COMPONENT` triggers some macros errors.

#[vertex_format]
struct PositionFormat { pos: [f32; 2] }

#[vertex_format]
struct ColorFormat { color: [f32; 4] }

#[vertex_format]
struct TexCoordsFormat { uv: [f32; 2] }

#[shader_param]
struct Params<R: gfx::Resources> {
    color: [f32; 4],
    _dummy: PhantomData<R>,
}

#[shader_param]
struct ParamsUV<R: gfx::Resources> {
    color: [f32; 4],
    s_texture: gfx::shade::TextureParam<R>,
}

/// The data used for drawing 2D graphics.
pub struct Gfx2d<R: gfx::Resources> {
    buffer_pos: gfx::BufferHandle<R, f32>,
    buffer_uv: gfx::BufferHandle<R, f32>,
    batch: gfx::batch::OwnedBatch<Params<R>>,
    batch_uv: gfx::batch::OwnedBatch<ParamsUV<R>>,
}

impl<R: gfx::Resources> Gfx2d<R> {
    /// Creates a new G2D object.
    pub fn new<D, F>(device: &mut D, factory: &mut F) -> Self
        where D: gfx::Device,
              F: gfx::Factory<R>
    {
        use gfx_lib::traits::*;
        use gfx_lib::VertexFormat;

        let shader_model = device.get_capabilities().shader_model;

        let vertex = gfx::ShaderSource {
            glsl_120: Some(shaders::VERTEX_SHADER[0]),
            glsl_150: Some(shaders::VERTEX_SHADER[1]),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(shaders::FRAGMENT_SHADER[0]),
            glsl_150: Some(shaders::FRAGMENT_SHADER[1]),
            .. gfx::ShaderSource::empty()
        };

        let program = factory.link_program(
            vertex.choose(shader_model).unwrap(),
            fragment.choose(shader_model).unwrap()
        ).unwrap();

        let vertex = gfx::ShaderSource {
            glsl_120: Some(shaders::VERTEX_SHADER_UV[0]),
            glsl_150: Some(shaders::VERTEX_SHADER_UV[1]),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(shaders::FRAGMENT_SHADER_UV[0]),
            glsl_150: Some(shaders::FRAGMENT_SHADER_UV[1]),
            .. gfx::ShaderSource::empty()
        };

        let program_uv = factory.link_program(
            vertex.choose(shader_model).unwrap(),
            fragment.choose(shader_model).unwrap()
        ).unwrap();

        let buffer_pos = factory.create_buffer(
            POS_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );
        let buffer_uv = factory.create_buffer(
            UV_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );

        let mut mesh = gfx::Mesh::new(BUFFER_SIZE as u32);
        mesh.attributes.extend(
            PositionFormat::generate(
                buffer_pos.raw().clone()
            )
        );

        // Reuse parameters from `mesh`.
        let mut mesh_uv = mesh.clone();
        mesh_uv.attributes.extend(
            TexCoordsFormat::generate(
                buffer_uv.raw().clone()
            )
        );

        let params = Params {
            color: [1.0; 4],
            _dummy: PhantomData,
        };
        let mut batch = gfx::batch::OwnedBatch::new(
            mesh,
            program,
            params
        ).unwrap();

        let sampler = factory.create_sampler(
            gfx::tex::SamplerInfo::new(
                gfx::tex::FilterMethod::Trilinear,
                gfx::tex::WrapMode::Clamp
            )
        );

        // Create a dummy texture
        let texture_info = gfx::tex::TextureInfo {
            width: 1,
            height: 1,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = factory.create_texture(texture_info).unwrap();

        factory.update_texture(
            &texture,
            &image_info,
            &[0x20u8, 0xA0, 0xC0, 0x00],
            Some(gfx::tex::TextureKind::Texture2D)
        ).unwrap();

        let params_uv = ParamsUV {
            color: [1.0; 4],
            s_texture: (texture, Some(sampler))
        };
        let mut batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv,
            program_uv,
            params_uv
        ).unwrap();

        // Disable culling.
        batch.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);
        batch_uv.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);

        Gfx2d {
            buffer_pos: buffer_pos,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }

    /// Renders graphics to a Gfx renderer.
    pub fn draw<C, F>(
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        frame: &gfx::Frame<R>,
        mut f: F
    )
        where C: gfx::CommandBuffer<R>,
              F: FnMut(Context, &mut GfxGraphics<R, C>)
    {
        let ref mut g = GfxGraphics::new(
            renderer,
            frame,
            self
        );
        let c = Context::abs(
            frame.width as f64,
            frame.height as f64
        );
        f(c, g);
    }
}

/// Used for rendering 2D graphics.
pub struct GfxGraphics<'a, R, C>
    where R: gfx::Resources + 'a,
          C: gfx::CommandBuffer<R> + 'a,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    renderer: &'a mut gfx::Renderer<R, C>,
    frame: &'a gfx::Frame<R>,
    g2d: &'a mut Gfx2d<R>,
}

impl<'a, R, C> GfxGraphics<'a, R, C>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>
{
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<R, C>,
               frame: &'a gfx::Frame<R>,
               g2d: &'a mut Gfx2d<R>) -> Self {
        GfxGraphics {
            renderer: renderer,
            frame: frame,
            g2d: g2d,
        }
    }

    /// Returns true if texture has alpha channel.
    pub fn has_texture_alpha(&self, texture: &Texture<R>) -> bool {
        use gfx_lib::tex::Components::RGBA;

        texture.handle.get_info().format.get_components() == Some(RGBA)
    }
}

impl<'a, R, C> Graphics for GfxGraphics<'a, R, C>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    type Texture = Texture<R>;

    fn clear(&mut self, color: [f32; 4]) {
        let &mut GfxGraphics {
            ref mut renderer,
            frame,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: color,
                depth: 0.0,
                stencil: 0,
            },
            gfx::COLOR,
            frame
        );
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref frame,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut batch,
                ..
            },
        } = self;

        batch.state = *draw_state;
        batch.param.color = *color;

        f(&mut |vertices: &[f32]| {
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch, *frame);
        })
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &<Self as Graphics>::Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref frame,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            },
        } = self;

        batch_uv.state = *draw_state;
        batch_uv.param.s_texture.0 = texture.handle.clone();
        batch_uv.param.color = *color;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            assert_eq!(
                vertices.len() * UV_COMPONENTS,
                texture_coords.len() * POS_COMPONENTS
            );
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);
            renderer.update_buffer_vec(&buffer_uv, texture_coords, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch_uv.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch_uv, *frame);
        })
    }
}
<commit_msg>Added clear_stencil<commit_after>use std::marker::PhantomData;
use graphics::{ Context, DrawState, Graphics };
use graphics::BACK_END_MAX_VERTEX_COUNT as BUFFER_SIZE;
use { Texture, shaders };
use gfx_lib as gfx;

const POS_COMPONENTS: usize = 2;
const UV_COMPONENTS: usize = 2;

// Boiler plate for automatic attribute construction.
// Needs to be improved on gfx-rs side.
// For some reason, using ``*_COMPONENT` triggers some macros errors.

#[vertex_format]
struct PositionFormat { pos: [f32; 2] }

#[vertex_format]
struct ColorFormat { color: [f32; 4] }

#[vertex_format]
struct TexCoordsFormat { uv: [f32; 2] }

#[shader_param]
struct Params<R: gfx::Resources> {
    color: [f32; 4],
    _dummy: PhantomData<R>,
}

#[shader_param]
struct ParamsUV<R: gfx::Resources> {
    color: [f32; 4],
    s_texture: gfx::shade::TextureParam<R>,
}

/// The data used for drawing 2D graphics.
pub struct Gfx2d<R: gfx::Resources> {
    buffer_pos: gfx::BufferHandle<R, f32>,
    buffer_uv: gfx::BufferHandle<R, f32>,
    batch: gfx::batch::OwnedBatch<Params<R>>,
    batch_uv: gfx::batch::OwnedBatch<ParamsUV<R>>,
}

impl<R: gfx::Resources> Gfx2d<R> {
    /// Creates a new G2D object.
    pub fn new<D, F>(device: &mut D, factory: &mut F) -> Self
        where D: gfx::Device,
              F: gfx::Factory<R>
    {
        use gfx_lib::traits::*;
        use gfx_lib::VertexFormat;

        let shader_model = device.get_capabilities().shader_model;

        let vertex = gfx::ShaderSource {
            glsl_120: Some(shaders::VERTEX_SHADER[0]),
            glsl_150: Some(shaders::VERTEX_SHADER[1]),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(shaders::FRAGMENT_SHADER[0]),
            glsl_150: Some(shaders::FRAGMENT_SHADER[1]),
            .. gfx::ShaderSource::empty()
        };

        let program = factory.link_program(
            vertex.choose(shader_model).unwrap(),
            fragment.choose(shader_model).unwrap()
        ).unwrap();

        let vertex = gfx::ShaderSource {
            glsl_120: Some(shaders::VERTEX_SHADER_UV[0]),
            glsl_150: Some(shaders::VERTEX_SHADER_UV[1]),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(shaders::FRAGMENT_SHADER_UV[0]),
            glsl_150: Some(shaders::FRAGMENT_SHADER_UV[1]),
            .. gfx::ShaderSource::empty()
        };

        let program_uv = factory.link_program(
            vertex.choose(shader_model).unwrap(),
            fragment.choose(shader_model).unwrap()
        ).unwrap();

        let buffer_pos = factory.create_buffer(
            POS_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );
        let buffer_uv = factory.create_buffer(
            UV_COMPONENTS * BUFFER_SIZE,
            gfx::BufferUsage::Dynamic
        );

        let mut mesh = gfx::Mesh::new(BUFFER_SIZE as u32);
        mesh.attributes.extend(
            PositionFormat::generate(
                buffer_pos.raw().clone()
            )
        );

        // Reuse parameters from `mesh`.
        let mut mesh_uv = mesh.clone();
        mesh_uv.attributes.extend(
            TexCoordsFormat::generate(
                buffer_uv.raw().clone()
            )
        );

        let params = Params {
            color: [1.0; 4],
            _dummy: PhantomData,
        };
        let mut batch = gfx::batch::OwnedBatch::new(
            mesh,
            program,
            params
        ).unwrap();

        let sampler = factory.create_sampler(
            gfx::tex::SamplerInfo::new(
                gfx::tex::FilterMethod::Trilinear,
                gfx::tex::WrapMode::Clamp
            )
        );

        // Create a dummy texture
        let texture_info = gfx::tex::TextureInfo {
            width: 1,
            height: 1,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = factory.create_texture(texture_info).unwrap();

        factory.update_texture(
            &texture,
            &image_info,
            &[0x20u8, 0xA0, 0xC0, 0x00],
            Some(gfx::tex::TextureKind::Texture2D)
        ).unwrap();

        let params_uv = ParamsUV {
            color: [1.0; 4],
            s_texture: (texture, Some(sampler))
        };
        let mut batch_uv = gfx::batch::OwnedBatch::new(
            mesh_uv,
            program_uv,
            params_uv
        ).unwrap();

        // Disable culling.
        batch.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);
        batch_uv.state.primitive.method =
            gfx::state::RasterMethod::Fill(gfx::state::CullFace::Nothing);

        Gfx2d {
            buffer_pos: buffer_pos,
            buffer_uv: buffer_uv,
            batch: batch,
            batch_uv: batch_uv,
        }
    }

    /// Renders graphics to a Gfx renderer.
    pub fn draw<C, F>(
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        frame: &gfx::Frame<R>,
        mut f: F
    )
        where C: gfx::CommandBuffer<R>,
              F: FnMut(Context, &mut GfxGraphics<R, C>)
    {
        let ref mut g = GfxGraphics::new(
            renderer,
            frame,
            self
        );
        let c = Context::abs(
            frame.width as f64,
            frame.height as f64
        );
        f(c, g);
    }
}

/// Used for rendering 2D graphics.
pub struct GfxGraphics<'a, R, C>
    where R: gfx::Resources + 'a,
          C: gfx::CommandBuffer<R> + 'a,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    renderer: &'a mut gfx::Renderer<R, C>,
    frame: &'a gfx::Frame<R>,
    g2d: &'a mut Gfx2d<R>,
}

impl<'a, R, C> GfxGraphics<'a, R, C>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>
{
    /// Creates a new object for rendering 2D graphics.
    pub fn new(renderer: &'a mut gfx::Renderer<R, C>,
               frame: &'a gfx::Frame<R>,
               g2d: &'a mut Gfx2d<R>) -> Self {
        GfxGraphics {
            renderer: renderer,
            frame: frame,
            g2d: g2d,
        }
    }

    /// Returns true if texture has alpha channel.
    pub fn has_texture_alpha(&self, texture: &Texture<R>) -> bool {
        use gfx_lib::tex::Components::RGBA;

        texture.handle.get_info().format.get_components() == Some(RGBA)
    }
}

impl<'a, R, C> Graphics for GfxGraphics<'a, R, C>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          R::Buffer: 'a,
          R::ArrayBuffer: 'a,
          R::Shader: 'a,
          R::Program: 'a,
          R::FrameBuffer: 'a,
          R::Surface: 'a,
          R::Texture: 'a,
          R::Sampler: 'a
{
    type Texture = Texture<R>;

    fn clear(&mut self, color: [f32; 4]) {
        let &mut GfxGraphics {
            ref mut renderer,
            frame,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: color,
                depth: 0.0,
                stencil: 0,
            },
            gfx::COLOR,
            frame
        );
    }

    fn clear_stencil(&mut self, value: u8) {
        let &mut GfxGraphics {
            ref mut renderer,
            frame,
            ..
        } = self;
        renderer.clear(
            gfx::ClearData {
                color: [0.0; 4],
                depth: 0.0,
                stencil: value,
            },
            gfx::STENCIL,
            frame
        );
    }

    fn tri_list<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref frame,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut batch,
                ..
            },
        } = self;

        batch.state = *draw_state;
        batch.param.color = *color;

        f(&mut |vertices: &[f32]| {
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch, *frame);
        })
    }

    fn tri_list_uv<F>(
        &mut self,
        draw_state: &DrawState,
        color: &[f32; 4],
        texture: &<Self as Graphics>::Texture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        let &mut GfxGraphics {
            ref mut renderer,
            ref frame,
            g2d: &mut Gfx2d {
                ref mut buffer_pos,
                ref mut buffer_uv,
                ref mut batch_uv,
                ..
            },
        } = self;

        batch_uv.state = *draw_state;
        batch_uv.param.s_texture.0 = texture.handle.clone();
        batch_uv.param.color = *color;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            assert_eq!(
                vertices.len() * UV_COMPONENTS,
                texture_coords.len() * POS_COMPONENTS
            );
            renderer.update_buffer_vec(&buffer_pos, vertices, 0);
            renderer.update_buffer_vec(&buffer_uv, texture_coords, 0);

            let n = vertices.len() / POS_COMPONENTS;
            batch_uv.slice = gfx::Slice {
                    prim_type: gfx::PrimitiveType::TriangleList,
                    start: 0,
                    end: n as u32,
                    kind: gfx::SliceKind::Vertex
            };
            let _ = renderer.draw(batch_uv, *frame);
        })
    }
}
<|endoftext|>


<commit_before>// this is just a test binary that can be hooked up to Instruments
extern crate lonlat_bng;
use lonlat_bng::{convert_to_bng_threaded, Array};

extern crate rand;
use rand::distributions::{IndependentSample, Range};

extern crate libc;

fn main() {
    let num_coords = 1000000;
    let between_lon = Range::new(-6.379880, 1.768960);
    let between_lat = Range::new(49.871159, 55.811741);
    let mut rng = rand::thread_rng();
    let lon_vec = vec![between_lon.ind_sample(&mut rng) as f32; num_coords];
    let lat_vec = vec![between_lat.ind_sample(&mut rng) as f32; num_coords];
    let lon_arr = Array {
        data: lon_vec.as_ptr() as *const libc::c_void,
        len: lon_vec.len() as libc::size_t,
    };
    let lat_arr = Array {
        data: lat_vec.as_ptr() as *const libc::c_void,
        len: lat_vec.len() as libc::size_t,
    };

    convert_to_bng_threaded(lon_arr, lat_arr);
}<commit_msg>Version bump<commit_after>// this is just a test binary that can be hooked up to Instruments
extern crate lonlat_bng;
use lonlat_bng::{convert_to_bng_threaded, convert_vec_c, Array};

extern crate rand;
use rand::distributions::{IndependentSample, Range};

extern crate libc;

fn main() {
    let num_coords = 1000000;
    let between_lon = Range::new(-6.379880, 1.768960);
    let between_lat = Range::new(49.871159, 55.811741);
    let mut rng = rand::thread_rng();
    let lon_vec = vec![between_lon.ind_sample(&mut rng) as f32; num_coords];
    let lat_vec = vec![between_lat.ind_sample(&mut rng) as f32; num_coords];
    let lon_arr = Array {
        data: lon_vec.as_ptr() as *const libc::c_void,
        len: lon_vec.len() as libc::size_t,
    };
    let lat_arr = Array {
        data: lat_vec.as_ptr() as *const libc::c_void,
        len: lat_vec.len() as libc::size_t,
    };

    // convert_vec_c(lon_arr, lat_arr);
    convert_to_bng_threaded(lon_arr, lat_arr);
}<|endoftext|>


<commit_before>use services::crypto::wrappers::bn::BigNumber;

extern crate milagro_crypto;

use std::collections::HashMap;

pub enum ByteOrder {
    Big,
    Little
}

pub struct SchemaKey {
    pub name: String,
    pub version: String,
    pub issue_id: String
}

pub struct PublicKey {
    pub n: BigNumber,
    pub s: BigNumber,
    pub rms: BigNumber,
    pub r: HashMap<String, BigNumber>,
    pub rctxt: BigNumber,
    pub z: BigNumber
}

pub struct ClaimInitData {
    pub u: BigNumber,
    pub v_prime: BigNumber
}

pub struct FullProof {
    pub c_hash: BigNumber,
    pub schema_keys: Vec<SchemaKey>,
    pub proofs: Vec<Proof>,
    pub c_list: Vec<BigNumber>
}

pub struct ProofInput {
    pub revealed_attrs: Vec<String>,
    pub predicates: Vec<Predicate>,
    pub ts: String,
    pub pubseq_no: String
}

pub struct Proof {
    pub primary_proof: Option<PrimaryProof>
    //non_revocation_proof
}

pub struct PrimaryProof {
    pub eq_proof: PrimaryEqualProof,
    pub ge_proofs: Vec<PrimaryPredicateGEProof>
}

pub struct PrimaryEqualProof {
    pub revealed_attr_names: Vec<String>,
    pub a_prime: BigNumber,
    pub e: BigNumber,
    pub v: BigNumber,
    pub m: HashMap<String, BigNumber>,
    pub m1: BigNumber,
    pub m2: BigNumber
}

pub struct PrimaryPredicateGEProof {
    pub u: HashMap<String, BigNumber>,
    pub r: HashMap<String, BigNumber>,
    pub mj: BigNumber,
    pub alpha: BigNumber,
    pub t: HashMap<String, BigNumber>,
    pub predicate: Predicate
}

pub struct Predicate {
    pub attr_name: String,
    pub p_type: String,
    pub value: i32
}<commit_msg>deleted milagro dependency<commit_after>use services::crypto::wrappers::bn::BigNumber;
use std::collections::HashMap;

pub enum ByteOrder {
    Big,
    Little
}

pub struct SchemaKey {
    pub name: String,
    pub version: String,
    pub issue_id: String
}

pub struct PublicKey {
    pub n: BigNumber,
    pub s: BigNumber,
    pub rms: BigNumber,
    pub r: HashMap<String, BigNumber>,
    pub rctxt: BigNumber,
    pub z: BigNumber
}

pub struct ClaimInitData {
    pub u: BigNumber,
    pub v_prime: BigNumber
}

pub struct FullProof {
    pub c_hash: BigNumber,
    pub schema_keys: Vec<SchemaKey>,
    pub proofs: Vec<Proof>,
    pub c_list: Vec<BigNumber>
}

pub struct ProofInput {
    pub revealed_attrs: Vec<String>,
    pub predicates: Vec<Predicate>,
    pub ts: String,
    pub pubseq_no: String
}

pub struct Proof {
    pub primary_proof: Option<PrimaryProof>
    //non_revocation_proof
}

pub struct PrimaryProof {
    pub eq_proof: PrimaryEqualProof,
    pub ge_proofs: Vec<PrimaryPredicateGEProof>
}

pub struct PrimaryEqualProof {
    pub revealed_attr_names: Vec<String>,
    pub a_prime: BigNumber,
    pub e: BigNumber,
    pub v: BigNumber,
    pub m: HashMap<String, BigNumber>,
    pub m1: BigNumber,
    pub m2: BigNumber
}

pub struct PrimaryPredicateGEProof {
    pub u: HashMap<String, BigNumber>,
    pub r: HashMap<String, BigNumber>,
    pub mj: BigNumber,
    pub alpha: BigNumber,
    pub t: HashMap<String, BigNumber>,
    pub predicate: Predicate
}

pub struct Predicate {
    pub attr_name: String,
    pub p_type: String,
    pub value: i32
}<|endoftext|>


<commit_before>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::Float;

use {math, Seed, Point2, Point3, Point4};

macro_rules! brownian {
    { $Brownian:ident, $Point:ident } => {
        pub struct $Brownian<T, F: Fn(&Seed, &$Point<T>) -> T> {
            /// The underlying noise function
            pub function: F,
            /// The number of octaves to use
            pub octaves: uint,
            /// The base frequency of the noise
            pub frequency: T,
            /// How quickly the amplitude of each octave decreases
            pub persistence: T,
            /// How quickly the frequency changes for each octave
            pub lacunarity: T,
        }

        impl<T: Float, F> $Brownian<T, F> where
            F: Fn(&Seed, &$Point<T>) -> T,
        {
            /// Consructs a new brownian noise function, defaulting to:
            ///
            /// - frequency: `1.0`
            /// - lacunarity: `2.0`
            /// - persistence: `0.5`
            #[inline]
            pub fn new(function: F, octaves: uint) -> $Brownian<T, F> {
                $Brownian {
                    function: function,
                    octaves: octaves,
                    frequency: math::cast(1.0f32),
                    lacunarity: math::cast(2.0f32),
                    persistence: math::cast(0.5f32),
                }
            }

            #[inline]
            pub fn function<Q>(self, function: Q) -> $Brownian<T, Q> where
                Q: Fn(&Seed, &$Point<T>) -> T,
            {
                let $Brownian { octaves, frequency, lacunarity, persistence, .. } = self;
                $Brownian {
                    function: function,
                    octaves: octaves,
                    frequency: frequency,
                    persistence: persistence,
                    lacunarity: lacunarity,
                }
            }

            #[inline]
            pub fn octaves(self, octaves: uint) -> $Brownian<T, F> {
                $Brownian { octaves: octaves, ..self }
            }

            #[inline]
            pub fn wavelength(self, wavelength: T) -> $Brownian<T, F> {
                $Brownian { frequency: wavelength.recip(), ..self }
            }

            #[inline]
            pub fn frequency(self, frequency: T) -> $Brownian<T, F> {
                $Brownian { frequency: frequency, ..self }
            }

            #[inline]
            pub fn persistence(self, persistence: T) -> $Brownian<T, F> {
                $Brownian { persistence: persistence, ..self }
            }

            #[inline]
            pub fn lacunarity(self, lacunarity: T) -> $Brownian<T, F> {
                $Brownian { lacunarity: lacunarity, ..self }
            }
        }
    }
}

brownian! { Brownian2, Point2 }
brownian! { Brownian3, Point3 }
brownian! { Brownian4, Point4 }

impl<'a, 'b, T, F> Fn(&'a Seed, &'b Point2<T>) -> T for Brownian2<T, F> where
    T: Float,
    F: Fn(&Seed, &Point2<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b Point2<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}

impl<'a, 'b, T, F> Fn(&'a Seed, &'b ::Point3<T>) -> T for Brownian3<T, F> where
    T: Float,
    F: Fn(&Seed, &::Point3<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b ::Point3<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency,
                                point[2] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}

impl<'a, 'b, T, F> Fn(&'a Seed, &'b ::Point4<T>) -> T for Brownian4<T, F> where
    T: Float,
    F: Fn(&Seed, &::Point4<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b ::Point4<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency,
                                point[2] * frequency,
                                point[3] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}
<commit_msg>Remove extraneuos colon prefixes<commit_after>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::Float;

use {math, Seed, Point2, Point3, Point4};

macro_rules! brownian {
    { $Brownian:ident, $Point:ident } => {
        pub struct $Brownian<T, F: Fn(&Seed, &$Point<T>) -> T> {
            /// The underlying noise function
            pub function: F,
            /// The number of octaves to use
            pub octaves: uint,
            /// The base frequency of the noise
            pub frequency: T,
            /// How quickly the amplitude of each octave decreases
            pub persistence: T,
            /// How quickly the frequency changes for each octave
            pub lacunarity: T,
        }

        impl<T: Float, F> $Brownian<T, F> where
            F: Fn(&Seed, &$Point<T>) -> T,
        {
            /// Consructs a new brownian noise function, defaulting to:
            ///
            /// - frequency: `1.0`
            /// - lacunarity: `2.0`
            /// - persistence: `0.5`
            #[inline]
            pub fn new(function: F, octaves: uint) -> $Brownian<T, F> {
                $Brownian {
                    function: function,
                    octaves: octaves,
                    frequency: math::cast(1.0f32),
                    lacunarity: math::cast(2.0f32),
                    persistence: math::cast(0.5f32),
                }
            }

            #[inline]
            pub fn function<Q>(self, function: Q) -> $Brownian<T, Q> where
                Q: Fn(&Seed, &$Point<T>) -> T,
            {
                let $Brownian { octaves, frequency, lacunarity, persistence, .. } = self;
                $Brownian {
                    function: function,
                    octaves: octaves,
                    frequency: frequency,
                    persistence: persistence,
                    lacunarity: lacunarity,
                }
            }

            #[inline]
            pub fn octaves(self, octaves: uint) -> $Brownian<T, F> {
                $Brownian { octaves: octaves, ..self }
            }

            #[inline]
            pub fn wavelength(self, wavelength: T) -> $Brownian<T, F> {
                $Brownian { frequency: wavelength.recip(), ..self }
            }

            #[inline]
            pub fn frequency(self, frequency: T) -> $Brownian<T, F> {
                $Brownian { frequency: frequency, ..self }
            }

            #[inline]
            pub fn persistence(self, persistence: T) -> $Brownian<T, F> {
                $Brownian { persistence: persistence, ..self }
            }

            #[inline]
            pub fn lacunarity(self, lacunarity: T) -> $Brownian<T, F> {
                $Brownian { lacunarity: lacunarity, ..self }
            }
        }
    }
}

brownian! { Brownian2, Point2 }
brownian! { Brownian3, Point3 }
brownian! { Brownian4, Point4 }

impl<'a, 'b, T, F> Fn(&'a Seed, &'b Point2<T>) -> T for Brownian2<T, F> where
    T: Float,
    F: Fn(&Seed, &Point2<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b Point2<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}

impl<'a, 'b, T, F> Fn(&'a Seed, &'b Point3<T>) -> T for Brownian3<T, F> where
    T: Float,
    F: Fn(&Seed, &::Point3<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b Point3<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency,
                                point[2] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}

impl<'a, 'b, T, F> Fn(&'a Seed, &'b ::Point4<T>) -> T for Brownian4<T, F> where
    T: Float,
    F: Fn(&Seed, &::Point4<T>) -> T,
{
    extern "rust-call" fn call(&self, (seed, point): (&'a Seed, &'b Point4<T>)) -> T {
        let mut frequency: T = self.frequency;
        let mut amplitude: T = Float::one();
        let mut result: T = Float::zero();
        for _ in range(0, self.octaves) {
            let scaled_point = [point[0] * frequency,
                                point[1] * frequency,
                                point[2] * frequency,
                                point[3] * frequency];
            result = result + ((self.function)(seed, &scaled_point) * amplitude);
            amplitude = amplitude * self.persistence;
            frequency = frequency * self.lacunarity;
        }
        result
    }
}
<|endoftext|>