<commit_before>pub trait Bits {
    const BITS: u32 = 0;
    type Signed;
    type Unsigned;

    fn bits(self, start: u32, end: u32) -> Self;
    fn bits_from(self, start: u32) -> Self;
    fn bit(self, offset: u32) -> Self;

    #[allow(clippy::wrong_self_convention)]
    fn is_bit_set(self, offset: u32) -> bool;
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self;
    fn replace_bit(self, offset: u32, value: bool) -> Self;
    fn sign_extend(self, bits: u32) -> Self;
}

impl Bits for u32 {
    const BITS: u32 = 32;
    type Signed = i32;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}

impl Bits for u16 {
    const BITS: u32 = 16;
    type Signed = i32;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}

impl Bits for u64 {
    const BITS: u32 = 64;
    type Signed = i64;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}
<commit_msg>Add `Bits` implementation for u8.<commit_after>pub trait Bits {
    const BITS: u32 = 0;
    type Signed;
    type Unsigned;

    fn bits(self, start: u32, end: u32) -> Self;
    fn bits_from(self, start: u32) -> Self;
    fn bit(self, offset: u32) -> Self;

    #[allow(clippy::wrong_self_convention)]
    fn is_bit_set(self, offset: u32) -> bool;
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self;
    fn replace_bit(self, offset: u32, value: bool) -> Self;
    fn sign_extend(self, bits: u32) -> Self;
}

impl Bits for u32 {
    const BITS: u32 = 32;
    type Signed = i32;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}

impl Bits for u16 {
    const BITS: u32 = 16;
    type Signed = i32;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}

impl Bits for u64 {
    const BITS: u32 = 64;
    type Signed = i64;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}

impl Bits for u8 {
    const BITS: u32 = 8;
    type Signed = i8;
    type Unsigned = Self;

    #[inline(always)]
    fn bits(self, start: u32, end: u32) -> Self {
        (self >> start) & ((1 << (end - start + 1)) - 1)
    }

    #[inline(always)]
    fn bits_from(self, start: u32) -> Self {
        (self >> start) & 1
    }

    #[inline(always)]
    fn bit(self, offset: u32) -> Self {
        (self >> offset) & 1
    }

    #[inline(always)]
    fn is_bit_set(self, offset: u32) -> bool {
        self.bit(offset) != 0
    }

    #[inline(always)]
    fn replace_bits(self, start: u32, end: u32, value: Self) -> Self {
        (self & !(((1 << (end - start + 1)) - 1) << start))
            | ((value & ((1 << (end - start + 1)) - 1)) << start)
    }

    #[inline(always)]
    fn replace_bit(self, offset: u32, value: bool) -> Self {
        self.replace_bits(offset, offset, value as Self)
    }

    #[inline(always)]
    fn sign_extend(self, bits: u32) -> Self {
        (((self << (Self::BITS as Self - bits as Self)) as Self::Signed) >> (32 - bits)) as Self
    }
}
<|endoftext|>


<commit_before>// Copyright 2017, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#[cfg(windows)]
extern crate winapi;
#[cfg(all(not(windows), feature = "dox"))]
pub mod winapi {
    pub struct HDC;
}

use std::ops::Deref;

#[cfg(feature = "use_glib")]
use glib::translate::*;
use ffi;
use ffi::enums::{Format, SurfaceType};
use surface::{Surface, SurfaceExt};
use Status;

#[derive(Debug)]
pub struct Win32Surface(Surface);

impl Win32Surface {
    pub fn from(surface: Surface) -> Result<Win32Surface, Surface> {
        if surface.get_type() == SurfaceType::Win32 {
            Ok(Win32Surface(surface))
        } else {
            Err(surface)
        }
    }

    #[doc(hidden)]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Result<Win32Surface, Status> {
        let surface = Self::from(Surface::from_raw_full(ptr)).unwrap();
        let status = surface.status();
        match status {
            Status::Success => Ok(surface),
            _ => Err(status)
        }
    }

    pub fn create(hdc: winapi::HDC) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create(hdc)) }
    }

    pub fn create_with_dib(format: Format, width: i32, height: i32) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create_with_dib(format, width, height)) }
    }

    pub fn create_with_ddb(hdc: winapi::HDC,
                           format: Format,
                           width: i32,
                           height: i32)
                           -> Result<Win32Surface, Status> {
        unsafe {
            Self::from_raw_full(ffi::cairo_win32_surface_create_with_ddb(hdc, format, width, height))
        }
    }

    pub fn printing_surface_create(hdc: winapi::HDC) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_printing_surface_create(hdc)) }
    }
}

#[cfg(feature = "use_glib")]
impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for Win32Surface {
    type Storage = &'a Surface;

    #[inline]
    fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> {
        let stash = self.0.to_glib_none();
        Stash(stash.0, stash.1)
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_none(ptr)).unwrap()
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_borrow(ptr)).unwrap()
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_full(ptr)).unwrap()
    }
}

impl AsRef<Surface> for Win32Surface {
    fn as_ref(&self) -> &Surface {
        &self.0
    }
}

impl Deref for Win32Surface {
    type Target = Surface;

    fn deref(&self) -> &Surface {
        &self.0
    }
}

impl Clone for Win32Surface {
    fn clone(&self) -> Win32Surface {
        Win32Surface(self.0.clone())
    }
}
<commit_msg>Fix dox for non-windows<commit_after>// Copyright 2017, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#[cfg(windows)]
extern crate winapi;
#[cfg(all(not(windows), feature = "dox"))]
pub use ffi::winapi;

use std::ops::Deref;

#[cfg(feature = "use_glib")]
use glib::translate::*;
use ffi;
use ffi::enums::{Format, SurfaceType};
use surface::{Surface, SurfaceExt};
use Status;

#[derive(Debug)]
pub struct Win32Surface(Surface);

impl Win32Surface {
    pub fn from(surface: Surface) -> Result<Win32Surface, Surface> {
        if surface.get_type() == SurfaceType::Win32 {
            Ok(Win32Surface(surface))
        } else {
            Err(surface)
        }
    }

    #[doc(hidden)]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Result<Win32Surface, Status> {
        let surface = Self::from(Surface::from_raw_full(ptr)).unwrap();
        let status = surface.status();
        match status {
            Status::Success => Ok(surface),
            _ => Err(status)
        }
    }

    pub fn create(hdc: winapi::HDC) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create(hdc)) }
    }

    pub fn create_with_dib(format: Format, width: i32, height: i32) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create_with_dib(format, width, height)) }
    }

    pub fn create_with_ddb(hdc: winapi::HDC,
                           format: Format,
                           width: i32,
                           height: i32)
                           -> Result<Win32Surface, Status> {
        unsafe {
            Self::from_raw_full(ffi::cairo_win32_surface_create_with_ddb(hdc, format, width, height))
        }
    }

    pub fn printing_surface_create(hdc: winapi::HDC) -> Result<Win32Surface, Status> {
        unsafe { Self::from_raw_full(ffi::cairo_win32_printing_surface_create(hdc)) }
    }
}

#[cfg(feature = "use_glib")]
impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for Win32Surface {
    type Storage = &'a Surface;

    #[inline]
    fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> {
        let stash = self.0.to_glib_none();
        Stash(stash.0, stash.1)
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_none(ptr)).unwrap()
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_borrow(ptr)).unwrap()
    }
}

#[cfg(feature = "use_glib")]
impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for Win32Surface {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> Win32Surface {
        Self::from(from_glib_full(ptr)).unwrap()
    }
}

impl AsRef<Surface> for Win32Surface {
    fn as_ref(&self) -> &Surface {
        &self.0
    }
}

impl Deref for Win32Surface {
    type Target = Surface;

    fn deref(&self) -> &Surface {
        &self.0
    }
}

impl Clone for Win32Surface {
    fn clone(&self) -> Win32Surface {
        Win32Surface(self.0.clone())
    }
}
<|endoftext|>


<commit_before>use std::io::{Read, Write};
use wire::data::PeerMsg;
use std::thread;
use std::sync::mpsc::{Sender, Receiver, channel};
use byteorder::{BigEndian, ReadBytesExt};
use byteorder::ByteOrder;

pub struct PeerManager<S: Read + Write> {
    source: S
}

struct StreamContainer<S: Read + Write> {
   src: S
}

impl<S: Read + Write> StreamContainer<S> {
    pub fn new(src: S) -> StreamContainer<S> {
        StreamContainer {
            src: src
        }
    }

    fn _read_message_bytes(&mut self) -> Vec<u8> {
        let mut buf = vec![0, 0, 0, 0];
        self.src.read_exact(&mut buf);
        let size = BigEndian::read_u32(&buf);
        let mut message_vec: Vec<u8> = Vec::with_capacity(size as usize);
        for i in 0..size {
            message_vec.push(0);
        }
        self.src.read_exact(&mut message_vec);
        buf.append(&mut message_vec);
        buf
    }

    pub fn run(mut self, tx: Sender<Vec<u8>>) {
        loop {
            let bytes = self._read_message_bytes();
            tx.send(bytes);
        }
    }

}

pub type Err = ();
impl<S: Read + Write> PeerManager<S> {
    pub fn send_message(&self, msg: PeerMsg) -> Result<PeerMsg, Err> {
        unimplemented!();
    }

    pub fn message_available(&self) -> bool {
        unimplemented!();
    }

    pub fn wait_message(&self) -> Result<PeerMsg, Err> {
        unimplemented!();
    }

}
<commit_msg>Need to change implementation of socket -- cannot share Read<commit_after>use std::io::{Read};
use wire::data::PeerMsg;
use std::thread;
use std::sync::mpsc::{Sender, Receiver, channel};
use byteorder::{BigEndian, ReadBytesExt};
use byteorder::ByteOrder;

struct StreamContainer<S: Read + Send> {
   src: S
}

impl<S: Read + Send> StreamContainer<S> {
    pub fn new(src: S) -> StreamContainer<S> {
        StreamContainer {
            src: src
        }
    }

    fn _read_message_bytes(&mut self) -> Vec<u8> {
        let mut buf = vec![0, 0, 0, 0];
        self.src.read_exact(&mut buf);
        let size = BigEndian::read_u32(&buf);
        let mut message_vec: Vec<u8> = Vec::with_capacity(size as usize);
        for i in 0..size {
            message_vec.push(0);
        }
        self.src.read_exact(&mut message_vec);
        buf.append(&mut message_vec);
        buf
    }

    pub fn run(mut self, tx: Sender<Vec<u8>>) {
        loop {
            let bytes = self._read_message_bytes();
            tx.send(bytes);
        }
    }

}

pub struct PeerManager {
    src: Receiver<Vec<u8>>
}

pub type Err = ();
impl PeerManager {
    pub fn from<S: Read>(src: S) -> PeerManager where S: Send {
        let (tx, rx) = channel();
        let container = StreamContainer::new(src);
        let job = move || container.run(tx);
        thread::spawn(job);
        PeerManager { src: rx }
    }

    pub fn send_message(&self, msg: PeerMsg) -> Result<PeerMsg, Err> {
        unimplemented!();
    }

    pub fn message_available(&self) -> bool {
        unimplemented!();
    }

    pub fn wait_message(&self) -> Result<PeerMsg, Err> {
        unimplemented!();
    }

}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/// Get the executable path (as `OsString`).
#[macro_export]
macro_rules! executable_os(
    () => ({
        &std::env::args_os().next().unwrap()
    })
);

/// Get the executable path (as `String`; lossless).
#[macro_export]
macro_rules! executable(
    () => ({
        let exe = match $crate::executable_os!().to_str() {
            // * UTF-8
            Some(s) => s.to_string(),
            // * "lossless" debug format if `executable_os!()` is not well-formed UTF-8
            None => format!("{:?}", $crate::executable_os!())
        };
        &exe.to_owned()
    })
);

/// Get the executable name.
#[macro_export]
macro_rules! executable_name(
    () => ({
        &std::path::Path::new($crate::executable_os!()).file_stem().unwrap().to_string_lossy()
    })
);

/// Derive the utility name.
#[macro_export]
macro_rules! util_name(
    () => ({
        let crate_name = env!("CARGO_PKG_NAME");
        if crate_name.starts_with("uu_") {
            &crate_name[3..]
        } else {
            &crate_name
        }
    })
);

//====

#[macro_export]
macro_rules! show(
    ($err:expr) => ({
        let e = $err;
        uucore::error::set_exit_code(e.code());
        eprintln!("{}: {}", $crate::util_name!(), e);
    })
);

#[macro_export]
macro_rules! show_if_err(
    ($res:expr) => ({
        if let Err(e) = $res {
            show!(e);
        }
    })
);

/// Show an error to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", $crate::util_name!());
        eprintln!($($args)+);
    })
);

/// Show a warning to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error_custom_description (
    ($err:expr,$($args:tt)+) => ({
        eprint!("{}: {}: ", $crate::util_name!(), $err);
        eprintln!($($args)+);
    })
);

#[macro_export]
macro_rules! show_warning(
    ($($args:tt)+) => ({
        eprint!("{}: warning: ", $crate::util_name!());
        eprintln!($($args)+);
    })
);

/// Show a bad invocation help message in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_usage_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", $crate::util_name!());
        eprintln!($($args)+);
        eprintln!("Try `{:?} --help` for more information.", $crate::executable!());
    })
);

//====

/// Calls `exit()` with the provided exit code.
#[macro_export]
macro_rules! exit(
    ($exit_code:expr) => ({
        ::std::process::exit($exit_code)
    })
);

/// Display the provided error message, then `exit()` with the provided exit code
#[macro_export]
macro_rules! crash(
    ($exit_code:expr, $($args:tt)+) => ({
        $crate::show_error!($($args)+);
        $crate::exit!($exit_code)
    })
);

/// Unwraps the Result. Instead of panicking, it exists the program with the
/// provided exit code.
#[macro_export]
macro_rules! crash_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => $crate::crash!($exit_code, "{}", f),
        }
    )
);

//====

/// Unwraps the Result. Instead of panicking, it shows the error and then
/// returns from the function with the provided exit code.
/// Assumes the current function returns an i32 value.
#[macro_export]
macro_rules! return_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => {
                $crate::show_error!("{}", f);
                return $exit_code;
            }
        }
    )
);

//====

#[macro_export]
macro_rules! safe_write(
    ($fd:expr, $($args:tt)+) => (
        match write!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

#[macro_export]
macro_rules! safe_writeln(
    ($fd:expr, $($args:tt)+) => (
        match writeln!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

/// Unwraps the Result. Instead of panicking, it exists the program with exit
/// code 1.
#[macro_export]
macro_rules! safe_unwrap(
    ($exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => $crate::crash!(1, "{}", f.to_string())
        }
    )
);

//-- message templates

//-- message templates : (join utility sub-macros)

#[macro_export]
macro_rules! snippet_list_join_oxford_comma {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{}, {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, $crate::snippet_list_join_oxford_comma!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

#[macro_export]
macro_rules! snippet_list_join {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{} {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, $crate::snippet_list_join_oxford_comma!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

//-- message templates : invalid input

#[macro_export]
macro_rules! msg_invalid_input {
    ($reason: expr) => {
        format!("invalid input: {}", $reason)
    };
}

// -- message templates : invalid input : flag

#[macro_export]
macro_rules! msg_invalid_opt_use {
    ($about:expr, $flag:expr) => {
        $crate::msg_invalid_input!(format!("The '{}' option {}", $flag, $about))
    };
    ($about:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_input!(format!(
            "The '{}' ('{}') option {}",
            $long_flag, $short_flag, $about
        ))
    };
}

#[macro_export]
macro_rules! msg_opt_only_usable_if {
    ($clause:expr, $flag:expr) => {
        $crate::msg_invalid_opt_use!(format!("only usable if {}", $clause), $flag)
    };
    ($clause:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("only usable if {}", $clause),
            $long_flag,
            $short_flag
        )
    };
}

#[macro_export]
macro_rules! msg_opt_invalid_should_be {
    ($expects:expr, $received:expr, $flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $flag
        )
    };
    ($expects:expr, $received:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $long_flag,
            $short_flag
        )
    };
}

// -- message templates : invalid input : input combinations

#[macro_export]
macro_rules! msg_expects_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        $crate::msg_invalid_input!(format!("expects one of {}", $crate::snippet_list_join!("or", $valOne $(, $remaining_values)*)))
    );
}

#[macro_export]
macro_rules! msg_expects_no_more_than_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        $crate::msg_invalid_input!(format!("expects no more than one of {}", $crate::snippet_list_join!("or", $valOne $(, $remaining_values)*))) ;
    );
}
<commit_msg>refactor/uucore ~ align return values for executable/util macros<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/// Get the executable path (as `OsString`).
#[macro_export]
macro_rules! executable_os(
    () => ({
        &std::env::args_os().next().unwrap()
    })
);

/// Get the executable path (as `String`; lossless).
#[macro_export]
macro_rules! executable(
    () => ({
        let exe = match $crate::executable_os!().to_str() {
            // * UTF-8
            Some(s) => s.to_string(),
            // * "lossless" debug format (if/when `executable_os!()` is not well-formed UTF-8)
            None => format!("{:?}", $crate::executable_os!())
        };
        &exe.to_owned()
    })
);

/// Get the executable name.
#[macro_export]
macro_rules! executable_name(
    () => ({
        let stem = &std::path::Path::new($crate::executable_os!()).file_stem().unwrap().to_owned();
        let exe = match stem.to_str() {
            // * UTF-8
            Some(s) => s.to_string(),
            // * "lossless" debug format (if/when `executable_os!()` is not well-formed UTF-8)
            None => format!("{:?}", stem)
        };
        &exe.to_owned()
    })
);

/// Derive the utility name.
#[macro_export]
macro_rules! util_name(
    () => ({
        let crate_name = env!("CARGO_PKG_NAME");
        let name = if crate_name.starts_with("uu_") {
            &crate_name[3..]
        } else {
            crate_name
        };
        &name.to_owned()
    })
);

//====

#[macro_export]
macro_rules! show(
    ($err:expr) => ({
        let e = $err;
        uucore::error::set_exit_code(e.code());
        eprintln!("{}: {}", $crate::util_name!(), e);
    })
);

#[macro_export]
macro_rules! show_if_err(
    ($res:expr) => ({
        if let Err(e) = $res {
            show!(e);
        }
    })
);

/// Show an error to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", $crate::util_name!());
        eprintln!($($args)+);
    })
);

/// Show a warning to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error_custom_description (
    ($err:expr,$($args:tt)+) => ({
        eprint!("{}: {}: ", $crate::util_name!(), $err);
        eprintln!($($args)+);
    })
);

#[macro_export]
macro_rules! show_warning(
    ($($args:tt)+) => ({
        eprint!("{}: warning: ", $crate::util_name!());
        eprintln!($($args)+);
    })
);

/// Show a bad invocation help message in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_usage_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", $crate::util_name!());
        eprintln!($($args)+);
        eprintln!("Try `{:?} --help` for more information.", $crate::executable!());
    })
);

//====

/// Calls `exit()` with the provided exit code.
#[macro_export]
macro_rules! exit(
    ($exit_code:expr) => ({
        ::std::process::exit($exit_code)
    })
);

/// Display the provided error message, then `exit()` with the provided exit code
#[macro_export]
macro_rules! crash(
    ($exit_code:expr, $($args:tt)+) => ({
        $crate::show_error!($($args)+);
        $crate::exit!($exit_code)
    })
);

/// Unwraps the Result. Instead of panicking, it exists the program with the
/// provided exit code.
#[macro_export]
macro_rules! crash_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => $crate::crash!($exit_code, "{}", f),
        }
    )
);

//====

/// Unwraps the Result. Instead of panicking, it shows the error and then
/// returns from the function with the provided exit code.
/// Assumes the current function returns an i32 value.
#[macro_export]
macro_rules! return_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => {
                $crate::show_error!("{}", f);
                return $exit_code;
            }
        }
    )
);

//====

#[macro_export]
macro_rules! safe_write(
    ($fd:expr, $($args:tt)+) => (
        match write!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

#[macro_export]
macro_rules! safe_writeln(
    ($fd:expr, $($args:tt)+) => (
        match writeln!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

/// Unwraps the Result. Instead of panicking, it exists the program with exit
/// code 1.
#[macro_export]
macro_rules! safe_unwrap(
    ($exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => $crate::crash!(1, "{}", f.to_string())
        }
    )
);

//-- message templates

//-- message templates : (join utility sub-macros)

#[macro_export]
macro_rules! snippet_list_join_oxford_comma {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{}, {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, $crate::snippet_list_join_oxford_comma!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

#[macro_export]
macro_rules! snippet_list_join {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{} {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, $crate::snippet_list_join_oxford_comma!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

//-- message templates : invalid input

#[macro_export]
macro_rules! msg_invalid_input {
    ($reason: expr) => {
        format!("invalid input: {}", $reason)
    };
}

// -- message templates : invalid input : flag

#[macro_export]
macro_rules! msg_invalid_opt_use {
    ($about:expr, $flag:expr) => {
        $crate::msg_invalid_input!(format!("The '{}' option {}", $flag, $about))
    };
    ($about:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_input!(format!(
            "The '{}' ('{}') option {}",
            $long_flag, $short_flag, $about
        ))
    };
}

#[macro_export]
macro_rules! msg_opt_only_usable_if {
    ($clause:expr, $flag:expr) => {
        $crate::msg_invalid_opt_use!(format!("only usable if {}", $clause), $flag)
    };
    ($clause:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("only usable if {}", $clause),
            $long_flag,
            $short_flag
        )
    };
}

#[macro_export]
macro_rules! msg_opt_invalid_should_be {
    ($expects:expr, $received:expr, $flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $flag
        )
    };
    ($expects:expr, $received:expr, $long_flag:expr, $short_flag:expr) => {
        $crate::msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $long_flag,
            $short_flag
        )
    };
}

// -- message templates : invalid input : input combinations

#[macro_export]
macro_rules! msg_expects_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        $crate::msg_invalid_input!(format!("expects one of {}", $crate::snippet_list_join!("or", $valOne $(, $remaining_values)*)))
    );
}

#[macro_export]
macro_rules! msg_expects_no_more_than_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        $crate::msg_invalid_input!(format!("expects no more than one of {}", $crate::snippet_list_join!("or", $valOne $(, $remaining_values)*))) ;
    );
}
<|endoftext|>


<commit_before>use std::{cmp::Ordering, path::Path};

use async_trait::async_trait;
use indexmap::IndexMap;
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json;

use crate::{
    build::BuildStep,
    bundle::{
        layout::{ios::IOsKbdLayer, IOsPlatform},
        KbdgenBundle,
    },
    util::split_keys,
};

#[derive(Serialize, Deserialize)]
pub struct IosInfo {
    name: String,
    locale: String,
    enter: String,
    space: String,
}

/// Removes all occurances of `character` in `input`
pub fn remove_all_occurances(input: String, character: char) -> String {
    input
        .as_str()
        .chars()
        .filter(|x| x.cmp(&character) != Ordering::Equal)
        .into_iter()
        .collect::<String>()
}

pub fn keyboard_component_from_string(input: String) -> Option<IosButton> {
    let regex = Regex::new(r"^\\s\{([^}:]+)(?::(\d+(?:\.\d+)?))?\}$").expect("valid regex");
    let captures = regex.captures(input.as_str());

    if let Some(captures) = captures {
        if let Some(id) = captures.get(1) {
            let id = match id.as_str().chars().next().unwrap().cmp(&'\"') {
                Ordering::Equal => remove_all_occurances(id.as_str().to_string(), '\"'),
                _ => format!("_{}", remove_all_occurances(id.as_str().to_string(), '\"')),
            };
            if let Some(width) = captures.get(2) {
                Some(IosButton {
                    id: id,
                    width: width.as_str().parse::<f32>().expect("invalid float value"),
                })
            } else {
                Some(IosButton {
                    id: id,
                    width: 1.0f32,
                })
            }
        } else {
            return None;
        }
    } else {
        return None;
    }
}

#[derive(Serialize, Deserialize)]
pub struct IosButton {
    id: String,
    width: f32,
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum IosKeyMapType {
    Character(String),
    Button(IosButton),
}

#[derive(Serialize, Deserialize)]
pub struct IosPlatform {
    #[serde(flatten)]
    layer: IndexMap<String, Vec<Vec<IosKeyMapType>>>,
}

#[derive(Serialize, Deserialize)]
pub struct IosDeadKeys {
    iphone: IndexMap<String, String>,
    #[serde(rename = "ipad-9in")]
    i_pad_9in: IndexMap<String, String>,
    #[serde(rename = "ipad-12in")]
    i_pad_12in: IndexMap<String, String>,
}

#[derive(Serialize, Deserialize)]
pub struct IosKeyboardDefinitions {
    #[serde(flatten)]
    info: IosInfo,
    longpress: IndexMap<String, Vec<String>>,
    dead_keys: IosDeadKeys,
    transforms: serde_json::value::Value,
    iphone: IosPlatform,
    i_pad_9in: IosPlatform,
    i_pad_12in: IosPlatform,
}

pub fn ios_layer_name(layer: &IOsKbdLayer) -> String {
    match layer {
        IOsKbdLayer::Default => "normal",
        IOsKbdLayer::Shift => "shifted",
        IOsKbdLayer::Alt => "alt",
        IOsKbdLayer::AltAndShift => "alt+shift",
        IOsKbdLayer::Symbols1 => "symbols-1",
        IOsKbdLayer::Symbols2 => "symbols-2",
    }
    .to_string()
}

pub fn generate_platform(platform: &IOsPlatform) -> IndexMap<String, Vec<Vec<IosKeyMapType>>> {
    let mut layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
    for (layer_name, layer_key_map) in &platform.layers {
        let layer_name = ios_layer_name(layer_name);
        let key_map_rows: Vec<&str> = layer_key_map
            .trim()
            .split("\n")
            .map(|x| x.clone())
            .collect();
        let mut layer_rows: Vec<Vec<IosKeyMapType>> = Vec::new();
        for key_map in key_map_rows {
            let key_map = split_keys(key_map);
            let mut new_key_map: Vec<IosKeyMapType> = Vec::new();
            for key in key_map {
                if let Some(keyboard_entity) = keyboard_component_from_string(key.clone()) {
                    new_key_map.push(IosKeyMapType::Button(keyboard_entity));
                } else {
                    new_key_map.push(IosKeyMapType::Character(key));
                }
            }
            layer_rows.push(new_key_map)
        }
        layers.insert(layer_name, layer_rows);
    }
    layers
}

pub struct GenerateIos;

#[async_trait(?Send)]
impl BuildStep for GenerateIos {
    async fn build(&self, bundle: &KbdgenBundle, output_path: &Path) {
        let keyboard_definitions_file_path = output_path.join("KeyboardDefinitions.json");

        for (language_tag, layout) in &bundle.layouts {
            let mut longpress: IndexMap<String, Vec<String>> = IndexMap::new();
            let mut iphone_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
            let mut i_pad_9in_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
            let mut i_pad_12in_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();

            if let Some(ios_target) = &layout.i_os {
                if let Some(layout_longpress) = &layout.longpress {
                    for (key, value) in layout_longpress {
                        longpress.insert(key.clone(), value.clone());
                    }
                }

                if let Some(primary_platform) = &ios_target.primary {
                    iphone_layers.extend(generate_platform(&primary_platform));
                }
                if let Some(i_pad_9in_platform) = &ios_target.i_pad_9in {
                    i_pad_9in_layers.extend(generate_platform(&i_pad_9in_platform));
                }
                if let Some(i_pad_12in_platform) = &ios_target.i_pad_12in {
                    i_pad_12in_layers.extend(generate_platform(&i_pad_12in_platform));
                }

                if let Some(key_names) = &layout.key_names {
                    std::fs::write(
                        output_path.join(keyboard_definitions_file_path.clone()),
                        serde_json::to_string_pretty(&[IosKeyboardDefinitions {
                            info: IosInfo {
                                name: layout
                                    .display_names
                                    .get(language_tag)
                                    .expect("can't evaluate language tag of layout")
                                    .to_string(),
                                locale: language_tag.to_string(),
                                enter: key_names.r#return.to_string(),
                                space: key_names.space.to_string(),
                            },
                            longpress: longpress,
                            dead_keys: IosDeadKeys {
                                iphone: IndexMap::new(),
                                i_pad_9in: IndexMap::new(),
                                i_pad_12in: IndexMap::new(),
                            },
                            transforms: serde_json::value::Value::Null,
                            iphone: IosPlatform {
                                layer: iphone_layers,
                            },
                            i_pad_9in: IosPlatform {
                                layer: i_pad_9in_layers,
                            },
                            i_pad_12in: IosPlatform {
                                layer: i_pad_12in_layers,
                            },
                        }])
                        .unwrap(),
                    )
                    .unwrap();
                }
            }
        }
    }
}
<commit_msg>cloning public repo<commit_after>use std::{cmp::Ordering, fs::read_dir, path::Path, process::Command};

use async_trait::async_trait;
use indexmap::IndexMap;
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json;

use crate::{
    build::BuildStep,
    bundle::{
        layout::{ios::IOsKbdLayer, IOsPlatform},
        KbdgenBundle,
    },
    util::split_keys,
};

const REPOSITORY: &str = "repo";
const MODELS: &str = "Keyboard/Models";

#[derive(Serialize, Deserialize)]
pub struct IosInfo {
    name: String,
    locale: String,
    enter: String,
    space: String,
}

/// Removes all occurances of `character` in `input`
pub fn remove_all_occurances(input: String, character: char) -> String {
    input
        .as_str()
        .chars()
        .filter(|x| x.cmp(&character) != Ordering::Equal)
        .into_iter()
        .collect::<String>()
}

pub fn keyboard_component_from_string(input: String) -> Option<IosButton> {
    let regex = Regex::new(r"^\\s\{([^}:]+)(?::(\d+(?:\.\d+)?))?\}$").expect("valid regex");
    let captures = regex.captures(input.as_str());

    if let Some(captures) = captures {
        if let Some(id) = captures.get(1) {
            let id = match id.as_str().chars().next().unwrap().cmp(&'\"') {
                Ordering::Equal => remove_all_occurances(id.as_str().to_string(), '\"'),
                _ => format!("_{}", remove_all_occurances(id.as_str().to_string(), '\"')),
            };
            if let Some(width) = captures.get(2) {
                Some(IosButton {
                    id: id,
                    width: width.as_str().parse::<f32>().expect("invalid float value"),
                })
            } else {
                Some(IosButton {
                    id: id,
                    width: 1.0f32,
                })
            }
        } else {
            return None;
        }
    } else {
        return None;
    }
}

#[derive(Serialize, Deserialize)]
pub struct IosButton {
    id: String,
    width: f32,
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum IosKeyMapType {
    Character(String),
    Button(IosButton),
}

#[derive(Serialize, Deserialize)]
pub struct IosPlatform {
    #[serde(flatten)]
    layer: IndexMap<String, Vec<Vec<IosKeyMapType>>>,
}

#[derive(Serialize, Deserialize)]
pub struct IosDeadKeys {
    iphone: IndexMap<String, String>,
    #[serde(rename = "ipad-9in")]
    i_pad_9in: IndexMap<String, String>,
    #[serde(rename = "ipad-12in")]
    i_pad_12in: IndexMap<String, String>,
}

#[derive(Serialize, Deserialize)]
pub struct IosKeyboardDefinitions {
    #[serde(flatten)]
    info: IosInfo,
    longpress: IndexMap<String, Vec<String>>,
    dead_keys: IosDeadKeys,
    transforms: serde_json::value::Value,
    iphone: IosPlatform,
    i_pad_9in: IosPlatform,
    i_pad_12in: IosPlatform,
}

pub fn ios_layer_name(layer: &IOsKbdLayer) -> String {
    match layer {
        IOsKbdLayer::Default => "normal",
        IOsKbdLayer::Shift => "shifted",
        IOsKbdLayer::Alt => "alt",
        IOsKbdLayer::AltAndShift => "alt+shift",
        IOsKbdLayer::Symbols1 => "symbols-1",
        IOsKbdLayer::Symbols2 => "symbols-2",
    }
    .to_string()
}

pub fn generate_platform(platform: &IOsPlatform) -> IndexMap<String, Vec<Vec<IosKeyMapType>>> {
    let mut layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
    for (layer_name, layer_key_map) in &platform.layers {
        let layer_name = ios_layer_name(layer_name);
        let key_map_rows: Vec<&str> = layer_key_map
            .trim()
            .split("\n")
            .map(|x| x.clone())
            .collect();
        let mut layer_rows: Vec<Vec<IosKeyMapType>> = Vec::new();
        for key_map in key_map_rows {
            let key_map = split_keys(key_map);
            let mut new_key_map: Vec<IosKeyMapType> = Vec::new();
            for key in key_map {
                if let Some(keyboard_entity) = keyboard_component_from_string(key.clone()) {
                    new_key_map.push(IosKeyMapType::Button(keyboard_entity));
                } else {
                    new_key_map.push(IosKeyMapType::Character(key));
                }
            }
            layer_rows.push(new_key_map)
        }
        layers.insert(layer_name, layer_rows);
    }
    layers
}

pub struct GenerateIos;

#[async_trait(?Send)]
impl BuildStep for GenerateIos {
    async fn build(&self, bundle: &KbdgenBundle, output_path: &Path) {
        let repository_path = output_path.join(REPOSITORY);
        let models_path = repository_path.join(MODELS);
        let keyboard_definitions_file_path = output_path.join("KeyboardDefinitions.json");

        for (language_tag, layout) in &bundle.layouts {
            if let None = read_dir(output_path).unwrap().next() {
                let repo_url = "https://github.com/divvun/giellakbd-ios.git";

                Command::new("git")
                    .arg("clone")
                    .arg(repo_url)
                    .arg(REPOSITORY)
                    .current_dir(output_path.clone())
                    .status()
                    .expect("to clone a public repo with no hippos");
            }

            let mut longpress: IndexMap<String, Vec<String>> = IndexMap::new();
            let mut iphone_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
            let mut i_pad_9in_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();
            let mut i_pad_12in_layers: IndexMap<String, Vec<Vec<IosKeyMapType>>> = IndexMap::new();

            if let Some(ios_target) = &layout.i_os {
                if let Some(layout_longpress) = &layout.longpress {
                    for (key, value) in layout_longpress {
                        longpress.insert(key.clone(), value.clone());
                    }
                }

                if let Some(primary_platform) = &ios_target.primary {
                    iphone_layers.extend(generate_platform(&primary_platform));
                }
                if let Some(i_pad_9in_platform) = &ios_target.i_pad_9in {
                    i_pad_9in_layers.extend(generate_platform(&i_pad_9in_platform));
                }
                if let Some(i_pad_12in_platform) = &ios_target.i_pad_12in {
                    i_pad_12in_layers.extend(generate_platform(&i_pad_12in_platform));
                }

                // if let Some(key_names) = &layout.key_names {
                //     std::fs::write(
                //         output_path.join(keyboard_definitions_file_path.clone()),
                //         serde_json::to_string_pretty(&[IosKeyboardDefinitions {
                //             info: IosInfo {
                //                 name: layout
                //                     .display_names
                //                     .get(language_tag)
                //                     .expect("can't evaluate language tag of layout")
                //                     .to_string(),
                //                 locale: language_tag.to_string(),
                //                 enter: key_names.r#return.to_string(),
                //                 space: key_names.space.to_string(),
                //             },
                //             longpress: longpress,
                //             dead_keys: IosDeadKeys {
                //                 iphone: IndexMap::new(),
                //                 i_pad_9in: IndexMap::new(),
                //                 i_pad_12in: IndexMap::new(),
                //             },
                //             transforms: serde_json::value::Value::Null,
                //             iphone: IosPlatform {
                //                 layer: iphone_layers,
                //             },
                //             i_pad_9in: IosPlatform {
                //                 layer: i_pad_9in_layers,
                //             },
                //             i_pad_12in: IosPlatform {
                //                 layer: i_pad_12in_layers,
                //             },
                //         }])
                //         .unwrap(),
                //     )
                //     .unwrap();
                // }
            }
        }
    }
}
<|endoftext|>


<commit_before>use utils::bigint::M256;
use super::errors::StackError;

pub struct Stack {
    stack: Vec<M256>,
}

impl Default for Stack {
    fn default() -> Stack {
        Stack {
            stack: Vec::new(),
        }
    }
}

impl Stack {
    /// Check a pop-push cycle. If the check succeeded, `push`, `pop`,
    /// `set`, `peek` within the limit should not fail.
    pub fn check_pop_push(&self, pop: usize, push: usize) -> Result<(), StackError> {
        if self.len() < pop {
            return Err(StackError::StackUnderflow);
        }
        if self.len() - pop + push > 1024 {
            return Err(StackError::StackOverflow);
        }
        Ok(())
    }

    pub fn push(&mut self, elem: M256) -> Result<(), StackError> {
        self.stack.push(elem);
        if self.len() > 1024 {
            self.stack.pop();
            Err(StackError::StackOverflow)
        } else {
            Ok(())
        }
    }

    pub fn pop(&mut self) -> Result<M256, StackError> {
        match self.stack.pop() {
            Some(x) => Ok(x),
            None => Err(StackError::StackUnderflow),
        }
    }

    pub fn set(&mut self, no_from_top: usize, val: M256) -> Result<(), StackError> {
        if self.stack.len() > no_from_top {
            let len = self.stack.len();
            self.stack[len - no_from_top - 1] = val;
            Ok(())
        } else {
            Err(StackError::StackUnderflow)
        }
    }

    pub fn peek(&self, no_from_top: usize) -> Result<M256, StackError> {
        if self.stack.len() > no_from_top {
            Ok(self.stack[self.stack.len() - no_from_top - 1])
        } else {
            Err(StackError::StackUnderflow)
        }
    }

    pub fn len(&self) -> usize {
        self.stack.len()
    }
}
<commit_msg>Problem: stack error is redundent Solution: StackOver/Underflow -> Over/Underflow<commit_after>use utils::bigint::M256;
use super::errors::StackError;

pub struct Stack {
    stack: Vec<M256>,
}

impl Default for Stack {
    fn default() -> Stack {
        Stack {
            stack: Vec::new(),
        }
    }
}

impl Stack {
    /// Check a pop-push cycle. If the check succeeded, `push`, `pop`,
    /// `set`, `peek` within the limit should not fail.
    pub fn check_pop_push(&self, pop: usize, push: usize) -> Result<(), StackError> {
        if self.len() < pop {
            return Err(StackError::Underflow);
        }
        if self.len() - pop + push > 1024 {
            return Err(StackError::Overflow);
        }
        Ok(())
    }

    pub fn push(&mut self, elem: M256) -> Result<(), StackError> {
        self.stack.push(elem);
        if self.len() > 1024 {
            self.stack.pop();
            Err(StackError::Overflow)
        } else {
            Ok(())
        }
    }

    pub fn pop(&mut self) -> Result<M256, StackError> {
        match self.stack.pop() {
            Some(x) => Ok(x),
            None => Err(StackError::Underflow),
        }
    }

    pub fn set(&mut self, no_from_top: usize, val: M256) -> Result<(), StackError> {
        if self.stack.len() > no_from_top {
            let len = self.stack.len();
            self.stack[len - no_from_top - 1] = val;
            Ok(())
        } else {
            Err(StackError::Underflow)
        }
    }

    pub fn peek(&self, no_from_top: usize) -> Result<M256, StackError> {
        if self.stack.len() > no_from_top {
            Ok(self.stack[self.stack.len() - no_from_top - 1])
        } else {
            Err(StackError::Underflow)
        }
    }

    pub fn len(&self) -> usize {
        self.stack.len()
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Ben Ashford
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//! Implementation of ElasticSearch Mapping operation

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type Properties<'a> = HashMap<&'a str, HashMap<&'a str, &'a str>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:     &'a mut Client,

    /// The index that will be created and eventually mapped
    index:      &'b str,

    /// The actual mapping
    properties: &'b Properties<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, properties: &'b Properties) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:     client,
            index:      index,
            properties: properties
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let body = hashmap! {
            "mappings" => hashmap! {
                "sample" => hashmap! {
                    "properties" => self.properties
                }
            }
        };

        let url = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &body));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! {
            "created_at" => hashmap! {
                "type" => "date",
                "format" => "strict_date_optional_time"
            },

            "title" => hashmap! {
                "type" => "string",
                "index" => "not_analyzed"
            }
        };

        let result = MappingOperation::new(&mut client, index_name, &mapping).send();
        assert!(result.is_ok());
    }
}
<commit_msg>Allow mapping for given type<commit_after>/*
 * Copyright 2016 Ben Ashford
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//! Implementation of ElasticSearch Mapping operation

use std::collections::HashMap;

use ::Client;
use ::error::EsError;

pub type Properties<'a> = HashMap<&'a str, HashMap<&'a str, &'a str>>;

/// An indexing operation
pub struct MappingOperation<'a, 'b> {
    /// The HTTP client that this operation will use
    client:     &'a mut Client,

    /// The index that will be created and eventually mapped
    index:      &'b str,

    /// The type that will be mapped
    doc_type:   &'b str,

    /// The actual mapping
    properties: &'b Properties<'b>
}

impl<'a, 'b> MappingOperation<'a, 'b> {
    pub fn new(client: &'a mut Client, index: &'b str, doc_type: &'b str, properties: &'b Properties) -> MappingOperation<'a, 'b> {
        MappingOperation {
            client:     client,
            index:      index,
            doc_type:   doc_type,
            properties: properties
        }
    }

    pub fn send(&'b mut self) -> Result<MappingResult, EsError> {
        let body = hashmap! {
            "mappings" => hashmap! {
                self.doc_type => hashmap! {
                    "properties" => self.properties
                }
            }
        };

        let url = format!("{}", self.index);
        let (_, _) = try!(self.client.put_body_op(&url, &body));
        Ok(MappingResult)
    }
}

/// The result of a mapping operation
#[derive(Debug)]
pub struct MappingResult;

#[cfg(test)]
pub mod tests {
    extern crate env_logger;

    use std::collections::HashMap;

    use super::MappingOperation;

    #[test]
    fn test_mapping() {
        let index_name = "tests_test_mapping";
        let mut client = ::tests::make_client();

        client.delete_op(&format!("/{}", index_name)).unwrap();

        let mapping = hashmap! {
            "created_at" => hashmap! {
                "type" => "date",
                "format" => "strict_date_optional_time"
            },

            "title" => hashmap! {
                "type" => "string",
                "index" => "not_analyzed"
            }
        };

        let result = MappingOperation::new(&mut client, index_name, "sample", &mapping).send();
        assert!(result.is_ok());
    }
}
<|endoftext|>


<commit_before>extern crate cairo;

use length::*;

struct ColorStop {
    offset: f64,
    rgba:   u32
}

/* Any of the attributes in gradient elements may be omitted.  In turn, the missing
 * ones can be inherited from the gradient referenced by its "fallback" IRI.  We
 * represent these possibly-missing attributes as Option<foo>.
 */
struct GradientCommon {
    obj_bbox: Option<bool>,
    affine:   Option<cairo::Matrix>,
    spread:   Option<cairo::Extend>,
    fallback: Option<&str>,
    stops:    Option<Vec<ColorStop>>
}

struct LinearGradient {
    common: GradientCommon,
    x1:     Option<RsvgLength>,
    y1:     Option<RsvgLength>,
    x2:     Option<RsvgLength>,
    y2:     Option<RsvgLength>
}

struct RadialGradient {
    common: GradientCommon,
    cx:     Option<RsvgLength>,
    cy:     Option<RsvgLength>,
    r:      Option<RsvgLength>,
    fx:     Option<RsvgLength>,
    fy:     Option<RsvgLength>,
}

impl GradientCommon {
    fn get_defaults () -> GradientCommon {
        GradientCommon {
            obj_bbox: Some (true),                         // these are per the spec
            affine:   Some (cairo::Matrix::identity ()),
            spread:   Some (cairo::Extend::Pad),
            fallback: None,
            stops:    Some (Vec<ColorStop>::new ())        // empty array of color stops
        }
    }

    fn is_resolved (&self) -> bool {
        self.obj_bbox.is_some() &&
            self.affine.is_some () &&
            self.spread.is_some () &&
            self.stops.is_some ()
    }
}

fn make_length (value: f64, dir: LengthDir) -> RsvgLength {
    assert! (value >= 0.0 && value <= 1.0);

    RsvgLength {
        length: value,
        unit:   LengthUnit::Default,
        dir:    dir
    }
}

impl LinearGradient {
    fn get_defaults () -> LinearGradient {
        LinearGradient {
            common: GradientCommon::get_defaults (),
            x1:     Some (make_length (0.0, LengthDir::Horizontal)),  // these are per the spec
            y1:     Some (make_length (0.0, LengthDir::Vertical)),
            x2:     Some (make_length (1.0, LengthDir::Horizontal)),
            y2:     Some (make_length (0.0, LengthDir::Vertical))
        }
    }

    fn is_resolved (&self) -> bool {
        self.common.is_resolved () &&
            self.x1.is_some () &&
            self.y1.is_some () &&
            self.x2.is_some () &&
            self.y2.is_some ()
    }
}

impl RadialGradient {
    fn get_defaults () -> RadialGradient {
        RadialGradient {
            common: GradientCommon::get_defaults (),
            cx:     Some (make_length (0.5, LengthDir::Horizontal)),
            cy:     Some (make_length (0.5, LengthDir::Vertical)),
            r:      Some (make_length (0.5, LengthDir::Both)),
            fx:     Some (make_length (0.5, LengthDir::Horizontal)) // per the spec, equal to cx
            fy:     Some (make_length (0.5, LengthDir::Vertical))   // per the spec, equal to cy
        }
    }

    fn is_resolved (&self) -> bool {
        self.common.is_resolved () &&
            self.cx.is_some () &&
            self.cy.is_some () &&
            self.r.is_some () &&
            self.fx.is_some () &&
            self.fy.is_some ()
    }
}
<commit_msg>gradient.rs: Don't initialize RsvgLength by hand; actually parse a valid one<commit_after>extern crate cairo;
extern crate cairo_sys;

use length::*;

use self::cairo::MatrixTrait;

struct ColorStop {
    offset: f64,
    rgba:   u32
}

/* Any of the attributes in gradient elements may be omitted.  In turn, the missing
 * ones can be inherited from the gradient referenced by its "fallback" IRI.  We
 * represent these possibly-missing attributes as Option<foo>.
 */
struct GradientCommon {
    obj_bbox: Option<bool>,
    affine:   Option<cairo::Matrix>,
    spread:   Option<cairo::enums::Extend>,
    fallback: Option<String>,
    stops:    Option<Vec<ColorStop>>
}

struct LinearGradient {
    common: GradientCommon,
    x1:     Option<RsvgLength>,
    y1:     Option<RsvgLength>,
    x2:     Option<RsvgLength>,
    y2:     Option<RsvgLength>
}

struct RadialGradient {
    common: GradientCommon,
    cx:     Option<RsvgLength>,
    cy:     Option<RsvgLength>,
    r:      Option<RsvgLength>,
    fx:     Option<RsvgLength>,
    fy:     Option<RsvgLength>,
}

impl GradientCommon {
    fn get_defaults () -> GradientCommon {
        GradientCommon {
            obj_bbox: Some (true),                         // these are per the spec
            affine:   Some (cairo::Matrix::identity ()),
            spread:   Some (cairo::enums::Extend::Pad),
            fallback: None,
            stops:    Some (Vec::<ColorStop>::new ())        // empty array of color stops
        }
    }

    fn is_resolved (&self) -> bool {
        self.obj_bbox.is_some() &&
            self.affine.is_some () &&
            self.spread.is_some () &&
            self.stops.is_some ()
    }
}

impl LinearGradient {
    fn get_defaults () -> LinearGradient {
        LinearGradient {
            common: GradientCommon::get_defaults (),
            x1:     Some (RsvgLength::parse ("0%", LengthDir::Horizontal)),  // these are per the spec
            y1:     Some (RsvgLength::parse ("0%", LengthDir::Vertical)),
            x2:     Some (RsvgLength::parse ("100%", LengthDir::Horizontal)),
            y2:     Some (RsvgLength::parse ("0%", LengthDir::Vertical))
        }
    }

    fn is_resolved (&self) -> bool {
        self.common.is_resolved () &&
            self.x1.is_some () &&
            self.y1.is_some () &&
            self.x2.is_some () &&
            self.y2.is_some ()
    }
}

impl RadialGradient {
    fn get_defaults () -> RadialGradient {
        RadialGradient {
            common: GradientCommon::get_defaults (),
            cx:     Some (RsvgLength::parse ("50%", LengthDir::Horizontal)),
            cy:     Some (RsvgLength::parse ("50%", LengthDir::Vertical)),
            r:      Some (RsvgLength::parse ("50%", LengthDir::Both)),
            fx:     Some (RsvgLength::parse ("50%", LengthDir::Horizontal)), // per the spec, equal to cx
            fy:     Some (RsvgLength::parse ("50%", LengthDir::Vertical))    // per the spec, equal to cy
        }
    }

    fn is_resolved (&self) -> bool {
        self.common.is_resolved () &&
            self.cx.is_some () &&
            self.cy.is_some () &&
            self.r.is_some () &&
            self.fx.is_some () &&
            self.fy.is_some ()
    }
}
<|endoftext|>


<commit_before>//! Utilities for generating and reading the self-signed certificate for use with the control
//! gateway.

use crate::{crypto::keys::NamedRevision,
            tls::rustls_wrapper::{self,
                                  Error as RustlsReadersError}};
use rcgen::{Certificate as RcgenCertificate,
            CertificateParams,
            DistinguishedName,
            DnType,
            RcgenError,
            PKCS_ECDSA_P256_SHA256};
use rustls::{Certificate,
             PrivateKey,
             RootCertStore};
use std::{fs::{self,
               File},
          io::{Error as IoError,
               Write},
          path::{Path,
                 PathBuf}};
use thiserror::Error;

const NAME_PREFIX: &str = "ctl-gateway";
const CRT_EXTENSION: &str = "crt.pem";
const KEY_EXTENSION: &str = "key.pem";

#[derive(Error, Debug)]
pub enum Error {
    #[error("ctl gateway TLS file lookup failed when trying to match files {0}")]
    FailedToMatchPattern(String),
    #[error("ctl gateway TLS file lookup failed, err: {0}")]
    RustlsReaders(#[from] RustlsReadersError),
    #[error("ctl gateway TLS file generation failed, err: {0}")]
    CertificateGeneration(#[from] RcgenError),
    #[error("writing the ctl gateway TLS files failed, err: {0}")]
    CertificateWrite(#[from] IoError),
}

pub fn generate_self_signed_certificate_and_key(subject_alternate_name: &str,
                                                path: impl AsRef<Path>)
                                                -> Result<(), Error> {
    let mut params =
        CertificateParams::new(vec![subject_alternate_name.to_string(), "localhost".to_string(),]);
    let mut distinguished_name = DistinguishedName::new();
    distinguished_name.push(DnType::CommonName, "Habitat Supervisor Control Gateway");
    params.distinguished_name = distinguished_name;
    params.alg = &PKCS_ECDSA_P256_SHA256;

    let certificate = RcgenCertificate::from_params(params)?;
    let crt = certificate.serialize_pem()?;
    let key = certificate.serialize_private_key_pem();

    fs::create_dir_all(&path)?;
    let named_revision = NamedRevision::new(NAME_PREFIX.to_string());

    let crt_path = path.as_ref()
                       .join(format!("{}.{}", named_revision, CRT_EXTENSION));
    let mut crt_file = File::create(crt_path)?;
    crt_file.write_all(crt.as_bytes())?;

    let key_path = path.as_ref()
                       .join(format!("{}.{}", named_revision, KEY_EXTENSION));
    let mut key_file = File::create(key_path)?;
    key_file.write_all(key.as_bytes())?;

    Ok(())
}

fn get_latest_path(path: impl AsRef<Path>, pattern: &str) -> Result<PathBuf, Error> {
    let pattern = path.as_ref().join(pattern);
    let pattern = pattern.to_string_lossy();
    glob::glob(&pattern).expect("valid pattern")
                        .filter_map(std::result::Result::ok)
                        .filter(|p| p.metadata().map(|m| m.is_file()).unwrap_or(false))
                        .max()
                        .ok_or_else(|| Error::FailedToMatchPattern(pattern.to_string()))
}

pub fn latest_certificates(path: impl AsRef<Path>) -> Result<Vec<Certificate>, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION))?;
    Ok(rustls_wrapper::certificates_from_file(&path)?)
}

pub fn latest_private_key(path: impl AsRef<Path>) -> Result<PrivateKey, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, KEY_EXTENSION))?;
    Ok(rustls_wrapper::private_key_from_file(&path)?)
}

pub fn latest_root_certificate_store(path: impl AsRef<Path>) -> Result<RootCertStore, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION))?;
    Ok(rustls_wrapper::root_certificate_store_from_file(&path)?)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::{fs,
              time::Duration};
    use tempfile::TempDir;

    #[test]
    fn ctl_gateway_generate_and_read_tls_files() {
        let tmpdir = TempDir::new().unwrap();

        generate_self_signed_certificate_and_key("a_test_domain", &tmpdir).unwrap();
        assert_eq!(fs::read_dir(&tmpdir).unwrap().count(), 2);
        let first_path =
            get_latest_path(&tmpdir, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION)).unwrap();
        let certificates = latest_certificates(&tmpdir).unwrap();
        assert_eq!(certificates.len(), 1);
        latest_private_key(&tmpdir).unwrap();
        let root_certificate_store = latest_root_certificate_store(&tmpdir).unwrap();
        assert_eq!(root_certificate_store.roots.len(), 1);

        // TLS files are named on second boundaries. Wait enough time to guarantee we get a new
        // name.
        std::thread::sleep(Duration::from_secs(2));

        generate_self_signed_certificate_and_key("another_domain", &tmpdir).unwrap();
        assert_eq!(fs::read_dir(&tmpdir).unwrap().count(), 4);
        let second_path =
            get_latest_path(&tmpdir, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION)).unwrap();
        let certificates = latest_certificates(&tmpdir).unwrap();
        assert_eq!(certificates.len(), 1);
        latest_private_key(&tmpdir).unwrap();
        let root_certificate_store = latest_root_certificate_store(&tmpdir).unwrap();
        assert_eq!(root_certificate_store.roots.len(), 1);

        assert!(second_path > first_path);
    }
}
<commit_msg>[Feedback] Use organization name<commit_after>//! Utilities for generating and reading the self-signed certificate for use with the control
//! gateway.

use crate::{crypto::keys::NamedRevision,
            tls::rustls_wrapper::{self,
                                  Error as RustlsReadersError}};
use rcgen::{Certificate as RcgenCertificate,
            CertificateParams,
            DistinguishedName,
            DnType,
            RcgenError,
            PKCS_ECDSA_P256_SHA256};
use rustls::{Certificate,
             PrivateKey,
             RootCertStore};
use std::{fs::{self,
               File},
          io::{Error as IoError,
               Write},
          path::{Path,
                 PathBuf}};
use thiserror::Error;

const NAME_PREFIX: &str = "ctl-gateway";
const CRT_EXTENSION: &str = "crt.pem";
const KEY_EXTENSION: &str = "key.pem";

#[derive(Error, Debug)]
pub enum Error {
    #[error("ctl gateway TLS file lookup failed when trying to match files {0}")]
    FailedToMatchPattern(String),
    #[error("ctl gateway TLS file lookup failed, err: {0}")]
    RustlsReaders(#[from] RustlsReadersError),
    #[error("ctl gateway TLS file generation failed, err: {0}")]
    CertificateGeneration(#[from] RcgenError),
    #[error("writing the ctl gateway TLS files failed, err: {0}")]
    CertificateWrite(#[from] IoError),
}

pub fn generate_self_signed_certificate_and_key(subject_alternate_name: &str,
                                                path: impl AsRef<Path>)
                                                -> Result<(), Error> {
    let mut params =
        CertificateParams::new(vec![subject_alternate_name.to_string(), "localhost".to_string(),]);
    let mut distinguished_name = DistinguishedName::new();
    distinguished_name.push(DnType::OrganizationName,
                            "Habitat Supervisor Control Gateway");
    params.distinguished_name = distinguished_name;
    params.alg = &PKCS_ECDSA_P256_SHA256;

    let certificate = RcgenCertificate::from_params(params)?;
    let crt = certificate.serialize_pem()?;
    let key = certificate.serialize_private_key_pem();

    fs::create_dir_all(&path)?;
    let named_revision = NamedRevision::new(NAME_PREFIX.to_string());

    let crt_path = path.as_ref()
                       .join(format!("{}.{}", named_revision, CRT_EXTENSION));
    let mut crt_file = File::create(crt_path)?;
    crt_file.write_all(crt.as_bytes())?;

    let key_path = path.as_ref()
                       .join(format!("{}.{}", named_revision, KEY_EXTENSION));
    let mut key_file = File::create(key_path)?;
    key_file.write_all(key.as_bytes())?;

    Ok(())
}

fn get_latest_path(path: impl AsRef<Path>, pattern: &str) -> Result<PathBuf, Error> {
    let pattern = path.as_ref().join(pattern);
    let pattern = pattern.to_string_lossy();
    glob::glob(&pattern).expect("valid pattern")
                        .filter_map(std::result::Result::ok)
                        .filter(|p| p.metadata().map(|m| m.is_file()).unwrap_or(false))
                        .max()
                        .ok_or_else(|| Error::FailedToMatchPattern(pattern.to_string()))
}

pub fn latest_certificates(path: impl AsRef<Path>) -> Result<Vec<Certificate>, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION))?;
    Ok(rustls_wrapper::certificates_from_file(&path)?)
}

pub fn latest_private_key(path: impl AsRef<Path>) -> Result<PrivateKey, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, KEY_EXTENSION))?;
    Ok(rustls_wrapper::private_key_from_file(&path)?)
}

pub fn latest_root_certificate_store(path: impl AsRef<Path>) -> Result<RootCertStore, Error> {
    let path = get_latest_path(path, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION))?;
    Ok(rustls_wrapper::root_certificate_store_from_file(&path)?)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::{fs,
              time::Duration};
    use tempfile::TempDir;

    #[test]
    fn ctl_gateway_generate_and_read_tls_files() {
        let tmpdir = TempDir::new().unwrap();

        generate_self_signed_certificate_and_key("a_test_domain", &tmpdir).unwrap();
        assert_eq!(fs::read_dir(&tmpdir).unwrap().count(), 2);
        let first_path =
            get_latest_path(&tmpdir, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION)).unwrap();
        let certificates = latest_certificates(&tmpdir).unwrap();
        assert_eq!(certificates.len(), 1);
        latest_private_key(&tmpdir).unwrap();
        let root_certificate_store = latest_root_certificate_store(&tmpdir).unwrap();
        assert_eq!(root_certificate_store.roots.len(), 1);

        // TLS files are named on second boundaries. Wait enough time to guarantee we get a new
        // name.
        std::thread::sleep(Duration::from_secs(2));

        generate_self_signed_certificate_and_key("another_domain", &tmpdir).unwrap();
        assert_eq!(fs::read_dir(&tmpdir).unwrap().count(), 4);
        let second_path =
            get_latest_path(&tmpdir, &format!("{}-*.{}", NAME_PREFIX, CRT_EXTENSION)).unwrap();
        let certificates = latest_certificates(&tmpdir).unwrap();
        assert_eq!(certificates.len(), 1);
        latest_private_key(&tmpdir).unwrap();
        let root_certificate_store = latest_root_certificate_store(&tmpdir).unwrap();
        assert_eq!(root_certificate_store.roots.len(), 1);

        assert!(second_path > first_path);
    }
}
<|endoftext|>


<commit_before>
use super::*;

mod micro_modules;
mod micro_modules_two;
mod micro_modules_two_joined;

// mod layer;
<commit_msg>!test<commit_after>
use super::*;

mod micro_modules;
mod micro_modules_two;
mod micro_modules_two_joined;

// mod layer;
<|endoftext|>


<commit_before>extern mod extra;
extern mod toml = "toml#0.1";

use extra::serialize::Decodable;

#[deriving(ToStr,Decodable)]
struct Config {
    host: ~str,
    port: Option<uint>
}

fn main() {
    let toml = r###"
        host = "localhost"
        port = 8080
    "###;

    let value = toml::parse_from_bytes(toml.as_bytes().to_owned());
    let cfg: Config = Decodable::decode(&mut toml::Decoder::new(&value));

    println!("{:s}", value.to_str());
    println!("{:s}", cfg.to_str());
}
<commit_msg>Extend decoder example<commit_after>extern mod extra;
extern mod toml = "toml#0.1";

use extra::serialize::Decodable;

#[deriving(ToStr,Decodable)]
struct Config {
    host: ~str,
    port: Option<uint>,
    ids: ~[uint],
    products: ~[Product]
}

#[deriving(ToStr,Decodable)]
struct Product {
    id: uint,
    name: ~str
}

fn main() {
    let toml = r###"
        host = "localhost"
        ids = [1, 10, 20]
          [[products]]
          id = 1
          name = "Product 1"
          [[products]]
          id = 2
          name = "Product 2"
    "###;

    let value = toml::parse_from_bytes(toml.as_bytes().to_owned());
    let cfg: Config = Decodable::decode(&mut toml::Decoder::new(&value));

    println!("{:s}", value.to_str());
    println!("{:s}", cfg.to_str());
}
<|endoftext|>


<commit_before>use hyper::{Uri, Client, Method, Error, StatusCode};
use hyper::header::UserAgent;
use hyper::client::{Request, FutureResponse};
use hyper_tls::HttpsConnector;
use futures::{Future, Stream};
use futures::future;
use serde_json;
use serde::Deserialize;

use std::fs::{File, OpenOptions}; // TODO file writing to utils.rs
use std::io::prelude::*;
use std::io::Write;
use std::path::Path;

use curl::easy::Easy;
use curl::easy;
use utils::{parse_url_from_str, log_response_status};
use utils;
use models::*;
use endpoint::HnNewsEndpoint;
use app::{AppDomain, AppStates, AppStateMachine};

pub fn get_top_story_ids(app_domain: &mut AppDomain,
                         state: &mut AppStateMachine)
                         -> Result<HnListOfItems, Error> {
    let logger = &app_domain.logger; // These need to be here as otherwise it'll cause mutable<>immutable borrow error
    let endpoint = &app_domain.endpoint;
    let client = &app_domain.client;
    state.current_state = AppStates::RetrievingResults;
    let work = request_top_story_ids(&client, &endpoint)
        .and_then(|res| {
            log_response_status(&logger, &endpoint.get_top_stories_path(), &res.status());
            res.body()
                .fold(Vec::new(), |mut v, chunk| {
                    v.extend(&chunk[..]);
                    future::ok::<_, Error>(v)
                })
        })
        .map(|chunks| deserialize::<HnListOfItems>(chunks));
    let result = app_domain.core.run(work);
    state.current_state = AppStates::DoingLocalWork;
    result
}

fn deserialize<T: Deserialize>(chunks: Vec<u8>) -> T {
    let s = String::from_utf8(chunks).unwrap();
    let deserialized: T = serde_json::from_str(&s).unwrap();
    deserialized
}

///
/// Gets HnItem wrapped in Result
///
pub fn get_item_by_id(item: &str,
                      app_domain: &mut AppDomain,
                      state: &mut AppStateMachine)
                      -> Result<HnItem, Error> {
    // note kids in item are comments, parts not sure what it is
    let logger = &app_domain.logger; // These need to be here as otherwise it'll cause mutable<>immutable borrow error
    let endpoint = &app_domain.endpoint;
    let client = &app_domain.client;
    state.current_state = AppStates::RetrievingResults;
    let work = request_item(&item, &client, &endpoint)
        .and_then(|res| {
            log_response_status(&logger, &endpoint.get_item_path(&item), &res.status());
            res.body()
                .fold(Vec::new(), |mut v, chunk| {
                    v.extend(&chunk[..]);
                    future::ok::<_, Error>(v)
                })
        })
        .map(|chunks| deserialize::<HnItem>(chunks));
    state.current_state = AppStates::DoingLocalWork;
    let result = app_domain.core.run(work);
    result
}

pub fn get_comments_for_item(item: &HnItem,
                         app_domain: &mut AppDomain,
                         state: &mut AppStateMachine)
                         -> Option<Vec<HnItem>> {
    match item.kids {
        Some(ref kids) => {
            let core = &mut app_domain.core;
            let logger = &mut app_domain.logger; // These need to be mutable as otherwise it'll cause mutable<>immutable borrow error
            let endpoint = &mut app_domain.endpoint;
            let client = &mut app_domain.client;
            state.current_state = AppStates::RetrievingResults;

            let comments: &Vec<i32> = &kids;
            info!(&logger,
                  format!("Retrieving comments for {} with {} comments",
                          &item.id,
                          kids.len()));
            let raw_items = comments.iter()
                .map(|item_id| {
                    (item_id.to_string(), request_item(&item_id.to_string(), &client, &endpoint))
                })
                .map(|(item_id, request_work)| {
                    let subtask = request_work.and_then(|response| {
                        response.body()
                            .fold(Vec::new(), |mut v, chunk| {
                                v.extend(&chunk[..]);
                                future::ok::<_, Error>(v)
                            })
                    });
                    core.run(subtask).unwrap()
                })
                .collect::<Vec<Vec<u8>>>();
            let items = raw_items.into_iter()
                .map(|chunks| deserialize::<HnItem>(chunks))
                .collect();
            state.current_state = AppStates::DoingLocalWork;
            Some(items)
        }
        None => None,
    }
}

fn request_top_story_ids(client: &Client<HttpsConnector>,
                         endpoints: &HnNewsEndpoint)
                         -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_top_stories_path());
    create_get_request(url, &client)
}

fn request_best_stories_ids(client: &Client<HttpsConnector>,
                            endpoints: &HnNewsEndpoint)
                            -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_best_stories_path());
    create_get_request(url, &client)
}

fn request_item(item: &str,
                client: &Client<HttpsConnector>,
                endpoints: &HnNewsEndpoint)
                -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_item_path(item));
    create_get_request(url, &client)
}

pub fn download_page_from_item(item: &HnItem,
                               app_domain: &mut AppDomain,
                               state: &mut AppStateMachine)
                               -> Result<String, String> {
    match item.url {
        Some(ref url) => {
            let core = &mut app_domain.core;
            let logger = &mut app_domain.logger;
            let uri = utils::parse_url_from_str(url);
            let mut filename: String = utils::filename_for_hnitem(&item);
            let path = Path::new(&filename);
            let mut file: File =
                OpenOptions::new().write(true).create(true).open(path.as_os_str()).unwrap();

            let v = curl_req(url);
            let s = String::from_utf8(v).unwrap(); // TODO Handle errs
            file.write_all(s.as_bytes());
            Ok(String::from(path.as_os_str().to_str().unwrap())) // should probably be path to string
        }
        None => Err(String::from("No url")),
    }

}

fn curl_req(url: &String) -> Vec<u8> {
    let mut vecced: Vec<u8> = Vec::new();
    let mut easy = Easy::new();
    easy.get(true).unwrap();
    easy.url(url).unwrap();
    {
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
                vecced.extend_from_slice(data);
                Ok(data.len())
            })
            .unwrap();
        transfer.perform().unwrap();
    }
    vecced
}

fn create_get_request(url: Uri, client: &Client<HttpsConnector>) -> FutureResponse {
    let mut request = Request::new(Method::Get, url);
    common_headers(&mut request);
    client.request(request)
}

fn common_headers(req: &mut Request) {
    req.headers_mut().set(UserAgent::new("rs-hackernews-cli"));
}

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

    #[test]
    fn request_item_test() {
        let mut app_domain = AppDomain::new();
        let s = String::from("8000");
        let response = app_domain.core
            .run(request_item(&s, &app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }
    #[test]
    fn request_top_stories_test() {
        let mut app_domain = AppDomain::new();
        let response = app_domain.core
            .run(request_top_story_ids(&app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }
    #[test]
    fn request_best_stories_test() {
        let mut app_domain = AppDomain::new();
        let response = app_domain.core
            .run(request_best_stories_ids(&app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }

    #[test]
    fn get_item_by_id_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let s = String::from("126809");
        let hnitem: HnItem = get_item_by_id(&s, &mut app_domain, &mut app_sm).unwrap();
        assert!(hnitem.score.unwrap() != 0);
        assert!(hnitem.id != 0);
        assert!(!hnitem.type_str.is_empty());
        assert!(!hnitem.title.unwrap().is_empty());
        assert_eq!(126809, hnitem.id);
    }
    #[test]
    fn get_top_stories_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let top_stories: HnListOfItems = get_top_story_ids(&mut app_domain, &mut app_sm).unwrap();
        assert!(top_stories.values.len() != 0);
    }

    #[test]
    fn get_comments_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let s = String::from("14114235");
        let hnitem: HnItem = get_item_by_id(&s, &mut app_domain, &mut app_sm).unwrap();
        let comments: Vec<HnItem> = get_comments_for_item(&hnitem, &mut app_domain, &mut app_sm)
            .unwrap();
        assert!(comments.len() != 0);
    }
}
<commit_msg>Minor changes in comment retrieval<commit_after>use hyper::{Uri, Client, Method, Error, StatusCode};
use hyper::header::UserAgent;
use hyper::client::{Request, FutureResponse};
use hyper_tls::HttpsConnector;
use futures::{Future, Stream};
use futures::future;
use serde_json;
use serde::Deserialize;

use std::fs::{File, OpenOptions}; // TODO file writing to utils.rs
use std::io::prelude::*;
use std::io::Write;
use std::path::Path;

use curl::easy::Easy;
use curl::easy;
use utils::{parse_url_from_str, log_response_status};
use utils;
use models::*;
use endpoint::HnNewsEndpoint;
use app::{AppDomain, AppStates, AppStateMachine};

pub fn get_top_story_ids(app_domain: &mut AppDomain,
                         state: &mut AppStateMachine)
                         -> Result<HnListOfItems, Error> {
    let logger = &app_domain.logger; // These need to be here as otherwise it'll cause mutable<>immutable borrow error
    let endpoint = &app_domain.endpoint;
    let client = &app_domain.client;
    state.current_state = AppStates::RetrievingResults;
    let work = request_top_story_ids(&client, &endpoint)
        .and_then(|res| {
            log_response_status(&logger, &endpoint.get_top_stories_path(), &res.status());
            res.body()
                .fold(Vec::new(), |mut v, chunk| {
                    v.extend(&chunk[..]);
                    future::ok::<_, Error>(v)
                })
        })
        .map(|chunks| deserialize::<HnListOfItems>(chunks));
    let result = app_domain.core.run(work);
    state.current_state = AppStates::DoingLocalWork;
    result
}

fn deserialize<T: Deserialize>(chunks: Vec<u8>) -> T {
    let s = String::from_utf8(chunks).unwrap();
    let deserialized: T = serde_json::from_str(&s).unwrap();
    deserialized
}

///
/// Gets HnItem wrapped in Result
///
pub fn get_item_by_id(item: &str,
                      app_domain: &mut AppDomain,
                      state: &mut AppStateMachine)
                      -> Result<HnItem, Error> {
    // note kids in item are comments, parts not sure what it is
    let logger = &app_domain.logger; // These need to be here as otherwise it'll cause mutable<>immutable borrow error
    let endpoint = &app_domain.endpoint;
    let client = &app_domain.client;
    state.current_state = AppStates::RetrievingResults;
    let work = request_item(&item, &client, &endpoint)
        .and_then(|res| {
            log_response_status(&logger, &endpoint.get_item_path(&item), &res.status());
            res.body()
                .fold(Vec::new(), |mut v, chunk| {
                    v.extend(&chunk[..]);
                    future::ok::<_, Error>(v)
                })
        })
        .map(|chunks| deserialize::<HnItem>(chunks));
    state.current_state = AppStates::DoingLocalWork;
    let result = app_domain.core.run(work);
    result
}

pub fn get_comments_for_item(item: &HnItem,
                         app_domain: &mut AppDomain,
                         state: &mut AppStateMachine)
                         -> Option<Vec<HnItem>> {
    match item.kids {
        Some(ref kids) => {
            let core = &mut app_domain.core;
            let logger = &mut app_domain.logger; // These need to be mutable as otherwise it'll cause mutable<>immutable borrow error
            let endpoint = &mut app_domain.endpoint;
            let client = &mut app_domain.client;
            state.current_state = AppStates::RetrievingResults;

            let comments: &Vec<i32> = &kids;
            info!(&logger,
                  format!("Retrieving comments for {} with {} comments",
                          &item.id,
                          kids.len()));
            let items = comments.iter()
                .map(|item_id| {
                    (item_id.to_string(), request_item(&item_id.to_string(), &client, &endpoint))
                })
                .map(|(item_id, request_work)| {
                    let subtask = request_work.and_then(|response| {
                        response.body()
                            .fold(Vec::new(), |mut v, chunk| {
                                v.extend(&chunk[..]);
                                future::ok::<_, Error>(v)
                            })
                    });
                    core.run(subtask).unwrap()
                })
                .collect::<Vec<Vec<u8>>>()
                .into_iter()
                .map(|chunks| deserialize::<HnItem>(chunks))
                .collect::<Vec<HnItem>>();
            state.current_state = AppStates::DoingLocalWork;
            Some(items)
        }
        None => None,
    }
}

fn request_top_story_ids(client: &Client<HttpsConnector>,
                         endpoints: &HnNewsEndpoint)
                         -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_top_stories_path());
    create_get_request(url, &client)
}

fn request_best_stories_ids(client: &Client<HttpsConnector>,
                            endpoints: &HnNewsEndpoint)
                            -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_best_stories_path());
    create_get_request(url, &client)
}

fn request_item(item: &str,
                client: &Client<HttpsConnector>,
                endpoints: &HnNewsEndpoint)
                -> FutureResponse {
    let url = parse_url_from_str(&endpoints.get_item_path(item));
    create_get_request(url, &client)
}

pub fn download_page_from_item(item: &HnItem,
                               app_domain: &mut AppDomain,
                               state: &mut AppStateMachine)
                               -> Result<String, String> {
    match item.url {
        Some(ref url) => {
            let core = &mut app_domain.core;
            let logger = &mut app_domain.logger;
            let uri = utils::parse_url_from_str(url);
            let mut filename: String = utils::filename_for_hnitem(&item);
            let path = Path::new(&filename);
            let mut file: File =
                OpenOptions::new().write(true).create(true).open(path.as_os_str()).unwrap();

            let v = curl_req(url);
            let s = String::from_utf8(v).unwrap(); // TODO Handle errs
            file.write_all(s.as_bytes());
            Ok(String::from(path.as_os_str().to_str().unwrap())) // should probably be path to string
        }
        None => Err(String::from("No url")),
    }

}

fn curl_req(url: &String) -> Vec<u8> {
    let mut vecced: Vec<u8> = Vec::new();
    let mut easy = Easy::new();
    easy.get(true).unwrap();
    easy.url(url).unwrap();
    {
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
                vecced.extend_from_slice(data);
                Ok(data.len())
            })
            .unwrap();
        transfer.perform().unwrap();
    }
    vecced
}

fn create_get_request(url: Uri, client: &Client<HttpsConnector>) -> FutureResponse {
    let mut request = Request::new(Method::Get, url);
    common_headers(&mut request);
    client.request(request)
}

fn common_headers(req: &mut Request) {
    req.headers_mut().set(UserAgent::new("rs-hackernews-cli"));
}

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

    #[test]
    fn request_item_test() {
        let mut app_domain = AppDomain::new();
        let s = String::from("8000");
        let response = app_domain.core
            .run(request_item(&s, &app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }
    #[test]
    fn request_top_stories_test() {
        let mut app_domain = AppDomain::new();
        let response = app_domain.core
            .run(request_top_story_ids(&app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }
    #[test]
    fn request_best_stories_test() {
        let mut app_domain = AppDomain::new();
        let response = app_domain.core
            .run(request_best_stories_ids(&app_domain.client, &app_domain.endpoint))
            .unwrap();
        assert_eq!(StatusCode::Ok, response.status());
    }

    #[test]
    fn get_item_by_id_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let s = String::from("126809");
        let hnitem: HnItem = get_item_by_id(&s, &mut app_domain, &mut app_sm).unwrap();
        assert!(hnitem.score.unwrap() != 0);
        assert!(hnitem.id != 0);
        assert!(!hnitem.type_str.is_empty());
        assert!(!hnitem.title.unwrap().is_empty());
        assert_eq!(126809, hnitem.id);
    }
    #[test]
    fn get_top_stories_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let top_stories: HnListOfItems = get_top_story_ids(&mut app_domain, &mut app_sm).unwrap();
        assert!(top_stories.values.len() != 0);
    }

    #[test]
    fn get_comments_test() {
        let mut app_domain = AppDomain::new();
        let mut app_sm = AppStateMachine::new();
        let s = String::from("14114235");
        let hnitem: HnItem = get_item_by_id(&s, &mut app_domain, &mut app_sm).unwrap();
        let comments: Vec<HnItem> = get_comments_for_item(&hnitem, &mut app_domain, &mut app_sm)
            .unwrap();
        assert!(comments.len() != 0);
    }
}
<|endoftext|>