<commit_before>use std::fs;
use std::env;
use std::fmt;
use std::path::Path;
use std::io::BufReader;
use std::borrow::Cow;

use plist::serde::deserialize;
use walkdir::WalkDir;
#[cfg(target_os="macos")]
use osascript;
#[cfg(target_os="macos")]
use unix_daemonize::{daemonize_redirect, ChdirMode};

use prelude::*;
use utils::{TempFile, expand_envvars};

#[derive(Deserialize, Debug)]
pub struct InfoPlist {
    #[serde(rename="CFBundleName")]
    name: String,
    #[serde(rename="CFBundleIdentifier")]
    bundle_id: String,
    #[serde(rename="CFBundleShortVersionString")]
    version: String,
    #[serde(rename="CFBundleVersion")]
    build: String,
}

impl fmt::Display for InfoPlist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} ({})", self.name(), &self.version)
    }
}

impl InfoPlist {

    pub fn discover_from_path<P: AsRef<Path>>(path: P) -> Result<Option<InfoPlist>> {
        let fpl_fn = Some("info.plist".to_string());
        for dent_res in WalkDir::new(path.as_ref()) {
            let dent = dent_res?;
            if dent.file_name().to_str().map(|x| x.to_lowercase()) == fpl_fn {
                let md = dent.metadata()?;
                if md.is_file() {
                    return Ok(Some(InfoPlist::from_path(dent.path())?));
                }
            }
        }
        Ok(None)
    }

    pub fn discover_from_env() -> Result<Option<InfoPlist>> {
        if let Ok(path) = env::var("INFOPLIST_FILE") {
            Ok(Some(InfoPlist::from_path(path)?))
        } else {
            Ok(None)
        }
    }

    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<InfoPlist> {
        let f = fs::File::open(path.as_ref()).chain_err(||
            Error::from("Could not open Info.plist file"))?;
        let mut rdr = BufReader::new(f);
        Ok(deserialize(&mut rdr).chain_err(||
            Error::from("Could not parse Info.plist file"))?)
    }

    pub fn version(&self) -> &str {
        &self.version
    }

    pub fn build(&self) -> &str {
        &self.build
    }

    pub fn release_name(&self) -> String {
        format!("{} ({})", self.version, self.build)
    }

    pub fn name<'a>(&'a self) -> Cow<'a, str> {
        expand_envvars(&self.name)
    }

    pub fn bundle_id<'a>(&'a self) -> Cow<'a, str> {
        expand_envvars(&self.bundle_id)
    }
}

/// Helper struct that allows the current execution to detach from
/// the xcode console and continue in the background.  This becomes
/// a dummy shim for non xcode runs or platforms.
pub struct MayDetach<'a> {
    output_file: Option<TempFile>,
    #[allow(dead_code)]
    task_name: &'a str,
}

impl<'a> MayDetach<'a> {
    fn new(task_name: &'a str) -> MayDetach<'a> {
        MayDetach {
            output_file: None,
            task_name: task_name,
        }
    }

    /// Returns true if we are deteached from xcode
    pub fn is_detached(&self) -> bool {
        self.output_file.is_some()
    }

    /// If we are launched from xcode this detaches us from the xcode console
    /// and continues execution in the background.  From this moment on output
    /// is captured and the user is notified with notifications.
    #[cfg(target_os="macos")]
    pub fn may_detach(&mut self) -> Result<bool> {
        if !launched_from_xcode() {
            return Ok(false);
        }

        println!("Continuing in background.");
        show_notification("Sentry", &format!("{} starting", self.task_name))?;
        let output_file = TempFile::new()?;
        daemonize_redirect(Some(output_file.path()),
                           Some(output_file.path()),
                           ChdirMode::NoChdir).unwrap();
        self.output_file = Some(output_file);
        Ok(true)
    }

    /// For non mac platforms this just never detaches.
    #[cfg(not(target_os="macos"))]
    pub fn may_detach(&mut self) -> Result<bool> {
        Ok(false)
    }

    /// Wraps the execution of a code block.  Does not detach until someone
    /// calls into `may_detach`.
    #[cfg(target_os="macos")]
    pub fn wrap<T, F: FnOnce(&mut MayDetach) -> Result<T>>(task_name: &'a str, f: F) -> Result<T> {
        use std::time::Duration;
        use std::thread;
        use open;
        use utils::print_error;

        let mut md = MayDetach::new(task_name);
        match f(&mut md) {
            Ok(x) => {
                md.show_done()?;
                Ok(x)
            }
            Err(err) => {
                if let Some(ref output_file) = md.output_file {
                    print_error(&err);
                    if md.show_critical_info()? {
                        open::that(&output_file.path())?;
                        thread::sleep(Duration::from_millis(5000));
                    }
                }
                Err(err)
            }
        }
    }

    /// Dummy wrap call that never detaches for non mac platforms.
    #[cfg(not(target_os="macos"))]
    pub fn wrap<T, F: FnOnce(&mut MayDetach) -> Result<T>>(task_name: &'a str, f: F) -> Result<T> {
        f(&mut MayDetach::new(task_name))
    }

    #[cfg(target_os="macos")]
    fn show_critical_info(&self) -> Result<bool> {
        show_critical_info(
            &format!("{} failed", self.task_name),
            "The Sentry build step failed while running in the background. \
             You can ignore this error or view details to attempt to resolve \
             it. Ignoring it might cause your crashes not to be handled \
             properly.")
    }

    #[cfg(target_os="macos")]
    fn show_done(&self) -> Result<()> {
        if self.is_detached() {
            show_notification("Sentry", &format!("{} finished", self.task_name))?;
        }
        Ok(())
    }
}

/// Returns true if we were invoked from xcode
#[cfg(target_os="macos")]
pub fn launched_from_xcode() -> bool {
    env::var("XCODE_VERSION_ACTUAL").is_ok() && env::var("TERM").is_err()
}

/// Shows a dialog in xcode and blocks.  The dialog will have a title and a
/// message as well as the buttons "Show details" and "Ignore".  Returns
/// `true` if the `show details` button has been pressed.
#[cfg(target_os="macos")]
pub fn show_critical_info(title: &str, msg: &str) -> Result<bool> {
    lazy_static! {
        static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new("
            var App = Application('XCode');
            App.includeStandardAdditions = true;
            return App.displayAlert($params.title, {
                message: $params.message,
                as: \"critical\",
                buttons: [\"Show details\", \"Ignore\"]
            });
        ");
    }

    #[derive(Serialize)]
    struct AlertParams<'a> {
        title: &'a str,
        message: &'a str,
    }

    #[derive(Debug, Deserialize)]
    struct AlertResult {
        #[serde(rename="buttonReturned")]
        button: String,
    }

    let rv: AlertResult = SCRIPT.execute_with_params(AlertParams {
        title: title,
        message: msg,
    }).chain_err(|| "Failed to display Xcode dialog")?;

    Ok(&rv.button != "Ignore")
}

/// Shows a notification in xcode
#[cfg(target_os="macos")]
pub fn show_notification(title: &str, msg: &str) -> Result<()> {
    lazy_static! {
        static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new("
            var App = Application.currentApplication();
            App.includeStandardAdditions = true;
            App.displayNotification($params.message, {
                withTitle: $params.title
            });
        ");
    }

    #[derive(Serialize)]
    struct NotificationParams<'a> {
        title: &'a str,
        message: &'a str,
    }

    Ok(SCRIPT.execute_with_params(NotificationParams {
        title: title,
        message: msg,
    }).chain_err(|| "Failed to display Xcode notification")?)
}
<commit_msg>Added support for :rfc1034identifier and :identifier for xcode<commit_after>use std::fs;
use std::env;
use std::fmt;
use std::path::Path;
use std::io::BufReader;
use std::borrow::Cow;

use plist::serde::deserialize;
use walkdir::WalkDir;
#[cfg(target_os="macos")]
use osascript;
#[cfg(target_os="macos")]
use unix_daemonize::{daemonize_redirect, ChdirMode};
use regex::Regex;

use prelude::*;
use utils::{TempFile, expand_vars};

#[derive(Deserialize, Debug)]
pub struct InfoPlist {
    #[serde(rename="CFBundleName")]
    name: String,
    #[serde(rename="CFBundleIdentifier")]
    bundle_id: String,
    #[serde(rename="CFBundleShortVersionString")]
    version: String,
    #[serde(rename="CFBundleVersion")]
    build: String,
}

impl fmt::Display for InfoPlist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} ({})", self.name(), &self.version)
    }
}

pub fn expand_xcodevars<'a>(s: &'a str) -> Cow<'a, str> {
    lazy_static! {
        static ref SEP_RE: Regex = Regex::new(r"[\s/]+").unwrap();
    }
    expand_vars(s, |key| {
        if key == "" {
            return "".into();
        }
        let mut iter = key.splitn(2, ':');
        let value = env::var(iter.next().unwrap()).unwrap_or("".into());
        match iter.next() {
            Some("rfc1034identifier") => {
                SEP_RE.replace_all(&value, "-").into_owned()
            },
            Some("identifier") => {
                SEP_RE.replace_all(&value, "_").into_owned()
            },
            None | Some(_) => value
        }
    })
}

impl InfoPlist {

    pub fn discover_from_path<P: AsRef<Path>>(path: P) -> Result<Option<InfoPlist>> {
        let fpl_fn = Some("info.plist".to_string());
        for dent_res in WalkDir::new(path.as_ref()) {
            let dent = dent_res?;
            if dent.file_name().to_str().map(|x| x.to_lowercase()) == fpl_fn {
                let md = dent.metadata()?;
                if md.is_file() {
                    return Ok(Some(InfoPlist::from_path(dent.path())?));
                }
            }
        }
        Ok(None)
    }

    pub fn discover_from_env() -> Result<Option<InfoPlist>> {
        if let Ok(path) = env::var("INFOPLIST_FILE") {
            Ok(Some(InfoPlist::from_path(path)?))
        } else {
            Ok(None)
        }
    }

    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<InfoPlist> {
        let f = fs::File::open(path.as_ref()).chain_err(||
            Error::from("Could not open Info.plist file"))?;
        let mut rdr = BufReader::new(f);
        Ok(deserialize(&mut rdr).chain_err(||
            Error::from("Could not parse Info.plist file"))?)
    }

    pub fn version(&self) -> &str {
        &self.version
    }

    pub fn build(&self) -> &str {
        &self.build
    }

    pub fn release_name(&self) -> String {
        format!("{} ({})", self.version, self.build)
    }

    pub fn name<'a>(&'a self) -> Cow<'a, str> {
        expand_xcodevars(&self.name)
    }

    pub fn bundle_id<'a>(&'a self) -> Cow<'a, str> {
        expand_xcodevars(&self.bundle_id)
    }
}

/// Helper struct that allows the current execution to detach from
/// the xcode console and continue in the background.  This becomes
/// a dummy shim for non xcode runs or platforms.
pub struct MayDetach<'a> {
    output_file: Option<TempFile>,
    #[allow(dead_code)]
    task_name: &'a str,
}

impl<'a> MayDetach<'a> {
    fn new(task_name: &'a str) -> MayDetach<'a> {
        MayDetach {
            output_file: None,
            task_name: task_name,
        }
    }

    /// Returns true if we are deteached from xcode
    pub fn is_detached(&self) -> bool {
        self.output_file.is_some()
    }

    /// If we are launched from xcode this detaches us from the xcode console
    /// and continues execution in the background.  From this moment on output
    /// is captured and the user is notified with notifications.
    #[cfg(target_os="macos")]
    pub fn may_detach(&mut self) -> Result<bool> {
        if !launched_from_xcode() {
            return Ok(false);
        }

        println!("Continuing in background.");
        show_notification("Sentry", &format!("{} starting", self.task_name))?;
        let output_file = TempFile::new()?;
        daemonize_redirect(Some(output_file.path()),
                           Some(output_file.path()),
                           ChdirMode::NoChdir).unwrap();
        self.output_file = Some(output_file);
        Ok(true)
    }

    /// For non mac platforms this just never detaches.
    #[cfg(not(target_os="macos"))]
    pub fn may_detach(&mut self) -> Result<bool> {
        Ok(false)
    }

    /// Wraps the execution of a code block.  Does not detach until someone
    /// calls into `may_detach`.
    #[cfg(target_os="macos")]
    pub fn wrap<T, F: FnOnce(&mut MayDetach) -> Result<T>>(task_name: &'a str, f: F) -> Result<T> {
        use std::time::Duration;
        use std::thread;
        use open;
        use utils::print_error;

        let mut md = MayDetach::new(task_name);
        match f(&mut md) {
            Ok(x) => {
                md.show_done()?;
                Ok(x)
            }
            Err(err) => {
                if let Some(ref output_file) = md.output_file {
                    print_error(&err);
                    if md.show_critical_info()? {
                        open::that(&output_file.path())?;
                        thread::sleep(Duration::from_millis(5000));
                    }
                }
                Err(err)
            }
        }
    }

    /// Dummy wrap call that never detaches for non mac platforms.
    #[cfg(not(target_os="macos"))]
    pub fn wrap<T, F: FnOnce(&mut MayDetach) -> Result<T>>(task_name: &'a str, f: F) -> Result<T> {
        f(&mut MayDetach::new(task_name))
    }

    #[cfg(target_os="macos")]
    fn show_critical_info(&self) -> Result<bool> {
        show_critical_info(
            &format!("{} failed", self.task_name),
            "The Sentry build step failed while running in the background. \
             You can ignore this error or view details to attempt to resolve \
             it. Ignoring it might cause your crashes not to be handled \
             properly.")
    }

    #[cfg(target_os="macos")]
    fn show_done(&self) -> Result<()> {
        if self.is_detached() {
            show_notification("Sentry", &format!("{} finished", self.task_name))?;
        }
        Ok(())
    }
}

/// Returns true if we were invoked from xcode
#[cfg(target_os="macos")]
pub fn launched_from_xcode() -> bool {
    env::var("XCODE_VERSION_ACTUAL").is_ok() && env::var("TERM").is_err()
}

/// Shows a dialog in xcode and blocks.  The dialog will have a title and a
/// message as well as the buttons "Show details" and "Ignore".  Returns
/// `true` if the `show details` button has been pressed.
#[cfg(target_os="macos")]
pub fn show_critical_info(title: &str, msg: &str) -> Result<bool> {
    lazy_static! {
        static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new("
            var App = Application('XCode');
            App.includeStandardAdditions = true;
            return App.displayAlert($params.title, {
                message: $params.message,
                as: \"critical\",
                buttons: [\"Show details\", \"Ignore\"]
            });
        ");
    }

    #[derive(Serialize)]
    struct AlertParams<'a> {
        title: &'a str,
        message: &'a str,
    }

    #[derive(Debug, Deserialize)]
    struct AlertResult {
        #[serde(rename="buttonReturned")]
        button: String,
    }

    let rv: AlertResult = SCRIPT.execute_with_params(AlertParams {
        title: title,
        message: msg,
    }).chain_err(|| "Failed to display Xcode dialog")?;

    Ok(&rv.button != "Ignore")
}

/// Shows a notification in xcode
#[cfg(target_os="macos")]
pub fn show_notification(title: &str, msg: &str) -> Result<()> {
    lazy_static! {
        static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new("
            var App = Application.currentApplication();
            App.includeStandardAdditions = true;
            App.displayNotification($params.message, {
                withTitle: $params.title
            });
        ");
    }

    #[derive(Serialize)]
    struct NotificationParams<'a> {
        title: &'a str,
        message: &'a str,
    }

    Ok(SCRIPT.execute_with_params(NotificationParams {
        title: title,
        message: msg,
    }).chain_err(|| "Failed to display Xcode notification")?)
}

#[test]
fn test_expansion() {
    env::set_var("FOO_BAR", "foo bar baz / blah");
    assert_eq!(expand_xcodevars("A$(FOO_BAR:rfc1034identifier)B").to_string(),
               "Afoo-bar-baz-blahB".to_string());
    assert_eq!(expand_xcodevars("A$(FOO_BAR:identifier)B").to_string(),
               "Afoo_bar_baz_blahB".to_string());
}
<|endoftext|>


<commit_before>use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::Rect;
use sdl2::render::{BlendMode, Renderer, Texture};
use sdl2::ttf::Sdl2TtfContext;

use position::Position;
use text::Text;

pub struct Console<'a> {
    pub visible: bool,

    input_buffer: String,
    buffer: Vec<String>,
    texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, renderer: &mut Renderer) -> Console<'a> {
        let mut texture = renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
            .unwrap();
        // Create a red-green gradient
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        Console {
            visible: false,
            input_buffer: "".into(),
            buffer: Vec::new(),
            texture: texture,
            ttf_context: ttf_context,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::TextInput { ref text, .. } => {
                self.add_text(text);
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Return), .. } => {
                self.commit();
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Backspace), .. } => {
                self.backspace();
            }
            _ => (),
        }
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        if self.visible {
            self.input_buffer.push_str(&input);
        }
    }

    pub fn commit(&mut self) {
        if self.visible {
            self.buffer.push(self.input_buffer.clone());
            self.input_buffer.clear();
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            self.input_buffer.pop();
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture, None, Some(Rect::new(0, 0, 640, 720))).unwrap();

            if self.input_buffer.len() > 0 {
                let text = Text::new(&self.ttf_context,
                                     &mut renderer,
                                     format!("{}|", &self.input_buffer[..]),
                                     Position::XY(0, 720 - 18),
                                     18,
                                     Color::RGBA(255, 255, 255, 255),
                                     "../assets/FantasqueSansMono-Bold.ttf");
                text.render(&mut renderer);
            }
        }
    }
}<commit_msg>Add navigation through console input buffer<commit_after>use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::Rect;
use sdl2::render::{BlendMode, Renderer, Texture};
use sdl2::ttf::Sdl2TtfContext;

use position::Position;
use text::Text;

pub struct Console<'a> {
    pub visible: bool,

    input_buffer: String,
    cursor_position: usize,
    buffer: Vec<String>,
    texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, renderer: &mut Renderer) -> Console<'a> {
        let mut texture = renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
            .unwrap();
        // Create a red-green gradient
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        Console {
            visible: false,
            input_buffer: "".into(),
            cursor_position: 0,
            buffer: Vec::new(),
            texture: texture,
            ttf_context: ttf_context,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::TextInput { ref text, .. } => {
                if self.visible {
                    self.add_text(text);
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => {
                if self.visible {
                    self.cursor_left();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => {
                if self.visible {
                    self.cursor_right();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Return), .. } => {
                if self.visible {
                    self.commit();
                }
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Backspace), .. } => {
                if self.visible {
                    self.backspace();
                }
            }
            _ => (),
        }
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        self.input_buffer.insert(self.cursor_position, input.chars().next().unwrap());
        self.cursor_position += 1;
    }

    pub fn commit(&mut self) {
        self.buffer.push(self.input_buffer.clone());
        self.input_buffer.clear();
    }

    pub fn cursor_left(&mut self) {
        if self.cursor_position > 0 {
            self.cursor_position -= 1;
        }
    }

    pub fn cursor_right(&mut self) {
        if self.cursor_position < self.input_buffer.len() {
            self.cursor_position += 1;
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            self.input_buffer.remove(self.cursor_position - 1);
            if self.cursor_position > 0 {
                self.cursor_position -= 1;
            }
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture, None, Some(Rect::new(0, 0, 640, 720))).unwrap();

            let mut output_text = self.input_buffer.clone();
            if self.cursor_position < output_text.len() {
                output_text.insert(self.cursor_position, '|');
            } else {
                output_text.push_str("|");
            }
            if self.input_buffer.len() > 0 {
                let text = Text::new(&self.ttf_context,
                                     &mut renderer,
                                     &output_text[..],
                                     Position::XY(0, 720 - 18),
                                     18,
                                     Color::RGBA(255, 255, 255, 255),
                                     "../assets/FantasqueSansMono-Bold.ttf");
                text.render(&mut renderer);
            }
        }
    }
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Rust helpers for Gecko's `nsStyleAutoArray`.

use gecko_bindings::structs::nsStyleAutoArray;
use std::iter::{once, Chain, Once, IntoIterator};
use std::slice::{Iter, IterMut};

impl<T> nsStyleAutoArray<T> {
    /// Mutably iterate over the array elements.
    pub fn iter_mut(&mut self) -> Chain<Once<&mut T>, IterMut<T>> {
        once(&mut self.mFirstElement).chain(self.mOtherElements.iter_mut())
    }

    /// Iterate over the array elements.
    pub fn iter(&self) -> Chain<Once<&T>, Iter<T>> {
        once(&self.mFirstElement).chain(self.mOtherElements.iter())
    }

    /// Returns the length of the array.
    ///
    /// Note that often structs containing autoarrays will have additional
    /// member fields that contain the length, which must be kept in sync.
    pub fn len(&self) -> usize {
        1 + self.mOtherElements.len()
    }
}

impl<'a, T> IntoIterator for &'a mut nsStyleAutoArray<T> {
    type Item = &'a mut T;
    type IntoIter = Chain<Once<&'a mut T>, IterMut<'a, T>>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}
<commit_msg>Implement Index for nsStyleAutoArray. r=heycam<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Rust helpers for Gecko's `nsStyleAutoArray`.

use gecko_bindings::structs::nsStyleAutoArray;
use std::iter::{once, Chain, Once, IntoIterator};
use std::ops::Index;
use std::slice::{Iter, IterMut};

impl<T> Index<usize> for nsStyleAutoArray<T> {
    type Output = T;
    fn index(&self, index: usize) -> &T {
        if index > self.len() {
            panic!("out of range")
        }
        match index {
            0 => &self.mFirstElement,
            _ => &self.mOtherElements[index - 1],
        }
    }
}

impl<T> nsStyleAutoArray<T> {
    /// Mutably iterate over the array elements.
    pub fn iter_mut(&mut self) -> Chain<Once<&mut T>, IterMut<T>> {
        once(&mut self.mFirstElement).chain(self.mOtherElements.iter_mut())
    }

    /// Iterate over the array elements.
    pub fn iter(&self) -> Chain<Once<&T>, Iter<T>> {
        once(&self.mFirstElement).chain(self.mOtherElements.iter())
    }

    /// Returns the length of the array.
    ///
    /// Note that often structs containing autoarrays will have additional
    /// member fields that contain the length, which must be kept in sync.
    pub fn len(&self) -> usize {
        1 + self.mOtherElements.len()
    }
}

impl<'a, T> IntoIterator for &'a mut nsStyleAutoArray<T> {
    type Item = &'a mut T;
    type IntoIter = Chain<Once<&'a mut T>, IterMut<'a, T>>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use super::{Error, Result};
use crate::utils::mtd;
use pkg_schema::definitions::{
    target_permissions::{Gid, Uid},
    TargetType,
};
use std::path::PathBuf;

/// Utility funtions for [TargetType](pkg_schema::definitions::TargetType)
pub(crate) trait TargetTypeExt {
    /// Checks whether the device is valid to start installation, i.e.,
    /// device exists, use have write permission.
    fn valid(&self) -> Result<&Self>;

    /// Gets device's path for mounting.
    fn get_target(&self) -> Result<PathBuf>;
}

impl TargetTypeExt for TargetType {
    fn valid(&self) -> Result<&Self> {
        Ok(match self {
            TargetType::Device(p) => {
                if !p.exists() {
                    return Err(Error::DeviceDoesNotExist(p.to_path_buf()));
                }
                if p.metadata()?.permissions().readonly() {
                    return Err(Error::MissingWritePermission(p.to_path_buf()));
                }
                &self
            }
            TargetType::UBIVolume(s) => {
                let dev = mtd::target_device_from_ubi_volume_name(s)?;
                if dev.metadata()?.permissions().readonly() {
                    return Err(Error::MissingWritePermission(dev));
                }
                &self
            }
            TargetType::MTDName(n) => {
                let dev = mtd::target_device_from_mtd_name(n)?;
                if dev.metadata()?.permissions().readonly() {
                    return Err(Error::MissingWritePermission(dev));
                }
                &self
            }
        })
    }

    fn get_target(&self) -> Result<PathBuf> {
        match self {
            TargetType::Device(p) => Ok(p.clone()),
            TargetType::UBIVolume(s) => mtd::target_device_from_ubi_volume_name(s),
            TargetType::MTDName(s) => mtd::target_device_from_mtd_name(s),
        }
    }
}

/// Utility funtions for [Gid](pkg_schema::definitions::target_permissions::Gid)
/// and [Uid](pkg_schema::definitions::target_permissions::Uid)
pub(crate) trait IdExt {
    /// Gets numeric id;
    fn as_u32(&self) -> u32;
}

impl IdExt for Gid {
    fn as_u32(&self) -> u32 {
        match self {
            Gid::Name(s) => nix::unistd::Group::from_name(s).unwrap().unwrap().gid.as_raw(),
            Gid::Number(n) => *n,
        }
    }
}

impl IdExt for Uid {
    fn as_u32(&self) -> u32 {
        match self {
            Uid::Name(s) => nix::unistd::User::from_name(s).unwrap().unwrap().uid.as_raw(),
            Uid::Number(n) => *n,
        }
    }
}
<commit_msg>updatehub: utils: definitions: Rework to reduce duplicated code<commit_after>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use super::{Error, Result};
use crate::utils::mtd;
use pkg_schema::definitions::{
    target_permissions::{Gid, Uid},
    TargetType,
};
use std::path::PathBuf;

/// Utility funtions for [TargetType](pkg_schema::definitions::TargetType)
pub(crate) trait TargetTypeExt {
    /// Checks whether the device is valid to start installation, i.e.,
    /// device exists, use have write permission.
    fn valid(&self) -> Result<&Self>;

    /// Gets device's path for mounting.
    fn get_target(&self) -> Result<PathBuf>;
}

impl TargetTypeExt for TargetType {
    fn valid(&self) -> Result<&Self> {
        let device = self.get_target()?;

        if !device.exists() {
            return Err(Error::DeviceDoesNotExist(device));
        }

        if device.metadata()?.permissions().readonly() {
            return Err(Error::MissingWritePermission(device));
        }

        Ok(&self)
    }

    fn get_target(&self) -> Result<PathBuf> {
        match self {
            TargetType::Device(p) => Ok(p.clone()),
            TargetType::UBIVolume(s) => mtd::target_device_from_ubi_volume_name(s),
            TargetType::MTDName(s) => mtd::target_device_from_mtd_name(s),
        }
    }
}

/// Utility funtions for [Gid](pkg_schema::definitions::target_permissions::Gid)
/// and [Uid](pkg_schema::definitions::target_permissions::Uid)
pub(crate) trait IdExt {
    /// Gets numeric id;
    fn as_u32(&self) -> u32;
}

impl IdExt for Gid {
    fn as_u32(&self) -> u32 {
        match self {
            Gid::Name(s) => nix::unistd::Group::from_name(s).unwrap().unwrap().gid.as_raw(),
            Gid::Number(n) => *n,
        }
    }
}

impl IdExt for Uid {
    fn as_u32(&self) -> u32 {
        match self {
            Uid::Name(s) => nix::unistd::User::from_name(s).unwrap().unwrap().uid.as_raw(),
            Uid::Number(n) => *n,
        }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;

fn sum(sizes: &[u32]) -> u32 {
    sizes.iter().fold(0, |acc, v| acc + v)
}

#[test]
fn test_sum() {
    assert_eq!(150, sum(&vec![10u32, 20u32, 30u32, 40u32, 50u32]));
}

fn combination(count: u32, from: &[u32]) -> Vec<Vec<u32>> {
    let mut combos: Vec<Vec<u32>> = Vec::new();
    if count == 1 {
        for i in from {
            combos.push(vec![*i]);
        }
    } else if count > 1 {
        for i in 0..from.len() {
            let sub_combos = combination(count - 1, &from[i + 1..]);
            for c in &sub_combos {
                let mut head = Vec::new();
                head.push(from[i]);
                head.extend(c);
                combos.push(head);
            }
        }
    }
    combos
}

fn part1_combos(eggnog: &u32, sizes: &Vec<u32>) {
    let mut count = 0;
    for i in 0..sizes.len() {
        for c in combination(i as u32, &sizes) {
            if sum(&c) == *eggnog {
                println!("150 == {:?}", c);
                count += 1;
            }
        }
    }
    println!("There are {} combos", count);
}

fn main() {
    let f = File::open("input.txt").unwrap();
    let line_buffer = BufReader::new(&f);

    let mut containers = Vec::new();
    let eggnog = 150u32;

    for line in line_buffer.lines() {
        let size = line.unwrap().parse::<u32>().unwrap();
        containers.push(size);
    }

    part1_combos(&eggnog, &containers);
}
<commit_msg> working 17 part 2<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;

fn sum(sizes: &[u32]) -> u32 {
    sizes.iter().fold(0, |acc, v| acc + v)
}

#[test]
fn test_sum() {
    assert_eq!(150, sum(&vec![10u32, 20u32, 30u32, 40u32, 50u32]));
}

fn combination(count: u32, from: &[u32]) -> Vec<Vec<u32>> {
    let mut combos: Vec<Vec<u32>> = Vec::new();
    if count == 1 {
        for i in from {
            combos.push(vec![*i]);
        }
    } else if count > 1 {
        for i in 0..from.len() {
            let sub_combos = combination(count - 1, &from[i + 1..]);
            for c in &sub_combos {
                let mut head = Vec::new();
                head.push(from[i]);
                head.extend(c);
                combos.push(head);
            }
        }
    }
    combos
}

fn part1_combos(eggnog: &u32, sizes: &Vec<u32>) {
    let mut count = 0;
    for i in 0..sizes.len() {
        for c in combination(i as u32, &sizes) {
            if sum(&c) == *eggnog {
                println!("150 == {:?}", c);
                count += 1;
            }
        }
    }
    println!("There are {} combos", count);
}

fn part2_min(eggnog: &u32, sizes: &Vec<u32>) {
    let mut count = 0;
    let mut found = false;
    for i in 0..sizes.len() {
        for c in combination(i as u32, &sizes) {
            if sum(&c) == *eggnog {
                found = true;
                println!("150 == {:?}", c);
                count += 1;
            }
        }
        // We found the min size, so only look that far
        if found {
            break;
        }
    }
    println!("There are {} combos", count);
}

fn main() {
    let f = File::open("input.txt").unwrap();
    let line_buffer = BufReader::new(&f);

    let mut containers = Vec::new();
    let eggnog = 150u32;

    for line in line_buffer.lines() {
        let size = line.unwrap().parse::<u32>().unwrap();
        containers.push(size);
    }

    part1_combos(&eggnog, &containers);
    part2_min(&eggnog, &containers);
}
<|endoftext|>


<commit_before>use super::{Error};
use std::io::Write;
use std::io::Read;
use super::super::parse::ast::DataSrc;
use super::super::parse::ast::CompType;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

/// General enums in SQL
#[derive(Debug, Clone, Copy, RustcDecodable, RustcEncodable, PartialEq)]
pub enum SqlType {
    Int,
    Bool,
    Char(u8),
}

/// Defines the size of Sql data types
/// and returns them
impl SqlType {
    pub fn size(&self) -> u32 {
        match self {
            &SqlType::Int => 4 as u32,
            &SqlType::Bool => 1 as u32,
            &SqlType::Char(len) => (len + 1) as u32,
        }
    }

    /// Decodes the data in buf according to SqlType into a DataSrc enum.
    pub fn decode_from<R: Read>(&self, mut buf: &mut R) -> Result<DataSrc, Error> {
        match self {
            &SqlType::Int => {
                let i = try!(buf.read_i32::<BigEndian>());
                Ok(DataSrc::Int(i as i64))
            },
            &SqlType::Bool => {
                let b = try!(buf.read_u8());
                Ok(DataSrc::Bool(b))
            },
            &SqlType::Char(_) => {
                let mut s = String::new();
                try!(buf.read_to_string(&mut s));
                Ok(DataSrc::String(s))
            },
        }
    }

    /// Writes data to buf
    /// Returns the bytes written.
    /// Returns Error::InvalidType if type of DataSrc does not match expected
    /// type.
    /// Returns byteorder::Error, if data could not be written to buf.
    /// DataSrc: contains data to write to buf
    /// buf: target of write operation.
    pub fn encode_into<W: Write>(&self, mut buf: &mut W, data: &DataSrc)
    -> Result<u32, Error>
    {
        match self {
            &SqlType::Int => {
                match data {
                    &DataSrc::Int(a) => {
                        if a > i32::max_value() as i64 {
                            Err(Error::InvalidType)
                        }
                        else {
                            try!(buf.write_i32::<BigEndian>(a as i32));
                            Ok(self.size())
                        }
                    },
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
            &SqlType::Bool => {
                match data {
                    &DataSrc::Bool(a) => {
                        try!(buf.write_u8(a as u8));
                        Ok(self.size())
                    }
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
            &SqlType::Char(len) => {
                match data {
                    &DataSrc::String(ref a) => {
                        let str_as_bytes = Self::to_nul_terminated_bytes(&a, (len + 1) as u32);
                        try!(buf.write_all(&str_as_bytes));
                        Ok(self.size())
                    }
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
        }
    }
    /// Writes the vector vec to buf.
    /// Returns the bytes written.
    /// Returns byteorder::Error if vec could not be written to buf
    fn write_to_buf<W: Write>(mut buf: W, vec: &Vec<u8>) -> Result<u32, Error> {
        let mut it = vec.into_iter();
        let mut bytes_written = 0;

        loop {
            match it.next() {
                Some(v) => {
                    try!(buf.write_u8(*v));
                    bytes_written += 1;
                },
                None => break,
            }
        }
        Ok(bytes_written)
    }

    /// Convert s to a vector with l bytes.
    /// If length of s is > l, the returning vector will only contain the first
    /// l bytes.
    /// Otherwise the returned vector will be filled with \0
    /// until it contains l bytes.
    fn to_nul_terminated_bytes(s : &str, l: u32) -> Vec<u8> {
        let mut v = s.to_string().into_bytes();

        v.truncate((l - 1) as usize);

        while v.len() < l as usize {
            v.push(0x00);
        }
        v
    }
    /// compare function that lets you logical compare slices of u8
    /// returns a boolean on success and Error on fail
    /// uses other compare fn for the actual compare
    pub fn cmp(&self, val: &[u8], val2: &[u8], comp: CompType)
    -> Result<bool, Error>
    {
        match self {
            &SqlType::Int => {
                match comp {
                    CompType::Equ => { self.compare_byte_for_equal(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },

            &SqlType::Bool => {
                match comp {
                    CompType::Equ => { self.compare_as_bool(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },

            &SqlType::Char(x) => {
                match comp {
                    CompType::Equ => { self.compare_byte_for_equal(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },
        }
    }
    /// fn compares slices of u8 byte for byte and returns if both values are equal
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_for_equal(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] != val2[i] {
                return Ok(false)
            }
        }
        Ok(true)
    }
    /// fn compares slices of u8 byte for byte and returns
    /// if first given value is greater than the second one
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_greater_than(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] > val2[i] {
                return Ok(true)
            }
        }
        Ok(false)
    }

    /// fn compares slices of u8 byte for byte and returns
    /// if first given value is lesser than the second one
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_lesser_than(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] < val2[i] {
                return Ok(true)
            }
        }
        Ok(false)
    }

    /// fn compares slices of u8 as booleans and returns
    /// if both both booleans are true
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_as_bool(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        let mut sov: bool = false;
        let mut sov2: bool = false;
        for i in 0 .. val.len() {
            if val[i] != 0 {
                sov = true;
                break;
            }
        }

        for i in 0 .. val2.len() {
            if val2[i] != 0 {
                sov = true;
                break;
            }
        }

        if sov == sov2 {
            return Ok(true)
        }

        Ok(false)
    }
}

//---------------------------------------------------------------
// Column
//---------------------------------------------------------------

/// A table column. Has a name, a type, ...
#[derive(Debug,RustcDecodable, RustcEncodable,Clone)]
pub struct Column {
    pub name: String, // name of column
    pub sql_type: SqlType, // name of the data type that is contained in this column
    pub is_primary_key: bool, // defines if column is PK
    pub allow_null: bool, // defines if cloumn allows null
    pub description: String //Displays text describing this column.
}

impl Column {
    /// Creates a new column object
    /// Returns with Column
    pub fn new(
        name: &str,
        sql_type: SqlType,
        allow_null: bool,
        description: &str,
        is_primary_key: bool
        ) -> Column {

        Column {
            name: name.to_string(),
            sql_type: sql_type.clone(),
            allow_null: allow_null,
            description: description.to_string(),
            is_primary_key: is_primary_key
        }
    }

    pub fn get_sql_type(&self) -> &SqlType {
        &self.sql_type
    }

    pub fn get_coulmn_name(&self) -> &str {
        &self.name
    }

    pub fn get_size(&self) -> u32 {
        self.sql_type.size() as u32
    }
}

//---------------------------------------------------------------
// FromSql
//---------------------------------------------------------------

pub trait FromSql {
    fn from_sql(data: &[u8]) -> Result<Self, Error>;
}

impl FromSql for i32 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let i = try!(data.read_i32::<BigEndian>());
        Ok(i)
    }
}

impl FromSql for u16 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let u = try!(data.read_u16::<BigEndian>());
        Ok(u)
    }
}

impl FromSql for u8 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        Err(Error::NoImplementation)
    }
}
impl FromSql for String {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {

        let mut s = String::new();

        try!(data.read_to_string(&mut s));
        //s.trim_matches('\0');
        Ok(s)
    }
}

impl FromSql for bool {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let b = try!(data.read_u8());
        if b == 0 {
            return Ok(false)
        }
        Ok(true)
    }
}
<commit_msg>Add value comparison for Int<commit_after>use super::{Error};
use std::io::Write;
use std::io::Read;
use super::super::parse::ast::DataSrc;
use super::super::parse::ast::CompType;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

/// General enums in SQL
#[derive(Debug, Clone, Copy, RustcDecodable, RustcEncodable, PartialEq)]
pub enum SqlType {
    Int,
    Bool,
    Char(u8),
}

/// Defines the size of Sql data types
/// and returns them
impl SqlType {
    pub fn size(&self) -> u32 {
        match self {
            &SqlType::Int => 4 as u32,
            &SqlType::Bool => 1 as u32,
            &SqlType::Char(len) => (len + 1) as u32,
        }
    }

    /// Decodes the data in buf according to SqlType into a DataSrc enum.
    pub fn decode_from<R: Read>(&self, mut buf: &mut R) -> Result<DataSrc, Error> {
        match self {
            &SqlType::Int => {
                let i = try!(buf.read_i32::<BigEndian>());
                Ok(DataSrc::Int(i as i64))
            },
            &SqlType::Bool => {
                let b = try!(buf.read_u8());
                Ok(DataSrc::Bool(b))
            },
            &SqlType::Char(_) => {
                let mut s = String::new();
                try!(buf.read_to_string(&mut s));
                Ok(DataSrc::String(s))
            },
        }
    }

    /// Writes data to buf
    /// Returns the bytes written.
    /// Returns Error::InvalidType if type of DataSrc does not match expected
    /// type.
    /// Returns byteorder::Error, if data could not be written to buf.
    /// DataSrc: contains data to write to buf
    /// buf: target of write operation.
    pub fn encode_into<W: Write>(&self, mut buf: &mut W, data: &DataSrc)
    -> Result<u32, Error>
    {
        match self {
            &SqlType::Int => {
                match data {
                    &DataSrc::Int(a) => {
                        if a > i32::max_value() as i64 {
                            Err(Error::InvalidType)
                        }
                        else {
                            try!(buf.write_i32::<BigEndian>(a as i32));
                            Ok(self.size())
                        }
                    },
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
            &SqlType::Bool => {
                match data {
                    &DataSrc::Bool(a) => {
                        try!(buf.write_u8(a as u8));
                        Ok(self.size())
                    }
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
            &SqlType::Char(len) => {
                match data {
                    &DataSrc::String(ref a) => {
                        let str_as_bytes = Self::to_nul_terminated_bytes(&a, (len + 1) as u32);
                        try!(buf.write_all(&str_as_bytes));
                        Ok(self.size())
                    }
                    _=> {
                        Err(Error::InvalidType)
                    }
                }
            },
        }
    }
    /// Writes the vector vec to buf.
    /// Returns the bytes written.
    /// Returns byteorder::Error if vec could not be written to buf
    fn write_to_buf<W: Write>(mut buf: W, vec: &Vec<u8>) -> Result<u32, Error> {
        let mut it = vec.into_iter();
        let mut bytes_written = 0;

        loop {
            match it.next() {
                Some(v) => {
                    try!(buf.write_u8(*v));
                    bytes_written += 1;
                },
                None => break,
            }
        }
        Ok(bytes_written)
    }

    /// Convert s to a vector with l bytes.
    /// If length of s is > l, the returning vector will only contain the first
    /// l bytes.
    /// Otherwise the returned vector will be filled with \0
    /// until it contains l bytes.
    fn to_nul_terminated_bytes(s : &str, l: u32) -> Vec<u8> {
        let mut v = s.to_string().into_bytes();

        v.truncate((l - 1) as usize);

        while v.len() < l as usize {
            v.push(0x00);
        }
        v
    }
    /// compare function that lets you logical compare slices of u8
    /// returns a boolean on success and Error on fail
    /// uses other compare fn for the actual compare
    pub fn cmp(&self, val: &[u8], val2: &[u8], comp: CompType)
    -> Result<bool, Error>
    {
        match self {
            &SqlType::Int => {
                match comp {
                    CompType::Equ => { self.compare_byte_for_equal(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },

            &SqlType::Bool => {
                match comp {
                    CompType::Equ => { self.compare_as_bool(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },

            &SqlType::Char(x) => {
                match comp {
                    CompType::Equ => { self.compare_byte_for_equal(val, val2) },
                    CompType::NEqu => { self.compare_byte_for_equal(val, val2).map(|x| !x) },
                    CompType::GThan => { self.compare_byte_greater_than(val, val2) },
                    CompType::SThan => { self.compare_byte_lesser_than(val, val2) },
                    CompType::GEThan => { self.compare_byte_lesser_than(val, val2).map(|x| !x) },
                    CompType::SEThan => { self.compare_byte_greater_than(val, val2).map(|x| !x) },
                }
            },
        }
    }
    /// fn compares slices of u8 byte for byte and returns if both values are equal
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_for_equal(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] != val2[i] {
                return Ok(false)
            }
        }
        Ok(true)
    }
    /// fn compares slices of u8 byte for byte and returns
    /// if first given value is greater than the second one
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_greater_than(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] > val2[i] {
                return Ok(true)
            }
        }
        Ok(false)
    }

    /// fn compares slices of u8 byte for byte and returns
    /// if first given value is lesser than the second one
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_byte_lesser_than(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        if val.len() != val2.len() {
            return Err(Error::WrongLength)
        }
        for i in 0 .. val.len() {
            if val[i] < val2[i] {
                return Ok(true)
            }
        }
        Ok(false)
    }

    /// fn compares slices of u8 as booleans and returns
    /// if both both booleans are true
    /// returns boolean on success and Error when given values do not have the same size
    fn compare_as_bool(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        let mut sov: bool = false;
        let mut sov2: bool = false;
        for i in 0 .. val.len() {
            if val[i] != 0 {
                sov = true;
                break;
            }
        }

        for i in 0 .. val2.len() {
            if val2[i] != 0 {
                sov = true;
                break;
            }
        }

        if sov == sov2 {
            return Ok(true)
        }

        Ok(false)
    }
    /// converts value to i32 and compares if equal
    /// returns boolean if successful returns Error if not
    fn equal_for_int_with_value(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        let int1: i32 = try!(i32::from_sql(val));
        let int2: i32 = try!(i32::from_sql(val2));

        if int1 != int2 {
            return Ok(false)
        }
        Ok(true)
    }

    /// converts value to i32 and compares if first value is greater
    /// returns boolean if successful returns Error if not
    fn greater_than_for_int_with_value(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        let int1: i32 = try!(i32::from_sql(val));
        let int2: i32 = try!(i32::from_sql(val2));

        if int1 > int2 {
            return Ok(true)
        }
        Ok(false)
    }

    /// converts value to i32 and compares if first value is lesser
    /// returns boolean if successful returns Error if not
    fn lesser_than_for_int_with_value(&self, val: &[u8], val2: &[u8])
    -> Result<bool, Error>
    {
        let int1: i32 = try!(i32::from_sql(val));
        let int2: i32 = try!(i32::from_sql(val2));

        if int1 < int2 {
            return Ok(true)
        }
        Ok(false)
    }
}

//---------------------------------------------------------------
// Column
//---------------------------------------------------------------

/// A table column. Has a name, a type, ...
#[derive(Debug,RustcDecodable, RustcEncodable,Clone)]
pub struct Column {
    pub name: String, // name of column
    pub sql_type: SqlType, // name of the data type that is contained in this column
    pub is_primary_key: bool, // defines if column is PK
    pub allow_null: bool, // defines if cloumn allows null
    pub description: String //Displays text describing this column.
}

impl Column {
    /// Creates a new column object
    /// Returns with Column
    pub fn new(
        name: &str,
        sql_type: SqlType,
        allow_null: bool,
        description: &str,
        is_primary_key: bool
        ) -> Column {

        Column {
            name: name.to_string(),
            sql_type: sql_type.clone(),
            allow_null: allow_null,
            description: description.to_string(),
            is_primary_key: is_primary_key
        }
    }

    pub fn get_sql_type(&self) -> &SqlType {
        &self.sql_type
    }

    pub fn get_coulmn_name(&self) -> &str {
        &self.name
    }

    pub fn get_size(&self) -> u32 {
        self.sql_type.size() as u32
    }
}

//---------------------------------------------------------------
// FromSql
//---------------------------------------------------------------

pub trait FromSql {
    fn from_sql(data: &[u8]) -> Result<Self, Error>;
}

impl FromSql for i32 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let i = try!(data.read_i32::<BigEndian>());
        Ok(i)
    }
}

impl FromSql for u16 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let u = try!(data.read_u16::<BigEndian>());
        Ok(u)
    }
}

impl FromSql for u8 {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        Err(Error::NoImplementation)
    }
}
impl FromSql for String {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {

        let mut s = String::new();

        try!(data.read_to_string(&mut s));
        //s.trim_matches('\0');
        Ok(s)
    }
}

impl FromSql for bool {
    fn from_sql(mut data: &[u8]) -> Result<Self, Error> {
        let b = try!(data.read_u8());
        if b == 0 {
            return Ok(false)
        }
        Ok(true)
    }
}
<|endoftext|>


<commit_before>use objects::message::Message;
use objects::user::User;

#[derive(Clone, Deserialize, Debug)]
pub struct CallBackQuery {
    id: String,
    from: User,
    message: Option<Message>,
    inline_message_id: Option<String>,
    chat_instance: String,
    data: Option<String>,
    game_short_name: Option<String>,
}<commit_msg>changed all values to public<commit_after>use objects::message::Message;
use objects::user::User;

#[derive(Clone, Deserialize, Debug)]
pub struct CallBackQuery {
    pub id: String,
    pub from: User,
    pub message: Option<Message>,
    pub inline_message_id: Option<String>,
    pub chat_instance: String,
    pub data: Option<String>,
    pub game_short_name: Option<String>,
}<|endoftext|>


<commit_before>use numbers::*;
use super::{Simd, SimdFrom};
use stdsimd::simd::*;
use stdsimd::vendor::*;

/// This value must be read in groups of 2 bits.
const SWAP_IQ_PS: i32 = 0b10110001;

/// This value must be read in groups of 2 bits:
/// 10 means that the third position (since it's the third bit pair)
/// will be replaced with the value of the second position (10b = 2d)
const SWAP_IQ_PD: i32 = 0b10110001;

impl Simd<f32> for f32x8 {
    type Array = [f32; 8];

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

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

	const LEN: usize = 8;

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

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

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

    #[inline]
    fn add_complex(self, value: Complex<f32>) -> f32x8 {
        let increment = f32x8::from_complex(value);
        self + increment
    }

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

    #[inline]
    fn scale_complex(self, value: Complex<f32>) -> f32x8 {
        let scaling_real = f32x8::splat(value.re);
        let scaling_imag = f32x8::splat(value.im);
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_ps(self, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_ps(parallel, cross) }
    }

    #[inline]
    fn mul_complex(self, value: f32x8) -> f32x8 {
        let scaling_real = f32x8::new(value.extract(0),
                                      value.extract(0),
                                      value.extract(2),
                                      value.extract(2),
                                      value.extract(4),
                                      value.extract(4),
                                      value.extract(6),
                                      value.extract(6));
        let scaling_imag = f32x8::new(value.extract(1),
                                      value.extract(1),
                                      value.extract(3),
                                      value.extract(3),
                                      value.extract(5),
                                      value.extract(5),
                                      value.extract(7),
                                      value.extract(7));
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_ps(self, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_ps(parallel, cross) }
    }

    #[inline]
    fn div_complex(self, value: f32x8) -> f32x8 {
        let scaling_imag = f32x8::new(self.extract(0),
                                      self.extract(0),
                                      self.extract(2),
                                      self.extract(2),
                                      self.extract(4),
                                      self.extract(4),
                                      self.extract(6),
                                      self.extract(6));
        let scaling_real = f32x8::new(self.extract(1),
                                      self.extract(1),
                                      self.extract(3),
                                      self.extract(3),
                                      self.extract(5),
                                      self.extract(5),
                                      self.extract(7),
                                      self.extract(7));
        let parallel = scaling_real * value;
        let shuffled = unsafe { _mm256_permute_ps(value, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        let mul = unsafe { _mm256_addsub_ps(parallel, cross) };
        let square = shuffled * shuffled;
        let square_shuffled = unsafe { _mm256_permute_ps(square, SWAP_IQ_PS) };
        let sum = square + square_shuffled;
        let div = mul / sum;
        unsafe { _mm256_permute_ps(div, SWAP_IQ_PS) }
    }

    #[inline]
    fn complex_abs_squared(self) -> f32x8 {
        let squared = self * self;
        unsafe { _mm256_hadd_ps(squared, squared) }
    }

    #[inline]
    fn complex_abs(self) -> f32x8 {
        let squared_sum = self.complex_abs_squared();
        unsafe { _mm256_sqrt_ps(squared_sum) }
    }

    #[inline]
    fn complex_abs_squared2(self) -> f32x8 {
        self.complex_abs_squared()
    }

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

    #[inline]
    fn sqrt(self) -> f32x8 {
        unsafe { _mm256_sqrt_ps(self) }
    }

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

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

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

    #[inline]
    fn max(self, other: Self) -> Self {
        unsafe { _mm256_max_ps(self, other) }
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        unsafe { _mm256_min_ps(self, other) }
    }
}

impl Simd<f64> for f64x4 {
    type Array = [f64; 4];

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

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

	const LEN: usize = 4;

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

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

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

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

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

    #[inline]
    fn scale_complex(self, value: Complex<f64>) -> f64x4 {
        let scaling_real = f64x4::splat(value.re);
        let scaling_imag = f64x4::splat(value.im);
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_pd(self, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_pd(parallel, cross) }
    }

    #[inline]
    fn mul_complex(self, value: f64x4) -> f64x4 {
        let scaling_real = f64x4::new(value.extract(0),
                                      value.extract(0),
                                      value.extract(2),
                                      value.extract(2));
        let scaling_imag = f64x4::new(value.extract(1),
                                      value.extract(1),
                                      value.extract(3),
                                      value.extract(3));
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_pd(self, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_pd(parallel, cross) }
    }

    #[inline]
    fn div_complex(self, value: f64x4) -> f64x4 {
        let scaling_imag = f64x4::new(self.extract(0),
                                      self.extract(0),
                                      self.extract(2),
                                      self.extract(2));
        let scaling_real = f64x4::new(self.extract(1),
                                      self.extract(1),
                                      self.extract(3),
                                      self.extract(3));
        let parallel = scaling_real * value;
        let shuffled = unsafe { _mm256_permute_pd(value, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        let mul = unsafe { _mm256_addsub_pd(parallel, cross) };
        let square = shuffled * shuffled;
        let square_shuffled = unsafe { _mm256_permute_pd(square, SWAP_IQ_PD) };
        let sum = square + square_shuffled;
        let div = mul / sum;
        unsafe { _mm256_permute_pd(div, SWAP_IQ_PD) }
    }

    #[inline]
    fn complex_abs_squared(self) -> f64x4 {
        let squared = self * self;
        unsafe { _mm256_hadd_pd(squared, squared) }
    }

    #[inline]
    fn complex_abs(self) -> f64x4 {
        let squared_sum = self.complex_abs_squared();
        unsafe { _mm256_sqrt_pd(squared_sum) }
    }

    #[inline]
    fn complex_abs_squared2(self) -> f64x4 {
        self.complex_abs_squared()
    }

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

    #[inline]
    fn sqrt(self) -> f64x4 {
        unsafe { _mm256_sqrt_pd(self) }
    }

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

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

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

    #[inline]
    fn max(self, other: Self) -> Self {
        unsafe { _mm256_max_pd(self, other) }
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        unsafe { _mm256_min_pd(self, other) }
    }
}

impl SimdFrom<f32x8> for i32x8 {
    fn regfrom(value: f32x8) -> Self {
        value.as_i32x8()
    }
}

impl SimdFrom<i32x8> for f32x8 {
    fn regfrom(value: i32x8) -> Self {
        value.as_f32x8()
    }
}

impl SimdFrom<f64x4> for i64x4 {
    fn regfrom(value: f64x4) -> Self {
        value.as_i64x4()
    }
}

impl SimdFrom<i64x4> for f64x4 {
    fn regfrom(value: i64x4) -> Self {
        value.as_f64x4()
    }
}

#[cfg(test)]
#[target_feature = "+avx"]
mod tests {
    use super::*;

    #[test]
    fn shuffle_test() {
        let vec = f32x8::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
        let result = unsafe { _mm256_permute_ps(vec, SWAP_IQ_PS) };
        let expected =
            f32x8::new(vec.extract(1),
                 vec.extract(0),
                 vec.extract(3),
                 vec.extract(2),
                 vec.extract(5),
                 vec.extract(4),
                 vec.extract(7),
                 vec.extract(6));
        assert_eq!(result, expected);
    }
}<commit_msg>Fixed warning<commit_after>use numbers::*;
use super::{Simd, SimdFrom};
use stdsimd::simd::*;
use stdsimd::vendor::*;

/// This value must be read in groups of 2 bits.
const SWAP_IQ_PS: i32 = 0b10110001;

/// This value must be read in groups of 2 bits:
/// 10 means that the third position (since it's the third bit pair)
/// will be replaced with the value of the second position (10b = 2d)
const SWAP_IQ_PD: i32 = 0b10110001;

impl Simd<f32> for f32x8 {
    type Array = [f32; 8];

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

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

	const LEN: usize = 8;

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

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

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

    #[inline]
    fn add_complex(self, value: Complex<f32>) -> f32x8 {
        let increment = f32x8::from_complex(value);
        self + increment
    }

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

    #[inline]
    fn scale_complex(self, value: Complex<f32>) -> f32x8 {
        let scaling_real = f32x8::splat(value.re);
        let scaling_imag = f32x8::splat(value.im);
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_ps(self, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_ps(parallel, cross) }
    }

    #[inline]
    fn mul_complex(self, value: f32x8) -> f32x8 {
        let scaling_real = f32x8::new(value.extract(0),
                                      value.extract(0),
                                      value.extract(2),
                                      value.extract(2),
                                      value.extract(4),
                                      value.extract(4),
                                      value.extract(6),
                                      value.extract(6));
        let scaling_imag = f32x8::new(value.extract(1),
                                      value.extract(1),
                                      value.extract(3),
                                      value.extract(3),
                                      value.extract(5),
                                      value.extract(5),
                                      value.extract(7),
                                      value.extract(7));
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_ps(self, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_ps(parallel, cross) }
    }

    #[inline]
    fn div_complex(self, value: f32x8) -> f32x8 {
        let scaling_imag = f32x8::new(self.extract(0),
                                      self.extract(0),
                                      self.extract(2),
                                      self.extract(2),
                                      self.extract(4),
                                      self.extract(4),
                                      self.extract(6),
                                      self.extract(6));
        let scaling_real = f32x8::new(self.extract(1),
                                      self.extract(1),
                                      self.extract(3),
                                      self.extract(3),
                                      self.extract(5),
                                      self.extract(5),
                                      self.extract(7),
                                      self.extract(7));
        let parallel = scaling_real * value;
        let shuffled = unsafe { _mm256_permute_ps(value, SWAP_IQ_PS) };
        let cross = scaling_imag * shuffled;
        let mul = unsafe { _mm256_addsub_ps(parallel, cross) };
        let square = shuffled * shuffled;
        let square_shuffled = unsafe { _mm256_permute_ps(square, SWAP_IQ_PS) };
        let sum = square + square_shuffled;
        let div = mul / sum;
        unsafe { _mm256_permute_ps(div, SWAP_IQ_PS) }
    }

    #[inline]
    fn complex_abs_squared(self) -> f32x8 {
        let squared = self * self;
        unsafe { _mm256_hadd_ps(squared, squared) }
    }

    #[inline]
    fn complex_abs(self) -> f32x8 {
        let squared_sum = self.complex_abs_squared();
        unsafe { _mm256_sqrt_ps(squared_sum) }
    }

    #[inline]
    fn complex_abs_squared2(self) -> f32x8 {
        self.complex_abs_squared()
    }

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

    #[inline]
    fn sqrt(self) -> f32x8 {
        unsafe { _mm256_sqrt_ps(self) }
    }

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

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

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

    #[inline]
    fn max(self, other: Self) -> Self {
        unsafe { _mm256_max_ps(self, other) }
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        unsafe { _mm256_min_ps(self, other) }
    }
}

impl Simd<f64> for f64x4 {
    type Array = [f64; 4];

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

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

	const LEN: usize = 4;

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

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

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

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

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

    #[inline]
    fn scale_complex(self, value: Complex<f64>) -> f64x4 {
        let scaling_real = f64x4::splat(value.re);
        let scaling_imag = f64x4::splat(value.im);
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_pd(self, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_pd(parallel, cross) }
    }

    #[inline]
    fn mul_complex(self, value: f64x4) -> f64x4 {
        let scaling_real = f64x4::new(value.extract(0),
                                      value.extract(0),
                                      value.extract(2),
                                      value.extract(2));
        let scaling_imag = f64x4::new(value.extract(1),
                                      value.extract(1),
                                      value.extract(3),
                                      value.extract(3));
        let parallel = scaling_real * self;
        let shuffled = unsafe { _mm256_permute_pd(self, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        unsafe { _mm256_addsub_pd(parallel, cross) }
    }

    #[inline]
    fn div_complex(self, value: f64x4) -> f64x4 {
        let scaling_imag = f64x4::new(self.extract(0),
                                      self.extract(0),
                                      self.extract(2),
                                      self.extract(2));
        let scaling_real = f64x4::new(self.extract(1),
                                      self.extract(1),
                                      self.extract(3),
                                      self.extract(3));
        let parallel = scaling_real * value;
        let shuffled = unsafe { _mm256_permute_pd(value, SWAP_IQ_PD) };
        let cross = scaling_imag * shuffled;
        let mul = unsafe { _mm256_addsub_pd(parallel, cross) };
        let square = shuffled * shuffled;
        let square_shuffled = unsafe { _mm256_permute_pd(square, SWAP_IQ_PD) };
        let sum = square + square_shuffled;
        let div = mul / sum;
        unsafe { _mm256_permute_pd(div, SWAP_IQ_PD) }
    }

    #[inline]
    fn complex_abs_squared(self) -> f64x4 {
        let squared = self * self;
        unsafe { _mm256_hadd_pd(squared, squared) }
    }

    #[inline]
    fn complex_abs(self) -> f64x4 {
        let squared_sum = self.complex_abs_squared();
        unsafe { _mm256_sqrt_pd(squared_sum) }
    }

    #[inline]
    fn complex_abs_squared2(self) -> f64x4 {
        self.complex_abs_squared()
    }

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

    #[inline]
    fn sqrt(self) -> f64x4 {
        unsafe { _mm256_sqrt_pd(self) }
    }

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

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

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

    #[inline]
    fn max(self, other: Self) -> Self {
        unsafe { _mm256_max_pd(self, other) }
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        unsafe { _mm256_min_pd(self, other) }
    }
}

impl SimdFrom<f32x8> for i32x8 {
    fn regfrom(value: f32x8) -> Self {
        value.as_i32x8()
    }
}

impl SimdFrom<i32x8> for f32x8 {
    fn regfrom(value: i32x8) -> Self {
        value.as_f32x8()
    }
}

impl SimdFrom<f64x4> for i64x4 {
    fn regfrom(value: f64x4) -> Self {
        value.as_i64x4()
    }
}

impl SimdFrom<i64x4> for f64x4 {
    fn regfrom(value: i64x4) -> Self {
        value.as_f64x4()
    }
}

#[cfg(test)]
#[target_feature(enable = "+avx")]
mod tests {
    use super::*;

    #[test]
    fn shuffle_test() {
        let vec = f32x8::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
        let result = unsafe { _mm256_permute_ps(vec, SWAP_IQ_PS) };
        let expected =
            f32x8::new(vec.extract(1),
                 vec.extract(0),
                 vec.extract(3),
                 vec.extract(2),
                 vec.extract(5),
                 vec.extract(4),
                 vec.extract(7),
                 vec.extract(6));
        assert_eq!(result, expected);
    }
}<|endoftext|>


<commit_before>use errors::*;

use rsa::Rsa;

use bignum::BigNumTrait;
use bignum::OpensslBigNum as BigNum;

pub fn run() -> Result<(), Error> {
    let bits = 512;
    let rsa = Rsa::<BigNum>::generate(bits);

    let m = BigNumTrait::gen_random(bits - 1);
    let c = rsa.encrypt(&m);

    let oracle = |x: &BigNum| -> Option<BigNum> {
        if *x == c {
            return None;
        }
        Some(rsa.decrypt(x))
    };

    let s = BigNum::gen_random(bits - 1);
    //TODO We should check that s > 1 and that s and rsa.n() have no common divisors
    let t = s
        .invmod(rsa.n())
        .ok_or_else(|| err_msg("s and n are not coprime"))?;

    let c2 = &(&c * &rsa.encrypt(&s)) % rsa.n();
    let m2 = oracle(&c2).ok_or_else(|| err_msg("wrong input to oracle"))?;
    compare_eq(m, &(&m2 * &t) % rsa.n())
}
<commit_msg>Use struct instead of closure<commit_after>use errors::*;

use rsa::Rsa;

use bignum::BigNumTrait;
use bignum::OpensslBigNum as BigNum;

const BITS:usize = 512;

struct Server {
    rsa: Rsa<BigNum>,
    cleartext: BigNum,
    ciphertext: BigNum,
}

impl Server {
    fn new() -> Self {
        let rsa = Rsa::<BigNum>::generate(BITS);
        let cleartext = BigNumTrait::gen_random(BITS - 1);
        let ciphertext = rsa.encrypt(&cleartext);
        Server { rsa, cleartext, ciphertext }
    }

    fn n(&self) -> &BigNum {
        &self.rsa.n()
    }

    fn get_ciphertext(&self) -> &BigNum {
        &self.ciphertext
    }

    fn encrypt(&self, cleartext: &BigNum) -> BigNum {
        self.rsa.encrypt(cleartext)
    }

    fn decrypt(&self, ciphertext: &BigNum) -> Option<BigNum> {
        // Reject ciphertext itself
        if ciphertext == &self.ciphertext {
            return None;
        }
        Some(self.rsa.decrypt(ciphertext))
    }

    fn verify_solution(&self, candidate: &BigNum) -> Result<(), Error> {
        compare_eq(&self.cleartext, candidate)
    }
}

pub fn run() -> Result<(), Error> {
    let server = Server::new();
    let ciphertext = server.get_ciphertext();

    let n = server.n();
    let s = &BigNum::from_u32(2);
    let t = &s.invmod(n).unwrap(); // unwrap is ok

    let altered_ciphertext = &(ciphertext * &server.encrypt(s)) % n;
    let altered_cleartext = server
        .decrypt(&altered_ciphertext)
        .ok_or_else(|| err_msg("wrong input to oracle"))?;

    let cleartext = &(&altered_cleartext * t) % n;
    server.verify_solution(&cleartext)
}
<|endoftext|>