<commit_before>use parser::context::ParserContext;
use parser::models::ParserElem;
use lexer::Lexer;
use parser::{ParsingInterpreter, InterpreterOutput, ParseResult};

use parser::comment::CommentInterpreter;
use parser::text::{TextInterpreter, EscapeCharInterpreter};
use parser::command::CommandInterpreter;

pub struct Parser<'a> {
    lexer: Lexer<'a>,
    context: ParserContext,
    interpreters: Vec<Box<ParsingInterpreter>>,
}

impl<'a> Parser<'a> {
    pub fn new(input: &'a str) -> Self {
        Parser {
            lexer: Lexer::new(input),
            context: ParserContext::new(),
            interpreters: vec![Box::new(CommentInterpreter::new()),
                               Box::new(TextInterpreter::new()),
                               Box::new(CommandInterpreter::new()),
                               Box::new(EscapeCharInterpreter::new())],
        }
    }

    pub fn parse(&mut self) -> ParseResult<Vec<ParserElem>> {
        let mut result = vec![];
        'main: loop {
            let token = self.lexer.next();
            'int: for int in &self.interpreters {
                let out = int.interpret(token.elem(),
                                        &mut result,
                                        &mut self.lexer,
                                        &mut self.context);
                match out {
                    Ok(InterpreterOutput::Stop) => break 'main,
                    Ok(InterpreterOutput::Matched) => break 'int,
                    Ok(_) => continue,
                    Err(err) => return Err(err),
                }
            }
        }
        Ok(result)
    }
}
<commit_msg>use Rust idiom<commit_after>use parser::context::ParserContext;
use parser::models::ParserElem;
use lexer::Lexer;
use parser::{ParsingInterpreter, InterpreterOutput, ParseResult};

use parser::comment::CommentInterpreter;
use parser::text::{TextInterpreter, EscapeCharInterpreter};
use parser::command::CommandInterpreter;

pub struct Parser<'a> {
    lexer: Lexer<'a>,
    context: ParserContext,
    interpreters: Vec<Box<ParsingInterpreter>>,
}

impl<'a> Parser<'a> {
    pub fn new(input: &'a str) -> Self {
        Parser {
            lexer: Lexer::new(input),
            context: ParserContext::new(),
            interpreters: vec![Box::new(CommentInterpreter::new()),
                               Box::new(TextInterpreter::new()),
                               Box::new(CommandInterpreter::new()),
                               Box::new(EscapeCharInterpreter::new())],
        }
    }

    pub fn parse(&mut self) -> ParseResult<Vec<ParserElem>> {
        let mut result = vec![];
        'main: loop {
            let token = self.lexer.next();
            'int: for int in &self.interpreters {
                let out = int.interpret(token.elem(),
                                        &mut result,
                                        &mut self.lexer,
                                        &mut self.context)?;
                match out {
                    InterpreterOutput::Stop => break 'main,
                    InterpreterOutput::Matched => break 'int,
                    _ => continue,
                }
            }
        }
        Ok(result)
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for discrete probability distributions in terms of cumulative distribution
//! functions (CDF).

use std::f64;
use std::iter;
use std::slice;
use std::ops::Range;

use itertools::Itertools;
use ordered_float::OrderedFloat;

use stats::LogProb;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry<T: Ord> {
    pub value: T,
    pub prob: LogProb,
}

impl<T: Ord> Entry<T> {
    pub fn new(value: T, prob: LogProb) -> Self {
        Entry {
            value: value,
            prob: prob,
        }
    }
}

/// Implementation of a cumulative distribution function.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CDF<T: Ord> {
    inner: Vec<Entry<T>>,
}

impl<T: Ord> CDF<T> {
    /// Create CDF from given probability mass function (PMF). The PMF may contain duplicate values
    /// the probabilities of which are summed during generation of the CDF.
    ///
    /// # Arguments
    ///
    /// * `pmf` - the PMF as a vector of `Entry` objects
    pub fn from_pmf(mut entries: Vec<Entry<T>>) -> Self {
        entries.sort_by(|a, b| a.value.cmp(&b.value));
        let mut inner: Vec<Entry<T>> = Vec::new();
        for mut e in entries {
            let p = inner
                .last()
                .map_or(LogProb::ln_zero(), |e| e.prob)
                .ln_add_exp(e.prob);
            if !inner.is_empty() && inner.last().unwrap().value == e.value {
                inner.last_mut().unwrap().prob = p;
            } else {
                e.prob = p;
                inner.push(e);
            }
        }
        let mut cdf = CDF { inner: inner };

        if relative_eq!(*cdf.total_prob(), *LogProb::ln_one()) &&
           *cdf.total_prob() > *LogProb::ln_one() {
            cdf.inner.last_mut().unwrap().prob = LogProb::ln_one();
        }

        cdf
    }

    /// Create CDF from iterator. This can be used to replace the values of a CDF.
    pub fn from_cdf<I: Iterator<Item = Entry<T>>>(entries: I) -> Self {
        CDF { inner: entries.collect_vec() }
    }

    /// Reduce CDF by omitting values with zero probability.
    pub fn reduce(self) -> Self {
        let mut inner = Vec::new();
        let mut last = LogProb::ln_zero();
        for e in self.inner {
            if last != e.prob {
                last = e.prob;
                inner.push(e);
            }
        }
        CDF { inner: inner }
    }

    /// Downsample CDF to n entries. Panics if n <= 1 and returns identity if n is greater
    /// than the number of entries.
    pub fn sample(mut self, n: usize) -> Self {
        assert!(n > 1);
        if self.inner.len() <= n {
            self
        } else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF { inner: inner }
        }
    }

    /// Provide iterator.
    pub fn iter(&self) -> slice::Iter<Entry<T>> {
        self.inner.iter()
    }

    /// Iterator over corresponding PMF.
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<'a, G: Ord>(last_prob: &mut LogProb,
                                  e: &'a Entry<G>)
                                  -> Option<Entry<&'a G>> {
            let prob = e.prob.ln_sub_exp(*last_prob);
            *last_prob = e.prob;
            Some(Entry::new(&e.value, prob))
        }
        self.inner.iter().scan(LogProb::ln_zero(), cdf_to_pmf)
    }

    /// Get cumulative probability for a given value. If the value is not present,
    /// return the probability of the previous value. Complexity O(log n).
    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => self.inner[i].prob,
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Get probability (i.e. probability mass) for a given value. Complexity O(log n).
    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => {
                         if i > 0 {
                             self.inner[i].prob.ln_sub_exp(self.inner[i - 1].prob)
                         } else {
                             self.inner[0].prob
                         }
                     }
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Return total probability.
    pub fn total_prob(&self) -> LogProb {
        self.inner.last().map_or(LogProb::ln_zero(), |e| e.prob)
    }

    /// Return maximum a posteriori probability estimate (MAP).
    pub fn map(&self) -> Option<&T> {
        if let Some(mut max) = self.iter_pmf().next() {
            for e in self.iter_pmf() {
                if e.prob >= max.prob {
                    max = e;
                }
            }
            Some(max.value)
        } else {
            None
        }
    }

    /// Return w%-credible interval. The width w is a float between 0 and 1. Panics otherwise.
    /// E.g. provide `width=0.95` for the 95% credible interval.
    pub fn credible_interval(&self, width: f64) -> Range<&T> {
        assert!(width >= 0.0 && width <= 1.0);
        let margin = 1.0 - width;
        let p_lower = OrderedFloat((margin / 2.0).ln());
        let p_upper = OrderedFloat((1.0 - margin / 2.0).ln());
        let lower = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_lower))
            .unwrap_or_else(|i| if i > 0 { i - 1 } else { 0 });
        let mut upper = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_upper))
            .unwrap_or_else(|i| i);
        if upper == self.inner.len() {
            upper -= 1;
        }

        &self.inner[lower].value..&self.inner[upper].value
    }

    /// Number of entries in the CDF.
    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

impl<T: Clone + Ord> CDF<T>
    where f64: From<T>
{
    /// Calculate expected value.
    pub fn expected_value(&self) -> f64 {
        self.iter_pmf()
            .map(|e| f64::from(e.value.clone()) * e.prob.exp())
            .fold(0.0f64, |s, e| s + e)
    }

    /// Calculate variance.
    pub fn variance(&self) -> f64 {
        let ev = self.expected_value();
        self.iter_pmf()
            .map(|e| (f64::from(e.value.clone()) - ev).powi(2) * e.prob.exp())
            .fold(0.0, |s, e| s + e)
    }

    /// Calculate standard deviation.
    pub fn standard_deviation(&self) -> f64 {
        self.variance().sqrt()
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, Entry<T>>,
                                        LogProb,
                                        fn(&mut LogProb, &'a Entry<T>) -> Option<Entry<&'a T>>>;

#[cfg(test)]
mod test {
    use super::*;
    use stats::LogProb;
    use ordered_float::NotNaN;

    #[test]
    fn test_cdf() {
        let mut pmf = vec![Entry::new(NotNaN::new(0.0).unwrap(), LogProb(0.1f64.ln()))];
        for i in 0..9 {
            pmf.push(Entry::new(NotNaN::new(i as f64).unwrap(), LogProb(0.1f64.ln())));
        }
        println!("{:?}", pmf);

        let cdf = CDF::from_pmf(pmf.clone());
        println!("{:?}", cdf);
        for e in pmf.iter().skip(2) {
            assert_ulps_eq!(*e.prob,
                            *cdf.get_pmf(&e.value).unwrap(),
                            epsilon = 0.0000000000001);
        }
        assert_relative_eq!(*cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(*cdf.get(&NotNaN::new(1.0).unwrap()).unwrap(),
                            0.3f64.ln(),
                            epsilon = 0.00000001);
        {
            let ci = cdf.credible_interval(0.95);
            assert_relative_eq!(**ci.start, 0.0);
            assert_relative_eq!(**ci.end, 8.0);
        }

        {
            for e in cdf.iter_pmf() {
                assert_relative_eq!(
                    e.prob.exp(),
                    if **e.value == 0.0 { 0.2 } else { 0.1 }
                );
            }
        }

        assert_relative_eq!(cdf.sample(5).total_prob().exp(), 1.0);
    }
}
<commit_msg>Handle the case of an empty cdf.<commit_after>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for discrete probability distributions in terms of cumulative distribution
//! functions (CDF).

use std::f64;
use std::iter;
use std::slice;
use std::ops::Range;

use itertools::Itertools;
use ordered_float::OrderedFloat;

use stats::LogProb;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry<T: Ord> {
    pub value: T,
    pub prob: LogProb,
}

impl<T: Ord> Entry<T> {
    pub fn new(value: T, prob: LogProb) -> Self {
        Entry {
            value: value,
            prob: prob,
        }
    }
}

/// Implementation of a cumulative distribution function.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CDF<T: Ord> {
    inner: Vec<Entry<T>>,
}

impl<T: Ord> CDF<T> {
    /// Create CDF from given probability mass function (PMF). The PMF may contain duplicate values
    /// the probabilities of which are summed during generation of the CDF.
    ///
    /// # Arguments
    ///
    /// * `pmf` - the PMF as a vector of `Entry` objects
    pub fn from_pmf(mut entries: Vec<Entry<T>>) -> Self {
        entries.sort_by(|a, b| a.value.cmp(&b.value));
        let mut inner: Vec<Entry<T>> = Vec::new();
        for mut e in entries {
            let p = inner
                .last()
                .map_or(LogProb::ln_zero(), |e| e.prob)
                .ln_add_exp(e.prob);
            if !inner.is_empty() && inner.last().unwrap().value == e.value {
                inner.last_mut().unwrap().prob = p;
            } else {
                e.prob = p;
                inner.push(e);
            }
        }
        let mut cdf = CDF { inner: inner };

        if relative_eq!(*cdf.total_prob(), *LogProb::ln_one()) &&
           *cdf.total_prob() > *LogProb::ln_one() {
            cdf.inner.last_mut().unwrap().prob = LogProb::ln_one();
        }

        cdf
    }

    /// Create CDF from iterator. This can be used to replace the values of a CDF.
    pub fn from_cdf<I: Iterator<Item = Entry<T>>>(entries: I) -> Self {
        CDF { inner: entries.collect_vec() }
    }

    /// Reduce CDF by omitting values with zero probability.
    pub fn reduce(self) -> Self {
        let mut inner = Vec::new();
        let mut last = LogProb::ln_zero();
        for e in self.inner {
            if last != e.prob {
                last = e.prob;
                inner.push(e);
            }
        }
        CDF { inner: inner }
    }

    /// Downsample CDF to n entries. Panics if n <= 1 and returns identity if n is greater
    /// than the number of entries.
    pub fn sample(mut self, n: usize) -> Self {
        assert!(n > 1);
        if self.inner.len() <= n {
            self
        } else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF { inner: inner }
        }
    }

    /// Provide iterator.
    pub fn iter(&self) -> slice::Iter<Entry<T>> {
        self.inner.iter()
    }

    /// Iterator over corresponding PMF.
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<'a, G: Ord>(last_prob: &mut LogProb,
                                  e: &'a Entry<G>)
                                  -> Option<Entry<&'a G>> {
            let prob = e.prob.ln_sub_exp(*last_prob);
            *last_prob = e.prob;
            Some(Entry::new(&e.value, prob))
        }
        self.inner.iter().scan(LogProb::ln_zero(), cdf_to_pmf)
    }

    /// Get cumulative probability for a given value. If the value is not present,
    /// return the probability of the previous value. Complexity O(log n).
    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => self.inner[i].prob,
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Get probability (i.e. probability mass) for a given value. Complexity O(log n).
    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => {
                         if i > 0 {
                             self.inner[i].prob.ln_sub_exp(self.inner[i - 1].prob)
                         } else {
                             self.inner[0].prob
                         }
                     }
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Return total probability.
    pub fn total_prob(&self) -> LogProb {
        self.inner.last().map_or(LogProb::ln_zero(), |e| e.prob)
    }

    /// Return maximum a posteriori probability estimate (MAP).
    pub fn map(&self) -> Option<&T> {
        if let Some(mut max) = self.iter_pmf().next() {
            for e in self.iter_pmf() {
                if e.prob >= max.prob {
                    max = e;
                }
            }
            Some(max.value)
        } else {
            None
        }
    }

    /// Return w%-credible interval. The width w is a float between 0 and 1. Panics otherwise.
    /// E.g. provide `width=0.95` for the 95% credible interval.
    pub fn credible_interval(&self, width: f64) -> Option<Range<&T>> {
        assert!(width >= 0.0 && width <= 1.0);

        if self.inner.is_empty() {
            return None;
        }

        let margin = 1.0 - width;
        let p_lower = OrderedFloat((margin / 2.0).ln());
        let p_upper = OrderedFloat((1.0 - margin / 2.0).ln());
        let lower = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_lower))
            .unwrap_or_else(|i| if i > 0 { i - 1 } else { 0 });
        let mut upper = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_upper))
            .unwrap_or_else(|i| i);
        if upper == self.inner.len() {
            upper -= 1;
        }

        Some(&self.inner[lower].value..&self.inner[upper].value)
    }

    /// Number of entries in the CDF.
    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

impl<T: Clone + Ord> CDF<T>
    where f64: From<T>
{
    /// Calculate expected value.
    pub fn expected_value(&self) -> f64 {
        self.iter_pmf()
            .map(|e| f64::from(e.value.clone()) * e.prob.exp())
            .fold(0.0f64, |s, e| s + e)
    }

    /// Calculate variance.
    pub fn variance(&self) -> f64 {
        let ev = self.expected_value();
        self.iter_pmf()
            .map(|e| (f64::from(e.value.clone()) - ev).powi(2) * e.prob.exp())
            .fold(0.0, |s, e| s + e)
    }

    /// Calculate standard deviation.
    pub fn standard_deviation(&self) -> f64 {
        self.variance().sqrt()
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, Entry<T>>,
                                        LogProb,
                                        fn(&mut LogProb, &'a Entry<T>) -> Option<Entry<&'a T>>>;

#[cfg(test)]
mod test {
    use super::*;
    use stats::LogProb;
    use ordered_float::NotNaN;

    #[test]
    fn test_cdf() {
        let mut pmf = vec![Entry::new(NotNaN::new(0.0).unwrap(), LogProb(0.1f64.ln()))];
        for i in 0..9 {
            pmf.push(Entry::new(NotNaN::new(i as f64).unwrap(), LogProb(0.1f64.ln())));
        }
        println!("{:?}", pmf);

        let cdf = CDF::from_pmf(pmf.clone());
        println!("{:?}", cdf);
        for e in pmf.iter().skip(2) {
            assert_ulps_eq!(*e.prob,
                            *cdf.get_pmf(&e.value).unwrap(),
                            epsilon = 0.0000000000001);
        }
        assert_relative_eq!(*cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(*cdf.get(&NotNaN::new(1.0).unwrap()).unwrap(),
                            0.3f64.ln(),
                            epsilon = 0.00000001);
        {
            let ci = cdf.credible_interval(0.95).unwrap();
            assert_relative_eq!(**ci.start, 0.0);
            assert_relative_eq!(**ci.end, 8.0);
        }

        {
            for e in cdf.iter_pmf() {
                assert_relative_eq!(
                    e.prob.exp(),
                    if **e.value == 0.0 { 0.2 } else { 0.1 }
                );
            }
        }

        assert_relative_eq!(cdf.sample(5).total_prob().exp(), 1.0);
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::slice;

extern crate libc;
use self::libc::{c_void};

#[repr(C)]
pub struct Array {
    pub data: *const c_void,
    pub len: libc::size_t,
}

use super::convert_to_bng_threaded_vec;
use super::convert_to_lonlat_threaded_vec;
use super::convert_to_osgb36_threaded_vec;
use super::convert_to_etrs89_threaded_vec;
use super::convert_etrs89_to_osgb36_threaded_vec;
use super::convert_etrs89_to_ll_threaded_vec;
use super::convert_osgb36_to_ll_threaded_vec;
use super::convert_osgb36_to_etrs89_threaded_vec;
use super::convert_epsg3857_to_wgs84_threaded_vec;

/// Free memory which Rust has allocated across the FFI boundary (f64 values)
///
/// # Examples
///
/// ```
/// # extern crate libc;
/// let lon_vec: Vec<f64> = vec![-2.0183041005533306];
/// let lat_vec: Vec<f64> = vec![54.589097162646141];
/// 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,
/// };
/// let (eastings, northings) = convert_to_bng_threaded(lon_arr, lat_arr);
/// drop_float_array(eastings, northings);
/// ```
/// An example FFI implementation is available at [Convertbng](https://github.com/urschrei/convertbng/blob/master/convertbng/util.py), specifically in the `_void_array_to_list` function.
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn drop_float_array(lons: Array, lats: Array) {
    if lons.data.is_null() {
        return;
    }
    if lats.data.is_null() {
        return;
    }
    unsafe {
        lons.as_f64_slice();
    }
    unsafe {
        lats.as_f64_slice();
    }
}

impl Array {
    pub unsafe fn as_f64_slice(&self) -> &mut [f64] {
        assert!(!self.data.is_null());
        slice::from_raw_parts_mut(self.data as *mut f64, self.len as usize)
    }
}

// Build an Array from &mut[f64], so it can be leaked across the FFI boundary
impl<'a, T> From<&'a mut [T]> for Array {
    fn from(sl: &mut [T]) -> Self {
        let array = Array {
            data: sl.as_ptr() as *const libc::c_void,
            len: sl.len() as libc::size_t,
        };
        mem::forget(sl);
        array
    }
}

/// A threaded, FFI-compatible wrapper for `lonlat_bng::convert_osgb36`
///
/// # Examples
///
/// ```
/// extern crate libc;
/// let lon_vec: Vec<f64> = vec![-2.0183041005533306,
///                              0.95511887434519682,
///                              0.44975855518383501,
///                              -0.096813621191803811,
///                              -0.36807065656416427,
///                              0.63486335458665621];
/// let lat_vec: Vec<f64> = vec![54.589097162646141,
///                              51.560873800587828,
///                              50.431429161121699,
///                              54.535021436247419,
///                              50.839059313135706,
///                              55.412189281234419];
/// 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,
/// };
/// let (eastings, northings) = convert_to_bng_threaded(lon_arr, lat_arr);
/// ```
/// For an FFI implementation, see the code at [Convertbng](https://github.com/urschrei/convertbng/blob/master/convertbng/util.py).
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_bng_threaded(longitudes: Array, latitudes: Array) -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_bng_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_ll`](fn.convert_osgb36_to_ll.html)
///
/// # Examples
///
/// See [`lonlat_bng::convert_to_bng_threaded`](fn.convert_to_bng_threaded.html)
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_lonlat_threaded(eastings: Array, northings: Array) -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_to_lonlat_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36`](fn.convert_osgb36.html)
///
/// # Examples
///
/// See [`lonlat_bng::convert_to_bng_threaded`](fn.convert_to_bng_threaded.html) for examples, substituting f64 vectors
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_osgb36_threaded(longitudes: Array,
                                             latitudes: Array)
                                             -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_osgb36_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89`](fn.convert_etrs89.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples, substituting f64 vectors
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_etrs89_threaded(longitudes: Array,
                                             latitudes: Array)
                                             -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_etrs89_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89_to_osgb36`](fn.convert_etrs89_to_osgb36.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_etrs89_to_osgb36_threaded(eastings: Array,
                                                    northings: Array)
                                                    -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_etrs89_to_osgb36_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89_to_ll`](fn.convert_etrs89_to_ll.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_etrs89_to_ll_threaded(eastings: Array,
                                                northings: Array)
                                                -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_etrs89_to_ll_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_ll`](fn.convert_osgb36_to_ll.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_osgb36_to_ll_threaded(eastings: Array,
                                                northings: Array)
                                                -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_osgb36_to_ll_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_etrs89`](fn.convert_osgb36_to_etrs89.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_osgb36_to_etrs89_threaded(eastings: Array,
                                                    northings: Array)
                                                    -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_osgb36_to_etrs89_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_epsg3857_to_wgs84`](fn.convert_epsg3857_to_wgs84.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_epsg3857_to_wgs84_threaded(x: Array, y: Array) -> (Array, Array) {
    let mut x_vec = unsafe { x.as_f64_slice() };
    let mut y_vec = unsafe { y.as_f64_slice() };
    convert_epsg3857_to_wgs84_threaded_vec(&mut x_vec, &mut y_vec);
    (Array::from(x_vec), Array::from(y_vec))
}
<commit_msg>Add Array <--> Vec From traits<commit_after>use std::mem;
use std::slice;

extern crate libc;
use self::libc::{c_void};

#[repr(C)]
pub struct Array {
    pub data: *const c_void,
    pub len: libc::size_t,
}

use super::convert_to_bng_threaded_vec;
use super::convert_to_lonlat_threaded_vec;
use super::convert_to_osgb36_threaded_vec;
use super::convert_to_etrs89_threaded_vec;
use super::convert_etrs89_to_osgb36_threaded_vec;
use super::convert_etrs89_to_ll_threaded_vec;
use super::convert_osgb36_to_ll_threaded_vec;
use super::convert_osgb36_to_etrs89_threaded_vec;
use super::convert_epsg3857_to_wgs84_threaded_vec;

/// Free memory which Rust has allocated across the FFI boundary (f64 values)
///
/// # Examples
///
/// ```
/// # extern crate libc;
/// let lon_vec: Vec<f64> = vec![-2.0183041005533306];
/// let lat_vec: Vec<f64> = vec![54.589097162646141];
/// 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,
/// };
/// let (eastings, northings) = convert_to_bng_threaded(lon_arr, lat_arr);
/// drop_float_array(eastings, northings);
/// ```
/// An example FFI implementation is available at [Convertbng](https://github.com/urschrei/convertbng/blob/master/convertbng/util.py), specifically in the `_void_array_to_list` function.
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn drop_float_array(lons: Array, lats: Array) {
    if lons.data.is_null() {
        return;
    }
    if lats.data.is_null() {
        return;
    }
    unsafe {
        lons.as_f64_slice();
    }
    unsafe {
        lats.as_f64_slice();
    }
}

// Convert Array to mutable [f64] slice
impl Array {
    pub unsafe fn as_f64_slice(&self) -> &mut [f64] {
        assert!(!self.data.is_null());
        slice::from_raw_parts_mut(self.data as *mut f64, self.len as usize)
    }
}

// Build an Array from &mut[T], so it can be leaked across the FFI boundary
impl<'a, T> From<&'a mut [T]> for Array {
    fn from(sl: &mut [T]) -> Self {
        let array = Array {
            data: sl.as_ptr() as *const libc::c_void,
            len: sl.len() as libc::size_t,
        };
        mem::forget(sl);
        array
    }
}

// Build an Array from a Vec, so it can be leaked across the FFI boundary
impl<T> From<Vec<T>> for Array {
    fn from(vec: Vec<T>) -> Self {
        let array = Array {
            data: vec.as_ptr() as *const libc::c_void,
            len: vec.len() as libc::size_t,
        };
        mem::forget(vec);
        array
    }
}

// Build a Vec from an Array, so it can be dropped
impl From<Array> for Vec<f64> {
    fn from(arr: Array) -> Self {
        unsafe { Vec::from_raw_parts(arr.data as *mut f64, arr.len, arr.len) }
    }
}

/// A threaded, FFI-compatible wrapper for `lonlat_bng::convert_osgb36`
///
/// # Examples
///
/// ```
/// extern crate libc;
/// let lon_vec: Vec<f64> = vec![-2.0183041005533306,
///                              0.95511887434519682,
///                              0.44975855518383501,
///                              -0.096813621191803811,
///                              -0.36807065656416427,
///                              0.63486335458665621];
/// let lat_vec: Vec<f64> = vec![54.589097162646141,
///                              51.560873800587828,
///                              50.431429161121699,
///                              54.535021436247419,
///                              50.839059313135706,
///                              55.412189281234419];
/// 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,
/// };
/// let (eastings, northings) = convert_to_bng_threaded(lon_arr, lat_arr);
/// ```
/// For an FFI implementation, see the code at [Convertbng](https://github.com/urschrei/convertbng/blob/master/convertbng/util.py).
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_bng_threaded(longitudes: Array, latitudes: Array) -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_bng_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_ll`](fn.convert_osgb36_to_ll.html)
///
/// # Examples
///
/// See [`lonlat_bng::convert_to_bng_threaded`](fn.convert_to_bng_threaded.html)
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_lonlat_threaded(eastings: Array, northings: Array) -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_to_lonlat_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36`](fn.convert_osgb36.html)
///
/// # Examples
///
/// See [`lonlat_bng::convert_to_bng_threaded`](fn.convert_to_bng_threaded.html) for examples, substituting f64 vectors
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_osgb36_threaded(longitudes: Array,
                                             latitudes: Array)
                                             -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_osgb36_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89`](fn.convert_etrs89.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples, substituting f64 vectors
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_to_etrs89_threaded(longitudes: Array,
                                             latitudes: Array)
                                             -> (Array, Array) {
    let mut longitudes_v = unsafe { longitudes.as_f64_slice() };
    let mut latitudes_v = unsafe { latitudes.as_f64_slice() };
    convert_to_etrs89_threaded_vec(&mut longitudes_v, &mut latitudes_v);
    (Array::from(longitudes_v), Array::from(latitudes_v))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89_to_osgb36`](fn.convert_etrs89_to_osgb36.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_etrs89_to_osgb36_threaded(eastings: Array,
                                                    northings: Array)
                                                    -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_etrs89_to_osgb36_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_etrs89_to_ll`](fn.convert_etrs89_to_ll.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_etrs89_to_ll_threaded(eastings: Array,
                                                northings: Array)
                                                -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_etrs89_to_ll_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_ll`](fn.convert_osgb36_to_ll.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_osgb36_to_ll_threaded(eastings: Array,
                                                northings: Array)
                                                -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_osgb36_to_ll_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_osgb36_to_etrs89`](fn.convert_osgb36_to_etrs89.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_osgb36_to_etrs89_threaded(eastings: Array,
                                                    northings: Array)
                                                    -> (Array, Array) {
    let mut eastings_vec = unsafe { eastings.as_f64_slice() };
    let mut northings_vec = unsafe { northings.as_f64_slice() };
    convert_osgb36_to_etrs89_threaded_vec(&mut eastings_vec, &mut northings_vec);
    (Array::from(eastings_vec), Array::from(northings_vec))
}

/// A threaded, FFI-compatible wrapper for [`lonlat_bng::convert_epsg3857_to_wgs84`](fn.convert_epsg3857_to_wgs84.html)
///
/// # Examples
///
/// See `lonlat_bng::convert_to_bng_threaded` for examples
///
/// # Safety
///
/// This function is unsafe because it accesses a raw pointer which could contain arbitrary data
#[no_mangle]
pub extern "C" fn convert_epsg3857_to_wgs84_threaded(x: Array, y: Array) -> (Array, Array) {
    let mut x_vec = unsafe { x.as_f64_slice() };
    let mut y_vec = unsafe { y.as_f64_slice() };
    convert_epsg3857_to_wgs84_threaded_vec(&mut x_vec, &mut y_vec);
    (Array::from(x_vec), Array::from(y_vec))
}
<|endoftext|>


<commit_before>use var::Var;
use def::Def;

pub struct Fun(Box<FnMut(&[Var], &Def) -> Option<Var>>);
impl Fun {
    pub fn run(&mut self, args: &[Var], def: &Def) -> Option<Var> {
        self.0(args, def)
    }

    pub fn new<F: 'static>(fun: F) -> Fun
        where F: FnMut(&[Var], &Def) -> Option<Var> {
        Fun(Box::new(fun))
    }
}
<commit_msg>impl send<commit_after>use var::Var;
use def::Def;

pub struct Fun(Box<FnMut(&[Var], &Def) -> Option<Var> + Send>);
impl Fun {
    pub fn run(&mut self, args: &[Var], def: &Def) -> Option<Var> {
        self.0(args, def)
    }

    pub fn new<F: 'static + Send>(fun: F) -> Fun
        where F: FnMut(&[Var], &Def) -> Option<Var> {
        Fun(Box::new(fun))
    }
}
<|endoftext|>


<commit_before>extern crate rand;

pub use rand::{Rng, SeedableRng};

pub struct BsdLcg {
    state: u32,
}

impl Rng for BsdLcg {
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(1_103_515_245).wrapping_add(12_345);
        self.state %= 1 << 31;
        self.state
    }
}

impl SeedableRng<u32> for BsdLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

pub struct MsLcg {
    state: u32,
}

impl Rng for MsLcg {
    // Because this only uses the high 16 bits of the state (`>> 16`), this should technically use
    // `next_u16`, but the `rand` crate does not provide it.  If serious usage is required,
    // implementing this function as a concatenation of two `next_u16`s (elsewhere defined) should
    // work.
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(214_013).wrapping_add(2_531_011);
        self.state %= 1 << 31;
        self.state >> 16 //  rand_n = state_n / 2^16
    }
}

impl SeedableRng<u32> for MsLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

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

    #[test]
    fn test_ms() {
        let mut rng = MsLcg::from_seed(1);

        for &num in &[41, 18467, 6334, 26500, 19169] {
            assert_eq!(rng.next_u32(), num);
        }
    }

    #[test]
    fn test_bsd() {
        let mut rng = BsdLcg::from_seed(1);

        for &num in &[1103527590, 377401575, 662824084, 1147902781, 2035015474] {
            assert_eq!(rng.next_u32(), num);
        }
    }
}
<commit_msg>update comments<commit_after>extern crate rand;

pub use rand::{Rng, SeedableRng};

pub struct BsdLcg {
    state: u32,
}

impl Rng for BsdLcg {
    // Because the output is in the range [0, 2147483647], this should technically be `next_u16`
    // (the largest integer size which is fully covered, as `rand::Rng` assumes).  The `rand`
    // crate does not provide it however.  If serious usage is required, implementing this
    // function as a concatenation of two `next_u16`s (elsewhere defined) should work.
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(1_103_515_245).wrapping_add(12_345);
        self.state %= 1 << 31;
        self.state
    }
}

impl SeedableRng<u32> for BsdLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

pub struct MsLcg {
    state: u32,
}

impl Rng for MsLcg {
    // Similarly, this outputs in the range [0, 32767] and should output a `u8`.  Concatenate
    // four `next_u8`s for serious usage.
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(214_013).wrapping_add(2_531_011);
        self.state %= 1 << 31;
        self.state >> 16 //  rand_n = state_n / 2^16
    }
}

impl SeedableRng<u32> for MsLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

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

    #[test]
    fn test_ms() {
        let mut rng = MsLcg::from_seed(1);

        for &num in &[41, 18467, 6334, 26500, 19169] {
            assert_eq!(rng.next_u32(), num);
        }
    }

    #[test]
    fn test_bsd() {
        let mut rng = BsdLcg::from_seed(1);

        for &num in &[1103527590, 377401575, 662824084, 1147902781, 2035015474] {
            assert_eq!(rng.next_u32(), num);
        }
    }
}
<|endoftext|>


<commit_before>//! Data structure for Tiled map editor JSON format.

use euclid::default::Point2D;
use euclid::point2;
use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use std::iter::{self, FromIterator, IntoIterator};
use std::path::PathBuf;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Orientation {
    #[serde(rename = "orthogonal")]
    Orthogonal,
    #[serde(rename = "isometric")]
    Isometric,
    #[serde(rename = "staggered")]
    Staggered,
    #[serde(rename = "hexagonal")]
    Hexagonal,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Chunk {
    pub data: Vec<u32>,
    pub width: u32,
    pub height: u32,
    pub x: i32,
    pub y: i32,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ChunkMap(pub Vec<Chunk>);

impl FromIterator<(Point2D<i32>, u32)> for ChunkMap {
    fn from_iter<I: IntoIterator<Item = (Point2D<i32>, u32)>>(iter: I) -> Self {
        const CHUNK_WIDTH: i32 = 16;
        const CHUNK_HEIGHT: i32 = 16;
        let mut chunks = HashMap::new();

        // Place all points into corresponding chunks.
        for (pt, c) in iter.into_iter() {
            // Get the top corner of the chunk where this point goes in.
            let x = if pt.x >= 0 {
                pt.x / CHUNK_WIDTH
            } else {
                ((pt.x + 1) / CHUNK_WIDTH) - 1
            };
            let y = if pt.y >= 0 {
                pt.y / CHUNK_HEIGHT
            } else {
                ((pt.y + 1) / CHUNK_HEIGHT) - 1
            };

            let origin = point2(x * CHUNK_WIDTH, y * CHUNK_HEIGHT);
            let offset = (pt.x - origin.x + (pt.y - origin.y) * CHUNK_WIDTH) as usize;
            chunks
                .entry(origin)
                .or_insert_with(|| vec![0; (CHUNK_WIDTH * CHUNK_HEIGHT) as usize])[offset] = c;
        }

        // Turn chunks into ChunkMap data.
        ChunkMap(
            chunks
                .into_iter()
                .map(|(orig, data): (Point2D<_>, Vec<_>)| Chunk {
                    data,
                    width: CHUNK_WIDTH as u32,
                    height: CHUNK_HEIGHT as u32,
                    x: orig.x,
                    y: orig.y,
                })
                .collect(),
        )
    }
}

impl ChunkMap {
    /// Iterate the nonzero points in a chunk map
    pub fn iter(&self) -> impl Iterator<Item = (Point2D<i32>, u32)> + '_ {
        let mut i = 0;
        let mut p = 0;
        iter::from_fn(move || {
            if i < self.0.len() && p >= self.0[i].data.len() {
                i += 1;
                p = 0;
            }
            if i >= self.0.len() {
                return None;
            }

            let chunk = &self.0[i];
            let pitch = chunk.width as i32;
            let offset = p as i32;
            let ret = (
                point2(chunk.x + offset % pitch, chunk.y + offset / pitch),
                chunk.data[p],
            );
            p += 1;
            Some(ret)
        })
        .filter(|(_, t)| *t != 0)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Layer {
    #[serde(rename = "tilelayer")]
    TileLayer {
        x: i32,
        y: i32,
        width: u32,
        height: u32,
        opacity: f32,
        name: String,
        id: u32,
        visible: bool,

        #[serde(skip_serializing_if = "Option::is_none")]
        chunks: Option<ChunkMap>,
        #[serde(skip_serializing_if = "Option::is_none")]
        data: Option<Vec<u32>>,
        // Not supported: compression, encoding
    },
    #[serde(rename = "objectgroup")]
    ObjectGroup {
        x: i32,
        y: i32,
        opacity: f32,
        name: String,
        id: u32,
        visible: bool,

        draworder: String,
        objects: Vec<Object>,
    },
    // Not supported: imagelayer, group
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Object {
    #[serde(rename = "type")]
    pub type_: String,
    pub gid: u32,
    pub id: u32,
    pub name: String,
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
    pub rotation: f32,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Tileset {
    pub columns: u32,
    pub tilecount: u32,
    pub tileheight: u32,
    pub tilewidth: u32,
    pub spacing: u32,
    pub firstgid: u32,
    pub image: PathBuf,
    pub imageheight: u32,
    pub imagewidth: u32,
    pub margin: u32,
    pub name: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Map {
    #[serde(rename = "type")]
    pub type_: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub backgroundcolor: Option<String>,
    pub width: u32,
    pub height: u32,
    pub layers: Vec<Layer>,
    pub infinite: bool,
    pub nextlayerid: u32,
    pub nextobjectid: u32,
    pub orientation: Orientation,
    pub renderorder: String,
    pub tiledversion: String,
    pub tileheight: u32,
    pub tilewidth: u32,
    pub version: f32,
    pub tilesets: Vec<Tileset>,
}
<commit_msg>Support global Tiled map properties<commit_after>//! Data structure for Tiled map editor JSON format.

use euclid::default::Point2D;
use euclid::point2;
use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use std::iter::{self, FromIterator, IntoIterator};
use std::path::PathBuf;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Orientation {
    #[serde(rename = "orthogonal")]
    Orthogonal,
    #[serde(rename = "isometric")]
    Isometric,
    #[serde(rename = "staggered")]
    Staggered,
    #[serde(rename = "hexagonal")]
    Hexagonal,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Chunk {
    pub data: Vec<u32>,
    pub width: u32,
    pub height: u32,
    pub x: i32,
    pub y: i32,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ChunkMap(pub Vec<Chunk>);

impl FromIterator<(Point2D<i32>, u32)> for ChunkMap {
    fn from_iter<I: IntoIterator<Item = (Point2D<i32>, u32)>>(iter: I) -> Self {
        const CHUNK_WIDTH: i32 = 16;
        const CHUNK_HEIGHT: i32 = 16;
        let mut chunks = HashMap::new();

        // Place all points into corresponding chunks.
        for (pt, c) in iter.into_iter() {
            // Get the top corner of the chunk where this point goes in.
            let x = if pt.x >= 0 {
                pt.x / CHUNK_WIDTH
            } else {
                ((pt.x + 1) / CHUNK_WIDTH) - 1
            };
            let y = if pt.y >= 0 {
                pt.y / CHUNK_HEIGHT
            } else {
                ((pt.y + 1) / CHUNK_HEIGHT) - 1
            };

            let origin = point2(x * CHUNK_WIDTH, y * CHUNK_HEIGHT);
            let offset = (pt.x - origin.x + (pt.y - origin.y) * CHUNK_WIDTH) as usize;
            chunks
                .entry(origin)
                .or_insert_with(|| vec![0; (CHUNK_WIDTH * CHUNK_HEIGHT) as usize])[offset] = c;
        }

        // Turn chunks into ChunkMap data.
        ChunkMap(
            chunks
                .into_iter()
                .map(|(orig, data): (Point2D<_>, Vec<_>)| Chunk {
                    data,
                    width: CHUNK_WIDTH as u32,
                    height: CHUNK_HEIGHT as u32,
                    x: orig.x,
                    y: orig.y,
                })
                .collect(),
        )
    }
}

impl ChunkMap {
    /// Iterate the nonzero points in a chunk map
    pub fn iter(&self) -> impl Iterator<Item = (Point2D<i32>, u32)> + '_ {
        let mut i = 0;
        let mut p = 0;
        iter::from_fn(move || {
            if i < self.0.len() && p >= self.0[i].data.len() {
                i += 1;
                p = 0;
            }
            if i >= self.0.len() {
                return None;
            }

            let chunk = &self.0[i];
            let pitch = chunk.width as i32;
            let offset = p as i32;
            let ret = (
                point2(chunk.x + offset % pitch, chunk.y + offset / pitch),
                chunk.data[p],
            );
            p += 1;
            Some(ret)
        })
        .filter(|(_, t)| *t != 0)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Layer {
    #[serde(rename = "tilelayer")]
    TileLayer {
        x: i32,
        y: i32,
        width: u32,
        height: u32,
        opacity: f32,
        name: String,
        id: u32,
        visible: bool,

        #[serde(skip_serializing_if = "Option::is_none")]
        chunks: Option<ChunkMap>,
        #[serde(skip_serializing_if = "Option::is_none")]
        data: Option<Vec<u32>>,
        // Not supported: compression, encoding
    },
    #[serde(rename = "objectgroup")]
    ObjectGroup {
        x: i32,
        y: i32,
        opacity: f32,
        name: String,
        id: u32,
        visible: bool,

        draworder: String,
        objects: Vec<Object>,
    },
    // Not supported: imagelayer, group
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Object {
    #[serde(rename = "type")]
    pub type_: String,
    pub gid: u32,
    pub id: u32,
    pub name: String,
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
    pub rotation: f32,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Tileset {
    pub columns: u32,
    pub tilecount: u32,
    pub tileheight: u32,
    pub tilewidth: u32,
    pub spacing: u32,
    pub firstgid: u32,
    pub image: PathBuf,
    pub imageheight: u32,
    pub imagewidth: u32,
    pub margin: u32,
    pub name: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum MapProperty {
    #[serde(rename = "boolean")]
    Boolean { name: String, value: bool },
    #[serde(rename = "color")]
    Color {
        name: String,
        value: String, // TODO: Deserialize to colory type from "#rrggbbaa"
    },
    #[serde(rename = "file")]
    File { name: String, value: PathBuf },
    #[serde(rename = "float")]
    Float { name: String, value: f64 },
    #[serde(rename = "int")]
    Int { name: String, value: i32 },
    #[serde(rename = "string")]
    String { name: String, value: String },
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Map {
    #[serde(rename = "type")]
    pub type_: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub backgroundcolor: Option<String>,
    pub width: u32,
    pub height: u32,
    pub layers: Vec<Layer>,
    pub infinite: bool,
    pub nextlayerid: u32,
    pub nextobjectid: u32,
    pub orientation: Orientation,
    pub properties: Vec<MapProperty>,
    pub renderorder: String,
    pub tiledversion: String,
    pub tileheight: u32,
    pub tilewidth: u32,
    pub version: f32,
    pub tilesets: Vec<Tileset>,
}
<|endoftext|>


<commit_before>//! # C API for rav1e
//!
//! [rav1e](https://github.com/xiph/rav1e/) is an [AV1](https://aomediacodec.github.io/av1-spec/)
//! encoder written in [Rust](https://rust-lang.org)
//!
//! This is the C-compatible API to it

extern crate rav1e;

use std::slice;
use std::sync::Arc;

use std::ffi::CStr;
use std::os::raw::c_char;
use std::os::raw::c_int;

/// Raw video Frame
///
/// It can be allocated throught rav1e_frame_new(), populated using rav1e_frame_fill_plane()
/// and freed using rav1e_frame_drop().
pub struct RaFrame(Arc<rav1e::Frame>);

pub struct RaConfig {
    cfg: rav1e::Config,
    last_err: Option<rav1e::EncoderStatus>,
}

pub struct RaContext {
    ctx: rav1e::Context,
    last_err: Option<rav1e::EncoderStatus>,
}

type RaFrameType = rav1e::FrameType;

#[repr(C)]
pub struct RaPacket {
    pub data: *const u8,
    pub len: usize,
    pub number: u64,
    pub frame_type: RaFrameType,
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_default(
    width: usize,
    height: usize,
    bit_depth: usize,
    chroma_sampling: rav1e::ChromaSampling,
    timebase: rav1e::Ratio,
) -> *mut RaConfig {
    let cfg = rav1e::Config {
        frame_info: rav1e::FrameInfo {
            width,
            height,
            bit_depth,
            chroma_sampling,
        },
        timebase,
        enc: Default::default(),
    };

    let c = Box::new(RaConfig {
        cfg,
        last_err: None,
    });

    Box::into_raw(c)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_drop(cfg: *mut RaConfig) {
    let _ = Box::from_raw(cfg);
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse(
    cfg: *mut RaConfig,
    key: *const c_char,
    value: *const c_char,
) -> c_int {
    let key = CStr::from_ptr(key).to_string_lossy();
    let value = CStr::from_ptr(value).to_string_lossy();

    (*cfg)
        .cfg
        .parse(&key, &value)
        .map(|_v| {
            (*cfg).last_err = None;
            0
        }).map_err(|e| (*cfg).last_err = Some(e))
        .unwrap_or(-1)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_context_new(cfg: *const RaConfig) -> *mut RaContext {
    let ctx = RaContext {
        ctx: (*cfg).cfg.new_context(),
        last_err: None,
    };

    Box::into_raw(Box::new(ctx))
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_context_drop(ctx: *mut RaContext) {
    let _ = Box::from_raw(ctx);
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_new(ctx: *const RaContext) -> *mut RaFrame {
    let f = (*ctx).ctx.new_frame();
    let frame = Box::new(RaFrame(f));

    Box::into_raw(frame)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_drop(ctx: *mut RaFrame) {
    let _ = Arc::from_raw(ctx);
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_send_frame(ctx: *mut RaContext, frame: *const RaFrame) -> c_int {
    let frame = if frame.is_null() {
        None
    } else {
        Some((*frame).0.clone())
    };

    (*ctx)
        .ctx
        .send_frame(frame)
        .map(|_v| {
            (*ctx).last_err = None;
            0
        }).map_err(|e| (*ctx).last_err = Some(e))
        .unwrap_or(-1)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_receive_packet(
    ctx: *mut RaContext,
    pkt: *mut *mut RaPacket,
) -> c_int {
    (*ctx)
        .ctx
        .receive_packet()
        .map(|p| {
            (*ctx).last_err = None;
            let packet = RaPacket {
                data: p.data.as_ptr(),
                len: p.data.len(),
                number: p.number,
                frame_type: p.frame_type,
            };
            *pkt = Box::into_raw(Box::new(packet));
            0
        }).map_err(|e| (*ctx).last_err = Some(e))
        .unwrap_or(-1)
}

#[no_mangle]
pub unsafe extern fn rav1e_packet_drop(pkt: *mut RaPacket) {
    let _ = Box::from_raw(pkt);
}

#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header(ctx: *mut RaContext, len: *mut usize) -> *mut u8 {
    let buf = (*ctx).ctx.container_sequence_header();

    *len = buf.len();
    Box::into_raw(buf.into_boxed_slice()) as *mut u8
}

pub unsafe extern fn rav1e_container_sequence_header_drop(sequence: *mut u8) {
    let _ = Box::from_raw(sequence);
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_fill_plane(
    frame: *mut RaFrame,
    plane: usize,
    data: *const u8,
    data_len: usize,
    stride: usize,
    bytewidth: usize,
) {
    let input = Arc::get_mut(&mut (*frame).0).unwrap();
    let data_slice = slice::from_raw_parts(data, data_len);

    input.planes[plane].copy_from_raw_u8(data_slice, stride, bytewidth);
}
<commit_msg>crav1e: wip: Update the documentation and use cbindgen.toml<commit_after>//! # C API for rav1e
//!
//! [rav1e](https://github.com/xiph/rav1e/) is an [AV1](https://aomediacodec.github.io/av1-spec/)
//! encoder written in [Rust](https://rust-lang.org)
//!
//! This is the C-compatible API to it

extern crate rav1e;

use std::slice;
use std::sync::Arc;

use std::ffi::CStr;
use std::os::raw::c_char;
use std::os::raw::c_int;

/// Raw video Frame
///
/// It can be allocated throught rav1e_frame_new(), populated using rav1e_frame_fill_plane()
/// and freed using rav1e_frame_drop().
pub struct Frame(Arc<rav1e::Frame>);

type EncoderStatus=rav1e::EncoderStatus;

/// Encoder configuration
///
/// Instantiate it using rav1e_config_default() and fine-tune it using
/// rav1e_config_parse().
///
/// Use rav1e_config_drop() to free its memory.
pub struct Config {
    cfg: rav1e::Config,
    last_err: Option<EncoderStatus>,
}

/// Encoder context
///
/// Contains the encoding state, it is created by rav1e_context_new() using an
/// Encoder configuration.
///
/// Use rav1e_context_drop() to free its memory.
pub struct Context {
    ctx: rav1e::Context,
    last_err: Option<EncoderStatus>,
}

type FrameType = rav1e::FrameType;

/// Encoded Packet
///
/// The encoded packets are retrieved using rav1e_receive_packet().
///
/// Use rav1e_packet_drop() to free its memory.
#[repr(C)]
pub struct Packet {
    /// Encoded data buffer
    pub data: *const u8,
    /// Encoded data buffer size
    pub len: usize,
    /// Frame sequence number
    pub number: u64,
    /// Frame type
    pub frame_type: FrameType,
}

type ChromaSampling=rav1e::ChromaSampling;
type Ratio=rav1e::Ratio;

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_default(
    width: usize,
    height: usize,
    bit_depth: usize,
    chroma_sampling: ChromaSampling,
    timebase: Ratio,
) -> *mut Config {
    let cfg = rav1e::Config {
        frame_info: rav1e::FrameInfo {
            width,
            height,
            bit_depth,
            chroma_sampling,
        },
        timebase,
        enc: Default::default(),
    };

    let c = Box::new(Config {
        cfg,
        last_err: None,
    });

    Box::into_raw(c)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_drop(cfg: *mut Config) {
    let _ = Box::from_raw(cfg);
}

/// Set a configuration parameter using its key and value
///
/// Available keys and values
/// - "quantizer": 0-255, default 100
/// - "speed": 0-10, default 3
/// - "tune": "psnr"-"psychovisual", default "psnr"
///
/// Returns a negative value on non-zero.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse(
    cfg: *mut Config,
    key: *const c_char,
    value: *const c_char,
) -> c_int {
    let key = CStr::from_ptr(key).to_string_lossy();
    let value = CStr::from_ptr(value).to_string_lossy();

    (*cfg)
        .cfg
        .parse(&key, &value)
        .map(|_v| {
            (*cfg).last_err = None;
            0
        }).map_err(|e| (*cfg).last_err = Some(e))
        .unwrap_or(-1)
}

/// Generate a new encoding context from a populated encoder configuration
///
/// Multiple contexts can be generated through it.
#[no_mangle]
pub unsafe extern "C" fn rav1e_context_new(cfg: *const Config) -> *mut Context {
    let ctx = Context {
        ctx: (*cfg).cfg.new_context(),
        last_err: None,
    };

    Box::into_raw(Box::new(ctx))
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_context_drop(ctx: *mut Context) {
    let _ = Box::from_raw(ctx);
}

/// Produce a new frame from the encoding context
///
/// It must be populated using rav1e_frame_fill_plane().
///
/// The frame is reference counted and must be released passing it to rav1e_frame_drop(),
/// see rav1e_send_frame().
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_new(ctx: *const Context) -> *mut Frame {
    let f = (*ctx).ctx.new_frame();
    let frame = Box::new(Frame(f));

    Box::into_raw(frame)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_drop(ctx: *mut Frame) {
    let _ = Arc::from_raw(ctx);
}

/// Send the frame for encoding
///
/// The function increases the frame internal reference count and it can be passed multiple
/// times to different rav1e_send_frame().
#[no_mangle]
pub unsafe extern "C" fn rav1e_send_frame(ctx: *mut Context, frame: *const Frame) -> c_int {
    let frame = if frame.is_null() {
        None
    } else {
        Some((*frame).0.clone())
    };

    (*ctx)
        .ctx
        .send_frame(frame)
        .map(|_v| {
            (*ctx).last_err = None;
            0
        }).map_err(|e| (*ctx).last_err = Some(e))
        .unwrap_or(-1)
}

/// Receive encoded data
#[no_mangle]
pub unsafe extern "C" fn rav1e_receive_packet(
    ctx: *mut Context,
    pkt: *mut *mut Packet,
) -> c_int {
    (*ctx)
        .ctx
        .receive_packet()
        .map(|p| {
            (*ctx).last_err = None;
            let packet = Packet {
                data: p.data.as_ptr(),
                len: p.data.len(),
                number: p.number,
                frame_type: p.frame_type,
            };
            *pkt = Box::into_raw(Box::new(packet));
            0
        }).map_err(|e| (*ctx).last_err = Some(e))
        .unwrap_or(-1)
}

#[no_mangle]
pub unsafe extern fn rav1e_packet_drop(pkt: *mut Packet) {
    let _ = Box::from_raw(pkt);
}

/// Produce a sequence header matching the current encoding context
///
/// Its format is compatible with the AV1 Matroska and ISOBMFF specification.
#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header(ctx: *mut Context, len: *mut usize) -> *mut u8 {
    let buf = (*ctx).ctx.container_sequence_header();

    *len = buf.len();
    Box::into_raw(buf.into_boxed_slice()) as *mut u8
}

pub unsafe extern fn rav1e_container_sequence_header_drop(sequence: *mut u8) {
    let _ = Box::from_raw(sequence);
}

/// Fill a frame plane
///
/// Currently the frame contains 3 frames, the first is luminance followed by
/// chrominance.
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_fill_plane(
    frame: *mut Frame,
    plane: usize,
    data: *const u8,
    data_len: usize,
    stride: usize,
    bytewidth: usize,
) {
    let input = Arc::get_mut(&mut (*frame).0).unwrap();
    let data_slice = slice::from_raw_parts(data, data_len);

    input.planes[plane].copy_from_raw_u8(data_slice, stride, bytewidth);
}
<|endoftext|>


<commit_before>//! CCID structures and types
#![allow(non_camel_case_types, non_snake_case)]

/// Generic CCID message header
#[repr(C, packed)]
pub struct Header {
    /// The message type (`bMessageType`) identifies the message.
    pub bMessageType: MessageType,

    /// The length field (`dwLength`) is the length of the message not
    /// including the 10-byte header.
    pub dwLength: u32,

    /// Identifies the slot number for this command
    ///
    /// The slot number (`bSlot`) identifies which ICC slot is being addressed
    /// by the message, if the CCID supports multiple slots. The slot number is
    /// zero-relative, and is in the range of zero to FFh.
    pub bSlot: u8,

    /// Sequence number for command
    ///
    /// The sequence number (`bSeq`) is a monotonically increasing by one
    /// counter of bulk messages sent to the CCID. Because the response to a
    /// command always uses the exact same sequence number contained in the
    /// command, the host can use the sequence number in a response message to
    /// verify that a particular response is the one expected in reply to a
    /// particular command.  This sequence number is not related to any
    /// interaction between the CCID and the ICC itself, but simply tracks the
    /// USB bulk message exchanges between the host and the CCID. The initial
    /// value of the sequence number is not important, but typically starts at
    /// zero.
    pub bSeq: u8,

    /// Reserved for Future Use
    pub abRFU: [u8; 3],
}

/// CCID message identifiers
#[repr(u8)]
pub enum MessageType {
    PC_to_RDR_IccPowerOn = 0x62,
    PC_to_RDR_IccPowerOff = 0x63,
    PC_to_RDR_GetSlotStatus = 0x65,
    PC_to_RDR_XfrBlock = 0x6F,
    PC_to_RDR_GetParameters = 0x6C,
    PC_to_RDR_ResetParameters = 0x6D,
    PC_to_RDR_SetParameters = 0x61,
    PC_to_RDR_Escape = 0x6B,
    PC_to_RDR_IccClock = 0x6E,
    PC_to_RDR_T0APDU = 0x6A,
    PC_to_RDR_Secure = 0x69,
    PC_to_RDR_Mechanical = 0x71,
    PC_to_RDR_Abort = 0x72,
    PC_to_RDR_SetDataRateAndClockFrequency = 0x73,

    RDR_to_PC_DataBlock = 0x80,
    RDR_to_PC_SlotStatus = 0x81,
    RDR_to_PC_Parameters = 0x82,
    RDR_to_PC_Escape = 0x83,
    RDR_to_PC_DataRateAndClockFrequency = 0x84,
}
<commit_msg>CCID: Add #[test] for header length<commit_after>//! CCID structures and types
#![allow(non_camel_case_types, non_snake_case)]

/// Generic CCID message header
#[repr(C, packed)]
pub struct Header {
    /// The message type (`bMessageType`) identifies the message.
    pub bMessageType: MessageType,

    /// The length field (`dwLength`) is the length of the message not
    /// including the 10-byte header.
    pub dwLength: u32,

    /// Identifies the slot number for this command
    ///
    /// The slot number (`bSlot`) identifies which ICC slot is being addressed
    /// by the message, if the CCID supports multiple slots. The slot number is
    /// zero-relative, and is in the range of zero to FFh.
    pub bSlot: u8,

    /// Sequence number for command
    ///
    /// The sequence number (`bSeq`) is a monotonically increasing by one
    /// counter of bulk messages sent to the CCID. Because the response to a
    /// command always uses the exact same sequence number contained in the
    /// command, the host can use the sequence number in a response message to
    /// verify that a particular response is the one expected in reply to a
    /// particular command.  This sequence number is not related to any
    /// interaction between the CCID and the ICC itself, but simply tracks the
    /// USB bulk message exchanges between the host and the CCID. The initial
    /// value of the sequence number is not important, but typically starts at
    /// zero.
    pub bSeq: u8,

    /// Reserved for Future Use
    pub abRFU: [u8; 3],
}

/// CCID message identifiers
#[repr(u8)]
pub enum MessageType {
    PC_to_RDR_IccPowerOn = 0x62,
    PC_to_RDR_IccPowerOff = 0x63,
    PC_to_RDR_GetSlotStatus = 0x65,
    PC_to_RDR_XfrBlock = 0x6F,
    PC_to_RDR_GetParameters = 0x6C,
    PC_to_RDR_ResetParameters = 0x6D,
    PC_to_RDR_SetParameters = 0x61,
    PC_to_RDR_Escape = 0x6B,
    PC_to_RDR_IccClock = 0x6E,
    PC_to_RDR_T0APDU = 0x6A,
    PC_to_RDR_Secure = 0x69,
    PC_to_RDR_Mechanical = 0x71,
    PC_to_RDR_Abort = 0x72,
    PC_to_RDR_SetDataRateAndClockFrequency = 0x73,

    RDR_to_PC_DataBlock = 0x80,
    RDR_to_PC_SlotStatus = 0x81,
    RDR_to_PC_Parameters = 0x82,
    RDR_to_PC_Escape = 0x83,
    RDR_to_PC_DataRateAndClockFrequency = 0x84,
}

#[cfg(test)]
mod test {
    use super::Header;
    use core::mem;

    #[test]
    fn test_ccid_header() {
        assert_eq!(mem::size_of::<Header>(), 10);
    }
}
<|endoftext|>


<commit_before>use anyhow::{anyhow, Result};
use std::collections::HashSet;
use std::path::Path;
use std::str;

use duct::cmd;
use git2::{Config, Repository};
use log::{debug, trace, warn};

/// Update old `req.key` config format to include remote name, i.e, `req.remote_name.key`
fn migrate_legacy(field_name: &str, remote_name: &str) {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();

    if let Ok(ref value) = cfg.get_string(&format!("req.{}", field_name)) {
        cfg.set_str(&format!("req.{}.{}", remote_name, field_name), value)
            .unwrap();
        cfg.remove(&format!("req.{}", field_name)).unwrap();
    }
}

/// Convert a domain string into a configuration slug
fn slugify_domain(domain: &str) -> String {
    str::replace(domain, ".", "|")
}

/// Get the remotes for the repository
pub fn get_remotes() -> HashSet<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    match repo.remotes() {
        Ok(remotes) => remotes
            .into_iter()
            .filter_map(|rem| rem)
            .map(String::from)
            .collect(),
        Err(_) => HashSet::new(),
    }
}

/// Get the URL of the given remote
pub fn get_remote_url(remote: &str) -> String {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let remote = repo.find_remote(remote).expect("Couldn't find the remote");
    String::from(remote.url().unwrap())
}

/// Get a value fom the repository config
pub fn get_repo_info(repo_field: &str) -> Result<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let cfg = repo.config().unwrap();
    cfg.get_string(repo_field)
        .or_else(|err| Err(anyhow!(err.to_string())))
}

/// Get a value for the given project-local git-req config
pub fn get_config(field_name: &str, remote_name: &str) -> Option<String> {
    migrate_legacy(field_name, "origin");
    let key = format!("req.{}.{}", remote_name, field_name);
    match get_repo_info(&key) {
        Ok(val) => Some(val),
        Err(_) => None,
    }
}

/// Set a value for the project remote-local git-req configuration
pub fn set_config(field_name: &str, remote_name: &str, value: &str) {
    migrate_legacy(field_name, "origin");
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.set_str(&format!("req.{}.{}", remote_name, field_name), value)
        .unwrap();
}

/// Delete the entry for the project-local git-req config field with the provided name
pub fn delete_config(field_name: &str, remote_name: &str) {
    migrate_legacy(field_name, "origin");
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.remove(&format!("req.{}.{}", remote_name, field_name))
        .unwrap();
}

/// Get a value for the given project-local git-req config
pub fn get_project_config(field_name: &str) -> Option<String> {
    let key = format!("req.{}", field_name);
    match get_repo_info(&key) {
        Ok(val) => Some(val),
        Err(_) => None,
    }
}

/// Set a value for the project-local git-req configuration. Consider using `set_config` unless
/// absolutely necessary.
pub fn set_project_config(field_name: &str, value: &str) {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.set_str(&format!("req.{}", field_name), value).unwrap();
}

/// Get a value for the given global git-req config
pub fn get_req_config(domain: &str, field: &str) -> Option<String> {
    let slug = slugify_domain(domain);
    let cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    match cfg.get_string(&format!("req.{}.{}", slug, field)) {
        Ok(val) => Some(val),
        Err(_) => None,
    }
}

/// Set a value for the global git-req configuration
pub fn set_req_config(domain: &str, field: &str, value: &str) {
    let slug = slugify_domain(domain);
    let mut cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    cfg.set_str(&format!("req.{}.{}", slug, field), value)
        .unwrap();
}

/// Clear the value for the lobal git-req configuration
pub fn delete_req_config(domain: &str, field: &str) -> Result<(), git2::Error> {
    let slug = slugify_domain(domain);
    let mut cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    cfg.remove(&format!("req.{}.{}", slug, field))
}

/// Guess the name of the default remote
pub fn guess_default_remote_name() -> Result<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let remotes = repo.remotes().expect("Couldn't fetch the list of remotes");
    match remotes.len() {
        0 => panic!("Could not find any remotes"),
        1 => Ok(String::from(remotes.get(0).unwrap())),
        _ => match repo.find_remote("origin") {
            Ok(_) => Ok(String::from("origin")),
            Err(_) => Err(anyhow!("No origin remote found")),
        },
    }
}

/// Check out a branch by name
pub fn checkout_branch(
    remote_name: &str,
    remote_branch_name: &str,
    local_branch_name: &str,
    is_virtual_remote_branch: bool,
) -> Result<()> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let local_branch_name = match get_project_config("defaultremote") {
        Some(default_remote_name) => {
            if remote_name != default_remote_name {
                trace!("Non-default remote name requested: {}", remote_name);
                format!("req/{}/{}", remote_name, local_branch_name)
            } else {
                trace!("Default remote name requested: {}", remote_name);
                String::from(local_branch_name)
            }
        }
        None => {
            warn!("No default remote found. Using {}", remote_name);
            format!("{}/{}", remote_name, local_branch_name)
        }
    };

    let local_branch_exists = repo.revparse_single(&local_branch_name);
    match local_branch_exists {
        Ok(_) => {
            debug!("Checking out branch: {}", local_branch_name);
            match cmd!("git", "checkout", &local_branch_name).run() {
                Ok(_) => Ok(()),
                Err(err) => Err(anyhow!("Could not check out local branch: {}", err)),
            }
        }
        Err(_) => {
            // Fetch the remote branch if there's no local branch with the correct name
            let mut fetch_args = vec!["fetch", &remote_name];
            let remote_to_local_binding = format!("{}:{}", remote_branch_name, local_branch_name);
            fetch_args.push(if is_virtual_remote_branch {
                &remote_to_local_binding
            } else {
                &remote_branch_name
            });
            if cmd("git", fetch_args).run().is_err() {
                return Err(anyhow!(
                    "Could not fetch remote branch '{}'",
                    remote_branch_name
                ));
            };
            debug!("Checking out branch: {}", local_branch_name);
            let mut checkout_args = vec!["checkout"];
            let origin_with_remote = format!("{}/{}", remote_name, remote_branch_name);
            if is_virtual_remote_branch {
                checkout_args.push(&local_branch_name);
                trace!("Checking out branch: {}", local_branch_name);
            } else {
                checkout_args.push("-b");
                checkout_args.push(&local_branch_name);
                checkout_args.push(&origin_with_remote);
                trace!(
                    "Checking '{}' as '{}'",
                    origin_with_remote,
                    local_branch_name
                );
            };
            match cmd("git", checkout_args).run() {
                Ok(_) => Ok(()),
                Err(err) => Err(anyhow!("Could not check out local branch: {}", err)),
            }
        }
    }
}
<commit_msg>Replace Result-to-Option mappings with .ok()<commit_after>use anyhow::{anyhow, Result};
use std::collections::HashSet;
use std::path::Path;
use std::str;

use duct::cmd;
use git2::{Config, Repository};
use log::{debug, trace, warn};

/// Update old `req.key` config format to include remote name, i.e, `req.remote_name.key`
fn migrate_legacy(field_name: &str, remote_name: &str) {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();

    if let Ok(ref value) = cfg.get_string(&format!("req.{}", field_name)) {
        cfg.set_str(&format!("req.{}.{}", remote_name, field_name), value)
            .unwrap();
        cfg.remove(&format!("req.{}", field_name)).unwrap();
    }
}

/// Convert a domain string into a configuration slug
fn slugify_domain(domain: &str) -> String {
    str::replace(domain, ".", "|")
}

/// Get the remotes for the repository
pub fn get_remotes() -> HashSet<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    match repo.remotes() {
        Ok(remotes) => remotes
            .into_iter()
            .filter_map(|rem| rem)
            .map(String::from)
            .collect(),
        Err(_) => HashSet::new(),
    }
}

/// Get the URL of the given remote
pub fn get_remote_url(remote: &str) -> String {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let remote = repo.find_remote(remote).expect("Couldn't find the remote");
    String::from(remote.url().unwrap())
}

/// Get a value fom the repository config
pub fn get_repo_info(repo_field: &str) -> Result<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let cfg = repo.config().unwrap();
    cfg.get_string(repo_field)
        .or_else(|err| Err(anyhow!(err.to_string())))
}

/// Get a value for the given project-local git-req config
pub fn get_config(field_name: &str, remote_name: &str) -> Option<String> {
    migrate_legacy(field_name, "origin");
    let key = format!("req.{}.{}", remote_name, field_name);
    get_repo_info(&key).ok()
}

/// Set a value for the project remote-local git-req configuration
pub fn set_config(field_name: &str, remote_name: &str, value: &str) {
    migrate_legacy(field_name, "origin");
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.set_str(&format!("req.{}.{}", remote_name, field_name), value)
        .unwrap();
}

/// Delete the entry for the project-local git-req config field with the provided name
pub fn delete_config(field_name: &str, remote_name: &str) {
    migrate_legacy(field_name, "origin");
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.remove(&format!("req.{}.{}", remote_name, field_name))
        .unwrap();
}

/// Get a value for the given project-local git-req config
pub fn get_project_config(field_name: &str) -> Option<String> {
    let key = format!("req.{}", field_name);
    get_repo_info(&key).ok()
}

/// Set a value for the project-local git-req configuration. Consider using `set_config` unless
/// absolutely necessary.
pub fn set_project_config(field_name: &str, value: &str) {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let mut cfg = repo.config().unwrap();
    cfg.set_str(&format!("req.{}", field_name), value).unwrap();
}

/// Get a value for the given global git-req config
pub fn get_req_config(domain: &str, field: &str) -> Option<String> {
    let slug = slugify_domain(domain);
    let cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    cfg.get_string(&format!("req.{}.{}", slug, field)).ok()
}

/// Set a value for the global git-req configuration
pub fn set_req_config(domain: &str, field: &str, value: &str) {
    let slug = slugify_domain(domain);
    let mut cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    cfg.set_str(&format!("req.{}.{}", slug, field), value)
        .unwrap();
}

/// Clear the value for the lobal git-req configuration
pub fn delete_req_config(domain: &str, field: &str) -> Result<(), git2::Error> {
    let slug = slugify_domain(domain);
    let mut cfg = Config::open(&Path::new(
        &shellexpand::tilde("~/.gitreqconfig").to_string(),
    ))
    .unwrap();
    cfg.remove(&format!("req.{}.{}", slug, field))
}

/// Guess the name of the default remote
pub fn guess_default_remote_name() -> Result<String> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let remotes = repo.remotes().expect("Couldn't fetch the list of remotes");
    match remotes.len() {
        0 => panic!("Could not find any remotes"),
        1 => Ok(String::from(remotes.get(0).unwrap())),
        _ => match repo.find_remote("origin") {
            Ok(_) => Ok(String::from("origin")),
            Err(_) => Err(anyhow!("No origin remote found")),
        },
    }
}

/// Check out a branch by name
pub fn checkout_branch(
    remote_name: &str,
    remote_branch_name: &str,
    local_branch_name: &str,
    is_virtual_remote_branch: bool,
) -> Result<()> {
    let repo = Repository::open_from_env().expect("Couldn't find repository");
    let local_branch_name = match get_project_config("defaultremote") {
        Some(default_remote_name) => {
            if remote_name != default_remote_name {
                trace!("Non-default remote name requested: {}", remote_name);
                format!("req/{}/{}", remote_name, local_branch_name)
            } else {
                trace!("Default remote name requested: {}", remote_name);
                String::from(local_branch_name)
            }
        }
        None => {
            warn!("No default remote found. Using {}", remote_name);
            format!("{}/{}", remote_name, local_branch_name)
        }
    };

    let local_branch_exists = repo.revparse_single(&local_branch_name);
    match local_branch_exists {
        Ok(_) => {
            debug!("Checking out branch: {}", local_branch_name);
            match cmd!("git", "checkout", &local_branch_name).run() {
                Ok(_) => Ok(()),
                Err(err) => Err(anyhow!("Could not check out local branch: {}", err)),
            }
        }
        Err(_) => {
            // Fetch the remote branch if there's no local branch with the correct name
            let mut fetch_args = vec!["fetch", &remote_name];
            let remote_to_local_binding = format!("{}:{}", remote_branch_name, local_branch_name);
            fetch_args.push(if is_virtual_remote_branch {
                &remote_to_local_binding
            } else {
                &remote_branch_name
            });
            if cmd("git", fetch_args).run().is_err() {
                return Err(anyhow!(
                    "Could not fetch remote branch '{}'",
                    remote_branch_name
                ));
            };
            debug!("Checking out branch: {}", local_branch_name);
            let mut checkout_args = vec!["checkout"];
            let origin_with_remote = format!("{}/{}", remote_name, remote_branch_name);
            if is_virtual_remote_branch {
                checkout_args.push(&local_branch_name);
                trace!("Checking out branch: {}", local_branch_name);
            } else {
                checkout_args.push("-b");
                checkout_args.push(&local_branch_name);
                checkout_args.push(&origin_with_remote);
                trace!(
                    "Checking '{}' as '{}'",
                    origin_with_remote,
                    local_branch_name
                );
            };
            match cmd("git", checkout_args).run() {
                Ok(_) => Ok(()),
                Err(err) => Err(anyhow!("Could not check out local branch: {}", err)),
            }
        }
    }
}
<|endoftext|>