<commit_before>use std::ops::{Mul,Add};
use num::traits::Zero;

#[derive(PartialEq,Debug)]
pub struct Vec3<T> where T: Mul<T, Output = T> + Add<T, Output = T> + Zero + Copy + Clone {
    x: T,
    y: T,
    z: T,
}

impl <T> Vec3<T> where T : Mul<T, Output = T> + Add<T, Output = T> + Zero + Copy + Clone {
    pub fn zero() -> Vec3<T> {
        Vec3 { x: T::zero(), y: T::zero(), z: T::zero() }
    }

    pub fn diagonal(xx: T) -> Vec3<T> {
        Vec3 { x: xx, y: xx, z: xx }
    }

    pub fn norm(self) -> T {
        (self.x * self.x + self.y * self.y + self.z * self.z)
    }
}

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

    #[test]
    fn should_initialize_to_zero_vector() {
        let v: Vec3<f64> = Vec3::zero();

        assert_eq!(v, Vec3::<f64>{ x: 0.0, y: 0.0, z: 0.0 });
    }

    #[test]
    fn should_initialize_to_diagonal_vector() {
        let v: Vec3<f64> = Vec3::diagonal(1.0);

        assert_eq!(v, Vec3::<f64>{ x: 1.0, y: 1.0, z: 1.0 });
    }

    #[test]
    fn should_know_its_norm() {
        let v: Vec3<f64> = Vec3 { x: 0.0, y: 0.0, z: 0.0 };

        assert_eq!(v.norm(), 0.0);
    }
}
<commit_msg>Create new Constructor<commit_after>use std::ops::{Mul,Add};
use num::traits::Zero;

#[derive(PartialEq,Debug)]
pub struct Vec3<T> where T: Mul<T, Output = T> + Add<T, Output = T> + Zero + Copy + Clone {
    x: T,
    y: T,
    z: T,
}

impl <T> Vec3<T> where T : Mul<T, Output = T> + Add<T, Output = T> + Zero + Copy + Clone {
    pub fn new(xx: T, yy: T, zz: T) -> Vec3<T> {
        Vec3 { x: xx, y: yy, z: zz }
    }

    pub fn zero() -> Vec3<T> {
        Vec3 { x: T::zero(), y: T::zero(), z: T::zero() }
    }

    pub fn diagonal(xx: T) -> Vec3<T> {
        Vec3 { x: xx, y: xx, z: xx }
    }

    pub fn norm(self) -> T {
        (self.x * self.x + self.y * self.y + self.z * self.z)
    }
}

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

    #[test]
    fn should_be_created_with_constructor() {
        let v: Vec3<f64> = Vec3::new(0.0, 1.0, 2.0);

        assert_eq!(v, Vec3 { x: 0.0, y: 1.0, z: 2.0 });
    }

    #[test]
    fn should_initialize_to_zero_vector() {
        let v: Vec3<f64> = Vec3::zero();

        assert_eq!(v, Vec3::<f64>{ x: 0.0, y: 0.0, z: 0.0 });
    }

    #[test]
    fn should_initialize_to_diagonal_vector() {
        let v: Vec3<f64> = Vec3::diagonal(1.0);

        assert_eq!(v, Vec3::<f64>{ x: 1.0, y: 1.0, z: 1.0 });
    }

    #[test]
    fn should_know_its_norm() {
        let v: Vec3<f64> = Vec3 { x: 0.0, y: 0.0, z: 0.0 };

        assert_eq!(v.norm(), 0.0);
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 GFX developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use super::*;

use cocoa_foundation::foundation::NSUInteger;

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum MTLLoadAction {
    DontCare = 0,
    Load = 1,
    Clear = 2,
}

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum MTLStoreAction {
    DontCare = 0,
    Store = 1,
    MultisampleResolve = 2,
    StoreAndMultisampleResolve = 3,
    Unknown = 4,
    CustomSampleDepthStore = 5,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MTLClearColor {
    pub red: f64,
    pub green: f64,
    pub blue: f64,
    pub alpha: f64,
}

impl MTLClearColor {
    #[inline]
    pub fn new(red: f64, green: f64, blue: f64, alpha: f64) -> Self {
        Self {
            red,
            green,
            blue,
            alpha,
        }
    }
}

#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum MTLMultisampleStencilResolveFilter {
    Sample0 = 0,
    DepthResolvedSample = 1,
}

pub enum MTLRenderPassAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassAttachmentDescriptor;
    pub struct RenderPassAttachmentDescriptor;
    pub struct RenderPassAttachmentDescriptorRef;
}

impl RenderPassAttachmentDescriptorRef {
    pub fn texture(&self) -> Option<&TextureRef> {
        unsafe { msg_send![self, texture] }
    }

    pub fn set_texture(&self, texture: Option<&TextureRef>) {
        unsafe { msg_send![self, setTexture: texture] }
    }

    pub fn level(&self) -> NSUInteger {
        unsafe { msg_send![self, level] }
    }

    pub fn set_level(&self, level: NSUInteger) {
        unsafe { msg_send![self, setLevel: level] }
    }

    pub fn slice(&self) -> NSUInteger {
        unsafe { msg_send![self, slice] }
    }

    pub fn set_slice(&self, slice: NSUInteger) {
        unsafe { msg_send![self, setSlice: slice] }
    }

    pub fn depth_plane(&self) -> NSUInteger {
        unsafe { msg_send![self, depthPlane] }
    }

    pub fn set_depth_plane(&self, depth_plane: NSUInteger) {
        unsafe { msg_send![self, setDepthPlane: depth_plane] }
    }

    pub fn resolve_texture(&self) -> Option<&TextureRef> {
        unsafe { msg_send![self, resolveTexture] }
    }

    pub fn set_resolve_texture(&self, resolve_texture: Option<&TextureRef>) {
        unsafe { msg_send![self, setResolveTexture: resolve_texture] }
    }

    pub fn resolve_level(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveLevel] }
    }

    pub fn set_resolve_level(&self, resolve_level: NSUInteger) {
        unsafe { msg_send![self, setResolveLevel: resolve_level] }
    }

    pub fn resolve_slice(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveSlice] }
    }

    pub fn set_resolve_slice(&self, resolve_slice: NSUInteger) {
        unsafe { msg_send![self, setResolveSlice: resolve_slice] }
    }

    pub fn resolve_depth_plane(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveDepthPlane] }
    }

    pub fn set_resolve_depth_plane(&self, resolve_depth_plane: NSUInteger) {
        unsafe { msg_send![self, setResolveDepthPlane: resolve_depth_plane] }
    }

    pub fn load_action(&self) -> MTLLoadAction {
        unsafe { msg_send![self, loadAction] }
    }

    pub fn set_load_action(&self, load_action: MTLLoadAction) {
        unsafe { msg_send![self, setLoadAction: load_action] }
    }

    pub fn store_action(&self) -> MTLStoreAction {
        unsafe { msg_send![self, storeAction] }
    }

    pub fn set_store_action(&self, store_action: MTLStoreAction) {
        unsafe { msg_send![self, setStoreAction: store_action] }
    }
}

pub enum MTLRenderPassColorAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassColorAttachmentDescriptor;
    pub struct RenderPassColorAttachmentDescriptor;
    pub struct RenderPassColorAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassColorAttachmentDescriptor {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLRenderPassColorAttachmentDescriptor);
            msg_send![class, new]
        }
    }
}

impl RenderPassColorAttachmentDescriptorRef {
    pub fn clear_color(&self) -> MTLClearColor {
        unsafe { msg_send![self, clearColor] }
    }

    pub fn set_clear_color(&self, clear_color: MTLClearColor) {
        unsafe { msg_send![self, setClearColor: clear_color] }
    }
}

pub enum MTLRenderPassDepthAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassDepthAttachmentDescriptor;
    pub struct RenderPassDepthAttachmentDescriptor;
    pub struct RenderPassDepthAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassDepthAttachmentDescriptorRef {
    pub fn clear_depth(&self) -> f64 {
        unsafe { msg_send![self, clearDepth] }
    }

    pub fn set_clear_depth(&self, clear_depth: f64) {
        unsafe { msg_send![self, setClearDepth: clear_depth] }
    }
}

pub enum MTLRenderPassStencilAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassStencilAttachmentDescriptor;
    pub struct RenderPassStencilAttachmentDescriptor;
    pub struct RenderPassStencilAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassStencilAttachmentDescriptorRef {
    pub fn clear_stencil(&self) -> u32 {
        unsafe { msg_send![self, clearStencil] }
    }

    pub fn set_clear_stencil(&self, clear_stencil: u32) {
        unsafe { msg_send![self, setClearStencil: clear_stencil] }
    }

    pub fn stencil_resolve_filter(&self) -> MTLMultisampleStencilResolveFilter {
        unsafe { msg_send![self, stencilResolveFilter] }
    }

    pub fn set_stencil_resolve_filter(
        &self,
        stencil_resolve_filter: MTLMultisampleStencilResolveFilter,
    ) {
        unsafe { msg_send![self, setStencilResolveFilter: stencil_resolve_filter] }
    }
}

pub enum MTLRenderPassColorAttachmentDescriptorArray {}

foreign_obj_type! {
    type CType = MTLRenderPassColorAttachmentDescriptorArray;
    pub struct RenderPassColorAttachmentDescriptorArray;
    pub struct RenderPassColorAttachmentDescriptorArrayRef;
}

impl RenderPassColorAttachmentDescriptorArrayRef {
    pub fn object_at(&self, index: NSUInteger) -> Option<&RenderPassColorAttachmentDescriptorRef> {
        unsafe { msg_send![self, objectAtIndexedSubscript: index] }
    }

    pub fn set_object_at(
        &self,
        index: NSUInteger,
        attachment: Option<&RenderPassColorAttachmentDescriptorRef>,
    ) {
        unsafe {
            msg_send![self, setObject:attachment
                     atIndexedSubscript:index]
        }
    }
}

pub enum MTLRenderPassDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassDescriptor;
    pub struct RenderPassDescriptor;
    pub struct RenderPassDescriptorRef;
}

impl RenderPassDescriptor {
    pub fn new<'a>() -> &'a RenderPassDescriptorRef {
        unsafe {
            let class = class!(MTLRenderPassDescriptorInternal);
            msg_send![class, renderPassDescriptor]
        }
    }
}

impl RenderPassDescriptorRef {
    pub fn color_attachments(&self) -> &RenderPassColorAttachmentDescriptorArrayRef {
        unsafe { msg_send![self, colorAttachments] }
    }

    pub fn depth_attachment(&self) -> Option<&RenderPassDepthAttachmentDescriptorRef> {
        unsafe { msg_send![self, depthAttachment] }
    }

    pub fn set_depth_attachment(
        &self,
        depth_attachment: Option<&RenderPassDepthAttachmentDescriptorRef>,
    ) {
        unsafe { msg_send![self, setDepthAttachment: depth_attachment] }
    }

    pub fn stencil_attachment(&self) -> Option<&RenderPassStencilAttachmentDescriptorRef> {
        unsafe { msg_send![self, stencilAttachment] }
    }

    pub fn set_stencil_attachment(
        &self,
        stencil_attachment: Option<&RenderPassStencilAttachmentDescriptorRef>,
    ) {
        unsafe { msg_send![self, setStencilAttachment: stencil_attachment] }
    }

    pub fn visibility_result_buffer(&self) -> Option<&BufferRef> {
        unsafe { msg_send![self, visibilityResultBuffer] }
    }

    pub fn set_visibility_result_buffer(&self, buffer: Option<&BufferRef>) {
        unsafe { msg_send![self, setVisibilityResultBuffer: buffer] }
    }

    pub fn render_target_array_length(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetArrayLength] }
    }

    pub fn set_render_target_array_length(&self, length: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetArrayLength: length] }
    }

    pub fn render_target_width(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetWidth] }
    }

    pub fn set_render_target_width(&self, size: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetWidth: size] }
    }

    pub fn render_target_height(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetHeight] }
    }

    pub fn set_render_target_height(&self, size: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetHeight: size] }
    }

    pub fn default_raster_sample_count(&self) -> NSUInteger {
        unsafe { msg_send![self, defaultRasterSampleCount] }
    }

    pub fn set_default_raster_sample_count(&self, count: NSUInteger) {
        unsafe { msg_send![self, setDefaultRasterSampleCount: count] }
    }
}
<commit_msg>Fix render pass construction (fixes #50)<commit_after>// Copyright 2016 GFX developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use super::*;

use cocoa_foundation::foundation::NSUInteger;

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum MTLLoadAction {
    DontCare = 0,
    Load = 1,
    Clear = 2,
}

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum MTLStoreAction {
    DontCare = 0,
    Store = 1,
    MultisampleResolve = 2,
    StoreAndMultisampleResolve = 3,
    Unknown = 4,
    CustomSampleDepthStore = 5,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MTLClearColor {
    pub red: f64,
    pub green: f64,
    pub blue: f64,
    pub alpha: f64,
}

impl MTLClearColor {
    #[inline]
    pub fn new(red: f64, green: f64, blue: f64, alpha: f64) -> Self {
        Self {
            red,
            green,
            blue,
            alpha,
        }
    }
}

#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum MTLMultisampleStencilResolveFilter {
    Sample0 = 0,
    DepthResolvedSample = 1,
}

pub enum MTLRenderPassAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassAttachmentDescriptor;
    pub struct RenderPassAttachmentDescriptor;
    pub struct RenderPassAttachmentDescriptorRef;
}

impl RenderPassAttachmentDescriptorRef {
    pub fn texture(&self) -> Option<&TextureRef> {
        unsafe { msg_send![self, texture] }
    }

    pub fn set_texture(&self, texture: Option<&TextureRef>) {
        unsafe { msg_send![self, setTexture: texture] }
    }

    pub fn level(&self) -> NSUInteger {
        unsafe { msg_send![self, level] }
    }

    pub fn set_level(&self, level: NSUInteger) {
        unsafe { msg_send![self, setLevel: level] }
    }

    pub fn slice(&self) -> NSUInteger {
        unsafe { msg_send![self, slice] }
    }

    pub fn set_slice(&self, slice: NSUInteger) {
        unsafe { msg_send![self, setSlice: slice] }
    }

    pub fn depth_plane(&self) -> NSUInteger {
        unsafe { msg_send![self, depthPlane] }
    }

    pub fn set_depth_plane(&self, depth_plane: NSUInteger) {
        unsafe { msg_send![self, setDepthPlane: depth_plane] }
    }

    pub fn resolve_texture(&self) -> Option<&TextureRef> {
        unsafe { msg_send![self, resolveTexture] }
    }

    pub fn set_resolve_texture(&self, resolve_texture: Option<&TextureRef>) {
        unsafe { msg_send![self, setResolveTexture: resolve_texture] }
    }

    pub fn resolve_level(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveLevel] }
    }

    pub fn set_resolve_level(&self, resolve_level: NSUInteger) {
        unsafe { msg_send![self, setResolveLevel: resolve_level] }
    }

    pub fn resolve_slice(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveSlice] }
    }

    pub fn set_resolve_slice(&self, resolve_slice: NSUInteger) {
        unsafe { msg_send![self, setResolveSlice: resolve_slice] }
    }

    pub fn resolve_depth_plane(&self) -> NSUInteger {
        unsafe { msg_send![self, resolveDepthPlane] }
    }

    pub fn set_resolve_depth_plane(&self, resolve_depth_plane: NSUInteger) {
        unsafe { msg_send![self, setResolveDepthPlane: resolve_depth_plane] }
    }

    pub fn load_action(&self) -> MTLLoadAction {
        unsafe { msg_send![self, loadAction] }
    }

    pub fn set_load_action(&self, load_action: MTLLoadAction) {
        unsafe { msg_send![self, setLoadAction: load_action] }
    }

    pub fn store_action(&self) -> MTLStoreAction {
        unsafe { msg_send![self, storeAction] }
    }

    pub fn set_store_action(&self, store_action: MTLStoreAction) {
        unsafe { msg_send![self, setStoreAction: store_action] }
    }
}

pub enum MTLRenderPassColorAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassColorAttachmentDescriptor;
    pub struct RenderPassColorAttachmentDescriptor;
    pub struct RenderPassColorAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassColorAttachmentDescriptor {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLRenderPassColorAttachmentDescriptor);
            msg_send![class, new]
        }
    }
}

impl RenderPassColorAttachmentDescriptorRef {
    pub fn clear_color(&self) -> MTLClearColor {
        unsafe { msg_send![self, clearColor] }
    }

    pub fn set_clear_color(&self, clear_color: MTLClearColor) {
        unsafe { msg_send![self, setClearColor: clear_color] }
    }
}

pub enum MTLRenderPassDepthAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassDepthAttachmentDescriptor;
    pub struct RenderPassDepthAttachmentDescriptor;
    pub struct RenderPassDepthAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassDepthAttachmentDescriptorRef {
    pub fn clear_depth(&self) -> f64 {
        unsafe { msg_send![self, clearDepth] }
    }

    pub fn set_clear_depth(&self, clear_depth: f64) {
        unsafe { msg_send![self, setClearDepth: clear_depth] }
    }
}

pub enum MTLRenderPassStencilAttachmentDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassStencilAttachmentDescriptor;
    pub struct RenderPassStencilAttachmentDescriptor;
    pub struct RenderPassStencilAttachmentDescriptorRef;
    type ParentType = RenderPassAttachmentDescriptorRef;
}

impl RenderPassStencilAttachmentDescriptorRef {
    pub fn clear_stencil(&self) -> u32 {
        unsafe { msg_send![self, clearStencil] }
    }

    pub fn set_clear_stencil(&self, clear_stencil: u32) {
        unsafe { msg_send![self, setClearStencil: clear_stencil] }
    }

    pub fn stencil_resolve_filter(&self) -> MTLMultisampleStencilResolveFilter {
        unsafe { msg_send![self, stencilResolveFilter] }
    }

    pub fn set_stencil_resolve_filter(
        &self,
        stencil_resolve_filter: MTLMultisampleStencilResolveFilter,
    ) {
        unsafe { msg_send![self, setStencilResolveFilter: stencil_resolve_filter] }
    }
}

pub enum MTLRenderPassColorAttachmentDescriptorArray {}

foreign_obj_type! {
    type CType = MTLRenderPassColorAttachmentDescriptorArray;
    pub struct RenderPassColorAttachmentDescriptorArray;
    pub struct RenderPassColorAttachmentDescriptorArrayRef;
}

impl RenderPassColorAttachmentDescriptorArrayRef {
    pub fn object_at(&self, index: NSUInteger) -> Option<&RenderPassColorAttachmentDescriptorRef> {
        unsafe { msg_send![self, objectAtIndexedSubscript: index] }
    }

    pub fn set_object_at(
        &self,
        index: NSUInteger,
        attachment: Option<&RenderPassColorAttachmentDescriptorRef>,
    ) {
        unsafe {
            msg_send![self, setObject:attachment
                     atIndexedSubscript:index]
        }
    }
}

pub enum MTLRenderPassDescriptor {}

foreign_obj_type! {
    type CType = MTLRenderPassDescriptor;
    pub struct RenderPassDescriptor;
    pub struct RenderPassDescriptorRef;
}

impl RenderPassDescriptor {
    /// Creates a default render pass descriptor with no attachments.
    pub fn new<'a>() -> &'a RenderPassDescriptorRef {
        unsafe { msg_send![class!(MTLRenderPassDescriptor), renderPassDescriptor] }
    }
}

impl RenderPassDescriptorRef {
    pub fn color_attachments(&self) -> &RenderPassColorAttachmentDescriptorArrayRef {
        unsafe { msg_send![self, colorAttachments] }
    }

    pub fn depth_attachment(&self) -> Option<&RenderPassDepthAttachmentDescriptorRef> {
        unsafe { msg_send![self, depthAttachment] }
    }

    pub fn set_depth_attachment(
        &self,
        depth_attachment: Option<&RenderPassDepthAttachmentDescriptorRef>,
    ) {
        unsafe { msg_send![self, setDepthAttachment: depth_attachment] }
    }

    pub fn stencil_attachment(&self) -> Option<&RenderPassStencilAttachmentDescriptorRef> {
        unsafe { msg_send![self, stencilAttachment] }
    }

    pub fn set_stencil_attachment(
        &self,
        stencil_attachment: Option<&RenderPassStencilAttachmentDescriptorRef>,
    ) {
        unsafe { msg_send![self, setStencilAttachment: stencil_attachment] }
    }

    pub fn visibility_result_buffer(&self) -> Option<&BufferRef> {
        unsafe { msg_send![self, visibilityResultBuffer] }
    }

    pub fn set_visibility_result_buffer(&self, buffer: Option<&BufferRef>) {
        unsafe { msg_send![self, setVisibilityResultBuffer: buffer] }
    }

    pub fn render_target_array_length(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetArrayLength] }
    }

    pub fn set_render_target_array_length(&self, length: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetArrayLength: length] }
    }

    pub fn render_target_width(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetWidth] }
    }

    pub fn set_render_target_width(&self, size: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetWidth: size] }
    }

    pub fn render_target_height(&self) -> NSUInteger {
        unsafe { msg_send![self, renderTargetHeight] }
    }

    pub fn set_render_target_height(&self, size: NSUInteger) {
        unsafe { msg_send![self, setRenderTargetHeight: size] }
    }

    pub fn default_raster_sample_count(&self) -> NSUInteger {
        unsafe { msg_send![self, defaultRasterSampleCount] }
    }

    pub fn set_default_raster_sample_count(&self, count: NSUInteger) {
        unsafe { msg_send![self, setDefaultRasterSampleCount: count] }
    }
}
<|endoftext|>


<commit_before>use libc::{uint32_t, c_void};
use std::mem;
use sys::timer as ll;

pub fn get_ticks() -> u32 {
    unsafe { ll::SDL_GetTicks() }
}

pub fn get_performance_counter() -> u64 {
    unsafe { ll::SDL_GetPerformanceCounter() }
}

pub fn get_performance_frequency() -> u64 {
    unsafe { ll::SDL_GetPerformanceFrequency() }
}

pub fn delay(ms: u32) {
    unsafe { ll::SDL_Delay(ms) }
}

pub type TimerCallback = Box<FnMut() -> u32+'static+Sync>;

#[unstable = "Unstable because of move to unboxed closures and `box` syntax"]
pub struct Timer {
    callback: Option<Box<TimerCallback>>,
    _delay: u32,
    raw: ll::SDL_TimerID,
}

impl Timer {
    /// Constructs a new timer using the boxed closure `callback`.
    /// The timer is started immediately, it will be cancelled either:
    ///   * when the timer is dropped
    ///   * or when the callback returns a non-positive continuation interval
    pub fn new(delay: u32, callback: TimerCallback) -> Timer {
        unsafe {
			let callback = Box::new(callback);
            let timer_id = ll::SDL_AddTimer(delay,
                                            Some(c_timer_callback),
                                            mem::transmute_copy(&callback));

            Timer {
                callback: Some(callback),
                _delay: delay,
                raw: timer_id,
            }
        }
    }

	/// Returns the closure as a trait-object and cancels the timer
	/// by consuming it...
	pub fn into_inner(mut self) -> TimerCallback {
		*self.callback.take().unwrap()
	}
}

#[unsafe_destructor]
impl Drop for Timer {
    fn drop(&mut self) {
        let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
        if ret != 1 {
            println!("error dropping timer {}, maybe already removed.", self.raw);
        }
    }
}

extern "C" fn c_timer_callback(_interval: u32, param: *const c_void) -> uint32_t {
    unsafe {
        let f: *const  Box<Fn() -> u32> = mem::transmute(param);
        (*f)() as uint32_t
    }
}

#[test]
fn test_timer_runs_multiple_times() {
    use std::sync::{Arc, Mutex};

    let local_num = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();

    let timer = Timer::new(100, Box::new(move|| {
        // increment up to 10 times (0 -> 9)
        // tick again in 100ms after each increment
        //
        let mut num = timer_num.lock().unwrap();
        if *num < 9 {
            *num += 1;
            100
        } else { 0 }
    }));

    delay(1200);                         // tick the timer at least 10 times w/ 200ms of "buffer"
    let num = local_num.lock().unwrap(); // read the number back
    assert_eq!(*num, 9);                 // it should have incremented at least 10 times...
}

#[test]
fn test_timer_runs_at_least_once() {
    use std::sync::{Arc, Mutex};

    let local_flag = Arc::new(Mutex::new(false));
    let timer_flag = local_flag.clone();

    let timer = Timer::new(500, Box::new(move|| {
        let mut flag = timer_flag.lock().unwrap();
        *flag = true; 0
    }));

    delay(700);
    let flag = local_flag.lock().unwrap();
    assert_eq!(*flag, true);
}

#[test]
fn test_timer_can_be_recreated() {
    use std::sync::{Arc, Mutex};

    let local_num = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();

    // run the timer once and reclaim its closure
    let mut timer_1 = Timer::new(100, Box::new(move|| {
        let mut num = timer_num.lock().unwrap();
        *num += 1; // increment the number
        0          // do not run timer again
    }));

    // reclaim closure after timer runs
    delay(200);
    let closure = timer_1.into_inner();

    // create a second timer and increment again
    let timer_2 = Timer::new(100, closure);
    delay(200);

    // check that timer was incremented twice
    let num = local_num.lock().unwrap();
    assert_eq!(*num, 2);
}
<commit_msg>Don't require that closure is moved ...<commit_after>use libc::{uint32_t, c_void};
use std::mem;
use sys::timer as ll;

pub fn get_ticks() -> u32 {
    unsafe { ll::SDL_GetTicks() }
}

pub fn get_performance_counter() -> u64 {
    unsafe { ll::SDL_GetPerformanceCounter() }
}

pub fn get_performance_frequency() -> u64 {
    unsafe { ll::SDL_GetPerformanceFrequency() }
}

pub fn delay(ms: u32) {
    unsafe { ll::SDL_Delay(ms) }
}

pub type TimerCallback<'a> = Box<FnMut() -> u32+'a+Sync>;

#[unstable = "Unstable because of move to unboxed closures and `box` syntax"]
pub struct Timer<'a> {
    callback: Option<Box<TimerCallback<'a>>>,
    _delay: u32,
    raw: ll::SDL_TimerID,
}

impl<'a> Timer<'a> {
    /// Constructs a new timer using the boxed closure `callback`.
    /// The timer is started immediately, it will be cancelled either:
    ///   * when the timer is dropped
    ///   * or when the callback returns a non-positive continuation interval
    pub fn new(delay: u32, callback: TimerCallback<'a>) -> Timer<'a> {
        unsafe {
			let callback = Box::new(callback);
            let timer_id = ll::SDL_AddTimer(delay,
                                            Some(c_timer_callback),
                                            mem::transmute_copy(&callback));

            Timer {
                callback: Some(callback),
                _delay: delay,
                raw: timer_id,
            }
        }
    }

	/// Returns the closure as a trait-object and cancels the timer
	/// by consuming it...
	pub fn into_inner(mut self) -> TimerCallback<'a> {
		*self.callback.take().unwrap()
	}
}

#[unsafe_destructor]
impl<'a> Drop for Timer<'a> {
    fn drop(&mut self) {
        let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
        if ret != 1 {
            println!("error dropping timer {}, maybe already removed.", self.raw);
        }
    }
}

extern "C" fn c_timer_callback(_interval: u32, param: *const c_void) -> uint32_t {
    unsafe {
        let f: *const  Box<Fn() -> u32> = mem::transmute(param);
        (*f)() as uint32_t
    }
}

#[test]
fn test_timer_runs_multiple_times() {
    use std::sync::{Arc, Mutex};

    let local_num = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();

    let timer = Timer::new(100, Box::new(|| {
        // increment up to 10 times (0 -> 9)
        // tick again in 100ms after each increment
        //
        let mut num = timer_num.lock().unwrap();
        if *num < 9 {
            *num += 1;
            100
        } else { 0 }
    }));

    delay(1200);                         // tick the timer at least 10 times w/ 200ms of "buffer"
    let num = local_num.lock().unwrap(); // read the number back
    assert_eq!(*num, 9);                 // it should have incremented at least 10 times...
}

#[test]
fn test_timer_runs_at_least_once() {
    use std::sync::{Arc, Mutex};

    let local_flag = Arc::new(Mutex::new(false));
    let timer_flag = local_flag.clone();

    let timer = Timer::new(500, Box::new(|| {
        let mut flag = timer_flag.lock().unwrap();
        *flag = true; 0
    }));

    delay(700);
    let flag = local_flag.lock().unwrap();
    assert_eq!(*flag, true);
}

#[test]
fn test_timer_can_be_recreated() {
    use std::sync::{Arc, Mutex};

    let local_num = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();

    // run the timer once and reclaim its closure
    let mut timer_1 = Timer::new(100, Box::new(move|| {
        let mut num = timer_num.lock().unwrap();
        *num += 1; // increment the number
        0          // do not run timer again
    }));

    // reclaim closure after timer runs
    delay(200);
    let closure = timer_1.into_inner();

    // create a second timer and increment again
    let timer_2 = Timer::new(100, closure);
    delay(200);

    // check that timer was incremented twice
    let num = local_num.lock().unwrap();
    assert_eq!(*num, 2);
}
<|endoftext|>


<commit_before>//! Hyper server bindings for unix domain sockets

// Std lib
use std::error;
use std::fmt;
use std::io;
use std::path::Path;

// Third party
use futures::future::Future;
use futures::stream::Stream;
use hyper::body::Payload;
use hyper::server::conn::Http as HyperHttp;
use hyper::service::{NewService, Service};
use hyper::Body;
use tokio_core::reactor::Core;
use tokio_uds::UnixListener;

/// An instance of a server created through `Http::bind`.
//
/// This structure is used to create instances of Servers to spawn off tasks
/// which handle a connection to an HTTP server.
pub struct Server<S>
where
    S: NewService<ReqBody = Body> + Send + 'static,
{
    new_service: S,
    core: Core,
    listener: UnixListener,
}

impl<S> Server<S>
where
    S: NewService<ReqBody = Body, ResBody = Body, Error = io::Error> + Send + Sync + 'static,
    S::InitError: fmt::Display,
    <S::Service as Service>::Future: Send,
{
    pub fn run(self) -> io::Result<()> {
        let Server {
            new_service,
            mut core,
            listener,
            ..
        } = self;

        let server = listener.incoming().for_each(move |sock| {
            new_service
                .new_service()
                .map_err(|e| {
                    io::Error::new(
                        io::ErrorKind::Other,
                        format!("failed to create service: {}", e),
                    )
                })
                .and_then(|service| {
                    HyperHttp::new()
                        .serve_connection(sock, service)
                        .map_err(|e| {
                            io::Error::new(
                                io::ErrorKind::Other,
                                format!("failed to serve connection: {}", e),
                            )
                        })
                })
        });

        core.run(server)
    }
}

/// A type that provides a factory interface for creating
/// unix socket based Servers
///
/// # examples
///
/// ```no_run
/// extern crate hyper;
/// extern crate hyperlocal;
///
/// //let server = hyperlocal::Http::new().bind(
///  // "path/to/socket",
///  //  || Ok(HelloWorld)
/// //)
///
/// ```
#[derive(Clone)]
pub struct Http;

impl Http {
    /// Creates a new instance of the HTTP protocol, ready to spawn a server or
    /// start accepting connections.
    pub fn new() -> Self {
        Http
    }

    /// Binds a new server instance to a unix domain socket path
    /// If the provided path exists this method will yield an error
    pub fn bind<P, S, B>(&self, path: P, new_service: S) -> io::Result<Server<S>>
    where
        P: AsRef<Path>,
        S: NewService<ReqBody = Body, ResBody = B> + Send + 'static,
        S::Error: Into<Box<error::Error + Send + Sync>>,
        S::Service: Send,
        <S::Service as Service>::Future: Send + 'static,
        B: Payload,
    {
        let core = Core::new()?;
        let listener = UnixListener::bind(path.as_ref())?;

        Ok(Server {
            core,
            listener,
            new_service,
        })
    }
}
<commit_msg>no other fields to exclude<commit_after>//! Hyper server bindings for unix domain sockets

// Std lib
use std::error;
use std::fmt;
use std::io;
use std::path::Path;

// Third party
use futures::future::Future;
use futures::stream::Stream;
use hyper::body::Payload;
use hyper::server::conn::Http as HyperHttp;
use hyper::service::{NewService, Service};
use hyper::Body;
use tokio_core::reactor::Core;
use tokio_uds::UnixListener;

/// An instance of a server created through `Http::bind`.
//
/// This structure is used to create instances of Servers to spawn off tasks
/// which handle a connection to an HTTP server.
pub struct Server<S>
where
    S: NewService<ReqBody = Body> + Send + 'static,
{
    new_service: S,
    core: Core,
    listener: UnixListener,
}

impl<S> Server<S>
where
    S: NewService<ReqBody = Body, ResBody = Body, Error = io::Error> + Send + Sync + 'static,
    S::InitError: fmt::Display,
    <S::Service as Service>::Future: Send,
{
    pub fn run(self) -> io::Result<()> {
        let Server {
            new_service,
            mut core,
            listener,
        } = self;

        let server = listener.incoming().for_each(move |sock| {
            new_service
                .new_service()
                .map_err(|e| {
                    io::Error::new(
                        io::ErrorKind::Other,
                        format!("failed to create service: {}", e),
                    )
                })
                .and_then(|service| {
                    HyperHttp::new()
                        .serve_connection(sock, service)
                        .map_err(|e| {
                            io::Error::new(
                                io::ErrorKind::Other,
                                format!("failed to serve connection: {}", e),
                            )
                        })
                })
        });

        core.run(server)
    }
}

/// A type that provides a factory interface for creating
/// unix socket based Servers
///
/// # examples
///
/// ```no_run
/// extern crate hyper;
/// extern crate hyperlocal;
///
/// //let server = hyperlocal::Http::new().bind(
///  // "path/to/socket",
///  //  || Ok(HelloWorld)
/// //)
///
/// ```
#[derive(Clone)]
pub struct Http;

impl Http {
    /// Creates a new instance of the HTTP protocol, ready to spawn a server or
    /// start accepting connections.
    pub fn new() -> Self {
        Http
    }

    /// Binds a new server instance to a unix domain socket path
    /// If the provided path exists this method will yield an error
    pub fn bind<P, S, B>(&self, path: P, new_service: S) -> io::Result<Server<S>>
    where
        P: AsRef<Path>,
        S: NewService<ReqBody = Body, ResBody = B> + Send + 'static,
        S::Error: Into<Box<error::Error + Send + Sync>>,
        S::Service: Send,
        <S::Service as Service>::Future: Send + 'static,
        B: Payload,
    {
        let core = Core::new()?;
        let listener = UnixListener::bind(path.as_ref())?;

        Ok(Server {
            core,
            listener,
            new_service,
        })
    }
}
<|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]

pub mod control_regs;
pub mod descriptor;
pub mod dtables;
pub mod io;
pub mod irq;
pub mod msr;
pub mod paging;
pub mod flags;
pub mod segmentation;
pub mod task;

bitflags!(
    pub flags Features: u64 {
        const Fpu = 1 << 0,
        const Virtual8086 = 1 << 1,
        const DebugExtension = 1 << 2,
        const PageSizeExtension = 1 << 3,
        const TimeStampCounter = 1 << 4,
        const ModelSpecificRegister = 1 << 5,
        const PhysicalAddressExtension = 1 << 6,
        const MachineCheckException = 1 << 7,
        const Cx8 = 1 << 8, // CMPXCHG8
        const Apic = 1 << 9,
        const SysEnter = 1 << 11,
        const MemoryTypeRange = 1 << 12,
        const PageGlobal = 1 << 13,
        const MachineCheckArchitecture = 1 << 14,
        const CMov = 1 << 15,
        const PageAttributeTable = 1 << 16,
        const PageSizeExtension36 = 1 << 17,
        const ProcessorSerial = 1 << 18,
        const CacheFlush = 1 << 19,
        const DebugStore = 1 << 21,
        const Acpi = 1 << 22,
        const Mmx = 1 << 23,
        const FxSave = 1 << 24,
        const Sse = 1 << 25,
        const Sse2 = 1 << 26,
        const SelfSnoop = 1 << 27,
        const HyperThreading = 1 << 28,
        const ThermalMonitor = 1 << 29,
        const Ia64 = 1 << 30,
        const PendingBreak = 1 << 31,

        const Sse3 = 1 << (32 + 0),
        const PclMulQdq = 1 << (32 + 1), // what
        const DebugStore64 = 1 << (32 + 2),
        const Monitor = 1 << (32 + 3),
        const CplDebugStore = 1 << (32 + 4),
        const Vmx = 1 << (32 + 5),
        const SaferMode = 1 << (32 + 6),
        const EnhancedSpeedStep = 1 << (32 + 7),
        const ThermalMonitor2 = 1 << (32 + 8),
        const Ssse3 = 1 << (32 + 9),
        const L1ContextId = 1 << (32 + 10),
        const Fma = 1 << (32 + 12),
        const Cx16 = 1 << (32 + 13), // CMPXCHG16B
        const Xtpr = 1 << (32 + 14), // I have no idea what this is
        const PerformanceMonitor = 1 << (32 + 15),
        const ProcessContextId = 1 << (32 + 17),
        const DirectCache = 1 << (32 + 18),
        const Sse41 = 1 << (32 + 19),
        const Sse42 = 1 << (32 + 20),
        const X2Apic = 1 << (32 + 21),
        const MovBe = 1 << (32 + 22),
        const PopulationCount = 1 << (32 + 23),
        const TscDeadline = 1 << (32 + 24),
        const AesNi = 1 << (32 + 25),
        const XSave = 1 << (32 + 26),
        const OsXSave = 1 << (32 + 27),
        const Avx = 1 << (32 + 28),
        const HalfPrecision = 1 << (32 + 29),
        const HwRandom = 1 << (32 + 30)
    }
);

#[inline(always)]
pub fn cpuid(function: u32) -> (u32, u32, u32, u32) {
    unsafe {
        let (eax, ebx, ecx, edx): (u32, u32, u32, u32);
        asm!("cpuid" : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx) : "{eax}"(function));
        (eax, ebx, ecx, edx)
    }
}

#[inline(always)]
pub fn supports() -> Features {
    let (_, _, feature_ecx, feature_edx) = cpuid(1);
    Features {
        bits: ((feature_ecx as u64) << 32) | (feature_edx as u64)
    }
}

#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum PrivilegeLevel {
    Ring0 = 0,
    Ring1 = 1,
    Ring2 = 2,
    Ring3 = 3,
}

#[inline(always)]
pub unsafe fn halt() {
    asm!("hlt" :::: "volatile", "intel");
}
<commit_msg>Delete libcpu's CPUID infra. This is handled by rust-cpuid not rust-x86.<commit_after>pub mod control_regs;
pub mod descriptor;
pub mod dtables;
pub mod io;
pub mod irq;
pub mod msr;
pub mod paging;
pub mod flags;
pub mod segmentation;
pub mod task;

#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum PrivilegeLevel {
    Ring0 = 0,
    Ring1 = 1,
    Ring2 = 2,
    Ring3 = 3,
}

#[inline(always)]
pub unsafe fn halt() {
    asm!("hlt" :::: "volatile", "intel");
}
<|endoftext|>


<commit_before>extern crate rand;

use self::rand::Rng;
use std::collections::HashMap;
use std::hash::Hash;

#[derive(Debug)]
pub struct AliasDistribution<T: Hash + Eq + Clone> {
    size: usize,
    values: Vec<T>,
    probability_table: Vec<f64>,
    alias_table: Vec<usize>,
    pub entropy: f64,
}

impl<T: Hash + Eq + Clone> AliasDistribution<T> {
    pub fn new(weights: &HashMap<T, usize>) -> AliasDistribution<T> {
        let size = weights.len();
        let total = weights.values().fold(0, |sum, x| sum + x) as f64;
        let mut entropy = 0.0;

        let mut values = Vec::with_capacity(size);
        let mut probability_table = Vec::with_capacity(size);
        for (value, weight) in weights.iter() {
            values.push(value.clone());
            let prob = (*weight as f64) / total;
            entropy -= prob * prob.log(2.0);
            probability_table.push(prob * (size as f64));
        };

        let mut alias_table: Vec<usize> = (0..size).collect();
        let mut overfull: Vec<usize> = Vec::with_capacity(size);
        let mut underfull: Vec<usize> = Vec::with_capacity(size);
        for (i, prob) in probability_table.iter().enumerate() {
            if *prob < 1.0 { underfull.push(i); } else { overfull.push(i); }
        };
        loop {
            if overfull.is_empty() || underfull.is_empty() { break }
            let i = underfull.pop().unwrap();
            let j = overfull.pop().unwrap();
            alias_table[i] = j;
            probability_table[j] = probability_table[i] + probability_table[j] - 1.0;
            if probability_table[j] < 1.0 { underfull.push(j) } else { overfull.push(j) };
        };
        for i in underfull.iter().chain(overfull.iter()) {
            alias_table[*i] = 1;
        };

        AliasDistribution {
            size: size,
            values: values,
            probability_table: probability_table,
            alias_table: alias_table,
            entropy: entropy,
        }
    }

    pub fn choice(&self) -> Option<&T> {
        if self.size == 0 { return None; };
        let mut rng = rand::thread_rng();
        let i = rng.gen_range(0, self.size);
        let y = rng.gen();
        let choice = if self.probability_table[i] >= y { i } else { self.alias_table[i] };
        Some(&self.values[choice])
    }
}
<commit_msg>Use cryptographically secure RNG<commit_after>extern crate rand;

use self::rand::Rng;
use std::collections::HashMap;
use std::hash::Hash;

#[derive(Debug)]
pub struct AliasDistribution<T: Hash + Eq + Clone> {
    size: usize,
    values: Vec<T>,
    probability_table: Vec<f64>,
    alias_table: Vec<usize>,
    pub entropy: f64,
}

impl<T: Hash + Eq + Clone> AliasDistribution<T> {
    pub fn new(weights: &HashMap<T, usize>) -> AliasDistribution<T> {
        let size = weights.len();
        let total = weights.values().fold(0, |sum, x| sum + x) as f64;
        let mut entropy = 0.0;

        let mut values = Vec::with_capacity(size);
        let mut probability_table = Vec::with_capacity(size);
        for (value, weight) in weights.iter() {
            values.push(value.clone());
            let prob = (*weight as f64) / total;
            entropy -= prob * prob.log(2.0);
            probability_table.push(prob * (size as f64));
        };

        let mut alias_table: Vec<usize> = (0..size).collect();
        let mut overfull: Vec<usize> = Vec::with_capacity(size);
        let mut underfull: Vec<usize> = Vec::with_capacity(size);
        for (i, prob) in probability_table.iter().enumerate() {
            if *prob < 1.0 { underfull.push(i); } else { overfull.push(i); }
        };
        loop {
            if overfull.is_empty() || underfull.is_empty() { break }
            let i = underfull.pop().unwrap();
            let j = overfull.pop().unwrap();
            alias_table[i] = j;
            probability_table[j] = probability_table[i] + probability_table[j] - 1.0;
            if probability_table[j] < 1.0 { underfull.push(j) } else { overfull.push(j) };
        };
        for i in underfull.iter().chain(overfull.iter()) {
            alias_table[*i] = 1;
        };

        AliasDistribution {
            size: size,
            values: values,
            probability_table: probability_table,
            alias_table: alias_table,
            entropy: entropy,
        }
    }

    pub fn choice(&self) -> Option<&T> {
        if self.size == 0 { return None; };
        let mut rng = rand::OsRng::new().unwrap();
        let i = rng.gen_range(0, self.size);
        let y = rng.gen();
        let choice = if self.probability_table[i] >= y { i } else { self.alias_table[i] };
        Some(&self.values[choice])
    }
}
<|endoftext|>


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

use std::fmt;
use std::iter;
use std::slice;

use htslib;

use bam;
use bam::record;

/// Iterator over alignments of a pileup.
pub type Alignments<'a> = iter::Map<
    slice::Iter<'a, htslib::bam_pileup1_t>,
    fn(&'a htslib::bam_pileup1_t) -> Alignment<'a>,
>;

/// A pileup over one genomic position.
#[derive(Debug)]
pub struct Pileup {
    inner: *const htslib::bam_pileup1_t,
    depth: u32,
    tid: u32,
    pos: u32,
}

impl Pileup {
    pub fn tid(&self) -> u32 {
        self.tid
    }

    pub fn pos(&self) -> u32 {
        self.pos
    }

    pub fn depth(&self) -> u32 {
        self.depth
    }

    pub fn alignments(&self) -> Alignments {
        self.inner().iter().map(Alignment::new)
    }

    fn inner(&self) -> &[htslib::bam_pileup1_t] {
        unsafe {
            slice::from_raw_parts(
                self.inner as *mut htslib::bam_pileup1_t,
                self.depth as usize,
            )
        }
    }
}

/// An aligned read in a pileup.
pub struct Alignment<'a> {
    inner: &'a htslib::bam_pileup1_t,
}

impl<'a> fmt::Debug for Alignment<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Alignment")
    }
}

impl<'a> Alignment<'a> {
    pub fn new(inner: &'a htslib::bam_pileup1_t) -> Self {
        Alignment { inner: inner }
    }

    /// Position within the read. None if either `is_del` or `is_refskip`.
    pub fn qpos(&self) -> Option<usize> {
        if self.is_del() || self.is_refskip() {
            // there is no alignment position in such a case
            None
        } else {
            Some(self.inner.qpos as usize)
        }
    }

    /// Insertion, deletion (with length) if indel starts at next base or None otherwise.
    pub fn indel(&self) -> Indel {
        match self.inner.indel {
            len if len < 0 => Indel::Del(-len as u32),
            len if len > 0 => Indel::Ins(len as u32),
            _ => Indel::None,
        }
    }

    /// Whether there is a deletion in the alignment at this position.
    pub fn is_del(&self) -> bool {
        self.inner.is_del() != 0
    }

    /// Whether the alignment starts at this position.
    pub fn is_head(&self) -> bool {
        self.inner.is_head() != 0
    }

    /// Whether the alignment ends at this position.
    pub fn is_tail(&self) -> bool {
        self.inner.is_tail() != 0
    }

    /// Whether this position is marked as refskip in the CIGAR string.
    pub fn is_refskip(&self) -> bool {
        self.inner.is_refskip() != 0
    }

    /// The corresponding record.
    pub fn record(&self) -> record::Record {
        record::Record::from_inner(self.inner.b)
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
pub enum Indel {
    Ins(u32),
    Del(u32),
    None,
}

/// Iterator over pileups.
#[derive(Debug)]
pub struct Pileups<'a, R: 'a + bam::Read> {
    #[allow(dead_code)]
    reader: &'a mut R,
    itr: htslib::bam_plp_t,
}

impl<'a, R: bam::Read> Pileups<'a, R> {
    pub fn new(reader: &'a mut R, itr: htslib::bam_plp_t) -> Self {
        Pileups {
            reader: reader,
            itr: itr,
        }
    }

    pub fn set_max_depth(&mut self, depth: u32) {
        unsafe {
            htslib::bam_plp_set_maxcnt(self.itr, depth as i32);
        }
    }
}

impl<'a, R: bam::Read> Iterator for Pileups<'a, R> {
    type Item = Result<Pileup, PileupError>;

    fn next(&mut self) -> Option<Result<Pileup, PileupError>> {
        let (mut tid, mut pos, mut depth) = (0i32, 0i32, 0i32);
        let inner = unsafe { htslib::bam_plp_auto(self.itr, &mut tid, &mut pos, &mut depth) };

        match inner.is_null() {
            true if depth == -1 => Some(Err(PileupError::Some)),
            true => None,
            false => Some(Ok(Pileup {
                inner: inner,
                depth: depth as u32,
                tid: tid as u32,
                pos: pos as u32,
            })),
        }
    }
}

impl<'a, R: bam::Read> Drop for Pileups<'a, R> {
    fn drop(&mut self) {
        unsafe {
            htslib::bam_plp_reset(self.itr);
            htslib::bam_plp_destroy(self.itr);
        }
    }
}

quick_error! {
    #[derive(Debug, Clone)]
    pub enum PileupError {
        Some {
            description("error generating pileup")
        }
    }
}
<commit_msg>Implement check for max_pileup_depth (#122)<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::iter;
use std::slice;

use htslib;

use bam;
use bam::record;

/// Iterator over alignments of a pileup.
pub type Alignments<'a> = iter::Map<
    slice::Iter<'a, htslib::bam_pileup1_t>,
    fn(&'a htslib::bam_pileup1_t) -> Alignment<'a>,
>;

/// A pileup over one genomic position.
#[derive(Debug)]
pub struct Pileup {
    inner: *const htslib::bam_pileup1_t,
    depth: u32,
    tid: u32,
    pos: u32,
}

impl Pileup {
    pub fn tid(&self) -> u32 {
        self.tid
    }

    pub fn pos(&self) -> u32 {
        self.pos
    }

    pub fn depth(&self) -> u32 {
        self.depth
    }

    pub fn alignments(&self) -> Alignments {
        self.inner().iter().map(Alignment::new)
    }

    fn inner(&self) -> &[htslib::bam_pileup1_t] {
        unsafe {
            slice::from_raw_parts(
                self.inner as *mut htslib::bam_pileup1_t,
                self.depth as usize,
            )
        }
    }
}

/// An aligned read in a pileup.
pub struct Alignment<'a> {
    inner: &'a htslib::bam_pileup1_t,
}

impl<'a> fmt::Debug for Alignment<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Alignment")
    }
}

impl<'a> Alignment<'a> {
    pub fn new(inner: &'a htslib::bam_pileup1_t) -> Self {
        Alignment { inner: inner }
    }

    /// Position within the read. None if either `is_del` or `is_refskip`.
    pub fn qpos(&self) -> Option<usize> {
        if self.is_del() || self.is_refskip() {
            // there is no alignment position in such a case
            None
        } else {
            Some(self.inner.qpos as usize)
        }
    }

    /// Insertion, deletion (with length) if indel starts at next base or None otherwise.
    pub fn indel(&self) -> Indel {
        match self.inner.indel {
            len if len < 0 => Indel::Del(-len as u32),
            len if len > 0 => Indel::Ins(len as u32),
            _ => Indel::None,
        }
    }

    /// Whether there is a deletion in the alignment at this position.
    pub fn is_del(&self) -> bool {
        self.inner.is_del() != 0
    }

    /// Whether the alignment starts at this position.
    pub fn is_head(&self) -> bool {
        self.inner.is_head() != 0
    }

    /// Whether the alignment ends at this position.
    pub fn is_tail(&self) -> bool {
        self.inner.is_tail() != 0
    }

    /// Whether this position is marked as refskip in the CIGAR string.
    pub fn is_refskip(&self) -> bool {
        self.inner.is_refskip() != 0
    }

    /// The corresponding record.
    pub fn record(&self) -> record::Record {
        record::Record::from_inner(self.inner.b)
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
pub enum Indel {
    Ins(u32),
    Del(u32),
    None,
}

/// Iterator over pileups.
#[derive(Debug)]
pub struct Pileups<'a, R: 'a + bam::Read> {
    #[allow(dead_code)]
    reader: &'a mut R,
    itr: htslib::bam_plp_t,
}

impl<'a, R: bam::Read> Pileups<'a, R> {
    pub fn new(reader: &'a mut R, itr: htslib::bam_plp_t) -> Self {
        Pileups {
            reader: reader,
            itr: itr,
        }
    }

    /// Warning: because htslib internally uses signed integer for depth this method
    /// will panic if `depth` exceeds `i32::max_value()`.
    pub fn set_max_depth(&mut self, depth: u32) {
        if depth > i32::max_value() as u32 {
            panic!("Maximum value for pileup depth is {} but {} was provided", i32::max_value(), depth)
        }
        let intdepth = depth as i32;
        unsafe {
            htslib::bam_plp_set_maxcnt(self.itr, intdepth);
        }
    }
}

impl<'a, R: bam::Read> Iterator for Pileups<'a, R> {
    type Item = Result<Pileup, PileupError>;

    fn next(&mut self) -> Option<Result<Pileup, PileupError>> {
        let (mut tid, mut pos, mut depth) = (0i32, 0i32, 0i32);
        let inner = unsafe { htslib::bam_plp_auto(self.itr, &mut tid, &mut pos, &mut depth) };

        match inner.is_null() {
            true if depth == -1 => Some(Err(PileupError::Some)),
            true => None,
            false => Some(Ok(Pileup {
                inner: inner,
                depth: depth as u32,
                tid: tid as u32,
                pos: pos as u32,
            })),
        }
    }
}

impl<'a, R: bam::Read> Drop for Pileups<'a, R> {
    fn drop(&mut self) {
        unsafe {
            htslib::bam_plp_reset(self.itr);
            htslib::bam_plp_destroy(self.itr);
        }
    }
}

quick_error! {
    #[derive(Debug, Clone)]
    pub enum PileupError {
        Some {
            description("error generating pileup")
        }
    }
}

#[cfg(test)]
mod tests {

    use bam;
    use prelude::*;

    #[test]
    fn test_max_pileup() {
        let mut bam = bam::Reader::from_path(&"test/test.bam").unwrap();
        let mut p = bam.pileup();
        p.set_max_depth(0u32);
        p.set_max_depth(800u32);

    }

    #[test]
    #[should_panic]
    fn test_max_pileup_to_high() {
        let mut bam = bam::Reader::from_path(&"test/test.bam").unwrap();
        let mut p = bam.pileup();
        p.set_max_depth((i32::max_value() as u32) + 1);
    }

}
<|endoftext|>


<commit_before>use crate::{Crate, Error};
use std::{
    io,
    path::{Path, PathBuf},
};

pub struct BareIndex {
    path: PathBuf,
    pub url: String,
}

impl BareIndex {
    /// Creates a bare index from a provided URL, opening the same location on
    /// disk that cargo uses for that registry index.
    pub fn from_url(url: &str) -> Result<Self, Error> {
        let (dir_name, canonical_url) = url_to_local_dir(url)?;
        let mut path = home::cargo_home().unwrap_or_default();

        path.push("registry/index");
        path.push(dir_name);

        Ok(Self {
            path,
            url: canonical_url,
        })
    }

    /// Creates a bare index at the provided path with the specified repository URL.
    pub fn with_path(path: PathBuf, url: &str) -> Self {
        Self {
            path,
            url: url.to_owned(),
        }
    }

    /// Creates an index for the default crates.io registry, using the same
    /// disk location as cargo itself.
    pub fn new_cargo_default() -> Self {
        // UNWRAP: The default index git URL is known to safely convert to a path.
        Self::from_url(crate::INDEX_GIT_URL).unwrap()
    }

    /// Opens the local index, which acts as a kind of lock for source control
    /// operations
    pub fn open_or_clone(&self) -> Result<BareIndexRepo<'_>, Error> {
        BareIndexRepo::new(self)
    }
}

pub struct BareIndexRepo<'a> {
    inner: &'a BareIndex,
    head: git2::Oid,
    repo: git2::Repository,
    /// This is safe as we implement Drop manually, dropping this tree
    /// reference before we drop the actual repo that its lifetime is actually
    /// tied to, which is basically the same way that cargo works
    tree: Option<git2::Tree<'static>>,
    head_str: String,
}

impl<'a> BareIndexRepo<'a> {
    fn new(index: &'a BareIndex) -> Result<Self, Error> {
        let exists = git2::Repository::discover(&index.path)
            .map(|repository| {
                repository
                    .find_remote("origin")
                    .ok()
                    // Cargo creates a checkout without an origin set,
                    // so default to true in case of missing origin
                    .map_or(true, |remote| {
                        remote.url().map_or(true, |url| url == index.url)
                    })
            })
            .unwrap_or(false);

        if !exists {
            git2::build::RepoBuilder::new()
                .fetch_options(crate::fetch_opts())
                .bare(true)
                .clone(&index.url, &index.path)?;
        }

        let repo = git2::Repository::open(&index.path)?;
        let head = repo
            // Fallback to HEAD, as a fresh clone won't have a FETCH_HEAD
            .refname_to_id("FETCH_HEAD")
            .or_else(|_| repo.refname_to_id("HEAD"))?;
        let head_str = head.to_string();

        let tree = {
            let commit = repo.find_commit(head)?;
            let tree = commit.tree()?;

            // See comment on self.tree
            unsafe { std::mem::transmute::<git2::Tree<'_>, git2::Tree<'static>>(tree) }
        };

        Ok(Self {
            inner: index,
            head,
            head_str,
            repo,
            tree: Some(tree),
        })
    }

    /// Fetches latest from the remote index repository. Note that using this
    /// method will mean no cache entries will be used, if a new commit is fetched
    /// from the repository, as their commit version will no longer match.
    pub fn retrieve(&mut self) -> Result<(), Error> {
        {
            let mut origin_remote = self
                .repo
                .find_remote("origin")
                .or_else(|_| self.repo.remote_anonymous(&self.inner.url))?;

            origin_remote.fetch(
                &["+refs/heads/*:refs/remotes/origin/*"],
                Some(&mut crate::fetch_opts()),
                None,
            )?;
        }

        let head = self
            .repo
            .refname_to_id("FETCH_HEAD")
            .or_else(|_| self.repo.refname_to_id("HEAD"))?;
        let head_str = head.to_string();

        let commit = self.repo.find_commit(head)?;
        let tree = commit.tree()?;

        // See comment on self.tree
        let tree = unsafe { std::mem::transmute::<git2::Tree<'_>, git2::Tree<'static>>(tree) };

        self.head = head;
        self.head_str = head_str;
        self.tree = Some(tree);

        Ok(())
    }

    /// Reads a crate from the index, it will attempt to use a cached entry if
    /// one is available, otherwise it will fallback to reading the crate
    /// directly from the git blob containing the crate information.
    pub fn crate_(&self, name: &str) -> Option<Crate> {
        let rel_path = match crate::crate_name_to_relative_path(name) {
            Some(rp) => rp,
            None => return None,
        };

        // Attempt to load the .cache/ entry first, this is purely an acceleration
        // mechanism and can fail for a few reasons that are non-fatal
        {
            let mut cache_path = self.inner.path.join(".cache");
            cache_path.push(&rel_path);
            if let Ok(cache_bytes) = std::fs::read(&cache_path) {
                if let Ok(krate) = Crate::from_cache_slice(&cache_bytes, &self.head_str) {
                    return Some(krate);
                }
            }
        }

        // Fallback to reading the blob directly via git if we don't have a
        // valid cache entry
        self.krate_from_blob(&rel_path).ok()
    }

    fn krate_from_blob(&self, path: &str) -> Result<Crate, Error> {
        let entry = self.tree.as_ref().unwrap().get_path(&Path::new(path))?;
        let object = entry.to_object(&self.repo)?;
        let blob = object
            .as_blob()
            .ok_or_else(|| Error::Io(io::Error::new(io::ErrorKind::NotFound, path.to_owned())))?;

        Crate::from_slice(blob.content()).map_err(Error::Io)
    }
}

impl<'a> Drop for BareIndexRepo<'a> {
    fn drop(&mut self) {
        // Just be sure to drop this before our other fields
        self.tree.take();
    }
}

/// Converts a full url, eg https://github.com/rust-lang/crates.io-index, into
/// the root directory name where cargo itself will fetch it on disk
fn url_to_local_dir(url: &str) -> Result<(String, String), Error> {
    fn to_hex(num: u64) -> String {
        const CHARS: &[u8] = b"0123456789abcdef";

        let bytes = &[
            num as u8,
            (num >> 8) as u8,
            (num >> 16) as u8,
            (num >> 24) as u8,
            (num >> 32) as u8,
            (num >> 40) as u8,
            (num >> 48) as u8,
            (num >> 56) as u8,
        ];

        let mut output = vec![0u8; 16];

        let mut ind = 0;

        for &byte in bytes {
            output[ind] = CHARS[(byte >> 4) as usize];
            output[ind + 1] = CHARS[(byte & 0xf) as usize];

            ind += 2;
        }

        String::from_utf8(output).expect("valid utf-8 hex string")
    }

    #[allow(deprecated)]
    fn hash_u64(url: &str) -> u64 {
        use std::hash::{Hash, Hasher, SipHasher};

        let mut hasher = SipHasher::new_with_keys(0, 0);
        // Registry
        2usize.hash(&mut hasher);
        // Url
        url.hash(&mut hasher);
        hasher.finish()
    }

    // Ensure we have a registry or bare url
    let (url, scheme_ind) = {
        let scheme_ind = url
            .find("://")
            .ok_or_else(|| Error::Url(format!("'{}' is not a valid url", url)))?;

        let scheme_str = &url[..scheme_ind];
        if let Some(ind) = scheme_str.find('+') {
            if &scheme_str[..ind] != "registry" {
                return Err(Error::Url(format!("'{}' is not a valid registry url", url)));
            }

            (&url[ind + 1..], scheme_ind - ind - 1)
        } else {
            (url, scheme_ind)
        }
    };

    // Could use the Url crate for this, but it's simple enough and we don't
    // need to deal with every possible url (I hope...)
    let host = match url[scheme_ind + 3..].find('/') {
        Some(end) => &url[scheme_ind + 3..scheme_ind + 3 + end],
        None => &url[scheme_ind + 3..],
    };

    // cargo special cases github.com for reasons, so do the same
    let mut canonical = if host == "github.com" {
        url.to_lowercase()
    } else {
        url.to_owned()
    };

    // Chop off any query params/fragments
    if let Some(hash) = canonical.rfind('#') {
        canonical.truncate(hash);
    }

    if let Some(query) = canonical.rfind('?') {
        canonical.truncate(query);
    }

    let ident = to_hex(hash_u64(&canonical));

    if canonical.ends_with('/') {
        canonical.pop();
    }

    if canonical.ends_with(".git") {
        canonical.truncate(canonical.len() - 4);
    }

    Ok((format!("{}-{}", host, ident), canonical))
}

#[cfg(test)]
mod test {
    #[test]
    fn matches_cargo() {
        assert_eq!(
            super::url_to_local_dir(crate::INDEX_GIT_URL).unwrap(),
            (
                "github.com-1ecc6299db9ec823".to_owned(),
                crate::INDEX_GIT_URL.to_owned()
            )
        );

        // I've confirmed this also works with a custom registry, unfortunately
        // that one includes a secret key as part of the url which would allow
        // anyone to publish to the registry, so uhh...here's a fake one instead
        assert_eq!(
            super::url_to_local_dir(
                "https://dl.cloudsmith.io/aBcW1234aBcW1234/embark/rust/cargo/index.git"
            )
            .unwrap(),
            (
                "dl.cloudsmith.io-ff79e51ddd2b38fd".to_owned(),
                "https://dl.cloudsmith.io/aBcW1234aBcW1234/embark/rust/cargo/index".to_owned()
            )
        );

        // Ensure we actually strip off the irrelevant parts of a url, note that
        // the .git suffix is not part of the canonical url, but *is* used when hashing
        assert_eq!(
            super::url_to_local_dir(&format!(
                "registry+{}.git?one=1&two=2#fragment",
                crate::INDEX_GIT_URL
            ))
            .unwrap(),
            (
                "github.com-c786010fb7ef2e6e".to_owned(),
                crate::INDEX_GIT_URL.to_owned()
            )
        );
    }

    #[test]
    fn clones_bare_index() {
        use super::BareIndex;

        let tmp_dir = tempdir::TempDir::new("clones_bare_index").unwrap();

        let index = BareIndex::with_path(tmp_dir.path().to_owned(), crate::INDEX_GIT_URL);

        let mut repo = index
            .open_or_clone()
            .expect("Failed to clone crates.io index");

        fn test_sval(repo: &super::BareIndexRepo<'_>) {
            let krate = repo
                .crate_("sval")
                .expect("Could not find the crate sval in the index");

            let version = krate
                .versions()
                .iter()
                .find(|v| v.version() == "0.0.1")
                .expect("Version 0.0.1 of sval does not exist?");
            let dep_with_package_name = version
                .dependencies()
                .iter()
                .find(|d| d.name() == "serde_lib")
                .expect("sval does not have expected dependency?");
            assert_ne!(
                dep_with_package_name.name(),
                dep_with_package_name.package().unwrap()
            );
            assert_eq!(
                dep_with_package_name.crate_name(),
                dep_with_package_name.package().unwrap()
            );
        }

        test_sval(&repo);

        repo.retrieve().expect("Failed to fetch crates.io index");

        test_sval(&repo);
    }

    #[test]
    fn opens_bare_index() {
        use super::BareIndex;

        let tmp_dir = tempdir::TempDir::new("opens_bare_index").unwrap();

        let index = BareIndex::with_path(tmp_dir.path().to_owned(), crate::INDEX_GIT_URL);

        {
            let _ = index
                .open_or_clone()
                .expect("Failed to clone crates.io index");
        }

        let mut repo = index
            .open_or_clone()
            .expect("Failed to open crates.io index");

        fn test_sval(repo: &super::BareIndexRepo<'_>) {
            let krate = repo
                .crate_("sval")
                .expect("Could not find the crate sval in the index");

            let version = krate
                .versions()
                .iter()
                .find(|v| v.version() == "0.0.1")
                .expect("Version 0.0.1 of sval does not exist?");
            let dep_with_package_name = version
                .dependencies()
                .iter()
                .find(|d| d.name() == "serde_lib")
                .expect("sval does not have expected dependency?");
            assert_ne!(
                dep_with_package_name.name(),
                dep_with_package_name.package().unwrap()
            );
            assert_eq!(
                dep_with_package_name.crate_name(),
                dep_with_package_name.package().unwrap()
            );
        }

        test_sval(&repo);

        repo.retrieve().expect("Failed to fetch crates.io index");

        test_sval(&repo);
    }
}
<commit_msg>Keep self-referential fields together<commit_after>use crate::{Crate, Error};
use std::{
    io,
    path::{Path, PathBuf},
};

pub struct BareIndex {
    path: PathBuf,
    pub url: String,
}

impl BareIndex {
    /// Creates a bare index from a provided URL, opening the same location on
    /// disk that cargo uses for that registry index.
    pub fn from_url(url: &str) -> Result<Self, Error> {
        let (dir_name, canonical_url) = url_to_local_dir(url)?;
        let mut path = home::cargo_home().unwrap_or_default();

        path.push("registry/index");
        path.push(dir_name);

        Ok(Self {
            path,
            url: canonical_url,
        })
    }

    /// Creates a bare index at the provided path with the specified repository URL.
    pub fn with_path(path: PathBuf, url: &str) -> Self {
        Self {
            path,
            url: url.to_owned(),
        }
    }

    /// Creates an index for the default crates.io registry, using the same
    /// disk location as cargo itself.
    pub fn new_cargo_default() -> Self {
        // UNWRAP: The default index git URL is known to safely convert to a path.
        Self::from_url(crate::INDEX_GIT_URL).unwrap()
    }

    /// Opens the local index, which acts as a kind of lock for source control
    /// operations
    pub fn open_or_clone(&self) -> Result<BareIndexRepo<'_>, Error> {
        BareIndexRepo::new(self)
    }
}

/// Self-referential struct where `Tree` borrows from `Repository`
struct UnsafeRepoTree {
    /// Warning: order of the fields is necessary for safety. `tree` must Drop before `repo`.
    tree: git2::Tree<'static>,
    repo: git2::Repository,
}

pub struct BareIndexRepo<'a> {
    inner: &'a BareIndex,
    head: git2::Oid,
    head_str: String,
    rt: UnsafeRepoTree,
}

impl<'a> BareIndexRepo<'a> {
    fn new(index: &'a BareIndex) -> Result<Self, Error> {
        let exists = git2::Repository::discover(&index.path)
            .map(|repository| {
                repository
                    .find_remote("origin")
                    .ok()
                    // Cargo creates a checkout without an origin set,
                    // so default to true in case of missing origin
                    .map_or(true, |remote| {
                        remote.url().map_or(true, |url| url == index.url)
                    })
            })
            .unwrap_or(false);

        if !exists {
            git2::build::RepoBuilder::new()
                .fetch_options(crate::fetch_opts())
                .bare(true)
                .clone(&index.url, &index.path)?;
        }

        let repo = git2::Repository::open(&index.path)?;
        let head = repo
            // Fallback to HEAD, as a fresh clone won't have a FETCH_HEAD
            .refname_to_id("FETCH_HEAD")
            .or_else(|_| repo.refname_to_id("HEAD"))?;
        let head_str = head.to_string();

        let tree = {
            let commit = repo.find_commit(head)?;
            let tree = commit.tree()?;

            // See `UnsafeRepoTree`
            unsafe { std::mem::transmute::<git2::Tree<'_>, git2::Tree<'static>>(tree) }
        };

        Ok(Self {
            inner: index,
            head,
            head_str,
            rt: UnsafeRepoTree {
                repo,
                tree,
            },
        })
    }

    /// Fetches latest from the remote index repository. Note that using this
    /// method will mean no cache entries will be used, if a new commit is fetched
    /// from the repository, as their commit version will no longer match.
    pub fn retrieve(&mut self) -> Result<(), Error> {
        {
            let mut origin_remote = self
                .rt.repo
                .find_remote("origin")
                .or_else(|_| self.rt.repo.remote_anonymous(&self.inner.url))?;

            origin_remote.fetch(
                &["+refs/heads/*:refs/remotes/origin/*"],
                Some(&mut crate::fetch_opts()),
                None,
            )?;
        }

        let head = self
            .rt.repo
            .refname_to_id("FETCH_HEAD")
            .or_else(|_| self.rt.repo.refname_to_id("HEAD"))?;
        let head_str = head.to_string();

        let commit = self.rt.repo.find_commit(head)?;
        let tree = commit.tree()?;

        // See `UnsafeRepoTree`
        let tree = unsafe { std::mem::transmute::<git2::Tree<'_>, git2::Tree<'static>>(tree) };

        self.head = head;
        self.head_str = head_str;
        self.rt.tree = tree;

        Ok(())
    }

    /// Reads a crate from the index, it will attempt to use a cached entry if
    /// one is available, otherwise it will fallback to reading the crate
    /// directly from the git blob containing the crate information.
    pub fn crate_(&self, name: &str) -> Option<Crate> {
        let rel_path = match crate::crate_name_to_relative_path(name) {
            Some(rp) => rp,
            None => return None,
        };

        // Attempt to load the .cache/ entry first, this is purely an acceleration
        // mechanism and can fail for a few reasons that are non-fatal
        {
            let mut cache_path = self.inner.path.join(".cache");
            cache_path.push(&rel_path);
            if let Ok(cache_bytes) = std::fs::read(&cache_path) {
                if let Ok(krate) = Crate::from_cache_slice(&cache_bytes, &self.head_str) {
                    return Some(krate);
                }
            }
        }

        // Fallback to reading the blob directly via git if we don't have a
        // valid cache entry
        self.krate_from_blob(&rel_path).ok()
    }

    fn krate_from_blob(&self, path: &str) -> Result<Crate, Error> {
        let entry = self.rt.tree.get_path(&Path::new(path))?;
        let object = entry.to_object(&self.rt.repo)?;
        let blob = object
            .as_blob()
            .ok_or_else(|| Error::Io(io::Error::new(io::ErrorKind::NotFound, path.to_owned())))?;

        Crate::from_slice(blob.content()).map_err(Error::Io)
    }
}

/// Converts a full url, eg https://github.com/rust-lang/crates.io-index, into
/// the root directory name where cargo itself will fetch it on disk
fn url_to_local_dir(url: &str) -> Result<(String, String), Error> {
    fn to_hex(num: u64) -> String {
        const CHARS: &[u8] = b"0123456789abcdef";

        let bytes = &[
            num as u8,
            (num >> 8) as u8,
            (num >> 16) as u8,
            (num >> 24) as u8,
            (num >> 32) as u8,
            (num >> 40) as u8,
            (num >> 48) as u8,
            (num >> 56) as u8,
        ];

        let mut output = vec![0u8; 16];

        let mut ind = 0;

        for &byte in bytes {
            output[ind] = CHARS[(byte >> 4) as usize];
            output[ind + 1] = CHARS[(byte & 0xf) as usize];

            ind += 2;
        }

        String::from_utf8(output).expect("valid utf-8 hex string")
    }

    #[allow(deprecated)]
    fn hash_u64(url: &str) -> u64 {
        use std::hash::{Hash, Hasher, SipHasher};

        let mut hasher = SipHasher::new_with_keys(0, 0);
        // Registry
        2usize.hash(&mut hasher);
        // Url
        url.hash(&mut hasher);
        hasher.finish()
    }

    // Ensure we have a registry or bare url
    let (url, scheme_ind) = {
        let scheme_ind = url
            .find("://")
            .ok_or_else(|| Error::Url(format!("'{}' is not a valid url", url)))?;

        let scheme_str = &url[..scheme_ind];
        if let Some(ind) = scheme_str.find('+') {
            if &scheme_str[..ind] != "registry" {
                return Err(Error::Url(format!("'{}' is not a valid registry url", url)));
            }

            (&url[ind + 1..], scheme_ind - ind - 1)
        } else {
            (url, scheme_ind)
        }
    };

    // Could use the Url crate for this, but it's simple enough and we don't
    // need to deal with every possible url (I hope...)
    let host = match url[scheme_ind + 3..].find('/') {
        Some(end) => &url[scheme_ind + 3..scheme_ind + 3 + end],
        None => &url[scheme_ind + 3..],
    };

    // cargo special cases github.com for reasons, so do the same
    let mut canonical = if host == "github.com" {
        url.to_lowercase()
    } else {
        url.to_owned()
    };

    // Chop off any query params/fragments
    if let Some(hash) = canonical.rfind('#') {
        canonical.truncate(hash);
    }

    if let Some(query) = canonical.rfind('?') {
        canonical.truncate(query);
    }

    let ident = to_hex(hash_u64(&canonical));

    if canonical.ends_with('/') {
        canonical.pop();
    }

    if canonical.ends_with(".git") {
        canonical.truncate(canonical.len() - 4);
    }

    Ok((format!("{}-{}", host, ident), canonical))
}

#[cfg(test)]
mod test {
    #[test]
    fn matches_cargo() {
        assert_eq!(
            super::url_to_local_dir(crate::INDEX_GIT_URL).unwrap(),
            (
                "github.com-1ecc6299db9ec823".to_owned(),
                crate::INDEX_GIT_URL.to_owned()
            )
        );

        // I've confirmed this also works with a custom registry, unfortunately
        // that one includes a secret key as part of the url which would allow
        // anyone to publish to the registry, so uhh...here's a fake one instead
        assert_eq!(
            super::url_to_local_dir(
                "https://dl.cloudsmith.io/aBcW1234aBcW1234/embark/rust/cargo/index.git"
            )
            .unwrap(),
            (
                "dl.cloudsmith.io-ff79e51ddd2b38fd".to_owned(),
                "https://dl.cloudsmith.io/aBcW1234aBcW1234/embark/rust/cargo/index".to_owned()
            )
        );

        // Ensure we actually strip off the irrelevant parts of a url, note that
        // the .git suffix is not part of the canonical url, but *is* used when hashing
        assert_eq!(
            super::url_to_local_dir(&format!(
                "registry+{}.git?one=1&two=2#fragment",
                crate::INDEX_GIT_URL
            ))
            .unwrap(),
            (
                "github.com-c786010fb7ef2e6e".to_owned(),
                crate::INDEX_GIT_URL.to_owned()
            )
        );
    }

    #[test]
    fn clones_bare_index() {
        use super::BareIndex;

        let tmp_dir = tempdir::TempDir::new("clones_bare_index").unwrap();

        let index = BareIndex::with_path(tmp_dir.path().to_owned(), crate::INDEX_GIT_URL);

        let mut repo = index
            .open_or_clone()
            .expect("Failed to clone crates.io index");

        fn test_sval(repo: &super::BareIndexRepo<'_>) {
            let krate = repo
                .crate_("sval")
                .expect("Could not find the crate sval in the index");

            let version = krate
                .versions()
                .iter()
                .find(|v| v.version() == "0.0.1")
                .expect("Version 0.0.1 of sval does not exist?");
            let dep_with_package_name = version
                .dependencies()
                .iter()
                .find(|d| d.name() == "serde_lib")
                .expect("sval does not have expected dependency?");
            assert_ne!(
                dep_with_package_name.name(),
                dep_with_package_name.package().unwrap()
            );
            assert_eq!(
                dep_with_package_name.crate_name(),
                dep_with_package_name.package().unwrap()
            );
        }

        test_sval(&repo);

        repo.retrieve().expect("Failed to fetch crates.io index");

        test_sval(&repo);
    }

    #[test]
    fn opens_bare_index() {
        use super::BareIndex;

        let tmp_dir = tempdir::TempDir::new("opens_bare_index").unwrap();

        let index = BareIndex::with_path(tmp_dir.path().to_owned(), crate::INDEX_GIT_URL);

        {
            let _ = index
                .open_or_clone()
                .expect("Failed to clone crates.io index");
        }

        let mut repo = index
            .open_or_clone()
            .expect("Failed to open crates.io index");

        fn test_sval(repo: &super::BareIndexRepo<'_>) {
            let krate = repo
                .crate_("sval")
                .expect("Could not find the crate sval in the index");

            let version = krate
                .versions()
                .iter()
                .find(|v| v.version() == "0.0.1")
                .expect("Version 0.0.1 of sval does not exist?");
            let dep_with_package_name = version
                .dependencies()
                .iter()
                .find(|d| d.name() == "serde_lib")
                .expect("sval does not have expected dependency?");
            assert_ne!(
                dep_with_package_name.name(),
                dep_with_package_name.package().unwrap()
            );
            assert_eq!(
                dep_with_package_name.crate_name(),
                dep_with_package_name.package().unwrap()
            );
        }

        test_sval(&repo);

        repo.retrieve().expect("Failed to fetch crates.io index");

        test_sval(&repo);
    }
}
<|endoftext|>


<commit_before>#[cfg(any(feature = "alloc", feature = "std"))]
use base::dimension::Dynamic;
use base::dimension::{U1, U2, U3, U4, U5, U6};
#[cfg(any(feature = "std", feature = "alloc"))]
use base::matrix_vec::MatrixVec;
use base::storage::Owned;
use base::Matrix;

/*
 *
 *
 * Column-major matrices.
 *
 *
 */
/// A staticaly sized column-major matrix with `R` rows and `C` columns.
#[deprecated(note = "This matrix name contains a typo. Use MatrixMN instead.")]
pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;

/// A staticaly sized column-major matrix with `R` rows and `C` columns.
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;

/// A staticaly sized column-major square matrix with `D` rows and columns.
pub type MatrixN<N, D> = MatrixMN<N, D, D>;

/// A dynamically sized column-major matrix.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type DMatrix<N> = MatrixN<N, Dynamic>;

/// A stack-allocated, column-major, 1x1 square matrix.
pub type Matrix1<N> = MatrixN<N, U1>;
/// A stack-allocated, column-major, 2x2 square matrix.
pub type Matrix2<N> = MatrixN<N, U2>;
/// A stack-allocated, column-major, 3x3 square matrix.
pub type Matrix3<N> = MatrixN<N, U3>;
/// A stack-allocated, column-major, 4x4 square matrix.
pub type Matrix4<N> = MatrixN<N, U4>;
/// A stack-allocated, column-major, 5x5 square matrix.
pub type Matrix5<N> = MatrixN<N, U5>;
/// A stack-allocated, column-major, 6x6 square matrix.
pub type Matrix6<N> = MatrixN<N, U6>;

/// A stack-allocated, column-major, 1x2 matrix.
pub type Matrix1x2<N> = MatrixMN<N, U1, U2>;
/// A stack-allocated, column-major, 1x3 matrix.
pub type Matrix1x3<N> = MatrixMN<N, U1, U3>;
/// A stack-allocated, column-major, 1x4 matrix.
pub type Matrix1x4<N> = MatrixMN<N, U1, U4>;
/// A stack-allocated, column-major, 1x5 matrix.
pub type Matrix1x5<N> = MatrixMN<N, U1, U5>;
/// A stack-allocated, column-major, 1x6 matrix.
pub type Matrix1x6<N> = MatrixMN<N, U1, U6>;

/// A stack-allocated, column-major, 2x3 matrix.
pub type Matrix2x3<N> = MatrixMN<N, U2, U3>;
/// A stack-allocated, column-major, 2x4 matrix.
pub type Matrix2x4<N> = MatrixMN<N, U2, U4>;
/// A stack-allocated, column-major, 2x5 matrix.
pub type Matrix2x5<N> = MatrixMN<N, U2, U5>;
/// A stack-allocated, column-major, 2x6 matrix.
pub type Matrix2x6<N> = MatrixMN<N, U2, U6>;

/// A stack-allocated, column-major, 3x4 matrix.
pub type Matrix3x4<N> = MatrixMN<N, U3, U4>;
/// A stack-allocated, column-major, 3x5 matrix.
pub type Matrix3x5<N> = MatrixMN<N, U3, U5>;
/// A stack-allocated, column-major, 3x6 matrix.
pub type Matrix3x6<N> = MatrixMN<N, U3, U6>;

/// A stack-allocated, column-major, 4x5 matrix.
pub type Matrix4x5<N> = MatrixMN<N, U4, U5>;
/// A stack-allocated, column-major, 4x6 matrix.
pub type Matrix4x6<N> = MatrixMN<N, U4, U6>;

/// A stack-allocated, column-major, 5x6 matrix.
pub type Matrix5x6<N> = MatrixMN<N, U5, U6>;

/// A stack-allocated, column-major, 2x1 matrix.
pub type Matrix2x1<N> = MatrixMN<N, U2, U1>;
/// A stack-allocated, column-major, 3x1 matrix.
pub type Matrix3x1<N> = MatrixMN<N, U3, U1>;
/// A stack-allocated, column-major, 4x1 matrix.
pub type Matrix4x1<N> = MatrixMN<N, U4, U1>;
/// A stack-allocated, column-major, 5x1 matrix.
pub type Matrix5x1<N> = MatrixMN<N, U5, U1>;
/// A stack-allocated, column-major, 6x1 matrix.
pub type Matrix6x1<N> = MatrixMN<N, U6, U1>;

/// A stack-allocated, column-major, 3x2 matrix.
pub type Matrix3x2<N> = MatrixMN<N, U3, U2>;
/// A stack-allocated, column-major, 4x2 matrix.
pub type Matrix4x2<N> = MatrixMN<N, U4, U2>;
/// A stack-allocated, column-major, 5x2 matrix.
pub type Matrix5x2<N> = MatrixMN<N, U5, U2>;
/// A stack-allocated, column-major, 6x2 matrix.
pub type Matrix6x2<N> = MatrixMN<N, U6, U2>;

/// A stack-allocated, column-major, 4x3 matrix.
pub type Matrix4x3<N> = MatrixMN<N, U4, U3>;
/// A stack-allocated, column-major, 5x3 matrix.
pub type Matrix5x3<N> = MatrixMN<N, U5, U3>;
/// A stack-allocated, column-major, 6x3 matrix.
pub type Matrix6x3<N> = MatrixMN<N, U6, U3>;

/// A stack-allocated, column-major, 5x4 matrix.
pub type Matrix5x4<N> = MatrixMN<N, U5, U4>;
/// A stack-allocated, column-major, 6x4 matrix.
pub type Matrix6x4<N> = MatrixMN<N, U6, U4>;

/// A stack-allocated, column-major, 6x5 matrix.
pub type Matrix6x5<N> = MatrixMN<N, U6, U5>;

/*
 *
 *
 * Column vectors.
 *
 *
 */
/// A dynamically sized column vector.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type DVector<N> = Matrix<N, Dynamic, U1, MatrixVec<N, Dynamic, U1>>;

/// A statically sized D-dimensional column vector.
pub type VectorN<N, D> = MatrixMN<N, D, U1>;

/// A stack-allocated, 1-dimensional column vector.
pub type Vector1<N> = VectorN<N, U1>;
/// A stack-allocated, 2-dimensional column vector.
pub type Vector2<N> = VectorN<N, U2>;
/// A stack-allocated, 3-dimensional column vector.
pub type Vector3<N> = VectorN<N, U3>;
/// A stack-allocated, 4-dimensional column vector.
pub type Vector4<N> = VectorN<N, U4>;
/// A stack-allocated, 5-dimensional column vector.
pub type Vector5<N> = VectorN<N, U5>;
/// A stack-allocated, 6-dimensional column vector.
pub type Vector6<N> = VectorN<N, U6>;

/*
 *
 *
 * Row vectors.
 *
 *
 */
/// A dynamically sized row vector.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type RowDVector<N> = Matrix<N, U1, Dynamic, MatrixVec<N, U1, Dynamic>>;

/// A statically sized D-dimensional row vector.
pub type RowVectorN<N, D> = MatrixMN<N, U1, D>;

/// A stack-allocated, 1-dimensional row vector.
pub type RowVector1<N> = RowVectorN<N, U1>;
/// A stack-allocated, 2-dimensional row vector.
pub type RowVector2<N> = RowVectorN<N, U2>;
/// A stack-allocated, 3-dimensional row vector.
pub type RowVector3<N> = RowVectorN<N, U3>;
/// A stack-allocated, 4-dimensional row vector.
pub type RowVector4<N> = RowVectorN<N, U4>;
/// A stack-allocated, 5-dimensional row vector.
pub type RowVector5<N> = RowVectorN<N, U5>;
/// A stack-allocated, 6-dimensional row vector.
pub type RowVector6<N> = RowVectorN<N, U6>;
<commit_msg>Fix minor typos<commit_after>#[cfg(any(feature = "alloc", feature = "std"))]
use base::dimension::Dynamic;
use base::dimension::{U1, U2, U3, U4, U5, U6};
#[cfg(any(feature = "std", feature = "alloc"))]
use base::matrix_vec::MatrixVec;
use base::storage::Owned;
use base::Matrix;

/*
 *
 *
 * Column-major matrices.
 *
 *
 */
/// A statically sized column-major matrix with `R` rows and `C` columns.
#[deprecated(note = "This matrix name contains a typo. Use MatrixMN instead.")]
pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;

/// A statically sized column-major matrix with `R` rows and `C` columns.
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;

/// A statically sized column-major square matrix with `D` rows and columns.
pub type MatrixN<N, D> = MatrixMN<N, D, D>;

/// A dynamically sized column-major matrix.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type DMatrix<N> = MatrixN<N, Dynamic>;

/// A stack-allocated, column-major, 1x1 square matrix.
pub type Matrix1<N> = MatrixN<N, U1>;
/// A stack-allocated, column-major, 2x2 square matrix.
pub type Matrix2<N> = MatrixN<N, U2>;
/// A stack-allocated, column-major, 3x3 square matrix.
pub type Matrix3<N> = MatrixN<N, U3>;
/// A stack-allocated, column-major, 4x4 square matrix.
pub type Matrix4<N> = MatrixN<N, U4>;
/// A stack-allocated, column-major, 5x5 square matrix.
pub type Matrix5<N> = MatrixN<N, U5>;
/// A stack-allocated, column-major, 6x6 square matrix.
pub type Matrix6<N> = MatrixN<N, U6>;

/// A stack-allocated, column-major, 1x2 matrix.
pub type Matrix1x2<N> = MatrixMN<N, U1, U2>;
/// A stack-allocated, column-major, 1x3 matrix.
pub type Matrix1x3<N> = MatrixMN<N, U1, U3>;
/// A stack-allocated, column-major, 1x4 matrix.
pub type Matrix1x4<N> = MatrixMN<N, U1, U4>;
/// A stack-allocated, column-major, 1x5 matrix.
pub type Matrix1x5<N> = MatrixMN<N, U1, U5>;
/// A stack-allocated, column-major, 1x6 matrix.
pub type Matrix1x6<N> = MatrixMN<N, U1, U6>;

/// A stack-allocated, column-major, 2x3 matrix.
pub type Matrix2x3<N> = MatrixMN<N, U2, U3>;
/// A stack-allocated, column-major, 2x4 matrix.
pub type Matrix2x4<N> = MatrixMN<N, U2, U4>;
/// A stack-allocated, column-major, 2x5 matrix.
pub type Matrix2x5<N> = MatrixMN<N, U2, U5>;
/// A stack-allocated, column-major, 2x6 matrix.
pub type Matrix2x6<N> = MatrixMN<N, U2, U6>;

/// A stack-allocated, column-major, 3x4 matrix.
pub type Matrix3x4<N> = MatrixMN<N, U3, U4>;
/// A stack-allocated, column-major, 3x5 matrix.
pub type Matrix3x5<N> = MatrixMN<N, U3, U5>;
/// A stack-allocated, column-major, 3x6 matrix.
pub type Matrix3x6<N> = MatrixMN<N, U3, U6>;

/// A stack-allocated, column-major, 4x5 matrix.
pub type Matrix4x5<N> = MatrixMN<N, U4, U5>;
/// A stack-allocated, column-major, 4x6 matrix.
pub type Matrix4x6<N> = MatrixMN<N, U4, U6>;

/// A stack-allocated, column-major, 5x6 matrix.
pub type Matrix5x6<N> = MatrixMN<N, U5, U6>;

/// A stack-allocated, column-major, 2x1 matrix.
pub type Matrix2x1<N> = MatrixMN<N, U2, U1>;
/// A stack-allocated, column-major, 3x1 matrix.
pub type Matrix3x1<N> = MatrixMN<N, U3, U1>;
/// A stack-allocated, column-major, 4x1 matrix.
pub type Matrix4x1<N> = MatrixMN<N, U4, U1>;
/// A stack-allocated, column-major, 5x1 matrix.
pub type Matrix5x1<N> = MatrixMN<N, U5, U1>;
/// A stack-allocated, column-major, 6x1 matrix.
pub type Matrix6x1<N> = MatrixMN<N, U6, U1>;

/// A stack-allocated, column-major, 3x2 matrix.
pub type Matrix3x2<N> = MatrixMN<N, U3, U2>;
/// A stack-allocated, column-major, 4x2 matrix.
pub type Matrix4x2<N> = MatrixMN<N, U4, U2>;
/// A stack-allocated, column-major, 5x2 matrix.
pub type Matrix5x2<N> = MatrixMN<N, U5, U2>;
/// A stack-allocated, column-major, 6x2 matrix.
pub type Matrix6x2<N> = MatrixMN<N, U6, U2>;

/// A stack-allocated, column-major, 4x3 matrix.
pub type Matrix4x3<N> = MatrixMN<N, U4, U3>;
/// A stack-allocated, column-major, 5x3 matrix.
pub type Matrix5x3<N> = MatrixMN<N, U5, U3>;
/// A stack-allocated, column-major, 6x3 matrix.
pub type Matrix6x3<N> = MatrixMN<N, U6, U3>;

/// A stack-allocated, column-major, 5x4 matrix.
pub type Matrix5x4<N> = MatrixMN<N, U5, U4>;
/// A stack-allocated, column-major, 6x4 matrix.
pub type Matrix6x4<N> = MatrixMN<N, U6, U4>;

/// A stack-allocated, column-major, 6x5 matrix.
pub type Matrix6x5<N> = MatrixMN<N, U6, U5>;

/*
 *
 *
 * Column vectors.
 *
 *
 */
/// A dynamically sized column vector.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type DVector<N> = Matrix<N, Dynamic, U1, MatrixVec<N, Dynamic, U1>>;

/// A statically sized D-dimensional column vector.
pub type VectorN<N, D> = MatrixMN<N, D, U1>;

/// A stack-allocated, 1-dimensional column vector.
pub type Vector1<N> = VectorN<N, U1>;
/// A stack-allocated, 2-dimensional column vector.
pub type Vector2<N> = VectorN<N, U2>;
/// A stack-allocated, 3-dimensional column vector.
pub type Vector3<N> = VectorN<N, U3>;
/// A stack-allocated, 4-dimensional column vector.
pub type Vector4<N> = VectorN<N, U4>;
/// A stack-allocated, 5-dimensional column vector.
pub type Vector5<N> = VectorN<N, U5>;
/// A stack-allocated, 6-dimensional column vector.
pub type Vector6<N> = VectorN<N, U6>;

/*
 *
 *
 * Row vectors.
 *
 *
 */
/// A dynamically sized row vector.
#[cfg(any(feature = "std", feature = "alloc"))]
pub type RowDVector<N> = Matrix<N, U1, Dynamic, MatrixVec<N, U1, Dynamic>>;

/// A statically sized D-dimensional row vector.
pub type RowVectorN<N, D> = MatrixMN<N, U1, D>;

/// A stack-allocated, 1-dimensional row vector.
pub type RowVector1<N> = RowVectorN<N, U1>;
/// A stack-allocated, 2-dimensional row vector.
pub type RowVector2<N> = RowVectorN<N, U2>;
/// A stack-allocated, 3-dimensional row vector.
pub type RowVector3<N> = RowVectorN<N, U3>;
/// A stack-allocated, 4-dimensional row vector.
pub type RowVector4<N> = RowVectorN<N, U4>;
/// A stack-allocated, 5-dimensional row vector.
pub type RowVector5<N> = RowVectorN<N, U5>;
/// A stack-allocated, 6-dimensional row vector.
pub type RowVector6<N> = RowVectorN<N, U6>;
<|endoftext|>