<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error::Error;
use std::iter;
use std::sync::Arc;

use buffer::TrackedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::DynamicState;
use command_buffer::pool::CommandPool;
use command_buffer::StatesManager;
use command_buffer::SubmitInfo;
use command_buffer::SubmitBuilder;
use command_buffer::Submit;
use command_buffer::sys::PipelineBarrierBuilder;
use command_buffer::sys::UnsafeCommandBufferBuilder;
use descriptor::PipelineLayoutRef;
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
use device::Device;
use device::Queue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use image::Layout;
use image::TrackedImage;
use instance::QueueFamily;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
use pipeline::vertex::Source;
use sync::Fence;
use vk;

pub use self::begin_render_pass::CmdBeginRenderPass;
pub use self::bind_index_buffer::CmdBindIndexBuffer;
pub use self::bind_descriptor_sets::{CmdBindDescriptorSets, CmdBindDescriptorSetsError};
pub use self::bind_pipeline::CmdBindPipeline;
pub use self::bind_vertex_buffers::CmdBindVertexBuffers;
pub use self::blit_image_unsynced::{BlitRegion, BlitRegionAspect};
pub use self::blit_image_unsynced::{CmdBlitImageUnsynced, CmdBlitImageUnsyncedError};
pub use self::copy_buffer::{CmdCopyBuffer, CmdCopyBufferError};
pub use self::dispatch::CmdDispatch;
pub use self::draw::CmdDraw;
pub use self::empty::{empty, EmptyCommandsList};
pub use self::end_render_pass::CmdEndRenderPass;
pub use self::fill_buffer::{CmdFillBuffer, CmdFillBufferError};
pub use self::next_subpass::CmdNextSubpass;
pub use self::push_constants::{CmdPushConstants, CmdPushConstantsError};
pub use self::set_state::{CmdSetState};
pub use self::update_buffer::{CmdUpdateBuffer, CmdUpdateBufferError};

mod begin_render_pass;
mod bind_descriptor_sets;
mod bind_index_buffer;
mod bind_pipeline;
mod bind_vertex_buffers;
mod blit_image_unsynced;
mod copy_buffer;
mod dispatch;
mod draw;
mod empty;
mod end_render_pass;
//pub mod execute;      // TODO: reenable when the concept of a command buffer is well defined
mod fill_buffer;
mod next_subpass;
mod push_constants;
mod set_state;
mod update_buffer;

/// A list of commands that can be turned into a command buffer.
///
/// This is just a naked list of commands. It stores buffers, images, etc. but the list of commands
/// itself is not a Vulkan object.
pub unsafe trait CommandsList {
    /// Adds a command that writes the content of a buffer.
    ///
    /// After this command is executed, the content of `buffer` will become `data`.
    #[inline]
    fn update_buffer<'a, B, D: ?Sized>(self, buffer: B, data: &'a D)
                                       -> Result<CmdUpdateBuffer<'a, Self, B, D>, CmdUpdateBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer, D: Copy + 'static
    {
        CmdUpdateBuffer::new(self, buffer, data)
    }

    /// Adds a command that copies the content of a buffer to another.
    #[inline]
    fn copy_buffer<S, D>(self, source: S, destination: D)
                         -> Result<CmdCopyBuffer<Self, S, D>, CmdCopyBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass,
              S: TrackedBuffer, D: TrackedBuffer
    {
        CmdCopyBuffer::new(self, source, destination)
    }

    /// Adds a command that writes the content of a buffer.
    #[inline]
    fn fill_buffer<B>(self, buffer: B, data: u32)
                      -> Result<CmdFillBuffer<Self, B>, CmdFillBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer
    {
        CmdFillBuffer::new(self, buffer, data)
    }

    // TODO: reenable
    /*/// Adds a command that executes a secondary command buffer.
    ///
    /// When you create a command buffer, you have the possibility to create either a primary
    /// command buffer or a secondary command buffer. Secondary command buffers can't be executed
    /// directly, but can be executed from a primary command buffer.
    ///
    /// A secondary command buffer can't execute another secondary command buffer. The only way
    /// you can use `execute` is to make a primary command buffer call a secondary command buffer.
    #[inline]
    fn execute<Cb>(self, command_buffer: Cb) -> execute::ExecuteCommand<Cb, Self>
        where Self: Sized, Cb: CommandsListOutput       /* FIXME: */
    {
        execute::ExecuteCommand::new(self, command_buffer)
    }*/

    /// Adds a command that executes a compute shader.
    ///
    /// The `dimensions` are the number of working groups to start. The GPU will execute the
    /// compute shader `dimensions[0] * dimensions[1] * dimensions[2]` times.
    ///
    /// The `pipeline` is the compute pipeline that will be executed, and the sets and push
    /// constants will be accessible to all the invocations.
    #[inline]
    fn dispatch<Pl, S, Pc>(self, pipeline: Arc<ComputePipeline<Pl>>, sets: S,
                           dimensions: [u32; 3], push_constants: Pc)
                           -> CmdDispatch<Self, Pl, S, Pc>
        where Self: Sized + CommandsList, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection
    {
        CmdDispatch::new(self, pipeline, sets, dimensions, push_constants)
    }

    /// Adds a command that starts a render pass.
    ///
    /// If `secondary` is true, then you will only be able to add secondary command buffers while
    /// you're inside the first subpass on the render pass. If `secondary` is false, you will only
    /// be able to add inline draw commands and not secondary command buffers.
    ///
    /// You must call this before you can add draw commands.
    #[inline]
    fn begin_render_pass<F, C>(self, framebuffer: F, secondary: bool, clear_values: C)
                               -> CmdBeginRenderPass<Self, F::RenderPass, F>
        where Self: Sized, F: TrackedFramebuffer,
              F::RenderPass: RenderPass + RenderPassClearValues<C>
    {
        CmdBeginRenderPass::new(self, framebuffer, secondary, clear_values)
    }

    /// Adds a command that jumps to the next subpass of the current render pass.
    #[inline]
    fn next_subpass(self, secondary: bool) -> CmdNextSubpass<Self>
        where Self: Sized
    {
        CmdNextSubpass::new(self, secondary)
    }

    /// Adds a command that ends the current render pass.
    ///
    /// This must be called after you went through all the subpasses and before you can build
    /// the command buffer or add further commands.
    #[inline]
    fn end_render_pass(self) -> CmdEndRenderPass<Self>
        where Self: Sized
    {
        CmdEndRenderPass::new(self)
    }

    /// Adds a command that draws.
    ///
    /// Can only be used from inside a render pass.
    #[inline]
    fn draw<Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
                                   dynamic: DynamicState, vertices: V, sets: S,
                                   push_constants: Pc)
                                   -> CmdDraw<Self, V, Pv, Pl, Prp, S, Pc>
        where Self: Sized + CommandsList + CommandsListPossibleInsideRenderPass, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection, Pv: Source<V>
    {
        CmdDraw::new(self, pipeline, dynamic, vertices, sets, push_constants)
    }

    /// Appends this list of commands at the end of a command buffer in construction.
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>);
}

unsafe impl CommandsList for Box<CommandsList> {
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        (**self).append(builder)
    }
}

/// Output of the "append" method. The lifetime corresponds to the CommandsList.
pub trait CommandsListSink<'a> {
    fn device(&self) -> &Arc<Device>;

    /// Note that the lifetime means that we hold a reference to the content of
    /// the commands list in that closure.
    fn add_command(&mut self, Box<CommandsListSinkCaller<'a> + 'a>);

    fn add_buffer_transition(&mut self, buffer: &TrackedBuffer, offset: usize, size: usize,
                             write: bool);

    ///
    ///
    /// If necessary, you must transition the image to the `layout`.
    fn add_image_transition(&mut self, image: &TrackedImage, first_layer: u32, num_layers: u32,
                            first_mipmap: u32, num_mipmaps: u32, layout: Layout);

    fn add_image_transition_notification(&mut self, image: &TrackedImage, first_layer: u32,
                                         num_layers: u32, first_mipmap: u32, num_mipmaps: u32,
                                         layout: Layout);
}

pub trait CommandsListSinkCaller<'a> {
    fn call(self: Box<Self>, &mut RawCommandBufferPrototype<'a>);
}
impl<'a, T> CommandsListSinkCaller<'a> for T where T: FnOnce(&mut RawCommandBufferPrototype<'a>) -> () + 'a {
    fn call(self: Box<Self>, proto: &mut RawCommandBufferPrototype<'a>) {
        self(proto);
    }
}

/// Extension trait for both `CommandsList` and `CommandsListOutput` that indicates that we're
/// possibly outside a render pass.
///
/// In other words, if this trait is *not* implemented then we're guaranteed *not* to be outside
/// of a render pass. If it is implemented, then we maybe are but that's not sure.
pub unsafe trait CommandsListPossibleOutsideRenderPass {
    /// Returns `true` if we're outside a render pass.
    fn is_outside_render_pass(&self) -> bool;
}

/// Extension trait for both `CommandsList` and `CommandsListOutput` that indicates that we're
/// possibly inside a render pass.
///
/// In other words, if this trait is *not* implemented then we're guaranteed *not* to be inside
/// a render pass. If it is implemented, then we maybe are but that's not sure.
// TODO: make all return values optional, since we're possibly not in a render pass
pub unsafe trait CommandsListPossibleInsideRenderPass {
    type RenderPass: RenderPass;

    /// Returns the number of the subpass we're in. The value is 0-indexed, so immediately after
    /// calling `begin_render_pass` the value will be `0`.
    ///
    /// The value should always be strictly inferior to the number of subpasses in the render pass.
    fn current_subpass_num(&self) -> u32;

    /// If true, only secondary command buffers can be added inside the subpass. If false, only
    /// inline draw commands can be added.
    fn secondary_subpass(&self) -> bool;

    /// Returns the description of the render pass we're in.
    // TODO: return a trait object instead?
    fn render_pass(&self) -> &Self::RenderPass;

    //fn current_subpass(&self) -> Subpass<&Self::RenderPass>;
}

#[deprecated]
pub unsafe trait CommandsListOutput<S = StatesManager> {
    /// Returns the inner object.
    // TODO: crappy API
    #[deprecated]
    fn inner(&self) -> vk::CommandBuffer;

    /// Returns the device this object belongs to.
    #[deprecated]
    fn device(&self) -> &Arc<Device>;

    #[deprecated]
    unsafe fn on_submit(&self, states: &S, queue: &Arc<Queue>,
                        fence: &mut FnMut() -> Arc<Fence>) -> SubmitInfo;
}

#[deprecated]
pub struct CommandBuffer<C = Box<CommandsListOutput>> {
    states: StatesManager,
    commands: C,
}

unsafe impl<C> Submit for CommandBuffer<C> where C: CommandsListOutput {
    #[inline]
    fn device(&self) -> &Arc<Device> {
        self.commands.device()
    }

    #[inline]
    unsafe fn append_submission<'a>(&'a self, mut base: SubmitBuilder<'a>, queue: &Arc<Queue>)
                                    -> Result<SubmitBuilder<'a>, Box<Error>>
    {
        let mut fence = None;
        let infos = self.commands.on_submit(&self.states, queue, &mut || {
            match &mut fence {
                f @ &mut None => {
                    let fe = Fence::new(self.device().clone()); *f = Some(fe.clone()); fe
                },
                &mut Some(ref f) => f.clone()
            }
        });

        for (sem_wait, sem_stage) in infos.semaphores_wait {
            base = base.add_wait_semaphore(sem_wait, sem_stage);
        }

        if !infos.pre_pipeline_barrier.is_empty() {
            unimplemented!()
        }

        base = base.add_command_buffer_raw(self.commands.inner());

        if !infos.post_pipeline_barrier.is_empty() {
            unimplemented!()
        }

        for sem_signal in infos.semaphores_signal {
            base = base.add_signal_semaphore(sem_signal);
        }

        if let Some(fence) = fence {
            base = base.add_fence_signal(fence);
        }

        Ok(base)
    }
}
<commit_msg>Some comments for buffer copy commands<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error::Error;
use std::iter;
use std::sync::Arc;

use buffer::TrackedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::DynamicState;
use command_buffer::pool::CommandPool;
use command_buffer::StatesManager;
use command_buffer::SubmitInfo;
use command_buffer::SubmitBuilder;
use command_buffer::Submit;
use command_buffer::sys::PipelineBarrierBuilder;
use command_buffer::sys::UnsafeCommandBufferBuilder;
use descriptor::PipelineLayoutRef;
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
use device::Device;
use device::Queue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use image::Layout;
use image::TrackedImage;
use instance::QueueFamily;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
use pipeline::vertex::Source;
use sync::Fence;
use vk;

pub use self::begin_render_pass::CmdBeginRenderPass;
pub use self::bind_index_buffer::CmdBindIndexBuffer;
pub use self::bind_descriptor_sets::{CmdBindDescriptorSets, CmdBindDescriptorSetsError};
pub use self::bind_pipeline::CmdBindPipeline;
pub use self::bind_vertex_buffers::CmdBindVertexBuffers;
pub use self::blit_image_unsynced::{BlitRegion, BlitRegionAspect};
pub use self::blit_image_unsynced::{CmdBlitImageUnsynced, CmdBlitImageUnsyncedError};
pub use self::copy_buffer::{CmdCopyBuffer, CmdCopyBufferError};
pub use self::dispatch::CmdDispatch;
pub use self::draw::CmdDraw;
pub use self::empty::{empty, EmptyCommandsList};
pub use self::end_render_pass::CmdEndRenderPass;
pub use self::fill_buffer::{CmdFillBuffer, CmdFillBufferError};
pub use self::next_subpass::CmdNextSubpass;
pub use self::push_constants::{CmdPushConstants, CmdPushConstantsError};
pub use self::set_state::{CmdSetState};
pub use self::update_buffer::{CmdUpdateBuffer, CmdUpdateBufferError};

mod begin_render_pass;
mod bind_descriptor_sets;
mod bind_index_buffer;
mod bind_pipeline;
mod bind_vertex_buffers;
mod blit_image_unsynced;
mod copy_buffer;
mod dispatch;
mod draw;
mod empty;
mod end_render_pass;
//pub mod execute;      // TODO: reenable when the concept of a command buffer is well defined
mod fill_buffer;
mod next_subpass;
mod push_constants;
mod set_state;
mod update_buffer;

/// A list of commands that can be turned into a command buffer.
///
/// This is just a naked list of commands. It stores buffers, images, etc. but the list of commands
/// itself is not a Vulkan object.
pub unsafe trait CommandsList {
    /// Adds a command that writes the content of a buffer.
    ///
    /// After this command is executed, the content of `buffer` will become `data`. If `data` is
    /// smaller than `buffer`, then only the beginning of `buffer` will be modified and the rest
    /// will be left untouched. If `buffer` is smaller than `data`, `buffer` will be entirely
    /// written and no error is generated.
    ///
    /// This command is limited to 64kB (65536 bytes) of data and should only be used for small
    /// amounts of data. For large amounts of data, you are encouraged to write the data to a
    /// buffer and use `copy_buffer` instead.
    #[inline]
    fn update_buffer<'a, B, D: ?Sized>(self, buffer: B, data: &'a D)
                                       -> Result<CmdUpdateBuffer<'a, Self, B, D>, CmdUpdateBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer, D: Copy + 'static
    {
        CmdUpdateBuffer::new(self, buffer, data)
    }

    /// Adds a command that copies the content of a buffer to another.
    ///
    /// If `source` is smaller than `destination`, only the beginning of `destination` will be
    /// modified.
    #[inline]
    fn copy_buffer<S, D>(self, source: S, destination: D)
                         -> Result<CmdCopyBuffer<Self, S, D>, CmdCopyBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass,
              S: TrackedBuffer, D: TrackedBuffer
    {
        CmdCopyBuffer::new(self, source, destination)
    }

    /// Adds a command that writes the content of a buffer.
    ///
    /// This function is similar to the `memset` function in C. The `data` parameter is a number
    /// that will be repeatidely written through the entire buffer.
    ///
    /// > **Note**: This function is technically safe because buffers can only contain integers or
    /// > floating point numbers, which are always valid whatever their memory representation is.
    /// > But unless your buffer actually contains only 32-bits integers, you are encouraged to use
    /// > this function only for zeroing the content of a buffer by passing `0` for the data.
    #[inline]
    fn fill_buffer<B>(self, buffer: B, data: u32)
                      -> Result<CmdFillBuffer<Self, B>, CmdFillBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer
    {
        CmdFillBuffer::new(self, buffer, data)
    }

    // TODO: reenable
    /*/// Adds a command that executes a secondary command buffer.
    ///
    /// When you create a command buffer, you have the possibility to create either a primary
    /// command buffer or a secondary command buffer. Secondary command buffers can't be executed
    /// directly, but can be executed from a primary command buffer.
    ///
    /// A secondary command buffer can't execute another secondary command buffer. The only way
    /// you can use `execute` is to make a primary command buffer call a secondary command buffer.
    #[inline]
    fn execute<Cb>(self, command_buffer: Cb) -> execute::ExecuteCommand<Cb, Self>
        where Self: Sized, Cb: CommandsListOutput       /* FIXME: */
    {
        execute::ExecuteCommand::new(self, command_buffer)
    }*/

    /// Adds a command that executes a compute shader.
    ///
    /// The `dimensions` are the number of working groups to start. The GPU will execute the
    /// compute shader `dimensions[0] * dimensions[1] * dimensions[2]` times.
    ///
    /// The `pipeline` is the compute pipeline that will be executed, and the sets and push
    /// constants will be accessible to all the invocations.
    #[inline]
    fn dispatch<Pl, S, Pc>(self, pipeline: Arc<ComputePipeline<Pl>>, sets: S,
                           dimensions: [u32; 3], push_constants: Pc)
                           -> CmdDispatch<Self, Pl, S, Pc>
        where Self: Sized + CommandsList, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection
    {
        CmdDispatch::new(self, pipeline, sets, dimensions, push_constants)
    }

    /// Adds a command that starts a render pass.
    ///
    /// If `secondary` is true, then you will only be able to add secondary command buffers while
    /// you're inside the first subpass on the render pass. If `secondary` is false, you will only
    /// be able to add inline draw commands and not secondary command buffers.
    ///
    /// You must call this before you can add draw commands.
    #[inline]
    fn begin_render_pass<F, C>(self, framebuffer: F, secondary: bool, clear_values: C)
                               -> CmdBeginRenderPass<Self, F::RenderPass, F>
        where Self: Sized, F: TrackedFramebuffer,
              F::RenderPass: RenderPass + RenderPassClearValues<C>
    {
        CmdBeginRenderPass::new(self, framebuffer, secondary, clear_values)
    }

    /// Adds a command that jumps to the next subpass of the current render pass.
    #[inline]
    fn next_subpass(self, secondary: bool) -> CmdNextSubpass<Self>
        where Self: Sized
    {
        CmdNextSubpass::new(self, secondary)
    }

    /// Adds a command that ends the current render pass.
    ///
    /// This must be called after you went through all the subpasses and before you can build
    /// the command buffer or add further commands.
    #[inline]
    fn end_render_pass(self) -> CmdEndRenderPass<Self>
        where Self: Sized
    {
        CmdEndRenderPass::new(self)
    }

    /// Adds a command that draws.
    ///
    /// Can only be used from inside a render pass.
    #[inline]
    fn draw<Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
                                   dynamic: DynamicState, vertices: V, sets: S,
                                   push_constants: Pc)
                                   -> CmdDraw<Self, V, Pv, Pl, Prp, S, Pc>
        where Self: Sized + CommandsList + CommandsListPossibleInsideRenderPass,
              Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection,
              Pv: Source<V>
    {
        CmdDraw::new(self, pipeline, dynamic, vertices, sets, push_constants)
    }

    /// Appends this list of commands at the end of a command buffer in construction.
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>);
}

unsafe impl CommandsList for Box<CommandsList> {
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        (**self).append(builder)
    }
}

/// Output of the "append" method. The lifetime corresponds to the CommandsList.
pub trait CommandsListSink<'a> {
    fn device(&self) -> &Arc<Device>;

    /// Note that the lifetime means that we hold a reference to the content of
    /// the commands list in that closure.
    fn add_command(&mut self, Box<CommandsListSinkCaller<'a> + 'a>);

    fn add_buffer_transition(&mut self, buffer: &TrackedBuffer, offset: usize, size: usize,
                             write: bool);

    ///
    ///
    /// If necessary, you must transition the image to the `layout`.
    fn add_image_transition(&mut self, image: &TrackedImage, first_layer: u32, num_layers: u32,
                            first_mipmap: u32, num_mipmaps: u32, layout: Layout);

    fn add_image_transition_notification(&mut self, image: &TrackedImage, first_layer: u32,
                                         num_layers: u32, first_mipmap: u32, num_mipmaps: u32,
                                         layout: Layout);
}

pub trait CommandsListSinkCaller<'a> {
    fn call(self: Box<Self>, &mut RawCommandBufferPrototype<'a>);
}
impl<'a, T> CommandsListSinkCaller<'a> for T where T: FnOnce(&mut RawCommandBufferPrototype<'a>) -> () + 'a {
    fn call(self: Box<Self>, proto: &mut RawCommandBufferPrototype<'a>) {
        self(proto);
    }
}

/// Extension trait for both `CommandsList` and `CommandsListOutput` that indicates that we're
/// possibly outside a render pass.
///
/// In other words, if this trait is *not* implemented then we're guaranteed *not* to be outside
/// of a render pass. If it is implemented, then we maybe are but that's not sure.
pub unsafe trait CommandsListPossibleOutsideRenderPass {
    /// Returns `true` if we're outside a render pass.
    fn is_outside_render_pass(&self) -> bool;
}

/// Extension trait for both `CommandsList` and `CommandsListOutput` that indicates that we're
/// possibly inside a render pass.
///
/// In other words, if this trait is *not* implemented then we're guaranteed *not* to be inside
/// a render pass. If it is implemented, then we maybe are but that's not sure.
// TODO: make all return values optional, since we're possibly not in a render pass
pub unsafe trait CommandsListPossibleInsideRenderPass {
    type RenderPass: RenderPass;

    /// Returns the number of the subpass we're in. The value is 0-indexed, so immediately after
    /// calling `begin_render_pass` the value will be `0`.
    ///
    /// The value should always be strictly inferior to the number of subpasses in the render pass.
    fn current_subpass_num(&self) -> u32;

    /// If true, only secondary command buffers can be added inside the subpass. If false, only
    /// inline draw commands can be added.
    fn secondary_subpass(&self) -> bool;

    /// Returns the description of the render pass we're in.
    // TODO: return a trait object instead?
    fn render_pass(&self) -> &Self::RenderPass;

    //fn current_subpass(&self) -> Subpass<&Self::RenderPass>;
}

#[deprecated]
pub unsafe trait CommandsListOutput<S = StatesManager> {
    /// Returns the inner object.
    // TODO: crappy API
    #[deprecated]
    fn inner(&self) -> vk::CommandBuffer;

    /// Returns the device this object belongs to.
    #[deprecated]
    fn device(&self) -> &Arc<Device>;

    #[deprecated]
    unsafe fn on_submit(&self, states: &S, queue: &Arc<Queue>,
                        fence: &mut FnMut() -> Arc<Fence>) -> SubmitInfo;
}

#[deprecated]
pub struct CommandBuffer<C = Box<CommandsListOutput>> {
    states: StatesManager,
    commands: C,
}

unsafe impl<C> Submit for CommandBuffer<C> where C: CommandsListOutput {
    #[inline]
    fn device(&self) -> &Arc<Device> {
        self.commands.device()
    }

    #[inline]
    unsafe fn append_submission<'a>(&'a self, mut base: SubmitBuilder<'a>, queue: &Arc<Queue>)
                                    -> Result<SubmitBuilder<'a>, Box<Error>>
    {
        let mut fence = None;
        let infos = self.commands.on_submit(&self.states, queue, &mut || {
            match &mut fence {
                f @ &mut None => {
                    let fe = Fence::new(self.device().clone()); *f = Some(fe.clone()); fe
                },
                &mut Some(ref f) => f.clone()
            }
        });

        for (sem_wait, sem_stage) in infos.semaphores_wait {
            base = base.add_wait_semaphore(sem_wait, sem_stage);
        }

        if !infos.pre_pipeline_barrier.is_empty() {
            unimplemented!()
        }

        base = base.add_command_buffer_raw(self.commands.inner());

        if !infos.post_pipeline_barrier.is_empty() {
            unimplemented!()
        }

        for sem_signal in infos.semaphores_signal {
            base = base.add_signal_semaphore(sem_signal);
        }

        if let Some(fence) = fence {
            base = base.add_fence_signal(fence);
        }

        Ok(base)
    }
}
<|endoftext|>


<commit_before>//! The `ztext` module contains encoding functions to encode text in z-ascii characters.
//!

use super::zbytes::Bytes;

pub static ALPHABET: [char; 78] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',

    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',

    ' ', '\n', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.',
    ',', '!', '?', '_', '#', '\'','"', '/', '\\','-', ':', '(', ')'];

/// encodes an string to z-characters
/// and returns the length of the used bytes
/// TODO: Only works with lower case letters
///
/// # Examples
///
/// ```ignore
/// let data = Bytes{bytes: Vec::new()};
/// let byteLength = data.encode("hello");
/// ```
pub fn encode(data: &mut Bytes, content: &str, unicode_table: &Vec<u16>) -> u16 {
    let zchars: Vec<u8> = string_to_zchar(content, unicode_table);

    let mut two_bytes: u16 = 0;
    let len = zchars.len();
    for i in 0..len {
        let zasci_id =zchars[i];

        two_bytes |= shift(zasci_id as u16, i as u8);

        if i % 3 == 2 {
            data.write_u16(two_bytes, pos_to_index(i));
            two_bytes = 0;
        }

        // end of string
        if i == len -1 {
            if i % 3 != 2 {
                for j in (i % 3) + 1..3 {
                    two_bytes |= shift(0x05 as u16, j as u8);
                }

                data.write_u16(two_bytes, pos_to_index(i));
            }

            // end bit is written to the first bit of the next to last byte
            let end_index: usize = data.bytes.len() - 2 as usize;
            let mut end_byte: u8 = data.bytes[end_index];

            end_byte |= 0x80;
            data.write_byte(end_byte, end_index as usize);
        }
    }

    data.bytes.len() as u16
}

/// reads the content and converts it to a zasci vector
fn string_to_zchar(content: &str, unicode_table: &Vec<u16>) -> Vec<u8> {
    //let string_bytes = content.to_string().into_bytes();
    let mut zchars: Vec<u8> = Vec::new();

    for character in content.chars() {

        let mut byte: u8 = character as u8;
        let alpha_index = pos_in_alpha(byte as u8);
        if character as u16 <= 126 && alpha_index != -1 {

            if byte == 0x0A {
                // newline
                zchars.push(0x05);
                zchars.push(7);
            } else if byte == 0x20 {
                // space
                zchars.push(0x00);
            } else {
                if alpha_index > 51 {
                    // in A2
                    zchars.push(0x05);
                    zchars.push(alpha_index as u8 % 26 + 6);
                } else if alpha_index < 26 {
                    // in A0
                    zchars.push(alpha_index as u8 % 26 + 6);
                } else {
                    // in A1
                    zchars.push(0x04);
                    zchars.push(alpha_index as u8 % 26 + 6);
                }
            }
        } else {
            // not in alphabet or unicode

            // to change alphabet
            zchars.push(0x05);

            // for special char (10 bit z-ascii)
            zchars.push(0x06);

            //let mut byte: u8;
            if character as u16 <= 126 {
                // not in alphabet, but still ascii
                byte = character as u8;
            } else {
                // unicode
                let unicode_index = pos_in_unicode(character as u16, unicode_table);
                byte = unicode_index as u8 + 155;
            }

            zchars.push(byte >> 5);
            zchars.push(byte & 0x1f);
        }
    }
    zchars
}

/// shifts the z-char in a 2 bytes-array to the right position
/// shift_length has 3 possibilities: 10, 5, 0
/// an z-char use 5 bytes
/// look into two bytes:
/// ____byte one____ ____byte two____
/// 1 2 3 4 5 6  7 8 1 2 3  4 5 6 7 8
///   ^          ^          1
///   1 2 3 4 5  1 2 3 4 5  1 2 3 4 5
///   1. zchar   2. zchar   3. zchar
///   10         5          0
fn shift(zchar: u16, position: u8) -> u16 {
    let shift_length = 10 - (position % 3) * 5;
    zchar << shift_length
}

/// Returns the location of the character of the specified index in the zcode character array
///
/// # Examples
///
fn pos_in_alpha(letter: u8) -> i8 {
    for i in 0..ALPHABET.len() {
        if ALPHABET[i] as u8 == letter {
            return i as i8
        }
    }

    return -1
}

/// returns the position in the unicode-table
pub fn pos_in_unicode(letter: u16, unicode_table: &Vec<u16>) -> i8 {
    for (i, character) in unicode_table.iter().enumerate() {
        if *character == letter {
            return i as i8
        }
    }

    return -1
}

/// position in the vector from the position of an character in the string
/// every 3 zchars encode() writes 2 bytes
/// for example "helloworld"
/// "h": nothing
/// "e": nothing
/// "l": write 2 bytes to position 0   (2 * 2/3))
/// "l": nothing
/// "o": nothing
/// "w": write 2 bytes to position 2   (2 * 5/3))
/// ...
///
/// # Examples
///
/// ```ignore
/// assert_eq!(pos_to_index(5), 2);
/// ```
fn pos_to_index(position: usize) -> usize {
    2 * (position / 3)
}

#[test]
fn test_pos_in_alpha() {
    assert_eq!(pos_in_alpha('a' as u8), 0);
    assert_eq!(pos_in_alpha('b' as u8), 1);
    assert_eq!(pos_in_alpha('c' as u8), 2);
    assert_eq!(pos_in_alpha('A' as u8), 26);
    assert_eq!(pos_in_alpha('B' as u8), 27);
    assert_eq!(pos_in_alpha('C' as u8), 28);
}

#[test]
fn test_pos_to_index() {
    assert_eq!(pos_to_index(5), 2);
}

#[test]
fn test_shift() {
    assert_eq!(shift(6,2), 6);
    assert_eq!(shift(26,5), 26);
}<commit_msg>more ztext test<commit_after>//! The `ztext` module contains encoding functions to encode text in z-ascii characters.
//!

use super::zbytes::Bytes;

pub static ALPHABET: [char; 78] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',

    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',

    ' ', '\n', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.',
    ',', '!', '?', '_', '#', '\'','"', '/', '\\','-', ':', '(', ')'];

/// encodes an string to z-characters
/// and returns the length of the used bytes
/// TODO: Only works with lower case letters
///
/// # Examples
///
/// ```ignore
/// let data = Bytes{bytes: Vec::new()};
/// let byteLength = data.encode("hello");
/// ```
pub fn encode(data: &mut Bytes, content: &str, unicode_table: &Vec<u16>) -> u16 {
    let zchars: Vec<u8> = string_to_zchar(content, unicode_table);

    let mut two_bytes: u16 = 0;
    let len = zchars.len();
    for i in 0..len {
        let zasci_id =zchars[i];

        two_bytes |= shift(zasci_id as u16, i as u8);

        if i % 3 == 2 {
            data.write_u16(two_bytes, pos_to_index(i));
            two_bytes = 0;
        }

        // end of string
        if i == len -1 {
            if i % 3 != 2 {
                for j in (i % 3) + 1..3 {
                    two_bytes |= shift(0x05 as u16, j as u8);
                }

                data.write_u16(two_bytes, pos_to_index(i));
            }

            // end bit is written to the first bit of the next to last byte
            let end_index: usize = data.bytes.len() - 2 as usize;
            let mut end_byte: u8 = data.bytes[end_index];

            end_byte |= 0x80;
            data.write_byte(end_byte, end_index as usize);
        }
    }

    data.bytes.len() as u16
}

/// reads the content and converts it to a zasci vector
fn string_to_zchar(content: &str, unicode_table: &Vec<u16>) -> Vec<u8> {
    //let string_bytes = content.to_string().into_bytes();
    let mut zchars: Vec<u8> = Vec::new();

    for character in content.chars() {

        let mut byte: u8 = character as u8;
        let alpha_index = pos_in_alpha(byte as u8);
        if character as u16 <= 126 && alpha_index != -1 {

            if byte == 0x0A {
                // newline
                zchars.push(0x05);
                zchars.push(7);
            } else if byte == 0x20 {
                // space
                zchars.push(0x00);
            } else {
                if alpha_index > 51 {
                    // in A2
                    zchars.push(0x05);
                    zchars.push(alpha_index as u8 % 26 + 6);
                } else if alpha_index < 26 {
                    // in A0
                    zchars.push(alpha_index as u8 % 26 + 6);
                } else {
                    // in A1
                    zchars.push(0x04);
                    zchars.push(alpha_index as u8 % 26 + 6);
                }
            }
        } else {
            // not in alphabet or unicode

            // to change alphabet
            zchars.push(0x05);

            // for special char (10 bit z-ascii)
            zchars.push(0x06);

            //let mut byte: u8;
            if character as u16 <= 126 {
                // not in alphabet, but still ascii
                byte = character as u8;
            } else {
                // unicode
                let unicode_index = pos_in_unicode(character as u16, unicode_table);
                byte = unicode_index as u8 + 155;
            }

            zchars.push(byte >> 5);
            zchars.push(byte & 0x1f);
        }
    }
    zchars
}

/// shifts the z-char in a 2 bytes-array to the right position
/// shift_length has 3 possibilities: 10, 5, 0
/// an z-char use 5 bytes
/// look into two bytes:
/// ____byte one____ ____byte two____
/// 1 2 3 4 5 6  7 8 1 2 3  4 5 6 7 8
///   ^          ^          1
///   1 2 3 4 5  1 2 3 4 5  1 2 3 4 5
///   1. zchar   2. zchar   3. zchar
///   10         5          0
fn shift(zchar: u16, position: u8) -> u16 {
    let shift_length = 10 - (position % 3) * 5;
    zchar << shift_length
}

/// Returns the location of the character of the specified index in the zcode character array
///
/// # Examples
///
fn pos_in_alpha(letter: u8) -> i8 {
    for i in 0..ALPHABET.len() {
        if ALPHABET[i] as u8 == letter {
            return i as i8
        }
    }

    return -1
}

/// returns the position in the unicode-table
pub fn pos_in_unicode(letter: u16, unicode_table: &Vec<u16>) -> i8 {
    for (i, character) in unicode_table.iter().enumerate() {
        if *character == letter {
            return i as i8
        }
    }

    return -1
}

/// position in the vector from the position of an character in the string
/// every 3 zchars encode() writes 2 bytes
/// for example "helloworld"
/// "h": nothing
/// "e": nothing
/// "l": write 2 bytes to position 0   (2 * 2/3))
/// "l": nothing
/// "o": nothing
/// "w": write 2 bytes to position 2   (2 * 5/3))
/// ...
///
/// # Examples
///
fn pos_to_index(position: usize) -> usize {
    2 * (position / 3)
}

#[test]
fn test_pos_in_alpha() {
    assert_eq!(pos_in_alpha('a' as u8), 0);
    assert_eq!(pos_in_alpha('b' as u8), 1);
    assert_eq!(pos_in_alpha('c' as u8), 2);
    assert_eq!(pos_in_alpha('A' as u8), 26);
    assert_eq!(pos_in_alpha('B' as u8), 27);
    assert_eq!(pos_in_alpha('C' as u8), 28);
}

#[test]
fn test_pos_to_index() {
    assert_eq!(pos_to_index(5), 2);
}

#[test]
fn test_shift() {
    assert_eq!(shift(6,2), 6);
    assert_eq!(shift(26,5), 26);
}

#[test]
fn test_string_to_zchar() {
    let mut vec: Vec<u16> = Vec::new();
    assert_eq!(string_to_zchar("i am a string, please test me, no unicode",&vec), vec![14, 0, 6, 18, 0, 6, 0, 24, 25, 23, 14, 19, 12, 5, 19, 0, 21, 17, 10, 6, 24, 10, 0, 25, 10, 24, 25, 0, 18, 10, 5, 19, 0, 19, 20, 0, 26, 19, 14, 8, 20, 9, 10]);
    vec.push('€' as u16);
    assert_eq!(string_to_zchar("nasty char: €",&vec), vec![19, 6, 24, 25, 30, 0, 8, 13, 6, 23, 5, 29, 0, 5, 6, 4, 27]);
}

// #[test]
// fn test_encode() {
//     let mut vec: Vec<u16> = Vec::new();
//     let mut data = Bytes{bytes: Vec::new()};
//     let byteLength = encode(&data,"hello",&vec);
//     assert_eq!(byteLength,5);
//     assert_eq!(data,5);
// }<|endoftext|>


<commit_before><commit_msg>Refactor Value impl with higher-order-functions<commit_after><|endoftext|>


<commit_before><commit_msg>Removes a long-outdated comment.<commit_after><|endoftext|>


<commit_before>
use std;
use std::num::FromPrimitive;
use std::c_str::CString;
use ffi;
use {
    FtResult,
    Matrix,
    Vector,
    GlyphSlot,
};

#[repr(u32)]
pub enum KerningMode {
    KerningDefault = ffi::FT_KERNING_DEFAULT,
    KerningUnfitted = ffi::FT_KERNING_UNFITTED,
    KerningUnscaled = ffi::FT_KERNING_UNSCALED
}

bitflags!(flags LoadFlag: i32 {
    static Default = ffi::FT_LOAD_DEFAULT,
    static NoScale = ffi::FT_LOAD_NO_SCALE,
    static NoHinting = ffi::FT_LOAD_NO_HINTING,
    static Render = ffi::FT_LOAD_RENDER,
    static NoBitmap = ffi::FT_LOAD_NO_BITMAP,
    static VerticalLayout = ffi::FT_LOAD_VERTICAL_LAYOUT,
    static ForceAutohint = ffi::FT_LOAD_FORCE_AUTOHINT,
    static CropBitmap = ffi::FT_LOAD_CROP_BITMAP,
    static Pendantic = ffi::FT_LOAD_PENDANTIC,
    static IgnoreGlobalAdvanceWidth = ffi::FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH,
    static NoRecurse = ffi::FT_LOAD_NO_RECURSE,
    static IgnoreTransform = ffi::FT_LOAD_IGNORE_TRANSFORM,
    static Monochrome = ffi::FT_LOAD_MONOCHROME,
    static LinearDesign = ffi::FT_LOAD_LINEAR_DESIGN,
    static NoAutohint = ffi::FT_LOAD_NO_AUTOHINT,
    static Color = ffi::FT_LOAD_COLOR
})

pub struct Face {
    raw: ffi::FT_Face,
    glyph: GlyphSlot,
}

impl Face {
    pub fn from_raw(raw: ffi::FT_Face) -> Face {
        Face {
            raw: raw,
            glyph: unsafe { GlyphSlot::from_raw((*raw).glyph) },
        }
    }

    pub fn attach_file(&self, filepathname: &str) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Attach_File(self.raw, filepathname.as_slice().as_ptr() as *const i8);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn reference(&self) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Reference_Face(self.raw);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_char_size(&self, char_width: ffi::FT_F26Dot6, char_height: ffi::FT_F26Dot6, horz_resolution: ffi::FT_UInt, vert_resolution: ffi::FT_UInt) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Set_Char_Size(self.raw, char_width, char_height, horz_resolution, vert_resolution);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_pixel_sizes(&self, pixel_width: ffi::FT_UInt, pixel_height: ffi::FT_UInt) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Set_Pixel_Sizes(self.raw, pixel_width, pixel_height);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn load_glyph(&self, glyph_index: ffi::FT_UInt, load_flags: LoadFlag) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Load_Glyph(self.raw, glyph_index, load_flags.bits);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn load_char(&self, char_code: ffi::FT_ULong, load_flags: LoadFlag) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Load_Char(self.raw, char_code, load_flags.bits);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_transform(&self, matrix: &Matrix, delta: &Vector) {
        unsafe {
            ffi::FT_Set_Transform(self.raw, matrix, delta);
        }
    }

    pub fn get_char_index(&self, charcode: ffi::FT_ULong) -> ffi::FT_UInt {
        unsafe {
            ffi::FT_Get_Char_Index(self.raw, charcode)
        }
    }

    pub fn get_kerning(&self, left_char_index: ffi::FT_UInt, right_char_index: ffi::FT_UInt, kern_mode: KerningMode)
        -> FtResult<Vector> {

        let vec = Vector { x: 0, y: 0 };

        let err_code = unsafe {
            ffi::FT_Get_Kerning(self.raw, left_char_index, right_char_index,
                                kern_mode as u32, std::mem::transmute(&vec))
        };

        if err_code == ffi::FT_Err_Ok {
            Ok(vec)
        } else {
            Err(FromPrimitive::from_i32(err_code).unwrap())
        }
    }

    // According to FreeType doc, each time you load a new glyph image,
    // the previous one is erased from the glyph slot.
    #[inline(always)]
    pub fn glyph(&self) -> &GlyphSlot {
        &self.glyph
    }

    #[inline(always)]
    pub fn has_horizontal(&self) -> bool {
        ffi::FT_HAS_HORIZONTAL(self.raw)
    }

    #[inline(always)]
    pub fn has_vertical(&self) -> bool {
        ffi::FT_HAS_VERTICAL(self.raw)
    }

    #[inline(always)]
    pub fn has_kerning(&self) -> bool {
        ffi::FT_HAS_KERNING(self.raw)
    }

    #[inline(always)]
    pub fn is_scalable(&self) -> bool {
        ffi::FT_IS_SCALABLE(self.raw)
    }

    #[inline(always)]
    pub fn is_sfnt(&self) -> bool {
        ffi::FT_IS_SFNT(self.raw)
    }

    #[inline(always)]
    pub fn is_fixed_width(&self) -> bool {
        ffi::FT_IS_FIXED_WIDTH(self.raw)
    }

    #[inline(always)]
    pub fn has_fixed_sizes(&self) -> bool {
        ffi::FT_HAS_FIXED_SIZES(self.raw)
    }

    #[inline(always)]
    pub fn has_glyph_names(&self) -> bool {
        ffi::FT_HAS_GLYPH_NAMES(self.raw)
    }

    #[inline(always)]
    pub fn is_cid_keyed(&self) -> bool {
        ffi::FT_IS_CID_KEYED(self.raw)
    }

    #[inline(always)]
    pub fn is_tricky(&self) -> bool {
        ffi::FT_IS_TRICKY(self.raw)
    }

    #[inline(always)]
    pub fn has_color(&self) -> bool {
        ffi::FT_HAS_COLOR(self.raw)
    }

    #[inline(always)]
    pub fn raw(&self) -> &ffi::FT_FaceRec {
        unsafe {
            &*self.raw
        }
    }

    #[inline(always)]
    pub fn ascender(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).ascender
        }
    }

    #[inline(always)]
    pub fn descender(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).descender
        }
    }

    #[inline(always)]
    pub fn height(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).height
        }
    }

    #[inline(always)]
    pub fn max_advance_width(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).max_advance_width
        }
    }

    #[inline(always)]
    pub fn max_advance_height(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).max_advance_height
        }
    }

    #[inline(always)]
    pub fn underline_position(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).underline_position
        }
    }

    #[inline(always)]
    pub fn underline_thickness(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).underline_thickness
        }
    }

    pub fn family_name(&self) -> Option<String> {
        let family_name = unsafe {
            CString::new((*self.raw).family_name, false)
        };

        if family_name.is_null() {
            None
        } else {
            Some(family_name.as_str().unwrap().into_string())
        }
    }

    pub fn style_name(&self) -> Option<String> {
        let style_name = unsafe {
            CString::new((*self.raw).style_name, false)
        };

        if style_name.is_null() {
            None
        } else {
            Some(style_name.as_str().unwrap().into_string())
        }
    }
}

impl Drop for Face {
    fn drop(&mut self) {
        unsafe {
            let err = ffi::FT_Done_Face(self.raw);
            if err != 0 {
                std::io::println(format!("Failed to drop face. Error Code: {}", err).as_slice());
            }
        }
    }
}

<commit_msg>Removed deprecated functions<commit_after>
use std;
use std::num::FromPrimitive;
use std::c_str::CString;
use ffi;
use {
    FtResult,
    Matrix,
    Vector,
    GlyphSlot,
};

#[repr(u32)]
pub enum KerningMode {
    KerningDefault = ffi::FT_KERNING_DEFAULT,
    KerningUnfitted = ffi::FT_KERNING_UNFITTED,
    KerningUnscaled = ffi::FT_KERNING_UNSCALED
}

bitflags!(flags LoadFlag: i32 {
    static Default = ffi::FT_LOAD_DEFAULT,
    static NoScale = ffi::FT_LOAD_NO_SCALE,
    static NoHinting = ffi::FT_LOAD_NO_HINTING,
    static Render = ffi::FT_LOAD_RENDER,
    static NoBitmap = ffi::FT_LOAD_NO_BITMAP,
    static VerticalLayout = ffi::FT_LOAD_VERTICAL_LAYOUT,
    static ForceAutohint = ffi::FT_LOAD_FORCE_AUTOHINT,
    static CropBitmap = ffi::FT_LOAD_CROP_BITMAP,
    static Pendantic = ffi::FT_LOAD_PENDANTIC,
    static IgnoreGlobalAdvanceWidth = ffi::FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH,
    static NoRecurse = ffi::FT_LOAD_NO_RECURSE,
    static IgnoreTransform = ffi::FT_LOAD_IGNORE_TRANSFORM,
    static Monochrome = ffi::FT_LOAD_MONOCHROME,
    static LinearDesign = ffi::FT_LOAD_LINEAR_DESIGN,
    static NoAutohint = ffi::FT_LOAD_NO_AUTOHINT,
    static Color = ffi::FT_LOAD_COLOR
})

pub struct Face {
    raw: ffi::FT_Face,
    glyph: GlyphSlot,
}

impl Face {
    pub fn from_raw(raw: ffi::FT_Face) -> Face {
        Face {
            raw: raw,
            glyph: unsafe { GlyphSlot::from_raw((*raw).glyph) },
        }
    }

    pub fn attach_file(&self, filepathname: &str) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Attach_File(self.raw, filepathname.as_slice().as_ptr() as *const i8);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn reference(&self) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Reference_Face(self.raw);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_char_size(&self, char_width: ffi::FT_F26Dot6, char_height: ffi::FT_F26Dot6, horz_resolution: ffi::FT_UInt, vert_resolution: ffi::FT_UInt) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Set_Char_Size(self.raw, char_width, char_height, horz_resolution, vert_resolution);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_pixel_sizes(&self, pixel_width: ffi::FT_UInt, pixel_height: ffi::FT_UInt) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Set_Pixel_Sizes(self.raw, pixel_width, pixel_height);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn load_glyph(&self, glyph_index: ffi::FT_UInt, load_flags: LoadFlag) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Load_Glyph(self.raw, glyph_index, load_flags.bits);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn load_char(&self, char_code: ffi::FT_ULong, load_flags: LoadFlag) -> FtResult<()> {
        unsafe {
            let err = ffi::FT_Load_Char(self.raw, char_code, load_flags.bits);
            if err == ffi::FT_Err_Ok {
                Ok(())
            } else {
                Err(FromPrimitive::from_i32(err).unwrap())
            }
        }
    }

    pub fn set_transform(&self, matrix: &Matrix, delta: &Vector) {
        unsafe {
            ffi::FT_Set_Transform(self.raw, matrix, delta);
        }
    }

    pub fn get_char_index(&self, charcode: ffi::FT_ULong) -> ffi::FT_UInt {
        unsafe {
            ffi::FT_Get_Char_Index(self.raw, charcode)
        }
    }

    pub fn get_kerning(&self, left_char_index: ffi::FT_UInt, right_char_index: ffi::FT_UInt, kern_mode: KerningMode)
        -> FtResult<Vector> {

        let vec = Vector { x: 0, y: 0 };

        let err_code = unsafe {
            ffi::FT_Get_Kerning(self.raw, left_char_index, right_char_index,
                                kern_mode as u32, std::mem::transmute(&vec))
        };

        if err_code == ffi::FT_Err_Ok {
            Ok(vec)
        } else {
            Err(FromPrimitive::from_i32(err_code).unwrap())
        }
    }

    // According to FreeType doc, each time you load a new glyph image,
    // the previous one is erased from the glyph slot.
    #[inline(always)]
    pub fn glyph(&self) -> &GlyphSlot {
        &self.glyph
    }

    #[inline(always)]
    pub fn has_horizontal(&self) -> bool {
        ffi::FT_HAS_HORIZONTAL(self.raw)
    }

    #[inline(always)]
    pub fn has_vertical(&self) -> bool {
        ffi::FT_HAS_VERTICAL(self.raw)
    }

    #[inline(always)]
    pub fn has_kerning(&self) -> bool {
        ffi::FT_HAS_KERNING(self.raw)
    }

    #[inline(always)]
    pub fn is_scalable(&self) -> bool {
        ffi::FT_IS_SCALABLE(self.raw)
    }

    #[inline(always)]
    pub fn is_sfnt(&self) -> bool {
        ffi::FT_IS_SFNT(self.raw)
    }

    #[inline(always)]
    pub fn is_fixed_width(&self) -> bool {
        ffi::FT_IS_FIXED_WIDTH(self.raw)
    }

    #[inline(always)]
    pub fn has_fixed_sizes(&self) -> bool {
        ffi::FT_HAS_FIXED_SIZES(self.raw)
    }

    #[inline(always)]
    pub fn has_glyph_names(&self) -> bool {
        ffi::FT_HAS_GLYPH_NAMES(self.raw)
    }

    #[inline(always)]
    pub fn is_cid_keyed(&self) -> bool {
        ffi::FT_IS_CID_KEYED(self.raw)
    }

    #[inline(always)]
    pub fn is_tricky(&self) -> bool {
        ffi::FT_IS_TRICKY(self.raw)
    }

    #[inline(always)]
    pub fn has_color(&self) -> bool {
        ffi::FT_HAS_COLOR(self.raw)
    }

    #[inline(always)]
    pub fn raw(&self) -> &ffi::FT_FaceRec {
        unsafe {
            &*self.raw
        }
    }

    #[inline(always)]
    pub fn ascender(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).ascender
        }
    }

    #[inline(always)]
    pub fn descender(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).descender
        }
    }

    #[inline(always)]
    pub fn height(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).height
        }
    }

    #[inline(always)]
    pub fn max_advance_width(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).max_advance_width
        }
    }

    #[inline(always)]
    pub fn max_advance_height(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).max_advance_height
        }
    }

    #[inline(always)]
    pub fn underline_position(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).underline_position
        }
    }

    #[inline(always)]
    pub fn underline_thickness(&self) -> ffi::FT_Short {
        unsafe {
            (*self.raw).underline_thickness
        }
    }

    pub fn family_name(&self) -> Option<String> {

        let family_name_ptr = unsafe { (*self.raw).family_name };

        if family_name_ptr.is_null() {
            None
        } else {
            let family_name = unsafe { CString::new(family_name_ptr, false) };
            Some(family_name.as_str().unwrap().into_string())
        }
    }

    pub fn style_name(&self) -> Option<String> {

        let style_name_ptr = unsafe { (*self.raw).style_name };

        if style_name_ptr.is_null() {
            None
        } else {
            let style_name = unsafe { CString::new(style_name_ptr, false) };
            Some(style_name.as_str().unwrap().into_string())
        }
    }
}

impl Drop for Face {
    fn drop(&mut self) {
        unsafe {
            let err = ffi::FT_Done_Face(self.raw);
            if err != 0 {
                std::io::println(format!("Failed to drop face. Error Code: {}", err).as_slice());
            }
        }
    }
}

<|endoftext|>


<commit_before>use std::num;

pub struct Point<T> {
    pub x: T,
    pub y: T
}

impl<T> Point<T> {
    pub fn new(x: T, y: T) -> Point<T> {
        return Point{x: x, y: y};
    }
}

impl<T:Clone + Add<T,T>> Add<Point<T>, Point<T>> for Point<T> {
    fn add(&self, other: &Point<T>) -> Point<T> {
        return Point::new(self.x + other.x, self.y + other.y);
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point<T>, Point<T>> for Point<T> {
    fn sub(&self, other: &Point<T>) -> Point<T> {
        return Point::new(self.x - other.x, self.y - other.y);
    }
}

impl<T:Clone + Mul<T,T>> Point<T> {
    pub fn scale(&self, factor: T) -> Point<T> {
        return Point::new(self.x * factor, self.y * factor);
    }
}

impl<T:NumCast + Clone> Point<T> {
    pub fn cast<U:NumCast>(&self) -> Option<Point<U>> {
        return match (num::cast(self.x.clone()), num::cast(self.y.clone())) {
            (Some(x), Some(y)) => Some(Point::new(x, y)),
            _                  => None
        }
    }
}

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

    #[test]
    fn test_add() {
        let p1 = Point::<int>::new(2, 3);
        let p2 = Point::<int>::new(1, 5);
        let p3 = p1 + p2;
        assert_eq!((p3.x, p3.y), (3, 8));
    }

    #[test]
    fn test_sub() {
        let p1 = Point::<int>::new(2, 3);
        let p2 = Point::<int>::new(1, 5);
        let p3 = p1 - p2;
        assert_eq!((p3.x, p3.y), (1, -2));
    }

    #[test]
    fn test_scale() {
        let p = Point::<int>::new(2, 3).scale(2);
        assert_eq!((p.x, p.y), (4, 6));
    }

    #[test]
    fn test_cast() {
        let pf = Point::<f64>::new(1.3, 2.9);
        let pi = pf.cast::<int>().unwrap();
        assert_eq!((pi.x, pi.y), (1, 2));
    }
}
<commit_msg>remove obsolete NumCast+Clone implementation<commit_after>use std::num;

pub struct Point<T> {
    pub x: T,
    pub y: T
}

impl<T> Point<T> {
    pub fn new(x: T, y: T) -> Point<T> {
        return Point{x: x, y: y};
    }
}

impl<T:Clone + Add<T,T>> Add<Point<T>, Point<T>> for Point<T> {
    fn add(&self, other: &Point<T>) -> Point<T> {
        return Point::new(self.x + other.x, self.y + other.y);
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point<T>, Point<T>> for Point<T> {
    fn sub(&self, other: &Point<T>) -> Point<T> {
        return Point::new(self.x - other.x, self.y - other.y);
    }
}

impl<T:Clone + Mul<T,T>> Point<T> {
    pub fn scale(&self, factor: T) -> Point<T> {
        return Point::new(self.x * factor, self.y * factor);
    }
}

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

    #[test]
    fn test_add() {
        let p1 = Point::<int>::new(2, 3);
        let p2 = Point::<int>::new(1, 5);
        let p3 = p1 + p2;
        assert_eq!((p3.x, p3.y), (3, 8));
    }

    #[test]
    fn test_sub() {
        let p1 = Point::<int>::new(2, 3);
        let p2 = Point::<int>::new(1, 5);
        let p3 = p1 - p2;
        assert_eq!((p3.x, p3.y), (1, -2));
    }

    #[test]
    fn test_scale() {
        let p = Point::<int>::new(2, 3).scale(2);
        assert_eq!((p.x, p.y), (4, 6));
    }

    #[test]
    fn test_cast() {
        let pf = Point::<f64>::new(1.3, 2.9);
        let pi = pf.cast::<int>().unwrap();
        assert_eq!((pi.x, pi.y), (1, 2));
    }
}
<|endoftext|>


<commit_before><commit_msg>use String functions - handle url prefix<commit_after><|endoftext|>


<commit_before>#![crate_id(name="comm", vers="1.0.0", author="Michael Gehring")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::cmp::Ord;
use std::io::{BufferedReader, IoResult, print};
use std::io::fs::File;
use std::io::stdio::stdin;
use std::os;
use std::path::Path;

static NAME : &'static str = "comm";
static VERSION : &'static str = "1.0.0";

fn mkdelim(col: uint, opts: &getopts::Matches) -> String {
    let mut s = String::new();
    let delim = match opts.opt_str("output-delimiter") {
        Some(d) => d.clone(),
        None => "\t".to_string(),
    };

    if col > 1 && !opts.opt_present("1") {
        s.push_str(delim.as_slice());
    }
    if col > 2 && !opts.opt_present("2") {
        s.push_str(delim.as_slice());
    }

    s
}

fn comm(a: &mut Box<Buffer>, b: &mut Box<Buffer>, opts: &getopts::Matches) {

    let delim = Vec::from_fn(4, |col| mkdelim(col, opts));

    let mut ra = a.read_line();
    let mut rb = b.read_line();

    while ra.is_ok() || rb.is_ok() {
        let ord = match (ra.clone(), rb.clone()) {
            (Err(_), Ok(_))  => Greater,
            (Ok(_) , Err(_)) => Less,
            (Ok(s0), Ok(s1)) => s0.cmp(&s1),
            _ => unreachable!(),
        };

        match ord {
            Less => {
                if !opts.opt_present("1") {
                    print!("{}{}", delim.get(1), ra.unwrap());
                }
                ra = a.read_line();
            }
            Greater => {
                if !opts.opt_present("2") {
                    print!("{}{}", delim.get(2), rb.unwrap());
                }
                rb = b.read_line();
            }
            Equal => {
                if !opts.opt_present("3") {
                    print!("{}{}", delim.get(3), ra.unwrap());
                }
                ra = a.read_line();
                rb = b.read_line();
            }
        }
    }
}

fn open_file(name: &str) -> IoResult<Box<Buffer>> {
    match name {
        "-" => Ok(box stdin() as Box<Buffer>),
        _   => {
            let f = try!(File::open(&Path::new(name)));
            Ok(box BufferedReader::new(f) as Box<Buffer>)
        }
    }
}

#[allow(dead_code)]
fn main() { uumain(os::args()); }

pub fn uumain(args: Vec<String>) {
    let opts = [
        getopts::optflag("1", "", "suppress column 1 (lines uniq to FILE1)"),
        getopts::optflag("2", "", "suppress column 2 (lines uniq to FILE2)"),
        getopts::optflag("3", "", "suppress column 3 (lines that appear in both files)"),
        getopts::optopt("", "output-delimiter", "separate columns with STR", "STR"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(err) => fail!("{}", err.to_err_msg()),
    };

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return;
    }

    if matches.opt_present("help") || matches.free.len() != 2 {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTIONS] FILE1 FILE2", NAME);
        println!("");
        print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice());
        if matches.free.len() != 2 {
            os::set_exit_status(1);
        }
        return;
    }

    let mut f1 = open_file(matches.free.get(0).as_slice()).unwrap();
    let mut f2 = open_file(matches.free.get(1).as_slice()).unwrap();

    comm(&mut f1, &mut f2, &matches)
}
<commit_msg>comm: handle final lines without \n<commit_after>#![crate_id(name="comm", vers="1.0.0", author="Michael Gehring")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::cmp::Ord;
use std::io::{BufferedReader, IoResult, print};
use std::io::fs::File;
use std::io::stdio::stdin;
use std::os;
use std::path::Path;

static NAME : &'static str = "comm";
static VERSION : &'static str = "1.0.0";

fn mkdelim(col: uint, opts: &getopts::Matches) -> String {
    let mut s = String::new();
    let delim = match opts.opt_str("output-delimiter") {
        Some(d) => d.clone(),
        None => "\t".to_string(),
    };

    if col > 1 && !opts.opt_present("1") {
        s.push_str(delim.as_slice());
    }
    if col > 2 && !opts.opt_present("2") {
        s.push_str(delim.as_slice());
    }

    s
}

fn ensure_nl(line: String) -> String {
    match line.as_slice().chars().last() {
        Some('\n') => line,
        _ => line.append("\n"),
    }
}

fn comm(a: &mut Box<Buffer>, b: &mut Box<Buffer>, opts: &getopts::Matches) {

    let delim = Vec::from_fn(4, |col| mkdelim(col, opts));

    let mut ra = a.read_line();
    let mut rb = b.read_line();

    while ra.is_ok() || rb.is_ok() {
        let ord = match (ra.clone(), rb.clone()) {
            (Err(_), Ok(_))  => Greater,
            (Ok(_) , Err(_)) => Less,
            (Ok(s0), Ok(s1)) => s0.cmp(&s1),
            _ => unreachable!(),
        };

        match ord {
            Less => {
                if !opts.opt_present("1") {
                    print!("{}{}", delim.get(1), ra.map(ensure_nl).unwrap());
                }
                ra = a.read_line();
            }
            Greater => {
                if !opts.opt_present("2") {
                    print!("{}{}", delim.get(2), rb.map(ensure_nl).unwrap());
                }
                rb = b.read_line();
            }
            Equal => {
                if !opts.opt_present("3") {
                    print!("{}{}", delim.get(3), ra.map(ensure_nl).unwrap());
                }
                ra = a.read_line();
                rb = b.read_line();
            }
        }
    }
}

fn open_file(name: &str) -> IoResult<Box<Buffer>> {
    match name {
        "-" => Ok(box stdin() as Box<Buffer>),
        _   => {
            let f = try!(File::open(&Path::new(name)));
            Ok(box BufferedReader::new(f) as Box<Buffer>)
        }
    }
}

#[allow(dead_code)]
fn main() { uumain(os::args()); }

pub fn uumain(args: Vec<String>) {
    let opts = [
        getopts::optflag("1", "", "suppress column 1 (lines uniq to FILE1)"),
        getopts::optflag("2", "", "suppress column 2 (lines uniq to FILE2)"),
        getopts::optflag("3", "", "suppress column 3 (lines that appear in both files)"),
        getopts::optopt("", "output-delimiter", "separate columns with STR", "STR"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(err) => fail!("{}", err.to_err_msg()),
    };

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return;
    }

    if matches.opt_present("help") || matches.free.len() != 2 {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTIONS] FILE1 FILE2", NAME);
        println!("");
        print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice());
        if matches.free.len() != 2 {
            os::set_exit_status(1);
        }
        return;
    }

    let mut f1 = open_file(matches.free.get(0).as_slice()).unwrap();
    let mut f2 = open_file(matches.free.get(1).as_slice()).unwrap();

    comm(&mut f1, &mut f2, &matches)
}
<|endoftext|>


<commit_before><commit_msg>Fix order of async unsafe specifiers in trait fn<commit_after><|endoftext|>


<commit_before><commit_msg>Create main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>report client connection state in an external file<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unneeded data copying (+~30% perf)<commit_after><|endoftext|>


<commit_before><commit_msg>Nitpick<commit_after><|endoftext|>


<commit_before><commit_msg>add hint for opening the html file<commit_after><|endoftext|>


<commit_before><commit_msg>Fix compilation on AVX2 machines<commit_after><|endoftext|>


<commit_before>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

impl ToString for Var {
  fn to_string(&self) -> String {
    self.name.clone()
    // + "@" + &self.idx.to_string()
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match self {
      &Const(ref constant) => constant.to_string(),
      &Var(ref var) => var.to_string(),
      &Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      &Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      &App(ref f, ref arg) => {
        "(".to_string() + &f.to_string() + ") " + &arg.to_string()
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  println!("{:?}", Expr::constant(Const::Data));
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = Expr::var(&a);
  let exprx = Expr::var(&x);
  println!("{}", x.to_string());
  let id = Expr::pi(a.clone(),
                    Expr::constant(Const::Data),
                    Expr::lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = Expr::app(Expr::app(id, Expr::var(&Var::new("int", 0))),
                           Expr::var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
}
<commit_msg>Add is_x checks to Expr. Parenthesize applications.<commit_after>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

impl ToString for Var {
  fn to_string(&self) -> String {
    self.name.clone()
    // + "@" + &self.idx.to_string()
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    use Expr::*;
    match *self {
      Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    use Expr::*;
    match *self {
      Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    use Expr::*;
    match *self {
      Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    use Expr::*;
    match *self {
      Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    use Expr::*;
    match *self {
      App(_, _) => true,
      _ => false,
    }
  }
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match self {
      &Const(ref constant) => constant.to_string(),
      &Var(ref var) => var.to_string(),
      &Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      &Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      &App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = Expr::var(&a);
  let exprx = Expr::var(&x);
  println!("{}", x.to_string());
  let id = Expr::pi(a.clone(),
                    Expr::constant(Const::Data),
                    Expr::lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = Expr::app(Expr::app(id, Expr::var(&Var::new("int", 0))),
                           Expr::var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
}
<|endoftext|>


<commit_before>//! rs-collector: An scollector compatible telemetry collector written in Rust.

extern crate clap;
extern crate env_logger;
#[macro_use] extern crate log;
extern crate rs_collector;
extern crate time;

use clap::{Arg, ArgMatches, App};
use log::SetLoggerError;
use std::env;
use std::error::Error;
use std::path::Path;

use rs_collector::config::Config;

static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static DEFAULT_CONFIG_FILE: &'static str = "/etc/rs-collector.conf";

fn main() {
    if init_logger().is_err() {
        exit_with_error("Could not initialize logger", -1);
    }

    let app = App::new("rs-collector")
        .version(VERSION)
        .after_help("Two modes are supported, i.e., sending a datum with meta data or \
                               sending only meta data. The modes are controlled whether a value \
                               `--value` is passed or not. Please mind that in both cases the \
                               meta data is required.")
        .arg(Arg::with_name("configfile")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Sets a custom config file")
            .takes_value(true))
        .arg(Arg::with_name("show-config")
            .long("show-config")
            .help("Prints config"));
    let cli_args = app.get_matches();

    let config: Config = match parse_args(&cli_args) {
        Ok(config) => config,
        Err(err) => {
            exit_with_error(&format!("Failed to parse configuration, because {}.", err), -2);
        }
    };
    // TODO a config must have been parsed; if not exit!
    if cli_args.is_present("show-config") {
        println!("config: {:?}", config);
    }

    run(&config);
}

fn init_logger() -> Result<(), SetLoggerError> {
    use log::{LogRecord, LogLevelFilter};
    use env_logger::LogBuilder;

    let format = |record: &LogRecord| {
        let t = time::now();
        format!("{},{:03} - {} - {} - {}:{}",
                time::strftime("%Y-%m-%d %H:%M:%S", &t).unwrap(),
                t.tm_nsec / 1000_000,
                record.level(),
                record.args(),
                record.location().file(),
                record.location().line(),
        )
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, LogLevelFilter::Info);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

fn parse_args(cli_args: &ArgMatches) -> Result<Config, Box<Error>> {
    let config_file_path = Path::new(cli_args.value_of("configfile").unwrap_or(DEFAULT_CONFIG_FILE));
    let config: Config = if config_file_path.exists() {
        let config = try!(Config::load_from_rs_collector_config(&config_file_path));
        config
    } else {
        Default::default()
    };

    Ok(config)
}

fn run(config: &Config) {
    let collectors = rs_collector::collectors::create_collectors(config);
    rs_collector::scheduler::run(collectors, config);
}

fn exit_with_error(msg: &str, exit_code: i32) -> ! {
    println!("{}", msg);
    std::process::exit(exit_code);
}

#[cfg(test)]
mod tests {
}
<commit_msg>Removed wrong information from help<commit_after>//! rs-collector: An scollector compatible telemetry collector written in Rust.

extern crate clap;
extern crate env_logger;
#[macro_use] extern crate log;
extern crate rs_collector;
extern crate time;

use clap::{Arg, ArgMatches, App};
use log::SetLoggerError;
use std::env;
use std::error::Error;
use std::path::Path;

use rs_collector::config::Config;

static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static DEFAULT_CONFIG_FILE: &'static str = "/etc/rs-collector.conf";

fn main() {
    if init_logger().is_err() {
        exit_with_error("Could not initialize logger", -1);
    }

    let app = App::new("rs-collector")
        .version(VERSION)
        .arg(Arg::with_name("configfile")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Sets a custom config file")
            .takes_value(true))
        .arg(Arg::with_name("show-config")
            .long("show-config")
            .help("Prints config"));
    let cli_args = app.get_matches();

    let config: Config = match parse_args(&cli_args) {
        Ok(config) => config,
        Err(err) => {
            exit_with_error(&format!("Failed to parse configuration, because {}.", err), -2);
        }
    };
    // TODO a config must have been parsed; if not exit!
    if cli_args.is_present("show-config") {
        println!("config: {:?}", config);
    }

    run(&config);
}

fn init_logger() -> Result<(), SetLoggerError> {
    use log::{LogRecord, LogLevelFilter};
    use env_logger::LogBuilder;

    let format = |record: &LogRecord| {
        let t = time::now();
        format!("{},{:03} - {} - {} - {}:{}",
                time::strftime("%Y-%m-%d %H:%M:%S", &t).unwrap(),
                t.tm_nsec / 1000_000,
                record.level(),
                record.args(),
                record.location().file(),
                record.location().line(),
        )
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, LogLevelFilter::Info);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

fn parse_args(cli_args: &ArgMatches) -> Result<Config, Box<Error>> {
    let config_file_path = Path::new(cli_args.value_of("configfile").unwrap_or(DEFAULT_CONFIG_FILE));
    let config: Config = if config_file_path.exists() {
        let config = try!(Config::load_from_rs_collector_config(&config_file_path));
        config
    } else {
        Default::default()
    };

    Ok(config)
}

fn run(config: &Config) {
    let collectors = rs_collector::collectors::create_collectors(config);
    rs_collector::scheduler::run(collectors, config);
}

fn exit_with_error(msg: &str, exit_code: i32) -> ! {
    println!("{}", msg);
    std::process::exit(exit_code);
}

#[cfg(test)]
mod tests {
}
<|endoftext|>


<commit_before>mod error;

// My IP address providers
mod myip;

// DNS providers
mod dns;

// Configuration
mod config;

mod gandi;

mod xmlrpc;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate rustc_serialize;
extern crate regex;
extern crate hyper;

extern crate time;

extern crate xml;

use clap::{Arg, App};
use config::Config;
use dns::DNSProvider;
use dns::DNSProviderFactory;
use dns::Record;
use env_logger::LogBuilder;
use error::Result;
use log::{LogRecord, LogLevelFilter};
use myip::GetMyIpAddr;
use myip::IpProvider;
use std::process;

fn main() {
    let config = build_config();

    match main_with_errors(&config) {
        Ok(_) => info!("Process ends with success"),
        Err(err) => {
            error!("Process failed with result: {}", err);
            process::exit(-1);
        }
    }
}

fn build_config() -> Config {
    let matches = App::new("gdu")
        .version(&crate_version!()[..])
        .author("Damien Lecan <dev@dlecan.com>")
        .about("Generic DNS update, useful to update your dynamic IP address into your DNS provider zone file, e.g. Gandi or Go Daddy.\n\
            GDU detects if your ip address is IPv4 or v6 and and will create a record with type 'A' or 'AAAA' accordingly.\n\n\
            IP address can be read from several HTTP providers or from stdin.\n\
            Only Gandi DNS provider is implemented in this version.")
        .args_from_usage(
            "-a --apikey=<apikey> 'Your API key provided by Gandi'
            -d --domain=<domain> 'The domain name whose active zonefile will be updated, e.g. \"domain.com\"'
            -n --dry-run 'Dry run, don't really update Gandi zone file'
            -f --force 'Force new zonefile creation even if IP address isn\'t modified'
            -r --record-name=<record_name> 'Name of the A or AAAA record to update or create (without domain)'
            [verbose]... -v 'Verbose mode'")
        .arg(Arg::with_name("ip_provider")
            .help("IP address provider to use to get your own IP address.\n                                       \
                Available values for <ip-provider>:\n                                        \
                 ipify         : Ipify (IPv4)\n
                 opendns       : OpenDNS (IPv6)\n                                        \
                 -             : read IP address from stdin\n                                        \
                 sfrlaboxfibre : French 'SFR Labox Fibre' subscribers (IPv4)")
            .short("i")
            .long("ip-provider")
            .takes_value(true)
            .multiple(false)
            .required(true))
        .get_matches();

    // Init logger
    let format = |record: &LogRecord| {
        let t = time::now();
        format!("{},{:03} - {} - {}",
                time::strftime("%Y-%m-%d %H:%M:%S", &t).unwrap(),
                t.tm_nsec / 1000_000,
                record.level(),
                record.args())
    };

    // Init logging to DEBUG only if user requires it
    let log_level_filter = match matches.occurrences_of("verbose") {
        0 => LogLevelFilter::Info,
        1 => {
            println!("Verbose mode");
            LogLevelFilter::Debug
        }
        2 | _ => {
            println!("More verbose mode");
            LogLevelFilter::Trace
        }
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, log_level_filter);
    builder.init().unwrap();

    // Read parameters
    let apikey = matches.value_of("apikey").unwrap();
    debug!("Using apikey: {}", apikey);

    let domain = matches.value_of("domain").unwrap();
    debug!("Using domain: {}", domain);

    let record_name = matches.value_of("record-name").unwrap();
    debug!("Using record name: {}", record_name);

    let dry_run = matches.is_present("dry-run");
    debug!("Dry run: {}", dry_run);

    let force = matches.is_present("force");
    debug!("Force: {}", force);

    let ip_provider = value_t_or_exit!(matches.value_of("ip_provider"), IpProvider);
    debug!("IP address provider: {:?}", ip_provider);

    Config {
        apikey: apikey.to_owned(),
        domain: domain.to_owned(),
        record_name: record_name.to_owned(),
        force: force,
        ip_provider: ip_provider,
    }
}

fn main_with_errors(config: &Config) -> Result<()> {

    let my_ip = try!(config.ip_provider.get_my_ip_addr());

    info!("My IP address: {:?}", my_ip);

    let mut dns_provider = dns::DNSProviderFactory::build(config);

    match my_ip {
        std::net::IpAddr::V6(_) if !dns_provider.handle_ipv6_addr() => {
            panic!("You cannot use IP v6 addresses with the selected DNS provider")
        }
        _ => (),
    }

    let record = Record::new(&config.record_name, &my_ip);

    try!(dns_provider.init(&config.domain));

    let maybe_checked = try!(dns_provider.is_record_already_declared(&record));

    match maybe_checked {
        Some(ip_addr) => {
            debug!("Record already declared, with IP address: {}", &ip_addr);

            if !config.force && (&ip_addr == &my_ip) {
                info!("IP address not modified, no record to update");
                Ok(())
            } else {
                info!("Update record '{:?}' with IP address '{:?}'",
                      &record,
                      &my_ip);
                Ok(try!(dns_provider.update_record(&record, &my_ip)))
            }
        }
        None => Ok(try!(dns_provider.create_record(&record, &my_ip))),
    }
}
<commit_msg>Remove warnings<commit_after>mod error;

// My IP address providers
mod myip;

// DNS providers
mod dns;

// Configuration
mod config;

mod gandi;

mod xmlrpc;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate rustc_serialize;
extern crate regex;
extern crate hyper;

extern crate time;

extern crate xml;

use clap::{Arg, App};
use config::Config;
use dns::DNSProviderFactory;
use dns::Record;
use env_logger::LogBuilder;
use error::Result;
use log::{LogRecord, LogLevelFilter};
use myip::GetMyIpAddr;
use myip::IpProvider;
use std::process;

fn main() {
    let config = build_config();

    match main_with_errors(&config) {
        Ok(_) => info!("Process ends with success"),
        Err(err) => {
            error!("Process failed with result: {}", err);
            process::exit(-1);
        }
    }
}

fn build_config() -> Config {
    let matches = App::new("gdu")
        .version(&crate_version!()[..])
        .author("Damien Lecan <dev@dlecan.com>")
        .about("Generic DNS update, useful to update your dynamic IP address into your DNS provider zone file, e.g. Gandi or Go Daddy.\n\
            GDU detects if your ip address is IPv4 or v6 and and will create a record with type 'A' or 'AAAA' accordingly.\n\n\
            IP address can be read from several HTTP providers or from stdin.\n\
            Only Gandi DNS provider is implemented in this version.")
        .args_from_usage(
            "-a --apikey=<apikey> 'Your API key provided by Gandi'
            -d --domain=<domain> 'The domain name whose active zonefile will be updated, e.g. \"domain.com\"'
            -n --dry-run 'Dry run, don't really update Gandi zone file'
            -f --force 'Force new zonefile creation even if IP address isn\'t modified'
            -r --record-name=<record_name> 'Name of the A or AAAA record to update or create (without domain)'
            [verbose]... -v 'Verbose mode'")
        .arg(Arg::with_name("ip_provider")
            .help("IP address provider to use to get your own IP address.\n                                       \
                Available values for <ip-provider>:\n                                        \
                 ipify         : Ipify (IPv4)\n
                 opendns       : OpenDNS (IPv6)\n                                        \
                 -             : read IP address from stdin\n                                        \
                 sfrlaboxfibre : French 'SFR Labox Fibre' subscribers (IPv4)")
            .short("i")
            .long("ip-provider")
            .takes_value(true)
            .multiple(false)
            .required(true))
        .get_matches();

    // Init logger
    let format = |record: &LogRecord| {
        let t = time::now();
        format!("{},{:03} - {} - {}",
                time::strftime("%Y-%m-%d %H:%M:%S", &t).unwrap(),
                t.tm_nsec / 1000_000,
                record.level(),
                record.args())
    };

    // Init logging to DEBUG only if user requires it
    let log_level_filter = match matches.occurrences_of("verbose") {
        0 => LogLevelFilter::Info,
        1 => {
            println!("Verbose mode");
            LogLevelFilter::Debug
        }
        2 | _ => {
            println!("More verbose mode");
            LogLevelFilter::Trace
        }
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, log_level_filter);
    builder.init().unwrap();

    // Read parameters
    let apikey = matches.value_of("apikey").unwrap();
    debug!("Using apikey: {}", apikey);

    let domain = matches.value_of("domain").unwrap();
    debug!("Using domain: {}", domain);

    let record_name = matches.value_of("record-name").unwrap();
    debug!("Using record name: {}", record_name);

    let dry_run = matches.is_present("dry-run");
    debug!("Dry run: {}", dry_run);

    let force = matches.is_present("force");
    debug!("Force: {}", force);

    let ip_provider = value_t_or_exit!(matches.value_of("ip_provider"), IpProvider);
    debug!("IP address provider: {:?}", ip_provider);

    Config {
        apikey: apikey.to_owned(),
        domain: domain.to_owned(),
        record_name: record_name.to_owned(),
        force: force,
        ip_provider: ip_provider,
    }
}

fn main_with_errors(config: &Config) -> Result<()> {

    let my_ip = try!(config.ip_provider.get_my_ip_addr());

    info!("My IP address: {:?}", my_ip);

    let mut dns_provider = DNSProviderFactory::build(config);

    match my_ip {
        std::net::IpAddr::V6(_) if !dns_provider.handle_ipv6_addr() => {
            panic!("You cannot use IP v6 addresses with the selected DNS provider")
        }
        _ => (),
    }

    let record = Record::new(&config.record_name, &my_ip);

    try!(dns_provider.init(&config.domain));

    let maybe_checked = try!(dns_provider.is_record_already_declared(&record));

    match maybe_checked {
        Some(ip_addr) => {
            debug!("Record already declared, with IP address: {}", &ip_addr);

            if !config.force && (&ip_addr == &my_ip) {
                info!("IP address not modified, no record to update");
                Ok(())
            } else {
                info!("Update record '{:?}' with IP address '{:?}'",
                      &record,
                      &my_ip);
                Ok(try!(dns_provider.update_record(&record, &my_ip)))
            }
        }
        None => Ok(try!(dns_provider.create_record(&record, &my_ip))),
    }
}
<|endoftext|>


<commit_before><commit_msg>fix: Calculate hash over extended private key<commit_after><|endoftext|>


<commit_before>use std::net::{TcpListener, TcpStream};
use std::io::prelude::*;
use std::io;

fn main() {

    let listener = TcpListener::bind("127.0.0.1:8000").expect("failed to start server");

    fn read_request(stream: &TcpStream) -> String {
        let mut istream = stream.try_clone().expect("couldn't clone");
        let mut reader = io::BufReader::new(stream);
        let mut request = String::new();
        let mut l;
        for line in reader.lines() {
            l = line.unwrap();
            if l == "" {
                istream.flush();
                break;
            } else {
                request.push_str(&l);
                request.push_str("\n");
            }
        }
        println!("finished reading");
        request
    }

    fn handle_client(stream: TcpStream) {
        println!("Hello, world!");

        let mut ostream = stream.try_clone().expect("couldn't clone");
        let mut request = String::new();

        request = read_request(&stream);
        println!("{:?} - {:?}", request.len(), request);

        ostream.write_all(b"HTTP/1.0 200 OK\nContent-Type: text/html\n\nHello there!").expect("write failed");

        ostream.flush().expect("stream flushed");
    }

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                handle_client(stream);
            }
            Err(e) => println!("{:?}", e)
        }
    }
}
<commit_msg>1. Remove useless ostream 2. Remove unneccessary mutability<commit_after>use std::net::{TcpListener, TcpStream};
use std::io::prelude::*;
use std::io;

fn main() {

    let listener = TcpListener::bind("127.0.0.1:8000").expect("failed to start server");

    fn read_request(stream: &TcpStream) -> String {
        let mut istream = stream.try_clone().expect("couldn't clone");
        let reader = io::BufReader::new(stream);
        let mut request = String::new();
        let mut l;
        for line in reader.lines() {
            l = line.unwrap();
            if l == "" {
                istream.flush().expect("stream couldn't be flushed");
                break;
            } else {
                request.push_str(&l);
                request.push_str("\n");
            }
        }
        println!("finished reading");
        request
    }

    fn handle_client(mut stream: TcpStream) {
        println!("Hello, world!");

        let request;

        request = read_request(&stream);
        println!("{:?} - {:?}", request.len(), request);

        stream.write_all(b"HTTP/1.0 200 OK\nContent-Type: text/html\n\nHello there!").expect("write failed");

        stream.flush().expect("stream couldn't be flushed");
    }

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                handle_client(stream);
            }
            Err(e) => println!("{:?}", e)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>default to a case that uses 4623042 hashed states<commit_after><|endoftext|>


<commit_before><commit_msg>fixed small typo<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Log trace for now<commit_after><|endoftext|>