<commit_before>extern crate iron;
extern crate oven;
extern crate cookie;

use iron::prelude::*;
use iron::middleware;
use oven::prelude::*;

pub struct LoginManager {
    signing_key: Vec<u8>
}

impl LoginManager {
    pub fn new(signing_key: Vec<u8>) -> LoginManager {
        LoginManager { signing_key: signing_key }
    }
}

impl middleware::AroundMiddleware for LoginManager {
    fn around(self, handler: Box<middleware::Handler>) -> Box<middleware::Handler> {
        let mut ch = Chain::new(handler);
        let key = self.signing_key;

        ch.link(oven::new(key.clone()));

        Box::new(ch)
    }
}

pub trait User: Send + Sync + Sized {
    fn from_username(request: &mut Request, username: &str) -> Option<Self>;
    fn get_username(&self) -> &str;

    fn from_request(request: &mut Request) -> Option<Self> {
        let value = match request.get_cookie("logged_in_user") {
            Some(x) => x.value.clone(),
            None => return None
        };
        Self::from_username(request, &value[..])
    }

    fn log_in_on(&self, response: &mut Response) {
        response.set_cookie(cookie::Cookie::new("logged_in_user".to_owned(), self.get_username().to_owned()));
    }

    fn log_in(self) -> LoginModifier<Self> { LoginModifier { user: self } }
}

pub struct LoginModifier<U: User> { user: U }
impl<U: User> iron::modifier::Modifier<Response> for LoginModifier<U> {
    fn modify(self, response: &mut Response) { self.user.log_in_on(response) }
}

pub fn log_out_of(response: &mut Response) {
    response.get_mut::<oven::ResponseCookies>().unwrap().remove("logged_in_user");
}

pub fn log_out() -> LogoutModifier { LogoutModifier }

pub struct LogoutModifier;
impl iron::modifier::Modifier<Response> for LogoutModifier {
    fn modify(self, response: &mut Response) { log_out_of(response) }
}
<commit_msg>Apply user session for all paths<commit_after>extern crate iron;
extern crate oven;
extern crate cookie;

use iron::prelude::*;
use iron::middleware;
use oven::prelude::*;

pub struct LoginManager {
    signing_key: Vec<u8>
}

impl LoginManager {
    pub fn new(signing_key: Vec<u8>) -> LoginManager {
        LoginManager { signing_key: signing_key }
    }
}

impl middleware::AroundMiddleware for LoginManager {
    fn around(self, handler: Box<middleware::Handler>) -> Box<middleware::Handler> {
        let mut ch = Chain::new(handler);
        let key = self.signing_key;

        ch.link(oven::new(key.clone()));

        Box::new(ch)
    }
}

pub trait User: Send + Sync + Sized {
    fn from_username(request: &mut Request, username: &str) -> Option<Self>;
    fn get_username(&self) -> &str;

    fn from_request(request: &mut Request) -> Option<Self> {
        let value = match request.get_cookie("logged_in_user") {
            Some(x) => x.value.clone(),
            None => return None
        };
        Self::from_username(request, &value[..])
    }

    fn log_in_on(&self, response: &mut Response) {
        response.set_cookie({
            let mut x = cookie::Cookie::new("logged_in_user".to_owned(), self.get_username().to_owned());
            x.path = None;
            x
        });
    }

    fn log_in(self) -> LoginModifier<Self> { LoginModifier { user: self } }
}

pub struct LoginModifier<U: User> { user: U }
impl<U: User> iron::modifier::Modifier<Response> for LoginModifier<U> {
    fn modify(self, response: &mut Response) { self.user.log_in_on(response) }
}

pub fn log_out_of(response: &mut Response) {
    response.get_mut::<oven::ResponseCookies>().unwrap().remove("logged_in_user");
}

pub fn log_out() -> LogoutModifier { LogoutModifier }

pub struct LogoutModifier;
impl iron::modifier::Modifier<Response> for LogoutModifier {
    fn modify(self, response: &mut Response) { log_out_of(response) }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use config::Config;
use std::process::Command;

pub struct GitTogether<C: Config> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_authors(&mut self, inits: &[&str]) {
    let domain = self.config.get("domain").unwrap();
    for init in inits {
      let raw = self.config.get(&format!("authors.{}", init)).unwrap();
      let mut split = raw.split(';');
      let name = split.next().unwrap().trim();
      let local_part = split.next().unwrap().trim();
      let email = format!("{}@{}", local_part, domain);

      self.config.set("author-name", name).unwrap();
      self.config.set("author-email", &email).unwrap();
    }
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> &'a mut Command {
    let author_name = self.config.get("author-name").unwrap();
    let author_email = self.config.get("author-email").unwrap();
    cmd.env("GIT_AUTHOR_NAME", author_name)
      .env("GIT_AUTHOR_EMAIL", author_email)
      .arg("--signoff")
  }
}

#[derive(Clone)]
pub struct Author {}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn set_authors() {
    let data = vec![
      ("domain", "rocinante.com"),
      ("authors.jh", "James Holden; jholden"),
      ("authors.nn", "Naomi Nagata; nnagata"),
    ]
      .iter()
      .map(|&(k, v)| (k.into(), v.into()))
      .collect();
    let config = MockConfig { data: RefCell::new(data) };
    let mut gt = GitTogether { config: config };

    gt.set_authors(&["jh"]);

    assert_eq!(gt.config.get("author-name").unwrap(),
               "James Holden".to_string());
    assert_eq!(gt.config.get("author-email").unwrap(),
               "jholden@rocinante.com".to_string());
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data.borrow().get(name.into()).cloned().ok_or("".into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<commit_msg>remove trait bound from GitTogether struct<commit_after>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use config::Config;
use std::process::Command;

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_authors(&mut self, inits: &[&str]) {
    let domain = self.config.get("domain").unwrap();
    for init in inits {
      let raw = self.config.get(&format!("authors.{}", init)).unwrap();
      let mut split = raw.split(';');
      let name = split.next().unwrap().trim();
      let local_part = split.next().unwrap().trim();
      let email = format!("{}@{}", local_part, domain);

      self.config.set("author-name", name).unwrap();
      self.config.set("author-email", &email).unwrap();
    }
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> &'a mut Command {
    let author_name = self.config.get("author-name").unwrap();
    let author_email = self.config.get("author-email").unwrap();
    cmd.env("GIT_AUTHOR_NAME", author_name)
      .env("GIT_AUTHOR_EMAIL", author_email)
      .arg("--signoff")
  }
}

#[derive(Clone)]
pub struct Author {}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn set_authors() {
    let data = vec![
      ("domain", "rocinante.com"),
      ("authors.jh", "James Holden; jholden"),
      ("authors.nn", "Naomi Nagata; nnagata"),
    ]
      .iter()
      .map(|&(k, v)| (k.into(), v.into()))
      .collect();
    let config = MockConfig { data: RefCell::new(data) };
    let mut gt = GitTogether { config: config };

    gt.set_authors(&["jh"]);

    assert_eq!(gt.config.get("author-name").unwrap(),
               "James Holden".to_string());
    assert_eq!(gt.config.get("author-email").unwrap(),
               "jholden@rocinante.com".to_string());
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data.borrow().get(name.into()).cloned().ok_or("".into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<|endoftext|>


<commit_before>/*!
```
extern crate hertz;
extern crate mel;

fn main() {
    let sample_rate = 44100;
    let window_size = 4096;
    let power_spectrum_size = window_size / 2;
    let filter_count = 100;

    for (row, col, value) in mel::enumerate_mel_scaling_matrix(
        sample_rate,
        window_size,
        power_spectrum_size,
        filter_count,
    ) {

    }
}
```
*/

use std::ops::{Add, Sub, Mul, Div, IndexMut, Range};
use std::cmp::{PartialOrd};

#[macro_use]
extern crate nalgebra;
use nalgebra::ApproxEq;

extern crate num;
use num::{Float, Zero, NumCast, ToPrimitive, FromPrimitive};

extern crate hertz;
extern crate apodize;

extern crate itertools;
use itertools::linspace;

macro_rules! f64_from_usize {
    ($val:expr) => {
        <f64>::from_usize($val)
            .expect("type `f64` can't represent a specific value of type `usize` on this architecture.");
    }
}

macro_rules! usize_from_f64 {
    ($val:expr) => {
        <usize>::from_f64($val)
            .expect("type `usize` can't represent a specific value of type `f64` on this architecture.");
    }
}

#[inline]
pub fn hertz_from_mel(mel: f64) -> f64 {
    700. * ((10.).powf(mel / 2595.) - 1.)
}

#[inline]
pub fn mel_from_hertz(hertz: f64) -> f64 {
    2595. * (1. + hertz / 700.).log10()
}

#[test]
fn test_mel() {
    assert_approx_eq_eps!(
        549.64, mel_from_hertz(440.), 0.01);
    assert_approx_eq_eps!(
        440., hertz_from_mel(549.64), 0.01);

    let mel = 0.;
    assert_approx_eq!(mel, mel_from_hertz(hertz_from_mel(mel)));
    let mel = 100.;
    assert_approx_eq_eps!(
        mel, mel_from_hertz(hertz_from_mel(mel)), 0.0001);
    let mel = 3000.;
    assert_approx_eq_eps!(
        mel, mel_from_hertz(hertz_from_mel(mel)), 0.0001);

    let hertz = 0.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
    let hertz = 1000.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
    let hertz = 44100. / 2.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
}

/// col index changes fastest
pub struct MelScalingMatrixEnumerator<WindowIter> {
    // parameters

    /// equivalent to col count
    input_size: usize,
    /// equivalent to row count
    output_size: usize,

    mel_from_hertz: fn(f64) -> f64,
    hertz_from_mel: fn(f64) -> f64,

    window_function: fn(usize) -> WindowIter,

    // state

    row_index: usize,
    col_index: usize,

    start_mels_iter: itertools::Linspace<f64>,
    end_mels_iter: itertools::Linspace<f64>,

    // this gets set anew for every row
    window_start: usize,
    window_size: usize,
    window_iter: WindowIter
}

impl<WindowIter> MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    #[inline]
    pub fn is_done(&self) -> bool {
        self.is_at_end_of_row() && self.is_at_end_of_col()
    }

    #[inline]
    pub fn is_at_end_of_col(&self) -> bool {
        self.output_size <= self.row_index
    }

    #[inline]
    pub fn is_at_end_of_row(&self) -> bool {
        self.input_size <= self.col_index
    }

    #[inline]
    pub fn index(&self) -> usize {
        self.row_index * self.input_size + self.col_index
    }

    #[inline]
    pub fn remaining(&self) -> usize {
        // TODO is this off by one ?
        self.len() - self.index()
    }
}

impl<WindowIter> Iterator for MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    type Item = (usize, usize, f64);

    #[inline]
    fn next(&mut self) -> Option<(usize, usize, f64)> {
        if self.is_done() {
            return None;
        }
        if self.is_at_end_of_row() {
            self.col_index = 0;
            self.row_index += 1;
            // TODO new window iterator...
            return Some((self.row_index, self.col_index, 0.));
        }

        let col = self.col_index;

        self.col_index += 1;
        Some((self.row_index, col, 0.))
    }

        // // iterate row in outer loop (slow)
        // // iterate col in inner loop (fast)
        // // fill matrix with zeros
        // for i_row in 0..output_size {
        //     for i_col in 0..input_size {
        //         matrix[(i_row, i_col)] = T::zero();
        //     }
        // }
        //
        //
        // for (i_mel, (start_mel, end_mel)) in start_mels_iter
        //     .zip(end_mels_iter)
        //     .enumerate()
        // {
        //     let start_hertz = hertz_from_mel(start_mel) as usize;
        //     let end_hertz = hertz_from_mel(end_mel) as usize;
        //     assert!(start_hertz < end_hertz);
        //     let window_size = end_hertz - start_hertz;
        //     assert!(0 < window_size);
        //     let window_iter = window_function(window_size);
        //     for (ifreq, factor) in window_iter.enumerate() {
        //         matrix[(imel, ifreq)] = factor / window_size;
        //     }
        // }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.remaining();
        (remaining, Some(remaining))
    }
}

impl<WindowIter> ExactSizeIterator for MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    #[inline]
    fn len(&self) -> usize {
        self.input_size * self.output_size
    }
}

/// (or many vectors at once in form of a matrix)
/// to transform that vector into mel space.
/// efficiently
/// rows are mel
/// cols are freq
/// TODO get frequency index pair for nth mel
/// TODO enumerate scaling vector
/// TODO which dimension first
pub fn enumerate_mel_scaling_matrix_base<WindowIter>(
    // TODO more descriptive argument names
    min_hertz: f64,
    max_hertz: f64,
    // TODO shape
    input_size: usize,
    output_size: usize,
    mel_from_hertz: fn(f64) -> f64,
    hertz_from_mel: fn(f64) -> f64,
    window_function: fn(usize) -> WindowIter
) -> MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    assert!(min_hertz < max_hertz);
    assert!(output_size < input_size);
    assert!(0 < output_size);
    assert!(0 < input_size);

    let min_mel = mel_from_hertz(min_hertz);
    let max_mel = mel_from_hertz(max_hertz);

    let mut start_mels_iter = linspace(min_mel, max_mel, output_size);
    let mut end_mels_iter = linspace(max_mel, max_mel, output_size);
    end_mels_iter.next();

    let start_mel = start_mels_iter.next().unwrap();
    let end_mel = end_mels_iter.next().unwrap();

    let start_hertz = hertz_from_mel(start_mel);
    let end_hertz = hertz_from_mel(end_mel);

    // TODO maybe round or floor or ceil here
    let start_index = usize_from_f64!(
        start_hertz / max_hertz * f64_from_usize!(output_size));

    let end_index = usize_from_f64!(
        end_hertz / max_hertz * f64_from_usize!(output_size));

    let window_size = end_index - start_index;

    let window_iter = window_function(window_size);

    MelScalingMatrixEnumerator::<WindowIter> {
        // parameters
        input_size: input_size,
        output_size: output_size,
        window_function: window_function,
        hertz_from_mel: hertz_from_mel,
        mel_from_hertz: mel_from_hertz,

        // state
        row_index: 0,
        col_index: 0,

        start_mels_iter: start_mels_iter,
        end_mels_iter: end_mels_iter,

        window_start: start_index,
        window_size: window_size,
        window_iter: window_iter,
    }
}

/// one filter per row
pub fn enumerate_mel_scaling_matrix(
    sample_rate: usize,
    window_size: usize,
    input_size: usize,
    output_size: usize,
) -> MelScalingMatrixEnumerator<apodize::TriangularWindowIter>
{
    enumerate_mel_scaling_matrix_base(
        hertz::rayleigh(
            f64_from_usize!(sample_rate),
            f64_from_usize!(window_size)),
        hertz::nyquist(f64_from_usize!(sample_rate)),
        input_size,
        output_size,
        mel_from_hertz,
        hertz_from_mel,
        apodize::triangular_iter
    )
}

// TODO test that identity matrix with
// output_size = input_size
// and conversion functions = identity

// TODO test in a small scale that scaling matrixes are correct
// then test it in emir directly and check correctness visually
<commit_msg>more work<commit_after>/*!
```
extern crate hertz;
extern crate mel;

fn main() {
    let sample_rate = 44100;
    let window_size = 4096;
    let power_spectrum_size = window_size / 2;
    let filter_count = 100;

    let mut calls: usize = 0;

    for (row, col, value) in mel::enumerate_mel_scaling_matrix(
        sample_rate,
        window_size,
        power_spectrum_size,
        filter_count,
    ) {
        calls += 1;
    }
    assert_eq!(calls, power_spectrum_size * filter_count);
}
```
*/

use std::ops::{Add, Sub, Mul, Div, IndexMut, Range};
use std::cmp::{PartialOrd};

#[macro_use]
extern crate nalgebra;
use nalgebra::ApproxEq;

extern crate num;
use num::{Float, Zero, NumCast, ToPrimitive, FromPrimitive};

extern crate hertz;
extern crate apodize;

extern crate itertools;
use itertools::linspace;

macro_rules! f64_from_usize {
    ($val:expr) => {
        <f64>::from_usize($val)
            .expect("type `f64` can't represent a specific value of type `usize` on this architecture.");
    }
}

macro_rules! usize_from_f64 {
    ($val:expr) => {
        <usize>::from_f64($val)
            .expect("type `usize` can't represent a specific value of type `f64` on this architecture.");
    }
}

#[inline]
pub fn hertz_from_mel(mel: f64) -> f64 {
    700. * ((10.).powf(mel / 2595.) - 1.)
}

#[inline]
pub fn mel_from_hertz(hertz: f64) -> f64 {
    2595. * (1. + hertz / 700.).log10()
}

#[test]
fn test_mel() {
    assert_approx_eq_eps!(
        549.64, mel_from_hertz(440.), 0.01);
    assert_approx_eq_eps!(
        440., hertz_from_mel(549.64), 0.01);

    let mel = 0.;
    assert_approx_eq!(mel, mel_from_hertz(hertz_from_mel(mel)));
    let mel = 100.;
    assert_approx_eq_eps!(
        mel, mel_from_hertz(hertz_from_mel(mel)), 0.0001);
    let mel = 3000.;
    assert_approx_eq_eps!(
        mel, mel_from_hertz(hertz_from_mel(mel)), 0.0001);

    let hertz = 0.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
    let hertz = 1000.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
    let hertz = 44100. / 2.;
    assert_approx_eq!(hertz, hertz_from_mel(mel_from_hertz(hertz)));
}

/// col index changes fastest
pub struct MelScalingMatrixEnumerator<WindowIter> {
    // parameters

    /// equivalent to col count
    input_size: usize,
    /// equivalent to row count
    output_size: usize,

    mel_from_hertz: fn(f64) -> f64,
    hertz_from_mel: fn(f64) -> f64,

    max_hertz: f64,

    window_function: fn(usize) -> WindowIter,

    // state

    row_index: usize,
    col_index: usize,

    start_mels_iter: itertools::Linspace<f64>,
    end_mels_iter: itertools::Linspace<f64>,

    // this gets set anew for every row
    window_start: usize,
    window_size: usize,
    window_iter: WindowIter
}

impl<WindowIter> MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    #[inline]
    pub fn is_done(&self) -> bool {
        self.is_last_row() && self.is_last_col()
    }

    #[inline]
    pub fn is_last_row(&self) -> bool {
        self.output_size <= self.row_index
    }

    #[inline]
    pub fn is_last_col(&self) -> bool {
        self.input_size <= self.col_index
    }

    #[inline]
    pub fn index(&self) -> usize {
        self.row_index * self.input_size + self.col_index
    }

    #[inline]
    pub fn remaining(&self) -> usize {
        // TODO is this off by one ?
        self.len() - self.index()
    }
}

impl<WindowIter> Iterator for MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    type Item = (usize, usize, f64);

    #[inline]
    fn next(&mut self) -> Option<(usize, usize, f64)> {
        if self.is_done() {
            return None;
        }

        // start a new row
        if self.is_last_col() {
            self.col_index = 0;
            self.row_index += 1;

            let start_mel = self.start_mels_iter.next().unwrap();
            let end_mel = self.end_mels_iter.next().unwrap();

            let hertz_from_mel = self.hertz_from_mel;
            let start_hertz = hertz_from_mel(start_mel);
            let end_hertz = hertz_from_mel(end_mel);

            // TODO maybe round or floor or ceil here
            self.window_start = usize_from_f64!(
                start_hertz /
                self.max_hertz *
                f64_from_usize!(self.output_size));

            let window_end = usize_from_f64!(
                end_hertz /
                self.max_hertz *
                f64_from_usize!(self.output_size));

            self.window_size = window_end - self.window_start;

            let window_function = self.window_function;
            self.window_iter = window_function(self.window_size);
        }

        let col = self.col_index;

        let value = if col < self.window_start {
            match self.window_iter.next() {
                Some(value) => {
                    value / f64_from_usize!(self.window_size)
                },
                None => 0.
            }
        } else {
            0.
        };

        self.col_index += 1;
        Some((self.row_index, col, value))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.remaining();
        (remaining, Some(remaining))
    }
}

impl<WindowIter> ExactSizeIterator for MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    #[inline]
    fn len(&self) -> usize {
        self.input_size * self.output_size
    }
}

/// (or many vectors at once in form of a matrix)
/// to transform that vector into mel space.
/// efficiently
/// rows are mel
/// cols are freq
/// TODO get frequency index pair for nth mel
/// TODO enumerate scaling vector
/// TODO which dimension first
pub fn enumerate_mel_scaling_matrix_base<WindowIter>(
    // TODO more descriptive argument names
    min_hertz: f64,
    max_hertz: f64,
    // TODO shape
    input_size: usize,
    output_size: usize,
    mel_from_hertz: fn(f64) -> f64,
    hertz_from_mel: fn(f64) -> f64,
    window_function: fn(usize) -> WindowIter
) -> MelScalingMatrixEnumerator<WindowIter>
    where WindowIter: Iterator<Item=f64>
{
    assert!(min_hertz < max_hertz);
    assert!(output_size < input_size);
    assert!(0 < output_size);
    assert!(0 < input_size);

    let min_mel = mel_from_hertz(min_hertz);
    let max_mel = mel_from_hertz(max_hertz);

    let mut start_mels_iter = linspace(min_mel, max_mel, output_size);
    let mut end_mels_iter = linspace(max_mel, max_mel, output_size);
    end_mels_iter.next();

    let start_mel = start_mels_iter.next().unwrap();
    let end_mel = end_mels_iter.next().unwrap();

    let start_hertz = hertz_from_mel(start_mel);
    let end_hertz = hertz_from_mel(end_mel);

    // TODO maybe round or floor or ceil here
    let start_index = usize_from_f64!(
        start_hertz / max_hertz * f64_from_usize!(output_size));

    let end_index = usize_from_f64!(
        end_hertz / max_hertz * f64_from_usize!(output_size));

    let window_size = end_index - start_index;

    let window_iter = window_function(window_size);

    MelScalingMatrixEnumerator::<WindowIter> {
        // parameters
        input_size: input_size,
        output_size: output_size,
        window_function: window_function,
        hertz_from_mel: hertz_from_mel,
        mel_from_hertz: mel_from_hertz,
        max_hertz: max_hertz,

        // state
        row_index: 0,
        col_index: 0,

        start_mels_iter: start_mels_iter,
        end_mels_iter: end_mels_iter,

        window_start: start_index,
        window_size: window_size,
        window_iter: window_iter,
    }
}

/// one filter per row
pub fn enumerate_mel_scaling_matrix(
    sample_rate: usize,
    window_size: usize,
    input_size: usize,
    output_size: usize,
) -> MelScalingMatrixEnumerator<apodize::TriangularWindowIter>
{
    enumerate_mel_scaling_matrix_base(
        hertz::rayleigh(
            f64_from_usize!(sample_rate),
            f64_from_usize!(window_size)),
        hertz::nyquist(f64_from_usize!(sample_rate)),
        input_size,
        output_size,
        mel_from_hertz,
        hertz_from_mel,
        apodize::triangular_iter
    )
}

// TODO test that identity matrix with
// output_size = input_size
// and conversion functions = identity

// TODO test in a small scale that scaling matrixes are correct
// then test it in emir directly and check correctness visually
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! A library to generate EPUB files.
//!
//! The purpose for this library is to make it easier to generate EPUB files:
//! it should take care of most of the boilerplate for you, leaving you only
//! with the task of filling the actual content.
//!
//! # Usage
//!
//! Add this in your `Cargo.toml` file:
//!
//! ```toml
//! [dependencies]
//! epub-builder = "0.4"
//! ```
//!
//! # Example
//!
//! ```ignore
//! extern crate epub_builder;
//!
//! use epub_builder::EpubBuilder;
//! use epub_builder::Result;
//! use epub_builder::ZipLibrary;
//! use epub_builder::EpubContent;
//! use epub_builder::ReferenceType;
//! use epub_builder::TocElement;
//!
//! use std::io;
//! use std::io::Write;
//!
//! // Try to print Zip file to stdout
//! fn run() -> Result<()> {
//!     // Some dummy content to fill our books
//!     let dummy_content = "Dummy content. This should be valid XHTML if you want a valid EPUB!";
//!     let dummy_image = "Not really a PNG image";
//!     let dummy_css = "body { background-color: pink }";
//!
//!     // Create a new EpubBuilder using the zip library
//!     EpubBuilder::new(ZipLibrary::new())?
//!     // Set some metadata
//!         .metadata("author", "Joan Doe")?
//!         .metadata("title", "Dummy Book")?
//!     // Set the stylesheet (create a "stylesheet.css" file in EPUB that is used by some generated files)
//!         .stylesheet(dummy_css.as_bytes())?
//!     // Add a image cover file
//!         .add_cover_image("cover.png", dummy_image.as_bytes(), "image/png")?
//!     // Add a resource that is not part of the linear document structure
//!         .add_resource("some_image.png", dummy_image.as_bytes(), "image/png")?
//!     // Add a cover page
//!         .add_content(EpubContent::new("cover.xhtml", dummy_content.as_bytes())
//!                      .title("Cover")
//!                      .reftype(ReferenceType::Cover))?
//!     // Add a title page
//!         .add_content(EpubContent::new("title.xhtml", dummy_content.as_bytes())
//!                      .title("Title")
//!                      .reftype(ReferenceType::TitlePage))?
//!     // Add a chapter, mark it as beginning of the "real content"
//!         .add_content(EpubContent::new("chapter_1.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 1")
//!                      .reftype(ReferenceType::Text))?
//!     // Add a second chapter; this one has more toc information about its internal structure
//!         .add_content(EpubContent::new("chapter_2.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 2")
//!                      .child(TocElement::new("chapter_2.xhtml#1", "Chapter 2, section 1")))?
//!     // Add a section. Since its level is set to 2, it will be attached to the previous chapter.
//!         .add_content(EpubContent::new("section.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 2, section 2")
//!                      .level(2))?
//!     // Add a chapter without a title, which will thus not appear in the TOC.
//!         .add_content(EpubContent::new("notes.xhtml", dummy_content.as_bytes()))?
//!     // Generate a toc inside of the document, that will be part of the linear structure.
//!         .inline_toc()
//!     // Finally, write the EPUB file to stdout
//!         .generate(&mut io::stdout())?;
//!     Ok(())
//! }
//!
//! fn main() {
//!     match run() {
//!         Ok(_) => {
//!             writeln!(&mut io::stderr(),
//!                      "Successfully wrote epub document to stdout!")
//!                 .unwrap()
//!         }
//!         Err(err) => writeln!(&mut io::stderr(), "Error: {}", err).unwrap(),
//!     };
//! }
//! ```
//!
//! # Features
//!
//! `epub-builder`'s aim is to make EPUB generation simpler. It takes care of zipping
//! the files and generate the following ones:
//!
//! * `mimetype`
//! * `toc.ncx`
//! * `nav.xhtml`
//! * `manifest.xml`
//! * `content.opf`
//! * `com.apple.ibooks.display-options.xml`.
//!
//! It also tries to make it easier to have a correct table of contents, and optionally
//! generate an inline one in the document.
//!
//! Supported EPUB versions:
//!
//! * 2.0.1 (default)
//! * 3.0.1
//!
//! ## Missing features
//!
//! There are various EPUB features that `epub-builder` doesn't handle. Particularly,
//! there are some metadata that could be better
//! handled (e.g. support multiple authors, multiple languages in the document and so on).
//!
//! There are also various things that aren't in the scope of this library: it doesn't
//! provide a default CSS, templates for your XHTML content and so on. This is left to
//! libraries or applications using it.
//!
//! # Conditional compilation
//!
//! EPUB files are Zip files, so we need to zip. By default, this library provides
//! wrappers around both the [Rust zip library](https://crates.io/crates/zip) and calls
//! to the `zip` command that may (or may not) be installed on your system.
//!
//! It is possible to disable the compilation (and the dependencies) of either of these
//! wrappers, using `no-default-features`. (If you don't enable at least one of them this
//! library will be pretty useless).
//!
//! # License
//!
//! This is free software, published under the [Mozilla Public License,
//! version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).
#![deny(missing_docs)]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate error_chain;
extern crate mustache;
extern crate chrono;
extern crate uuid;
#[cfg(feature = "zip-command")]
extern crate tempdir;
#[cfg(feature = "zip-library")]
extern crate zip as libzip;
extern crate regex;
extern crate html2text;
#[cfg(test)] #[macro_use] extern crate pretty_assertions;

mod errors;
mod epub;
mod zip;
mod templates;
mod toc;
mod epub_content;
#[cfg(feature = "zip-command")]
mod zip_command;
#[cfg(feature = "zip-library")]
mod zip_library;
#[cfg(feature = "zip-command")]
#[cfg(feature = "zip-library")]
mod zip_command_or_library;
mod common;

pub use errors::*;
pub use epub::EpubBuilder;
pub use epub::EpubVersion;
pub use zip::Zip;
pub use toc::Toc;
pub use toc::TocElement;
pub use epub_content::EpubContent;
pub use epub_content::ReferenceType;
#[cfg(feature = "zip-command")]
pub use zip_command::ZipCommand;
#[cfg(feature = "zip-library")]
pub use zip_library::ZipLibrary;
#[cfg(feature = "zip-command")]
#[cfg(feature = "zip-library")]
pub use zip_command_or_library::ZipCommandOrLibrary;
<commit_msg>Also add missing ? after ZipLibrary::new() in srl/lib.rs<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! A library to generate EPUB files.
//!
//! The purpose for this library is to make it easier to generate EPUB files:
//! it should take care of most of the boilerplate for you, leaving you only
//! with the task of filling the actual content.
//!
//! # Usage
//!
//! Add this in your `Cargo.toml` file:
//!
//! ```toml
//! [dependencies]
//! epub-builder = "0.4"
//! ```
//!
//! # Example
//!
//! ```ignore
//! extern crate epub_builder;
//!
//! use epub_builder::EpubBuilder;
//! use epub_builder::Result;
//! use epub_builder::ZipLibrary;
//! use epub_builder::EpubContent;
//! use epub_builder::ReferenceType;
//! use epub_builder::TocElement;
//!
//! use std::io;
//! use std::io::Write;
//!
//! // Try to print Zip file to stdout
//! fn run() -> Result<()> {
//!     // Some dummy content to fill our books
//!     let dummy_content = "Dummy content. This should be valid XHTML if you want a valid EPUB!";
//!     let dummy_image = "Not really a PNG image";
//!     let dummy_css = "body { background-color: pink }";
//!
//!     // Create a new EpubBuilder using the zip library
//!     EpubBuilder::new(ZipLibrary::new()?)?
//!     // Set some metadata
//!         .metadata("author", "Joan Doe")?
//!         .metadata("title", "Dummy Book")?
//!     // Set the stylesheet (create a "stylesheet.css" file in EPUB that is used by some generated files)
//!         .stylesheet(dummy_css.as_bytes())?
//!     // Add a image cover file
//!         .add_cover_image("cover.png", dummy_image.as_bytes(), "image/png")?
//!     // Add a resource that is not part of the linear document structure
//!         .add_resource("some_image.png", dummy_image.as_bytes(), "image/png")?
//!     // Add a cover page
//!         .add_content(EpubContent::new("cover.xhtml", dummy_content.as_bytes())
//!                      .title("Cover")
//!                      .reftype(ReferenceType::Cover))?
//!     // Add a title page
//!         .add_content(EpubContent::new("title.xhtml", dummy_content.as_bytes())
//!                      .title("Title")
//!                      .reftype(ReferenceType::TitlePage))?
//!     // Add a chapter, mark it as beginning of the "real content"
//!         .add_content(EpubContent::new("chapter_1.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 1")
//!                      .reftype(ReferenceType::Text))?
//!     // Add a second chapter; this one has more toc information about its internal structure
//!         .add_content(EpubContent::new("chapter_2.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 2")
//!                      .child(TocElement::new("chapter_2.xhtml#1", "Chapter 2, section 1")))?
//!     // Add a section. Since its level is set to 2, it will be attached to the previous chapter.
//!         .add_content(EpubContent::new("section.xhtml", dummy_content.as_bytes())
//!                      .title("Chapter 2, section 2")
//!                      .level(2))?
//!     // Add a chapter without a title, which will thus not appear in the TOC.
//!         .add_content(EpubContent::new("notes.xhtml", dummy_content.as_bytes()))?
//!     // Generate a toc inside of the document, that will be part of the linear structure.
//!         .inline_toc()
//!     // Finally, write the EPUB file to stdout
//!         .generate(&mut io::stdout())?;
//!     Ok(())
//! }
//!
//! fn main() {
//!     match run() {
//!         Ok(_) => {
//!             writeln!(&mut io::stderr(),
//!                      "Successfully wrote epub document to stdout!")
//!                 .unwrap()
//!         }
//!         Err(err) => writeln!(&mut io::stderr(), "Error: {}", err).unwrap(),
//!     };
//! }
//! ```
//!
//! # Features
//!
//! `epub-builder`'s aim is to make EPUB generation simpler. It takes care of zipping
//! the files and generate the following ones:
//!
//! * `mimetype`
//! * `toc.ncx`
//! * `nav.xhtml`
//! * `manifest.xml`
//! * `content.opf`
//! * `com.apple.ibooks.display-options.xml`.
//!
//! It also tries to make it easier to have a correct table of contents, and optionally
//! generate an inline one in the document.
//!
//! Supported EPUB versions:
//!
//! * 2.0.1 (default)
//! * 3.0.1
//!
//! ## Missing features
//!
//! There are various EPUB features that `epub-builder` doesn't handle. Particularly,
//! there are some metadata that could be better
//! handled (e.g. support multiple authors, multiple languages in the document and so on).
//!
//! There are also various things that aren't in the scope of this library: it doesn't
//! provide a default CSS, templates for your XHTML content and so on. This is left to
//! libraries or applications using it.
//!
//! # Conditional compilation
//!
//! EPUB files are Zip files, so we need to zip. By default, this library provides
//! wrappers around both the [Rust zip library](https://crates.io/crates/zip) and calls
//! to the `zip` command that may (or may not) be installed on your system.
//!
//! It is possible to disable the compilation (and the dependencies) of either of these
//! wrappers, using `no-default-features`. (If you don't enable at least one of them this
//! library will be pretty useless).
//!
//! # License
//!
//! This is free software, published under the [Mozilla Public License,
//! version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).
#![deny(missing_docs)]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate error_chain;
extern crate mustache;
extern crate chrono;
extern crate uuid;
#[cfg(feature = "zip-command")]
extern crate tempdir;
#[cfg(feature = "zip-library")]
extern crate zip as libzip;
extern crate regex;
extern crate html2text;
#[cfg(test)] #[macro_use] extern crate pretty_assertions;

mod errors;
mod epub;
mod zip;
mod templates;
mod toc;
mod epub_content;
#[cfg(feature = "zip-command")]
mod zip_command;
#[cfg(feature = "zip-library")]
mod zip_library;
#[cfg(feature = "zip-command")]
#[cfg(feature = "zip-library")]
mod zip_command_or_library;
mod common;

pub use errors::*;
pub use epub::EpubBuilder;
pub use epub::EpubVersion;
pub use zip::Zip;
pub use toc::Toc;
pub use toc::TocElement;
pub use epub_content::EpubContent;
pub use epub_content::ReferenceType;
#[cfg(feature = "zip-command")]
pub use zip_command::ZipCommand;
#[cfg(feature = "zip-library")]
pub use zip_library::ZipLibrary;
#[cfg(feature = "zip-command")]
#[cfg(feature = "zip-library")]
pub use zip_command_or_library::ZipCommandOrLibrary;
<|endoftext|>


<commit_before>use std::any::{TypeId, Any};
use std::clone::Clone;
use std::fmt::{Display, Debug, Formatter, Error as FmtError};

pub struct Variant<'a> {
   data: *mut (),
   vtable: &'a VTable,
}

pub struct VariantRef<'a> {
   data: &'a (),
   vtable: &'a VTable,
}

pub struct VariantRefMut<'a> {
   data: &'a mut (),
   vtable: &'a VTable,
}

pub struct VTable {
   id: TypeId,
   clone: CloneFn,
   drop: DropFn,
   display: DisplayFn,
   debug: DebugFn,
}

type CloneFn = for<'b> fn(&VariantRef<'b>) -> Variant<'b>;

type DropFn = for<'b> fn(&mut Variant<'b>);

type DisplayFn = for<'b> fn(&VariantRef<'b>, f: &mut Formatter) -> Result<(), FmtError>;

type DebugFn = DisplayFn;

impl<'a> Variant<'a> {
   pub fn new<T: Any>(value: T, vtable: &'a VTable) -> Self {
      Variant {
         data: Box::into_raw(Box::new(value)) as *mut (),
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
      if self.is::<T>() {
         unsafe { Some(&mut *(self.data as *mut T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const T)
   }

   #[inline]
   pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
      debug_assert!(self.is::<T>());

      &mut *(self.data as *mut T)
   }
}

impl<'a> AsRef<VariantRef<'a>> for Variant<'a> {
   fn as_ref(&self) -> &VariantRef<'a> {
      unsafe { &*(self as *const _ as *const VariantRef<'a>) }
   }
}

impl<'a> AsMut<VariantRefMut<'a>> for Variant<'a> {
   fn as_mut(&mut self) -> &mut VariantRefMut<'a> {
      unsafe { &mut *(self as *mut _ as *mut VariantRefMut<'a>) }
   }
}

impl<'a> Clone for Variant<'a> {
   fn clone(&self) -> Self {
      (self.vtable.clone)(self.as_ref())
   }
}

impl<'a> Drop for Variant<'a> {
   fn drop(&mut self) {
      (self.vtable.drop)(self)
   }
}

impl<'a> Display for Variant<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self.as_ref(), f)
   }
}

impl<'a> Debug for Variant<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self.as_ref(), f)
   }
}

impl<'a> VariantRef<'a> {
   pub fn new<T: Any>(value: &'a T, vtable: &'a VTable) -> Self {
      VariantRef {
         data: unsafe { &*(value as *const _ as *const ()) },
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const _ as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const _ as *const T)
   }
}

impl<'a> Display for VariantRef<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self, f)
   }
}

impl<'a> Debug for VariantRef<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self, f)
   }
}

impl<'a> VariantRefMut<'a> {
   pub fn new<T: Any>(value: &'a mut T, vtable: &'a VTable) -> Self {
      VariantRefMut {
         data: unsafe { &mut *(value as *mut _ as *mut ()) },
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const _ as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
      if self.is::<T>() {
         unsafe { Some(&mut *(self.data as *mut _ as *mut T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const _ as *const T)
   }

   #[inline]
   pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
      debug_assert!(self.is::<T>());

      &mut *(self.data as *mut _ as *mut T)
   }
}

impl<'a> AsRef<VariantRef<'a>> for VariantRefMut<'a> {
   fn as_ref(&self) -> &VariantRef<'a> {
      unsafe { &*(self as *const _ as *const VariantRef<'a>) }
   }
}

impl<'a> Display for VariantRefMut<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self.as_ref(), f)
   }
}

impl<'a> Debug for VariantRefMut<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self.as_ref(), f)
   }
}

impl VTable {
   pub fn new<T: Any + Clone + Display + Debug>() -> Self {
      VTable {
         id: TypeId::of::<T>(),
         clone: clone_variant::<T>,
         drop: drop_variant::<T>,
         display: display_variant::<T>,
         debug: debug_variant::<T>,
      }
   }

   pub fn variant<T: Any>(&self, value: T) -> Variant {
      Variant::new(value, self)
   }

   pub fn variant_ref<'a, T: Any>(&'a self, value: &'a T) -> VariantRef<'a> {
      VariantRef::new(value, self)
   }

   pub fn variant_ref_mut<'a, T: Any>(&'a self, value: &'a mut T) -> VariantRefMut<'a> {
      VariantRefMut::new(value, self)
   }
}

fn clone_variant<'a, T: Any + Clone>(variant: &VariantRef<'a>) -> Variant<'a> {
   Variant::new(unsafe { variant.downcast_ref_unchecked() as &T }.clone(), variant.vtable)
}

fn drop_variant<T>(variant: &mut Variant) {
   drop(unsafe { *Box::from_raw(variant.data as *mut T) });
}

fn display_variant<T: Any + Display>(
   variant: &VariantRef,
   f: &mut Formatter,
) -> Result<(), FmtError> {
   Display::fmt(unsafe { variant.downcast_ref_unchecked() as &T }, f)
}

fn debug_variant<T: Any + Debug>(variant: &VariantRef, f: &mut Formatter) -> Result<(), FmtError> {
   Debug::fmt(unsafe { variant.downcast_ref_unchecked() as &T }, f)
}

#[cfg(test)]
mod tests {
   use std::fmt::{Display, Debug};

   use super::*;

   #[test]
   fn clone() {
      let vtable = VTable::new::<i64>();
      let origin = vtable.variant(1234_i64);
      let cloned = origin.clone();
      assert_eq!(origin.downcast_ref::<i64>(), cloned.downcast_ref::<i64>());
      assert_eq!(Some(&1234_i64), cloned.downcast_ref::<i64>());
   }

   #[test]
   fn drop_count() {
      #[derive(Clone, Debug)]
      struct Dropper(*mut usize);

      impl Drop for Dropper {
         fn drop(&mut self) {
            unsafe { *self.0 += 1 };
         }
      }

      impl Display for Dropper {
         fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
            Debug::fmt(self, f)
         }
      }

      let vtable = VTable::new::<Dropper>();
      let mut dropped: usize = 0;
      let variant = vtable.variant(Dropper(&mut dropped));
      drop(variant);
      assert_eq!(dropped, 1);

      dropped = 0;
      let variant = vtable.variant(Dropper(&mut dropped));
      let clone = variant.clone();
      drop(variant);
      drop(clone);
      assert_eq!(dropped, 2);
   }

   #[test]
   fn debug() {
      let vtable = VTable::new::<&str>();
      let variant = vtable.variant("data");
      assert_eq!("\"data\"", format!("{:?}", variant));

      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);
      assert_eq!("1234", format!("{:?}", variant));
   }

   #[test]
   fn debug_ref() {
      let vtable = VTable::new::<&str>();
      let data = "data";
      let variant_ref = vtable.variant_ref(&data);
      assert_eq!("\"data\"", format!("{:?}", variant_ref));

      let vtable = VTable::new::<i64>();
      let data = 1234_i64;
      let variant_ref = vtable.variant_ref(&data);
      assert_eq!("1234", format!("{:?}", variant_ref));
   }

   #[test]
   fn debug_ref_mut() {
      let vtable = VTable::new::<&str>();
      let mut data = "data";
      let variant_ref = vtable.variant_ref_mut(&mut data);
      assert_eq!("\"data\"", format!("{:?}", variant_ref));

      let vtable = VTable::new::<i64>();
      let mut data = 1234_i64;
      let variant_ref = vtable.variant_ref_mut(&mut data);
      assert_eq!("1234", format!("{:?}", variant_ref));
   }

   #[test]
   fn display() {
      let vtable = VTable::new::<&str>();
      let variant = vtable.variant("data");
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn display_ref() {
      let vtable = VTable::new::<&str>();
      let data = "data";
      let variant = vtable.variant_ref(&data);
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let data = 1234_i64;
      let variant = vtable.variant_ref(&data);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn display_ref_mut() {
      let vtable = VTable::new::<&str>();
      let mut data = "data";
      let variant = vtable.variant_ref_mut(&mut data);
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let mut data = 1234_i64;
      let variant = vtable.variant_ref_mut(&mut data);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn as_ref() {
      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);

      fn inner(variant: &VariantRef) {
         assert_eq!(Some(&1234_i64), variant.downcast_ref::<i64>());
      }

      inner(variant.as_ref());
   }

   #[test]
   fn as_mut() {
      let vtable = VTable::new::<i64>();
      let mut variant = vtable.variant(1234_i64);

      fn inner(variant: &mut VariantRefMut) {
         *variant.downcast_mut::<i64>().unwrap() *= 2;
      }

      inner(variant.as_mut());

      assert_eq!(Some(&2468_i64), variant.downcast_ref::<i64>());
   }

   #[test]
   fn stack_ref() {
      let vtable = VTable::new::<i64>();
      let values: [i64; 4] = [0, 2, 5, 6];
      let variants = [
         vtable.variant_ref(&values[0]),
         vtable.variant_ref(&values[1]),
         vtable.variant_ref(&values[2]),
         vtable.variant_ref(&values[3]),
      ];
      let mut sum: i64 = 0;
      for variant in &variants {
         sum += *variant.downcast_ref::<i64>().unwrap();
      }
      assert_eq!(13_i64, sum);
   }
}
<commit_msg>Deref for Variant<commit_after>use std::any::{TypeId, Any};
use std::clone::Clone;
use std::fmt::{Display, Debug, Formatter, Error as FmtError};
use std::ops::Deref;

pub struct Variant<'a> {
   data: *mut (),
   vtable: &'a VTable,
}

pub struct VariantRef<'a> {
   data: &'a (),
   vtable: &'a VTable,
}

pub struct VariantRefMut<'a> {
   data: &'a mut (),
   vtable: &'a VTable,
}

pub struct VTable {
   id: TypeId,
   clone: CloneFn,
   drop: DropFn,
   display: DisplayFn,
   debug: DebugFn,
}

type CloneFn = for<'b> fn(&VariantRef<'b>) -> Variant<'b>;

type DropFn = for<'b> fn(&mut Variant<'b>);

type DisplayFn = for<'b> fn(&VariantRef<'b>, f: &mut Formatter) -> Result<(), FmtError>;

type DebugFn = DisplayFn;

impl<'a> Variant<'a> {
   pub fn new<T: Any>(value: T, vtable: &'a VTable) -> Self {
      Variant {
         data: Box::into_raw(Box::new(value)) as *mut (),
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
      if self.is::<T>() {
         unsafe { Some(&mut *(self.data as *mut T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const T)
   }

   #[inline]
   pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
      debug_assert!(self.is::<T>());

      &mut *(self.data as *mut T)
   }
}

impl<'a> Deref for Variant<'a> {
   type Target = VariantRef<'a>;

   fn deref(&self) -> &VariantRef<'a> {
      self.as_ref()
   }
}

impl<'a> AsRef<VariantRef<'a>> for Variant<'a> {
   fn as_ref(&self) -> &VariantRef<'a> {
      unsafe { &*(self as *const _ as *const VariantRef<'a>) }
   }
}

impl<'a> AsMut<VariantRefMut<'a>> for Variant<'a> {
   fn as_mut(&mut self) -> &mut VariantRefMut<'a> {
      unsafe { &mut *(self as *mut _ as *mut VariantRefMut<'a>) }
   }
}

impl<'a> Clone for Variant<'a> {
   fn clone(&self) -> Self {
      (self.vtable.clone)(self.as_ref())
   }
}

impl<'a> Drop for Variant<'a> {
   fn drop(&mut self) {
      (self.vtable.drop)(self)
   }
}

impl<'a> Display for Variant<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self.as_ref(), f)
   }
}

impl<'a> Debug for Variant<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self.as_ref(), f)
   }
}

impl<'a> VariantRef<'a> {
   pub fn new<T: Any>(value: &'a T, vtable: &'a VTable) -> Self {
      VariantRef {
         data: unsafe { &*(value as *const _ as *const ()) },
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const _ as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const _ as *const T)
   }
}

impl<'a> Display for VariantRef<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self, f)
   }
}

impl<'a> Debug for VariantRef<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self, f)
   }
}

impl<'a> VariantRefMut<'a> {
   pub fn new<T: Any>(value: &'a mut T, vtable: &'a VTable) -> Self {
      VariantRefMut {
         data: unsafe { &mut *(value as *mut _ as *mut ()) },
         vtable: vtable,
      }
   }

   #[inline]
   pub fn is<T: Any>(&self) -> bool {
      self.vtable.id == TypeId::of::<T>()
   }

   #[inline]
   pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
      if self.is::<T>() {
         unsafe { Some(&*(self.data as *const _ as *const T)) }
      } else {
         None
      }
   }

   #[inline]
   pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
      if self.is::<T>() {
         unsafe { Some(&mut *(self.data as *mut _ as *mut T)) }
      } else {
         None
      }
   }

   #[inline]
   pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
      debug_assert!(self.is::<T>());

      &*(self.data as *const _ as *const T)
   }

   #[inline]
   pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
      debug_assert!(self.is::<T>());

      &mut *(self.data as *mut _ as *mut T)
   }
}

impl<'a> AsRef<VariantRef<'a>> for VariantRefMut<'a> {
   fn as_ref(&self) -> &VariantRef<'a> {
      unsafe { &*(self as *const _ as *const VariantRef<'a>) }
   }
}

impl<'a> Display for VariantRefMut<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.display)(self.as_ref(), f)
   }
}

impl<'a> Debug for VariantRefMut<'a> {
   fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
      (self.vtable.debug)(self.as_ref(), f)
   }
}

impl VTable {
   pub fn new<T: Any + Clone + Display + Debug>() -> Self {
      VTable {
         id: TypeId::of::<T>(),
         clone: clone_variant::<T>,
         drop: drop_variant::<T>,
         display: display_variant::<T>,
         debug: debug_variant::<T>,
      }
   }

   pub fn variant<T: Any>(&self, value: T) -> Variant {
      Variant::new(value, self)
   }

   pub fn variant_ref<'a, T: Any>(&'a self, value: &'a T) -> VariantRef<'a> {
      VariantRef::new(value, self)
   }

   pub fn variant_ref_mut<'a, T: Any>(&'a self, value: &'a mut T) -> VariantRefMut<'a> {
      VariantRefMut::new(value, self)
   }
}

fn clone_variant<'a, T: Any + Clone>(variant: &VariantRef<'a>) -> Variant<'a> {
   Variant::new(unsafe { variant.downcast_ref_unchecked() as &T }.clone(), variant.vtable)
}

fn drop_variant<T>(variant: &mut Variant) {
   drop(unsafe { *Box::from_raw(variant.data as *mut T) });
}

fn display_variant<T: Any + Display>(
   variant: &VariantRef,
   f: &mut Formatter,
) -> Result<(), FmtError> {
   Display::fmt(unsafe { variant.downcast_ref_unchecked() as &T }, f)
}

fn debug_variant<T: Any + Debug>(variant: &VariantRef, f: &mut Formatter) -> Result<(), FmtError> {
   Debug::fmt(unsafe { variant.downcast_ref_unchecked() as &T }, f)
}

#[cfg(test)]
mod tests {
   use std::fmt::{Display, Debug};

   use super::*;

   #[test]
   fn clone() {
      let vtable = VTable::new::<i64>();
      let origin = vtable.variant(1234_i64);
      let cloned = origin.clone();
      assert_eq!(origin.downcast_ref::<i64>(), cloned.downcast_ref::<i64>());
      assert_eq!(Some(&1234_i64), cloned.downcast_ref::<i64>());
   }

   #[test]
   fn drop_count() {
      #[derive(Clone, Debug)]
      struct Dropper(*mut usize);

      impl Drop for Dropper {
         fn drop(&mut self) {
            unsafe { *self.0 += 1 };
         }
      }

      impl Display for Dropper {
         fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
            Debug::fmt(self, f)
         }
      }

      let vtable = VTable::new::<Dropper>();
      let mut dropped: usize = 0;
      let variant = vtable.variant(Dropper(&mut dropped));
      drop(variant);
      assert_eq!(dropped, 1);

      dropped = 0;
      let variant = vtable.variant(Dropper(&mut dropped));
      let clone = variant.clone();
      drop(variant);
      drop(clone);
      assert_eq!(dropped, 2);
   }

   #[test]
   fn debug() {
      let vtable = VTable::new::<&str>();
      let variant = vtable.variant("data");
      assert_eq!("\"data\"", format!("{:?}", variant));

      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);
      assert_eq!("1234", format!("{:?}", variant));
   }

   #[test]
   fn debug_ref() {
      let vtable = VTable::new::<&str>();
      let data = "data";
      let variant_ref = vtable.variant_ref(&data);
      assert_eq!("\"data\"", format!("{:?}", variant_ref));

      let vtable = VTable::new::<i64>();
      let data = 1234_i64;
      let variant_ref = vtable.variant_ref(&data);
      assert_eq!("1234", format!("{:?}", variant_ref));
   }

   #[test]
   fn debug_ref_mut() {
      let vtable = VTable::new::<&str>();
      let mut data = "data";
      let variant_ref = vtable.variant_ref_mut(&mut data);
      assert_eq!("\"data\"", format!("{:?}", variant_ref));

      let vtable = VTable::new::<i64>();
      let mut data = 1234_i64;
      let variant_ref = vtable.variant_ref_mut(&mut data);
      assert_eq!("1234", format!("{:?}", variant_ref));
   }

   #[test]
   fn display() {
      let vtable = VTable::new::<&str>();
      let variant = vtable.variant("data");
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn display_ref() {
      let vtable = VTable::new::<&str>();
      let data = "data";
      let variant = vtable.variant_ref(&data);
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let data = 1234_i64;
      let variant = vtable.variant_ref(&data);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn display_ref_mut() {
      let vtable = VTable::new::<&str>();
      let mut data = "data";
      let variant = vtable.variant_ref_mut(&mut data);
      assert_eq!("data", format!("{}", variant));

      let vtable = VTable::new::<i64>();
      let mut data = 1234_i64;
      let variant = vtable.variant_ref_mut(&mut data);
      assert_eq!("1234", format!("{}", variant));
   }

   #[test]
   fn deref() {
      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);

      fn inner(variant: &VariantRef) {
         assert_eq!(Some(&1234_i64), variant.downcast_ref::<i64>());
      }

      inner(&variant);
   }

   #[test]
   fn as_ref() {
      let vtable = VTable::new::<i64>();
      let variant = vtable.variant(1234_i64);

      fn inner(variant: &VariantRef) {
         assert_eq!(Some(&1234_i64), variant.downcast_ref::<i64>());
      }

      inner(variant.as_ref());
   }

   #[test]
   fn as_mut() {
      let vtable = VTable::new::<i64>();
      let mut variant = vtable.variant(1234_i64);

      fn inner(variant: &mut VariantRefMut) {
         *variant.downcast_mut::<i64>().unwrap() *= 2;
      }

      inner(variant.as_mut());

      assert_eq!(Some(&2468_i64), variant.downcast_ref::<i64>());
   }

   #[test]
   fn stack_ref() {
      let vtable = VTable::new::<i64>();
      let values: [i64; 4] = [0, 2, 5, 6];
      let variants = [
         vtable.variant_ref(&values[0]),
         vtable.variant_ref(&values[1]),
         vtable.variant_ref(&values[2]),
         vtable.variant_ref(&values[3]),
      ];
      let mut sum: i64 = 0;
      for variant in &variants {
         sum += *variant.downcast_ref::<i64>().unwrap();
      }
      assert_eq!(13_i64, sum);
   }
}
<|endoftext|>


<commit_before>use std::ops::Index;
use std::convert::Into;

#[derive(Debug, Clone, Copy)]
pub enum BezNode {
    Point {
        x: f32,
        y: f32
    },

    Control {
        x: f32,
        y: f32
    }
}

impl BezNode {
    pub fn x(self) -> f32 {
        <BezNode as Into<(f32, f32)>>::into(self).0
    }

    pub fn y(self) -> f32 {
        <BezNode as Into<(f32, f32)>>::into(self).1
    }
}

impl Into<[f32; 2]> for BezNode {
    fn into(self) -> [f32; 2] {
        use self::BezNode::*;

        match self {
            Point{x, y} |
            Control{x, y} => [x, y]
        }
    }
}

impl Into<(f32, f32)> for BezNode {
    fn into(self) -> (f32, f32) {
        use self::BezNode::*;

        match self {
            Point{x, y} |
            Control{x, y} => (x, y)
        }
    }
}

pub struct BezQuad<I: Index<usize, Output = BezNode>> {
    array: I
}

<commit_msg>Add BezNode convenience functions<commit_after>use std::ops::Index;
use std::convert::Into;

#[derive(Debug, Clone, Copy)]
pub enum BezNode {
    Point {
        x: f32,
        y: f32
    },

    Control {
        x: f32,
        y: f32
    }
}

impl BezNode {
    pub fn new_point(x: f32, y: f32) -> BezNode {
        BezNode::Point {
            x: x,
            y: y
        }
    }

    pub fn new_control(x: f32, y: f32) -> BezNode {
        BezNode::Control {
            x: x,
            y: y
        }
    }

    pub fn x(self) -> f32 {
        <BezNode as Into<(f32, f32)>>::into(self).0
    }

    pub fn y(self) -> f32 {
        <BezNode as Into<(f32, f32)>>::into(self).1
    }

    pub fn is_point(self) -> bool {
        use self::BezNode::*;
        match self {
            Point{..} => true,
            Control{..} => false
        }
    }

    pub fn is_control(self) -> bool {
        use self::BezNode::*;
        match self {
            Point{..} => false,
            Control{..} => true
        }
    }
}

impl Into<[f32; 2]> for BezNode {
    fn into(self) -> [f32; 2] {
        use self::BezNode::*;

        match self {
            Point{x, y}    |
            Control{x, y} => [x, y]
        }
    }
}

impl Into<(f32, f32)> for BezNode {
    fn into(self) -> (f32, f32) {
        use self::BezNode::*;

        match self {
            Point{x, y}    |
            Control{x, y} => (x, y)
        }
    }
}

pub struct BezQuad<I: Index<usize, Output = BezNode>> {
    array: I
}

<|endoftext|>


<commit_before>//! # `object`
//!
//! The `object` crate provides a unified interface to working with object files
//! across platforms.
//!
//! See the [`File` struct](./struct.File.html) for details.

#![deny(missing_docs)]

extern crate goblin;

use goblin::{elf, mach};
use std::io::Cursor;

/// An object file.
pub struct File<'a> {
    kind: ObjectKind<'a>,
    data: &'a [u8],
}

enum ObjectKind<'a> {
    Elf(elf::Elf<'a>),
    MachO(mach::MachO<'a>),
}

impl<'a> File<'a> {
    /// Parse the raw object file data.
    pub fn parse(data: &'a [u8]) -> Result<Self, &'static str> {
        let mut cursor = Cursor::new(data);
        let kind = match goblin::peek(&mut cursor)
                  .map_err(|_| "Could not parse file magic")? {
            goblin::Hint::Elf(_) => {
                let elf = elf::Elf::parse(data)
                    .map_err(|_| "Could not parse ELF header")?;
                ObjectKind::Elf(elf)
            }
            goblin::Hint::Mach(_) => {
                let macho = mach::MachO::parse(data, 0)
                    .map_err(|_| "Could not parse Mach-O header")?;
                ObjectKind::MachO(macho)
            }
            _ => return Err("Unknown file magic"),
        };
        Ok(File { kind, data })
    }

    /// Get the contents of the section named `section_name`, if such
    /// a section exists.
    pub fn get_section(&self, section_name: &str) -> Option<&'a [u8]> {
        match self.kind {
            ObjectKind::Elf(ref elf) => elf_get_section(elf, section_name, self.data),
            ObjectKind::MachO(ref macho) => macho_get_section(macho, section_name),
        }
    }

    /// Return true if the file is little endian, false if it is big endian.
    pub fn is_little_endian(&self) -> bool {
        match self.kind {
            ObjectKind::Elf(ref elf) => elf.little_endian,
            ObjectKind::MachO(ref macho) => macho.header.is_little_endian(),
        }
    }
}

fn elf_get_section<'a>(elf: &elf::Elf<'a>, section_name: &str, data: &'a [u8]) -> Option<&'a [u8]> {
    for header in &elf.section_headers {
        if let Some(Ok(name)) = elf.shdr_strtab.get(header.sh_name) {
            if name == section_name {
                return Some(&data[header.sh_offset as usize..][..header.sh_size as usize]);
            }
        }
    }
    None
}

fn macho_get_section<'a>(macho: &mach::MachO<'a>, section_name: &str) -> Option<&'a [u8]> {
    let segment_name = if section_name == ".eh_frame" {
        "__TEXT"
    } else {
        "__DWARF"
    };
    let section_name = macho_translate_section_name(section_name);

    for segment in &macho.segments {
        if let Ok(name) = segment.name() {
            if name == segment_name {
                for section in segment {
                    if let Ok((section, data)) = section {
                        if let Ok(name) = section.name() {
                            if name.as_bytes() == &*section_name {
                                return Some(data);
                            }
                        }
                    }
                }
            }
        }
    }
    None
}

// Translate the "." prefix to the "__" prefix used by OSX/Mach-O, eg
// ".debug_info" to "__debug_info".
fn macho_translate_section_name(section_name: &str) -> Vec<u8> {
    let mut name = Vec::with_capacity(section_name.len() + 1);
    name.push(b'_');
    name.push(b'_');
    for ch in &section_name.as_bytes()[1..] {
        name.push(*ch);
    }
    name
}

#[doc(hidden)]
#[deprecated]
pub trait Object {}
<commit_msg>Run rustfmt<commit_after>//! # `object`
//!
//! The `object` crate provides a unified interface to working with object files
//! across platforms.
//!
//! See the [`File` struct](./struct.File.html) for details.

#![deny(missing_docs)]

extern crate goblin;

use goblin::{elf, mach};
use std::io::Cursor;

/// An object file.
pub struct File<'a> {
    kind: ObjectKind<'a>,
    data: &'a [u8],
}

enum ObjectKind<'a> {
    Elf(elf::Elf<'a>),
    MachO(mach::MachO<'a>),
}

impl<'a> File<'a> {
    /// Parse the raw object file data.
    pub fn parse(data: &'a [u8]) -> Result<Self, &'static str> {
        let mut cursor = Cursor::new(data);
        let kind = match goblin::peek(&mut cursor).map_err(|_| "Could not parse file magic")? {
            goblin::Hint::Elf(_) => {
                let elf = elf::Elf::parse(data).map_err(|_| "Could not parse ELF header")?;
                ObjectKind::Elf(elf)
            }
            goblin::Hint::Mach(_) => {
                let macho =
                    mach::MachO::parse(data, 0).map_err(|_| "Could not parse Mach-O header")?;
                ObjectKind::MachO(macho)
            }
            _ => return Err("Unknown file magic"),
        };
        Ok(File { kind, data })
    }

    /// Get the contents of the section named `section_name`, if such
    /// a section exists.
    pub fn get_section(&self, section_name: &str) -> Option<&'a [u8]> {
        match self.kind {
            ObjectKind::Elf(ref elf) => elf_get_section(elf, section_name, self.data),
            ObjectKind::MachO(ref macho) => macho_get_section(macho, section_name),
        }
    }

    /// Return true if the file is little endian, false if it is big endian.
    pub fn is_little_endian(&self) -> bool {
        match self.kind {
            ObjectKind::Elf(ref elf) => elf.little_endian,
            ObjectKind::MachO(ref macho) => macho.header.is_little_endian(),
        }
    }
}

fn elf_get_section<'a>(elf: &elf::Elf<'a>, section_name: &str, data: &'a [u8]) -> Option<&'a [u8]> {
    for header in &elf.section_headers {
        if let Some(Ok(name)) = elf.shdr_strtab.get(header.sh_name) {
            if name == section_name {
                return Some(&data[header.sh_offset as usize..][..header.sh_size as usize]);
            }
        }
    }
    None
}

fn macho_get_section<'a>(macho: &mach::MachO<'a>, section_name: &str) -> Option<&'a [u8]> {
    let segment_name = if section_name == ".eh_frame" {
        "__TEXT"
    } else {
        "__DWARF"
    };
    let section_name = macho_translate_section_name(section_name);

    for segment in &macho.segments {
        if let Ok(name) = segment.name() {
            if name == segment_name {
                for section in segment {
                    if let Ok((section, data)) = section {
                        if let Ok(name) = section.name() {
                            if name.as_bytes() == &*section_name {
                                return Some(data);
                            }
                        }
                    }
                }
            }
        }
    }
    None
}

// Translate the "." prefix to the "__" prefix used by OSX/Mach-O, eg
// ".debug_info" to "__debug_info".
fn macho_translate_section_name(section_name: &str) -> Vec<u8> {
    let mut name = Vec::with_capacity(section_name.len() + 1);
    name.push(b'_');
    name.push(b'_');
    for ch in &section_name.as_bytes()[1..] {
        name.push(*ch);
    }
    name
}

#[doc(hidden)]
#[deprecated]
pub trait Object {}
<|endoftext|>


<commit_before>// DOCS

#![feature(path,io)]
use std::old_io;
pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

pub trait GenericAtomicFile {
    /// Helper for writing to `path` in write-only mode.
    ///
    /// If `DisallowOverwrite` is given, errors will be returned from `self.write(...)` if the file
    /// exists.
    fn new(path: &Path, overwrite: OverwriteBehavior) -> Self;

    /// Get the target filepath.
    fn path(&self) -> &Path;

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    fn write<F: FnMut(&mut old_io::File) -> old_io::IoResult<()>>(&self, mut f: F) -> old_io::IoResult<()>;
}

#[derive(Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite
}

pub mod posix {
    use super::{GenericAtomicFile,OverwriteBehavior,AllowOverwrite,DisallowOverwrite};
    use std::old_io;

    pub struct AtomicFile {
        path: Path,
        overwrite: OverwriteBehavior,
        tmpdir: Path
    }

    impl AtomicFile {
        pub fn new_with_tmpdir(path: &Path, overwrite: OverwriteBehavior, tmpdir: &Path) -> Self {
            AtomicFile {
                path: path.clone(),
                overwrite: overwrite,
                tmpdir: tmpdir.clone()
            }
        }

        fn commit(&self, tmppath: &Path) -> old_io::IoResult<()> {
            match self.overwrite {
                AllowOverwrite => old_io::fs::rename(&tmppath, &self.path),
                DisallowOverwrite => old_io::fs::link(&tmppath, &self.path)
            }
        }
    }

    impl GenericAtomicFile for AtomicFile {
        fn new(path: &Path, overwrite: OverwriteBehavior) -> Self {
            AtomicFile::new_with_tmpdir(path, overwrite, &path.dir_path())
        }

        fn path(&self) -> &Path { &self.path }

        fn write<F: FnMut(&mut old_io::File) -> old_io::IoResult<()>>(&self, mut f: F) -> old_io::IoResult<()> {
            let tmpdir = try!(old_io::TempDir::new_in(&self.tmpdir, ".atomicwrite"));
            let tmppath = tmpdir.path().join(Path::new("tmpfile.tmp"));
            {
                let mut tmpfile = try!(old_io::File::create(&tmppath));
                try!(f(&mut tmpfile));
            };
            try!(self.commit(&tmppath));
            Ok(())
        }

    }
}

pub mod windows {
    use super::OverwriteBehavior;

    /// Currently a stub. Windows support is not implemented yet.
    pub struct AtomicFile {
        path: Path,
        overwrite: OverwriteBehavior
    }
}

pub use self::posix::AtomicFile as PosixAtomicFile;
pub use self::windows::AtomicFile as WindowsAtomicFile;

#[cfg(unix)]
pub use self::posix::AtomicFile as AtomicFile;

#[cfg(windows)]
pub use self::windows::AtomicFile as AtomicFile;
<commit_msg>API rewrite<commit_after>// DOCS

#![feature(path,io)]
use std::old_io;
pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

pub trait GenericAtomicFile {
    /// Helper for writing to `path` in write-only mode.
    ///
    /// If `DisallowOverwrite` is given, errors will be returned from `self.write(...)` if the file
    /// exists.
    fn new(path: &Path, overwrite: OverwriteBehavior) -> Self;

    /// Get the target filepath.
    fn path(&self) -> &Path;

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    fn write<F: FnMut(&mut old_io::File) -> old_io::IoResult<()>>(&self, mut f: F) -> old_io::IoResult<()>;
}

#[derive(Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite
}

pub struct AtomicFile {
    path: Path,
    overwrite: OverwriteBehavior,
    tmpdir: Path
}

impl AtomicFile {
    pub fn new_with_tmpdir(path: &Path, overwrite: OverwriteBehavior, tmpdir: &Path) -> Self {
        AtomicFile {
            path: path.clone(),
            overwrite: overwrite,
            tmpdir: tmpdir.clone()
        }
    }

    fn commit(&self, tmppath: &Path) -> old_io::IoResult<()> {
        match self.overwrite {
            AllowOverwrite => replace_atomic(tmppath, self.path()),
            DisallowOverwrite => move_atomic(tmppath, self.path())
        }
    }
}

impl GenericAtomicFile for AtomicFile {
    fn new(path: &Path, overwrite: OverwriteBehavior) -> Self {
        AtomicFile::new_with_tmpdir(path, overwrite, &path.dir_path())
    }

    fn path(&self) -> &Path { &self.path }

    fn write<F: FnMut(&mut old_io::File) -> old_io::IoResult<()>>(&self, mut f: F) -> old_io::IoResult<()> {
        let tmpdir = try!(old_io::TempDir::new_in(&self.tmpdir, ".atomicwrite"));
        let tmppath = tmpdir.path().join(Path::new("tmpfile.tmp"));
        {
            let mut tmpfile = try!(old_io::File::create(&tmppath));
            try!(f(&mut tmpfile));
        };
        try!(self.commit(&tmppath));
        Ok(())
    }

}

#[cfg(unix)]
fn replace_atomic_impl(src: &Path, dst: &Path) -> old_io::IoResult<()> {
    old_io::fs::rename(src, dst)
}

#[cfg(unix)]
fn move_atomic_impl(src: &Path, dst: &Path) -> old_io::IoResult<()> {
    try!(old_io::fs::link(src, dst));
    old_io::fs::unlink(src)
}

/// Move `src` to `dst`. If `dst` exists, it will be silently overwritten.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn replace_atomic(src: &Path, dst: &Path) -> old_io::IoResult<()> {
    replace_atomic_impl(src, dst)
}

/// Move `src` to `dst`. An error will be returned if `dst` exists.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn move_atomic(src: &Path, dst: &Path) -> old_io::IoResult<()> {
    move_atomic_impl(src, dst)
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![deny(missing_copy_implementations, missing_debug_implementations,
       missing_docs, trivial_casts, trivial_numeric_casts, unsafe_code, unused_import_braces,
       unused_qualifications, variant_size_differences)]

//! Contains a lexer for lexing the WebIDL grammar.

extern crate lalrpop_util;

/// Contains lexer related structures and functions for lexing the WebIDL grammar.
mod lexer;

/// Contains parser related structures and functions for parsing the WebIDL grammar.
mod parser;

pub use lexer::*;
pub use parser::*;
<commit_msg>update main module doc<commit_after>#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![deny(missing_copy_implementations, missing_debug_implementations, missing_docs, trivial_casts,
        trivial_numeric_casts, unsafe_code, unused_import_braces, unused_qualifications,
        variant_size_differences)]

//! Contains a lexer and parser for the WebIDL grammar.

extern crate lalrpop_util;

/// Contains lexer related structures and functions for lexing the WebIDL grammar.
mod lexer;

/// Contains parser related structures and functions for parsing the WebIDL grammar.
mod parser;

pub use lexer::*;
pub use parser::*;
<|endoftext|>


<commit_before>use std::cell::{Cell, RefCell};
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::ptr;

/// Trait for types that implement `as_ptr`.
///
/// This is implemented by types which can be converted
/// to a pointer from a borrowed reference.
///
/// # Example
/// ```
/// use ptrplus::AsPtr;
///
/// let x: &u32 = &5;
/// let y: *const u32 = x.as_ptr();
/// unsafe {
///     assert_eq!(*y, 5);
/// }
/// ```
///
/// ```
/// use ptrplus::AsPtr;
///
/// let x = 5;
/// let o1: Option<&u32> = None;
/// let o2: Option<&u32> = Some(&x);
///
/// assert!(o1.as_ptr().is_null());
/// assert!(!o2.as_ptr().is_null());
/// unsafe {
///     assert_eq!(*o2.as_ptr(), 5);
/// }
/// ```
pub trait AsPtr {
    /// The type pointed to
    ///
    /// `as_ptr` will return a pointer to this type
    type Raw;

    /// Returns a raw pointer to the contained content
    ///
    /// The caller must ensure `self` outlives the pointer
    /// that is returned, or else it will end up pointing
    /// to garbage.
    ///
    /// Mutating `self` may also invalidate this pointer,
    /// depending on the implementation.
    fn as_ptr(&self) -> *const Self::Raw;
}

impl<T> AsPtr for [T] {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        <[T]>::as_ptr(self)
    }
}

impl AsPtr for CStr {
    type Raw = c_char;
    fn as_ptr(&self) -> *const c_char {
        CStr::as_ptr(self)
    }
}

impl<'a, T> AsPtr for &'a T
where
    T: Sized,
{
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        *self as *const T
    }
}

impl<T> AsPtr for *const T {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        *self
    }
}

impl<T> AsPtr for Cell<T>
where
    T: Copy,
{
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        Cell::as_ptr(self)
    }
}

impl<T> AsPtr for RefCell<T> {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        RefCell::as_ptr(self)
    }
}

impl<T> AsPtr for Option<T>
where
    T: AsPtr,
{
    type Raw = T::Raw;
    fn as_ptr(&self) -> *const T::Raw {
        match self {
            Some(ref v) => v.as_ptr(),
            None => ptr::null(),
        }
    }
}

/// Trait for types that implement `into_raw`
///
/// This is implemented by types that can be converted
/// into a pointer by consuming ownership of the object
///
/// # Example
/// ```
/// use ptrplus::IntoRaw;
///
/// let x: Box<u32> = Box::new(5);
/// let y: *mut u32 = IntoRaw::into_raw(x);
/// unsafe {
///   assert_eq!(*y, 5);
///   *y = 6;
///   Box::from_raw(y);
/// }
///
/// ```
///
/// ```
/// use ptrplus::{FromRaw, IntoRaw};
///
/// let o1: Option<Box<u32>> = None;
/// let o2: Option<Box<u32>> = Some(Box::new(5));
///
/// let p1: *mut u32 = o1.into_raw();
/// let p2: *mut u32 = o2.into_raw();
///
/// assert!(p1.is_null());
/// assert!(!p2.is_null());
/// unsafe {
///     assert_eq!(*p2, 5);
///     let o1: Option<Box<u32>> = Option::from_raw(p1);
///     let o2: Option<Box<u32>> = Option::from_raw(p2);
///     assert!(o1.is_none());
///     assert!(!o2.is_none());
/// }
/// ```
pub trait IntoRaw {
    /// The type pointed to
    ///
    /// `into_raw` returns a mutable pointer to this type
    type Raw;

    /// Consumes `self` returning the wrapped raw pointer.
    ///
    /// After calling this method, the caller is responsable
    /// for making sure any resources attached to this pointer
    /// (such as memory) are cleaned up. The proper way to do this
    /// is to convert the pointer back to `Self`.
    ///
    /// See `FromRaw`
    fn into_raw(self) -> *mut Self::Raw;
}

impl<T> IntoRaw for Box<T> {
    type Raw = T;
    fn into_raw(self) -> *mut T {
        Box::into_raw(self)
    }
}

impl IntoRaw for CString {
    type Raw = c_char;
    fn into_raw(self) -> *mut c_char {
        CString::into_raw(self)
    }
}

impl<T> IntoRaw for *mut T {
    type Raw = T;
    fn into_raw(self) -> *mut T {
        self
    }
}

impl<T> IntoRaw for Option<T>
where
    T: IntoRaw,
{
    type Raw = T::Raw;
    fn into_raw(self) -> *mut T::Raw {
        match self {
            Some(v) => v.into_raw(),
            None => ptr::null_mut(),
        }
    }
}

/// Trait for types that can be created from a raw pointer
///
/// # Examples
/// ```
/// use ptrplus::{FromRaw, IntoRaw};
///
/// let x: Box<u32> = Box::new(5);
/// let y = x.into_raw();
/// let z: Box<u32> = unsafe { FromRaw::from_raw(y) };
/// assert_eq!(*z, 5);
///
/// ```
///
pub trait FromRaw<T> {
    /// Create `Self` from a raw pointer
    ///
    /// After calling this method the raw pointer
    /// is owned by the resulting object. This
    /// means that the resulting object should
    /// clean up any resources associated with
    /// the pointer (such as memory).
    ///
    /// # Safety
    ///
    /// `raw` must be a pointer that is compatible with
    /// the resulting type. For example, if `Self` is
    /// `Box<T>`, then `raw` must be a pointer to memory allocated
    /// as a Box. The exact requirements depend on the implementation.
    ///
    /// Additionally, this function takes ownership of the pointer. If
    /// `raw` or an alias thereof is used after calling this function
    /// it can potentially result in double-free, data races, or other
    /// undefined behavior.
    unsafe fn from_raw(raw: *mut T) -> Self;
}

///
impl<T> FromRaw<T> for Box<T> {
    unsafe fn from_raw(raw: *mut T) -> Self {
        Box::from_raw(raw)
    }
}

impl FromRaw<c_char> for CString {
    unsafe fn from_raw(raw: *mut c_char) -> CString {
        CString::from_raw(raw)
    }
}

impl<T> FromRaw<T> for *mut T {
    unsafe fn from_raw(raw: *mut T) -> *mut T {
        raw
    }
}

impl<T, U> FromRaw<U> for Option<T>
where
    T: FromRaw<U>,
{
    unsafe fn from_raw(raw: *mut U) -> Option<T> {
        if raw.is_null() {
            None
        } else {
            Some(T::from_raw(raw))
        }
    }
}
<commit_msg>Add AsPtr implementations for Box and Cstr<commit_after>use std::cell::{Cell, RefCell};
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::ops::Deref;
use std::ptr;

/// Trait for types that implement `as_ptr`.
///
/// This is implemented by types which can be converted
/// to a pointer from a borrowed reference.
///
/// # Example
/// ```
/// use ptrplus::AsPtr;
///
/// let x: &u32 = &5;
/// let y: *const u32 = x.as_ptr();
/// unsafe {
///     assert_eq!(*y, 5);
/// }
/// ```
///
/// ```
/// use ptrplus::AsPtr;
///
/// let x = 5;
/// let o1: Option<&u32> = None;
/// let o2: Option<&u32> = Some(&x);
///
/// assert!(o1.as_ptr().is_null());
/// assert!(!o2.as_ptr().is_null());
/// unsafe {
///     assert_eq!(*o2.as_ptr(), 5);
/// }
/// ```
pub trait AsPtr {
    /// The type pointed to
    ///
    /// `as_ptr` will return a pointer to this type
    type Raw;

    /// Returns a raw pointer to the contained content
    ///
    /// The caller must ensure `self` outlives the pointer
    /// that is returned, or else it will end up pointing
    /// to garbage.
    ///
    /// Mutating `self` may also invalidate this pointer,
    /// depending on the implementation.
    fn as_ptr(&self) -> *const Self::Raw;
}

impl<T> AsPtr for [T] {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        <[T]>::as_ptr(self)
    }
}

impl AsPtr for CStr {
    type Raw = c_char;
    fn as_ptr(&self) -> *const c_char {
        CStr::as_ptr(self)
    }
}

impl<'a, T> AsPtr for &'a T
where
    T: Sized,
{
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        *self as *const T
    }
}

impl<T> AsPtr for *const T {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        *self
    }
}

impl<T> AsPtr for Cell<T>
where
    T: Copy,
{
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        Cell::as_ptr(self)
    }
}

impl<T> AsPtr for RefCell<T> {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        RefCell::as_ptr(self)
    }
}

impl<T> AsPtr for Box<T> {
    type Raw = T;
    fn as_ptr(&self) -> *const T {
        self.deref().as_ptr()
    }
}

impl AsPtr for CString {
    type Raw = c_char;

    fn as_ptr(&self) -> *const c_char {
        CStr::as_ptr(self)
    }
}

impl<T> AsPtr for Option<T>
where
    T: AsPtr,
{
    type Raw = T::Raw;
    fn as_ptr(&self) -> *const T::Raw {
        match self {
            Some(ref v) => v.as_ptr(),
            None => ptr::null(),
        }
    }
}

/// Trait for types that implement `into_raw`
///
/// This is implemented by types that can be converted
/// into a pointer by consuming ownership of the object
///
/// # Example
/// ```
/// use ptrplus::IntoRaw;
///
/// let x: Box<u32> = Box::new(5);
/// let y: *mut u32 = IntoRaw::into_raw(x);
/// unsafe {
///   assert_eq!(*y, 5);
///   *y = 6;
///   Box::from_raw(y);
/// }
///
/// ```
///
/// ```
/// use ptrplus::{FromRaw, IntoRaw};
///
/// let o1: Option<Box<u32>> = None;
/// let o2: Option<Box<u32>> = Some(Box::new(5));
///
/// let p1: *mut u32 = o1.into_raw();
/// let p2: *mut u32 = o2.into_raw();
///
/// assert!(p1.is_null());
/// assert!(!p2.is_null());
/// unsafe {
///     assert_eq!(*p2, 5);
///     let o1: Option<Box<u32>> = Option::from_raw(p1);
///     let o2: Option<Box<u32>> = Option::from_raw(p2);
///     assert!(o1.is_none());
///     assert!(!o2.is_none());
/// }
/// ```
pub trait IntoRaw {
    /// The type pointed to
    ///
    /// `into_raw` returns a mutable pointer to this type
    type Raw;

    /// Consumes `self` returning the wrapped raw pointer.
    ///
    /// After calling this method, the caller is responsable
    /// for making sure any resources attached to this pointer
    /// (such as memory) are cleaned up. The proper way to do this
    /// is to convert the pointer back to `Self`.
    ///
    /// See `FromRaw`
    fn into_raw(self) -> *mut Self::Raw;
}

impl<T> IntoRaw for Box<T> {
    type Raw = T;
    fn into_raw(self) -> *mut T {
        Box::into_raw(self)
    }
}

impl IntoRaw for CString {
    type Raw = c_char;
    fn into_raw(self) -> *mut c_char {
        CString::into_raw(self)
    }
}

impl<T> IntoRaw for *mut T {
    type Raw = T;
    fn into_raw(self) -> *mut T {
        self
    }
}

impl<T> IntoRaw for Option<T>
where
    T: IntoRaw,
{
    type Raw = T::Raw;
    fn into_raw(self) -> *mut T::Raw {
        match self {
            Some(v) => v.into_raw(),
            None => ptr::null_mut(),
        }
    }
}

/// Trait for types that can be created from a raw pointer
///
/// # Examples
/// ```
/// use ptrplus::{FromRaw, IntoRaw};
///
/// let x: Box<u32> = Box::new(5);
/// let y = x.into_raw();
/// let z: Box<u32> = unsafe { FromRaw::from_raw(y) };
/// assert_eq!(*z, 5);
///
/// ```
///
pub trait FromRaw<T> {
    /// Create `Self` from a raw pointer
    ///
    /// After calling this method the raw pointer
    /// is owned by the resulting object. This
    /// means that the resulting object should
    /// clean up any resources associated with
    /// the pointer (such as memory).
    ///
    /// # Safety
    ///
    /// `raw` must be a pointer that is compatible with
    /// the resulting type. For example, if `Self` is
    /// `Box<T>`, then `raw` must be a pointer to memory allocated
    /// as a Box. The exact requirements depend on the implementation.
    ///
    /// Additionally, this function takes ownership of the pointer. If
    /// `raw` or an alias thereof is used after calling this function
    /// it can potentially result in double-free, data races, or other
    /// undefined behavior.
    unsafe fn from_raw(raw: *mut T) -> Self;
}

///
impl<T> FromRaw<T> for Box<T> {
    unsafe fn from_raw(raw: *mut T) -> Self {
        Box::from_raw(raw)
    }
}

impl FromRaw<c_char> for CString {
    unsafe fn from_raw(raw: *mut c_char) -> CString {
        CString::from_raw(raw)
    }
}

impl<T> FromRaw<T> for *mut T {
    unsafe fn from_raw(raw: *mut T) -> *mut T {
        raw
    }
}

impl<T, U> FromRaw<U> for Option<T>
where
    T: FromRaw<U>,
{
    unsafe fn from_raw(raw: *mut U) -> Option<T> {
        if raw.is_null() {
            None
        } else {
            Some(T::from_raw(raw))
        }
    }
}
<|endoftext|>