<commit_before>use gfx;
use glutin;
use gfx_device_gl;

use gfx::format::{Srgba8, Rgba8};
use gfx::Device;
use gfx::traits::FactoryExt;
use gfx_window_glutin;

use Color;

use super::{Vertex, ColorFormat, DepthFormat, GeometryBuffer, Locals};
use super::{pipe_blend, pipe_opaque, get_dimensions};

use {input, JamError, JamResult};
use render::{FileResources, FileWatcher, TextureArrayDimensions, Uniforms, Blend};
use font::FontDirectory;
use {Dimensions, InputState};
use glutin::GlContext;

use image::DynamicImage;
use notify::{RawEvent};
use std::sync::mpsc::{Receiver};

pub type OpenGLRenderer = Renderer<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer, gfx_device_gl::Factory, gfx_device_gl::Device>;

pub struct Renderer<R, C, F, D> where R : gfx::Resources,
                                 C : gfx::CommandBuffer<R>,
                                 F : gfx::Factory<R>,
                                 D : gfx::Device {
    pub file_resources: FileResources,
    pub file_watcher: FileWatcher,

    // I guess closing over these with an enum would be the path
    pub window: glutin::GlWindow, // opengl
    pub events_loop: glutin::EventsLoop, // opengl

    pub device: D,
    pub factory: F,

    pub screen_colour_target: gfx::handle::RenderTargetView<R, ColorFormat>,
    pub screen_depth_target: gfx::handle::DepthStencilView<R, DepthFormat>,
    pub encoder: gfx::Encoder<R, C>,

    pub texture: Option<(gfx::handle::Texture<R, gfx::format::R8_G8_B8_A8>, gfx::handle::ShaderResourceView<R, [f32; 4]>)>,

    pub sampler: gfx::handle::Sampler<R>,

    pub pipelines: Option<Pipelines<R>>,

    pub dimensions: Dimensions,
    pub input_state: InputState,
}

pub struct Pipelines<R> where R : gfx::Resources {
    pub opaque: OpaquePipeline<R>,
    pub blend: BlendPipeline<R>,
}

pub struct OpaquePipeline<R> where R : gfx::Resources {
    pub pipeline: gfx::PipelineState<R, pipe_opaque::Meta>,
    pub data : Option<pipe_opaque::Data<R>>,
}

pub struct BlendPipeline<R> where R : gfx::Resources {
    pub pipeline: gfx::PipelineState<R, pipe_blend::Meta>,
    pub data : Option<pipe_blend::Data<R>>,
}

impl<F> Renderer<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer, F, gfx_device_gl::Device> where F : gfx::Factory<gfx_device_gl::Resources> {
    pub fn begin_frame(&mut self, clear_color: Color) -> (Dimensions, InputState) {
        self.load_resources();

        let mut events : Vec<glutin::Event> = Vec::new();

        self.events_loop.poll_events(|ev| events.push(ev));

        let mut close_requested = false;
        let mut resize = false;

        for ev in &events {
            if let &glutin::Event::WindowEvent { ref event, .. } = ev {
                match event {
                    &glutin::WindowEvent::KeyboardInput {
                        input: glutin::KeyboardInput {
                            virtual_keycode: Some(glutin::VirtualKeyCode::Escape),
                            ..
                        },
                        ..
                    } => {
                        close_requested = true
                    },
                    &glutin::WindowEvent::Closed => {
                        close_requested = true
                    },
                    &glutin::WindowEvent::Resized(width, height) => {
                        self.window.resize(width, height);
                        resize = true;
                    },
                    _ => (),
                }
            }
        }

        if resize {
            println!("resize, PRE -> {:?}", get_dimensions(&self.window));
            gfx_window_glutin::update_views(&self.window, &mut self.screen_colour_target, &mut self.screen_depth_target);
            println!("POST -> {:?}", get_dimensions(&self.window));
        }

        self.input_state = input::produce(&self.input_state, &events);
        self.input_state.close = close_requested;

        let dimensions = get_dimensions(&self.window);

        // clear
        if !close_requested {
            self.encoder.clear(&self.screen_colour_target, clear_color.float_raw());
            self.encoder.clear_depth(&self.screen_depth_target, 1.0);
//            let ad = self.screen_colour_target.get_dimensions();
//            println!("internal dimensions -> {:?}", ad);
        }

        (dimensions, self.input_state.clone())
    }

    pub fn load_resources(&mut self) {
        let (reload_program, reload_texture) = check_reload(&self.file_watcher.change_events, &self.file_resources);

        if reload_program || self.pipelines.is_none() {
            println!("LOAD PIPELINES");
            let pipeline_load_result = self.file_resources.shader_pair.load().and_then( |shader_data| {
                let opaque_pso = self.factory.create_pipeline_simple(
                    &shader_data.vertex_data,
                    &shader_data.fragment_data,
                    pipe_opaque::new()
                ).map_err(JamError::PipelineError)?;

                let blend_pso = self.factory.create_pipeline_simple(
                    &shader_data.vertex_data,
                    &shader_data.fragment_data,
                    pipe_blend::new()
                ).map_err(JamError::PipelineError)?;

                Ok(Pipelines {
                    opaque: OpaquePipeline {
                        pipeline: opaque_pso,
                        data: None,
                    },
                    blend: BlendPipeline {
                        pipeline: blend_pso,
                        data: None,
                    },
                })
            });

            match pipeline_load_result {
                Ok(p) => self.pipelines = Some(p),
                Err(e) => println!("pipeline load error -> {:?}", e),
            }
        }

        if reload_texture || self.texture.is_none() {
            println!("LOAD TEXTURES");
            let texture_load_result = self.file_resources.texture_directory.load().and_then(|texture_array_data| {
                let images_raw : Vec<_> = texture_array_data.images.iter().map(|img| {
//                    let dyn_image = DynamicImage::ImageRgba8(img.clone()).flipv();
//                    dyn_image.to_rgba().into_raw()
                    img.clone().into_raw()
                } ).collect();
                let data : Vec<_> = images_raw.iter().map(|v| v.as_slice()).collect();

                let kind = texture_kind_for(&texture_array_data.dimensions);

                println!("kind -> {:?}", kind);
                let (texture, texture_view) = self.factory.create_texture_immutable_u8::<Srgba8>(kind, data.as_slice()).map_err(JamError::CombinedGFXError)?;

                Ok((texture, texture_view))
            });

            match texture_load_result {
                Ok((t, tv)) => {
                    let pair = (t, tv);
                    self.texture = Some(pair);
                },
                Err(e) => println!("texture load error -> {:?}", e),
            }
        }
    }

    pub fn clear_depth(&mut self) {
        self.encoder.clear_depth(&self.screen_depth_target, 1.0);
    }

    pub fn upload(&mut self, vertices: &[Vertex]) -> GeometryBuffer<gfx_device_gl::Resources> {
        let (buffer, slice) = self.factory.create_vertex_buffer_with_slice(vertices, ());
        GeometryBuffer {
            buffer,
            slice,
        }
    }

    pub fn screenshot(&mut self) -> JamResult<()> { // -> image::DynamicImage
        let (width, height, depth, _) = self.screen_colour_target.get_dimensions();
        let pixels = (width as usize * height as usize * depth as usize);
        println!("screen dimensions {:?} x {:?} x {:?} pixels -> {:?}", width, height, depth, pixels);

        let download_buffer = self.factory.create_download_buffer::<u8>(pixels * 4).map_err(JamError::CreationError)?;

        // this would appear to require a frame buffer now ... which is ... quite a cost just to take screenshots.

//        self.encoder.copy_texture_to_buffer_raw(src: &RawTexture<R>, None, info: texture::RawImageInfo,
//                                                dst: &handle::RawBuffer<R>, 0);
//        ,
//        face: Option<CubeFace>,
//        info: RawImageInfo,
//        dst: &RawBuffer<R>,
//        dst_offset_bytes: usize

//        let image: glium::texture::RawImage2d<u8> = self.display.read_front_buffer();
//        let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
//        let image = image::DynamicImage::ImageRgba8(image).flipv();
//        image
        Ok(())
    }

    pub fn draw(&mut self, geometry: &GeometryBuffer<gfx_device_gl::Resources>, uniforms: Uniforms, blend:Blend) -> JamResult<()> {
        let &(ref t, ref tv) = self.texture.as_ref().ok_or(JamError::NoTexture())?;

//        println!("draw geometry -> {:?}", geometry);
        match blend {
            Blend::None => {
                let opaque_pipe = self.pipelines.as_mut().ok_or(JamError::NoPipeline()).map(|p| &mut p.opaque )?;
                let opaque_data = pipe_opaque::Data {
                    vbuf: geometry.buffer.clone(),
                    texture: (tv.clone(), self.sampler.clone()),
                    locals: self.factory.create_constant_buffer(1),
                    out_color: self.screen_colour_target.clone(),
                    out_depth: self.screen_depth_target.clone(),
                };
                let locals = Locals {
                    u_transform: uniforms.transform,
                    u_color: uniforms.color.float_raw(),
                    u_alpha_minimum: 0.01,
                };
                self.encoder.update_constant_buffer(&opaque_data.locals, &locals);
                self.encoder.draw(&geometry.slice, &opaque_pipe.pipeline, &opaque_data);
            },
            Blend::Add => {
//                println!("no add pipeline atm")
            },
            Blend::Alpha => {
                let blend_pipe = self.pipelines.as_mut().ok_or(JamError::NoPipeline()).map(|p| &mut p.blend )?;
                let blend_data = pipe_blend::Data {
                    vbuf: geometry.buffer.clone(),
                    texture: (tv.clone(), self.sampler.clone()),
                    locals: self.factory.create_constant_buffer(1),
                    out_color: self.screen_colour_target.clone(),
                    out_depth: self.screen_depth_target.clone(),
                };
                let locals = Locals {
                    u_transform: uniforms.transform,
                    u_color: uniforms.color.float_raw(),
                    u_alpha_minimum: 0.01,
                };
                self.encoder.update_constant_buffer(&blend_data.locals, &locals);
                self.encoder.draw(&geometry.slice, &blend_pipe.pipeline, &blend_data);
            },
        }

        Ok(())
    }

    pub fn draw_vertices(&mut self, vertices: &[Vertex], uniforms: Uniforms, blend:Blend) -> JamResult<GeometryBuffer<gfx_device_gl::Resources>> {
        let geometry = self.upload(vertices);
        let res = self.draw(&geometry, uniforms, blend);
        res.map(|()| geometry)
    }

    pub fn finish_frame(&mut self) -> JamResult<()> {
        self.encoder.flush(&mut self.device);
        self.window.swap_buffers().map_err(JamError::ContextError)?;
        self.device.cleanup();
        Ok(())
    }
}

pub fn texture_kind_for(dimensions: &TextureArrayDimensions) -> gfx::texture::Kind {
    gfx::texture::Kind::D2Array(dimensions.width as u16, dimensions.height as u16, dimensions.layers as u16, gfx::texture::AaMode::Single)
}

pub fn check_reload(rx: &Receiver<RawEvent>, files:&FileResources) -> (bool, bool) {
    let mut reload_program = false;
    let mut reload_texture = false;

    'fs: loop {
        match rx.try_recv() {
            Ok(RawEvent { path, op:_, cookie:_ }) => {
                if let Some(p) = path {
                    if files.shader_pair.contains(&p) {
                        reload_program = true;
                    } else if files.texture_directory.contains(&p) {
                        reload_texture = true;
                    } else {
                        use std::path;
                        let components: Vec<path::Component> = p.components().collect();
                        println!("fs event {:?} -> {:?}", p, components);
                    }
                }
            },
            Err(_) => break 'fs,
        }
    }

    (reload_program, reload_texture)
}<commit_msg>Commented out screenshot stuff<commit_after>use gfx;
use glutin;
use gfx_device_gl;

use gfx::format::{Srgba8, Rgba8};
use gfx::Device;
use gfx::traits::FactoryExt;
use gfx_window_glutin;

use Color;

use super::{Vertex, ColorFormat, DepthFormat, GeometryBuffer, Locals};
use super::{pipe_blend, pipe_opaque, get_dimensions};

use {input, JamError, JamResult};
use render::{FileResources, FileWatcher, TextureArrayDimensions, Uniforms, Blend};
use font::FontDirectory;
use {Dimensions, InputState};
use glutin::GlContext;

use image::DynamicImage;
use notify::{RawEvent};
use std::sync::mpsc::{Receiver};

pub type OpenGLRenderer = Renderer<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer, gfx_device_gl::Factory, gfx_device_gl::Device>;

pub struct Renderer<R, C, F, D> where R : gfx::Resources,
                                 C : gfx::CommandBuffer<R>,
                                 F : gfx::Factory<R>,
                                 D : gfx::Device {
    pub file_resources: FileResources,
    pub file_watcher: FileWatcher,

    // I guess closing over these with an enum would be the path
    pub window: glutin::GlWindow, // opengl
    pub events_loop: glutin::EventsLoop, // opengl

    pub device: D,
    pub factory: F,

    pub screen_colour_target: gfx::handle::RenderTargetView<R, ColorFormat>,
    pub screen_depth_target: gfx::handle::DepthStencilView<R, DepthFormat>,
    pub encoder: gfx::Encoder<R, C>,

    pub texture: Option<(gfx::handle::Texture<R, gfx::format::R8_G8_B8_A8>, gfx::handle::ShaderResourceView<R, [f32; 4]>)>,

    pub sampler: gfx::handle::Sampler<R>,

    pub pipelines: Option<Pipelines<R>>,

    pub dimensions: Dimensions,
    pub input_state: InputState,
}

pub struct Pipelines<R> where R : gfx::Resources {
    pub opaque: OpaquePipeline<R>,
    pub blend: BlendPipeline<R>,
}

pub struct OpaquePipeline<R> where R : gfx::Resources {
    pub pipeline: gfx::PipelineState<R, pipe_opaque::Meta>,
    pub data : Option<pipe_opaque::Data<R>>,
}

pub struct BlendPipeline<R> where R : gfx::Resources {
    pub pipeline: gfx::PipelineState<R, pipe_blend::Meta>,
    pub data : Option<pipe_blend::Data<R>>,
}

impl<F> Renderer<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer, F, gfx_device_gl::Device> where F : gfx::Factory<gfx_device_gl::Resources> {
    pub fn begin_frame(&mut self, clear_color: Color) -> (Dimensions, InputState) {
        self.load_resources();

        let mut events : Vec<glutin::Event> = Vec::new();

        self.events_loop.poll_events(|ev| events.push(ev));

        let mut close_requested = false;
        let mut resize = false;

        for ev in &events {
            if let &glutin::Event::WindowEvent { ref event, .. } = ev {
                match event {
                    &glutin::WindowEvent::KeyboardInput {
                        input: glutin::KeyboardInput {
                            virtual_keycode: Some(glutin::VirtualKeyCode::Escape),
                            ..
                        },
                        ..
                    } => {
                        close_requested = true
                    },
                    &glutin::WindowEvent::Closed => {
                        close_requested = true
                    },
                    &glutin::WindowEvent::Resized(width, height) => {
                        self.window.resize(width, height);
                        resize = true;
                    },
                    _ => (),
                }
            }
        }

        if resize {
            println!("resize, PRE -> {:?}", get_dimensions(&self.window));
            gfx_window_glutin::update_views(&self.window, &mut self.screen_colour_target, &mut self.screen_depth_target);
            println!("POST -> {:?}", get_dimensions(&self.window));
        }

        self.input_state = input::produce(&self.input_state, &events);
        self.input_state.close = close_requested;

        let dimensions = get_dimensions(&self.window);

        // clear
        if !close_requested {
            self.encoder.clear(&self.screen_colour_target, clear_color.float_raw());
            self.encoder.clear_depth(&self.screen_depth_target, 1.0);
//            let ad = self.screen_colour_target.get_dimensions();
//            println!("internal dimensions -> {:?}", ad);
        }

        (dimensions, self.input_state.clone())
    }

    pub fn load_resources(&mut self) {
        let (reload_program, reload_texture) = check_reload(&self.file_watcher.change_events, &self.file_resources);

        if reload_program || self.pipelines.is_none() {
            println!("LOAD PIPELINES");
            let pipeline_load_result = self.file_resources.shader_pair.load().and_then( |shader_data| {
                let opaque_pso = self.factory.create_pipeline_simple(
                    &shader_data.vertex_data,
                    &shader_data.fragment_data,
                    pipe_opaque::new()
                ).map_err(JamError::PipelineError)?;

                let blend_pso = self.factory.create_pipeline_simple(
                    &shader_data.vertex_data,
                    &shader_data.fragment_data,
                    pipe_blend::new()
                ).map_err(JamError::PipelineError)?;

                Ok(Pipelines {
                    opaque: OpaquePipeline {
                        pipeline: opaque_pso,
                        data: None,
                    },
                    blend: BlendPipeline {
                        pipeline: blend_pso,
                        data: None,
                    },
                })
            });

            match pipeline_load_result {
                Ok(p) => self.pipelines = Some(p),
                Err(e) => println!("pipeline load error -> {:?}", e),
            }
        }

        if reload_texture || self.texture.is_none() {
            println!("LOAD TEXTURES");
            let texture_load_result = self.file_resources.texture_directory.load().and_then(|texture_array_data| {
                let images_raw : Vec<_> = texture_array_data.images.iter().map(|img| {
//                    let dyn_image = DynamicImage::ImageRgba8(img.clone()).flipv();
//                    dyn_image.to_rgba().into_raw()
                    img.clone().into_raw()
                } ).collect();
                let data : Vec<_> = images_raw.iter().map(|v| v.as_slice()).collect();

                let kind = texture_kind_for(&texture_array_data.dimensions);

                println!("kind -> {:?}", kind);
                let (texture, texture_view) = self.factory.create_texture_immutable_u8::<Srgba8>(kind, data.as_slice()).map_err(JamError::CombinedGFXError)?;

                Ok((texture, texture_view))
            });

            match texture_load_result {
                Ok((t, tv)) => {
                    let pair = (t, tv);
                    self.texture = Some(pair);
                },
                Err(e) => println!("texture load error -> {:?}", e),
            }
        }
    }

    pub fn clear_depth(&mut self) {
        self.encoder.clear_depth(&self.screen_depth_target, 1.0);
    }

    pub fn upload(&mut self, vertices: &[Vertex]) -> GeometryBuffer<gfx_device_gl::Resources> {
        let (buffer, slice) = self.factory.create_vertex_buffer_with_slice(vertices, ());
        GeometryBuffer {
            buffer,
            slice,
        }
    }

    pub fn screenshot(&mut self) -> JamResult<()> { // -> image::DynamicImage
        let (width, height, depth, _) = self.screen_colour_target.get_dimensions();
        let pixels = (width as usize * height as usize * depth as usize);
        println!("screen dimensions {:?} x {:?} x {:?} pixels -> {:?}", width, height, depth, pixels);

//        let (tex, srv, rtv) = self.factory.create_render_target(width, height)?;

//        let download_buffer = self.factory.create_download_buffer::<u8>(pixels * 4).map_err(JamError::CreationError)?;

        // this would appear to require a frame buffer now ... which is ... quite a cost just to take screenshots.

//        self.encoder.copy_texture_to_buffer_raw(src: &RawTexture<R>, None, info: texture::RawImageInfo,
//                                                dst: &handle::RawBuffer<R>, 0);
//        ,
//        face: Option<CubeFace>,
//        info: RawImageInfo,
//        dst: &RawBuffer<R>,
//        dst_offset_bytes: usize

//        let image: glium::texture::RawImage2d<u8> = self.display.read_front_buffer();
//        let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
//        let image = image::DynamicImage::ImageRgba8(image).flipv();
//        image
        Ok(())
    }

    pub fn draw(&mut self, geometry: &GeometryBuffer<gfx_device_gl::Resources>, uniforms: Uniforms, blend:Blend) -> JamResult<()> {
        let &(ref t, ref tv) = self.texture.as_ref().ok_or(JamError::NoTexture())?;

//        println!("draw geometry -> {:?}", geometry);
        match blend {
            Blend::None => {
                let opaque_pipe = self.pipelines.as_mut().ok_or(JamError::NoPipeline()).map(|p| &mut p.opaque )?;
                let opaque_data = pipe_opaque::Data {
                    vbuf: geometry.buffer.clone(),
                    texture: (tv.clone(), self.sampler.clone()),
                    locals: self.factory.create_constant_buffer(1),
                    out_color: self.screen_colour_target.clone(),
                    out_depth: self.screen_depth_target.clone(),
                };
                let locals = Locals {
                    u_transform: uniforms.transform,
                    u_color: uniforms.color.float_raw(),
                    u_alpha_minimum: 0.01,
                };
                self.encoder.update_constant_buffer(&opaque_data.locals, &locals);
                self.encoder.draw(&geometry.slice, &opaque_pipe.pipeline, &opaque_data);
            },
            Blend::Add => {
//                println!("no add pipeline atm")
            },
            Blend::Alpha => {
                let blend_pipe = self.pipelines.as_mut().ok_or(JamError::NoPipeline()).map(|p| &mut p.blend )?;
                let blend_data = pipe_blend::Data {
                    vbuf: geometry.buffer.clone(),
                    texture: (tv.clone(), self.sampler.clone()),
                    locals: self.factory.create_constant_buffer(1),
                    out_color: self.screen_colour_target.clone(),
                    out_depth: self.screen_depth_target.clone(),
                };
                let locals = Locals {
                    u_transform: uniforms.transform,
                    u_color: uniforms.color.float_raw(),
                    u_alpha_minimum: 0.01,
                };
                self.encoder.update_constant_buffer(&blend_data.locals, &locals);
                self.encoder.draw(&geometry.slice, &blend_pipe.pipeline, &blend_data);
            },
        }

        Ok(())
    }

    pub fn draw_vertices(&mut self, vertices: &[Vertex], uniforms: Uniforms, blend:Blend) -> JamResult<GeometryBuffer<gfx_device_gl::Resources>> {
        let geometry = self.upload(vertices);
        let res = self.draw(&geometry, uniforms, blend);
        res.map(|()| geometry)
    }

    pub fn finish_frame(&mut self) -> JamResult<()> {
        self.encoder.flush(&mut self.device);
        self.window.swap_buffers().map_err(JamError::ContextError)?;
        self.device.cleanup();
        Ok(())
    }
}

pub fn texture_kind_for(dimensions: &TextureArrayDimensions) -> gfx::texture::Kind {
    gfx::texture::Kind::D2Array(dimensions.width as u16, dimensions.height as u16, dimensions.layers as u16, gfx::texture::AaMode::Single)
}

pub fn check_reload(rx: &Receiver<RawEvent>, files:&FileResources) -> (bool, bool) {
    let mut reload_program = false;
    let mut reload_texture = false;

    'fs: loop {
        match rx.try_recv() {
            Ok(RawEvent { path, op:_, cookie:_ }) => {
                if let Some(p) = path {
                    if files.shader_pair.contains(&p) {
                        reload_program = true;
                    } else if files.texture_directory.contains(&p) {
                        reload_texture = true;
                    } else {
                        use std::path;
                        let components: Vec<path::Component> = p.components().collect();
                        println!("fs event {:?} -> {:?}", p, components);
                    }
                }
            },
            Err(_) => break 'fs,
        }
    }

    (reload_program, reload_texture)
}<|endoftext|>


<commit_before>use helper::*;
use nom::{self, is_digit};
use super::{Time, DateTime, Date};

macro_rules! empty_or(
    ($i:expr, $submac:ident!( $($args:tt)* )) => (
        if $i.len() == 0 {
            nom::IResult::Done($i, None)
        } else {
            match $submac!($i, $($args)*) {
                nom::IResult::Done(i,o)     => nom::IResult::Done(i, Some(o)),
                nom::IResult::Error(_)      => nom::IResult::Done($i, None),
                nom::IResult::Incomplete(i) => nom::IResult::Incomplete(i)

            }
        }
    );
);

macro_rules! check(
  ($input:expr, $submac:ident!( $($args:tt)* )) => (

    {
      let mut failed = false;
      for idx in 0..$input.len() {
        if !$submac!($input[idx], $($args)*) {
            failed = true;
            break;
        }
      }
      if failed {
        nom::IResult::Error(nom::Err::Position(nom::ErrorKind::Custom(20),$input))
      } else {
        nom::IResult::Done(&b""[..], $input)
      }
    }
  );
  ($input:expr, $f:expr) => (
    check!($input, call!($f));
  );
);

macro_rules! char_between(
    ($input:expr, $min:expr, $max:expr) => (
        {
        fn f(c: u8) -> bool { c >= ($min as u8) && c <= ($max as u8)}
        flat_map!($input, take!(1), check!(f))
        }
    );
);

named!(pub take_4_digits, flat_map!(take!(4), check!(is_digit)));

// year
named!(year_prefix, alt!(tag!("+") | tag!("-")));
named!(pub year <i32>, chain!(
        pref: opt!(year_prefix) ~
        year: call!(take_4_digits)
        ,
        || {
            match pref {
                Some(b"-") => -buf_to_i32(year),
                _ => buf_to_i32(year)
            }
        }));

// MM
named!(lower_month <u32>, chain!(tag!("0") ~ s:char_between!('1', '9') , || buf_to_u32(s)));
named!(upper_month <u32>, chain!(tag!("1") ~ s:char_between!('0', '2') , || 10+buf_to_u32(s)));
named!(pub month <u32>, alt!(lower_month | upper_month));

// DD
named!(day_zero  <u32>, chain!(tag!("0") ~ s:char_between!('1', '9') , || buf_to_u32(s)));
named!(day_one   <u32>, chain!(tag!("1") ~ s:char_between!('0', '9') , || 10+buf_to_u32(s)));
named!(day_two   <u32>, chain!(tag!("2") ~ s:char_between!('0', '9') , || 20+buf_to_u32(s)));
named!(day_three <u32>, chain!(tag!("3") ~ s:char_between!('0', '1') , || 30+buf_to_u32(s)));
named!(pub day <u32>, alt!(day_zero | day_one | day_two | day_three));

// WW
// reusing day_N parsers, sorry
named!(week_three <u32>, chain!(tag!("3") ~ s:char_between!('0', '9') , || 30+buf_to_u32(s)));
named!(week_four  <u32>, chain!(tag!("4") ~ s:char_between!('0', '9') , || 40+buf_to_u32(s)));
named!(week_five  <u32>, chain!(tag!("5") ~ s:char_between!('0', '3') , || 50+buf_to_u32(s)));

named!(week <u32>, alt!(day_zero | day_one | day_two | week_three| week_four | week_five ));
named!(week_day <u32>, chain!(s:char_between!('1', '7') , || buf_to_u32(s)));

// ordinal DDD
named!(ord_day <u32>, chain!(
        a:char_between!('0','3') ~
        b:char_between!('0','9') ~
        c:char_between!('0','9')
        ,
        || { buf_to_u32(a)*100 + buf_to_u32(b)*10 + buf_to_u32(c) }
        ));

// YYYY-MM-DD
named!(pub ymd_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        m: month ~
        opt!(tag!("-")) ~
        d: day
        ,
        || { Date::YMD{ year: y, month: m, day: d } }
        ));

// YYYY-MM-DD
named!(pub ordinal_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        d: ord_day
        ,
        || { Date::Ordinal{ year: y, ddd: d } }
        ));

// YYYY-"W"WW-D
named!(pub iso_week_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        tag!("W") ~
        w: week ~
        opt!(tag!("-")) ~
        d: week_day
        ,
        || { Date::Week{ year: y, ww: w, d: d } }
        ));

named!(pub parse_date <Date>, alt!( ymd_date | iso_week_date | ordinal_date ) );

// TIME

// HH
named!(lower_hour <u32>, chain!(f:char_between!('0','1') ~ s:char_between!('0','9') ,
                                       || { buf_to_u32(f)*10 + buf_to_u32(s) } ));
named!(upper_hour <u32>, chain!(tag!("2") ~ s:char_between!('0','4') , || 20+buf_to_u32(s)));
named!(pub hour <u32>, alt!(lower_hour | upper_hour));

// MM
named!(below_sixty <u32>, chain!(f:char_between!('0','5') ~ s:char_between!('0','9'), || { buf_to_u32(f)*10 + buf_to_u32(s) } ));
named!(upto_sixty <u32>, alt!(below_sixty | map!(tag!("60"), |_| 60)));

named!(pub minute <u32>, call!(below_sixty));
named!(pub second <u32>, call!(upto_sixty));
named!(pub millisecond <u32>, chain!( ms: is_a!("0123456789"), || buf_to_u32(ms) ) );

// HH:MM:[SS][.(m*)][(Z|+...|-...)]
named!(pub parse_time <Time>, chain!(
        h: hour ~
        opt!(tag!(":")) ~
        m: minute ~
        s:  opt!( chain!( opt!(tag!(":")) ~ s:second, || s)) ~
        ms: opt!( chain!( tag!(".") ~ ms:millisecond, || ms)) ~
        z:  opt!( alt!( timezone_hour | timezone_utc) ) ,
        || {
            Time {
                hour: h,
                minute: m,
                second: s.unwrap_or(0),
                millisecond: ms.unwrap_or(0),
                tz_offset_hours: z.unwrap_or((0,0)).0,
                tz_offset_minutes: z.unwrap_or((0,0)).1
            }
        }
        ));

named!(sign <i32>, alt!(
        tag!("-") => { |_| -1 } |
        tag!("+") => { |_| 1 }
        )
    );

named!(timezone_hour <(i32,i32)>, chain!(
        s: sign ~
        h: hour ~
        m: empty_or!(
            chain!(
                tag!(":")? ~ m: minute , || { m }
            ))
        ,
        || { (s * (h as i32) , s * (m.unwrap_or(0) as i32)) }
        ));

named!(timezone_utc <(i32,i32)>, map!(tag!("Z"), |_| (0,0)));

// Full ISO8601
named!(pub parse_datetime <DateTime>, chain!(
        d: parse_date ~
        tag!("T") ~
        t: parse_time
        ,
        || {
            DateTime{
                date: d,
                time: t,
            }
        }
        ));
<commit_msg>changed a chain to map<commit_after>use helper::*;
use nom::{self, is_digit};
use super::{Time, DateTime, Date};

macro_rules! empty_or(
    ($i:expr, $submac:ident!( $($args:tt)* )) => (
        if $i.len() == 0 {
            nom::IResult::Done($i, None)
        } else {
            match $submac!($i, $($args)*) {
                nom::IResult::Done(i,o)     => nom::IResult::Done(i, Some(o)),
                nom::IResult::Error(_)      => nom::IResult::Done($i, None),
                nom::IResult::Incomplete(i) => nom::IResult::Incomplete(i)

            }
        }
    );
);

macro_rules! check(
  ($input:expr, $submac:ident!( $($args:tt)* )) => (

    {
      let mut failed = false;
      for idx in 0..$input.len() {
        if !$submac!($input[idx], $($args)*) {
            failed = true;
            break;
        }
      }
      if failed {
        nom::IResult::Error(nom::Err::Position(nom::ErrorKind::Custom(20),$input))
      } else {
        nom::IResult::Done(&b""[..], $input)
      }
    }
  );
  ($input:expr, $f:expr) => (
    check!($input, call!($f));
  );
);

macro_rules! char_between(
    ($input:expr, $min:expr, $max:expr) => (
        {
        fn f(c: u8) -> bool { c >= ($min as u8) && c <= ($max as u8)}
        flat_map!($input, take!(1), check!(f))
        }
    );
);

named!(pub take_4_digits, flat_map!(take!(4), check!(is_digit)));

// year
named!(year_prefix, alt!(tag!("+") | tag!("-")));
named!(pub year <i32>, chain!(
        pref: opt!(year_prefix) ~
        year: call!(take_4_digits)
        ,
        || {
            match pref {
                Some(b"-") => -buf_to_i32(year),
                _ => buf_to_i32(year)
            }
        }));

// MM
named!(lower_month <u32>, chain!(tag!("0") ~ s:char_between!('1', '9') , || buf_to_u32(s)));
named!(upper_month <u32>, chain!(tag!("1") ~ s:char_between!('0', '2') , || 10+buf_to_u32(s)));
named!(pub month <u32>, alt!(lower_month | upper_month));

// DD
named!(day_zero  <u32>, chain!(tag!("0") ~ s:char_between!('1', '9') , || buf_to_u32(s)));
named!(day_one   <u32>, chain!(tag!("1") ~ s:char_between!('0', '9') , || 10+buf_to_u32(s)));
named!(day_two   <u32>, chain!(tag!("2") ~ s:char_between!('0', '9') , || 20+buf_to_u32(s)));
named!(day_three <u32>, chain!(tag!("3") ~ s:char_between!('0', '1') , || 30+buf_to_u32(s)));
named!(pub day <u32>, alt!(day_zero | day_one | day_two | day_three));

// WW
// reusing day_N parsers, sorry
named!(week_three <u32>, chain!(tag!("3") ~ s:char_between!('0', '9') , || 30+buf_to_u32(s)));
named!(week_four  <u32>, chain!(tag!("4") ~ s:char_between!('0', '9') , || 40+buf_to_u32(s)));
named!(week_five  <u32>, chain!(tag!("5") ~ s:char_between!('0', '3') , || 50+buf_to_u32(s)));

named!(week <u32>, alt!(day_zero | day_one | day_two | week_three| week_four | week_five ));
named!(week_day <u32>, chain!(s:char_between!('1', '7') , || buf_to_u32(s)));

// ordinal DDD
named!(ord_day <u32>, chain!(
        a:char_between!('0','3') ~
        b:char_between!('0','9') ~
        c:char_between!('0','9')
        ,
        || { buf_to_u32(a)*100 + buf_to_u32(b)*10 + buf_to_u32(c) }
        ));

// YYYY-MM-DD
named!(pub ymd_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        m: month ~
        opt!(tag!("-")) ~
        d: day
        ,
        || { Date::YMD{ year: y, month: m, day: d } }
        ));

// YYYY-MM-DD
named!(pub ordinal_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        d: ord_day
        ,
        || { Date::Ordinal{ year: y, ddd: d } }
        ));

// YYYY-"W"WW-D
named!(pub iso_week_date <Date>, chain!(
        y: year ~
        opt!(tag!("-")) ~
        tag!("W") ~
        w: week ~
        opt!(tag!("-")) ~
        d: week_day
        ,
        || { Date::Week{ year: y, ww: w, d: d } }
        ));

named!(pub parse_date <Date>, alt!( ymd_date | iso_week_date | ordinal_date ) );

// TIME

// HH
named!(lower_hour <u32>, chain!(f:char_between!('0','1') ~ s:char_between!('0','9') ,
                                       || { buf_to_u32(f)*10 + buf_to_u32(s) } ));
named!(upper_hour <u32>, chain!(tag!("2") ~ s:char_between!('0','4') , || 20+buf_to_u32(s)));
named!(pub hour <u32>, alt!(lower_hour | upper_hour));

// MM
named!(below_sixty <u32>, chain!(f:char_between!('0','5') ~ s:char_between!('0','9'), || { buf_to_u32(f)*10 + buf_to_u32(s) } ));
named!(upto_sixty <u32>, alt!(below_sixty | map!(tag!("60"), |_| 60)));

named!(pub minute <u32>, call!(below_sixty));
named!(pub second <u32>, call!(upto_sixty);
named!(pub millisecond <u32>, map!( is_a!("0123456789"), |ms| buf_to_u32(ms) ) );

// HH:MM:[SS][.(m*)][(Z|+...|-...)]
named!(pub parse_time <Time>, chain!(
        h: hour ~
        opt!(tag!(":")) ~
        m: minute ~
        s:  opt!( chain!( opt!(tag!(":")) ~ s:second, || s)) ~
        ms: opt!( chain!( tag!(".") ~ ms:millisecond, || ms)) ~
        z:  opt!( alt!( timezone_hour | timezone_utc) ) ,
        || {
            Time {
                hour: h,
                minute: m,
                second: s.unwrap_or(0),
                millisecond: ms.unwrap_or(0),
                tz_offset_hours: z.unwrap_or((0,0)).0,
                tz_offset_minutes: z.unwrap_or((0,0)).1
            }
        }
        ));

named!(sign <i32>, alt!(
        tag!("-") => { |_| -1 } |
        tag!("+") => { |_| 1 }
        )
    );

named!(timezone_hour <(i32,i32)>, chain!(
        s: sign ~
        h: hour ~
        m: empty_or!(
            chain!(
                tag!(":")? ~ m: minute , || { m }
            ))
        ,
        || { (s * (h as i32) , s * (m.unwrap_or(0) as i32)) }
        ));

named!(timezone_utc <(i32,i32)>, map!(tag!("Z"), |_| (0,0)));

// Full ISO8601
named!(pub parse_datetime <DateTime>, chain!(
        d: parse_date ~
        tag!("T") ~
        t: parse_time
        ,
        || {
            DateTime{
                date: d,
                time: t,
            }
        }
        ));
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

//! The [`uuid`] prelude.
//!
//! This module contains the most important items of the [`uuid`] crate.
//!
//! To use the prelude, include the following in your crate root:
//!
//! ```rust
//! extern crate uuid;
//! ```
//!
//! and the following in every module:
//!
//! ```rust
//! use uuid::prelude::*;
//! ```
//!
//! # Prelude Contents
//!
//! Currently the prelude reexports the following:
//!
//! [`uuid`]`::{`[`Uuid`], [`Variant`], [`Version`], builder::[`Builder`]`}`:
//! The fundamental types used in [`uuid`] crate.
//!
//! [`uuid`]: ../index.html
//! [`Uuid`]: ../struct.Uuid.html
//! [`Variant`]: ../enum.Variant.html
//! [`Version`]: ../enum.Version.html
//! [`Builder`]: ../builder/struct.Builder.html
//!
#![cfg_attr(feature = "v1",
doc = "
[`uuid::v1`]`::{`[`ClockSequence`],[`Context`]`}`: The types useful for
handling uuid version 1. Requires feature `v1`.

[`uuid::v1`]: ../v1/index.html
[`Context`]: ../v1/struct.Context.html
[`ClockSequence`]: ../v1/trait.ClockSequence.html")]

pub use super::{Builder, Bytes, Uuid, Variant, Version};
#[cfg(feature = "v1")]
pub use v1::{ClockSequence, Context};
<commit_msg>add uuid::Error to the prelude<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

//! The [`uuid`] prelude.
//!
//! This module contains the most important items of the [`uuid`] crate.
//!
//! To use the prelude, include the following in your crate root:
//!
//! ```rust
//! extern crate uuid;
//! ```
//!
//! and the following in every module:
//!
//! ```rust
//! use uuid::prelude::*;
//! ```
//!
//! # Prelude Contents
//!
//! Currently the prelude reexports the following:
//!
//! [`uuid`]`::{`[`Error`], [`Uuid`], [`Variant`], [`Version`], builder::[`Builder`]`}`:
//! The fundamental types used in [`uuid`] crate.
//!
//! [`uuid`]: ../index.html
//! [`Error`]: ../enum.Error.html
//! [`Uuid`]: ../struct.Uuid.html
//! [`Variant`]: ../enum.Variant.html
//! [`Version`]: ../enum.Version.html
//! [`Builder`]: ../builder/struct.Builder.html
//!
#![cfg_attr(feature = "v1",
doc = "
[`uuid::v1`]`::{`[`ClockSequence`],[`Context`]`}`: The types useful for
handling uuid version 1. Requires feature `v1`.

[`uuid::v1`]: ../v1/index.html
[`Context`]: ../v1/struct.Context.html
[`ClockSequence`]: ../v1/trait.ClockSequence.html")]

pub use super::{Builder, Bytes, Uuid, Variant, Version};
#[cfg(feature = "v1")]
pub use v1::{ClockSequence, Context};
<|endoftext|>


<commit_before>use std::f64::INFINITY;
use raytracer::Intersection;
use scene::Scene;
use vec3::Vec3;

pub struct Ray {
    pub origin: Vec3,
    pub direction: Vec3,
    pub inverse_dir: Vec3 // This is used to optimise ray-bbox intersection checks
}

impl Ray {
    pub fn new(origin: Vec3, direction: Vec3) -> Ray {
        Ray {
            origin: origin,
            direction: direction,
            inverse_dir: Vec3 {
                x: 1.0 / direction.x,
                y: 1.0 / direction.y,
                z: 1.0 / direction.z
            }.scale(-1.0)
        }
    }

    pub fn get_nearest_hit<'a>(&'a self, scene: &'a Scene) -> Option<Intersection<'a>> {
        let t_min = 0.000001;
        let mut nearest_hit = None;
        let mut nearest_t = INFINITY;

        let candidate_nodes = scene.prim_strat.get_intersection_objects(self);

        for prim in candidate_nodes.iter() {
            let intersection = prim.intersects(self, t_min, nearest_t);

            nearest_hit = match intersection {
                Some(intersection) => {
                    if intersection.t > t_min && intersection.t < nearest_t {
                        nearest_t = intersection.t;
                        Some(intersection)
                    } else {
                        nearest_hit
                    }
                }
                None => {nearest_hit}
            };
        }

        nearest_hit
    }
}
<commit_msg>Missed one spot where -Vec3 is used<commit_after>use std::f64::INFINITY;
use raytracer::Intersection;
use scene::Scene;
use vec3::Vec3;

pub struct Ray {
    pub origin: Vec3,
    pub direction: Vec3,
    pub inverse_dir: Vec3 // This is used to optimise ray-bbox intersection checks
}

impl Ray {
    pub fn new(origin: Vec3, direction: Vec3) -> Ray {
        Ray {
            origin: origin,
            direction: direction,
            inverse_dir: -Vec3 {
                x: 1.0 / direction.x,
                y: 1.0 / direction.y,
                z: 1.0 / direction.z
            }
        }
    }

    pub fn get_nearest_hit<'a>(&'a self, scene: &'a Scene) -> Option<Intersection<'a>> {
        let t_min = 0.000001;
        let mut nearest_hit = None;
        let mut nearest_t = INFINITY;

        let candidate_nodes = scene.prim_strat.get_intersection_objects(self);

        for prim in candidate_nodes.iter() {
            let intersection = prim.intersects(self, t_min, nearest_t);

            nearest_hit = match intersection {
                Some(intersection) => {
                    if intersection.t > t_min && intersection.t < nearest_t {
                        nearest_t = intersection.t;
                        Some(intersection)
                    } else {
                        nearest_hit
                    }
                }
                None => {nearest_hit}
            };
        }

        nearest_hit
    }
}
<|endoftext|>


<commit_before>use simd::f32x4;
use simd::x86::sse3::Sse3F32x4;
use num::complex::Complex;
use super::Simd;
use simd::x86::sse2::f64x2;

pub type Reg32 = f32x4;

pub type Reg64 = f64x2;

impl Simd<f32> for f32x4
{
    type Array = [f32; 4];

    #[inline]
    fn to_array(self) -> Self::Array {
        let mut target = [0.0; 4];
        self.store(&mut target, 0);
        target
    }

    type ComplexArray = [Complex<f32>; 2];

    #[inline]
    fn len() -> usize {
        4
    }

    #[inline]
    fn load_wrap_unchecked(array: &[f32], idx: usize) -> f32x4 {
        let mut temp = [0.0; 4];
        for i in 0..temp.len() {
            temp[i] = unsafe {*array.get_unchecked((idx + i) % array.len())};
        }
        f32x4::load(&temp, 0)
    }

    #[inline]
    fn from_complex(value: Complex<f32>) -> f32x4 {
        f32x4::new(value.re, value.im, value.re, value.im)
    }

    #[inline]
    fn add_real(self, value: f32) -> f32x4
    {
        let increment = f32x4::splat(value);
        self + increment
    }

    #[inline]
    fn add_complex(self, value: Complex<f32>) -> f32x4
    {
        let increment = f32x4::new(value.re, value.im, value.re, value.im);
        self + increment
    }

    #[inline]
    fn scale_real(self, value: f32) -> f32x4
    {
        let scale_vector = f32x4::splat(value);
        self * scale_vector
    }

    #[inline]
    fn scale_complex(self, value: Complex<f32>) -> f32x4
    {
        let scaling_real = f32x4::splat(value.re);
        let scaling_imag = f32x4::splat(value.im);
        let parallel = scaling_real * self;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(self.extract(1), self.extract(0), self.extract(3), self.extract(2));
        let cross = scaling_imag * shuffled;
        parallel.addsub(cross)
    }

    #[inline]
    fn mul_complex(self, value: f32x4) -> f32x4
    {
        let scaling_real = f32x4::new(value.extract(0), value.extract(0), value.extract(2), value.extract(2));

        let scaling_imag = f32x4::new(value.extract(1), value.extract(1), value.extract(3), value.extract(3));

        let parallel = scaling_real * self;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(self.extract(1), self.extract(0), self.extract(3), self.extract(2));

        let cross = scaling_imag * shuffled;
        parallel.addsub(cross)
    }

    #[inline]
    fn div_complex(self, value: f32x4) -> f32x4
    {
        let scaling_imag = f32x4::new(self.extract(0), self.extract(0), self.extract(2), self.extract(2));
        let scaling_real = f32x4::new(self.extract(1), self.extract(1), self.extract(3), self.extract(3));
        let parallel = scaling_real * value;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(value.extract(1), value.extract(0), value.extract(3), value.extract(2));

        let cross = scaling_imag * shuffled;
        let mul = parallel.addsub(cross);
        let square = shuffled * shuffled;
        let square_shuffled = f32x4::new(square.extract(1), square.extract(0), square.extract(3), square.extract(2));

        let sum = square + square_shuffled;
        let div = mul / sum;
        f32x4::new(div.extract(1), div.extract(0), div.extract(3), div.extract(2))
    }

    #[inline]
    fn complex_abs_squared(self) -> f32x4
    {
        let squared = self * self;

        squared.hadd(squared)
    }

    #[inline]
    fn complex_abs(self) -> f32x4
    {
        let squared = self * self;

        let squared_sum = squared.hadd(squared);
        squared_sum.sqrt()
    }

    #[inline]
    fn complex_abs_squared2(self) -> f32x4
    {

        let abs = self.complex_abs_squared();
        f32x4::new(abs.extract(0), abs.extract(2), abs.extract(1), abs.extract(3))
    }

    #[inline]
    fn complex_abs2(self) -> f32x4
    {

        let abs = self.complex_abs();
        f32x4::new(abs.extract(0), abs.extract(2), abs.extract(1), abs.extract(3))
    }

    #[inline]
    fn sqrt(self) -> f32x4 {
        self.sqrt()
    }

    #[inline]
    fn store_half_unchecked(self, target: &mut [f32], index: usize)
    {
        let mut temp = [0.0; 4];
        self.store(&mut temp, 0);
        unsafe {
            *target.get_unchecked_mut(index) = temp[0];
            *target.get_unchecked_mut(index + 1) = temp[1];
        }
    }

    #[inline]
    fn sum_real(&self) -> f32 {
        self.extract(0) +
        self.extract(1) +
        self.extract(2) +
        self.extract(3)
    }

    #[inline]
    fn sum_complex(&self) -> Complex<f32> {
        Complex::<f32>::new(self.extract(0) + self.extract(2), self.extract(1) + self.extract(3))
    }
}

impl Simd<f64> for f64x2
{
    type Array = [f64; 2];

    #[inline]
    fn to_array(self) -> Self::Array {
        let mut target = [0.0; 2];
        self.store(&mut target, 0);
        target
    }

    type ComplexArray = [Complex<f64>; 1];

    #[inline]
    fn len() -> usize {
        2
    }

    #[inline]
    fn load(array: &[f64], idx: usize) -> f64x2 {
        f64x2::load(array, idx)
    }

    #[inline]
    fn load_wrap_unchecked(array: &[f64], idx: usize) -> f64x2 {
        let mut temp = [0.0; 2];
        for i in 0..temp.len() {
            temp[i] = unsafe {*array.get_unchecked((idx + i) % array.len())};
        }

        f64x2::load(&temp, 0)
    }

    #[inline]
    fn from_complex(value: Complex<f64>) -> f64x2 {
        f64x2::new(value.re, value.im)
    }

    #[inline]
    fn add_real(self, value: f64) -> f64x2
    {
        let increment = f64x2::splat(value);
        self + increment
    }

    #[inline]
    fn add_complex(self, value: Complex<f64>) -> f64x2
    {
        let increment = f64x2::new(value.re, value.im);
        self + increment
    }

    #[inline]
    fn scale_real(self, value: f64) -> f64x2
    {
        let scale_vector = f64x2::splat(value);
        self * scale_vector
    }

    #[inline]
    fn scale_complex(self, value: Complex<f64>) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let result = complex * value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn mul_complex(self, value: f64x2) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let value = Complex::new(value.extract(0), value.extract(1));
        let result = complex * value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn div_complex(self, value: f64x2) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let value = Complex::new(value.extract(0), value.extract(1));
        let result = complex / value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn complex_abs_squared(self) -> f64x2
    {
        let a = self.extract(0);
        let b = self.extract(1);
        let result = a * a + b * b;
        f64x2::new(result, 0.0)
    }

    #[inline]
    fn complex_abs(self) -> f64x2
    {
        let a = self.extract(0);
        let b = self.extract(1);
        let result = (a * a + b * b).sqrt();
        f64x2::new(result, 0.0)
    }
    #[inline]

    fn complex_abs_squared2(self) -> f64x2
    {
        self.complex_abs_squared()
    }

    #[inline]
    fn complex_abs2(self) -> f64x2
    {
        self.complex_abs()
    }

    #[inline]
    fn sqrt(self) -> f64x2 {
        f64x2::new(self.extract(0).sqrt(), self.extract(1).sqrt())
    }

    #[inline]
    fn store_half_unchecked(self, target: &mut [f64], index: usize)
    {
        unsafe {
            *target.get_unchecked_mut(index) = self.extract(0);
        }
    }

    #[inline]
    fn sum_real(&self) -> f64 {
        self.extract(0) +
        self.extract(1)
    }

    #[inline]
    fn sum_complex(&self) -> Complex<f64> {
        Complex::<f64>::new(self.extract(0), self.extract(1))
    }
} <commit_msg>Removed unused method<commit_after>use simd::f32x4;
use simd::x86::sse3::Sse3F32x4;
use num::complex::Complex;
use super::Simd;
use simd::x86::sse2::f64x2;

pub type Reg32 = f32x4;

pub type Reg64 = f64x2;

impl Simd<f32> for f32x4
{
    type Array = [f32; 4];

    #[inline]
    fn to_array(self) -> Self::Array {
        let mut target = [0.0; 4];
        self.store(&mut target, 0);
        target
    }

    type ComplexArray = [Complex<f32>; 2];

    #[inline]
    fn len() -> usize {
        4
    }

    #[inline]
    fn load_wrap_unchecked(array: &[f32], idx: usize) -> f32x4 {
        let mut temp = [0.0; 4];
        for i in 0..temp.len() {
            temp[i] = unsafe {*array.get_unchecked((idx + i) % array.len())};
        }
        f32x4::load(&temp, 0)
    }

    #[inline]
    fn from_complex(value: Complex<f32>) -> f32x4 {
        f32x4::new(value.re, value.im, value.re, value.im)
    }

    #[inline]
    fn add_real(self, value: f32) -> f32x4
    {
        let increment = f32x4::splat(value);
        self + increment
    }

    #[inline]
    fn add_complex(self, value: Complex<f32>) -> f32x4
    {
        let increment = f32x4::new(value.re, value.im, value.re, value.im);
        self + increment
    }

    #[inline]
    fn scale_real(self, value: f32) -> f32x4
    {
        let scale_vector = f32x4::splat(value);
        self * scale_vector
    }

    #[inline]
    fn scale_complex(self, value: Complex<f32>) -> f32x4
    {
        let scaling_real = f32x4::splat(value.re);
        let scaling_imag = f32x4::splat(value.im);
        let parallel = scaling_real * self;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(self.extract(1), self.extract(0), self.extract(3), self.extract(2));
        let cross = scaling_imag * shuffled;
        parallel.addsub(cross)
    }

    #[inline]
    fn mul_complex(self, value: f32x4) -> f32x4
    {
        let scaling_real = f32x4::new(value.extract(0), value.extract(0), value.extract(2), value.extract(2));

        let scaling_imag = f32x4::new(value.extract(1), value.extract(1), value.extract(3), value.extract(3));

        let parallel = scaling_real * self;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(self.extract(1), self.extract(0), self.extract(3), self.extract(2));

        let cross = scaling_imag * shuffled;
        parallel.addsub(cross)
    }

    #[inline]
    fn div_complex(self, value: f32x4) -> f32x4
    {
        let scaling_imag = f32x4::new(self.extract(0), self.extract(0), self.extract(2), self.extract(2));
        let scaling_real = f32x4::new(self.extract(1), self.extract(1), self.extract(3), self.extract(3));
        let parallel = scaling_real * value;
        // There should be a shufps operation which shuffles the vector self
        let shuffled = f32x4::new(value.extract(1), value.extract(0), value.extract(3), value.extract(2));

        let cross = scaling_imag * shuffled;
        let mul = parallel.addsub(cross);
        let square = shuffled * shuffled;
        let square_shuffled = f32x4::new(square.extract(1), square.extract(0), square.extract(3), square.extract(2));

        let sum = square + square_shuffled;
        let div = mul / sum;
        f32x4::new(div.extract(1), div.extract(0), div.extract(3), div.extract(2))
    }

    #[inline]
    fn complex_abs_squared(self) -> f32x4
    {
        let squared = self * self;

        squared.hadd(squared)
    }

    #[inline]
    fn complex_abs(self) -> f32x4
    {
        let squared = self * self;

        let squared_sum = squared.hadd(squared);
        squared_sum.sqrt()
    }

    #[inline]
    fn complex_abs_squared2(self) -> f32x4
    {

        let abs = self.complex_abs_squared();
        f32x4::new(abs.extract(0), abs.extract(2), abs.extract(1), abs.extract(3))
    }

    #[inline]
    fn complex_abs2(self) -> f32x4
    {

        let abs = self.complex_abs();
        f32x4::new(abs.extract(0), abs.extract(2), abs.extract(1), abs.extract(3))
    }

    #[inline]
    fn sqrt(self) -> f32x4 {
        self.sqrt()
    }

    #[inline]
    fn store_half_unchecked(self, target: &mut [f32], index: usize)
    {
        let mut temp = [0.0; 4];
        self.store(&mut temp, 0);
        unsafe {
            *target.get_unchecked_mut(index) = temp[0];
            *target.get_unchecked_mut(index + 1) = temp[1];
        }
    }

    #[inline]
    fn sum_real(&self) -> f32 {
        self.extract(0) +
        self.extract(1) +
        self.extract(2) +
        self.extract(3)
    }

    #[inline]
    fn sum_complex(&self) -> Complex<f32> {
        Complex::<f32>::new(self.extract(0) + self.extract(2), self.extract(1) + self.extract(3))
    }
}

impl Simd<f64> for f64x2
{
    type Array = [f64; 2];

    #[inline]
    fn to_array(self) -> Self::Array {
        let mut target = [0.0; 2];
        self.store(&mut target, 0);
        target
    }

    type ComplexArray = [Complex<f64>; 1];

    #[inline]
    fn len() -> usize {
        2
    }

    #[inline]
    fn load_wrap_unchecked(array: &[f64], idx: usize) -> f64x2 {
        let mut temp = [0.0; 2];
        for i in 0..temp.len() {
            temp[i] = unsafe {*array.get_unchecked((idx + i) % array.len())};
        }

        f64x2::load(&temp, 0)
    }

    #[inline]
    fn from_complex(value: Complex<f64>) -> f64x2 {
        f64x2::new(value.re, value.im)
    }

    #[inline]
    fn add_real(self, value: f64) -> f64x2
    {
        let increment = f64x2::splat(value);
        self + increment
    }

    #[inline]
    fn add_complex(self, value: Complex<f64>) -> f64x2
    {
        let increment = f64x2::new(value.re, value.im);
        self + increment
    }

    #[inline]
    fn scale_real(self, value: f64) -> f64x2
    {
        let scale_vector = f64x2::splat(value);
        self * scale_vector
    }

    #[inline]
    fn scale_complex(self, value: Complex<f64>) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let result = complex * value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn mul_complex(self, value: f64x2) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let value = Complex::new(value.extract(0), value.extract(1));
        let result = complex * value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn div_complex(self, value: f64x2) -> f64x2
    {
        let complex = Complex::new(self.extract(0), self.extract(1));
        let value = Complex::new(value.extract(0), value.extract(1));
        let result = complex / value;
        f64x2::new(result.re, result.im)
    }

    #[inline]
    fn complex_abs_squared(self) -> f64x2
    {
        let a = self.extract(0);
        let b = self.extract(1);
        let result = a * a + b * b;
        f64x2::new(result, 0.0)
    }

    #[inline]
    fn complex_abs(self) -> f64x2
    {
        let a = self.extract(0);
        let b = self.extract(1);
        let result = (a * a + b * b).sqrt();
        f64x2::new(result, 0.0)
    }
    #[inline]

    fn complex_abs_squared2(self) -> f64x2
    {
        self.complex_abs_squared()
    }

    #[inline]
    fn complex_abs2(self) -> f64x2
    {
        self.complex_abs()
    }

    #[inline]
    fn sqrt(self) -> f64x2 {
        f64x2::new(self.extract(0).sqrt(), self.extract(1).sqrt())
    }

    #[inline]
    fn store_half_unchecked(self, target: &mut [f64], index: usize)
    {
        unsafe {
            *target.get_unchecked_mut(index) = self.extract(0);
        }
    }

    #[inline]
    fn sum_real(&self) -> f64 {
        self.extract(0) +
        self.extract(1)
    }

    #[inline]
    fn sum_complex(&self) -> Complex<f64> {
        Complex::<f64>::new(self.extract(0), self.extract(1))
    }
} <|endoftext|>


<commit_before>pub trait EventHandler<T: Event> {
    fn handle_event(&mut self, event: T);
    fn handler(&self) -> T::Handler;
}

pub trait EventDemultiplexer {
    type Event;
    fn select(&mut self) -> Option<Self::Event>;
}

pub trait Reactor {
    type Event: Event;
    type Handler;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event>>);
    fn remove_handler_by_handler(&mut self, handler: &Self::Handler);
}

pub trait Event {
    type Handler;
    fn handler(&self) -> Self::Handler;
}
<commit_msg>EventDemultiplexer: add Event bound to the associated type<commit_after>pub trait EventHandler<T: Event> {
    fn handle_event(&mut self, event: T);
    fn handler(&self) -> T::Handler;
}

pub trait EventDemultiplexer {
    type Event: Event;
    fn select(&mut self) -> Option<Self::Event>;
}

pub trait Reactor {
    type Event: Event;
    type Handler;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event>>);
    fn remove_handler_by_handler(&mut self, handler: &Self::Handler);
}

pub trait Event {
    type Handler;
    fn handler(&self) -> Self::Handler;
}
<|endoftext|>


<commit_before>use core::ptr;

pub struct UnsafeList<T> {
    head: Link<Node<T>>,
}

impl<T> UnsafeList<T> {
    pub unsafe fn new() -> Self {
        UnsafeList {
            head: Link::none(),
        }
    }

    pub unsafe fn push_front(&mut self, mut elem: Link<Node<T>>) {
        match self.head.as_mut() {
            None => {
                if let Some(ref mut node) = elem.as_mut() {
                    node.prev = Link::none();
                    node.next = Link::none();
                }
            },
            Some(ref mut node) => {
                if let Some(ref mut elem_node) = elem.as_mut() {
                    node.prev = elem.clone();

                    elem_node.next = self.head.clone();
                    elem_node.prev = Link::none();
                }
            }
        }

        self.head = elem;
    }

    pub unsafe fn pop(&mut self, mut elem: Link<Node<T>>) {
        if let Some(node) = elem.as_mut() {
            if let Some(prev) = node.prev.as_mut() {
                prev.next = node.next.clone();
            }

            if let Some(next) = node.next.as_mut() {
                next.prev = node.prev.clone();
            }
        } else {
            return;
        }

        if elem == self.head {
            if let Some(head) = self.head.as_mut() {
                self.head = head.next.clone();
            } else {
                self.head = Link::none();
            }
        }
    }

    pub unsafe fn cursor<'a>(&'a mut self) -> UnsafeCursor<'a, T> {
        let head_dup = self.head.clone();

        UnsafeCursor {
            head: &mut self.head,
            current: head_dup,
        }
    }
}

pub struct UnsafeCursor<'a, T: 'a> {
    head: &'a mut Link<Node<T>>,
    current: Link<Node<T>>,
}

impl<'a, T: 'a> UnsafeCursor<'a, T> {
    pub unsafe fn remove(&mut self) -> Link<Node<T>> {
        if self.current.is_null() {
            return Link::none();
        }

        let mut res = self.current.clone();
        let update_head = *self.head == self.current;

        self.next();

        if let Some(node) = res.as_mut() {
            if let Some(prev) = node.prev.as_mut() {
                prev.next = node.next.clone();
            }

            if let Some(next) = node.next.as_mut() {
                next.prev = node.prev.clone();
            }

            node.next = Link::none();
            node.prev = Link::none();
        }

        if update_head {
            *self.head = self.current.clone();
        }

        res
    }

    pub unsafe fn next(&mut self) {
        if let Some(node) = self.current.as_mut() {
            self.current = node.next.clone();
        }
    }

    pub unsafe fn as_ref(&self) -> Option<&Node<T>> {
        self.current.as_ref()
    }
}

pub struct Node<T> {
    pub elem: T,
    pub prev: Link<Node<T>>,
    pub next: Link<Node<T>>,
}

impl<T> Node<T> {
    pub fn new(elem: T) -> Self {
        Node {
            elem: elem,
            prev: Link::none(),
            next: Link::none(),
        }
    }
}

pub struct Link<T> {
    ptr: *mut T,
}

impl<T> Link<T> {
    pub fn some(ptr: *mut T) -> Self {
        Link {
            ptr: ptr,
        }
    }

    pub fn none() -> Self {
        Link {
            ptr: ptr::null_mut(),
        }
    }

    pub fn is_null(&self) -> bool {
        self.ptr == ptr::null_mut()
    }

    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        self.ptr.as_ref()
    }

    pub unsafe fn as_mut<'a>(&mut self) -> Option<&'a mut T> {
        self.ptr.as_mut()
    }
}

impl<T> Clone for Link<T> {
    fn clone(&self) -> Self {
        Link {
            ptr: self.ptr,
        }
    }
}

impl<T> PartialEq<Link<T>> for Link<T> {
    fn eq(&self, rhs: &Link<T>) -> bool {
        self.ptr == rhs.ptr
    }
}
<commit_msg>heap: Add type UnsafeList<T><commit_after>use core::ptr;

pub struct UnsafeList<T> {
    head: Link<Node<T>>,
}

impl<T> UnsafeList<T> {
    pub unsafe fn new() -> Self {
        UnsafeList {
            head: Link::none(),
        }
    }

    pub unsafe fn push_front(&mut self, mut elem: Link<Node<T>>) {
        match self.head.as_mut() {
            None => {
                if let Some(ref mut node) = elem.as_mut() {
                    node.prev = Link::none();
                    node.next = Link::none();
                }
            },
            Some(ref mut node) => {
                if let Some(ref mut elem_node) = elem.as_mut() {
                    node.prev = elem.clone();

                    elem_node.next = self.head.clone();
                    elem_node.prev = Link::none();
                }
            }
        }

        self.head = elem;
    }

    pub unsafe fn pop(&mut self, mut elem: Link<Node<T>>) {
        if let Some(node) = elem.as_mut() {
            if let Some(prev) = node.prev.as_mut() {
                prev.next = node.next.clone();
            }

            if let Some(next) = node.next.as_mut() {
                next.prev = node.prev.clone();
            }
        } else {
            return;
        }

        if elem == self.head {
            if let Some(head) = self.head.as_mut() {
                self.head = head.next.clone();
            } else {
                self.head = Link::none();
            }
        }
    }
}

pub struct Node<T> {
    pub elem: T,
    pub prev: Link<Node<T>>,
    pub next: Link<Node<T>>,
}

impl<T> Node<T> {
    pub fn new(elem: T) -> Self {
        Node {
            elem: elem,
            prev: Link::none(),
            next: Link::none(),
        }
    }
}

pub struct Link<T> {
    ptr: *mut T,
}

impl<T> Link<T> {
    pub fn some(ptr: *mut T) -> Self {
        Link {
            ptr: ptr,
        }
    }

    pub fn none() -> Self {
        Link {
            ptr: ptr::null_mut(),
        }
    }

    pub fn is_null(&self) -> bool {
        self.ptr == ptr::null_mut()
    }

    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        self.ptr.as_ref()
    }

    pub unsafe fn as_mut<'a>(&mut self) -> Option<&'a mut T> {
        self.ptr.as_mut()
    }
}

impl<T> Clone for Link<T> {
    fn clone(&self) -> Self {
        Link {
            ptr: self.ptr,
        }
    }
}

impl<T> PartialEq<Link<T>> for Link<T> {
    fn eq(&self, rhs: &Link<T>) -> bool {
        self.ptr == rhs.ptr
    }
}
<|endoftext|>


<commit_before>use ring::{digest, hmac};
use hyper::method::Method;
use hyper::Url;
use std::io;
use std::io::Write;
use super::scheme::Scheme;
use time;
use rustc_serialize::base64;
use rustc_serialize::base64::ToBase64;

// import the digest algorithms here
pub use ring::digest::{SHA1, SHA256, SHA384, SHA512};

pub struct Credentials {
    pub id: Vec<u8>,
    pub key: hmac::SigningKey,
}

impl Credentials {
    pub fn new<B>(id: B, key: B, algorithm: &'static digest::Algorithm) -> Credentials
        where B: Into<Vec<u8>>
    {
        let key = key.into();
        let key = hmac::SigningKey::new(algorithm, key.as_ref());
        Credentials {
            id: id.into(),
            key: key.into(),
        }
    }
}

pub struct Request<'a> {
    url: Url,
    method: Method,
    credentials: &'a Credentials,
    ext: Option<String>,
    hash: Option<Vec<u8>>,
    app: Option<String>,
    dlg: Option<String>,
}

impl<'a> Request<'a> {
    /// Create a new Request with the given details.
    pub fn new(url: Url,
               method: Method,
               credentials: &'a Credentials,
               ext: Option<String>,
               hash: Option<Vec<u8>>,
               app: Option<String>,
               dlg: Option<String>)
               -> Request {
        Request {
            url: url,
            method: method,
            credentials: credentials,
            ext: ext,
            hash: hash,
            app: app,
            dlg: dlg,
        }
    }

    fn make_request_mac(&self,
                        ts: time::Timespec,
                        nonce: &String,
                        path: &str,
                        host: &str,
                        port: u16)
                        -> Result<Vec<u8>, io::Error> {
        let mut buffer: Vec<u8> = vec![];
        try!(write!(buffer, "hawk.1.header\n"));
        try!(write!(buffer, "{}\n", ts.sec));
        try!(write!(buffer, "{}\n", nonce));
        try!(write!(buffer, "{}\n", self.method));
        try!(write!(buffer, "{}\n", path));
        try!(write!(buffer, "{}\n", host));
        try!(write!(buffer, "{}\n", port));
        try!(write!(buffer,
                    "{}\n",
                    match self.hash {
                        Some(ref h) => {
                            h.to_base64(base64::Config {
                                char_set: base64::CharacterSet::Standard,
                                newline: base64::Newline::LF,
                                pad: true,
                                line_length: None,
                            })
                        }
                        None => "".to_string(),
                    }));
        try!(write!(buffer,
                    "{}\n",
                    match self.ext {
                        Some(ref e) => e,
                        None => "",
                    }));

        println!("{:?}", String::from_utf8(buffer.clone()).unwrap());

        let digest = hmac::sign(&self.credentials.key, buffer.as_ref());

        // TODO: store the mac in the header as a Digest
        let mut mac = vec![0; self.credentials.key.digest_algorithm().output_len];
        mac.clone_from_slice(digest.as_ref());
        return Ok(mac);
    }

    pub fn hyper_scheme(&self) -> Result<Scheme, String> {
        let id = "id".to_string(); // TODO: random (extern crate rand); move to Request
        let ts = time::now_utc().to_timespec();
        let nonce = "nonce".to_string(); // TODO: random
        let path = self.url.path();
        let host = match self.url.host_str() {
            Some(h) => h,
            None => {
                return Err(format!("url {} has no host", self.url));
            }
        };
        let port = match self.url.port() {
            Some(p) => p,
            None => {
                return Err(format!("url {} has no port", self.url));
            }
        };

        let mac = match self.make_request_mac(ts, &nonce, path, host, port) {
            Ok(mac) => mac,
            Err(ioerr) => {
                return Err(ioerr.to_string());
            }
        };
        return Ok(Scheme::new_extended(id,
                                       ts,
                                       nonce,
                                       mac,
                                       self.ext.clone(),
                                       self.hash.clone(),
                                       self.app.clone(),
                                       self.dlg.clone()));
    }
}
<commit_msg>request uses references<commit_after>use ring::{digest, hmac};
use hyper::method::Method;
use hyper::Url;
use std::io;
use std::io::Write;
use super::scheme::Scheme;
use time;
use rustc_serialize::base64;
use rustc_serialize::base64::ToBase64;

// import the digest algorithms here
pub use ring::digest::{SHA1, SHA256, SHA384, SHA512};

pub struct Credentials {
    pub id: Vec<u8>,
    pub key: hmac::SigningKey,
}

impl Credentials {
    pub fn new<B>(id: B, key: B, algorithm: &'static digest::Algorithm) -> Credentials
        where B: Into<Vec<u8>>
    {
        let key = key.into();
        let key = hmac::SigningKey::new(algorithm, key.as_ref());
        Credentials {
            id: id.into(),
            key: key.into(),
        }
    }
}

pub struct Request<'a> {
    url: Url,
    method: Method,
    credentials: &'a Credentials,
    ext: Option<&'a String>,
    hash: Option<&'a Vec<u8>>,
    app: Option<&'a String>,
    dlg: Option<&'a String>,
}

impl<'a> Request<'a> {
    /// Create a new Request with the given details.
    pub fn new(url: Url,
               method: Method,
               credentials: &'a Credentials,
               ext: Option<&'a String>,
               hash: Option<&'a Vec<u8>>,
               app: Option<&'a String>,
               dlg: Option<&'a String>)
               -> Request<'a> {
        Request {
            url: url,
            method: method,
            credentials: credentials,
            ext: ext,
            hash: hash,
            app: app,
            dlg: dlg,
        }
    }

    fn make_request_mac(&self,
                        ts: time::Timespec,
                        nonce: &String,
                        path: &str,
                        host: &str,
                        port: u16)
                        -> Result<Vec<u8>, io::Error> {
        let mut buffer: Vec<u8> = vec![];
        try!(write!(buffer, "hawk.1.header\n"));
        try!(write!(buffer, "{}\n", ts.sec));
        try!(write!(buffer, "{}\n", nonce));
        try!(write!(buffer, "{}\n", self.method));
        try!(write!(buffer, "{}\n", path));
        try!(write!(buffer, "{}\n", host));
        try!(write!(buffer, "{}\n", port));
        if let Some(ref h) = self.hash {
            try!(write!(buffer,
                        "{}\n",
                        h.to_base64(base64::Config {
                            char_set: base64::CharacterSet::Standard,
                            newline: base64::Newline::LF,
                            pad: true,
                            line_length: None,
                        })));
        } else {
            try!(write!(buffer, "\n"));
        }
        if let Some(ref e) = self.ext {
            try!(write!(buffer, "{}\n", e));
        } else {
            try!(write!(buffer, "\n"));
        }

        println!("{:?}", String::from_utf8(buffer.clone()).unwrap());

        let digest = hmac::sign(&self.credentials.key, buffer.as_ref());

        // TODO: store the mac in the header as a Digest
        let mut mac = vec![0; self.credentials.key.digest_algorithm().output_len];
        mac.clone_from_slice(digest.as_ref());
        return Ok(mac);
    }

    pub fn hyper_scheme(&self) -> Result<Scheme, String> {
        let id = "id".to_string(); // TODO: random (extern crate rand); move to Request
        let ts = time::now_utc().to_timespec();
        let nonce = "nonce".to_string(); // TODO: random
        let path = self.url.path();
        let host = match self.url.host_str() {
            Some(h) => h,
            None => {
                return Err(format!("url {} has no host", self.url));
            }
        };
        let port = match self.url.port() {
            Some(p) => p,
            None => {
                return Err(format!("url {} has no port", self.url));
            }
        };

        let mac = match self.make_request_mac(ts, &nonce, path, host, port) {
            Ok(mac) => mac,
            Err(ioerr) => {
                return Err(ioerr.to_string());
            }
        };

        let ext = match self.ext {
            Some(ext) => Some(ext.clone()),
            None => None,
        };

        let hash = match self.hash {
            Some(hash) => Some(hash.clone()),
            None => None,
        };

        let app = match self.app {
            Some(app) => Some(app.clone()),
            None => None,
        };

        let dlg = match self.dlg {
            Some(dlg) => Some(dlg.clone()),
            None => None,
        };

        return Ok(Scheme::new_extended(id, ts, nonce, mac, ext, hash, app, dlg));
    }
}
<|endoftext|>


<commit_before><commit_msg>Increase id also for invalid records.<commit_after><|endoftext|>


<commit_before>#![unstable(feature = "unicode_internals", issue = "none")]
#![allow(missing_docs)]

mod bool_trie;
pub(crate) mod printable;
pub(crate) mod tables;
pub(crate) mod version;

// For use in liballoc, not re-exported in libstd.
pub mod derived_property {
    pub use crate::unicode::tables::derived_property::{Case_Ignorable, Cased};
}
pub mod conversions {
    pub use crate::unicode::tables::conversions::{to_lower, to_upper};
}
<commit_msg>Add support code for new unicode_data module<commit_after>#![unstable(feature = "unicode_internals", issue = "none")]
#![allow(missing_docs)]

pub(crate) mod printable;
mod unicode_data;
pub(crate) mod version;

use version::UnicodeVersion;

/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
/// `char` and `str` methods are based on.
#[unstable(feature = "unicode_version", issue = "49726")]
pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
    major: unicode_data::UNICODE_VERSION.0,
    minor: unicode_data::UNICODE_VERSION.1,
    micro: unicode_data::UNICODE_VERSION.2,
    _priv: (),
};

// For use in liballoc, not re-exported in libstd.
pub mod derived_property {
    pub use super::{Case_Ignorable, Cased};
}

pub use unicode_data::alphabetic::lookup as Alphabetic;
pub use unicode_data::case_ignorable::lookup as Case_Ignorable;
pub use unicode_data::cased::lookup as Cased;
pub use unicode_data::cc::lookup as Cc;
pub use unicode_data::conversions;
pub use unicode_data::grapheme_extend::lookup as Grapheme_Extend;
pub use unicode_data::lowercase::lookup as Lowercase;
pub use unicode_data::n::lookup as N;
pub use unicode_data::uppercase::lookup as Uppercase;
pub use unicode_data::white_space::lookup as White_Space;

#[inline(always)]
fn range_search<const N: usize, const N1: usize, const N2: usize>(
    needle: u32,
    chunk_idx_map: &[u8; N],
    (last_chunk_idx, last_chunk_mapping): (u16, u8),
    bitset_chunk_idx: &[[u8; 16]; N1],
    bitset: &[u64; N2],
) -> bool {
    let bucket_idx = (needle / 64) as usize;
    let chunk_map_idx = bucket_idx / 16;
    let chunk_piece = bucket_idx % 16;
    let chunk_idx = if chunk_map_idx >= N {
        if chunk_map_idx == last_chunk_idx as usize {
            last_chunk_mapping
        } else {
            return false;
        }
    } else {
        chunk_idx_map[chunk_map_idx]
    };
    let idx = bitset_chunk_idx[(chunk_idx as usize)][chunk_piece];
    let word = bitset[(idx as usize)];
    (word & (1 << (needle % 64) as u64)) != 0
}
<|endoftext|>