<commit_before>use std::path::Path;
use std::fs::File;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage { cover_image: image::open(&Path::new(&file_path)).unwrap() }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let tiled_image = tile_image(c_image);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<commit_msg>start of dct<commit_after>use std::path::Path;
use std::fs::File;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage { cover_image: image::open(&Path::new(&file_path)).unwrap() }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let mut tiled_image_vec = tile_image(c_image);
    let encoded_image = dct(&mut tiled_image_vec, bit_vec);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {
                    image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

fn dct(tiled_image: &mut Vec<image::Rgba<u8>>, message: &Vec<u8>) {
    for (x, y) in (0..2).enumerate() {

    }
}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<|endoftext|>


<commit_before>
use ffi;
use num_traits::{One, Zero};
use std::ops::*;

#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Copy)]
pub struct c64(ffi::fftw_complex);

impl Deref for c64 {
    type Target = ffi::fftw_complex;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for c64 {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl c64 {
    pub fn re(&self) -> f64 {
        self[0]
    }
    pub fn im(&self) -> f64 {
        self[1]
    }
    pub fn new(re: f64, im: f64) -> Self {
        c64([re, im])
    }
    pub fn abs(&self) -> f64 {
        (self.re() * self.re() + self.im() * self.im()).sqrt()
    }
}

impl Add for c64 {
    type Output = c64;
    fn add(self, other: Self) -> Self {
        c64([self.re() + other.re(), self.im() + other.im()])
    }
}

impl Sub for c64 {
    type Output = c64;
    fn sub(self, other: Self) -> Self {
        c64([self.re() - other.re(), self.im() - other.im()])
    }
}

impl Neg for c64 {
    type Output = c64;
    fn neg(self) -> Self {
        c64([-self[0], self[1]])
    }
}

impl Mul for c64 {
    type Output = c64;
    fn mul(self, other: Self) -> Self {
        c64([self.re() * other.re() - self.im() * other.im(),
             self.re() * other.im() + self.im() * other.re()])
    }
}

impl Add<f64> for c64 {
    type Output = c64;
    fn add(self, other: f64) -> Self {
        c64([self.re() + other, self.im()])
    }
}

impl AddAssign<f64> for c64 {
    fn add_assign(&mut self, rhs: f64) {
        self[0] += rhs;
    }
}

impl Mul<f64> for c64 {
    type Output = c64;
    fn mul(self, other: f64) -> Self {
        c64([self.re() * other, self.im() * other])
    }
}

impl MulAssign<f64> for c64 {
    fn mul_assign(&mut self, rhs: f64) {
        self[0] *= rhs;
        self[1] *= rhs;
    }
}

impl Div<f64> for c64 {
    type Output = c64;
    fn div(self, rhs: f64) -> Self {
        c64([self.re() / rhs, self.im() / rhs])
    }
}

impl One for c64 {
    fn one() -> Self {
        c64([1.0, 0.0])
    }
}

impl Zero for c64 {
    fn zero() -> Self {
        c64([0.0, 0.0])
    }
    fn is_zero(&self) -> bool {
        self.re().is_zero() && self.im().is_zero()
    }
}
<commit_msg>Bug fix<commit_after>
use ffi;
use num_traits::{One, Zero};
use std::ops::*;

#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Copy)]
pub struct c64(ffi::fftw_complex);

impl Deref for c64 {
    type Target = ffi::fftw_complex;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for c64 {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl c64 {
    pub fn re(&self) -> f64 {
        self[0]
    }
    pub fn im(&self) -> f64 {
        self[1]
    }
    pub fn new(re: f64, im: f64) -> Self {
        c64([re, im])
    }
    pub fn abs(&self) -> f64 {
        (self.re() * self.re() + self.im() * self.im()).sqrt()
    }
}

impl Add for c64 {
    type Output = c64;
    fn add(self, other: Self) -> Self {
        c64([self.re() + other.re(), self.im() + other.im()])
    }
}

impl Sub for c64 {
    type Output = c64;
    fn sub(self, other: Self) -> Self {
        c64([self.re() - other.re(), self.im() - other.im()])
    }
}

impl Neg for c64 {
    type Output = c64;
    fn neg(self) -> Self {
        c64([-self[0], -self[1]])
    }
}

impl Mul for c64 {
    type Output = c64;
    fn mul(self, other: Self) -> Self {
        c64([self.re() * other.re() - self.im() * other.im(),
             self.re() * other.im() + self.im() * other.re()])
    }
}

impl Add<f64> for c64 {
    type Output = c64;
    fn add(self, other: f64) -> Self {
        c64([self.re() + other, self.im()])
    }
}

impl AddAssign<f64> for c64 {
    fn add_assign(&mut self, rhs: f64) {
        self[0] += rhs;
    }
}

impl Mul<f64> for c64 {
    type Output = c64;
    fn mul(self, other: f64) -> Self {
        c64([self.re() * other, self.im() * other])
    }
}

impl MulAssign<f64> for c64 {
    fn mul_assign(&mut self, rhs: f64) {
        self[0] *= rhs;
        self[1] *= rhs;
    }
}

impl Div<f64> for c64 {
    type Output = c64;
    fn div(self, rhs: f64) -> Self {
        c64([self.re() / rhs, self.im() / rhs])
    }
}

impl One for c64 {
    fn one() -> Self {
        c64([1.0, 0.0])
    }
}

impl Zero for c64 {
    fn zero() -> Self {
        c64([0.0, 0.0])
    }
    fn is_zero(&self) -> bool {
        self.re().is_zero() && self.im().is_zero()
    }
}
<|endoftext|>


<commit_before>//! Composition tools

use rotor::mio::EventSet;
use rotor::void::{Void, unreachable};
use rotor::{Machine, Scope, Response};

/// Composes two state machines where of the state machines spawns
/// multiple instances of another one
pub enum Spawn<S: Spawner> {
    Spawner(S),
    Child(S::Child),
}

pub trait Spawner: Machine<Seed=Void> {
    type Child: Machine<Context=Self::Context, Seed=Void>;
    type Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>;
}

impl<T, C> Spawner for ::uniform::Uniform<T>
    where T: Spawner<Context=C> + ::uniform::Action<Seed=Void, Context=C>
{
    type Child = T::Child;
    type Seed = <T as Spawner>::Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>
    {
        T::spawn(seed, scope)
    }
}

impl<S> Machine for Spawn<S>
    where S: Spawner,
{
    type Context = <S::Child as Machine>::Context;
    type Seed = <S as Spawner>::Seed;

    fn create(seed: <S as Spawner>::Seed, scope: &mut Scope<Self::Context>)
        -> Response<Self, Void>
    {
        S::spawn(seed, scope).wrap(Spawn::Child)
    }
    fn ready(self, events: EventSet, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.ready(events, scope)
                             .map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.ready(events, scope)
                           .map(Child, |x| unreachable(x)) }
        }
    }
    fn spawned(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.spawned(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.spawned(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn timeout(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.timeout(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.timeout(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn wakeup(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.wakeup(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.wakeup(scope).map(Child, |x| unreachable(x)) }
        }
    }
}
<commit_msg>Another correction of Spawner abstraction<commit_after>//! Composition tools

use rotor::mio::EventSet;
use rotor::void::{Void, unreachable};
use rotor::{Machine, Scope, Response};

/// Composes two state machines where of the state machines spawns
/// multiple instances of another one
pub enum Spawn<S: Spawner> {
    Spawner(S),
    Child(S::Child),
}

pub trait Spawner {
    type Child: Machine<Seed=Void>;
    type Seed;

    fn spawn(seed: Self::Seed,
        scope: &mut Scope<<Self::Child as Machine>::Context>)
        -> Response<Self::Child, Void>;
}

impl<T, C> Spawner for ::uniform::Uniform<T>
    where T: Spawner + ::uniform::Action<Seed=Void, Context=C>
{
    type Child = T::Child;
    type Seed = <T as Spawner>::Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>
    {
        T::spawn(seed, scope)
    }
}

impl<S, C> Machine for Spawn<S>
    where S: Spawner<Child=C> + Machine<Context=C::Context, Seed=Void>,
          C: Machine<Seed=Void>,
{
    type Context = <S::Child as Machine>::Context;
    type Seed = <S as Spawner>::Seed;

    fn create(seed: <S as Spawner>::Seed, scope: &mut Scope<Self::Context>)
        -> Response<Self, Void>
    {
        S::spawn(seed, scope).wrap(Spawn::Child)
    }
    fn ready(self, events: EventSet, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.ready(events, scope)
                             .map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.ready(events, scope)
                           .map(Child, |x| unreachable(x)) }
        }
    }
    fn spawned(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.spawned(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.spawned(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn timeout(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.timeout(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.timeout(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn wakeup(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.wakeup(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.wakeup(scope).map(Child, |x| unreachable(x)) }
        }
    }
}
<|endoftext|>


<commit_before>use std;
use std::io;

use ::as_u16;
use ::as_u32;

use ::errors::Result;
use ::errors::ErrorKind::*;

#[derive(Debug)]
struct Extent {
    block: u32,
    start: u64,
    len: u16,
}

pub struct TreeReader<R> {
    inner: R,
    pos: u64,
    len: u64,
    block_size: u32,
    extents: Vec<Extent>,
}

impl<R> TreeReader<R>
where R: io::Read + io::Seek {
    pub fn new(mut inner: R, block_size: u32, size: u64, block: [u8; 4 * 15]) -> Result<TreeReader<R>> {
        let extents = load_extent_tree(&mut inner, block, block_size)?;
        TreeReader::create(inner, block_size, size, extents)
    }

    fn create(inner: R, block_size: u32, size: u64, extents: Vec<Extent>) -> Result<TreeReader<R>> {
        Ok(TreeReader {
            pos: 0,
            len: size,
            inner,
            extents,
            block_size,
        })
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

enum FoundBlock<'a> {
    Actual(&'a Extent),
    Sparse(u32),
}

fn find_block(block: u32, extents: &[Extent]) -> FoundBlock {
    for extent in extents {
        if block < extent.block {
            // we've gone past it
            return FoundBlock::Sparse(extent.block - block);
        }

        if block >= extent.block && block < extent.block + extent.len as u32 {
            // we're inside it
            return FoundBlock::Actual(extent);
        }
    }

    return FoundBlock::Sparse(std::u32::MAX);
}

impl<R> io::Read for TreeReader<R>
    where R: io::Read + io::Seek {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let block_size = self.block_size as u64;

        let wanted_block = (self.pos / block_size) as u32;
        let read_of_this_block = self.pos % block_size;

        match find_block(wanted_block, &self.extents) {
            FoundBlock::Actual(extent) => {
                let bytes_through_extent = (block_size * (wanted_block - extent.block) as u64) + read_of_this_block;
                let remaining_bytes_in_extent = (extent.len as u64 * block_size) - bytes_through_extent;
                let to_read = std::cmp::min(remaining_bytes_in_extent, buf.len() as u64) as usize;
                let to_read = std::cmp::min(to_read as u64, self.len - self.pos) as usize;
                self.inner.seek(io::SeekFrom::Start(extent.start as u64 * block_size + bytes_through_extent))?;
                let read = self.inner.read(&mut buf[0..to_read])?;
                self.pos += read as u64;
                return Ok(read);
            }
            FoundBlock::Sparse(max) => {
                let max_bytes = max as u64 * block_size;
                let read = std::cmp::min(max_bytes, buf.len() as u64) as usize;
                let read = std::cmp::min(read as u64, self.len - self.pos) as usize;
                zero(&mut buf[0..read]);
                self.pos += read as u64;
                return Ok(read);
            }
        }
    }
}

impl<R> io::Seek for TreeReader<R>
where R: io::Read + io::Seek {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(set) => { self.pos = set }
            io::SeekFrom::Current(diff) => { self.pos = (self.pos as i64 + diff) as u64 }
            io::SeekFrom::End(set) => {
                assert!(set >= 0);
                self.pos = self.len - set as u64
            }
        }

        assert!(self.pos <= self.len);

        Ok(self.pos)
    }
}

fn add_found_extents<R>(
    block_size: u32,
    mut inner: &mut R,
    block: &[u8],
    expected_depth: u16,
    extents: &mut Vec<Extent>) -> Result<()>
where R: io::Read + io::Seek {

    ensure!(0x0a == block[0] && 0xf3 == block[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&block[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&block[6..]);
    // 8..: generation, not used in standard ext4

    ensure!(expected_depth == depth,
        AssumptionFailed(format!("depth incorrect: {} != {}", expected_depth, depth)));

    if 0 == depth {
        for en in 0..extent_entries {
            let raw_extent = &block[12 + en as usize * 12..];
            let ee_block = as_u32(raw_extent);
            let ee_len = as_u16(&raw_extent[4..]);
            let ee_start_hi = as_u16(&raw_extent[6..]);
            let ee_start_lo = as_u32(&raw_extent[8..]);
            let ee_start = ee_start_lo as u64 + 0x1000 * ee_start_hi as u64;

            extents.push(Extent {
                block: ee_block,
                start: ee_start,
                len: ee_len,
            });
        }

        return Ok(());
    }

    for en in 0..extent_entries {
        let extent_idx = &block[12 + en as usize * 12..];
        //            let ei_block = as_u32(extent_idx);
        let ei_leaf_lo = as_u32(&extent_idx[4..]);
        let ei_leaf_hi = as_u16(&extent_idx[8..]);
        let ee_leaf: u64 = ei_leaf_lo as u64 + ((ei_leaf_hi as u64) << 32);
        inner.seek(io::SeekFrom::Start(block_size as u64 * ee_leaf))?;
        let mut block = vec![0u8; block_size as usize];
        inner.read_exact(&mut block)?;
        add_found_extents(block_size, inner, &block, depth - 1, extents)?;
    }

    Ok(())
}

fn load_extent_tree<R>(mut inner: R, start: [u8; 4 * 15], block_size: u32) -> Result<Vec<Extent>>
    where R: io::Read + io::Seek {
    ensure!(0x0a == start[0] && 0xf3 == start[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&start[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&start[6..]);

    ensure!(depth <= 5,
        AssumptionFailed(format!("initial depth too high: {}", depth)));

    let mut extents = Vec::with_capacity(extent_entries as usize + depth as usize * 200);

    add_found_extents(block_size, &mut inner, &start, depth, &mut extents)?;

    extents.sort_by_key(|e| e.block);

    Ok(extents)
}

fn zero(buf: &mut [u8]) {
    for i in buf {
        *i = 0;
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use ::extents::TreeReader;
    use ::extents::Extent;

    #[test]
    fn simple_tree() {
        let data = (0..255u8).collect::<Vec<u8>>();
        let size = 4 + 4 * 2;
        let all_bytes = io::Cursor::new(data);
        let mut reader = TreeReader::create(all_bytes, 4, size as u64,
            vec![
                Extent {
                    block: 0,
                    start: 10,
                    len: 1,
                },
                Extent {
                    block: 1,
                    start: 20,
                    len: 2,
                }
            ]
        ).unwrap();

        let mut res = Vec::new();
        assert_eq!(size, reader.read_to_end(&mut res).unwrap());

        assert_eq!(vec![
            40, 41, 42, 43,
            80, 81, 82, 83,
            84, 85, 86, 87,
        ], res);
    }

    #[test]
    fn zero_buf() {
        let mut buf = [7u8; 5];
        assert_eq!(7, buf[0]);
        ::extents::zero(&mut buf);
        for i in &buf {
            assert_eq!(0, *i);
        }
    }
}
<commit_msg>use 'unsafe' memset to make tests not as unbearably slow in debug mode<commit_after>use std;
use std::io;

use ::as_u16;
use ::as_u32;

use ::errors::Result;
use ::errors::ErrorKind::*;

#[derive(Debug)]
struct Extent {
    block: u32,
    start: u64,
    len: u16,
}

pub struct TreeReader<R> {
    inner: R,
    pos: u64,
    len: u64,
    block_size: u32,
    extents: Vec<Extent>,
}

impl<R> TreeReader<R>
where R: io::Read + io::Seek {
    pub fn new(mut inner: R, block_size: u32, size: u64, block: [u8; 4 * 15]) -> Result<TreeReader<R>> {
        let extents = load_extent_tree(&mut inner, block, block_size)?;
        TreeReader::create(inner, block_size, size, extents)
    }

    fn create(inner: R, block_size: u32, size: u64, extents: Vec<Extent>) -> Result<TreeReader<R>> {
        Ok(TreeReader {
            pos: 0,
            len: size,
            inner,
            extents,
            block_size,
        })
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

enum FoundBlock<'a> {
    Actual(&'a Extent),
    Sparse(u32),
}

fn find_block(block: u32, extents: &[Extent]) -> FoundBlock {
    for extent in extents {
        if block < extent.block {
            // we've gone past it
            return FoundBlock::Sparse(extent.block - block);
        }

        if block >= extent.block && block < extent.block + extent.len as u32 {
            // we're inside it
            return FoundBlock::Actual(extent);
        }
    }

    return FoundBlock::Sparse(std::u32::MAX);
}

impl<R> io::Read for TreeReader<R>
    where R: io::Read + io::Seek {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let block_size = self.block_size as u64;

        let wanted_block = (self.pos / block_size) as u32;
        let read_of_this_block = self.pos % block_size;

        match find_block(wanted_block, &self.extents) {
            FoundBlock::Actual(extent) => {
                let bytes_through_extent = (block_size * (wanted_block - extent.block) as u64) + read_of_this_block;
                let remaining_bytes_in_extent = (extent.len as u64 * block_size) - bytes_through_extent;
                let to_read = std::cmp::min(remaining_bytes_in_extent, buf.len() as u64) as usize;
                let to_read = std::cmp::min(to_read as u64, self.len - self.pos) as usize;
                self.inner.seek(io::SeekFrom::Start(extent.start as u64 * block_size + bytes_through_extent))?;
                let read = self.inner.read(&mut buf[0..to_read])?;
                self.pos += read as u64;
                return Ok(read);
            }
            FoundBlock::Sparse(max) => {
                let max_bytes = max as u64 * block_size;
                let read = std::cmp::min(max_bytes, buf.len() as u64) as usize;
                let read = std::cmp::min(read as u64, self.len - self.pos) as usize;
                zero(&mut buf[0..read]);
                self.pos += read as u64;
                return Ok(read);
            }
        }
    }
}

impl<R> io::Seek for TreeReader<R>
where R: io::Read + io::Seek {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(set) => { self.pos = set }
            io::SeekFrom::Current(diff) => { self.pos = (self.pos as i64 + diff) as u64 }
            io::SeekFrom::End(set) => {
                assert!(set >= 0);
                self.pos = self.len - set as u64
            }
        }

        assert!(self.pos <= self.len);

        Ok(self.pos)
    }
}

fn add_found_extents<R>(
    block_size: u32,
    mut inner: &mut R,
    block: &[u8],
    expected_depth: u16,
    extents: &mut Vec<Extent>) -> Result<()>
where R: io::Read + io::Seek {

    ensure!(0x0a == block[0] && 0xf3 == block[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&block[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&block[6..]);
    // 8..: generation, not used in standard ext4

    ensure!(expected_depth == depth,
        AssumptionFailed(format!("depth incorrect: {} != {}", expected_depth, depth)));

    if 0 == depth {
        for en in 0..extent_entries {
            let raw_extent = &block[12 + en as usize * 12..];
            let ee_block = as_u32(raw_extent);
            let ee_len = as_u16(&raw_extent[4..]);
            let ee_start_hi = as_u16(&raw_extent[6..]);
            let ee_start_lo = as_u32(&raw_extent[8..]);
            let ee_start = ee_start_lo as u64 + 0x1000 * ee_start_hi as u64;

            extents.push(Extent {
                block: ee_block,
                start: ee_start,
                len: ee_len,
            });
        }

        return Ok(());
    }

    for en in 0..extent_entries {
        let extent_idx = &block[12 + en as usize * 12..];
        //            let ei_block = as_u32(extent_idx);
        let ei_leaf_lo = as_u32(&extent_idx[4..]);
        let ei_leaf_hi = as_u16(&extent_idx[8..]);
        let ee_leaf: u64 = ei_leaf_lo as u64 + ((ei_leaf_hi as u64) << 32);
        inner.seek(io::SeekFrom::Start(block_size as u64 * ee_leaf))?;
        let mut block = vec![0u8; block_size as usize];
        inner.read_exact(&mut block)?;
        add_found_extents(block_size, inner, &block, depth - 1, extents)?;
    }

    Ok(())
}

fn load_extent_tree<R>(mut inner: R, start: [u8; 4 * 15], block_size: u32) -> Result<Vec<Extent>>
    where R: io::Read + io::Seek {
    ensure!(0x0a == start[0] && 0xf3 == start[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&start[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&start[6..]);

    ensure!(depth <= 5,
        AssumptionFailed(format!("initial depth too high: {}", depth)));

    let mut extents = Vec::with_capacity(extent_entries as usize + depth as usize * 200);

    add_found_extents(block_size, &mut inner, &start, depth, &mut extents)?;

    extents.sort_by_key(|e| e.block);

    Ok(extents)
}

fn zero(mut buf: &mut [u8]) {
    unsafe {
        std::ptr::write_bytes(buf.as_mut_ptr(), 0u8, buf.len())
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use ::extents::TreeReader;
    use ::extents::Extent;

    #[test]
    fn simple_tree() {
        let data = (0..255u8).collect::<Vec<u8>>();
        let size = 4 + 4 * 2;
        let all_bytes = io::Cursor::new(data);
        let mut reader = TreeReader::create(all_bytes, 4, size as u64,
            vec![
                Extent {
                    block: 0,
                    start: 10,
                    len: 1,
                },
                Extent {
                    block: 1,
                    start: 20,
                    len: 2,
                }
            ]
        ).unwrap();

        let mut res = Vec::new();
        assert_eq!(size, reader.read_to_end(&mut res).unwrap());

        assert_eq!(vec![
            40, 41, 42, 43,
            80, 81, 82, 83,
            84, 85, 86, 87,
        ], res);
    }

    #[test]
    fn zero_buf() {
        let mut buf = [7u8; 5];
        assert_eq!(7, buf[0]);
        ::extents::zero(&mut buf);
        for i in &buf {
            assert_eq!(0, *i);
        }
    }
}
<|endoftext|>


<commit_before>//! Interval-based annotation features.

use std::collections::HashMap;
use std::iter::FromIterator;

use bio::data_structures::interval_tree::{IntervalTree, IntervalTreeIterator};
use bio::io::Strand;
use bio::utils::{Interval, IntervalError};

pub trait NamedInterval: Sized {

    /// Underlying interval struct.
    fn interval(&self) -> &Interval<u64>;  // TODO: Generalize over interval types.

    /// Name of the interval.
    fn name(&self) -> Option<&str>;

    /// Name setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_name<T: Into<String>>(self, name: T) -> Self;

    /// Coordinate setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_coords(self, start: u64, end: u64) -> Result<Self, IntervalError>;

    /// Start coordinate of the interval.
    fn start(&self) -> u64 {
        self.interval().start
    }

    /// End coordinate of the interval.
    fn end(&self) -> u64 {
        self.interval().end
    }

    /// The number of bases covered by the interval.
    fn span(&self) -> u64 {
        self.end() - self.start()
    }

    /// Whether two intervals have an overlap or not.
    fn overlaps(&self, other: &Self) -> bool {
        self.start() < other.end() && other.start() < self.end()
    }

    /// Whether one interval completely contains the other.
    fn envelops(&self, other: &Self) -> bool {
        self.start() <= other.start() && self.end() >= other.end()
    }

    /// Whether two intervals cover a contiguous region without any overlaps.
    fn is_adjacent(&self, other: &Self) -> bool {
        self.end() == other.start() || self.start() == other.end()
    }
}

/// Macro for default function implementations of interval types.
macro_rules! impl_ninterval {
    ($struct_ty:ty) => (

        impl NamedInterval for $struct_ty {

            /// Name of the interval.
            fn name(&self) -> Option<&str> {
                self.name.as_ref().map(|n| n.as_str())
            }

            fn with_name<T>(mut self, name: T) -> $struct_ty
                where T: Into<String>
            {
                self.name = Some(name.into());
                self
            }

            fn interval(&self) -> &Interval<u64> {
                &self.interval
            }

            fn with_coords(mut self, start: u64, end: u64) -> Result<$struct_ty, IntervalError> {
                Interval::new(start..end)
                    .map(|iv| {
                        self.interval = iv;
                        self
                    })
            }
        }

    );
}

/// Default implementation of the `Interval` trait.
///
/// This struct also provides static methods for creating exons, transcripts, and genes.
#[derive(Debug)]
pub struct Feature {
    interval: Interval<u64>,
    name: Option<String>,
}

impl Default for Feature {

    fn default() -> Feature {
        Feature { interval: Interval::new(0..0).unwrap(), name: None }
    }
}

impl Feature {

    /// Creates a gene interval with default values.
    ///
    /// A gene interval is a container for transcript intervals.
    ///
    /// # Examples
    ///
    /// ```
    /// let gene = Feature::gene();
    ///
    /// assert_eq!(gene.transcript().len(), 0);
    /// assert_eq!(gene.start(), 0);
    /// assert_eq!(gene.end(), 0);
    /// assert!(gene.name().is_none());
    /// ```
    pub fn gene() -> Gene {
        Gene::default()
    }

    /// Creates a transcript interval with default values.
    ///
    /// A transcript interval is a container for exon intervals.
    ///
    /// # Examples
    ///
    /// ```
    /// use bio::io::Strand;
    ///
    /// let transcript = Feature::transcript();
    ///
    /// assert_eq!(transcript.exons().len(), 0);
    /// assert_eq!(transcript.strand(), &Strand::Unknown)
    /// assert_eq!(transcript.start(), 0);
    /// assert_eq!(transcript.end(), 0);
    /// assert!(transcript.name().is_none());
    /// ```
    pub fn transcript() -> Transcript {
        Transcript::default()
    }

    /// Creates an exon interval with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// let exon = Feature::exon();
    ///
    /// assert_eq!(exon.start(), 0);
    /// assert_eq!(exon.end(), 0);
    /// assert!(exon.name().is_none());
    /// ```
    pub fn exon() -> Exon {
        Exon::default()
    }
}

impl_ninterval!(Feature);

/// Exon annotation.
#[derive(Debug)]
pub struct Exon {
    interval: Interval<u64>,
    name: Option<String>,
}

impl Default for Exon {

    fn default() -> Exon {
        Exon { interval: Interval::new(0..0).unwrap(), name: None }
    }
}

impl_ninterval!(Exon);

/// Transcript annotation.
#[derive(Debug)]
pub struct Transcript {
    interval: Interval<u64>,
    name: Option<String>,
    strand: Strand,
    cds: Option<Feature>,
    exons: IntervalTree<u64, Exon>,
}

impl Default for Transcript {

    fn default() -> Transcript {
        Transcript {
            interval: Interval::new(0..0).unwrap(),
            name: None,
            strand: Strand::Unknown,
            cds: None,
            exons: IntervalTree::new(),
        }
    }
}

impl_ninterval!(Transcript);

impl Transcript {

    pub fn strand(&self) -> &Strand {
        &self.strand
    }

    pub fn with_strand(mut self, strand: Strand) -> Transcript {
        self.strand = strand;
        self
    }

    pub fn exons(&self) -> &IntervalTree<u64, Exon> {
        &self.exons
    }

    pub fn with_exons<I>(mut self, exons: I) -> Transcript
        where I: IntoIterator<Item=Exon>
    {
        let exp_iter = exons.into_iter()
            .map(|exn| (exn.interval.clone(), exn));
        self.exons = IntervalTree::from_iter(exp_iter);
        self
    }

    pub fn insert_exon(&mut self, exon: Exon) {
        self.exons.insert(exon.start()..exon.end(), exon);
    }

    pub fn cds(&self) -> Option<&Feature> {
        self.cds.as_ref()
    }

    pub fn with_cds(mut self, cds: Feature) -> Transcript {
        self.cds = Some(cds);
        self
    }

    pub fn iter(&self) -> IntervalTreeIterator<u64, Exon> {
        // FIXME: iteration over IntervalTree items instead of using (min, max) hack.
        self.exons.find(0..u64::max_value())
    }

    /// Returns the number of exons in the trancripts in O(n) time.
    pub fn len(&self) -> usize {
        self.iter().map(|_exon| 1).fold(0, |acc, x| acc + x)
    }
}

/// Gene annotation.
#[derive(Debug)]
pub struct Gene {
    interval: Interval<u64>,
    name: Option<String>,
    transcripts: HashMap<String, Transcript>,
}

impl Default for Gene {

    fn default() -> Gene {
        Gene { interval: Interval::new(0..0).unwrap(),
               name: None,
               transcripts: HashMap::new(),
        }
    }
}

impl_ninterval!(Gene);

impl Gene {

    pub fn transcripts(&self) -> &HashMap<String, Transcript> {
        &self.transcripts
    }
}

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

    #[test]
    fn default() {
        let fx = Feature::default();
        assert_eq!(fx.start(), 0);
        assert_eq!(fx.end(), 0);
        assert!(fx.name().is_none());
    }

    #[test]
    fn with_name() {
        let fx1 = Feature::default()
            .with_name("fx1");
        assert_eq!(fx1.start(), 0);
        assert_eq!(fx1.end(), 0);
        assert_eq!(fx1.name(), Some("fx1"));

        let fx2 = Feature::default()
            .with_name("fx2".to_owned());
        assert_eq!(fx2.start(), 0);
        assert_eq!(fx2.end(), 0);
        assert_eq!(fx2.name(), Some("fx2"));
    }

    #[test]
    fn with_coords() {
        let fxm = Feature::default()
            .with_coords(1, 3);
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 1);
        assert_eq!(fx.end(), 3);
        assert!(fx.name().is_none());
    }

    #[test]
    fn with_coords_err() {
        let fxm = Feature::default()
            .with_coords(3, 1);
        assert!(fxm.is_err());
    }

    #[test]
    fn with_multiples() {
        let fxm = Feature::default()
            .with_coords(20, 30)
            .map(|f| f.with_name("fx"));
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 20);
        assert_eq!(fx.end(), 30);
        assert_eq!(fx.name(), Some("fx"));
    }

    fn make_feature(start: u64, end: u64) -> Feature {
        Feature::default().with_coords(start, end).unwrap()
    }

    #[test]
    fn span() {
        let fx = make_feature(0, 15);
        assert_eq!(fx.span(), 15);
    }

    #[test]
    fn overlaps() {
        let fx1 = make_feature(100, 115);

        let fx2 = make_feature(110, 120);
        assert!(fx1.overlaps(&fx2));
        assert!(fx1.overlaps(&fx2));

        let fx3 = make_feature(115, 120);
        assert!(!fx1.overlaps(&fx3));
        assert!(!fx3.overlaps(&fx1));

        let fx4 = make_feature(90, 100);
        assert!(!fx1.overlaps(&fx4));
        assert!(!fx4.overlaps(&fx1));

        let fx5 = make_feature(200, 300);
        assert!(!fx1.overlaps(&fx5));
        assert!(!fx5.overlaps(&fx1));
    }

    #[test]
    fn envelops() {
        let fx1 = make_feature(100, 120);

        let fx2 = make_feature(105, 115);
        assert!(fx1.envelops(&fx2));
        assert!(!fx2.envelops(&fx1));

        let fx3 = make_feature(100, 105);
        assert!(fx1.envelops(&fx3));
        assert!(!fx3.envelops(&fx1));

        let fx4 = make_feature(115, 120);
        assert!(fx1.envelops(&fx4));
        assert!(!fx4.envelops(&fx1));

        let fx5 = make_feature(90, 105);
        assert!(!fx1.envelops(&fx5));
        assert!(!fx5.envelops(&fx1));

        let fx6 = make_feature(115, 130);
        assert!(!fx1.envelops(&fx5));
        assert!(!fx6.envelops(&fx1));

        let fx7 = make_feature(80, 90);
        assert!(!fx1.envelops(&fx7));
        assert!(!fx7.envelops(&fx1));
    }

    #[test]
    fn is_adjacent() {
        let fx1 = make_feature(100, 120);

        let fx2 = make_feature(90, 100);
        assert!(fx1.is_adjacent(&fx2));
        assert!(fx2.is_adjacent(&fx1));

        let fx3 = make_feature(120, 130);
        assert!(fx1.is_adjacent(&fx3));
        assert!(fx3.is_adjacent(&fx1));

        let fx4 = make_feature(90, 99);
        assert!(!fx1.is_adjacent(&fx4));
        assert!(!fx4.is_adjacent(&fx1));

        let fx5 = make_feature(119, 130);
        assert!(!fx1.is_adjacent(&fx5));
        assert!(!fx5.is_adjacent(&fx1));

        let fx6 = make_feature(100, 110);
        assert!(!fx1.is_adjacent(&fx6));
        assert!(!fx6.is_adjacent(&fx1));

        let fx7 = make_feature(110, 120);
        assert!(!fx1.is_adjacent(&fx7));
        assert!(!fx7.is_adjacent(&fx1));
    }
}

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

    #[test]
    fn default() {
        let exon = Feature::exon();
        assert_eq!(exon.start(), 0);
        assert_eq!(exon.end(), 0);
        assert!(exon.name().is_none());
    }
}

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

    #[test]
    fn default() {
        let trx = Feature::transcript();
        assert_eq!(trx.start(), 0);
        assert_eq!(trx.end(), 0);
        assert!(trx.name().is_none());
        assert_eq!(trx.strand(), &Strand::Unknown);
        assert!(trx.cds().is_none());
        assert_eq!(trx.len(), 0);
    }

    #[test]
    fn with_strand() {
        let trx = Feature::transcript()
            .with_strand(Strand::Forward);
        assert_eq!(trx.strand(), &Strand::Forward);
    }

    fn make_exon<T: Into<String>>(start: u64, end: u64, name: T) -> Exon {
        Feature::exon()
            .with_name(name)
            .with_coords(start, end).unwrap()
    }

    #[test]
    fn with_exons() {
        let trx = Feature::transcript()
            .with_exons(vec![
                make_exon(1, 2, "ex1"),
                make_exon(10, 20, "ex2"),
                make_exon(100, 200, "ex3"),
            ]);
        assert_eq!(trx.len(), 3);
    }

    #[test]
    fn insert_exon() {
        let mut trx = Feature::transcript();
        assert_eq!(trx.len(), 0);
        trx.insert_exon(make_exon(1, 2, "ex"));
        assert_eq!(trx.len(), 1);
    }
}

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

    #[test]
    fn default() {
        let gene = Feature::gene();
        assert_eq!(gene.start(), 0);
        assert_eq!(gene.end(), 0);
        assert!(gene.name().is_none());
        assert_eq!(gene.transcripts().len(), 0);
    }
}
<commit_msg>Refactor features<commit_after>//! Interval-based annotation features.

use std::error::Error;
use std::collections::HashMap;
use std::fmt::{self, Display};

use bio::io::Strand;
use bio::utils::{Interval, IntervalError};

use self::error::FeatureError;

pub mod error {

    use super::*;

    #[derive(Debug, PartialEq)]
    pub enum FeatureError {
        IntervalError,
        StrandCharError,
    }

    impl Error for FeatureError {

        fn description(&self) -> &str {
            match *self {
                FeatureError::IntervalError => "interval start coordinate larger than its end coordinate",
                FeatureError::StrandCharError => "strand character is invalid",
            }
        }

        fn cause(&self) -> Option<&Error> {
            None
        }
    }

    impl Display for FeatureError {

        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "FeatureError: {}", self.description())
        }
    }
}

trait Annotation {
    fn seq_name(&self) -> &str;
    fn interval(&self) -> &Interval<u64>;
    fn attributes(&self) -> &HashMap<String, String>;
    fn attribute(&self, key: &str) -> Option<&str>;
    fn strand(&self) -> &Strand;
}

macro_rules! impl_annotation {
    ($struct_ty:ty) => (

        impl Annotation for $struct_ty {

            fn seq_name(&self) -> &str {
                self.seq_name.as_str()
            }

            fn interval(&self) -> &Interval<u64> {
                &self.interval
            }

            fn attributes(&self) -> &HashMap<String, String> {
                &self.attributes
            }

            fn attribute(&self, key: &str) -> Option<&str> {
                self.attributes.get(key).map(|n| n.as_str())
            }

            fn strand(&self) -> &Strand {
                &self.strand
            }
        }

    );
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TxFeature {
    Exon,
    UTR,
    UTR5,
    UTR3,
    CDS,
    StartCodon,
    StopCodon,
    Any,
}

#[derive(Debug)]
pub struct TranscriptFeature {
    kind: TxFeature,
    seq_name: String,
    interval: Interval<u64>,
    strand: Strand,
    attributes: HashMap<String, String>
}

impl_annotation!(TranscriptFeature);

impl TranscriptFeature {

    fn kind(&self) -> &TxFeature {
        &self.kind
    }
}

pub struct TxFeatureBuilder {
    seq_name: String,
    start: u64,
    end: u64,
    strand: Strand,
    strand_char: Option<char>,
    attributes: HashMap<String, String>,
    kind: TxFeature,
}

impl TxFeatureBuilder {

    fn new<T>(seq_name: T, start: u64, end: u64) -> TxFeatureBuilder
        where T: Into<String>
    {
        TxFeatureBuilder {
            seq_name: seq_name.into(),
            start: start, end: end,
            kind: TxFeature::Any,
            strand: Strand::Unknown,
            attributes: HashMap::new(),
            strand_char: None,
        }
    }

    fn kind(mut self, kind: TxFeature) -> TxFeatureBuilder {
        self.kind = kind;
        self
    }

    fn strand(mut self, strand: Strand) -> TxFeatureBuilder {
        self.strand = strand;
        self
    }

    fn strand_char(mut self, strand_char: char) -> TxFeatureBuilder {
        self.strand_char = Some(strand_char);
        self
    }

    fn attribute<K, V>(mut self, key: K, value: V) -> TxFeatureBuilder
        where K: Into<String>, V: Into<String>
    {
        self.attributes.insert(key.into(), value.into());
        self
    }

    fn build(self) -> Result<TranscriptFeature, FeatureError> {
        let interval = Interval::new(self.start..self.end)
            .map_err(|err| match err {
                IntervalError::InvalidRange => FeatureError::IntervalError
            })?;

        let strand = match self.strand_char {
            None => Ok(self.strand),
            Some('+') | Some('f') => Ok(Strand::Forward),
            Some('-') | Some('r') => Ok(Strand::Reverse),
            Some('.') | Some('?') => Ok(Strand::Unknown),
            _         => Err(FeatureError::StrandCharError),
        }?;

        let feature = TranscriptFeature {
            seq_name: self.seq_name, kind: self.kind, interval: interval,
            strand: strand, attributes: self.attributes,
        };
        Ok(feature)
    }
}

#[derive(Debug)]
pub struct Transcript {
    seq_name: String,
    interval: Interval<u64>,
    strand: Strand,
    attributes: HashMap<String, String>,
    features: Vec<TranscriptFeature>,
}

impl_annotation!(Transcript);

#[derive(Debug)]
pub struct Gene {
    seq_name: String,
    interval: Interval<u64>,
    strand: Strand,
    attributes: HashMap<String, String>,
    transcripts: HashMap<String, Transcript>,
}

impl_annotation!(Gene);

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

    #[test]
    fn test_builder() {
        let tfm1 = TxFeatureBuilder::new("chrT", 10, 20)
            .kind(TxFeature::Exon)
            .strand(Strand::Forward)
            .attribute("name", "ex1")
            .build();
        assert!(tfm1.is_ok());
        let tf = tfm1.unwrap();
        assert_eq!(tf.seq_name(), "chrT");
        assert_eq!(tf.kind(), &TxFeature::Exon);
        assert_eq!(tf.strand(), &Strand::Forward);
        assert_eq!(tf.attribute("name"), Some("ex1"));
        assert_eq!(tf.attributes.len(), 1);

        let tfm2 = TxFeatureBuilder::new("chrO", 10, 10)
            .build();
        assert!(tfm2.is_ok());
    }

    #[test]
    fn test_builder_strand_char() {
        let tfm = TxFeatureBuilder::new("chrT", 20, 30)
            .strand(Strand::Forward)
            .strand_char('-')
            .build();
        assert!(tfm.is_ok());
        let tf = tfm.unwrap();
        assert_eq!(tf.strand(), &Strand::Reverse);
    }

    #[test]
    fn test_builder_interval_err() {
        let tfm = TxFeatureBuilder::new("chrE", 20, 10).build();
        assert!(tfm.is_err());
        assert_eq!(tfm.unwrap_err(), FeatureError::IntervalError);
    }

    #[test]
    fn test_build_strand_char_err() {
        let tfm = TxFeatureBuilder::new("chrE", 10, 20)
            .strand_char('w')
            .build();
        assert!(tfm.is_err());
        assert_eq!(tfm.unwrap_err(), FeatureError::StrandCharError);
    }
}
<|endoftext|>


<commit_before>use crate::Error;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};

#[cfg(backtrace)]
use std::backtrace::Backtrace;

/// Provides the `context` method for `Result`.
pub trait Context<T, E> {
    /// Wrap the error value with additional context.
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static;

    /// Wrap the error value with additional context lazily.
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C;
}

impl<T, E> Context<T, E> for Result<T, E>
where
    E: StdError + Send + Sync + 'static,
{
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        self.map_err(|error| Error::from(ContextError { error, context }))
    }

    fn with_context<C, F>(self, context: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        self.map_err(|error| {
            Error::from(ContextError {
                error,
                context: context(),
            })
        })
    }
}

impl<T> Context<T, Error> for Result<T, Error> {
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        self.map_err(|error| error.context(context))
    }

    fn with_context<C, F>(self, context: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        self.map_err(|error| error.context(context()))
    }
}

pub(crate) struct ContextError<E, C> {
    pub error: E,
    pub context: C,
}

impl<E, C> Debug for ContextError<E, C>
where
    E: Debug,
    C: Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}\n\n{}", self.error, self.context)
    }
}

impl<E, C> Display for ContextError<E, C>
where
    C: Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.context, f)
    }
}

impl<E, C> StdError for ContextError<E, C>
where
    E: StdError + 'static,
    C: Display,
{
    #[cfg(backtrace)]
    fn backtrace(&self) -> Option<&Backtrace> {
        self.error.backtrace()
    }

    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&self.error)
    }
}

impl<C> StdError for ContextError<Error, C>
where
    C: Display,
{
    #[cfg(backtrace)]
    fn backtrace(&self) -> Option<&Backtrace> {
        Some(self.error.backtrace())
    }

    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&*self.error)
    }
}
<commit_msg>Document Context trait with example<commit_after>use crate::Error;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};

#[cfg(backtrace)]
use std::backtrace::Backtrace;

/// Provides the `context` method for `Result`.
///
/// # Example
///
/// ```
/// use anyhow::{Context, Result};
/// use std::fs;
/// use std::path::PathBuf;
///
/// pub struct ImportantThing {
///     path: PathBuf,
/// }
///
/// impl ImportantThing {
///     # const IGNORE: &'static str = stringify! {
///     pub fn detach(&mut self) -> Result<()> {...}
///     # };
///     # fn detach(&mut self) -> Result<()> {
///     #     unimplemented!()
///     # }
/// }
///
/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
///     it.detach().context("failed to detach the important thing")?;
///
///     let path = &it.path;
///     let content = fs::read(path)
///         .with_context(|| format!("failed to read instrs from {}", path.display()))?;
///
///     Ok(content)
/// }
/// ```
///
/// When printed, the outermost context would be printed first and the lower
/// level underlying causes would be enumerated below.
///
/// ```console
/// Error: failed to read instrs from ./path/to/instrs.jsox
///
/// caused by:
///     0: No such file or directory (os error 2)
/// ```
pub trait Context<T, E> {
    /// Wrap the error value with additional context.
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static;

    /// Wrap the error value with additional context that is evaluated lazily
    /// only once an error does occur.
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C;
}

impl<T, E> Context<T, E> for Result<T, E>
where
    E: StdError + Send + Sync + 'static,
{
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        self.map_err(|error| Error::from(ContextError { error, context }))
    }

    fn with_context<C, F>(self, context: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        self.map_err(|error| {
            Error::from(ContextError {
                error,
                context: context(),
            })
        })
    }
}

impl<T> Context<T, Error> for Result<T, Error> {
    fn context<C>(self, context: C) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
    {
        self.map_err(|error| error.context(context))
    }

    fn with_context<C, F>(self, context: F) -> Result<T, Error>
    where
        C: Display + Send + Sync + 'static,
        F: FnOnce() -> C,
    {
        self.map_err(|error| error.context(context()))
    }
}

pub(crate) struct ContextError<E, C> {
    pub error: E,
    pub context: C,
}

impl<E, C> Debug for ContextError<E, C>
where
    E: Debug,
    C: Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}\n\n{}", self.error, self.context)
    }
}

impl<E, C> Display for ContextError<E, C>
where
    C: Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.context, f)
    }
}

impl<E, C> StdError for ContextError<E, C>
where
    E: StdError + 'static,
    C: Display,
{
    #[cfg(backtrace)]
    fn backtrace(&self) -> Option<&Backtrace> {
        self.error.backtrace()
    }

    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&self.error)
    }
}

impl<C> StdError for ContextError<Error, C>
where
    C: Display,
{
    #[cfg(backtrace)]
    fn backtrace(&self) -> Option<&Backtrace> {
        Some(self.error.backtrace())
    }

    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&*self.error)
    }
}
<|endoftext|>


<commit_before>use std::io::{File,fs};
use std::path::posix::Path;
use std::os::{homedir};
use std::rand::random;

pub fn new(name: &str) {
    let home_unwrap = homedir().unwrap();
    let home        = home_unwrap.display();

    let muxed_dir = if muxed_dir_exists(&"muxed".to_string()) {
      Path::new(format!("{}/.muxed/", home))
    } else {
      create_muxed_dir(&"muxed".to_string())
    };

    let path = format!("{}/{}", muxed_dir.display(), name);

    File::create(&Path::new(path));
}

fn create_muxed_dir(name: &String) -> Path {
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.{}", home_unwrap.display(), name));
    fs::mkdir(path, ::std::io::UserRWX);
    path.clone()
}

fn muxed_dir_exists(name: &String) -> bool {
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.{}", home_unwrap.display(), name));
    path.exists()
}

#[test]
fn muxed_dir_exists_returns_false() {
  let dir = format!("test_dir_{}", random::<f64>());
  assert!(!muxed_dir_exists(&dir));
}

#[test]
fn muxed_dir_exists_returns_true() {
  let dir = format!("test_dir_{}", random::<f64>());
  create_muxed_dir(&dir);
  assert!(muxed_dir_exists(&dir));

  let home_unwrap = homedir().unwrap();
  let muxed_path  = &Path::new(format!("{}/.{}/", home_unwrap.display(), dir.as_slice()));
  fs::rmdir_recursive(muxed_path);
}

#[test]
fn creates_muxed_dir() {
    let name        = format!("test_project_{}", random::<f64>());
    let dir         = format!("test_dir_{}", random::<f64>());
    let home_unwrap = homedir().unwrap();
    let muxed_path  = &Path::new(format!("{}/.{}/", home_unwrap.display(), dir.as_slice()));
    create_muxed_dir(&dir);
    assert!(muxed_path.exists());
    fs::rmdir_recursive(muxed_path);
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = format!("test_project_{}", random::<f64>());
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.muxed/{}", home_unwrap.display(), name));
    new(name.as_slice());
    assert!(path.exists());
    fs::unlink(path);
}
<commit_msg>Check to ensure existing files aren't overwritten.<commit_after>#![allow(experimental)]

use std::io::{File,fs};
use std::path::posix::Path;
use std::os::{homedir};
use std::rand::random;
use std::finally::Finally;

pub fn new(name: &str) {
    let home_unwrap = homedir().unwrap();
    let home        = home_unwrap.display();

    let muxed_dir = if muxed_dir_exists(&"muxed".to_string()) {
      Path::new(format!("{}/.muxed/", home))
    } else {
      create_muxed_dir(&"muxed".to_string())
    };

    let path = format!("{}/{}", muxed_dir.display(), name);

    File::create(&Path::new(path));
}

fn create_muxed_dir(name: &String) -> Path {
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.{}", home_unwrap.display(), name));
    fs::mkdir(path, ::std::io::UserRWX);
    path.clone()
}

fn muxed_dir_exists(name: &String) -> bool {
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.{}", home_unwrap.display(), name));
    path.exists()
}

#[test]
fn muxed_dir_exists_returns_false() {
  let dir = format!("test_dir_{}", random::<f64>());
  assert!(!muxed_dir_exists(&dir));
}

#[test]
fn muxed_dir_exists_returns_true() {
  let dir = format!("test_dir_{}", random::<f64>());
  create_muxed_dir(&dir);
  assert!(muxed_dir_exists(&dir));

  let home_unwrap = homedir().unwrap();
  let muxed_path  = &Path::new(format!("{}/.{}/", home_unwrap.display(), dir.as_slice()));
  fs::rmdir_recursive(muxed_path);
}

#[test]
fn creates_muxed_dir() {
    let name        = format!("test_project_{}", random::<f64>());
    let dir         = format!("test_dir_{}", random::<f64>());
    let home_unwrap = homedir().unwrap();
    let muxed_path  = &Path::new(format!("{}/.{}/", home_unwrap.display(), dir.as_slice()));
    create_muxed_dir(&dir);
    assert!(muxed_path.exists());
    fs::rmdir_recursive(muxed_path);
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = format!("test_project_{}", random::<f64>());
    let home_unwrap = homedir().unwrap();
    let path = &Path::new(format!("{}/.muxed/{}", home_unwrap.display(), name));
    new(name.as_slice());
    assert!(path.exists());
    fs::unlink(path);
}

#[test]
#[should_fail]
fn new_doesnt_overwrite_existing_file() {
    let name = format!("test_project_{}", random::<f64>());
    let path = &Path::new(format!("{}/.muxed/{}", homedir_string(), name));
    new(name.as_slice());
    (|| {
        new(name.as_slice());
    }).finally(|| {
        fs::unlink(path);
    })
}
<|endoftext|>


<commit_before>pub use mat::{Mat2, Mat3, Mat4};
pub use vec::{Vec2, Vec3, Vec4};
pub use quat::Quat;

use vec::{Vector, NumericVector};
use mat::{NumericMatrix, NumericMatrix_NxN};

// Vector aliases

pub type vec2  = Vec2<f32>;             /// a two-component single-precision floating-point vector
pub type vec3  = Vec3<f32>;             /// a three-component single-precision floating-point vector
pub type vec4  = Vec4<f32>;             /// a four-component single-precision floating-point vector

pub type dvec2 = Vec2<f64>;             /// a two-component double-precision floating-point vector
pub type dvec3 = Vec3<f64>;             /// a three-component double-precision floating-point vector
pub type dvec4 = Vec4<f64>;             /// a four-component double-precision floating-point vector

pub type bvec2 = Vec2<bool>;            /// a two-component Boolean vector
pub type bvec3 = Vec3<bool>;            /// a three-component Boolean vector
pub type bvec4 = Vec4<bool>;            /// a four-component Boolean vector

pub type ivec2 = Vec2<i32>;             /// a two-component signed integer vector
pub type ivec3 = Vec3<i32>;             /// a three-component signed integer vector
pub type ivec4 = Vec4<i32>;             /// a four-component signed integer vector

pub type uvec2 = Vec2<u32>;             /// a two-component unsigned integer vector
pub type uvec3 = Vec3<u32>;             /// a three-component unsigned integer vector
pub type uvec4 = Vec4<u32>;             /// a four-component unsigned integer vector

//
// Wrappers to make working with static functions cleaner
//
// For example:   let v = dvec::identity();
// as opposed to: let v: dvec4 = NumericVector::identity();
//

pub impl vec2 {
    #[inline(always)] static pure fn new(x: f32, y: f32) -> vec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec2 { NumericVector::zero() }
}

pub impl vec3 {
    #[inline(always)] static pure fn new(x: f32, y: f32, z: f32) -> vec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec3 { NumericVector::zero() }
}

pub impl vec4 {
    #[inline(always)] static pure fn new(x: f32, y: f32, z: f32, w: f32) -> vec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec4 { NumericVector::zero() }
}

pub impl dvec2 {
    #[inline(always)] static pure fn new(x: f64, y: f64) -> dvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec2 { NumericVector::zero() }
}

pub impl dvec3 {
    #[inline(always)] static pure fn new(x: f64, y: f64, z: f64) -> dvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec3 { NumericVector::zero() }
}

pub impl dvec4 {
    #[inline(always)] static pure fn new(x: f64, y: f64, z: f64, w: f64) -> dvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec4 { NumericVector::zero() }
}

pub impl bvec2 {
    #[inline(always)] static pure fn new(x: bool, y: bool) -> bvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec2 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec2 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec2 { NumericVector::zero() }
}

pub impl bvec3 {
    #[inline(always)] static pure fn new(x: bool, y: bool, z: bool) -> bvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec3 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec3 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec3 { NumericVector::zero() }
}

pub impl bvec4 {
    #[inline(always)] static pure fn new(x: bool, y: bool, z: bool, w: bool) -> bvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec4 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec4 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec4 { NumericVector::zero() }
}

pub impl ivec2 {
    #[inline(always)] static pure fn new(x: i32, y: i32) -> ivec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec2 { NumericVector::zero() }
}

pub impl ivec3 {
    #[inline(always)] static pure fn new(x: i32, y: i32, z: i32) -> ivec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec3 { NumericVector::zero() }
}

pub impl ivec4 {
    #[inline(always)] static pure fn new(x: i32, y: i32, z: i32, w: i32) -> ivec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec4 { NumericVector::zero() }
}

pub impl uvec2 {
    #[inline(always)] static pure fn new(x: u32, y: u32) -> uvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec2 { NumericVector::zero() }
}

pub impl uvec3 {
    #[inline(always)] static pure fn new(x: u32, y: u32, z: u32) -> uvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec3 { NumericVector::zero() }
}

pub impl uvec4 {
    #[inline(always)] static pure fn new(x: u32, y: u32, z: u32, w: u32) -> uvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec4 { NumericVector::zero() }
}

// Matrix aliases

pub type mat2 = Mat2<f32>;              /// a 2×2 single-precision floating-point matrix
pub type mat3 = Mat3<f32>;              /// a 3×3 single-precision floating-point matrix
pub type mat4 = Mat4<f32>;              /// a 4×4 single-precision floating-point matrix
pub type mat2x2 = Mat2<f32>;            /// same as a `mat2`
// pub type mat2x3 =                    /// a single-precision floating-point matrix with 2 columns and 3 rows
// pub type mat2x4 =                    /// a single-precision floating-point matrix with 2 columns and 4 rows
// pub type mat3x2 =                    /// a single-precision floating-point matrix with 3 columns and 2 rows
pub type mat3x3 = Mat3<f32>;            /// same as a `mat3`
// pub type mat3x4 =                    /// a single-precision floating-point matrix with 3 columns and 4 rows
// pub type mat4x2 =                    /// a single-precision floating-point matrix with 4 columns and 2 rows
// pub type mat4x3 =                    /// a single-precision floating-point matrix with 4 columns and 3 rows
pub type mat4x4 = Mat4<f32>;            /// same as a `mat4`

pub type dmat2 = Mat2<f64>;             /// a 2×2 double-precision floating-point matrix
pub type dmat3 = Mat3<f64>;             /// a 3×3 double-precision floating-point matrix
pub type dmat4 = Mat4<f64>;             /// a 4×4 double-precision floating-point matrix
pub type dmat2x2 = Mat2<f64>;           /// same as a `dmat2`
// pub type dmat2x3 =                   /// a double-precision floating-point matrix with 2 columns and 3 rows
// pub type dmat2x4 =                   /// a double-precision floating-point matrix with 2 columns and 4 rows
// pub type dmat3x2 =                   /// a double-precision floating-point matrix with 3 columns and 2 rows
pub type dmat3x3 = Mat3<f64>;           /// same as a `dmat3`
// pub type dmat3x4 =                   /// a double-precision floating-point matrix with 3 columns and 4 rows
// pub type dmat4x2 =                   /// a double-precision floating-point matrix with 4 columns and 2 rows
// pub type dmat4x3 =                   /// a double-precision floating-point matrix with 4 columns and 3 rows
pub type dmat4x4 = Mat4<f64>;           /// same as a `dmat4`

//
// Wrappers to make working with static functions cleaner
//
// For example:   let m = dmat::identity();
// as opposed to: let m: dmat4 = NumericMatrix_NxN::identity();
//

pub impl mat2  {
    #[inline(always)] static pure fn identity() -> mat2 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat2  { NumericMatrix::zero() }
}

pub impl mat3  {
    #[inline(always)] static pure fn identity() -> mat3 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat3  { NumericMatrix::zero() }
}

pub impl mat4  {
    #[inline(always)] static pure fn identity() -> mat4 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat4  { NumericMatrix::zero() }
}

pub impl dmat2 {
    #[inline(always)] static pure fn identity() -> dmat2 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat2 { NumericMatrix::zero() }
}

pub impl dmat3 {
    #[inline(always)] static pure fn identity() -> dmat3 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat3 { NumericMatrix::zero() }
}

pub impl dmat4 {
    #[inline(always)] static pure fn identity() -> dmat4 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat4 { NumericMatrix::zero() }
}

// Quaternion types

// These quaternion type aliases are not actually specified in the GLSL spec
// but they follow the same nomenclature

pub type quat4  = Quat<f32>;             /// a single-precision floating-point quaternion
pub type dquat4 = Quat<f64>;             /// a double-precision floating-point quaternion

// prevents "error: expected item"
priv fn hack() {}<commit_msg>Make matN alias definitions dependent on their respective matNxN alias<commit_after>pub use mat::{Mat2, Mat3, Mat4};
pub use vec::{Vec2, Vec3, Vec4};
pub use quat::Quat;

use vec::{Vector, NumericVector};
use mat::{NumericMatrix, NumericMatrix_NxN};

// Vector aliases

pub type vec2  = Vec2<f32>;             /// a two-component single-precision floating-point vector
pub type vec3  = Vec3<f32>;             /// a three-component single-precision floating-point vector
pub type vec4  = Vec4<f32>;             /// a four-component single-precision floating-point vector

pub type dvec2 = Vec2<f64>;             /// a two-component double-precision floating-point vector
pub type dvec3 = Vec3<f64>;             /// a three-component double-precision floating-point vector
pub type dvec4 = Vec4<f64>;             /// a four-component double-precision floating-point vector

pub type bvec2 = Vec2<bool>;            /// a two-component Boolean vector
pub type bvec3 = Vec3<bool>;            /// a three-component Boolean vector
pub type bvec4 = Vec4<bool>;            /// a four-component Boolean vector

pub type ivec2 = Vec2<i32>;             /// a two-component signed integer vector
pub type ivec3 = Vec3<i32>;             /// a three-component signed integer vector
pub type ivec4 = Vec4<i32>;             /// a four-component signed integer vector

pub type uvec2 = Vec2<u32>;             /// a two-component unsigned integer vector
pub type uvec3 = Vec3<u32>;             /// a three-component unsigned integer vector
pub type uvec4 = Vec4<u32>;             /// a four-component unsigned integer vector

//
// Wrappers to make working with static functions cleaner
//
// For example:   let v = dvec::identity();
// as opposed to: let v: dvec4 = NumericVector::identity();
//

pub impl vec2 {
    #[inline(always)] static pure fn new(x: f32, y: f32) -> vec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec2 { NumericVector::zero() }
}

pub impl vec3 {
    #[inline(always)] static pure fn new(x: f32, y: f32, z: f32) -> vec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec3 { NumericVector::zero() }
}

pub impl vec4 {
    #[inline(always)] static pure fn new(x: f32, y: f32, z: f32, w: f32) -> vec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: f32) -> vec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> vec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> vec4 { NumericVector::zero() }
}

pub impl dvec2 {
    #[inline(always)] static pure fn new(x: f64, y: f64) -> dvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec2 { NumericVector::zero() }
}

pub impl dvec3 {
    #[inline(always)] static pure fn new(x: f64, y: f64, z: f64) -> dvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec3 { NumericVector::zero() }
}

pub impl dvec4 {
    #[inline(always)] static pure fn new(x: f64, y: f64, z: f64, w: f64) -> dvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: f64) -> dvec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> dvec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> dvec4 { NumericVector::zero() }
}

pub impl bvec2 {
    #[inline(always)] static pure fn new(x: bool, y: bool) -> bvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec2 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec2 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec2 { NumericVector::zero() }
}

pub impl bvec3 {
    #[inline(always)] static pure fn new(x: bool, y: bool, z: bool) -> bvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec3 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec3 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec3 { NumericVector::zero() }
}

pub impl bvec4 {
    #[inline(always)] static pure fn new(x: bool, y: bool, z: bool, w: bool) -> bvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: bool) -> bvec4 { Vector::from_value(v) }
    // #[inline(always)] static pure fn identity() -> bvec4 { NumericVector::identity() }
    // #[inline(always)] static pure fn zero() -> bvec4 { NumericVector::zero() }
}

pub impl ivec2 {
    #[inline(always)] static pure fn new(x: i32, y: i32) -> ivec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec2 { NumericVector::zero() }
}

pub impl ivec3 {
    #[inline(always)] static pure fn new(x: i32, y: i32, z: i32) -> ivec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec3 { NumericVector::zero() }
}

pub impl ivec4 {
    #[inline(always)] static pure fn new(x: i32, y: i32, z: i32, w: i32) -> ivec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: i32) -> ivec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> ivec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> ivec4 { NumericVector::zero() }
}

pub impl uvec2 {
    #[inline(always)] static pure fn new(x: u32, y: u32) -> uvec2 { Vec2::new(x, y) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec2 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec2 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec2 { NumericVector::zero() }
}

pub impl uvec3 {
    #[inline(always)] static pure fn new(x: u32, y: u32, z: u32) -> uvec3 { Vec3::new(x, y, z) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec3 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec3 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec3 { NumericVector::zero() }
}

pub impl uvec4 {
    #[inline(always)] static pure fn new(x: u32, y: u32, z: u32, w: u32) -> uvec4 { Vec4::new(x, y, z, w) }
    #[inline(always)] static pure fn from_value(v: u32) -> uvec4 { Vector::from_value(v) }
    #[inline(always)] static pure fn identity() -> uvec4 { NumericVector::identity() }
    #[inline(always)] static pure fn zero() -> uvec4 { NumericVector::zero() }
}

// Matrix aliases

pub type mat2 = mat2x2;                 /// a 2×2 single-precision floating-point matrix
pub type mat3 = mat3x3;                 /// a 3×3 single-precision floating-point matrix
pub type mat4 = mat4x4;                 /// a 4×4 single-precision floating-point matrix
pub type mat2x2 = Mat2<f32>;            /// same as a `mat2`
// pub type mat2x3 =                    /// a single-precision floating-point matrix with 2 columns and 3 rows
// pub type mat2x4 =                    /// a single-precision floating-point matrix with 2 columns and 4 rows
// pub type mat3x2 =                    /// a single-precision floating-point matrix with 3 columns and 2 rows
pub type mat3x3 = Mat3<f32>;            /// same as a `mat3`
// pub type mat3x4 =                    /// a single-precision floating-point matrix with 3 columns and 4 rows
// pub type mat4x2 =                    /// a single-precision floating-point matrix with 4 columns and 2 rows
// pub type mat4x3 =                    /// a single-precision floating-point matrix with 4 columns and 3 rows
pub type mat4x4 = Mat4<f32>;            /// same as a `mat4`

pub type dmat2 = dmat2x2;               /// a 2×2 double-precision floating-point matrix
pub type dmat3 = dmat3x3;               /// a 3×3 double-precision floating-point matrix
pub type dmat4 = dmat4x4;               /// a 4×4 double-precision floating-point matrix
pub type dmat2x2 = Mat2<f64>;           /// same as a `dmat2`
// pub type dmat2x3 =                   /// a double-precision floating-point matrix with 2 columns and 3 rows
// pub type dmat2x4 =                   /// a double-precision floating-point matrix with 2 columns and 4 rows
// pub type dmat3x2 =                   /// a double-precision floating-point matrix with 3 columns and 2 rows
pub type dmat3x3 = Mat3<f64>;           /// same as a `dmat3`
// pub type dmat3x4 =                   /// a double-precision floating-point matrix with 3 columns and 4 rows
// pub type dmat4x2 =                   /// a double-precision floating-point matrix with 4 columns and 2 rows
// pub type dmat4x3 =                   /// a double-precision floating-point matrix with 4 columns and 3 rows
pub type dmat4x4 = Mat4<f64>;           /// same as a `dmat4`

//
// Wrappers to make working with static functions cleaner
//
// For example:   let m = dmat::identity();
// as opposed to: let m: dmat4 = NumericMatrix_NxN::identity();
//

pub impl mat2 {
    #[inline(always)] static pure fn identity() -> mat2 { mat2x2::identity() }
    #[inline(always)] static pure fn zero() -> mat2 { mat2x2::zero() }
}

pub impl mat3 {
    #[inline(always)] static pure fn identity() -> mat3 { mat3x3::identity() }
    #[inline(always)] static pure fn zero() -> mat3 { mat3x3::zero() }
}

pub impl mat4 {
    #[inline(always)] static pure fn identity() -> mat4 { mat4x4::identity() }
    #[inline(always)] static pure fn zero() -> mat4 { mat4x4::zero() }
}

pub impl mat2x2 {
    #[inline(always)] static pure fn identity() -> mat2x2 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat2x2 { NumericMatrix::zero() }
}

pub impl mat3x3 {
    #[inline(always)] static pure fn identity() -> mat3x3 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat3x3 { NumericMatrix::zero() }
}

pub impl mat4x4 {
    #[inline(always)] static pure fn identity() -> mat4x4 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> mat4x4 { NumericMatrix::zero() }
}

pub impl dmat2 {
    #[inline(always)] static pure fn identity() -> dmat2 { dmat2x2::identity() }
    #[inline(always)] static pure fn zero() -> dmat2 { NumericMatrix::zero() }
}

pub impl dmat3 {
    #[inline(always)] static pure fn identity() -> dmat3 { dmat3x3::identity() }
    #[inline(always)] static pure fn zero() -> dmat3 { dmat3x3::zero() }
}

pub impl dmat4 {
    #[inline(always)] static pure fn identity() -> dmat4 { dmat4x4::identity() }
    #[inline(always)] static pure fn zero() -> dmat4 { dmat4x4::zero() }
}

pub impl dmat2x2 {
    #[inline(always)] static pure fn identity() -> dmat2x2 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat2x2 { NumericMatrix::zero() }
}

pub impl dmat3x3 {
    #[inline(always)] static pure fn identity() -> dmat3x3 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat3x3 { NumericMatrix::zero() }
}

pub impl dmat4x4 {
    #[inline(always)] static pure fn identity() -> dmat4x4 { NumericMatrix_NxN::identity() }
    #[inline(always)] static pure fn zero() -> dmat4x4 { NumericMatrix::zero() }
}

// Quaternion types

// These quaternion type aliases are not actually specified in the GLSL spec
// but they follow the same nomenclature

pub type quat4  = Quat<f32>;             /// a single-precision floating-point quaternion
pub type dquat4 = Quat<f64>;             /// a double-precision floating-point quaternion

// prevents "error: expected item"
priv fn hack() {}<|endoftext|>