<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::mem;
use std::iter::Empty;
use std::ops::Range;
use std::sync::Arc;
use std::sync::Mutex;

use command_buffer::Submission;
use device::Device;
use format::FormatDesc;
use format::FormatTy;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
use image::sys::Usage;
use image::traits::AccessRange;
use image::traits::GpuAccessResult;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

pub struct AttachmentImage<F> {
    image: UnsafeImage,
    view: UnsafeImageView,
    memory: DeviceMemory,
    format: F,

    // Layout to use when the image is used as a framebuffer attachment.
    // Should be either "depth-stencil optimal" or "color optimal".
    attachment_layout: Layout,

    latest_submission: Mutex<Option<Arc<Submission>>>,
}

impl<F> AttachmentImage<F> {
    pub fn new(device: &Arc<Device>, dimensions: [u32; 2], format: F)
               -> Result<Arc<AttachmentImage<F>>, OomError>
        where F: FormatDesc
    {
        let is_depth = match format.format().ty() {
            FormatTy::Depth => true,
            FormatTy::DepthStencil => true,
            FormatTy::Compressed => panic!(),
            _ => false
        };

        let usage = Usage {
            transfer_source: true,
            sampled: true,
            color_attachment: !is_depth,
            depth_stencil_attachment: is_depth,
            input_attachment: true,
            .. Usage::none()
        };

        let (image, mem_reqs) = unsafe {
            try!(UnsafeImage::new(device, &usage, format.format(),
                                  Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] },
                                  1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        unsafe { try!(image.bind_memory(&mem, 0 .. mem_reqs.size)); }

        let view = unsafe {
            try!(UnsafeImageView::new(&image))
        };

        Ok(Arc::new(AttachmentImage {
            image: image,
            view: view,
            memory: mem,
            format: format,
            attachment_layout: if is_depth { Layout::DepthStencilAttachmentOptimal }
                               else { Layout::ColorAttachmentOptimal },
            latest_submission: Mutex::new(None),
        }))
    }

    #[inline]
    pub fn dimensions(&self) -> Dimensions {
        self.image.dimensions()
    }
}

unsafe impl<F> Image for AttachmentImage<F> {
    #[inline]
    fn inner_image(&self) -> &UnsafeImage {
        &self.image
    }

    #[inline]
    fn blocks(&self, _: Range<u32>, _: Range<u32>) -> Vec<(u32, u32)> {
        vec![(0, 0)]
    }

    #[inline]
    fn block_mipmap_levels_range(&self, block: (u32, u32)) -> Range<u32> {
        0 .. 1
    }

    #[inline]
    fn block_array_layers_range(&self, block: (u32, u32)) -> Range<u32> {
        0 .. 1
    }

    #[inline]
    fn initial_layout(&self, _: (u32, u32), _: Layout) -> (Layout, bool, bool) {
        (self.attachment_layout, false, false)
    }

    #[inline]
    fn final_layout(&self, _: (u32, u32), _: Layout) -> (Layout, bool, bool) {
        (self.attachment_layout, false, false)
    }

    fn needs_fence(&self, access: &mut Iterator<Item = AccessRange>) -> Option<bool> {
        Some(false)
    }

    unsafe fn gpu_access(&self, _: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> GpuAccessResult
    {
        let mut latest_submission = self.latest_submission.lock().unwrap();
        let dependency = mem::replace(&mut *latest_submission, Some(submission.clone()));

        GpuAccessResult {
            dependencies: if let Some(dependency) = dependency {
                vec![dependency]
            } else {
                vec![]
            },
            additional_wait_semaphore: None,
            additional_signal_semaphore: None,
            before_transitions: vec![],
            after_transitions: vec![],
        }
    }
}

unsafe impl<P, F> ImageContent<P> for AttachmentImage<F> {
    #[inline]
    fn matches_format(&self) -> bool {
        true        // FIXME:
    }
}

unsafe impl<F: 'static> ImageView for AttachmentImage<F> {
    #[inline]
    fn parent(&self) -> &Image {
        self
    }

    #[inline]
    fn parent_arc(me: &Arc<Self>) -> Arc<Image> where Self: Sized {
        me.clone() as Arc<_>
    }

    #[inline]
    fn inner_view(&self) -> &UnsafeImageView {
        &self.view
    }

    #[inline]
    fn descriptor_set_storage_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_combined_image_sampler_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_sampled_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_input_attachment_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn identity_swizzle(&self) -> bool {
        true
    }
}
<commit_msg>Transition AttachmentImages to correct layout<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::mem;
use std::iter::Empty;
use std::ops::Range;
use std::sync::Arc;
use std::sync::Mutex;

use command_buffer::Submission;
use device::Device;
use format::FormatDesc;
use format::FormatTy;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
use image::sys::Usage;
use image::traits::AccessRange;
use image::traits::GpuAccessResult;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use image::traits::Transition;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

pub struct AttachmentImage<F> {
    image: UnsafeImage,
    view: UnsafeImageView,
    memory: DeviceMemory,
    format: F,

    // Layout to use when the image is used as a framebuffer attachment.
    // Should be either "depth-stencil optimal" or "color optimal".
    attachment_layout: Layout,

    guarded: Mutex<Guarded>,
}

struct Guarded {
    correct_layout: bool,
    latest_submission: Option<Arc<Submission>>,
}

impl<F> AttachmentImage<F> {
    pub fn new(device: &Arc<Device>, dimensions: [u32; 2], format: F)
               -> Result<Arc<AttachmentImage<F>>, OomError>
        where F: FormatDesc
    {
        let is_depth = match format.format().ty() {
            FormatTy::Depth => true,
            FormatTy::DepthStencil => true,
            FormatTy::Compressed => panic!(),
            _ => false
        };

        let usage = Usage {
            transfer_source: true,
            sampled: true,
            color_attachment: !is_depth,
            depth_stencil_attachment: is_depth,
            input_attachment: true,
            .. Usage::none()
        };

        let (image, mem_reqs) = unsafe {
            try!(UnsafeImage::new(device, &usage, format.format(),
                                  Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] },
                                  1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        unsafe { try!(image.bind_memory(&mem, 0 .. mem_reqs.size)); }

        let view = unsafe {
            try!(UnsafeImageView::new(&image))
        };

        Ok(Arc::new(AttachmentImage {
            image: image,
            view: view,
            memory: mem,
            format: format,
            attachment_layout: if is_depth { Layout::DepthStencilAttachmentOptimal }
                               else { Layout::ColorAttachmentOptimal },
            guarded: Mutex::new(Guarded {
                correct_layout: false,
                latest_submission: None,
            }),
        }))
    }

    #[inline]
    pub fn dimensions(&self) -> Dimensions {
        self.image.dimensions()
    }
}

unsafe impl<F> Image for AttachmentImage<F> {
    #[inline]
    fn inner_image(&self) -> &UnsafeImage {
        &self.image
    }

    #[inline]
    fn blocks(&self, _: Range<u32>, _: Range<u32>) -> Vec<(u32, u32)> {
        vec![(0, 0)]
    }

    #[inline]
    fn block_mipmap_levels_range(&self, block: (u32, u32)) -> Range<u32> {
        0 .. 1
    }

    #[inline]
    fn block_array_layers_range(&self, block: (u32, u32)) -> Range<u32> {
        0 .. 1
    }

    #[inline]
    fn initial_layout(&self, _: (u32, u32), _: Layout) -> (Layout, bool, bool) {
        (self.attachment_layout, false, false)
    }

    #[inline]
    fn final_layout(&self, _: (u32, u32), _: Layout) -> (Layout, bool, bool) {
        (self.attachment_layout, false, false)
    }

    fn needs_fence(&self, access: &mut Iterator<Item = AccessRange>) -> Option<bool> {
        Some(false)
    }

    unsafe fn gpu_access(&self, _: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> GpuAccessResult
    {
        let mut guarded = self.guarded.lock().unwrap();

        let dependency = mem::replace(&mut guarded.latest_submission, Some(submission.clone()));

        let transition = if guarded.correct_layout {
            vec![Transition {
                block: (0, 0),
                from: Layout::Undefined,
                to: self.attachment_layout,
            }]
        } else {
            vec![]
        };

        guarded.correct_layout = true;

        GpuAccessResult {
            dependencies: if let Some(dependency) = dependency {
                vec![dependency]
            } else {
                vec![]
            },
            additional_wait_semaphore: None,
            additional_signal_semaphore: None,
            before_transitions: transition,
            after_transitions: vec![],
        }
    }
}

unsafe impl<P, F> ImageContent<P> for AttachmentImage<F> {
    #[inline]
    fn matches_format(&self) -> bool {
        true        // FIXME:
    }
}

unsafe impl<F: 'static> ImageView for AttachmentImage<F> {
    #[inline]
    fn parent(&self) -> &Image {
        self
    }

    #[inline]
    fn parent_arc(me: &Arc<Self>) -> Arc<Image> where Self: Sized {
        me.clone() as Arc<_>
    }

    #[inline]
    fn inner_view(&self) -> &UnsafeImageView {
        &self.view
    }

    #[inline]
    fn descriptor_set_storage_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_combined_image_sampler_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_sampled_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_input_attachment_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn identity_swizzle(&self) -> bool {
        true
    }
}
<|endoftext|>


<commit_before>use crate::{error::Result,
            hcore::{fs as hfs,
                    package::{list,
                              PackageIdent}}};
use clap::ArgMatches;
use habitat_common::cli::FS_ROOT;
use std::str::FromStr;

/// There are three options for what we can list:
///   - All packages (no prefix supplied)
///   - All packages in an origin (string with no '/')
///   - A set of packages with a common package ident (e.g. /ORIGIN/NAME) with optionally
///     version/release
#[derive(Debug)]
pub enum ListingType {
    AllPackages,
    Origin(String),
    Ident(PackageIdent),
}

/// Convert a set of command line options into a ListingType
impl<'a> From<&'a ArgMatches<'a>> for ListingType {
    /// Convert clap options into a listing type.
    ///
    /// We assume that the arguments have been validated during CLI parsing i.e.
    /// ORIGIN and PKG_IDENT are a valid origin and package identifier
    fn from(m: &ArgMatches<'_>) -> Self {
        if m.is_present("ALL") {
            return ListingType::AllPackages;
        }

        if m.is_present("ORIGIN") {
            let origin = m.value_of("ORIGIN").unwrap(); // Required by clap
            return ListingType::Origin(origin.to_string());
        }

        let p = m.value_of("PKG_IDENT").unwrap(); // Required by clap
        match PackageIdent::from_str(&p) {
            Ok(ident) => ListingType::Ident(ident),
            Err(_) => unreachable!("We've already validated PackageIdent {}", &p),
        }
    }
}

pub fn package_list(listing: &ListingType) -> Result<Vec<PackageIdent>> {
    let package_path = hfs::pkg_root_path(Some(&*FS_ROOT));

    let mut packages = match listing {
        ListingType::AllPackages => list::all_packages(&package_path)?,
        ListingType::Origin(origin) => list::package_list_for_origin(&package_path, &origin)?,
        ListingType::Ident(ident) => list::package_list_for_ident(&package_path, &ident)?,
    };

    packages.sort_unstable_by(|a, b| a.by_parts_cmp(b));
    Ok(packages)
}

pub fn start(listing: &ListingType) -> Result<()> {
    let packages = package_list(listing)?;
    for p in &packages {
        println!("{}", &p);
    }

    Ok(())
}
<commit_msg>Add from PackageIdent for ListingType<commit_after>use crate::{error::Result,
            hcore::{fs as hfs,
                    package::{list,
                              PackageIdent}}};
use clap::ArgMatches;
use habitat_common::cli::FS_ROOT;
use std::str::FromStr;

/// There are three options for what we can list:
///   - All packages (no prefix supplied)
///   - All packages in an origin (string with no '/')
///   - A set of packages with a common package ident (e.g. /ORIGIN/NAME) with optionally
///     version/release
#[derive(Debug)]
pub enum ListingType {
    AllPackages,
    Origin(String),
    Ident(PackageIdent),
}

/// Convert a set of command line options into a ListingType
impl<'a> From<&'a ArgMatches<'a>> for ListingType {
    /// Convert clap options into a listing type.
    ///
    /// We assume that the arguments have been validated during CLI parsing i.e.
    /// ORIGIN and PKG_IDENT are a valid origin and package identifier
    fn from(m: &ArgMatches<'_>) -> Self {
        if m.is_present("ALL") {
            return ListingType::AllPackages;
        }

        if m.is_present("ORIGIN") {
            let origin = m.value_of("ORIGIN").unwrap(); // Required by clap
            return ListingType::Origin(origin.to_string());
        }

        let p = m.value_of("PKG_IDENT").unwrap(); // Required by clap
        match PackageIdent::from_str(&p) {
            Ok(ident) => ListingType::Ident(ident),
            Err(_) => unreachable!("We've already validated PackageIdent {}", &p),
        }
    }
}

impl From<PackageIdent> for ListingType {
    fn from(ident: PackageIdent) -> Self { ListingType::Ident(ident) }
}

pub fn package_list(listing: &ListingType) -> Result<Vec<PackageIdent>> {
    let package_path = hfs::pkg_root_path(Some(&*FS_ROOT));

    let mut packages = match listing {
        ListingType::AllPackages => list::all_packages(&package_path)?,
        ListingType::Origin(origin) => list::package_list_for_origin(&package_path, &origin)?,
        ListingType::Ident(ident) => list::package_list_for_ident(&package_path, &ident)?,
    };

    packages.sort_unstable_by(|a, b| a.by_parts_cmp(b));
    Ok(packages)
}

pub fn start(listing: &ListingType) -> Result<()> {
    let packages = package_list(listing)?;
    for p in &packages {
        println!("{}", &p);
    }

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Bump hammer<commit_after><|endoftext|>


<commit_before>#![allow(unknown_lints)] // older rustc doesn't know `unused_macros`
#![allow(unused_macros)]

macro_rules! forward_val_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref
                $imp::$method(self, &other)
            }
        }
    };
}

macro_rules! forward_val_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref, with the larger capacity as val
                if self.capacity() >= other.capacity() {
                    $imp::$method(self, &other)
                } else {
                    $imp::$method(other, &self)
                }
            }
        }
    };
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to ref-ref
                $imp::$method(self, &other)
            }
        }
    };
}

macro_rules! forward_ref_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // reverse, forward to val-ref
                $imp::$method(other, self)
            }
        }
    };
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to ref-ref
                $imp::$method(&self, other)
            }
        }
    };
}

macro_rules! forward_ref_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref
                $imp::$method(self.clone(), other)
            }
        }
    };
}

macro_rules! forward_ref_ref_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref, choosing the larger to clone
                if self.len() >= other.len() {
                    $imp::$method(self.clone(), other)
                } else {
                    $imp::$method(other.clone(), self)
                }
            }
        }
    };
}

macro_rules! forward_val_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    };
}
macro_rules! forward_val_assign_scalar {
    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    };
}

macro_rules! forward_scalar_val_val_binop_commutative {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(other, self)
            }
        }
    };
}

macro_rules! forward_scalar_val_ref_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $scalar> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self, *other)
            }
        }

        impl<'a> $imp<$res> for &'a $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(*self, other)
            }
        }
    };
}

macro_rules! forward_scalar_ref_val_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a> $imp<$scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $scalar) -> $res {
                $imp::$method(self.clone(), other)
            }
        }

        impl<'a> $imp<&'a $res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(self, other.clone())
            }
        }
    };
}

macro_rules! forward_scalar_ref_ref_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self.clone(), *other)
            }
        }

        impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(*self, other.clone())
            }
        }
    };
}

macro_rules! promote_scalars {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);

            impl $imp<$scalar> for $res {
                type Output = $res;

                #[inline]
                fn $method(self, other: $scalar) -> $res {
                    $imp::$method(self, other as $promo)
                }
            }

            impl $imp<$res> for $scalar {
                type Output = $res;

                #[inline]
                fn $method(self, other: $res) -> $res {
                    $imp::$method(self as $promo, other)
                }
            }
        )*
    }
}
macro_rules! promote_scalars_assign {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            impl $imp<$scalar> for $res {
                #[inline]
                fn $method(&mut self, other: $scalar) {
                    self.$method(other as $promo);
                }
            }
        )*
    }
}

macro_rules! promote_unsigned_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_unsigned_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_signed_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
    }
}

macro_rules! promote_signed_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, isize);
    }
}

// Forward everything to ref-ref, when reusing storage is not helpful
macro_rules! forward_all_binop_to_ref_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_val_ref_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, so LHS storage can be reused
macro_rules! forward_all_binop_to_val_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
        forward_ref_ref_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
macro_rules! forward_all_binop_to_val_ref_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
    };
}

macro_rules! forward_all_scalar_binop_to_val_val {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! forward_all_scalar_binop_to_val_val_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! promote_all_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars!(impl $imp for $res, $method);
        promote_signed_scalars!(impl $imp for $res, $method);
    }
}

macro_rules! promote_all_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars_assign!(impl $imp for $res, $method);
        promote_signed_scalars_assign!(impl $imp for $res, $method);
    }
}

macro_rules! impl_sum_iter_type {
    ($res:ty) => {
        impl<T> Sum<T> for $res
        where
            $res: Add<T, Output = $res>,
        {
            fn sum<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>,
            {
                iter.fold(Zero::zero(), <$res>::add)
            }
        }
    };
}

macro_rules! impl_product_iter_type {
    ($res:ty) => {
        impl<T> Product<T> for $res
        where
            $res: Mul<T, Output = $res>,
        {
            fn product<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>,
            {
                iter.fold(One::one(), <$res>::mul)
            }
        }
    };
}
<commit_msg>Allow cast_lossless lint for macros<commit_after>#![allow(unknown_lints)] // older rustc doesn't know `unused_macros`
#![allow(unused_macros)]

macro_rules! forward_val_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref
                $imp::$method(self, &other)
            }
        }
    };
}

macro_rules! forward_val_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref, with the larger capacity as val
                if self.capacity() >= other.capacity() {
                    $imp::$method(self, &other)
                } else {
                    $imp::$method(other, &self)
                }
            }
        }
    };
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to ref-ref
                $imp::$method(self, &other)
            }
        }
    };
}

macro_rules! forward_ref_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // reverse, forward to val-ref
                $imp::$method(other, self)
            }
        }
    };
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to ref-ref
                $imp::$method(&self, other)
            }
        }
    };
}

macro_rules! forward_ref_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref
                $imp::$method(self.clone(), other)
            }
        }
    };
}

macro_rules! forward_ref_ref_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref, choosing the larger to clone
                if self.len() >= other.len() {
                    $imp::$method(self.clone(), other)
                } else {
                    $imp::$method(other.clone(), self)
                }
            }
        }
    };
}

macro_rules! forward_val_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    };
}
macro_rules! forward_val_assign_scalar {
    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    };
}

macro_rules! forward_scalar_val_val_binop_commutative {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(other, self)
            }
        }
    };
}

macro_rules! forward_scalar_val_ref_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $scalar> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self, *other)
            }
        }

        impl<'a> $imp<$res> for &'a $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(*self, other)
            }
        }
    };
}

macro_rules! forward_scalar_ref_val_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a> $imp<$scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $scalar) -> $res {
                $imp::$method(self.clone(), other)
            }
        }

        impl<'a> $imp<&'a $res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(self, other.clone())
            }
        }
    };
}

macro_rules! forward_scalar_ref_ref_binop {
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self.clone(), *other)
            }
        }

        impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(*self, other.clone())
            }
        }
    };
}

macro_rules! promote_scalars {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);

            impl $imp<$scalar> for $res {
                type Output = $res;

                #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
                #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
                #[inline]
                fn $method(self, other: $scalar) -> $res {
                    $imp::$method(self, other as $promo)
                }
            }

            impl $imp<$res> for $scalar {
                type Output = $res;

                #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
                #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
                #[inline]
                fn $method(self, other: $res) -> $res {
                    $imp::$method(self as $promo, other)
                }
            }
        )*
    }
}
macro_rules! promote_scalars_assign {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            impl $imp<$scalar> for $res {
                #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
                #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
                #[inline]
                fn $method(&mut self, other: $scalar) {
                    self.$method(other as $promo);
                }
            }
        )*
    }
}

macro_rules! promote_unsigned_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_unsigned_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_signed_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
    }
}

macro_rules! promote_signed_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, isize);
    }
}

// Forward everything to ref-ref, when reusing storage is not helpful
macro_rules! forward_all_binop_to_ref_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_val_ref_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, so LHS storage can be reused
macro_rules! forward_all_binop_to_val_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
        forward_ref_ref_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
macro_rules! forward_all_binop_to_val_ref_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
    };
}

macro_rules! forward_all_scalar_binop_to_val_val {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! forward_all_scalar_binop_to_val_val_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! promote_all_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars!(impl $imp for $res, $method);
        promote_signed_scalars!(impl $imp for $res, $method);
    }
}

macro_rules! promote_all_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars_assign!(impl $imp for $res, $method);
        promote_signed_scalars_assign!(impl $imp for $res, $method);
    }
}

macro_rules! impl_sum_iter_type {
    ($res:ty) => {
        impl<T> Sum<T> for $res
        where
            $res: Add<T, Output = $res>,
        {
            fn sum<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>,
            {
                iter.fold(Zero::zero(), <$res>::add)
            }
        }
    };
}

macro_rules! impl_product_iter_type {
    ($res:ty) => {
        impl<T> Product<T> for $res
        where
            $res: Mul<T, Output = $res>,
        {
            fn product<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>,
            {
                iter.fold(One::one(), <$res>::mul)
            }
        }
    };
}
<|endoftext|>


<commit_before>//! A Netherrack buffer backed by a VecDeque::<u8>

use std::collections::VecDeque;

extern crate bit_utils;
use self::bit_utils::BitInformation;

/// Defines a DequeBuffer
///
/// At some stage in the future, this will be changed to inherit the trait NetherrackBuffer<(Something extending Read and Write), but for now, we'll do everything here
pub struct DequeBuffer {

    data: VecDeque<u8>

}

impl DequeBuffer {

    /// Creates a DequeBuffer from a VecDeque
    ///
    /// After this method, we own the VecDeque
    pub fn from(deque: VecDeque<u8>) -> DequeBuffer {
        DequeBuffer { data: deque }
    }

    /// Creates a new empty DequeBuffer
    pub fn new() -> DequeBuffer {
        DequeBuffer { data: VecDeque::<u8>::new() }
    }

    /// Creates a new empty DequeBuffer with the specified initial capacity
    pub fn with_capacity(capacity: usize) -> DequeBuffer {
        DequeBuffer { data: VecDeque::<u8>::with_capacity(capacity) }
    }

    /// Gets the remaining bytes in this DequeBuffer
    pub fn remaining(&self) -> usize {
        self.data.len()
    }

    /// Reads a UTF-8 string from the buffer
    pub fn read_utf8_string(&mut self) -> String {
        let size_result = self.read_unsigned_varint_32();

        if size_result.is_err() {
            return String::from("!!!BAD_SIZE!!!");
        } else {
            let mut size: u32 = size_result.unwrap();

            let mut bytes: Vec<u8> = Vec::<u8>::with_capacity(size as usize);

            while size > 0 {
                bytes.push(self.read_unsigned_byte());
                size -= 1;
            }

            let result = String::from_utf8(bytes);

            if result.is_ok() {
                return result.unwrap();
            } else {
                return String::from("!!!INVALID_UTF8!!!");
            }

        }
    }

    /// Reads an unsigned byte from the buffer, returning 0 if no data is available
    pub fn read_unsigned_byte(&mut self) -> u8 {
        match self.data.pop_front() {
            Some(value) => value,
            None => 0
        }
    }

    /// Reads an unsigned byte from the buffer, returning -127 if no data is available
    pub fn read_signed_byte(&mut self) -> i8 {
        match self.data.pop_front() {
            Some(value) => value as i8,
            None => -127
        }
    }

    /// Reads an unsigned short from the buffer
    pub fn read_unsigned_short(&mut self) -> u16 {

        let high: u8 = self.read_unsigned_byte();
        let low: u8 = self.read_unsigned_byte();

        ((high as u16) << 8) | low as u16

    }

    /// Writes an unsigned byte to the buffer
    pub fn write_unsigned_byte(&mut self, value: u8) {
        self.data.push_back(value);
    }

    /// Writes a signed byte to the buffer
    pub fn write_signed_byte(&mut self, value: i8) {
        self.data.push_back(value as u8);
    }

    /// Reads an unsigned Varint from the buffer
    pub fn read_unsigned_varint_32(&mut self) -> Result<u32, &'static str> {
        if self.remaining() == 0 {
            return Err("Cannot read a Varint with no data to read.");
        } else {
            // The number of bits to shift by. <<0, <<7, <<14, etc
            let mut shift_amount: u32 = 0;

            // The decoded value
            let mut decoded_value: u32 = 0;

            while self.remaining() >= 1 {

                let byte_value: u8 = self.read_unsigned_byte(); //Yay for this existing!

                decoded_value |= ((byte_value & 0b01111111) as u32) << shift_amount; // We're not shifting for the first byte ;)

                // See if we're still reading bytes
                if byte_value.has_most_signifigant_bit() {
                    shift_amount += 7;
                } else {
                    return Ok(decoded_value);
                }

            }

            return Err("Reached end of buffer while reading a varint32");

        }
    }

}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn new_contains_no_elements() {
        let new = DequeBuffer::new();

        assert_eq!(0, new.remaining());
    }

    #[test]
    fn new_with_capacity_contains_no_elements() {
        let new = DequeBuffer::with_capacity(25000); //WOW, MUCH BIG PACKET

        assert_eq!(0, new.remaining());
    }

}<commit_msg>Test unsigned and signed byte methods in DequeBuffer<commit_after>//! A Netherrack buffer backed by a VecDeque::<u8>

use std::collections::VecDeque;

extern crate bit_utils;
use self::bit_utils::BitInformation;

/// Defines a DequeBuffer
///
/// At some stage in the future, this will be changed to inherit the trait NetherrackBuffer<(Something extending Read and Write), but for now, we'll do everything here
pub struct DequeBuffer {

    data: VecDeque<u8>

}

impl DequeBuffer {

    /// Creates a DequeBuffer from a VecDeque
    ///
    /// After this method, we own the VecDeque
    pub fn from(deque: VecDeque<u8>) -> DequeBuffer {
        DequeBuffer { data: deque }
    }

    /// Creates a new empty DequeBuffer
    pub fn new() -> DequeBuffer {
        DequeBuffer { data: VecDeque::<u8>::new() }
    }

    /// Creates a new empty DequeBuffer with the specified initial capacity
    pub fn with_capacity(capacity: usize) -> DequeBuffer {
        DequeBuffer { data: VecDeque::<u8>::with_capacity(capacity) }
    }

    /// Gets the remaining bytes in this DequeBuffer
    pub fn remaining(&self) -> usize {
        self.data.len()
    }

    /// Reads a UTF-8 string from the buffer
    pub fn read_utf8_string(&mut self) -> String {
        let size_result = self.read_unsigned_varint_32();

        if size_result.is_err() {
            return String::from("!!!BAD_SIZE!!!");
        } else {
            let mut size: u32 = size_result.unwrap();

            let mut bytes: Vec<u8> = Vec::<u8>::with_capacity(size as usize);

            while size > 0 {
                bytes.push(self.read_unsigned_byte());
                size -= 1;
            }

            let result = String::from_utf8(bytes);

            if result.is_ok() {
                return result.unwrap();
            } else {
                return String::from("!!!INVALID_UTF8!!!");
            }

        }
    }

    /// Reads an unsigned byte from the buffer, returning 0 if no data is available
    pub fn read_unsigned_byte(&mut self) -> u8 {
        match self.data.pop_front() {
            Some(value) => value,
            None => 0
        }
    }

    /// Reads an unsigned byte from the buffer, returning -127 if no data is available
    pub fn read_signed_byte(&mut self) -> i8 {
        match self.data.pop_front() {
            Some(value) => value as i8,
            None => -127
        }
    }

    /// Reads an unsigned short from the buffer
    pub fn read_unsigned_short(&mut self) -> u16 {

        let high: u8 = self.read_unsigned_byte();
        let low: u8 = self.read_unsigned_byte();

        ((high as u16) << 8) | low as u16

    }

    /// Writes an unsigned byte to the buffer
    pub fn write_unsigned_byte(&mut self, value: u8) {
        self.data.push_back(value);
    }

    /// Writes a signed byte to the buffer
    pub fn write_signed_byte(&mut self, value: i8) {
        self.data.push_back(value as u8);
    }

    /// Reads an unsigned Varint from the buffer
    pub fn read_unsigned_varint_32(&mut self) -> Result<u32, &'static str> {
        if self.remaining() == 0 {
            return Err("Cannot read a Varint with no data to read.");
        } else {
            // The number of bits to shift by. <<0, <<7, <<14, etc
            let mut shift_amount: u32 = 0;

            // The decoded value
            let mut decoded_value: u32 = 0;

            while self.remaining() >= 1 {

                let byte_value: u8 = self.read_unsigned_byte(); //Yay for this existing!

                decoded_value |= ((byte_value & 0b01111111) as u32) << shift_amount; // We're not shifting for the first byte ;)

                // See if we're still reading bytes
                if byte_value.has_most_signifigant_bit() {
                    shift_amount += 7;
                } else {
                    return Ok(decoded_value);
                }

            }

            return Err("Reached end of buffer while reading a varint32");

        }
    }

}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn new_contains_no_elements() {
        let new = DequeBuffer::new();

        assert_eq!(0, new.remaining());
    }

    #[test]
    fn new_with_capacity_contains_no_elements() {
        let new = DequeBuffer::with_capacity(25000); //WOW, MUCH BIG PACKET

        assert_eq!(0, new.remaining());
    }

    #[test]
    fn unsigned_byte() {
        let mut buffer = DequeBuffer::with_capacity(2);

        buffer.write_unsigned_byte(1);
        buffer.write_unsigned_byte(15);

        assert_eq!(2, buffer.remaining());

        assert_eq!(1, buffer.read_unsigned_byte());
        assert_eq!(15, buffer.read_unsigned_byte());
    }

    #[test]
    fn signed_byte() {
        let mut buffer = DequeBuffer::with_capacity(2);

        buffer.write_signed_byte(-50);
        buffer.write_signed_byte(0);

        assert_eq!(2, buffer.remaining());

        assert_eq!(-50, buffer.read_signed_byte());
        assert_eq!(-0, buffer.read_signed_byte());
    }

}<|endoftext|>


<commit_before>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::presigning::config::PresigningConfig;
use aws_sdk_s3::presigning::request::PresignedRequest;
use aws_sdk_s3::{Client, Region, PKG_VERSION};
use std::error::Error;
use std::time::Duration;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    /// The AWS Region.
    #[structopt(short, long)]
    region: Option<String>,

    /// The data to be uploaded to S3.
    #[structopt(short, long)]
    body: String,

    /// The name of the bucket.
    #[structopt(short, long)]
    bucket: String,

    /// The object key.
    #[structopt(short, long)]
    object: String,

    /// How long in seconds before the presigned request should expire.
    #[structopt(short, long, default_value = "900")]
    expires_in: u64,

    /// Whether to display additional information.
    #[structopt(short, long)]
    verbose: bool,
}

/// Adds an object to a bucket and returns a public URI.
/// # Arguments
///
/// * `[-r REGION]` - The Region in which the client is created.
///   If not supplied, uses the value of the **AWS_REGION** environment variable.
/// * `-b BUCKET` - The bucket where the object is uploaded.
/// * `-o OBJECT` - The name of the file to upload to the bucket.
///   If the environment variable is not set, defaults to **us-west-2**.
/// * `[-e EXPIRES_IN]` - The amount of time the presigned request should be valid for.
///   If not given, this defaults to 15 minutes.
/// * `[-v]` - Whether to display additional information.
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    tracing_subscriber::fmt::init();

    let Opt {
        region,
        body,
        bucket,
        object,
        expires_in,
        verbose,
    } = Opt::from_args();

    let region_provider = RegionProviderChain::first_try(region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));
    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client = Client::new(&shared_config);

    println!();

    if verbose {
        println!("S3 client version: {}", PKG_VERSION);
        println!("Region:            {}", shared_config.region().unwrap());
        println!("Bucket:            {}", &bucket);
        println!("Object:            {}", &object);
        println!("Body:              {}", &body);
        println!("Expires in:        {} seconds", expires_in);
        println!();
    }

    let expires_in = Duration::from_secs(expires_in);

    let presigned_request = client
        .put_object()
        .bucket(bucket)
        .key(object)
        .presigned(PresigningConfig::expires_in(expires_in)?)
        .await?;

    println!("Object URI: {}", presigned_request.uri());

    // Presigned requests can be used in several ways. Here are a few examples:
    print_as_curl_request(&presigned_request, Some(body.as_str()));
    send_presigned_request_with_reqwest(&presigned_request, body.as_str()).await;
    send_presigned_request_with_hyper(presigned_request, hyper::Body::from(body.as_str())).await;

    Ok(())
}

/// This function demonstrates how you can convert a presigned request into a cURL command
/// that you can run from your terminal of choice.
///
/// _NOTE:_ This only prints out the command, it's up to you to copy-paste it and run it.
fn print_as_curl_request(presigned_req: &PresignedRequest, body: Option<&str>) {
    println!(
        "curl -X {} {} \\",
        presigned_req.method(),
        presigned_req.uri()
    );

    if let Some(body) = body {
        println!("-d '{}' \\", body);
    }

    for (name, value) in presigned_req.headers() {
        // This value conversion method is naïve and will drop values that aren't valid UTF8
        // It's only here for demonstration purposes; Don't use this unless you're confident
        // that your header values are valid UTF-8
        println!(
            "-H '{}: {}' \\",
            name,
            value.to_str().unwrap_or_default().to_string()
        )
    }

    println!("--verbose");
}

/// This function demonstrates how you can send a presigned request using [hyper](https://crates.io/crates/hyper)
async fn send_presigned_request_with_hyper(req: PresignedRequest, body: hyper::Body) {
    let conn = aws_smithy_client::conns::https();
    let client = hyper::Client::builder().build(conn);
    let req = req.to_http_request(body).unwrap();

    let res = client.request(req).await;

    match res {
        Ok(res) => {
            println!("Response: {:?}", res)
        }
        Err(err) => {
            println!("Error: {}", err)
        }
    }
}

/// This function demonstrates how you can send a presigned request using [reqwest](https://crates.io/crates/reqwest)
async fn send_presigned_request_with_reqwest(
    req: &PresignedRequest,
    body: impl Into<reqwest::Body>,
) {
    let client = reqwest::Client::new();
    let res = client
        .request(req.method().clone(), &req.uri().to_string())
        .headers(req.headers().clone())
        .body(body)
        .send()
        .await;

    match res {
        Ok(res) => {
            println!("Response: {:?}", res)
        }
        Err(err) => {
            println!("Error: {}", err)
        }
    }
}
<commit_msg>fix: clippy lint errors<commit_after>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::presigning::config::PresigningConfig;
use aws_sdk_s3::presigning::request::PresignedRequest;
use aws_sdk_s3::{Client, Region, PKG_VERSION};
use std::error::Error;
use std::time::Duration;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    /// The AWS Region.
    #[structopt(short, long)]
    region: Option<String>,

    /// The data to be uploaded to S3.
    #[structopt(short, long)]
    body: String,

    /// The name of the bucket.
    #[structopt(short, long)]
    bucket: String,

    /// The object key.
    #[structopt(short, long)]
    object: String,

    /// How long in seconds before the presigned request should expire.
    #[structopt(short, long, default_value = "900")]
    expires_in: u64,

    /// Whether to display additional information.
    #[structopt(short, long)]
    verbose: bool,
}

/// Adds an object to a bucket and returns a public URI.
/// # Arguments
///
/// * `[-r REGION]` - The Region in which the client is created.
///   If not supplied, uses the value of the **AWS_REGION** environment variable.
/// * `-b BUCKET` - The bucket where the object is uploaded.
/// * `-o OBJECT` - The name of the file to upload to the bucket.
///   If the environment variable is not set, defaults to **us-west-2**.
/// * `[-e EXPIRES_IN]` - The amount of time the presigned request should be valid for.
///   If not given, this defaults to 15 minutes.
/// * `[-v]` - Whether to display additional information.
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    tracing_subscriber::fmt::init();

    let Opt {
        region,
        body,
        bucket,
        object,
        expires_in,
        verbose,
    } = Opt::from_args();

    let region_provider = RegionProviderChain::first_try(region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));
    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client = Client::new(&shared_config);

    println!();

    if verbose {
        println!("S3 client version: {}", PKG_VERSION);
        println!("Region:            {}", shared_config.region().unwrap());
        println!("Bucket:            {}", &bucket);
        println!("Object:            {}", &object);
        println!("Body:              {}", &body);
        println!("Expires in:        {} seconds", expires_in);
        println!();
    }

    let expires_in = Duration::from_secs(expires_in);

    let presigned_request = client
        .put_object()
        .bucket(bucket)
        .key(object)
        .presigned(PresigningConfig::expires_in(expires_in)?)
        .await?;

    println!("Object URI: {}", presigned_request.uri());

    // Presigned requests can be used in several ways. Here are a few examples:
    print_as_curl_request(&presigned_request, Some(body.as_str()));
    send_presigned_request_with_reqwest(&presigned_request, body.clone()).await;
    send_presigned_request_with_hyper(presigned_request, hyper::Body::from(body.clone())).await;

    Ok(())
}

/// This function demonstrates how you can convert a presigned request into a cURL command
/// that you can run from your terminal of choice.
///
/// _NOTE:_ This only prints out the command, it's up to you to copy-paste it and run it.
fn print_as_curl_request(presigned_req: &PresignedRequest, body: Option<&str>) {
    println!(
        "curl -X {} {} \\",
        presigned_req.method(),
        presigned_req.uri()
    );

    if let Some(body) = body {
        println!("-d '{}' \\", body);
    }

    for (name, value) in presigned_req.headers() {
        // This value conversion method is naïve and will drop values that aren't valid UTF8
        // It's only here for demonstration purposes; Don't use this unless you're confident
        // that your header values are valid UTF-8
        println!(
            "-H '{}: {}' \\",
            name,
            value.to_str().unwrap_or_default().to_string()
        )
    }

    println!("--verbose");
}

/// This function demonstrates how you can send a presigned request using [hyper](https://crates.io/crates/hyper)
async fn send_presigned_request_with_hyper(req: PresignedRequest, body: hyper::Body) {
    let conn = aws_smithy_client::conns::https();
    let client = hyper::Client::builder().build(conn);
    let req = req.to_http_request(body).unwrap();

    let res = client.request(req).await;

    match res {
        Ok(res) => {
            println!("Response: {:?}", res)
        }
        Err(err) => {
            println!("Error: {}", err)
        }
    }
}

/// This function demonstrates how you can send a presigned request using [reqwest](https://crates.io/crates/reqwest)
async fn send_presigned_request_with_reqwest(
    req: &PresignedRequest,
    body: impl Into<reqwest::Body>,
) {
    let client = reqwest::Client::new();
    let res = client
        .request(req.method().clone(), &req.uri().to_string())
        .headers(req.headers().clone())
        .body(body)
        .send()
        .await;

    match res {
        Ok(res) => {
            println!("Response: {:?}", res)
        }
        Err(err) => {
            println!("Error: {}", err)
        }
    }
}
<|endoftext|>


<commit_before>use std::io::{Read, BufRead, Error as IoError};
use std::str::{from_utf8, Utf8Error};

use num::bigint::{BigInt, ToBigInt, Sign, ParseBigIntError};
use byteorder::{ReadBytesExt, LittleEndian, Error as ByteorderError};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        ReadError(err: ByteorderError) {
            from()
        }
        IoError(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}
        InvalidInt {
            from(Utf8Error)
            from(ParseBigIntError)
        }
        InvalidString
        ExpectedTrailingL
        InvalidLong
    }
}

#[derive(Debug)]
pub enum OpCode {
    Int(BigInt),
    BinInt(i32),
    BinInt1(u8),
    BinInt2(u16),
    Long(BigInt),
    Long1(BigInt),
    Long4(BigInt),

    String(Vec<u8>),
    BinString(Vec<u8>),
    ShortBinString(Vec<u8>),

    None,

    NewTrue,
    NewFalse,

    Unicode(String),
    BinUnicode(String),

    Float(f64),
    BinFloat(f64),

    EmptyList,
    Append,
    Appends,
    List,

    EmptyTuple,
    Tuple,
    Tuple1,
    Tuple2,
    Tuple3,

    EmptyDict,
    Dict,
    SetItem,
    SetItems,

    Pop,
    Dup,
    Mark,
    PopMark,

    Get(usize),
    BinGet(usize),
    LongBinGet(usize),
    Put(usize),
    BinPut(usize),
    LongBinPut(usize),

    Ext1(u8),
    Ext2(u16),
    Ext4(i32),

    Global(Vec<u8>, Vec<u8>),
    Reduce,
    Build,
    Inst(Vec<u8>, Vec<u8>),
    Obj,
    NewObj,
    Proto(u8),
    Stop,
    PersId(Vec<u8>),
    BinPersId,
}

pub fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        None => Err(Error::InvalidString),
        Some((_last, init)) => Ok(init.to_vec()),
    }
}

pub fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(rd.read_exact(buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub fn read_opcode<R>(rd: &mut R) -> Result<OpCode, Error> where R: Read + BufRead {
    let marker = try!(rd.read_u8());
    return Ok(match marker {
        73 => {
            let s = try!(read_until_newline(rd));
            OpCode::Int(try!(try!(from_utf8(&s)).parse()))  // http://rust-num.github.io/num/num/bigint/struct.BigInt.html#method.parse_bytes
        },
        74 => OpCode::BinInt(try!(rd.read_i32::<LittleEndian>())),
        75 => OpCode::BinInt1(try!(rd.read_u8())),
        77 => OpCode::BinInt2(try!(rd.read_u16::<LittleEndian>())),
        76 => {
            let s = try!(read_until_newline(rd));

            let init = match s.split_last() {
                None => return Err(Error::InvalidString),
                Some((&76, init)) => init,
                Some(_) => return Err(Error::ExpectedTrailingL),
            };

            OpCode::Long(try!(try!(from_utf8(init)).parse()))
        },
        138 => {
            let length = try!(rd.read_u8());
            OpCode::Long1(try!(read_long(rd, length as usize)))

        },
        139 => {
            let length = try!(rd.read_i32::<LittleEndian>());
            OpCode::Long1(try!(read_long(rd, length as usize)))

        },
        c => return Err(Error::UnknownOpcode(c)),
    })
}

#[cfg(test)]
mod tests {
    use std::io::{Cursor};

    use num::{FromPrimitive};

    use super::{OpCode, Error, read_opcode};

    macro_rules! t {
        ($buffer: expr, $pat:pat, $result:expr) => ({
            match read_opcode(&mut Cursor::new(&$buffer[..])) {
                $pat => $result,
                other => {
                    println!("ERROR {:?}", other);
                    assert!(false)
                },
            }
        })
    }

    #[test]
    fn test_int() {
        t!(b"I", Err(Error::InvalidString), assert!(true));
        t!(b"I\n", Err(Error::InvalidInt), assert!(true));
        t!(b"Iabc\n", Err(Error::InvalidInt), assert!(true));
        t!(b"I123\n", Ok(OpCode::Int(n)), assert_eq!(n, FromPrimitive::from_usize(123).unwrap()));
    }

    #[test]
    fn test_bin_int() {
        t!(b"J\x0a", Err(Error::ReadError(_)), assert!(true));
        t!(b"J\x0a\x00\x00\x00", Ok(OpCode::BinInt(n)), assert_eq!(n, 10));
        t!(b"J\x0a\x00\x00\x01", Ok(OpCode::BinInt(n)), assert_eq!(n, 16777226));
    }

    #[test]
    fn test_bin_int1() {
        t!(b"K", Err(Error::ReadError(_)), assert!(true));
        t!(b"K\x0a", Ok(OpCode::BinInt1(n)), assert_eq!(n, 10));
    }

    #[test]
    fn test_bin_int2() {
        t!(b"M\x0a", Err(Error::ReadError(_)), assert!(true));
        t!(b"M\x0a\x00\x00\x00", Ok(OpCode::BinInt2(n)), assert_eq!(n, 10));
        t!(b"M\x0a\x01\x00\x00", Ok(OpCode::BinInt2(n)), assert_eq!(n, 266));
    }

    #[test]
    fn test_long() {
        t!(b"L", Err(Error::InvalidString), assert!(true));
        t!(b"L\n", Err(Error::InvalidString), assert!(true));
        t!(b"Labc\n", Err(Error::ExpectedTrailingL), assert!(true));
        t!(b"LabcL\n", Err(Error::InvalidInt), assert!(true));
        t!(b"L123L\n", Ok(OpCode::Long(n)), assert_eq!(n, FromPrimitive::from_usize(123).unwrap()));
    }

    #[test]
    fn test_long1() {
        t!(b"\x8a", Err(Error::ReadError(_)), assert!(true));
        t!(b"\x8a\x01\x0a", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_usize(10).unwrap()));
        t!(b"\x8a\x01\xf6", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_isize(-10).unwrap()));
        t!(b"\x8a\x02.\xfb", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_isize(-1234).unwrap()));
    }

    #[test]
    fn test_long4() {
        t!(b"\x8b\x0a", Err(Error::ReadError(_)), assert!(true));
    }
}
<commit_msg>Inline read_exact method<commit_after>use std::io::{Read, BufRead, Error as IoError, ErrorKind};
use std::str::{from_utf8, Utf8Error};

use num::bigint::{BigInt, ToBigInt, Sign, ParseBigIntError};
use byteorder::{ReadBytesExt, LittleEndian, Error as ByteorderError};

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        ReadError(err: ByteorderError) {
            from()
        }
        IoError(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}
        InvalidInt {
            from(Utf8Error)
            from(ParseBigIntError)
        }
        InvalidString
        ExpectedTrailingL
        InvalidLong
    }
}

#[derive(Debug)]
pub enum OpCode {
    Int(BigInt),
    BinInt(i32),
    BinInt1(u8),
    BinInt2(u16),
    Long(BigInt),
    Long1(BigInt),
    Long4(BigInt),

    String(Vec<u8>),
    BinString(Vec<u8>),
    ShortBinString(Vec<u8>),

    None,

    NewTrue,
    NewFalse,

    Unicode(String),
    BinUnicode(String),

    Float(f64),
    BinFloat(f64),

    EmptyList,
    Append,
    Appends,
    List,

    EmptyTuple,
    Tuple,
    Tuple1,
    Tuple2,
    Tuple3,

    EmptyDict,
    Dict,
    SetItem,
    SetItems,

    Pop,
    Dup,
    Mark,
    PopMark,

    Get(usize),
    BinGet(usize),
    LongBinGet(usize),
    Put(usize),
    BinPut(usize),
    LongBinPut(usize),

    Ext1(u8),
    Ext2(u16),
    Ext4(i32),

    Global(Vec<u8>, Vec<u8>),
    Reduce,
    Build,
    Inst(Vec<u8>, Vec<u8>),
    Obj,
    NewObj,
    Proto(u8),
    Stop,
    PersId(Vec<u8>),
    BinPersId,
}

fn read_exact<R>(rd: &mut R, mut buf: &mut [u8]) -> Result<(), IoError> where R: Read {
    while !buf.is_empty() {
        match rd.read(buf) {
            Ok(0) => break,
            Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    if !buf.is_empty() {
        Err(IoError::new(ErrorKind::Other,
                       "failed to fill whole buffer"))
    } else {
        Ok(())
    }
}

pub fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        None => Err(Error::InvalidString),
        Some((_last, init)) => Ok(init.to_vec()),
    }
}

pub fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(read_exact(rd, buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub fn read_opcode<R>(rd: &mut R) -> Result<OpCode, Error> where R: Read + BufRead {
    let marker = try!(rd.read_u8());
    return Ok(match marker {
        73 => {
            let s = try!(read_until_newline(rd));
            OpCode::Int(try!(try!(from_utf8(&s)).parse()))  // http://rust-num.github.io/num/num/bigint/struct.BigInt.html#method.parse_bytes
        },
        74 => OpCode::BinInt(try!(rd.read_i32::<LittleEndian>())),
        75 => OpCode::BinInt1(try!(rd.read_u8())),
        77 => OpCode::BinInt2(try!(rd.read_u16::<LittleEndian>())),
        76 => {
            let s = try!(read_until_newline(rd));

            let init = match s.split_last() {
                None => return Err(Error::InvalidString),
                Some((&76, init)) => init,
                Some(_) => return Err(Error::ExpectedTrailingL),
            };

            OpCode::Long(try!(try!(from_utf8(init)).parse()))
        },
        138 => {
            let length = try!(rd.read_u8());
            OpCode::Long1(try!(read_long(rd, length as usize)))

        },
        139 => {
            let length = try!(rd.read_i32::<LittleEndian>());
            OpCode::Long1(try!(read_long(rd, length as usize)))

        },
        c => return Err(Error::UnknownOpcode(c)),
    })
}

#[cfg(test)]
mod tests {
    use std::io::{Cursor};

    use num::{FromPrimitive};

    use super::{OpCode, Error, read_opcode};

    macro_rules! t {
        ($buffer: expr, $pat:pat, $result:expr) => ({
            match read_opcode(&mut Cursor::new(&$buffer[..])) {
                $pat => $result,
                other => {
                    println!("ERROR {:?}", other);
                    assert!(false)
                },
            }
        })
    }

    #[test]
    fn test_int() {
        t!(b"I", Err(Error::InvalidString), assert!(true));
        t!(b"I\n", Err(Error::InvalidInt), assert!(true));
        t!(b"Iabc\n", Err(Error::InvalidInt), assert!(true));
        t!(b"I123\n", Ok(OpCode::Int(n)), assert_eq!(n, FromPrimitive::from_usize(123).unwrap()));
    }

    #[test]
    fn test_bin_int() {
        t!(b"J\x0a", Err(Error::ReadError(_)), assert!(true));
        t!(b"J\x0a\x00\x00\x00", Ok(OpCode::BinInt(n)), assert_eq!(n, 10));
        t!(b"J\x0a\x00\x00\x01", Ok(OpCode::BinInt(n)), assert_eq!(n, 16777226));
    }

    #[test]
    fn test_bin_int1() {
        t!(b"K", Err(Error::ReadError(_)), assert!(true));
        t!(b"K\x0a", Ok(OpCode::BinInt1(n)), assert_eq!(n, 10));
    }

    #[test]
    fn test_bin_int2() {
        t!(b"M\x0a", Err(Error::ReadError(_)), assert!(true));
        t!(b"M\x0a\x00\x00\x00", Ok(OpCode::BinInt2(n)), assert_eq!(n, 10));
        t!(b"M\x0a\x01\x00\x00", Ok(OpCode::BinInt2(n)), assert_eq!(n, 266));
    }

    #[test]
    fn test_long() {
        t!(b"L", Err(Error::InvalidString), assert!(true));
        t!(b"L\n", Err(Error::InvalidString), assert!(true));
        t!(b"Labc\n", Err(Error::ExpectedTrailingL), assert!(true));
        t!(b"LabcL\n", Err(Error::InvalidInt), assert!(true));
        t!(b"L123L\n", Ok(OpCode::Long(n)), assert_eq!(n, FromPrimitive::from_usize(123).unwrap()));
    }

    #[test]
    fn test_long1() {
        t!(b"\x8a", Err(Error::ReadError(_)), assert!(true));
        t!(b"\x8a\x01\x0a", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_usize(10).unwrap()));
        t!(b"\x8a\x01\xf6", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_isize(-10).unwrap()));
        t!(b"\x8a\x02.\xfb", Ok(OpCode::Long1(n)), assert_eq!(n, FromPrimitive::from_isize(-1234).unwrap()));
    }

    #[test]
    fn test_long4() {
        t!(b"\x8b\x0a", Err(Error::ReadError(_)), assert!(true));
    }
}
<|endoftext|>


<commit_before>#![cfg(target_os = "windows")]

pub mod ffi {
   #![allow(non_snake_case)]

   pub use libc::{
      c_int, c_uint, c_void, uintptr_t, c_long, c_ulong
   };
   pub use libc::types::os::arch::extra::{
      HANDLE, LONG_PTR, LRESULT, HINSTANCE, LPCWSTR, HMODULE, LPVOID, BOOL
   };
   use std::mem;

   pub type HWND = HANDLE;
   pub type HICON = HANDLE;
   pub type HBRUSH = HANDLE;
   pub type HMENU = HANDLE;
   pub type HDC = HANDLE;
   pub type HCURSOR = HICON;

   pub type WPARAM = uintptr_t;
   pub type LPARAM = LONG_PTR;

   pub type ATOM = u16;

   pub type WNDPROC = Option<unsafe extern "system" fn(HWND, c_uint, WPARAM, LPARAM) -> LRESULT>;

   pub const CS_VREDRAW:                 c_ulong = 0x00000001;
   pub const CS_HREDRAW:                 c_ulong = 0x00000002;
   pub const CS_DBLCLKS:                 c_ulong = 0x00000008;
   pub const CS_OWNDC:                   c_ulong = 0x00000020;
   pub const CS_CLASSDC:                 c_ulong = 0x00000040;
   pub const CS_PARENTDC:                c_ulong = 0x00000080;
   pub const CS_NOCLOSE:                 c_ulong = 0x00000200;
   pub const CS_SAVEBITS:                c_ulong = 0x00000800;
   pub const CS_BYTEALIGNCLIENT:         c_ulong = 0x00001000;
   pub const CS_BYTEALIGNWINDOW:         c_ulong = 0x00002000;
   pub const CS_GLOBALCLASS:             c_ulong = 0x00004000;
   pub const CS_IME:                     c_ulong = 0x00010000;
   pub const CS_DROPSHADOW:              c_ulong = 0x00020000;

   pub const WS_OVERLAPPED:              c_ulong = 0x00000000;
   pub const WS_POPUP:                   c_ulong = 0x80000000;
   pub const WS_CHILD:                   c_ulong = 0x40000000;
   pub const WS_MINIMIZE:                c_ulong = 0x20000000;
   pub const WS_VISIBLE:                 c_ulong = 0x10000000;
   pub const WS_DISABLED:                c_ulong = 0x08000000;
   pub const WS_CLIPSIBLINGS:            c_ulong = 0x04000000;
   pub const WS_CLIPCHILDREN:            c_ulong = 0x02000000;
   pub const WS_MAXIMIZE:                c_ulong = 0x01000000;
   pub const WS_CAPTION:                 c_ulong = 0x00C00000;
   pub const WS_BORDER:                  c_ulong = 0x00800000;
   pub const WS_DLGFRAME:                c_ulong = 0x00400000;
   pub const WS_VSCROLL:                 c_ulong = 0x00200000;
   pub const WS_HSCROLL:                 c_ulong = 0x00100000;
   pub const WS_SYSMENU:                 c_ulong = 0x00080000;
   pub const WS_THICKFRAME:              c_ulong = 0x00040000;
   pub const WS_GROUP:                   c_ulong = 0x00020000;
   pub const WS_TABSTOP:                 c_ulong = 0x00010000;
   pub const WS_MINIMIZEBOX:             c_ulong = 0x00020000;
   pub const WS_MAXIMIZEBOX:             c_ulong = 0x00010000;
   pub const WS_TILED:                   c_ulong = WS_OVERLAPPED;
   pub const WS_ICONIC:                  c_ulong = WS_MINIMIZE;
   pub const WS_SIZEBOX:                 c_ulong = WS_THICKFRAME;
   pub const WS_TILEDWINDOW:             c_ulong = WS_OVERLAPPEDWINDOW;
   pub const WS_OVERLAPPEDWINDOW:        c_ulong = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
   pub const WS_POPUPWINDOW:             c_ulong = WS_POPUP | WS_BORDER | WS_SYSMENU;
   pub const WS_CHILDWINDOW:             c_ulong = WS_CHILD;

   pub const WS_EX_DLGMODALFRAME:        c_ulong = 0x00000001;
   pub const WS_EX_NOPARENTNOTIFY:       c_ulong = 0x00000004;
   pub const WS_EX_TOPMOST:              c_ulong = 0x00000008;
   pub const WS_EX_ACCEPTFILES:          c_ulong = 0x00000010;
   pub const WS_EX_TRANSPARENT:          c_ulong = 0x00000020;
   pub const WS_EX_MDICHILD:             c_ulong = 0x00000040;
   pub const WS_EX_TOOLWINDOW:           c_ulong = 0x00000080;
   pub const WS_EX_WINDOWEDGE:           c_ulong = 0x00000100;
   pub const WS_EX_CLIENTEDGE:           c_ulong = 0x00000200;
   pub const WS_EX_CONTEXTHELP:          c_ulong = 0x00000400;
   pub const WS_EX_RIGHT:                c_ulong = 0x00001000;
   pub const WS_EX_LEFT:                 c_ulong = 0x00000000;
   pub const WS_EX_RTLREADING:           c_ulong = 0x00002000;
   pub const WS_EX_LTRREADING:           c_ulong = 0x00000000;
   pub const WS_EX_LEFTSCROLLBAR:        c_ulong = 0x00004000;
   pub const WS_EX_RIGHTSCROLLBAR:       c_ulong = 0x00000000;
   pub const WS_EX_CONTROLPARENT:        c_ulong = 0x00010000;
   pub const WS_EX_STATICEDGE:           c_ulong = 0x00020000;
   pub const WS_EX_APPWINDOW:            c_ulong = 0x00040000;
   pub const WS_EX_OVERLAPPEDWINDOW:     c_ulong = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE;
   pub const WS_EX_PALETTEWINDOW:        c_ulong = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
   pub const WS_EX_LAYERED:              c_ulong = 0x00080000;
   pub const WS_EX_NOINHERITLAYOUT:      c_ulong = 0x00100000;
   pub const WS_EX_NOREDIRECTIONBITMAP:  c_ulong = 0x00200000;
   pub const WS_EX_LAYOUTRTL:            c_ulong = 0x00400000;
   pub const WS_EX_COMPOSITED:           c_ulong = 0x02000000;
   pub const WS_EX_NOACTIVATE:           c_ulong = 0x08000000;

   pub const CW_USEDEFAULT:                c_int = 0x80000000u32 as c_int;

   pub const WM_CLOSE:                    c_uint = 16;

   pub const SW_SHOWNORMAL:                c_int = 1;
   pub const SW_SHOWMINIMIZED:             c_int = 2;
   pub const SW_MAXIMIZE:                  c_int = 3;
   pub const SW_SHOWMAXIMIZED:             c_int = 3;
   pub const SW_SHOWNOACTIVATE:            c_int = 4;
   pub const SW_SHOW:                      c_int = 5;
   pub const SW_MINIMIZE:                  c_int = 6;
   pub const SW_SHOWMINNOACTIVE:           c_int = 7;
   pub const SW_SHOWNA:                    c_int = 8;
   pub const SW_RESTORE:                   c_int = 9;
   pub const SW_SHOWDEFAULT:               c_int = 10;
   pub const SW_FORCEMINIMIZE:             c_int = 11;

   #[repr(C)]
   #[derive(Copy)]
   pub struct WNDCLASSEXW {
      pub cbSize: c_uint,
      pub style: c_uint,
      pub lpfnWndProc: WNDPROC,
      pub cbClsExtra: c_int,
      pub cbWndExtra: c_int,
      pub hInstance: HINSTANCE,
      pub hIcon: HICON,
      pub hCursor: HCURSOR,
      pub hbrBackground: HBRUSH,
      pub lpszMenuName: LPCWSTR,
      pub lpszClassName: LPCWSTR,
      pub hIconSm: HICON,
   }
   impl Clone for WNDCLASSEXW {
      fn clone(&self) -> Self { *self }
   }
   impl Default for WNDCLASSEXW {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   #[repr(C)]
   #[derive(Copy)]
   pub struct POINT {
      pub x: c_long,
      pub y: c_long,
   }
   impl Clone for POINT {
      fn clone(&self) -> Self { *self }
   }
   impl Default for POINT {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   #[repr(C)]
   #[derive(Copy)]
   pub struct MSG {
      pub hwnd: HWND,
      pub message: c_uint,
      pub wParam: WPARAM,
      pub lParam: LPARAM,
      pub time: c_ulong,
      pub pt: POINT,
   }
   impl Clone for MSG {
      fn clone(&self) -> Self { *self }
   }
   impl Default for MSG {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   extern "system" {
      pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;

      pub fn RegisterClassExW(lpWndClass: *const WNDCLASSEXW) -> ATOM;

      pub fn ShowWindow(hwnd: HWND, nCmdShow: c_int) -> BOOL;

      pub fn PostQuitMessage(nExitCode: c_int);

      pub fn TranslateMessage(lpmsg: *const MSG) -> BOOL;

      pub fn DispatchMessageW(lpmsg: *const MSG) -> LRESULT;

      pub fn GetDC(hwnd: HWND) -> HDC;

      pub fn DefWindowProcW(
         hwnd: HWND,
         Msg: c_uint,
         wParam: WPARAM,
         lParam: LPARAM
      ) -> LRESULT;

      pub fn CreateWindowExW(
         dwExStyle: c_ulong,
         lpClassName: LPCWSTR,
         lpWindowName: LPCWSTR,
         dwStyle: c_ulong,
         x: c_int,
         y: c_int,
         nWidth: c_int,
         nHeight: c_int,
         hWndParent: HWND,
         hMenu: HMENU,
         hInstance: HINSTANCE,
         lpParam: LPVOID,
      ) -> HWND;

      pub fn GetMessageW(
         lpMsg: *const MSG,
         hwnd: HWND,
         wMsgFilterMin: c_uint,
         wMsgFilterMax: c_uint
      ) -> BOOL;
   }
}

use std::ptr;
use std::mem;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;

fn to_utf16_os(s: &str) -> Vec<u16> {
   let mut v: Vec<_> = OsStr::new(s).encode_wide().collect();
   v.push(0);
   v
}

pub fn register_window_class(class_name: &str) {
   unsafe extern "system" fn wnd_proc(
      hwnd: ffi::HWND,
      msg: ffi::c_uint,
      wparam: ffi::WPARAM,
      lparam: ffi::LPARAM
   ) -> ffi::LRESULT {
      match msg {
         ffi::WM_CLOSE => {
            ffi::PostQuitMessage(0);
         },
         _ => {
            return ffi::DefWindowProcW(hwnd, msg, wparam, lparam);
         }
      }

      return 0;
   }

   unsafe {
      let wnd_class = ffi::WNDCLASSEXW {
         cbSize: mem::size_of::<ffi::WNDCLASSEXW>() as ffi::c_uint,
         style: ffi::CS_HREDRAW | ffi::CS_VREDRAW | ffi::CS_OWNDC,
         lpfnWndProc: Some(wnd_proc),
         cbClsExtra: 0,
         cbWndExtra: 0,
         hInstance: ffi::GetModuleHandleW(ptr::null()),
         hIcon: ptr::null_mut(),
         hCursor: ptr::null_mut(),
         hbrBackground: ptr::null_mut(),
         lpszMenuName: ptr::null(),
         lpszClassName: to_utf16_os(class_name).as_ptr(),
         hIconSm: ptr::null_mut(),
      };

      ffi::RegisterClassExW(&wnd_class);
   }
}

pub struct Window {
   pub hwnd: ffi::HWND
}

impl Window {
   pub fn create(width: ffi::c_int, height: ffi::c_int, title: &str, class_name: &str) -> Self {
      let hwnd = unsafe {
         ffi::CreateWindowExW(
            ffi::WS_EX_CLIENTEDGE,
            to_utf16_os(class_name).as_ptr(),
            to_utf16_os(title).as_ptr(),
            ffi::WS_OVERLAPPEDWINDOW | ffi::WS_VISIBLE,
            ffi::CW_USEDEFAULT, ffi::CW_USEDEFAULT,
            width, height,
            ptr::null_mut(),
            ptr::null_mut(),
            ffi::GetModuleHandleW(ptr::null()),
            ptr::null_mut()
         )
      };

      Window {
         hwnd: hwnd
      }
   }

   pub fn dc(&self) -> ffi::HDC {
      unsafe {
         ffi::GetDC(self.hwnd)
      }
   }

   pub fn show_normal(&self) {
      unsafe {
         ffi::ShowWindow(self.hwnd, ffi::SW_SHOWNORMAL)
      };
   }
}

pub struct Message {
   msg: ffi::MSG
}

impl Message {
   pub fn get() -> Option<Self> {
      let mut msg = unsafe { mem::uninitialized() };

      match unsafe { ffi::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) } {
         0 => None,
         _ => Some(Message {
            msg: msg
         })
      }
   }

   pub fn translate(&self) {
      unsafe {
         ffi::TranslateMessage(&self.msg)
      };
   }

   pub fn dispatch(&self) {
      unsafe {
         ffi::DispatchMessageW(&self.msg)
      };
   }
}
<commit_msg>Adjusting win32 window style<commit_after>#![cfg(target_os = "windows")]

pub mod ffi {
   #![allow(non_snake_case)]

   pub use libc::{
      c_int, c_uint, c_void, uintptr_t, c_long, c_ulong
   };
   pub use libc::types::os::arch::extra::{
      HANDLE, LONG_PTR, LRESULT, HINSTANCE, LPCWSTR, HMODULE, LPVOID, BOOL
   };
   use std::mem;

   pub type HWND = HANDLE;
   pub type HICON = HANDLE;
   pub type HBRUSH = HANDLE;
   pub type HMENU = HANDLE;
   pub type HDC = HANDLE;
   pub type HCURSOR = HICON;

   pub type WPARAM = uintptr_t;
   pub type LPARAM = LONG_PTR;

   pub type ATOM = u16;

   pub type WNDPROC = Option<unsafe extern "system" fn(HWND, c_uint, WPARAM, LPARAM) -> LRESULT>;

   pub const CS_VREDRAW:                 c_ulong = 0x00000001;
   pub const CS_HREDRAW:                 c_ulong = 0x00000002;
   pub const CS_DBLCLKS:                 c_ulong = 0x00000008;
   pub const CS_OWNDC:                   c_ulong = 0x00000020;
   pub const CS_CLASSDC:                 c_ulong = 0x00000040;
   pub const CS_PARENTDC:                c_ulong = 0x00000080;
   pub const CS_NOCLOSE:                 c_ulong = 0x00000200;
   pub const CS_SAVEBITS:                c_ulong = 0x00000800;
   pub const CS_BYTEALIGNCLIENT:         c_ulong = 0x00001000;
   pub const CS_BYTEALIGNWINDOW:         c_ulong = 0x00002000;
   pub const CS_GLOBALCLASS:             c_ulong = 0x00004000;
   pub const CS_IME:                     c_ulong = 0x00010000;
   pub const CS_DROPSHADOW:              c_ulong = 0x00020000;

   pub const WS_OVERLAPPED:              c_ulong = 0x00000000;
   pub const WS_POPUP:                   c_ulong = 0x80000000;
   pub const WS_CHILD:                   c_ulong = 0x40000000;
   pub const WS_MINIMIZE:                c_ulong = 0x20000000;
   pub const WS_VISIBLE:                 c_ulong = 0x10000000;
   pub const WS_DISABLED:                c_ulong = 0x08000000;
   pub const WS_CLIPSIBLINGS:            c_ulong = 0x04000000;
   pub const WS_CLIPCHILDREN:            c_ulong = 0x02000000;
   pub const WS_MAXIMIZE:                c_ulong = 0x01000000;
   pub const WS_CAPTION:                 c_ulong = 0x00C00000;
   pub const WS_BORDER:                  c_ulong = 0x00800000;
   pub const WS_DLGFRAME:                c_ulong = 0x00400000;
   pub const WS_VSCROLL:                 c_ulong = 0x00200000;
   pub const WS_HSCROLL:                 c_ulong = 0x00100000;
   pub const WS_SYSMENU:                 c_ulong = 0x00080000;
   pub const WS_THICKFRAME:              c_ulong = 0x00040000;
   pub const WS_GROUP:                   c_ulong = 0x00020000;
   pub const WS_TABSTOP:                 c_ulong = 0x00010000;
   pub const WS_MINIMIZEBOX:             c_ulong = 0x00020000;
   pub const WS_MAXIMIZEBOX:             c_ulong = 0x00010000;
   pub const WS_TILED:                   c_ulong = WS_OVERLAPPED;
   pub const WS_ICONIC:                  c_ulong = WS_MINIMIZE;
   pub const WS_SIZEBOX:                 c_ulong = WS_THICKFRAME;
   pub const WS_TILEDWINDOW:             c_ulong = WS_OVERLAPPEDWINDOW;
   pub const WS_OVERLAPPEDWINDOW:        c_ulong = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
   pub const WS_POPUPWINDOW:             c_ulong = WS_POPUP | WS_BORDER | WS_SYSMENU;
   pub const WS_CHILDWINDOW:             c_ulong = WS_CHILD;

   pub const WS_EX_DLGMODALFRAME:        c_ulong = 0x00000001;
   pub const WS_EX_NOPARENTNOTIFY:       c_ulong = 0x00000004;
   pub const WS_EX_TOPMOST:              c_ulong = 0x00000008;
   pub const WS_EX_ACCEPTFILES:          c_ulong = 0x00000010;
   pub const WS_EX_TRANSPARENT:          c_ulong = 0x00000020;
   pub const WS_EX_MDICHILD:             c_ulong = 0x00000040;
   pub const WS_EX_TOOLWINDOW:           c_ulong = 0x00000080;
   pub const WS_EX_WINDOWEDGE:           c_ulong = 0x00000100;
   pub const WS_EX_CLIENTEDGE:           c_ulong = 0x00000200;
   pub const WS_EX_CONTEXTHELP:          c_ulong = 0x00000400;
   pub const WS_EX_RIGHT:                c_ulong = 0x00001000;
   pub const WS_EX_LEFT:                 c_ulong = 0x00000000;
   pub const WS_EX_RTLREADING:           c_ulong = 0x00002000;
   pub const WS_EX_LTRREADING:           c_ulong = 0x00000000;
   pub const WS_EX_LEFTSCROLLBAR:        c_ulong = 0x00004000;
   pub const WS_EX_RIGHTSCROLLBAR:       c_ulong = 0x00000000;
   pub const WS_EX_CONTROLPARENT:        c_ulong = 0x00010000;
   pub const WS_EX_STATICEDGE:           c_ulong = 0x00020000;
   pub const WS_EX_APPWINDOW:            c_ulong = 0x00040000;
   pub const WS_EX_OVERLAPPEDWINDOW:     c_ulong = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE;
   pub const WS_EX_PALETTEWINDOW:        c_ulong = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
   pub const WS_EX_LAYERED:              c_ulong = 0x00080000;
   pub const WS_EX_NOINHERITLAYOUT:      c_ulong = 0x00100000;
   pub const WS_EX_NOREDIRECTIONBITMAP:  c_ulong = 0x00200000;
   pub const WS_EX_LAYOUTRTL:            c_ulong = 0x00400000;
   pub const WS_EX_COMPOSITED:           c_ulong = 0x02000000;
   pub const WS_EX_NOACTIVATE:           c_ulong = 0x08000000;

   pub const CW_USEDEFAULT:                c_int = 0x80000000u32 as c_int;

   pub const WM_CREATE:                   c_uint = 1;
   pub const WM_CLOSE:                    c_uint = 16;

   pub const SW_SHOWNORMAL:                c_int = 1;
   pub const SW_SHOWMINIMIZED:             c_int = 2;
   pub const SW_MAXIMIZE:                  c_int = 3;
   pub const SW_SHOWMAXIMIZED:             c_int = 3;
   pub const SW_SHOWNOACTIVATE:            c_int = 4;
   pub const SW_SHOW:                      c_int = 5;
   pub const SW_MINIMIZE:                  c_int = 6;
   pub const SW_SHOWMINNOACTIVE:           c_int = 7;
   pub const SW_SHOWNA:                    c_int = 8;
   pub const SW_RESTORE:                   c_int = 9;
   pub const SW_SHOWDEFAULT:               c_int = 10;
   pub const SW_FORCEMINIMIZE:             c_int = 11;

   #[repr(C)]
   #[derive(Copy)]
   pub struct WNDCLASSEXW {
      pub cbSize: c_uint,
      pub style: c_uint,
      pub lpfnWndProc: WNDPROC,
      pub cbClsExtra: c_int,
      pub cbWndExtra: c_int,
      pub hInstance: HINSTANCE,
      pub hIcon: HICON,
      pub hCursor: HCURSOR,
      pub hbrBackground: HBRUSH,
      pub lpszMenuName: LPCWSTR,
      pub lpszClassName: LPCWSTR,
      pub hIconSm: HICON,
   }
   impl Clone for WNDCLASSEXW {
      fn clone(&self) -> Self { *self }
   }
   impl Default for WNDCLASSEXW {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   #[repr(C)]
   #[derive(Copy)]
   pub struct POINT {
      pub x: c_long,
      pub y: c_long,
   }
   impl Clone for POINT {
      fn clone(&self) -> Self { *self }
   }
   impl Default for POINT {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   #[repr(C)]
   #[derive(Copy)]
   pub struct MSG {
      pub hwnd: HWND,
      pub message: c_uint,
      pub wParam: WPARAM,
      pub lParam: LPARAM,
      pub time: c_ulong,
      pub pt: POINT,
   }
   impl Clone for MSG {
      fn clone(&self) -> Self { *self }
   }
   impl Default for MSG {
      fn default() -> Self { unsafe { mem::zeroed() } }
   }

   extern "system" {
      pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;

      pub fn RegisterClassExW(lpWndClass: *const WNDCLASSEXW) -> ATOM;

      pub fn ShowWindow(hwnd: HWND, nCmdShow: c_int) -> BOOL;

      pub fn PostQuitMessage(nExitCode: c_int);

      pub fn TranslateMessage(lpmsg: *const MSG) -> BOOL;

      pub fn DispatchMessageW(lpmsg: *const MSG) -> LRESULT;

      pub fn GetDC(hwnd: HWND) -> HDC;

      pub fn DefWindowProcW(
         hwnd: HWND,
         Msg: c_uint,
         wParam: WPARAM,
         lParam: LPARAM
      ) -> LRESULT;

      pub fn CreateWindowExW(
         dwExStyle: c_ulong,
         lpClassName: LPCWSTR,
         lpWindowName: LPCWSTR,
         dwStyle: c_ulong,
         x: c_int,
         y: c_int,
         nWidth: c_int,
         nHeight: c_int,
         hWndParent: HWND,
         hMenu: HMENU,
         hInstance: HINSTANCE,
         lpParam: LPVOID,
      ) -> HWND;

      pub fn GetMessageW(
         lpMsg: *const MSG,
         hwnd: HWND,
         wMsgFilterMin: c_uint,
         wMsgFilterMax: c_uint
      ) -> BOOL;
   }
}

use std::ptr;
use std::mem;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;

fn to_utf16_os(s: &str) -> Vec<u16> {
   let mut v: Vec<_> = OsStr::new(s).encode_wide().collect();
   v.push(0);
   v
}

unsafe extern "system" fn wnd_proc(
   hwnd: ffi::HWND,
   msg: ffi::c_uint,
   wparam: ffi::WPARAM,
   lparam: ffi::LPARAM
) -> ffi::LRESULT {
   match msg {
      ffi::WM_CLOSE => {
         ffi::PostQuitMessage(0);
      },
      ffi::WM_CREATE => {
         return 0;
      },
      _ => {
         return ffi::DefWindowProcW(hwnd, msg, wparam, lparam);
      }
   }

   return 0;
}

pub fn register_window_class(class_name: &str) {
   unsafe {
      let wnd_class = ffi::WNDCLASSEXW {
         cbSize: mem::size_of::<ffi::WNDCLASSEXW>() as ffi::c_uint,
         style: ffi::CS_HREDRAW | ffi::CS_VREDRAW | ffi::CS_OWNDC,
         lpfnWndProc: Some(wnd_proc),
         cbClsExtra: 0,
         cbWndExtra: 0,
         hInstance: ffi::GetModuleHandleW(ptr::null()),
         hIcon: ptr::null_mut(),
         hCursor: ptr::null_mut(),
         hbrBackground: ptr::null_mut(),
         lpszMenuName: ptr::null(),
         lpszClassName: to_utf16_os(class_name).as_ptr(),
         hIconSm: ptr::null_mut(),
      };

      ffi::RegisterClassExW(&wnd_class);
   }
}

pub struct Window {
   pub hwnd: ffi::HWND
}

impl Window {
   pub fn create(width: ffi::c_int, height: ffi::c_int, title: &str, class_name: &str) -> Self {
      let hwnd = unsafe {
         ffi::CreateWindowExW(
            ffi::WS_EX_APPWINDOW | ffi::WS_EX_WINDOWEDGE,
            to_utf16_os(class_name).as_ptr(),
            to_utf16_os(title).as_ptr(),
            ffi::WS_OVERLAPPEDWINDOW | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN,
            ffi::CW_USEDEFAULT, ffi::CW_USEDEFAULT,
            width, height,
            ptr::null_mut(),
            ptr::null_mut(),
            ffi::GetModuleHandleW(ptr::null()),
            ptr::null_mut()
         )
      };

      Window {
         hwnd: hwnd
      }
   }

   pub fn dc(&self) -> ffi::HDC {
      unsafe {
         ffi::GetDC(self.hwnd)
      }
   }

   pub fn show_normal(&self) {
      unsafe {
         ffi::ShowWindow(self.hwnd, ffi::SW_SHOWNORMAL)
      };
   }
}

pub struct Message {
   msg: ffi::MSG
}

impl Message {
   pub fn get() -> Option<Self> {
      let mut msg = unsafe { mem::uninitialized() };

      match unsafe { ffi::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) } {
         0 => None,
         _ => Some(Message {
            msg: msg
         })
      }
   }

   pub fn translate(&self) {
      unsafe {
         ffi::TranslateMessage(&self.msg)
      };
   }

   pub fn dispatch(&self) {
      unsafe {
         ffi::DispatchMessageW(&self.msg)
      };
   }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Unix-specific extension to the primitives in the `std::ffi` module

#![stable(feature = "rust1", since = "1.0.0")]

use ffi::{OsStr, OsString};
use mem;
use sys::os_str::Buf;
use sys_common::{FromInner, IntoInner, AsInner};

/// Unix-specific extensions to `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
    /// Creates an `OsString` from a byte vector.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn from_vec(vec: Vec<u8>) -> Self;

    /// Yields the underlying byte vector of this `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into_vec(self) -> Vec<u8>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl OsStringExt for OsString {
    fn from_vec(vec: Vec<u8>) -> OsString {
        FromInner::from_inner(Buf { inner: vec })
    }
    fn into_vec(self) -> Vec<u8> {
        self.into_inner().inner
    }
}

/// Unix-specific extensions to `OsStr`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn from_bytes(slice: &[u8]) -> &Self;

    /// Gets the underlying byte view of the `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_bytes(&self) -> &[u8];
}

#[stable(feature = "rust1", since = "1.0.0")]
impl OsStrExt for OsStr {
    fn from_bytes(slice: &[u8]) -> &OsStr {
        unsafe { mem::transmute(slice) }
    }
    fn as_bytes(&self) -> &[u8] {
        &self.as_inner().inner
    }
}
<commit_msg>Rollup merge of #39065 - frewsxcv:libstd-os-unix-ffi-docs, r=GuillaumeGomez<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Unix-specific extension to the primitives in the `std::ffi` module

#![stable(feature = "rust1", since = "1.0.0")]

use ffi::{OsStr, OsString};
use mem;
use sys::os_str::Buf;
use sys_common::{FromInner, IntoInner, AsInner};

/// Unix-specific extensions to `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
    /// Creates an [`OsString`] from a byte vector.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::ffi::OsString;
    /// use std::os::unix::ffi::OsStringExt;
    ///
    /// let bytes = b"foo".to_vec();
    /// let os_string = OsString::from_vec(bytes);
    /// assert_eq!(os_string.to_str(), Some("foo"));
    /// ```
    ///
    /// [`OsString`]: ../../../ffi/struct.OsString.html
    #[stable(feature = "rust1", since = "1.0.0")]
    fn from_vec(vec: Vec<u8>) -> Self;

    /// Yields the underlying byte vector of this [`OsString`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::ffi::OsString;
    /// use std::os::unix::ffi::OsStringExt;
    ///
    /// let mut os_string = OsString::new();
    /// os_string.push("foo");
    /// let bytes = os_string.into_vec();
    /// assert_eq!(bytes, b"foo");
    /// ```
    ///
    /// [`OsString`]: ../../../ffi/struct.OsString.html
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into_vec(self) -> Vec<u8>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl OsStringExt for OsString {
    fn from_vec(vec: Vec<u8>) -> OsString {
        FromInner::from_inner(Buf { inner: vec })
    }
    fn into_vec(self) -> Vec<u8> {
        self.into_inner().inner
    }
}

/// Unix-specific extensions to `OsStr`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
    #[stable(feature = "rust1", since = "1.0.0")]
    /// Creates an [`OsStr`] from a byte slice.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::ffi::OsStr;
    /// use std::os::unix::ffi::OsStrExt;
    ///
    /// let bytes = b"foo";
    /// let os_str = OsStr::from_bytes(bytes);
    /// assert_eq!(os_str.to_str(), Some("foo"));
    /// ```
    ///
    /// [`OsStr`]: ../../../ffi/struct.OsStr.html
    fn from_bytes(slice: &[u8]) -> &Self;

    /// Gets the underlying byte view of the [`OsStr`] slice.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::ffi::OsStr;
    /// use std::os::unix::ffi::OsStrExt;
    ///
    /// let mut os_str = OsStr::new("foo");
    /// let bytes = os_str.as_bytes();
    /// assert_eq!(bytes, b"foo");
    /// ```
    ///
    /// [`OsStr`]: ../../../ffi/struct.OsStr.html
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_bytes(&self) -> &[u8];
}

#[stable(feature = "rust1", since = "1.0.0")]
impl OsStrExt for OsStr {
    fn from_bytes(slice: &[u8]) -> &OsStr {
        unsafe { mem::transmute(slice) }
    }
    fn as_bytes(&self) -> &[u8] {
        &self.as_inner().inner
    }
}
<|endoftext|>