<commit_before>//! Window creation using glutin for gfx.
//!
//! # Examples
//!
//! The following code creates a `gfx::Surface` using glutin.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//!
//! fn main() {
//!     use gfx_backend_gl::Surface;
//!     use glutin::{EventsLoop, WindowBuilder, ContextBuilder, WindowedContext};
//!
//!     // First create a window using glutin.
//!     let mut events_loop = EventsLoop::new();
//!     let wb = WindowBuilder::new();
//!     let cb = ContextBuilder::new().with_vsync(true);
//!     let glutin_window = WindowedContext::new_windowed(wb, cb, &events_loop).unwrap();
//!
//!     // Then use the glutin window to create a gfx surface.
//!     let surface = Surface::from_window(glutin_window);
//! }
//! ```
//!
//! Headless initialization without a window.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//! extern crate gfx_hal;
//!
//! use gfx_hal::Instance;
//! use gfx_backend_gl::Headless;
//! use glutin::{Context, ContextBuilder, EventsLoop};
//!
//! fn main() {
//!     let events_loop = EventsLoop::new();
//!     let context = Context::new_headless(&events_loop, ContextBuilder::new(), glutin::dpi::PhysicalSize::new(0.0, 0.0))
//!         .expect("Failed to build headless context");
//!     let headless = Headless(context);
//!     let _adapters = headless.enumerate_adapters();
//! }
//! ```

use crate::hal::window::Extent2D;
use crate::hal::{self, format as f, image, memory, CompositeAlpha};
use crate::{native, Backend as B, Device, GlContainer, PhysicalDevice, QueueFamily, Starc};

use glow::Context;

use glutin;

fn get_window_extent(window: &glutin::WindowedContext) -> image::Extent {
    let px = window
        .get_inner_size()
        .unwrap()
        .to_physical(window.get_hidpi_factor());
    image::Extent {
        width: px.width as image::Size,
        height: px.height as image::Size,
        depth: 1,
    }
}

#[derive(Debug)]
pub struct Swapchain {
    // Underlying window, required for presentation
    pub(crate) window: Starc<glutin::WindowedContext>,
    // Extent because the window lies
    pub(crate) extent: Extent2D,
}

impl hal::Swapchain<B> for Swapchain {
    unsafe fn acquire_image(
        &mut self,
        _timeout_ns: u64,
        _semaphore: Option<&native::Semaphore>,
        _fence: Option<&native::Fence>,
    ) -> Result<(hal::SwapImageIndex, Option<hal::window::Suboptimal>), hal::AcquireError> {
        // TODO: sync
        Ok((0, None))
    }
}

//TODO: if we make `Surface` a `WindowBuilder` instead of `WindowedContext`,
// we could spawn window + GL context when a swapchain is requested
// and actually respect the swapchain configuration provided by the user.
#[derive(Debug)]
pub struct Surface {
    window: Starc<glutin::WindowedContext>,
}

impl Surface {
    pub fn from_window(window: glutin::WindowedContext) -> Self {
        Surface {
            window: Starc::new(window),
        }
    }

    pub fn get_window(&self) -> &glutin::WindowedContext {
        &*self.window
    }

    pub fn window(&self) -> &glutin::WindowedContext {
        &self.window
    }

    fn swapchain_formats(&self) -> Vec<f::Format> {
        let pixel_format = self.window.get_pixel_format();
        let color_bits = pixel_format.color_bits;
        let alpha_bits = pixel_format.alpha_bits;
        let srgb = pixel_format.srgb;

        // TODO: expose more formats
        match (color_bits, alpha_bits, srgb) {
            (24, 8, true) => vec![f::Format::Rgba8Srgb, f::Format::Bgra8Srgb],
            (24, 8, false) => vec![f::Format::Rgba8Unorm, f::Format::Bgra8Unorm],
            _ => vec![],
        }
    }
}

impl hal::Surface<B> for Surface {
    fn kind(&self) -> hal::image::Kind {
        let ex = get_window_extent(&self.window);
        let samples = self.window.get_pixel_format().multisampling.unwrap_or(1);
        hal::image::Kind::D2(ex.width, ex.height, 1, samples as _)
    }

    fn compatibility(
        &self,
        _: &PhysicalDevice,
    ) -> (
        hal::SurfaceCapabilities,
        Option<Vec<f::Format>>,
        Vec<hal::PresentMode>,
    ) {
        let ex = get_window_extent(&self.window);
        let extent = hal::window::Extent2D::from(ex);

        let caps = hal::SurfaceCapabilities {
            image_count: if self.window.get_pixel_format().double_buffer {
                2..3
            } else {
                1..2
            },
            current_extent: Some(extent),
            extents: extent..hal::window::Extent2D {
                width: ex.width + 1,
                height: ex.height + 1,
            },
            max_image_layers: 1,
            usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC,
            composite_alpha: CompositeAlpha::OPAQUE, //TODO
        };
        let present_modes = vec![
            hal::PresentMode::Fifo, //TODO
        ];

        (caps, Some(self.swapchain_formats()), present_modes)
    }

    fn supports_queue_family(&self, _: &QueueFamily) -> bool {
        true
    }
}

impl Device {
    pub(crate) fn create_swapchain_impl(
        &self,
        surface: &mut Surface,
        config: hal::SwapchainConfig,
    ) -> (Swapchain, Vec<native::Image>) {
        let swapchain = Swapchain {
            extent: config.extent,
            window: surface.window.clone(),
        };

        let gl = &self.share.context;

        let (int_format, iformat, itype) = match config.format {
            f::Format::Rgba8Unorm => (glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE),
            f::Format::Bgra8Unorm => (glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE),
            f::Format::Rgba8Srgb => (glow::SRGB8_ALPHA8, glow::RGBA, glow::UNSIGNED_BYTE),
            _ => unimplemented!(),
        };

        let channel = config.format.base_format().1;

        let images = (0..config.image_count)
            .map(|_| unsafe {
                let image = if config.image_layers > 1
                    || config.image_usage.contains(image::Usage::STORAGE)
                    || config.image_usage.contains(image::Usage::SAMPLED)
                {
                    let name = gl.create_texture().unwrap();
                    match config.extent {
                        Extent2D {
                            width: w,
                            height: h,
                        } => {
                            gl.bind_texture(glow::TEXTURE_2D, Some(name));
                            if self.share.private_caps.image_storage {
                                gl.tex_storage_2d(
                                    glow::TEXTURE_2D,
                                    config.image_layers as _,
                                    int_format,
                                    w as _,
                                    h as _,
                                );
                            } else {
                                gl.tex_parameter_i32(
                                    glow::TEXTURE_2D,
                                    glow::TEXTURE_MAX_LEVEL,
                                    (config.image_layers - 1) as _,
                                );
                                let mut w = w;
                                let mut h = h;
                                for i in 0..config.image_layers {
                                    gl.tex_image_2d(
                                        glow::TEXTURE_2D,
                                        i as _,
                                        int_format as _,
                                        w as _,
                                        h as _,
                                        0,
                                        iformat,
                                        itype,
                                        None,
                                    );
                                    w = std::cmp::max(w / 2, 1);
                                    h = std::cmp::max(h / 2, 1);
                                }
                            }
                        }
                    };
                    native::ImageKind::Texture(name, glow::TEXTURE_2D)
                } else {
                    let name = gl.create_renderbuffer().unwrap();
                    match config.extent {
                        Extent2D {
                            width: w,
                            height: h,
                        } => {
                            gl.bind_renderbuffer(glow::RENDERBUFFER, Some(name));
                            gl.renderbuffer_storage(glow::RENDERBUFFER, int_format, w as _, h as _);
                        }
                    };
                    native::ImageKind::Surface(name)
                };

                let surface_desc = config.format.base_format().0.desc();
                let bytes_per_texel = surface_desc.bits / 8;
                let ext = config.extent;
                let size = (ext.width * ext.height) as u64 * bytes_per_texel as u64;

                if let Err(err) = self.share.check() {
                    panic!(
                        "Error creating swapchain image: {:?} with {:?} format",
                        err, config.format
                    );
                }

                native::Image {
                    kind: image,
                    channel,
                    requirements: memory::Requirements {
                        size,
                        alignment: 1,
                        type_mask: 0x7,
                    },
                }
            })
            .collect::<Vec<_>>();

        (swapchain, images)
    }
}

impl hal::Instance for Surface {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.window.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(GlContainer::from_fn_proc(
            |s| self.window.get_proc_address(s) as *const _
        ));
        vec![adapter]
    }
}

pub fn config_context(
    builder: glutin::ContextBuilder,
    color_format: f::Format,
    ds_format: Option<f::Format>,
) -> glutin::ContextBuilder {
    let color_base = color_format.base_format();
    let color_bits = color_base.0.describe_bits();
    let depth_bits = match ds_format {
        Some(fm) => fm.base_format().0.describe_bits(),
        None => f::BITS_ZERO,
    };
    builder
        .with_depth_buffer(depth_bits.depth)
        .with_stencil_buffer(depth_bits.stencil)
        .with_pixel_format(color_bits.color, color_bits.alpha)
        .with_srgb(color_base.1 == f::ChannelType::Srgb)
}

pub struct Headless(pub glutin::Context);

unsafe impl Send for Headless {}
unsafe impl Sync for Headless {}

impl hal::Instance for Headless {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.0.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(GlContainer::from_fn_proc(
            |s| self.0.get_proc_address(s) as *const _
        ));
        vec![adapter]
    }
}
<commit_msg>Start Working w/ Currency System<commit_after>//! Window creation using glutin for gfx.
//!
//! # Examples
//!
//! The following code creates a `gfx::Surface` using glutin.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//!
//! fn main() {
//!     use gfx_backend_gl::Surface;
//!     use glutin::{EventsLoop, WindowBuilder, ContextBuilder, WindowedContext};
//!
//!     // First create a window using glutin.
//!     let mut events_loop = EventsLoop::new();
//!     let wb = WindowBuilder::new();
//!     let cb = ContextBuilder::new().with_vsync(true);
//!     let glutin_window = WindowedContext::new_windowed(wb, cb, &events_loop).unwrap();
//!
//!     // Then use the glutin window to create a gfx surface.
//!     let surface = Surface::from_window(glutin_window);
//! }
//! ```
//!
//! Headless initialization without a window.
//!
//! ```no_run
//! extern crate glutin;
//! extern crate gfx_backend_gl;
//! extern crate gfx_hal;
//!
//! use gfx_hal::Instance;
//! use gfx_backend_gl::Headless;
//! use glutin::{Context, ContextBuilder, EventsLoop};
//!
//! fn main() {
//!     let events_loop = EventsLoop::new();
//!     let context = Context::new_headless(&events_loop, ContextBuilder::new(), glutin::dpi::PhysicalSize::new(0.0, 0.0))
//!         .expect("Failed to build headless context");
//!     let headless = Headless(context);
//!     let _adapters = headless.enumerate_adapters();
//! }
//! ```

use crate::hal::window::Extent2D;
use crate::hal::{self, format as f, image, memory, CompositeAlpha};
use crate::{native, Backend as B, Device, GlContainer, PhysicalDevice, QueueFamily, Starc};

use glow::Context;

use glutin;

fn get_window_extent<C>(context: &glutin::WindowedContext<C>) -> image::Extent
where
    C: glutin::ContextCurrentState,
{
    let window = context.window();
    let px = window
        .get_inner_size()
        .unwrap()
        .to_physical(window.get_hidpi_factor());
    image::Extent {
        width: px.width as image::Size,
        height: px.height as image::Size,
        depth: 1,
    }
}

#[derive(Debug)]
pub struct Swapchain {
    // Underlying window, required for presentation
    pub(crate) window: Starc<glutin::WindowedContext<glutin::PossiblyCurrent>>,
    // Extent because the window lies
    pub(crate) extent: Extent2D,
}

impl hal::Swapchain<B> for Swapchain {
    unsafe fn acquire_image(
        &mut self,
        _timeout_ns: u64,
        _semaphore: Option<&native::Semaphore>,
        _fence: Option<&native::Fence>,
    ) -> Result<(hal::SwapImageIndex, Option<hal::window::Suboptimal>), hal::AcquireError> {
        // TODO: sync
        Ok((0, None))
    }
}

//TODO: if we make `Surface` a `WindowBuilder` instead of `WindowedContext`,
// we could spawn window + GL context when a swapchain is requested
// and actually respect the swapchain configuration provided by the user.
#[derive(Debug)]
pub struct Surface {
    window: Starc<glutin::WindowedContext<glutin::PossiblyCurrent>>,
}

impl Surface {
    pub fn from_window(window: glutin::WindowedContext<glutin::PossiblyCurrent>) -> Self {
        Surface {
            window: Starc::new(window),
        }
    }

    pub fn get_window(&self) -> &glutin::WindowedContext<glutin::PossiblyCurrent> {
        &*self.window
    }

    pub fn window(&self) -> &glutin::WindowedContext<glutin::PossiblyCurrent> {
        &self.window
    }

    fn swapchain_formats(&self) -> Vec<f::Format> {
        let pixel_format = self.window.get_pixel_format();
        let color_bits = pixel_format.color_bits;
        let alpha_bits = pixel_format.alpha_bits;
        let srgb = pixel_format.srgb;

        // TODO: expose more formats
        match (color_bits, alpha_bits, srgb) {
            (24, 8, true) => vec![f::Format::Rgba8Srgb, f::Format::Bgra8Srgb],
            (24, 8, false) => vec![f::Format::Rgba8Unorm, f::Format::Bgra8Unorm],
            _ => vec![],
        }
    }
}

impl hal::Surface<B> for Surface {
    fn kind(&self) -> hal::image::Kind {
        let ex = get_window_extent(&self.window);
        let samples = self.window.get_pixel_format().multisampling.unwrap_or(1);
        hal::image::Kind::D2(ex.width, ex.height, 1, samples as _)
    }

    fn compatibility(
        &self,
        _: &PhysicalDevice,
    ) -> (
        hal::SurfaceCapabilities,
        Option<Vec<f::Format>>,
        Vec<hal::PresentMode>,
    ) {
        let ex = get_window_extent(&self.window);
        let extent = hal::window::Extent2D::from(ex);

        let caps = hal::SurfaceCapabilities {
            image_count: if self.window.get_pixel_format().double_buffer {
                2..3
            } else {
                1..2
            },
            current_extent: Some(extent),
            extents: extent..hal::window::Extent2D {
                width: ex.width + 1,
                height: ex.height + 1,
            },
            max_image_layers: 1,
            usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC,
            composite_alpha: CompositeAlpha::OPAQUE, //TODO
        };
        let present_modes = vec![
            hal::PresentMode::Fifo, //TODO
        ];

        (caps, Some(self.swapchain_formats()), present_modes)
    }

    fn supports_queue_family(&self, _: &QueueFamily) -> bool {
        true
    }
}

impl Device {
    pub(crate) fn create_swapchain_impl(
        &self,
        surface: &mut Surface,
        config: hal::SwapchainConfig,
    ) -> (Swapchain, Vec<native::Image>) {
        let swapchain = Swapchain {
            extent: config.extent,
            window: surface.window.clone(),
        };

        let gl = &self.share.context;

        let (int_format, iformat, itype) = match config.format {
            f::Format::Rgba8Unorm => (glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE),
            f::Format::Bgra8Unorm => (glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE),
            f::Format::Rgba8Srgb => (glow::SRGB8_ALPHA8, glow::RGBA, glow::UNSIGNED_BYTE),
            _ => unimplemented!(),
        };

        let channel = config.format.base_format().1;

        let images = (0..config.image_count)
            .map(|_| unsafe {
                let image = if config.image_layers > 1
                    || config.image_usage.contains(image::Usage::STORAGE)
                    || config.image_usage.contains(image::Usage::SAMPLED)
                {
                    let name = gl.create_texture().unwrap();
                    match config.extent {
                        Extent2D {
                            width: w,
                            height: h,
                        } => {
                            gl.bind_texture(glow::TEXTURE_2D, Some(name));
                            if self.share.private_caps.image_storage {
                                gl.tex_storage_2d(
                                    glow::TEXTURE_2D,
                                    config.image_layers as _,
                                    int_format,
                                    w as _,
                                    h as _,
                                );
                            } else {
                                gl.tex_parameter_i32(
                                    glow::TEXTURE_2D,
                                    glow::TEXTURE_MAX_LEVEL,
                                    (config.image_layers - 1) as _,
                                );
                                let mut w = w;
                                let mut h = h;
                                for i in 0..config.image_layers {
                                    gl.tex_image_2d(
                                        glow::TEXTURE_2D,
                                        i as _,
                                        int_format as _,
                                        w as _,
                                        h as _,
                                        0,
                                        iformat,
                                        itype,
                                        None,
                                    );
                                    w = std::cmp::max(w / 2, 1);
                                    h = std::cmp::max(h / 2, 1);
                                }
                            }
                        }
                    };
                    native::ImageKind::Texture(name, glow::TEXTURE_2D)
                } else {
                    let name = gl.create_renderbuffer().unwrap();
                    match config.extent {
                        Extent2D {
                            width: w,
                            height: h,
                        } => {
                            gl.bind_renderbuffer(glow::RENDERBUFFER, Some(name));
                            gl.renderbuffer_storage(glow::RENDERBUFFER, int_format, w as _, h as _);
                        }
                    };
                    native::ImageKind::Surface(name)
                };

                let surface_desc = config.format.base_format().0.desc();
                let bytes_per_texel = surface_desc.bits / 8;
                let ext = config.extent;
                let size = (ext.width * ext.height) as u64 * bytes_per_texel as u64;

                if let Err(err) = self.share.check() {
                    panic!(
                        "Error creating swapchain image: {:?} with {:?} format",
                        err, config.format
                    );
                }

                native::Image {
                    kind: image,
                    channel,
                    requirements: memory::Requirements {
                        size,
                        alignment: 1,
                        type_mask: 0x7,
                    },
                }
            })
            .collect::<Vec<_>>();

        (swapchain, images)
    }
}

impl hal::Instance for Surface {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.window.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(GlContainer::from_fn_proc(|s| {
            self.window.get_proc_address(s) as *const _
        }));
        vec![adapter]
    }
}

pub fn config_context<C>(
    builder: glutin::ContextBuilder<C>,
    color_format: f::Format,
    ds_format: Option<f::Format>,
) -> glutin::ContextBuilder<C>
where
    C: glutin::ContextCurrentState,
{
    let color_base = color_format.base_format();
    let color_bits = color_base.0.describe_bits();
    let depth_bits = match ds_format {
        Some(fm) => fm.base_format().0.describe_bits(),
        None => f::BITS_ZERO,
    };
    builder
        .with_depth_buffer(depth_bits.depth)
        .with_stencil_buffer(depth_bits.stencil)
        .with_pixel_format(color_bits.color, color_bits.alpha)
        .with_srgb(color_base.1 == f::ChannelType::Srgb)
}

pub struct Headless(pub glutin::Context<glutin::PossiblyCurrent>);

unsafe impl Send for Headless {}
unsafe impl Sync for Headless {}

impl hal::Instance for Headless {
    type Backend = B;
    fn enumerate_adapters(&self) -> Vec<hal::Adapter<B>> {
        unsafe { self.0.make_current().unwrap() };
        let adapter = PhysicalDevice::new_adapter(GlContainer::from_fn_proc(|s| {
            self.0.get_proc_address(s) as *const _
        }));
        vec![adapter]
    }
}
<|endoftext|>


<commit_before>use super::Mode;
use super::KeyMap;
use super::Key;
use super::Command;
use super::KeyMapState;
use super::Direction;
use super::WordEdgeMatch;
use super::OverlayType;

use command;

/// NormalMode mimics Vi's Normal mode.
pub struct NormalMode {
    keymap: KeyMap<Command>,
    builder: command::Builder,
}

impl NormalMode {

    /// Create a new instance of NormalMode
    pub fn new() -> NormalMode {
        NormalMode {
            keymap: NormalMode::key_defaults(),
            builder: command::Builder::new(),
        }
    }

    /// Creates a KeyMap with default NormalMode key bindings
    fn key_defaults() -> KeyMap<Command> {
        let mut keymap = KeyMap::new();

        // movement
        keymap.bind_key(Key::Up, Command::MoveCursor(Direction::Up, 1));
        keymap.bind_key(Key::Down, Command::MoveCursor(Direction::Down, 1));
        keymap.bind_key(Key::Left, Command::MoveCursor(Direction::Left, 1));
        keymap.bind_key(Key::Right, Command::MoveCursor(Direction::Right, 1));
        keymap.bind_key(Key::Char('h'), Command::MoveCursor(Direction::Left, 1));
        keymap.bind_key(Key::Char('j'), Command::MoveCursor(Direction::Down, 1));
        keymap.bind_key(Key::Char('k'), Command::MoveCursor(Direction::Up, 1));
        keymap.bind_key(Key::Char('l'), Command::MoveCursor(Direction::Right, 1));
        keymap.bind_key(Key::Char('W'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('B'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('w'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('b'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('G'), Command::MoveCursor(Direction::LastLine, 0));
        keymap.bind_keys(&[Key::Char('g'), Key::Char('g')], Command::MoveCursor(Direction::FirstLine, 0));

        keymap.bind_key(Key::Char('0'), Command::LineStart);
        keymap.bind_key(Key::Char('$'), Command::LineEnd);

        // editing
        keymap.bind_keys(&[Key::Char('d'), Key::Char('W')], Command::Delete(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('B')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('w')], Command::Delete(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('b')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('x'), Command::Delete(Direction::Right, 1));
        keymap.bind_key(Key::Char('X'), Command::Delete(Direction::Left, 1));
        keymap.bind_key(Key::Char('u'), Command::Undo);
        keymap.bind_key(Key::Ctrl('r'), Command::Redo);

        // open a prompt to the user
        keymap.bind_key(Key::Char(':'), Command::SetOverlay(OverlayType::Prompt));

        keymap
    }

}

impl Mode for NormalMode {
    /// Given a key, pass it through the NormalMode KeyMap and return the associated Command, if any.
    fn handle_key_event(&mut self, key: Key) -> command::BuilderEvent {
        self.builder.check_key(key)
    }
}

#[cfg(test)]
mod tests {
    use editor::Command;
    use buffer::Direction;
    use keyboard::Key;
    use modes::Mode;
    use super::*;

    fn expect_key_command(k: Key, c: Command) {
        let mut mode: Box<Mode> = Box::new(NormalMode::new());
        let command = mode.handle_key_event(k);
        assert_eq!(command, c)
    }

    #[test]
    fn test_movement_keybindings() {
        expect_key_command(Key::Char('h'), Command::MoveCursor(Direction::Left, 1));
        expect_key_command(Key::Char('j'), Command::MoveCursor(Direction::Down, 1));
        expect_key_command(Key::Char('k'), Command::MoveCursor(Direction::Up, 1));
        expect_key_command(Key::Char('l'), Command::MoveCursor(Direction::Right, 1));
    }
}
<commit_msg>Remove obsolete tests<commit_after>use super::Mode;
use super::KeyMap;
use super::Key;
use super::Command;
use super::KeyMapState;
use super::Direction;
use super::WordEdgeMatch;
use super::OverlayType;

use command;

/// NormalMode mimics Vi's Normal mode.
pub struct NormalMode {
    keymap: KeyMap<Command>,
    builder: command::Builder,
}

impl NormalMode {

    /// Create a new instance of NormalMode
    pub fn new() -> NormalMode {
        NormalMode {
            keymap: NormalMode::key_defaults(),
            builder: command::Builder::new(),
        }
    }

    /// Creates a KeyMap with default NormalMode key bindings
    fn key_defaults() -> KeyMap<Command> {
        let mut keymap = KeyMap::new();

        // movement
        keymap.bind_key(Key::Up, Command::MoveCursor(Direction::Up, 1));
        keymap.bind_key(Key::Down, Command::MoveCursor(Direction::Down, 1));
        keymap.bind_key(Key::Left, Command::MoveCursor(Direction::Left, 1));
        keymap.bind_key(Key::Right, Command::MoveCursor(Direction::Right, 1));
        keymap.bind_key(Key::Char('h'), Command::MoveCursor(Direction::Left, 1));
        keymap.bind_key(Key::Char('j'), Command::MoveCursor(Direction::Down, 1));
        keymap.bind_key(Key::Char('k'), Command::MoveCursor(Direction::Up, 1));
        keymap.bind_key(Key::Char('l'), Command::MoveCursor(Direction::Right, 1));
        keymap.bind_key(Key::Char('W'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('B'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_key(Key::Char('w'), Command::MoveCursor(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('b'), Command::MoveCursor(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('G'), Command::MoveCursor(Direction::LastLine, 0));
        keymap.bind_keys(&[Key::Char('g'), Key::Char('g')], Command::MoveCursor(Direction::FirstLine, 0));

        keymap.bind_key(Key::Char('0'), Command::LineStart);
        keymap.bind_key(Key::Char('$'), Command::LineEnd);

        // editing
        keymap.bind_keys(&[Key::Char('d'), Key::Char('W')], Command::Delete(Direction::RightWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('B')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Whitespace), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('w')], Command::Delete(Direction::RightWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_keys(&[Key::Char('d'), Key::Char('b')], Command::Delete(Direction::LeftWord(WordEdgeMatch::Alphabet), 1));
        keymap.bind_key(Key::Char('x'), Command::Delete(Direction::Right, 1));
        keymap.bind_key(Key::Char('X'), Command::Delete(Direction::Left, 1));
        keymap.bind_key(Key::Char('u'), Command::Undo);
        keymap.bind_key(Key::Ctrl('r'), Command::Redo);

        // open a prompt to the user
        keymap.bind_key(Key::Char(':'), Command::SetOverlay(OverlayType::Prompt));

        keymap
    }

}

impl Mode for NormalMode {
    /// Given a key, pass it through the NormalMode KeyMap and return the associated Command, if any.
    fn handle_key_event(&mut self, key: Key) -> command::BuilderEvent {
        self.builder.check_key(key)
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).

use std;
use std::convert::TryInto;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;

use tokio::runtime::Runtime;

use futures::Future;

use crate::core::{Failure, TypeId};
use crate::handles::maybe_drop_handles;
use crate::nodes::{NodeKey, WrappedNode};
use crate::scheduler::Session;
use crate::tasks::{Rule, Tasks};
use crate::types::Types;
use boxfuture::{BoxFuture, Boxable};
use core::clone::Clone;
use fs::{safe_create_dir_all_ioerror, PosixFS};
use graph::{EntryId, Graph, NodeContext};
use parking_lot::RwLock;
use process_execution::{self, BoundedCommandRunner};
use rand::seq::SliceRandom;
use reqwest;
use rule_graph::RuleGraph;
use std::collections::btree_map::BTreeMap;
use store::Store;

///
/// The core context shared (via Arc) between the Scheduler and the Context objects of
/// all running Nodes.
///
/// Over time, most usage of `ResettablePool` (which wraps use of blocking APIs) should migrate
/// to the Tokio `Runtime`. The next candidate is likely to be migrating PosixFS to tokio-fs once
/// https://github.com/tokio-rs/tokio/issues/369 is resolved.
///
pub struct Core {
  pub graph: Graph<NodeKey>,
  pub tasks: Tasks,
  pub rule_graph: RuleGraph<Rule>,
  pub types: Types,
  runtime: Arc<RwLock<Runtime>>,
  store: Store,
  pub command_runner: BoundedCommandRunner,
  pub http_client: reqwest::r#async::Client,
  pub vfs: PosixFS,
  pub build_root: PathBuf,
}

impl Core {
  pub fn new(
    root_subject_types: Vec<TypeId>,
    tasks: Tasks,
    types: Types,
    build_root: PathBuf,
    ignore_patterns: &[String],
    work_dir: PathBuf,
    local_store_dir: PathBuf,
    remote_execution: bool,
    remote_store_servers: Vec<String>,
    remote_execution_server: Option<String>,
    remote_execution_process_cache_namespace: Option<String>,
    remote_instance_name: Option<String>,
    remote_root_ca_certs_path: Option<PathBuf>,
    remote_oauth_bearer_token_path: Option<PathBuf>,
    remote_store_thread_count: usize,
    remote_store_chunk_bytes: usize,
    remote_store_chunk_upload_timeout: Duration,
    remote_store_rpc_retries: usize,
    remote_execution_extra_platform_properties: BTreeMap<String, String>,
    process_execution_local_parallelism: usize,
    process_execution_remote_parallelism: usize,
    process_execution_cleanup_local_dirs: bool,
  ) -> Core {
    // Randomize CAS address order to avoid thundering herds from common config.
    let mut remote_store_servers = remote_store_servers;
    remote_store_servers.shuffle(&mut rand::thread_rng());

    let runtime =
      Arc::new(RwLock::new(Runtime::new().unwrap_or_else(|e| {
        panic!("Could not initialize Runtime: {:?}", e)
      })));
    // We re-use these certs for both the execution and store service; they're generally tied together.
    let root_ca_certs = if let Some(path) = remote_root_ca_certs_path {
      Some(
        std::fs::read(&path)
          .unwrap_or_else(|err| panic!("Error reading root CA certs file {:?}: {}", path, err)),
      )
    } else {
      None
    };

    // We re-use this token for both the execution and store service; they're generally tied together.
    let oauth_bearer_token = if let Some(path) = remote_oauth_bearer_token_path {
      Some(
        std::fs::read_to_string(&path)
          .unwrap_or_else(|err| panic!("Error reading root CA certs file {:?}: {}", path, err)),
      )
    } else {
      None
    };

    let local_store_dir = local_store_dir.clone();
    let store = safe_create_dir_all_ioerror(&local_store_dir)
      .map_err(|e| format!("Error making directory {:?}: {:?}", local_store_dir, e))
      .and_then(|()| {
        if remote_store_servers.is_empty() {
          Store::local_only(local_store_dir)
        } else {
          Store::with_remote(
            local_store_dir,
            &remote_store_servers,
            remote_instance_name.clone(),
            &root_ca_certs,
            oauth_bearer_token.clone(),
            remote_store_thread_count,
            remote_store_chunk_bytes,
            remote_store_chunk_upload_timeout,
            // TODO: Take a parameter
            store::BackoffConfig::new(Duration::from_millis(10), 1.0, Duration::from_millis(10))
              .unwrap(),
            remote_store_rpc_retries,
          )
        }
      })
      .unwrap_or_else(|e| panic!("Could not initialize Store: {:?}", e));

    let command_runner = match &remote_execution_server {
      Some(ref address) if remote_execution => BoundedCommandRunner::new(
        Box::new(process_execution::remote::CommandRunner::new(
          address,
          remote_execution_process_cache_namespace.clone(),
          remote_instance_name.clone(),
          root_ca_certs.clone(),
          oauth_bearer_token.clone(),
          remote_execution_extra_platform_properties.clone(),
          store.clone(),
        )),
        process_execution_remote_parallelism,
      ),
      _ => BoundedCommandRunner::new(
        Box::new(process_execution::local::CommandRunner::new(
          store.clone(),
          work_dir.clone(),
          process_execution_cleanup_local_dirs,
        )),
        process_execution_local_parallelism,
      ),
    };

    let http_client = reqwest::r#async::Client::new();
    let rule_graph = RuleGraph::new(tasks.as_map(), root_subject_types);

    Core {
      graph: Graph::new(),
      tasks: tasks,
      rule_graph: rule_graph,
      types: types,
      runtime: runtime,
      store,
      command_runner,
      http_client,
      // TODO: Errors in initialization should definitely be exposed as python
      // exceptions, rather than as panics.
      vfs: PosixFS::new(&build_root, &ignore_patterns).unwrap_or_else(|e| {
        panic!("Could not initialize VFS: {:?}", e);
      }),
      build_root: build_root,
    }
  }

  pub fn store(&self) -> Store {
    self.store.clone()
  }

  ///
  /// Start running a Future on a tokio Runtime.
  ///
  pub fn spawn<F: Future<Item = (), Error = ()> + Send + 'static>(&self, future: F) {
    // Make sure to copy our (thread-local) logging destination into the task.
    // When a daemon thread kicks off a future, it should log like a daemon thread (and similarly
    // for a user-facing thread).
    let logging_destination = logging::get_destination();
    self
      .runtime
      .read()
      .executor()
      .spawn(futures::future::ok(()).and_then(move |()| {
        logging::set_destination(logging_destination);
        future
      }))
  }

  ///
  /// Run a Future and return its resolved Result.
  ///
  /// This should never be called from in a Future context, or any context where anyone may want to
  /// spawn something on the runtime using Core::spawn.
  ///
  pub fn block_on<
    Item: Send + 'static,
    Error: Send + 'static,
    F: Future<Item = Item, Error = Error> + Send + 'static,
  >(
    &self,
    future: F,
  ) -> Result<Item, Error> {
    // Make sure to copy our (thread-local) logging destination into the task.
    // When a daemon thread kicks off a future, it should log like a daemon thread (and similarly
    // for a user-facing thread).
    let logging_destination = logging::get_destination();
    self
      .runtime
      .write()
      .block_on(futures::future::ok(()).and_then(move |()| {
        logging::set_destination(logging_destination);
        future
      }))
  }
}

#[derive(Clone)]
pub struct Context {
  pub entry_id: EntryId,
  pub core: Arc<Core>,
  pub session: Session,
}

impl Context {
  pub fn new(entry_id: EntryId, core: Arc<Core>, session: Session) -> Context {
    Context {
      entry_id: entry_id,
      core: core,
      session: session,
    }
  }

  ///
  /// Get the future value for the given Node implementation.
  ///
  pub fn get<N: WrappedNode>(&self, node: N) -> BoxFuture<N::Item, Failure> {
    // TODO: Odd place for this... could do it periodically in the background?
    maybe_drop_handles();
    self
      .core
      .graph
      .get(self.entry_id, self, node.into())
      .map(|node_result| {
        node_result
          .try_into()
          .unwrap_or_else(|_| panic!("A Node implementation was ambiguous."))
      })
      .to_boxed()
  }
}

impl NodeContext for Context {
  type Node = NodeKey;

  ///
  /// Clones this Context for a new EntryId. Because the Core of the context is an Arc, this
  /// is a shallow clone.
  ///
  fn clone_for(&self, entry_id: EntryId) -> Context {
    Context {
      entry_id: entry_id,
      core: self.core.clone(),
      session: self.session.clone(),
    }
  }

  fn graph(&self) -> &Graph<NodeKey> {
    &self.core.graph
  }

  fn spawn<F>(&self, future: F)
  where
    F: Future<Item = (), Error = ()> + Send + 'static,
  {
    self.core.runtime.read().executor().spawn(future);
  }
}
<commit_msg>Don't use remote store when --no-remote-execution specified (#8010)<commit_after>// Copyright 2017 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).

use std;
use std::convert::TryInto;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;

use tokio::runtime::Runtime;

use futures::Future;

use crate::core::{Failure, TypeId};
use crate::handles::maybe_drop_handles;
use crate::nodes::{NodeKey, WrappedNode};
use crate::scheduler::Session;
use crate::tasks::{Rule, Tasks};
use crate::types::Types;
use boxfuture::{BoxFuture, Boxable};
use core::clone::Clone;
use fs::{safe_create_dir_all_ioerror, PosixFS};
use graph::{EntryId, Graph, NodeContext};
use parking_lot::RwLock;
use process_execution::{self, BoundedCommandRunner};
use rand::seq::SliceRandom;
use reqwest;
use rule_graph::RuleGraph;
use std::collections::btree_map::BTreeMap;
use store::Store;

///
/// The core context shared (via Arc) between the Scheduler and the Context objects of
/// all running Nodes.
///
/// Over time, most usage of `ResettablePool` (which wraps use of blocking APIs) should migrate
/// to the Tokio `Runtime`. The next candidate is likely to be migrating PosixFS to tokio-fs once
/// https://github.com/tokio-rs/tokio/issues/369 is resolved.
///
pub struct Core {
  pub graph: Graph<NodeKey>,
  pub tasks: Tasks,
  pub rule_graph: RuleGraph<Rule>,
  pub types: Types,
  runtime: Arc<RwLock<Runtime>>,
  store: Store,
  pub command_runner: BoundedCommandRunner,
  pub http_client: reqwest::r#async::Client,
  pub vfs: PosixFS,
  pub build_root: PathBuf,
}

impl Core {
  pub fn new(
    root_subject_types: Vec<TypeId>,
    tasks: Tasks,
    types: Types,
    build_root: PathBuf,
    ignore_patterns: &[String],
    work_dir: PathBuf,
    local_store_dir: PathBuf,
    remote_execution: bool,
    remote_store_servers: Vec<String>,
    remote_execution_server: Option<String>,
    remote_execution_process_cache_namespace: Option<String>,
    remote_instance_name: Option<String>,
    remote_root_ca_certs_path: Option<PathBuf>,
    remote_oauth_bearer_token_path: Option<PathBuf>,
    remote_store_thread_count: usize,
    remote_store_chunk_bytes: usize,
    remote_store_chunk_upload_timeout: Duration,
    remote_store_rpc_retries: usize,
    remote_execution_extra_platform_properties: BTreeMap<String, String>,
    process_execution_local_parallelism: usize,
    process_execution_remote_parallelism: usize,
    process_execution_cleanup_local_dirs: bool,
  ) -> Core {
    // Randomize CAS address order to avoid thundering herds from common config.
    let mut remote_store_servers = remote_store_servers;
    remote_store_servers.shuffle(&mut rand::thread_rng());

    let runtime =
      Arc::new(RwLock::new(Runtime::new().unwrap_or_else(|e| {
        panic!("Could not initialize Runtime: {:?}", e)
      })));
    // We re-use these certs for both the execution and store service; they're generally tied together.
    let root_ca_certs = if let Some(path) = remote_root_ca_certs_path {
      Some(
        std::fs::read(&path)
          .unwrap_or_else(|err| panic!("Error reading root CA certs file {:?}: {}", path, err)),
      )
    } else {
      None
    };

    // We re-use this token for both the execution and store service; they're generally tied together.
    let oauth_bearer_token = if let Some(path) = remote_oauth_bearer_token_path {
      Some(
        std::fs::read_to_string(&path)
          .unwrap_or_else(|err| panic!("Error reading root CA certs file {:?}: {}", path, err)),
      )
    } else {
      None
    };

    let local_store_dir = local_store_dir.clone();
    let store = safe_create_dir_all_ioerror(&local_store_dir)
      .map_err(|e| format!("Error making directory {:?}: {:?}", local_store_dir, e))
      .and_then(|()| {
        if !remote_execution || remote_store_servers.is_empty() {
          Store::local_only(local_store_dir)
        } else {
          Store::with_remote(
            local_store_dir,
            &remote_store_servers,
            remote_instance_name.clone(),
            &root_ca_certs,
            oauth_bearer_token.clone(),
            remote_store_thread_count,
            remote_store_chunk_bytes,
            remote_store_chunk_upload_timeout,
            // TODO: Take a parameter
            store::BackoffConfig::new(Duration::from_millis(10), 1.0, Duration::from_millis(10))
              .unwrap(),
            remote_store_rpc_retries,
          )
        }
      })
      .unwrap_or_else(|e| panic!("Could not initialize Store: {:?}", e));

    let command_runner = match &remote_execution_server {
      Some(ref address) if remote_execution => BoundedCommandRunner::new(
        Box::new(process_execution::remote::CommandRunner::new(
          address,
          remote_execution_process_cache_namespace.clone(),
          remote_instance_name.clone(),
          root_ca_certs.clone(),
          oauth_bearer_token.clone(),
          remote_execution_extra_platform_properties.clone(),
          store.clone(),
        )),
        process_execution_remote_parallelism,
      ),
      _ => BoundedCommandRunner::new(
        Box::new(process_execution::local::CommandRunner::new(
          store.clone(),
          work_dir.clone(),
          process_execution_cleanup_local_dirs,
        )),
        process_execution_local_parallelism,
      ),
    };

    let http_client = reqwest::r#async::Client::new();
    let rule_graph = RuleGraph::new(tasks.as_map(), root_subject_types);

    Core {
      graph: Graph::new(),
      tasks: tasks,
      rule_graph: rule_graph,
      types: types,
      runtime: runtime,
      store,
      command_runner,
      http_client,
      // TODO: Errors in initialization should definitely be exposed as python
      // exceptions, rather than as panics.
      vfs: PosixFS::new(&build_root, &ignore_patterns).unwrap_or_else(|e| {
        panic!("Could not initialize VFS: {:?}", e);
      }),
      build_root: build_root,
    }
  }

  pub fn store(&self) -> Store {
    self.store.clone()
  }

  ///
  /// Start running a Future on a tokio Runtime.
  ///
  pub fn spawn<F: Future<Item = (), Error = ()> + Send + 'static>(&self, future: F) {
    // Make sure to copy our (thread-local) logging destination into the task.
    // When a daemon thread kicks off a future, it should log like a daemon thread (and similarly
    // for a user-facing thread).
    let logging_destination = logging::get_destination();
    self
      .runtime
      .read()
      .executor()
      .spawn(futures::future::ok(()).and_then(move |()| {
        logging::set_destination(logging_destination);
        future
      }))
  }

  ///
  /// Run a Future and return its resolved Result.
  ///
  /// This should never be called from in a Future context, or any context where anyone may want to
  /// spawn something on the runtime using Core::spawn.
  ///
  pub fn block_on<
    Item: Send + 'static,
    Error: Send + 'static,
    F: Future<Item = Item, Error = Error> + Send + 'static,
  >(
    &self,
    future: F,
  ) -> Result<Item, Error> {
    // Make sure to copy our (thread-local) logging destination into the task.
    // When a daemon thread kicks off a future, it should log like a daemon thread (and similarly
    // for a user-facing thread).
    let logging_destination = logging::get_destination();
    self
      .runtime
      .write()
      .block_on(futures::future::ok(()).and_then(move |()| {
        logging::set_destination(logging_destination);
        future
      }))
  }
}

#[derive(Clone)]
pub struct Context {
  pub entry_id: EntryId,
  pub core: Arc<Core>,
  pub session: Session,
}

impl Context {
  pub fn new(entry_id: EntryId, core: Arc<Core>, session: Session) -> Context {
    Context {
      entry_id: entry_id,
      core: core,
      session: session,
    }
  }

  ///
  /// Get the future value for the given Node implementation.
  ///
  pub fn get<N: WrappedNode>(&self, node: N) -> BoxFuture<N::Item, Failure> {
    // TODO: Odd place for this... could do it periodically in the background?
    maybe_drop_handles();
    self
      .core
      .graph
      .get(self.entry_id, self, node.into())
      .map(|node_result| {
        node_result
          .try_into()
          .unwrap_or_else(|_| panic!("A Node implementation was ambiguous."))
      })
      .to_boxed()
  }
}

impl NodeContext for Context {
  type Node = NodeKey;

  ///
  /// Clones this Context for a new EntryId. Because the Core of the context is an Arc, this
  /// is a shallow clone.
  ///
  fn clone_for(&self, entry_id: EntryId) -> Context {
    Context {
      entry_id: entry_id,
      core: self.core.clone(),
      session: self.session.clone(),
    }
  }

  fn graph(&self) -> &Graph<NodeKey> {
    &self.core.graph
  }

  fn spawn<F>(&self, future: F)
  where
    F: Future<Item = (), Error = ()> + Send + 'static,
  {
    self.core.runtime.read().executor().spawn(future);
  }
}
<|endoftext|>


<commit_before>use rusqlite::Connection;

#[derive(Debug)]
pub struct VariableName {
    pub id: i32,
    pub name: String,
}

pub fn table_create_variable_name(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE VARIABLE_NAME (
                  id            INTEGER PRIMARY KEY ASC,
                  name      TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_variable_name(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let me = VariableName {
        id: 0,
        name: name.clone(),
    };
    let variable_name_instance = conn.execute(
        "INSERT INTO VARIABLE_NAME (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if variable_name_instance.is_err() {
        return Err("Insert failed");
    }
    variable_name_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_name(conn: &Connection) -> Vec<VariableName> {
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<VariableName>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_name_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name, fk_provider, sq_order FROM VARIABLE_NAME")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        info!("Found variable_name {:?}", person.unwrap());
    }
}

pub fn pk_variable_name_by_name(conn: &Connection, name: &str) -> Result<i32, &'static str> {
    let mut output = 0;
    let bill = String::from(name);
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME WHERE name = ?1")
        .unwrap();
    let variable_name_iter = stmt.query_map(&[&name], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    if variable_name_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_name_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<commit_msg>Remove unused variables<commit_after>use rusqlite::Connection;

#[derive(Debug)]
pub struct VariableName {
    pub id: i32,
    pub name: String,
}

pub fn table_create_variable_name(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE VARIABLE_NAME (
                  id            INTEGER PRIMARY KEY ASC,
                  name      TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_variable_name(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let me = VariableName {
        id: 0,
        name: name.clone(),
    };
    let variable_name_instance = conn.execute(
        "INSERT INTO VARIABLE_NAME (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if variable_name_instance.is_err() {
        return Err("Insert failed");
    }
    variable_name_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_name(conn: &Connection) -> Vec<VariableName> {
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<VariableName>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_name_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name, fk_provider, sq_order FROM VARIABLE_NAME")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        info!("Found variable_name {:?}", person.unwrap());
    }
}

pub fn pk_variable_name_by_name(conn: &Connection, name: &str) -> Result<i32, &'static str> {
    let mut output = 0;
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME WHERE name = ?1")
        .unwrap();
    let variable_name_iter = stmt.query_map(&[&name], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    if variable_name_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_name_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>export writeinstr;
export writer;
export writer_factory;
export writer_util;
export make_writer_factory;
export future_writer_factory;

enum writeinstr {
    write(str),
    done
}

type writer = fn~(+writeinstr);
type writer_factory = fn~(page: doc::page) -> writer;

impl writer_util for writer {
    fn write_str(str: str) {
        self(write(str));
    }

    fn write_line(str: str) {
        self.write_str(str + "\n");
    }

    fn write_done() {
        self(done)
    }
}

fn make_writer_factory(config: config::config) -> writer_factory {
    alt config.output_format {
      config::markdown {
        markdown_writer_factory(config)
      }
      config::pandoc_html {
        pandoc_writer_factory(config)
      }
    }
}

fn markdown_writer_factory(config: config::config) -> writer_factory {
    fn~(page: doc::page) -> writer {
        markdown_writer(config, page)
    }
}

fn pandoc_writer_factory(config: config::config) -> writer_factory {
    fn~(page: doc::page) -> writer {
        pandoc_writer(config, page)
    }
}

fn markdown_writer(
    config: config::config,
    page: doc::page
) -> writer {
    let filename = make_filename(config, page);
    generic_writer {|markdown|
        write_file(filename, markdown);
    }
}

fn pandoc_writer(
    config: config::config,
    page: doc::page
) -> writer {
    assert option::is_some(config.pandoc_cmd);
    let pandoc_cmd = option::get(config.pandoc_cmd);
    let filename = make_filename(config, page);

    let pandoc_args = [
        "--standalone",
        "--section-divs",
        "--from=markdown",
        "--to=html",
        "--css=rust.css",
        "--output=" + filename
    ];

    generic_writer {|markdown|
        import std::run;
        import std::os;
        import std::io;
        import std::io::writer_util;

        #debug("pandoc cmd: %s", pandoc_cmd);
        #debug("pandoc args: %s", str::connect(pandoc_args, " "));

        let pipe_in = os::pipe();
        let pipe_out = os::pipe();
        let pipe_err = os::pipe();
        let pid = run::spawn_process(
            pandoc_cmd, pandoc_args, none, none,
            pipe_in.in, pipe_out.out, pipe_err.out);

        let writer = io::fd_writer(pipe_in.out, false);
        writer.write_str(markdown);

        os::close(pipe_in.in);
        os::close(pipe_out.out);
        os::close(pipe_err.out);
        os::close(pipe_in.out);
        os::close(pipe_out.in);
        os::close(pipe_err.in);

        let status = run::waitpid(pid);
        #debug("pandoc result: %i", status);
        if status != 0 {
            fail "pandoc failed";
        }
    }
}

fn generic_writer(process: fn~(markdown: str)) -> writer {
    let ch = task::spawn_listener {|po: comm::port<writeinstr>|
        let markdown = "";
        let keep_going = true;
        while keep_going {
            alt comm::recv(po) {
              write(s) { markdown += s; }
              done { keep_going = false; }
            }
        }
        process(markdown);
    };

    fn~(+instr: writeinstr) {
        comm::send(ch, instr);
    }
}

fn make_filename(
    config: config::config,
    page: doc::page
) -> str {
    import std::fs;

    let filename = {
        alt page {
          doc::cratepage(doc) {
            if config.output_format == config::pandoc_html &&
                config.output_style == config::doc_per_mod {
                "index"
            } else {
                assert doc.topmod.name() != "";
                doc.topmod.name()
            }
          }
          doc::itempage(doc) {
            str::connect(doc.path() + [doc.name()], "_")
          }
        }
    };
    let ext = alt config.output_format {
      config::markdown { "md" }
      config::pandoc_html { "html" }
    };
    fs::connect(config.output_dir, filename + "." + ext)
}

#[test]
fn should_use_markdown_file_name_based_off_crate() {
    let config = {
        output_dir: "output/dir",
        output_format: config::markdown,
        output_style: config::doc_per_crate
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("test", "");
    let page = doc::cratepage(doc.cratedoc());
    let filename = make_filename(config, page);
    assert filename == "output/dir/test.md";
}

#[test]
fn should_name_html_crate_file_name_index_html_when_doc_per_mod() {
    let config = {
        output_dir: "output/dir",
        output_format: config::pandoc_html,
        output_style: config::doc_per_mod
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("", "");
    let page = doc::cratepage(doc.cratedoc());
    let filename = make_filename(config, page);
    assert filename == "output/dir/index.html";
}

#[test]
fn should_name_mod_file_names_by_path() {
    let config = {
        output_dir: "output/dir",
        output_format: config::pandoc_html,
        output_style: config::doc_per_mod
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("", "mod a { mod b { } }");
    let modb = doc.cratemod().mods()[0].mods()[0];
    let page = doc::itempage(doc::modtag(modb));
    let filename = make_filename(config, page);
    assert  filename == "output/dir/a_b.html";
}

#[cfg(test)]
mod test {
    fn mk_doc(name: str, source: str) -> doc::doc {
        astsrv::from_str(source) {|srv|
            let doc = extract::from_srv(srv, name);
            let doc = path_pass::mk_pass().f(srv, doc);
            doc
        }
    }
}

fn write_file(path: str, s: str) {
    import std::io;
    import std::io::writer_util;

    alt io::file_writer(path, [io::create, io::truncate]) {
      result::ok(writer) {
        writer.write_str(s);
      }
      result::err(e) { fail e }
    }
}

fn future_writer_factory(
) -> (writer_factory, comm::port<(doc::page, str)>) {
    let markdown_po = comm::port();
    let markdown_ch = comm::chan(markdown_po);
    let writer_factory = fn~(page: doc::page) -> writer {
        let writer_po = comm::port();
        let writer_ch = comm::chan(writer_po);
        task::spawn {||
            let (writer, future) = future_writer();
            comm::send(writer_ch, writer);
            let s = future::get(future);
            comm::send(markdown_ch, (page, s));
        }
        comm::recv(writer_po)
    };

    (writer_factory, markdown_po)
}

fn future_writer() -> (writer, future::future<str>) {
    let port = comm::port();
    let chan = comm::chan(port);
    let writer = fn~(+instr: writeinstr) {
        comm::send(chan, copy instr);
    };
    let future = future::from_fn {||
        let res = "";
        while true {
            alt comm::recv(port) {
              write(s) { res += s }
              done { break }
            }
        }
        res
    };
    (writer, future)
}
<commit_msg>rustdoc: Add some more error reporting for pandoc<commit_after>export writeinstr;
export writer;
export writer_factory;
export writer_util;
export make_writer_factory;
export future_writer_factory;

enum writeinstr {
    write(str),
    done
}

type writer = fn~(+writeinstr);
type writer_factory = fn~(page: doc::page) -> writer;

impl writer_util for writer {
    fn write_str(str: str) {
        self(write(str));
    }

    fn write_line(str: str) {
        self.write_str(str + "\n");
    }

    fn write_done() {
        self(done)
    }
}

fn make_writer_factory(config: config::config) -> writer_factory {
    alt config.output_format {
      config::markdown {
        markdown_writer_factory(config)
      }
      config::pandoc_html {
        pandoc_writer_factory(config)
      }
    }
}

fn markdown_writer_factory(config: config::config) -> writer_factory {
    fn~(page: doc::page) -> writer {
        markdown_writer(config, page)
    }
}

fn pandoc_writer_factory(config: config::config) -> writer_factory {
    fn~(page: doc::page) -> writer {
        pandoc_writer(config, page)
    }
}

fn markdown_writer(
    config: config::config,
    page: doc::page
) -> writer {
    let filename = make_filename(config, page);
    generic_writer {|markdown|
        write_file(filename, markdown);
    }
}

fn pandoc_writer(
    config: config::config,
    page: doc::page
) -> writer {
    assert option::is_some(config.pandoc_cmd);
    let pandoc_cmd = option::get(config.pandoc_cmd);
    let filename = make_filename(config, page);

    let pandoc_args = [
        "--standalone",
        "--section-divs",
        "--from=markdown",
        "--to=html",
        "--css=rust.css",
        "--output=" + filename
    ];

    generic_writer {|markdown|
        import std::run;
        import std::os;
        import std::io;
        import std::io::writer_util;

        #debug("pandoc cmd: %s", pandoc_cmd);
        #debug("pandoc args: %s", str::connect(pandoc_args, " "));

        let pipe_in = os::pipe();
        let pipe_out = os::pipe();
        let pipe_err = os::pipe();
        let pid = run::spawn_process(
            pandoc_cmd, pandoc_args, none, none,
            pipe_in.in, pipe_out.out, pipe_err.out);

        let writer = io::fd_writer(pipe_in.out, false);
        writer.write_str(markdown);

        os::close(pipe_in.in);
        os::close(pipe_out.out);
        os::close(pipe_err.out);
        os::close(pipe_in.out);

        let stdout = result::get(task::try {||
            readclose(pipe_out.in)
        });
        let stderr = result::get(task::try {||
            readclose(pipe_err.in)
        });

        let status = run::waitpid(pid);
        #debug("pandoc result: %i", status);
        if status != 0 {
            #error("pandoc-out: %s", stdout);
            #error("pandoc-err: %s", stderr);
            fail "pandoc failed";
        }
    }
}

fn readclose(fd: ctypes::fd_t) -> str {
    import std::os;
    import std::io;

    // Copied from run::program_output
    let file = os::fd_FILE(fd);
    let reader = io::FILE_reader(file, false);
    let buf = "";
    while !reader.eof() {
        let bytes = reader.read_bytes(4096u);
        buf += str::from_bytes(bytes);
    }
    os::fclose(file);
    ret buf;
}

fn generic_writer(process: fn~(markdown: str)) -> writer {
    let ch = task::spawn_listener {|po: comm::port<writeinstr>|
        let markdown = "";
        let keep_going = true;
        while keep_going {
            alt comm::recv(po) {
              write(s) { markdown += s; }
              done { keep_going = false; }
            }
        }
        process(markdown);
    };

    fn~(+instr: writeinstr) {
        comm::send(ch, instr);
    }
}

fn make_filename(
    config: config::config,
    page: doc::page
) -> str {
    import std::fs;

    let filename = {
        alt page {
          doc::cratepage(doc) {
            if config.output_format == config::pandoc_html &&
                config.output_style == config::doc_per_mod {
                "index"
            } else {
                assert doc.topmod.name() != "";
                doc.topmod.name()
            }
          }
          doc::itempage(doc) {
            str::connect(doc.path() + [doc.name()], "_")
          }
        }
    };
    let ext = alt config.output_format {
      config::markdown { "md" }
      config::pandoc_html { "html" }
    };
    fs::connect(config.output_dir, filename + "." + ext)
}

#[test]
fn should_use_markdown_file_name_based_off_crate() {
    let config = {
        output_dir: "output/dir",
        output_format: config::markdown,
        output_style: config::doc_per_crate
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("test", "");
    let page = doc::cratepage(doc.cratedoc());
    let filename = make_filename(config, page);
    assert filename == "output/dir/test.md";
}

#[test]
fn should_name_html_crate_file_name_index_html_when_doc_per_mod() {
    let config = {
        output_dir: "output/dir",
        output_format: config::pandoc_html,
        output_style: config::doc_per_mod
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("", "");
    let page = doc::cratepage(doc.cratedoc());
    let filename = make_filename(config, page);
    assert filename == "output/dir/index.html";
}

#[test]
fn should_name_mod_file_names_by_path() {
    let config = {
        output_dir: "output/dir",
        output_format: config::pandoc_html,
        output_style: config::doc_per_mod
        with config::default_config("input/test.rc")
    };
    let doc = test::mk_doc("", "mod a { mod b { } }");
    let modb = doc.cratemod().mods()[0].mods()[0];
    let page = doc::itempage(doc::modtag(modb));
    let filename = make_filename(config, page);
    assert  filename == "output/dir/a_b.html";
}

#[cfg(test)]
mod test {
    fn mk_doc(name: str, source: str) -> doc::doc {
        astsrv::from_str(source) {|srv|
            let doc = extract::from_srv(srv, name);
            let doc = path_pass::mk_pass().f(srv, doc);
            doc
        }
    }
}

fn write_file(path: str, s: str) {
    import std::io;
    import std::io::writer_util;

    alt io::file_writer(path, [io::create, io::truncate]) {
      result::ok(writer) {
        writer.write_str(s);
      }
      result::err(e) { fail e }
    }
}

fn future_writer_factory(
) -> (writer_factory, comm::port<(doc::page, str)>) {
    let markdown_po = comm::port();
    let markdown_ch = comm::chan(markdown_po);
    let writer_factory = fn~(page: doc::page) -> writer {
        let writer_po = comm::port();
        let writer_ch = comm::chan(writer_po);
        task::spawn {||
            let (writer, future) = future_writer();
            comm::send(writer_ch, writer);
            let s = future::get(future);
            comm::send(markdown_ch, (page, s));
        }
        comm::recv(writer_po)
    };

    (writer_factory, markdown_po)
}

fn future_writer() -> (writer, future::future<str>) {
    let port = comm::port();
    let chan = comm::chan(port);
    let writer = fn~(+instr: writeinstr) {
        comm::send(chan, copy instr);
    };
    let future = future::from_fn {||
        let res = "";
        while true {
            alt comm::recv(port) {
              write(s) { res += s }
              done { break }
            }
        }
        res
    };
    (writer, future)
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::ffi::OsString;
use url::Url;
use download;

error_chain! {
    links {
        Download(download::Error, download::ErrorKind);
    }

    foreign_links { }

    errors {
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not create {} directory: '{}'", name, path.display())
        }
        ExpectedType(t: &'static str, n: String) {
            description("expected type")
            display("expected type: '{}' for '{}'", t, n)
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        DownloadNotExists {
            url: Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}
<commit_msg>Fix two missing quotes of download error message<commit_after>use std::path::PathBuf;
use std::ffi::OsString;
use url::Url;
use download;

error_chain! {
    links {
        Download(download::Error, download::ErrorKind);
    }

    foreign_links { }

    errors {
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not create {} directory: '{}'", name, path.display())
        }
        ExpectedType(t: &'static str, n: String) {
            description("expected type")
            display("expected type: '{}' for '{}'", t, n)
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}'", url, path.display())
        }
        DownloadNotExists {
            url: Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}'", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}
<|endoftext|>


<commit_before>use libc::{c_int,size_t,intptr_t};
use std::vec;
use std::ptr;

#[link(name="libfwnt")]
extern {
    fn libfwnt_lzxpress_huffman_decompress(
        compressed_data: *const u8,
        compressed_data_size: size_t,
        uncompressed_data: *mut u8,
        uncompressed_data_size: *mut size_t,
        error: *mut intptr_t
    ) -> c_int;
}

pub fn decompress(compressed_data: &[u8],uncompressed_size: usize) -> Option<Vec<u8>> {
    unsafe {
        // Get size of compressed data
        let compressed_data_size = compressed_data.len() as size_t;

        // Create compressed data pointer
        let compressed_data_ptr = compressed_data.as_ptr();

        let mut uncompressed_data_size: size_t = uncompressed_size;

        // To hold uncompressed data
        let mut uncompressed_data: Vec<u8> = Vec::with_capacity(
            uncompressed_data_size as usize
        );
        let uncompressed_data_ptr = uncompressed_data.as_mut_ptr();

        // Error ptr... not sure if this is how it should be handled...
        let mut error: intptr_t = 0;

        let result: c_int = libfwnt_lzxpress_huffman_decompress(
            compressed_data_ptr,
            compressed_data_size,
            uncompressed_data_ptr,
            &mut uncompressed_data_size,
            &mut error
        );

        if result == 1 {
            uncompressed_data.set_len(
                uncompressed_data_size as usize
            );
            Some(uncompressed_data)
        } else {
            // TODO Handle Errors. -1 == ERROR
            None
        }
    }
}
<commit_msg>Needed lib imports<commit_after>use byteorder::{ReadBytesExt, LittleEndian};
use libc::{c_int,size_t,intptr_t};
use std::io::Read;
use std::io;
use std::vec;
use std::ptr;

#[link(name="libfwnt")]
extern {
    fn libfwnt_lzxpress_huffman_decompress(
        compressed_data: *const u8,
        compressed_data_size: size_t,
        uncompressed_data: *mut u8,
        uncompressed_data_size: *mut size_t,
        error: *mut intptr_t
    ) -> c_int;
}

pub fn decompress(compressed_data: &[u8],uncompressed_size: usize) -> Option<Vec<u8>> {
    unsafe {
        // Get size of compressed data
        let compressed_data_size = compressed_data.len() as size_t;

        // Create compressed data pointer
        let compressed_data_ptr = compressed_data.as_ptr();

        let mut uncompressed_data_size: size_t = uncompressed_size;

        // To hold uncompressed data
        let mut uncompressed_data: Vec<u8> = Vec::with_capacity(
            uncompressed_data_size as usize
        );
        let uncompressed_data_ptr = uncompressed_data.as_mut_ptr();

        // Error ptr... not sure if this is how it should be handled...
        let mut error: intptr_t = 0;

        let result: c_int = libfwnt_lzxpress_huffman_decompress(
            compressed_data_ptr,
            compressed_data_size,
            uncompressed_data_ptr,
            &mut uncompressed_data_size,
            &mut error
        );

        if result == 1 {
            uncompressed_data.set_len(
                uncompressed_data_size as usize
            );
            Some(uncompressed_data)
        } else {
            // TODO Handle Errors. -1 == ERROR
            None
        }
    }
}
<|endoftext|>