<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! PS/2 keyboard driver
use arch::cpu::Port;
use spin::Mutex;

use core::default::Default;

/// PS/2 keyboard scancode
#[derive(Copy,Clone,Debug)]
pub struct Scancode(u8);

impl Scancode {
    fn to_ascii(&self) -> Option<u8> {
        match self.0 {
            0x01 ... 0x1c => Some(TO_ASCII_LOW[self.0 as usize - 0x01])
          , 0x1e ... 0x28 => Some(TO_ASCII_MID[self.0 as usize - 0x1e])
          , 0x2c ... 0x35 => Some(TO_ASCII_HIGH[self.0 as usize - 0x2c])
          , 0x39 => Some(b' ')
          , _ => None
        }
    }
}

/// A PS/2 keyboard state
pub struct Keyboard { /// Port for reading data from the keyboard
                      data_port: Port
                    // , /// Port for sending control signals to the keyboard
                    //   control_port: Port
                    , /// The keyboard's modifier keys
                      pub state: Modifiers
                    }

impl Keyboard {
    #[inline] pub fn read_scancode(&self) -> Scancode {
        unsafe { Scancode(self.data_port.in8()) }
    }
}

/// Scancodes range 0x01 ... 0x1c
const TO_ASCII_LOW: &'static [u8; 31]
    = b"\x1B1234567890-=\0x02\tqwertyuiop[]\r";

/// Scancodes range 0x1E ... 0x28
const TO_ASCII_MID: &'static [u8; 11] = b"asdfghjkl;'";

/// Scancodes range 0x2C ... 0x35
const TO_ASCII_HIGH: &'static [u8; 10] = b"zxcvbnm,./";

impl Keyboard {

}

bitflags! {
    pub flags Modifiers: u8 { const L_SHIFT  = 0b1000_0000
                            , const R_SHIFT  = 0b0100_0000
                            , const SHIFT    = L_SHIFT.bits | R_SHIFT.bits
                            , const R_CTRL   = 0b0010_0000
                            , const L_CTRL   = 0b0001_0000
                            , const CTRL     = L_CTRL.bits | R_CTRL.bits
                            , const R_ALT    = 0b0000_1000
                            , const L_ALT    = 0b0000_0100
                            , const ALT      = L_ALT.bits | R_ALT.bits
                            , const CAPSLOCK = 0b0000_0010
                            , const NUMLOCK  = 0b0000_0001
                            }
}

impl Default for Modifiers {
    #[inline] fn default() -> Self { Modifiers::new() }
}

impl Modifiers {

    pub const fn new() -> Self {
        Modifiers { bits: 0b0000_0000 }
    }

    /// Returns true if either shift key is pressed.
    #[inline] pub fn is_shifted(&self) -> bool {
        self.contains(SHIFT)
    }

    /// Returns true if the keyboard's state is currently uppercase.
    #[inline] pub fn is_uppercase(&self) -> bool {
        self.is_shifted() ^ self.contains(CAPSLOCK)
    }

    /// Updates the modifiers state from a given scancode.
    fn update(&mut self, scancode: Scancode) {
        match scancode { Scancode(0x1D) => self.insert(L_CTRL)
                       , Scancode(0x2A) => self.insert(L_SHIFT)
                       , Scancode(0x36) => self.insert(R_SHIFT)
                       , Scancode(0x38) => self.insert(L_ALT)
                         // Caps lock toggles on leading edge
                       , Scancode(0x3A) => self.toggle(CAPSLOCK)
                       , Scancode(0x9D) => self.remove(L_CTRL)
                       , Scancode(0xAA) => self.remove(L_SHIFT)
                       , Scancode(0xB6) => self.remove(R_SHIFT)
                       , Scancode(0xB8) => self.remove(L_ALT)
                       , _    => {}
        }
    }

    /// Apply the keyboard's modifiers to an ASCII scancode.
    fn modify(&self, ascii: u8) -> u8 {
        match ascii {
            b'a' ... b'z' if self.is_uppercase() => ascii - b'a' + b'A'
          , b'1' ... b'9' if self.is_shifted()   => ascii - b'1' + b'!'
          , b'0' if self.is_shifted()            => b')'
          , _ => ascii
        }
    }
}

/// Our global keyboard state, protected by a mutex.
static KEYBOARD: Mutex<Keyboard> = Mutex::new(Keyboard {
    data_port: unsafe { Port::new(0x60) }
  , state: Modifiers::new()
});

pub fn read_char() -> Option<char> {
    let mut lock = KEYBOARD.lock();

    let code = lock.read_scancode();
    lock.state.update(code);

    code.to_ascii()
        .map(|ascii| lock.state.modify(ascii) as char)
}
<commit_msg>[kernel] fix keyboard driver translating scancodes incorrectly Closes #4. Turns out I am dumb and can't count.<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! PS/2 keyboard driver
use arch::cpu::Port;
use spin::Mutex;

use core::default::Default;

/// PS/2 keyboard scancode
#[derive(Copy,Clone,Debug)]
pub struct Scancode(u8);

impl Scancode {
    fn to_ascii(&self) -> Option<u8> {
        match self.0 {
            0x01 ... 0x0e => Some(TO_ASCII_LOW[self.0 as usize - 0x01])
          , 0x0f ... 0x1c => Some(TO_ASCII_MID1[self.0 as usize - 0x0f])
          , 0x1e ... 0x28 => Some(TO_ASCII_MID2[self.0 as usize - 0x1e])
          , 0x2c ... 0x35 => Some(TO_ASCII_HIGH[self.0 as usize - 0x2c])
          , 0x39 => Some(b' ')
          , _ => None
        }
    }
}

/// A PS/2 keyboard state
pub struct Keyboard { /// Port for reading data from the keyboard
                      data_port: Port
                    // , /// Port for sending control signals to the keyboard
                    //   control_port: Port
                    , /// The keyboard's modifier keys
                      pub state: Modifiers
                    }

impl Keyboard {
    #[inline] pub fn read_scancode(&self) -> Scancode {
        unsafe { Scancode(self.data_port.in8()) }
    }
}

/// Scancodes range 0x01 ... 0x1c
const TO_ASCII_LOW: &'static [u8; 17]
    = b"\x1B1234567890-=\0x02";

const TO_ASCII_MID1: &'static [u8; 14] = b"\tqwertyuiop[]\r";

/// Scancodes range 0x1E ... 0x28
const TO_ASCII_MID2: &'static [u8; 11] = b"asdfghjkl;'";

/// Scancodes range 0x2C ... 0x35
const TO_ASCII_HIGH: &'static [u8; 10] = b"zxcvbnm,./";

bitflags! {
    pub flags Modifiers: u8 { const L_SHIFT  = 0b1000_0000
                            , const R_SHIFT  = 0b0100_0000
                            , const SHIFT    = L_SHIFT.bits | R_SHIFT.bits
                            , const R_CTRL   = 0b0010_0000
                            , const L_CTRL   = 0b0001_0000
                            , const CTRL     = L_CTRL.bits | R_CTRL.bits
                            , const R_ALT    = 0b0000_1000
                            , const L_ALT    = 0b0000_0100
                            , const ALT      = L_ALT.bits | R_ALT.bits
                            , const CAPSLOCK = 0b0000_0010
                            , const NUMLOCK  = 0b0000_0001
                            }
}

impl Default for Modifiers {
    #[inline] fn default() -> Self { Modifiers::new() }
}

impl Modifiers {

    pub const fn new() -> Self {
        Modifiers { bits: 0b0000_0000 }
    }

    /// Returns true if either shift key is pressed.
    #[inline] pub fn is_shifted(&self) -> bool {
        self.contains(SHIFT)
    }

    /// Returns true if the keyboard's state is currently uppercase.
    #[inline] pub fn is_uppercase(&self) -> bool {
        self.is_shifted() ^ self.contains(CAPSLOCK)
    }

    /// Updates the modifiers state from a given scancode.
    fn update(&mut self, scancode: Scancode) {
        match scancode { Scancode(0x1D) => self.insert(L_CTRL)
                       , Scancode(0x2A) => self.insert(L_SHIFT)
                       , Scancode(0x36) => self.insert(R_SHIFT)
                       , Scancode(0x38) => self.insert(L_ALT)
                         // Caps lock toggles on leading edge
                       , Scancode(0x3A) => self.toggle(CAPSLOCK)
                       , Scancode(0x9D) => self.remove(L_CTRL)
                       , Scancode(0xAA) => self.remove(L_SHIFT)
                       , Scancode(0xB6) => self.remove(R_SHIFT)
                       , Scancode(0xB8) => self.remove(L_ALT)
                       , _    => {}
        }
    }

    /// Apply the keyboard's modifiers to an ASCII scancode.
    fn modify(&self, ascii: u8) -> u8 {
        match ascii {
            b'a' ... b'z' if self.is_uppercase() => ascii - b'a' + b'A'
          , b'1' ... b'9' if self.is_shifted()   => ascii - b'1' + b'!'
          , b'0' if self.is_shifted()            => b')'
          , _ => ascii
        }
    }
}

/// Our global keyboard state, protected by a mutex.
//  TODO: can this be thread local?
static KEYBOARD: Mutex<Keyboard> = Mutex::new(Keyboard {
    data_port: unsafe { Port::new(0x60) }
  , state: Modifiers::new()
});

pub fn read_char() -> Option<char> {
    let mut lock = KEYBOARD.lock();

    let code = lock.read_scancode();
    lock.state.update(code);

    code.to_ascii()
        .map(|ascii| lock.state.modify(ascii) as char)
}
<|endoftext|>


<commit_before>pub const VGA_BUFFER: *mut u8 = 0xb8000 as *mut u8;
<commit_msg>vga: add Color, ColorCode<commit_after>pub const VGA_BUFFER: *mut u8 = 0xb8000 as *mut u8;

#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Color {
    Black = 0,
    Blue = 1,
    Green = 2,
    Cyan = 3,
    Red = 4,
    Magenta = 5,
    Brown = 6,
    LightGray = 7,
    DarkGray = 8,
    LightBlue = 9,
    LightGreen = 10,
    LightCyan = 11,
    LightRed = 12,
    Pink = 13,
    Yellow = 14,
    White = 15,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
struct ColorCode(u8);

impl ColorCode {
    fn new(foreground: Color, background: Color) -> ColorCode {
        ColorCode((background as u8) << 4 | (foreground as u8))
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::convert::TryFrom;
use seckey::Key;
use rand::{ Rng, OsRng, ChaChaRng };
use newhope::{
    N, POLY_BYTES, SENDABYTES, SENDBBYTES,
    poly_frombytes, poly_tobytes,
    rec_frombytes, rec_tobytes,
    keygen, sharedb, shareda,
    sha3_256
};
use super::KeyExchange;

/// Newhope key exchange.
///
/// # Example(exchange)
/// ```
/// use sarkara::kex::{ KeyExchange, NewHope };
///
/// let (mut keya, mut keyb) = ([0; 32], [0; 32]);
/// let (sk, pk) = NewHope::keygen();
/// let rec = NewHope::exchange(&mut keyb, &pk);
/// NewHope::exchange_from(&mut keya, &sk, &rec);
///
/// assert_eq!(keya, keyb);
/// ```
///
/// # Example(import/export)
/// ```
/// # #![feature(try_from)]
/// # use std::convert::TryFrom;
/// # use sarkara::kex::{ KeyExchange, PrivateKey, NewHope };
/// # let (mut keya, mut keyb) = ([0; 32], [0; 32]);
/// # let (sk, pk) = NewHope::keygen();
/// let sk_bytes: Vec<u8> = sk.into();
/// let sk = PrivateKey::try_from(&sk_bytes[..]).unwrap();
/// # let rec = NewHope::exchange(&mut keyb, &pk);
/// # NewHope::exchange_from(&mut keya, &sk, &rec);
/// # assert_eq!(keya, keyb);
/// ```
pub struct NewHope;

impl KeyExchange for NewHope {
    type PrivateKey = PrivateKey;
    type PublicKey = PublicKey;
    type Reconciliation = Reconciliation;

    #[inline] fn sk_length() -> usize { POLY_BYTES }
    #[inline] fn pk_length() -> usize { SENDABYTES }
    #[inline] fn rec_length() -> usize { SENDBBYTES }

    fn keygen() -> (Self::PrivateKey, Self::PublicKey) {
        let (mut sk, mut pk) = ([0; N], [0; SENDABYTES]);
        let (mut pka, mut nonce) = ([0; N], [0; 32]);
        let mut rng = OsRng::new().unwrap().gen::<ChaChaRng>();

        rng.fill_bytes(&mut nonce);
        keygen(&mut sk, &mut pka, &nonce, rng);

        pk[..POLY_BYTES].clone_from_slice(&poly_tobytes(&pka));
        pk[POLY_BYTES..].clone_from_slice(&nonce);

        (PrivateKey(sk.into()), PublicKey(pk))
    }

    fn exchange(sharedkey: &mut [u8], &PublicKey(ref pka): &Self::PublicKey) -> Self::Reconciliation {
        let (mut key, mut pkb, mut rec) = ([0; 32], [0; N], [0; N]);
        let (pk, nonce) = pka.split_at(POLY_BYTES);

        sharedb(
            &mut key, &mut pkb, &mut rec,
            &poly_frombytes(pk), nonce, OsRng::new().unwrap().gen::<ChaChaRng>()
        );

        sha3_256(sharedkey, &key);

        let mut output = [0; SENDBBYTES];
        output[..POLY_BYTES].clone_from_slice(&poly_tobytes(&pkb));
        output[POLY_BYTES..].clone_from_slice(&rec_tobytes(&rec));
        Reconciliation(output)
    }

    fn exchange_from(
        sharedkey: &mut [u8],
        &PrivateKey(Key(ref sk)): &Self::PrivateKey,
        &Reconciliation(ref pkb): &Self::Reconciliation
    ) {
        let mut key = [0; 32];
        let (pk, rec) = pkb.split_at(POLY_BYTES);
        shareda(&mut key, &sk[..], &poly_frombytes(pk), &rec_frombytes(rec));

        sha3_256(sharedkey, &key);
    }
}

new_type!(
    /// Newhope private key.
    pub struct PrivateKey(pub Key<[u16; N]>);
    from: (input) {
        if input.len() == POLY_BYTES {
            Ok(PrivateKey(poly_frombytes(input).into()))
        } else {
            err!(InvalidInput, "PrivateKey: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let PrivateKey(Key(ref input)) = input;
        Vec::from(&poly_tobytes(input)[..])
    }
);

new_type!(
    /// Newhope public key.
    pub struct PublicKey(pub [u8; SENDABYTES]);
    from: (input) {
        if input.len() == SENDABYTES {
            let mut pk = [0; SENDABYTES];
            pk.clone_from_slice(input);
            Ok(PublicKey(pk))
        } else {
            err!(InvalidInput, "PublicKey: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let PublicKey(ref input) = input;
        Vec::from(&input[..])
    }
);

new_type!(
    /// Newhope reconciliation data.
    pub struct Reconciliation(pub [u8; SENDBBYTES]);
    from: (input) {
        if input.len() == SENDBBYTES {
            let mut rec = [0; SENDBBYTES];
            rec.clone_from_slice(input);
            Ok(Reconciliation(rec))
        } else {
            err!(InvalidInput, "Reconciliation: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let Reconciliation(ref input) = input;
        Vec::from(&input[..])
    }
);
<commit_msg>fix(newhope): protect key<commit_after>use std::io;
use std::convert::TryFrom;
use seckey::Key;
use rand::{ Rng, OsRng, ChaChaRng };
use newhope::{
    N, POLY_BYTES, SENDABYTES, SENDBBYTES,
    poly_frombytes, poly_tobytes,
    rec_frombytes, rec_tobytes,
    keygen, sharedb, shareda,
    sha3_256
};
use super::KeyExchange;

/// Newhope key exchange.
///
/// # Example(exchange)
/// ```
/// use sarkara::kex::{ KeyExchange, NewHope };
///
/// let (mut keya, mut keyb) = ([0; 32], [0; 32]);
/// let (sk, pk) = NewHope::keygen();
/// let rec = NewHope::exchange(&mut keyb, &pk);
/// NewHope::exchange_from(&mut keya, &sk, &rec);
///
/// assert_eq!(keya, keyb);
/// ```
///
/// # Example(import/export)
/// ```
/// # #![feature(try_from)]
/// # use std::convert::TryFrom;
/// # use sarkara::kex::{ KeyExchange, PrivateKey, NewHope };
/// # let (mut keya, mut keyb) = ([0; 32], [0; 32]);
/// # let (sk, pk) = NewHope::keygen();
/// let sk_bytes: Vec<u8> = sk.into();
/// let sk = PrivateKey::try_from(&sk_bytes[..]).unwrap();
/// # let rec = NewHope::exchange(&mut keyb, &pk);
/// # NewHope::exchange_from(&mut keya, &sk, &rec);
/// # assert_eq!(keya, keyb);
/// ```
pub struct NewHope;

impl KeyExchange for NewHope {
    type PrivateKey = PrivateKey;
    type PublicKey = PublicKey;
    type Reconciliation = Reconciliation;

    #[inline] fn sk_length() -> usize { POLY_BYTES }
    #[inline] fn pk_length() -> usize { SENDABYTES }
    #[inline] fn rec_length() -> usize { SENDBBYTES }

    fn keygen() -> (Self::PrivateKey, Self::PublicKey) {
        let (mut sk, mut pk) = ([0; N].into(), [0; SENDABYTES]);

        {
            let Key(ref mut sk) = sk;
            let (mut pka, mut nonce) = ([0; N], [0; 32]);
            let mut rng = OsRng::new().unwrap().gen::<ChaChaRng>();

            rng.fill_bytes(&mut nonce);
            keygen(sk, &mut pka, &nonce, rng);

            pk[..POLY_BYTES].clone_from_slice(&poly_tobytes(&pka));
            pk[POLY_BYTES..].clone_from_slice(&nonce);
        }

        (PrivateKey(sk), PublicKey(pk))
    }

    fn exchange(sharedkey: &mut [u8], &PublicKey(ref pka): &Self::PublicKey) -> Self::Reconciliation {
        let (Key(mut key), mut pkb, mut rec) = ([0; 32].into(), [0; N], [0; N]);
        let (pk, nonce) = pka.split_at(POLY_BYTES);

        sharedb(
            &mut key, &mut pkb, &mut rec,
            &poly_frombytes(pk), nonce, OsRng::new().unwrap().gen::<ChaChaRng>()
        );

        sha3_256(sharedkey, &key);

        let mut output = [0; SENDBBYTES];
        output[..POLY_BYTES].clone_from_slice(&poly_tobytes(&pkb));
        output[POLY_BYTES..].clone_from_slice(&rec_tobytes(&rec));
        Reconciliation(output)
    }

    fn exchange_from(
        sharedkey: &mut [u8],
        &PrivateKey(Key(ref sk)): &Self::PrivateKey,
        &Reconciliation(ref pk): &Self::Reconciliation
    ) {
        let Key(mut key) = [0; 32].into();
        let (pkb, rec) = pk.split_at(POLY_BYTES);
        shareda(&mut key, sk, &poly_frombytes(pkb), &rec_frombytes(rec));

        sha3_256(sharedkey, &key);
    }
}

new_type!(
    /// Newhope private key.
    pub struct PrivateKey(pub Key<[u16; N]>);
    from: (input) {
        if input.len() == POLY_BYTES {
            Ok(PrivateKey(poly_frombytes(input).into()))
        } else {
            err!(InvalidInput, "PrivateKey: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let PrivateKey(Key(ref input)) = input;
        Vec::from(&poly_tobytes(input)[..])
    }
);

new_type!(
    /// Newhope public key.
    pub struct PublicKey(pub [u8; SENDABYTES]);
    from: (input) {
        if input.len() == SENDABYTES {
            let mut pk = [0; SENDABYTES];
            pk.clone_from_slice(input);
            Ok(PublicKey(pk))
        } else {
            err!(InvalidInput, "PublicKey: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let PublicKey(ref input) = input;
        Vec::from(&input[..])
    }
);

new_type!(
    /// Newhope reconciliation data.
    pub struct Reconciliation(pub [u8; SENDBBYTES]);
    from: (input) {
        if input.len() == SENDBBYTES {
            let mut rec = [0; SENDBBYTES];
            rec.clone_from_slice(input);
            Ok(Reconciliation(rec))
        } else {
            err!(InvalidInput, "Reconciliation: invalid input length.")
        }
    },
    into: (input) -> Vec<u8> {
        let Reconciliation(ref input) = input;
        Vec::from(&input[..])
    }
);
<|endoftext|>


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

//! Traits for dynamic typing of any `'static` type (through runtime reflection)
//!
//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `as_ref` methods, to test if the contained value is of a given type, and to
//! get a reference to the inner value as a type. As`&mut Any`, there is also
//! the `as_mut` method, for getting a mutable reference to the inner value.
//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
//! object.  See the extension traits (`*Ext`) for the full details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Show, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Show;
//! use std::any::{Any, AnyRefExt};
//!
//! // Logger function for any type that implements Show.
//! fn log<T: Any+Show>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Show+'static>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable]

use mem::{transmute, transmute_copy};
use option::{Option, Some, None};
use raw::TraitObject;
use intrinsics::TypeId;

/// A type with no inhabitants
#[deprecated = "this type is being removed, define a type locally if \
                necessary"]
pub enum Void { }

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// The `Any` trait is implemented by all `'static` types, and can be used for
/// dynamic typing
///
/// Every type with no non-`'static` references implements `Any`, so `Any` can
/// be used as a trait object to emulate the effects dynamic typing.
#[stable]
pub trait Any: AnyPrivate {}

/// An inner trait to ensure that only this module can call `get_type_id()`.
pub trait AnyPrivate {
    /// Get the `TypeId` of `self`
    fn get_type_id(&self) -> TypeId;
}

impl<T: 'static> AnyPrivate for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

impl<T: 'static + AnyPrivate> Any for T {}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
// Implemented as three extension traits so that the methods can be generic.
///////////////////////////////////////////////////////////////////////////////

/// Extension methods for a referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
              part of `impl Any`"]
pub trait AnyRefExt<'a> {
    /// Returns true if the boxed type is the same as `T`
    #[stable]
    fn is<T: 'static>(self) -> bool;

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_ref<T: 'static>(self) -> Option<&'a T>;

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[deprecated = "this function has been renamed to `downcast_ref`"]
    fn as_ref<T: 'static>(self) -> Option<&'a T> {
        self.downcast_ref::<T>()
    }
}

#[stable]
impl<'a> AnyRefExt<'a> for &'a Any+'a {
    #[inline]
    #[stable]
    fn is<T: 'static>(self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    #[inline]
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

/// Extension methods for a mutable referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
              part of `impl Any`"]
pub trait AnyMutRefExt<'a> {
    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T>;

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[deprecated = "this function has been renamed to `downcast_mut`"]
    fn as_mut<T: 'static>(self) -> Option<&'a mut T> {
        self.downcast_mut::<T>()
    }
}

#[stable]
impl<'a> AnyMutRefExt<'a> for &'a mut Any+'a {
    #[inline]
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}
<commit_msg>auto merge of #17132 : reem/rust/any-static-bound, r=alexcrichton<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Traits for dynamic typing of any `'static` type (through runtime reflection)
//!
//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `as_ref` methods, to test if the contained value is of a given type, and to
//! get a reference to the inner value as a type. As`&mut Any`, there is also
//! the `as_mut` method, for getting a mutable reference to the inner value.
//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
//! object.  See the extension traits (`*Ext`) for the full details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Show, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Show;
//! use std::any::{Any, AnyRefExt};
//!
//! // Logger function for any type that implements Show.
//! fn log<T: Any+Show>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Show+'static>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable]

use mem::{transmute, transmute_copy};
use option::{Option, Some, None};
use raw::TraitObject;
use intrinsics::TypeId;

/// A type with no inhabitants
#[deprecated = "this type is being removed, define a type locally if \
                necessary"]
pub enum Void { }

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// The `Any` trait is implemented by all `'static` types, and can be used for
/// dynamic typing
///
/// Every type with no non-`'static` references implements `Any`, so `Any` can
/// be used as a trait object to emulate the effects dynamic typing.
#[stable]
pub trait Any: AnyPrivate + 'static {}

/// An inner trait to ensure that only this module can call `get_type_id()`.
pub trait AnyPrivate {
    /// Get the `TypeId` of `self`
    fn get_type_id(&self) -> TypeId;
}

impl<T: 'static> AnyPrivate for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

impl<T: 'static + AnyPrivate> Any for T {}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
// Implemented as three extension traits so that the methods can be generic.
///////////////////////////////////////////////////////////////////////////////

/// Extension methods for a referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
              part of `impl Any`"]
pub trait AnyRefExt<'a> {
    /// Returns true if the boxed type is the same as `T`
    #[stable]
    fn is<T: 'static>(self) -> bool;

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_ref<T: 'static>(self) -> Option<&'a T>;

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[deprecated = "this function has been renamed to `downcast_ref`"]
    fn as_ref<T: 'static>(self) -> Option<&'a T> {
        self.downcast_ref::<T>()
    }
}

#[stable]
impl<'a> AnyRefExt<'a> for &'a Any {
    #[inline]
    #[stable]
    fn is<T: 'static>(self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    #[inline]
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

/// Extension methods for a mutable referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
              part of `impl Any`"]
pub trait AnyMutRefExt<'a> {
    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T>;

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[deprecated = "this function has been renamed to `downcast_mut`"]
    fn as_mut<T: 'static>(self) -> Option<&'a mut T> {
        self.downcast_mut::<T>()
    }
}

#[stable]
impl<'a> AnyMutRefExt<'a> for &'a mut Any {
    #[inline]
    #[unstable = "naming conventions around acquiring references may change"]
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}
<|endoftext|>


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

fn most_frequent(counts: &HashMap<char, i32>) -> char
{
    let (mut c, mut freq) = (' ', 0);
    for (cc, cfreq) in counts {
        if *cfreq > freq {
            freq = *cfreq;
            c = *cc;
        }
    }
    return c;
}

fn least_frequent(counts: &HashMap<char, i32>) -> char
{
    let (mut c, mut freq) = (' ', i32::max_value());
    for (cc, cfreq) in counts {
        if *cfreq < freq {
            freq = *cfreq;
            c = *cc;
        }
    }
    return c;
}

fn main() {
    println!("Hello, world!");

    let args: Vec<String> = env::args().collect();
    let f = File::open(&args[1]).expect("Could not open file");
    let reader = BufReader::new(f);

    let mut counts: Vec<HashMap<char, i32>> = Vec::new();

    for line in reader.lines() {
        for (i, c) in line.unwrap().trim().chars().enumerate() {
            let pos = i as usize;
            if pos >= counts.len() {
                counts.push(HashMap::new());
            }

            if ! counts[pos].contains_key(&c) {
                counts[pos].insert(c, 1);
            } else {
                let cur = counts[pos][&c];
                counts[pos].insert(c, cur + 1);
            }
        }
    }

    let decoded: String = counts.iter().map(|counts| most_frequent(counts)).collect();
    let least_decoded: String = counts.iter().map(|counts| least_frequent(counts)).collect();
    println!("Final (most frequent) word: {}", decoded);
    println!("Final (least frequent) word: {}", least_decoded);
}
<commit_msg>Clean up day 06.<commit_after>use std::env;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::collections::HashMap;

fn most_frequent(counts: &HashMap<char, i32>) -> char
{
    let (mut c, mut freq) = (' ', 0);
    for (cc, cfreq) in counts {
        if *cfreq > freq {
            freq = *cfreq;
            c = *cc;
        }
    }
    return c;
}

fn least_frequent(counts: &HashMap<char, i32>) -> char
{
    let (mut c, mut freq) = (' ', i32::max_value());
    for (cc, cfreq) in counts {
        if *cfreq < freq {
            freq = *cfreq;
            c = *cc;
        }
    }
    return c;
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let f = File::open(&args[1]).expect("Could not open file");
    let reader = BufReader::new(f);

    let mut counts: Vec<HashMap<char, i32>> = Vec::new();

    for line in reader.lines() {
        for (i, c) in line.unwrap().trim().chars().enumerate() {
            if i >= counts.len() {
                counts.push(HashMap::new());
            }

            let cur = counts[i].entry(c).or_insert(0);
            *cur += 1;
        }
    }

    let decoded: String = counts.iter().map(|counts| most_frequent(counts)).collect();
    let least_decoded: String = counts.iter().map(|counts| least_frequent(counts)).collect();
    println!("Final (most frequent) word: {}", decoded);
    println!("Final (least frequent) word: {}", least_decoded);
}
<|endoftext|>


<commit_before>use super::RawOutcome;
use crate::core::{FilterList, LowercaseText};
use crate::utils::is_stop_char;
use crate::{Lang, Script};

use once_cell::sync::Lazy;
use std::collections::HashMap;

const AFR: &str = "abcdefghijklmnopqrstuvwxyzáèéêëíîïóôúû";
const AKA: &str = "abdefghiklmnoprstuwyɔɛ";
const AZE: &str = "abcdefghijklmnopqrstuvxyzçöüğışə̇";
const CAT: &str = "abcdefghijklmnopqrstuvwxyz·àçèéíïòóúü";
const CES: &str = "abcdefghijklmnopqrstuvwxyzáéóúýčďěňřšťůž";
const DAN: &str = "abcdefghijklmnopqrstuvwxyzåæø";
const DEU: &str = "abcdefghijklmnopqrstuvwxyzßäöü";
const ENG: &str = "abcdefghijklmnopqrstuvwxyz";
const EPO: &str = "abcdefghijklmnoprstuvzĉĝĥĵŝŭ";
const EST: &str = "abcdefghijklmnopqrstuvwxyzäõöü";
const FIN: &str = "abcdefghijklmnopqrstuvwxyzäöšž";
const FRA: &str = "abcdefghijklmnopqrstuvwxyzàâçèéêëîïôùûüÿœ";
const HRV: &str = "abcdefghijklmnopqrstuvwxyzćčđšž";
const HUN: &str = "abcdefghijklmnopqrstuvwxyzáéíóöúüőű";
const IND: &str = "abcdefghijklmnopqrstuvwxyz";
const ITA: &str = "abcdefghijklmnopqrstuvwxyzàèéìòù";
const JAV: &str = "abcdefghijklmnopqrstuvwxyzèé";
const LAT: &str = "abcdefghijklmnopqrstuvwxyz";
const LAV: &str = "abcdefghijklmnopqrstuvwxyzāčēģīķļņōŗšūž";
const LIT: &str = "abcdefghijklmnopqrstuvwxyząčėęįšūųž";
const NLD: &str = "abcdefghijklmnopqrstuvwxyzàèéëïĳ";
const NOB: &str = "abcdefghijklmnopqrstuvwxyzåæø";
const POL: &str = "abcdefghijklmnopqrstuvwxyzóąćęłńśźż";
const POR: &str = "abcdefghijklmnopqrstuvwxyzàáâãçéêíóôõú";
const RON: &str = "abcdefghijklmnopqrstuvwxyzâîăşţ";
const SLK: &str = "abcdefghijklmnopqrstuvwxyzáäéíóôúýčďĺľňŕšťž";
const SLV: &str = "abcdefghijklmnopqrstuvwxyzčšž";
const SNA: &str = "abcdefghijklmnopqrstuvwxyz";
const SPA: &str = "abcdefghijklmnopqrstuvwxyz¡¿áéíñóúü";
const SWE: &str = "abcdefghijklmnopqrstuvwxyzäåö";
const TGL: &str = "abcdefghijklmnopqrstuvwxyzáéíñóú";
const TUK: &str = "abdefghijklmnoprstuwyzäçöüýňşž";
const TUR: &str = "abcdefghijklmnopqrstuvwxyzçöüğış̇";
const UZB: &str = "abcdefghijklmnopqrstuvxyzʻ";
const VIE: &str =
    "abcdefghijklmnopqrstuvwxyzàáâãèéêìíòóôõùúýăđĩũơưạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ";
const ZUL: &str = "abcdefghijklmnopqrstuvwxyz";

const LATIN_ALPHABETS: &[(Lang, &str)] = &[
    (Lang::Afr, AFR),
    (Lang::Aka, AKA),
    (Lang::Aze, AZE),
    (Lang::Cat, CAT),
    (Lang::Ces, CES),
    (Lang::Dan, DAN),
    (Lang::Deu, DEU),
    (Lang::Eng, ENG),
    (Lang::Epo, EPO),
    (Lang::Est, EST),
    (Lang::Fin, FIN),
    (Lang::Fra, FRA),
    (Lang::Hrv, HRV),
    (Lang::Hun, HUN),
    (Lang::Ind, IND),
    (Lang::Ita, ITA),
    (Lang::Jav, JAV),
    (Lang::Lat, LAT),
    (Lang::Lav, LAV),
    (Lang::Lit, LIT),
    (Lang::Nld, NLD),
    (Lang::Nob, NOB),
    (Lang::Pol, POL),
    (Lang::Por, POR),
    (Lang::Ron, RON),
    (Lang::Slk, SLK),
    (Lang::Slv, SLV),
    (Lang::Sna, SNA),
    (Lang::Spa, SPA),
    (Lang::Swe, SWE),
    (Lang::Tgl, TGL),
    (Lang::Tuk, TUK),
    (Lang::Tur, TUR),
    (Lang::Uzb, UZB),
    (Lang::Vie, VIE),
    (Lang::Zul, ZUL),
];

/// Inverted map binding a character to a set of languages.
pub static ALPHABET_LANG_MAP: Lazy<Vec<(char, Vec<Lang>)>> = Lazy::new(|| {
    let mut map = HashMap::new();

    for (lang, alphabet) in LATIN_ALPHABETS {
        for c in alphabet.chars() {
            let entry = map.entry(c).or_insert_with(Vec::new);
            entry.push(*lang);
        }
    }

    let mut char_lang = Vec::new();

    for (ch, languages) in map {
        char_lang.push((ch, languages));
    }

    char_lang.sort_unstable_by_key(|(c, _)| *c);
    char_lang
});

pub fn alphabet_calculate_scores(text: &LowercaseText, filter_list: &FilterList) -> RawOutcome {
    let char_lang = &*ALPHABET_LANG_MAP;
    let max_raw_score = text.chars().filter(|&ch| !is_stop_char(ch)).count();

    let mut raw_scores: Vec<(Lang, usize)> = Script::Latin
        .langs()
        .iter()
        .filter(|&&l| filter_list.is_allowed(l))
        .map(|&l| (l, 0))
        .collect();

    let mut common_score = 0;
    for ch in text.chars() {
        if is_stop_char(ch) {
            continue;
        }

        if let Ok(position) = char_lang.binary_search_by_key(&ch, |(c, _)| *c) {
            let (_, languages) = &char_lang[position];
            // if this char is common to all Languages, add 2 to a common counter
            // instead of iterating over all Languages counters.
            if languages.len() == LATIN_ALPHABETS.len() {
                common_score += 2;
            } else {
                for lang in languages {
                    if let Some((_, score)) = raw_scores.iter_mut().find(|(l, _)| l == lang) {
                        *score += 2;
                    }
                }
            }
        }
    }

    raw_scores.sort_unstable_by(|a, b| b.1.cmp(&a.1));

    let mut normalized_scores = vec![];

    for (lang, raw_score) in raw_scores.iter_mut() {
        *raw_score = (*raw_score + common_score).saturating_sub(max_raw_score);
        let normalized_score = *raw_score as f64 / max_raw_score as f64;
        normalized_scores.push((*lang, normalized_score));
    }

    RawOutcome {
        count: max_raw_score,
        raw_scores,
        scores: normalized_scores,
    }
}
<commit_msg>Use intermediate char score<commit_after>use super::RawOutcome;
use crate::core::{FilterList, LowercaseText};
use crate::utils::is_stop_char;
use crate::{Lang, Script};

use once_cell::sync::Lazy;
use std::collections::HashMap;

const AFR: &str = "abcdefghijklmnopqrstuvwxyzáèéêëíîïóôúû";
const AKA: &str = "abdefghiklmnoprstuwyɔɛ";
const AZE: &str = "abcdefghijklmnopqrstuvxyzçöüğışə̇";
const CAT: &str = "abcdefghijklmnopqrstuvwxyz·àçèéíïòóúü";
const CES: &str = "abcdefghijklmnopqrstuvwxyzáéóúýčďěňřšťůž";
const DAN: &str = "abcdefghijklmnopqrstuvwxyzåæø";
const DEU: &str = "abcdefghijklmnopqrstuvwxyzßäöü";
const ENG: &str = "abcdefghijklmnopqrstuvwxyz";
const EPO: &str = "abcdefghijklmnoprstuvzĉĝĥĵŝŭ";
const EST: &str = "abcdefghijklmnopqrstuvwxyzäõöü";
const FIN: &str = "abcdefghijklmnopqrstuvwxyzäöšž";
const FRA: &str = "abcdefghijklmnopqrstuvwxyzàâçèéêëîïôùûüÿœ";
const HRV: &str = "abcdefghijklmnopqrstuvwxyzćčđšž";
const HUN: &str = "abcdefghijklmnopqrstuvwxyzáéíóöúüőű";
const IND: &str = "abcdefghijklmnopqrstuvwxyz";
const ITA: &str = "abcdefghijklmnopqrstuvwxyzàèéìòù";
const JAV: &str = "abcdefghijklmnopqrstuvwxyzèé";
const LAT: &str = "abcdefghijklmnopqrstuvwxyz";
const LAV: &str = "abcdefghijklmnopqrstuvwxyzāčēģīķļņōŗšūž";
const LIT: &str = "abcdefghijklmnopqrstuvwxyząčėęįšūųž";
const NLD: &str = "abcdefghijklmnopqrstuvwxyzàèéëïĳ";
const NOB: &str = "abcdefghijklmnopqrstuvwxyzåæø";
const POL: &str = "abcdefghijklmnopqrstuvwxyzóąćęłńśźż";
const POR: &str = "abcdefghijklmnopqrstuvwxyzàáâãçéêíóôõú";
const RON: &str = "abcdefghijklmnopqrstuvwxyzâîăşţ";
const SLK: &str = "abcdefghijklmnopqrstuvwxyzáäéíóôúýčďĺľňŕšťž";
const SLV: &str = "abcdefghijklmnopqrstuvwxyzčšž";
const SNA: &str = "abcdefghijklmnopqrstuvwxyz";
const SPA: &str = "abcdefghijklmnopqrstuvwxyz¡¿áéíñóúü";
const SWE: &str = "abcdefghijklmnopqrstuvwxyzäåö";
const TGL: &str = "abcdefghijklmnopqrstuvwxyzáéíñóú";
const TUK: &str = "abdefghijklmnoprstuwyzäçöüýňşž";
const TUR: &str = "abcdefghijklmnopqrstuvwxyzçöüğış̇";
const UZB: &str = "abcdefghijklmnopqrstuvxyzʻ";
const VIE: &str =
    "abcdefghijklmnopqrstuvwxyzàáâãèéêìíòóôõùúýăđĩũơưạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ";
const ZUL: &str = "abcdefghijklmnopqrstuvwxyz";

const LATIN_ALPHABETS: &[(Lang, &str)] = &[
    (Lang::Afr, AFR),
    (Lang::Aka, AKA),
    (Lang::Aze, AZE),
    (Lang::Cat, CAT),
    (Lang::Ces, CES),
    (Lang::Dan, DAN),
    (Lang::Deu, DEU),
    (Lang::Eng, ENG),
    (Lang::Epo, EPO),
    (Lang::Est, EST),
    (Lang::Fin, FIN),
    (Lang::Fra, FRA),
    (Lang::Hrv, HRV),
    (Lang::Hun, HUN),
    (Lang::Ind, IND),
    (Lang::Ita, ITA),
    (Lang::Jav, JAV),
    (Lang::Lat, LAT),
    (Lang::Lav, LAV),
    (Lang::Lit, LIT),
    (Lang::Nld, NLD),
    (Lang::Nob, NOB),
    (Lang::Pol, POL),
    (Lang::Por, POR),
    (Lang::Ron, RON),
    (Lang::Slk, SLK),
    (Lang::Slv, SLV),
    (Lang::Sna, SNA),
    (Lang::Spa, SPA),
    (Lang::Swe, SWE),
    (Lang::Tgl, TGL),
    (Lang::Tuk, TUK),
    (Lang::Tur, TUR),
    (Lang::Uzb, UZB),
    (Lang::Vie, VIE),
    (Lang::Zul, ZUL),
];

/// Inverted map binding a character to a set of languages.
pub static ALPHABET_LANG_MAP: Lazy<(Vec<char>, Vec<Vec<Lang>>)> = Lazy::new(|| {
    let mut map = HashMap::new();

    for (lang, alphabet) in LATIN_ALPHABETS {
        for c in alphabet.chars() {
            let entry = map.entry(c).or_insert_with(Vec::new);
            entry.push(*lang);
        }
    }

    let mut char_lang: Vec<_> = map.into_iter().collect();

    char_lang.sort_unstable_by_key(|(c, _)| *c);

    let mut chars = Vec::with_capacity(char_lang.len());
    let mut langs = Vec::with_capacity(char_lang.len());
    for (ch, languages) in char_lang {
        chars.push(ch);
        langs.push(languages);
    }

    (chars, langs)
});

pub fn alphabet_calculate_scores(text: &LowercaseText, filter_list: &FilterList) -> RawOutcome {
    let (chars, langs) = &*ALPHABET_LANG_MAP;
    let max_raw_score = text.chars().filter(|&ch| !is_stop_char(ch)).count();

    // score of each character.
    let mut scores: Vec<_> = chars.iter().map(|_| 0).collect();
    for ch in text.chars() {
        if is_stop_char(ch) {
            continue;
        }

        if let Ok(position) = chars.binary_search(&ch) {
            scores[position] += 2;
        }
    }

    let mut raw_scores: Vec<(Lang, usize)> = Script::Latin
        .langs()
        .iter()
        .filter(|&&l| filter_list.is_allowed(l))
        .map(|&l| (l, 0))
        .collect();

    let mut common_score = 0;
    for (position, char_score) in scores.into_iter().enumerate() {
        if char_score > 0 {
            let languages = &langs[position];
            // if current character is common to all Languages, increment a common score
            // instead of iterating over all Languages scores.
            if languages.len() == LATIN_ALPHABETS.len() {
                common_score += char_score;
            } else {
                for lang in languages {
                    if let Some((_, score)) = raw_scores.iter_mut().find(|(l, _)| l == lang) {
                        *score += char_score;
                    }
                }
            }
        }
    }

    raw_scores.sort_unstable_by(|a, b| b.1.cmp(&a.1));

    let mut normalized_scores = vec![];

    for (lang, raw_score) in raw_scores.iter_mut() {
        *raw_score = (*raw_score + common_score).saturating_sub(max_raw_score);
        let normalized_score = *raw_score as f64 / max_raw_score as f64;
        normalized_scores.push((*lang, normalized_score));
    }

    RawOutcome {
        count: max_raw_score,
        raw_scores,
        scores: normalized_scores,
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use std::rc::Rc;
use consumer::*;
use producer::*;
use stream::*;

pub struct Subscription<I> {
    producer: Option<Rc<Producer>>,
    marker: PhantomData<I>,
}

impl<I> Consumer for Subscription<I> {
    type Item = I;

    fn init(&mut self, producer: Rc<Producer>) {
        self.producer = Some(producer);
    }

    fn emit(&mut self, _: Self::Item) {}

    fn end(self) {}
}

pub trait  SubscribableStream : Stream {
    fn subscribe(self)
        where Self: Sized
    {
        self.consume(Subscription {
            producer: None,
            marker: PhantomData::<Self::Item>,
        });
    }
}

impl<S> SubscribableStream for S where S: Stream
{}
<commit_msg>add close to subscription<commit_after>use std::marker::PhantomData;
use std::mem;
use std::option::*;
use std::rc::Rc;
use consumer::*;
use producer::*;
use stream::*;

/// Represents a subscription to a `Stream`
pub struct Subscription<I> {
    producer: Option<Rc<Producer>>,
    marker: PhantomData<I>,
}

impl<I> Subscription<I> {
    /// Closes the `Subscription<I>`
    pub fn close(mut self) {
        if let Some(p) = mem::replace(&mut self.producer, None) {
            p.close();
        }
    }
}

impl<I> Consumer for Subscription<I> {
    type Item = I;

    fn init(&mut self, producer: Rc<Producer>) {
        self.producer = Some(producer);
    }

    fn emit(&mut self, _: Self::Item) {}

    fn end(self) {}
}

pub trait  SubscribableStream : Stream {
    fn subscribe(self)
        where Self: Sized
    {
        self.consume(Subscription {
            producer: None,
            marker: PhantomData::<Self::Item>,
        });
    }
}

impl<S> SubscribableStream for S where S: Stream
{}
<|endoftext|>


<commit_before>//! Interface for the `signalfd` syscall.
//!
//! # Signal discarding
//! When a signal can't be delivered to a process (or thread), it will become a pending signal.
//! Failure to deliver could happen if the signal is blocked by every thread in the process or if
//! the signal handler is still handling a previous signal.
//!
//! If a signal is sent to a process (or thread) that already has a pending signal of the same
//! type, it will be discarded. This means that if signals of the same type are received faster than
//! they are processed, some of those signals will be dropped. Because of this limitation,
//! `signalfd` in itself cannot be used for reliable communication between processes or threads.
//!
//! Once the signal is unblocked, or the signal handler is finished, and a signal is still pending
//! (ie. not consumed from a signalfd) it will be delivered to the signal handler.
//!
//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
//! signal handlers.
use libc;
use crate::unistd;
use crate::{Error, Result};
use crate::errno::Errno;
pub use crate::sys::signal::{self, SigSet};
pub use libc::signalfd_siginfo as siginfo;

use std::os::unix::io::{RawFd, AsRawFd};
use std::mem;

libc_bitflags!{
    pub struct SfdFlags: libc::c_int {
        SFD_NONBLOCK;
        SFD_CLOEXEC;
    }
}

pub const SIGNALFD_NEW: RawFd = -1;
pub const SIGNALFD_SIGINFO_SIZE: usize = 128;

/// Creates a new file descriptor for reading signals.
///
/// **Important:** please read the module level documentation about signal discarding before using
/// this function!
///
/// The `mask` parameter specifies the set of signals that can be accepted via this file descriptor.
///
/// A signal must be blocked on every thread in a process, otherwise it won't be visible from
/// signalfd (the default handler will be invoked instead).
///
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
    unsafe {
        Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits()))
    }
}

/// A helper struct for creating, reading and closing a `signalfd` instance.
///
/// **Important:** please read the module level documentation about signal discarding before using
/// this struct!
///
/// # Examples
///
/// ```
/// # use nix::sys::signalfd::*;
/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used
/// let mut mask = SigSet::empty();
/// mask.add(signal::SIGUSR1);
/// mask.thread_block().unwrap();
///
/// // Signals are queued up on the file descriptor
/// let mut sfd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
///
/// match sfd.read_signal() {
///     // we caught a signal
///     Ok(Some(sig)) => (),
///     // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set,
///     // otherwise the read_signal call blocks)
///     Ok(None) => (),
///     Err(err) => (), // some error happend
/// }
/// ```
#[derive(Debug, Eq, Hash, PartialEq)]
pub struct SignalFd(RawFd);

impl SignalFd {
    pub fn new(mask: &SigSet) -> Result<SignalFd> {
        Self::with_flags(mask, SfdFlags::empty())
    }

    pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
        let fd = signalfd(SIGNALFD_NEW, mask, flags)?;

        Ok(SignalFd(fd))
    }

    pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
        signalfd(self.0, mask, SfdFlags::empty()).map(drop)
    }

    pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
        let mut buffer = mem::MaybeUninit::<[u8; SIGNALFD_SIGINFO_SIZE]>::uninit();

        let res = Errno::result(unsafe {
            libc::read(self.0,
                       buffer.as_mut_ptr() as *mut libc::c_void,
                       SIGNALFD_SIGINFO_SIZE as libc::size_t)
        }).map(|r| r as usize);
        match res {
            Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer.assume_init()) })),
            Ok(_) => unreachable!("partial read on signalfd"),
            Err(Errno::EAGAIN) => Ok(None),
            Err(error) => Err(error)
        }
    }
}

impl Drop for SignalFd {
    fn drop(&mut self) {
        let e = unistd::close(self.0);
        if !std::thread::panicking() && e == Err(Error::from(Errno::EBADF)) {
            panic!("Closing an invalid file descriptor!");
        };
    }
}

impl AsRawFd for SignalFd {
    fn as_raw_fd(&self) -> RawFd {
        self.0
    }
}

impl Iterator for SignalFd {
    type Item = siginfo;

    fn next(&mut self) -> Option<Self::Item> {
        match self.read_signal() {
            Ok(Some(sig)) => Some(sig),
            Ok(None) | Err(_) => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::mem;
    use libc;

    #[test]
    fn check_siginfo_size() {
        assert_eq!(mem::size_of::<libc::signalfd_siginfo>(), SIGNALFD_SIGINFO_SIZE);
    }

    #[test]
    fn create_signalfd() {
        let mask = SigSet::empty();
        let fd = SignalFd::new(&mask);
        assert!(fd.is_ok());
    }

    #[test]
    fn create_signalfd_with_opts() {
        let mask = SigSet::empty();
        let fd = SignalFd::with_flags(&mask, SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK);
        assert!(fd.is_ok());
    }

    #[test]
    fn read_empty_signalfd() {
        let mask = SigSet::empty();
        let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();

        let res = fd.read_signal();
        assert!(res.unwrap().is_none());
    }
}
<commit_msg>Simplify definition of SIGNALFD_SIGINFO_SIZE<commit_after>//! Interface for the `signalfd` syscall.
//!
//! # Signal discarding
//! When a signal can't be delivered to a process (or thread), it will become a pending signal.
//! Failure to deliver could happen if the signal is blocked by every thread in the process or if
//! the signal handler is still handling a previous signal.
//!
//! If a signal is sent to a process (or thread) that already has a pending signal of the same
//! type, it will be discarded. This means that if signals of the same type are received faster than
//! they are processed, some of those signals will be dropped. Because of this limitation,
//! `signalfd` in itself cannot be used for reliable communication between processes or threads.
//!
//! Once the signal is unblocked, or the signal handler is finished, and a signal is still pending
//! (ie. not consumed from a signalfd) it will be delivered to the signal handler.
//!
//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
//! signal handlers.
use libc;
use crate::unistd;
use crate::{Error, Result};
use crate::errno::Errno;
pub use crate::sys::signal::{self, SigSet};
pub use libc::signalfd_siginfo as siginfo;

use std::os::unix::io::{RawFd, AsRawFd};
use std::mem;

libc_bitflags!{
    pub struct SfdFlags: libc::c_int {
        SFD_NONBLOCK;
        SFD_CLOEXEC;
    }
}

pub const SIGNALFD_NEW: RawFd = -1;
pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<libc::signalfd_siginfo>();

/// Creates a new file descriptor for reading signals.
///
/// **Important:** please read the module level documentation about signal discarding before using
/// this function!
///
/// The `mask` parameter specifies the set of signals that can be accepted via this file descriptor.
///
/// A signal must be blocked on every thread in a process, otherwise it won't be visible from
/// signalfd (the default handler will be invoked instead).
///
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
    unsafe {
        Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits()))
    }
}

/// A helper struct for creating, reading and closing a `signalfd` instance.
///
/// **Important:** please read the module level documentation about signal discarding before using
/// this struct!
///
/// # Examples
///
/// ```
/// # use nix::sys::signalfd::*;
/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used
/// let mut mask = SigSet::empty();
/// mask.add(signal::SIGUSR1);
/// mask.thread_block().unwrap();
///
/// // Signals are queued up on the file descriptor
/// let mut sfd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
///
/// match sfd.read_signal() {
///     // we caught a signal
///     Ok(Some(sig)) => (),
///     // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set,
///     // otherwise the read_signal call blocks)
///     Ok(None) => (),
///     Err(err) => (), // some error happend
/// }
/// ```
#[derive(Debug, Eq, Hash, PartialEq)]
pub struct SignalFd(RawFd);

impl SignalFd {
    pub fn new(mask: &SigSet) -> Result<SignalFd> {
        Self::with_flags(mask, SfdFlags::empty())
    }

    pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
        let fd = signalfd(SIGNALFD_NEW, mask, flags)?;

        Ok(SignalFd(fd))
    }

    pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
        signalfd(self.0, mask, SfdFlags::empty()).map(drop)
    }

    pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
        let mut buffer = mem::MaybeUninit::<[u8; SIGNALFD_SIGINFO_SIZE]>::uninit();

        let res = Errno::result(unsafe {
            libc::read(self.0,
                       buffer.as_mut_ptr() as *mut libc::c_void,
                       SIGNALFD_SIGINFO_SIZE as libc::size_t)
        }).map(|r| r as usize);
        match res {
            Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer.assume_init()) })),
            Ok(_) => unreachable!("partial read on signalfd"),
            Err(Errno::EAGAIN) => Ok(None),
            Err(error) => Err(error)
        }
    }
}

impl Drop for SignalFd {
    fn drop(&mut self) {
        let e = unistd::close(self.0);
        if !std::thread::panicking() && e == Err(Error::from(Errno::EBADF)) {
            panic!("Closing an invalid file descriptor!");
        };
    }
}

impl AsRawFd for SignalFd {
    fn as_raw_fd(&self) -> RawFd {
        self.0
    }
}

impl Iterator for SignalFd {
    type Item = siginfo;

    fn next(&mut self) -> Option<Self::Item> {
        match self.read_signal() {
            Ok(Some(sig)) => Some(sig),
            Ok(None) | Err(_) => None,
        }
    }
}

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

    #[test]
    fn create_signalfd() {
        let mask = SigSet::empty();
        let fd = SignalFd::new(&mask);
        assert!(fd.is_ok());
    }

    #[test]
    fn create_signalfd_with_opts() {
        let mask = SigSet::empty();
        let fd = SignalFd::with_flags(&mask, SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK);
        assert!(fd.is_ok());
    }

    #[test]
    fn read_empty_signalfd() {
        let mask = SigSet::empty();
        let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();

        let res = fd.read_signal();
        assert!(res.unwrap().is_none());
    }
}
<|endoftext|>


<commit_before>use super::command::{Command, Query};
use super::command::Command::TableRemove;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TableRemoveCommand {
    command: Command,
    name: String,
    arguments: HashMap<String, String>,
}

impl Default for TableRemoveCommand {
    fn default() -> TableRemoveCommand {
        TableRemoveCommand {
            command: TableRemove,
            name: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl TableRemoveCommand {
    pub fn new(name: String) -> TableRemoveCommand {
        let default: TableRemoveCommand = Default::default();
        TableRemoveCommand {
            command: default.command,
            name: name,
            arguments: default.arguments,
        }
    }

    pub fn dependent(mut self, dependent: bool) -> TableRemoveCommand {
        let flag = match dependent {
            true => "yes",
            false => "no",
        };
        self.arguments.insert("dependent".to_string(), flag.to_string());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("name".to_string(), self.name)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (TableRemove, query)
    }
}

impl Queryable for TableRemoveCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for TableRemoveCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(TableRemoveCommand);
request_cancellable!(TableRemoveCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::TableRemove;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let table_rename = TableRemoveCommand::new("Table".to_string());
        let expected = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, table_rename);
    }

    #[test]
    fn test_dependent_plugins() {
        let dependent_yes = TableRemoveCommand::new("Table".to_string()).dependent(true);
        let mut arg_yes: HashMap<String, String> = HashMap::new();
        arg_yes.insert("dependent".to_string(), "yes".to_string());
        let expected_yes = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg_yes,
        };
        assert_eq!(expected_yes, dependent_yes);
        let dependent_no = TableRemoveCommand::new("Table".to_string()).dependent(false);
        let mut arg_no: HashMap<String, String> = HashMap::new();
        arg_no.insert("dependent".to_string(), "no".to_string());
        let expected_no = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg_no,
        };
        assert_eq!(expected_no, dependent_no);
    }

    #[test]
    fn test_build() {
        let actual = TableRemoveCommand::new("Table".to_string()).build();
        let expected_query: Query = vec![("name".to_string(), "Table".to_string())];
        let expected = (TableRemove, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = TableRemoveCommand::new("Table".to_string()).to_query();
        let url_encoded = "/d/table_remove?name=Table";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = TableRemoveCommand::new("Table".to_string()).to_command();
        let url_encoded = "table_remove --name Table";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg.clone(),
        };
        let query = TableRemoveCommand::new("Table".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<commit_msg>table_remove: Fix an inappropriate test case name<commit_after>use super::command::{Command, Query};
use super::command::Command::TableRemove;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TableRemoveCommand {
    command: Command,
    name: String,
    arguments: HashMap<String, String>,
}

impl Default for TableRemoveCommand {
    fn default() -> TableRemoveCommand {
        TableRemoveCommand {
            command: TableRemove,
            name: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl TableRemoveCommand {
    pub fn new(name: String) -> TableRemoveCommand {
        let default: TableRemoveCommand = Default::default();
        TableRemoveCommand {
            command: default.command,
            name: name,
            arguments: default.arguments,
        }
    }

    pub fn dependent(mut self, dependent: bool) -> TableRemoveCommand {
        let flag = match dependent {
            true => "yes",
            false => "no",
        };
        self.arguments.insert("dependent".to_string(), flag.to_string());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("name".to_string(), self.name)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (TableRemove, query)
    }
}

impl Queryable for TableRemoveCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for TableRemoveCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(TableRemoveCommand);
request_cancellable!(TableRemoveCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::TableRemove;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let table_rename = TableRemoveCommand::new("Table".to_string());
        let expected = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, table_rename);
    }

    #[test]
    fn test_dependent() {
        let dependent_yes = TableRemoveCommand::new("Table".to_string()).dependent(true);
        let mut arg_yes: HashMap<String, String> = HashMap::new();
        arg_yes.insert("dependent".to_string(), "yes".to_string());
        let expected_yes = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg_yes,
        };
        assert_eq!(expected_yes, dependent_yes);
        let dependent_no = TableRemoveCommand::new("Table".to_string()).dependent(false);
        let mut arg_no: HashMap<String, String> = HashMap::new();
        arg_no.insert("dependent".to_string(), "no".to_string());
        let expected_no = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg_no,
        };
        assert_eq!(expected_no, dependent_no);
    }

    #[test]
    fn test_build() {
        let actual = TableRemoveCommand::new("Table".to_string()).build();
        let expected_query: Query = vec![("name".to_string(), "Table".to_string())];
        let expected = (TableRemove, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = TableRemoveCommand::new("Table".to_string()).to_query();
        let url_encoded = "/d/table_remove?name=Table";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = TableRemoveCommand::new("Table".to_string()).to_command();
        let url_encoded = "table_remove --name Table";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = TableRemoveCommand {
            command: TableRemove,
            name: "Table".to_string(),
            arguments: arg.clone(),
        };
        let query = TableRemoveCommand::new("Table".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<|endoftext|>


<commit_before>#![cfg(target_os="android")]
#![cfg(feature = "oculusvr")]

use {VRDisplay, VRDisplayData, VRDisplayCapabilities,
    VREvent, VRDisplayEvent, VREyeParameters, VRFrameData, VRLayer};
use ovr_mobile_sys as ovr;
use ovr_mobile_sys::ovrSystemProperty::*;
use std::sync::Arc;
use std::cell::RefCell;
use super::service::OculusVRService;
use super::super::utils;

pub type OculusVRDisplayPtr = Arc<RefCell<OculusVRDisplay>>;

pub struct OculusVRDisplay {
    display_id: u32,
    ovr_java: *const ovr::ovrJava,
}

unsafe impl Send for OculusVRDisplay {}
unsafe impl Sync for OculusVRDisplay {}

impl VRDisplay for OculusVRDisplay {

    fn id(&self) -> u32 {
        self.display_id
    }

    fn data(&self) -> VRDisplayData {
        let mut data = VRDisplayData::default();

        data.display_name = "Oculus VR".into();
        data.display_id = self.display_id;
        data.connected = true;

        self.fetch_capabilities(&mut data.capabilities);
        unsafe {
            self.fetch_eye_parameters(&mut data.left_eye_parameters, &mut data.right_eye_parameters);
        }
        data.stage_parameters = None;

        data
    }

    fn inmediate_frame_data(&self, near: f64, far: f64) -> VRFrameData {
        let mut data = VRFrameData::default();

        data
    }

    fn synced_frame_data(&self, near: f64, far: f64) -> VRFrameData {
        let mut data = VRFrameData::default();

        data
    }

    fn reset_pose(&mut self) {

    }

    fn sync_poses(&mut self) {

    }

    fn submit_frame(&mut self, layer: &VRLayer) {

    }
}

impl OculusVRDisplay {
    pub unsafe fn new(ovr_java: *const ovr::ovrJava) -> Arc<RefCell<OculusVRDisplay>> {
        Arc::new(RefCell::new(OculusVRDisplay {
            display_id: utils::new_id(),
            ovr_java: ovr_java,
        }))
    }

    pub fn pause(&self) {

    }

    pub fn resume(&self) {

    }

    fn fetch_capabilities(&self, capabilities: &mut VRDisplayCapabilities) {
        capabilities.can_present = true;
        capabilities.has_orientation = true;
        capabilities.has_external_display = false;
        capabilities.has_position = false;
    }

    unsafe fn fetch_eye_parameters(&self, left_eye: &mut VREyeParameters, right_eye: &mut VREyeParameters) {
        let fov_x = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X)
        };
        let fov_y = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y)
        };

        left_eye.field_of_view.left_degrees = fov_x as f64;
        left_eye.field_of_view.right_degrees = fov_x as f64;
        left_eye.field_of_view.up_degrees = fov_y as f64;
        left_eye.field_of_view.down_degrees = fov_y as f64;

        right_eye.field_of_view.left_degrees = fov_x as f64;
        right_eye.field_of_view.right_degrees = fov_x as f64;
        right_eye.field_of_view.up_degrees = fov_y as f64;
        right_eye.field_of_view.down_degrees = fov_y as f64;

        let render_size = self.recommended_render_size();

        left_eye.render_width = render_size.0;
        left_eye.render_height = render_size.1;
        right_eye.render_width = render_size.0;
        right_eye.render_height = render_size.1;
    }

    fn recommended_render_size(&self) -> (u32, u32) {
        let w = unsafe {
            ovr::vrapi_GetSystemPropertyInt(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH)
        };
        let h = unsafe {
            ovr::vrapi_GetSystemPropertyInt(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT)
        };

        (w as u32, h as u32)
    }

    unsafe fn fetch_frame_data(&self,
                               out: &mut VRFrameData,
                               near: f32,
                               far: f32) {
        let fov_x = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X)
        };
        let fov_y = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y)
        };
        let projection = ovr::helpers::ovrMatrix4f_CreateProjectionFov(fov_x, fov_y, 0.0, 0.0, near, far);
        let projection = ovr_mat4_to_array(&projection);

        out.left_projection_matrix = projection;
        out.right_projection_matrix = projection;

        // Timestamp
        out.timestamp = utils::timestamp();
    }
}

#[inline]
fn ovr_mat4_to_array(matrix: &ovr::ovrMatrix4f) -> [f32; 16] {
    [matrix.M[0][0], matrix.M[1][0], matrix.M[2][0], matrix.M[3][0],
     matrix.M[0][1], matrix.M[1][1], matrix.M[2][1], matrix.M[3][1],
     matrix.M[0][2], matrix.M[1][2], matrix.M[2][2], matrix.M[3][2],
     matrix.M[0][3], matrix.M[1][3], matrix.M[2][3], matrix.M[3][3]]
}
<commit_msg>Implement enter/exit VRMode and fetch VRFrameData<commit_after>#![cfg(target_os="android")]
#![cfg(feature = "oculusvr")]

use {VRDisplay, VRDisplayData, VRDisplayCapabilities,
    VREvent, VRDisplayEvent, VREyeParameters, VRFrameData, VRLayer};
use android_injected_glue;
use ovr_mobile_sys as ovr;
use ovr_mobile_sys::ovrSystemProperty::*;
use std::sync::Arc;
use std::cell::RefCell;
use std::ptr;
use super::service::OculusVRService;
use super::super::utils;

pub type OculusVRDisplayPtr = Arc<RefCell<OculusVRDisplay>>;

extern {
    fn eglGetCurrentContext() -> *mut ::std::os::raw::c_void;
    fn eglGetCurrentDisplay() -> *mut ::std::os::raw::c_void;
}

pub struct OculusVRDisplay {
    display_id: u32,
    ovr: *mut ovr::ovrMobile,
    ovr_java: *const ovr::ovrJava,
    resumed: bool,
    frame_index: i64,
}

unsafe impl Send for OculusVRDisplay {}
unsafe impl Sync for OculusVRDisplay {}

impl VRDisplay for OculusVRDisplay {

    fn id(&self) -> u32 {
        self.display_id
    }

    fn data(&self) -> VRDisplayData {
        let mut data = VRDisplayData::default();

        data.display_name = "Oculus VR".into();
        data.display_id = self.display_id;
        data.connected = true;

        self.fetch_capabilities(&mut data.capabilities);
        unsafe {
            self.fetch_eye_parameters(&mut data.left_eye_parameters, &mut data.right_eye_parameters);
        }
        data.stage_parameters = None;

        data
    }

    fn inmediate_frame_data(&self, near: f64, far: f64) -> VRFrameData {
        let mut data = VRFrameData::default();

        if self.is_in_vr_mode() {
			let tracking = unsafe { ovr::vrapi_GetPredictedTracking(self.ovr, 0.0) };
            self.fetch_frame_data(&tracking, &mut data, near as f32, far as f32);
        }

        data
    }

    fn synced_frame_data(&self, near: f64, far: f64) -> VRFrameData {
        let mut data = VRFrameData::default();

        if self.is_in_vr_mode() {
            let prediction = unsafe { ovr::vrapi_GetPredictedDisplayTime(self.ovr, self.frame_index) };
			let tracking = unsafe { ovr::vrapi_GetPredictedTracking(self.ovr, prediction) };
            self.fetch_frame_data(&tracking, &mut data, near as f32, far as f32);
        }

        data
    }

    fn reset_pose(&mut self) {
        if self.is_in_vr_mode() {
            unsafe {
                ovr::vrapi_RecenterPose(self.ovr);
            }
        }
    }

    fn sync_poses(&mut self) {

    }

    fn submit_frame(&mut self, layer: &VRLayer) {

    }

    fn start_present(&mut self) {
        if !self.ovr.is_null() {
            return;
        }

        let mut mode = ovr::helpers::vrapi_DefaultModeParms(self.ovr_java);
        mode.Flags |= ovr::ovrModeFlags::VRAPI_MODE_FLAG_NATIVE_WINDOW as u32;
        mode.WindowSurface = unsafe { android_injected_glue::get_native_window() as u64 };
        mode.Display = unsafe { eglGetCurrentDisplay() as u64 };
        mode.ShareContext = unsafe { eglGetCurrentContext() as u64 };

        self.ovr = unsafe { ovr::vrapi_EnterVrMode(&mode) };

        if self.ovr.is_null() {
            error!("Entering VR mode failed because the ANativeWindow was not valid.");
        }
    }

    fn stop_present(&mut self) {
        if !self.ovr.is_null() {
            return;
        }
        unsafe {
            ovr::vrapi_LeaveVrMode(self.ovr);
        }
        self.ovr = ptr::null_mut();
    }
}

impl OculusVRDisplay {
    pub unsafe fn new(ovr_java: *const ovr::ovrJava) -> Arc<RefCell<OculusVRDisplay>> {
        Arc::new(RefCell::new(OculusVRDisplay {
            display_id: utils::new_id(),
            ovr: ptr::null_mut(),
            ovr_java: ovr_java,
            resumed: false,
            frame_index: 0,
        }))
    }

    pub fn pause(&mut self) {
        self.resumed = false;
    }

    pub fn resume(&mut self) {
        self.resumed = true;
    }

    fn is_in_vr_mode(&self) -> bool {
        self.resumed && !self.ovr.is_null()
    }

    fn fetch_capabilities(&self, capabilities: &mut VRDisplayCapabilities) {
        capabilities.can_present = true;
        capabilities.has_orientation = true;
        capabilities.has_external_display = false;
        capabilities.has_position = false;
    }

    unsafe fn fetch_eye_parameters(&self, left_eye: &mut VREyeParameters, right_eye: &mut VREyeParameters) {
        let fov_x = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X)
        };
        let fov_y = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y)
        };

        left_eye.field_of_view.left_degrees = fov_x as f64;
        left_eye.field_of_view.right_degrees = fov_x as f64;
        left_eye.field_of_view.up_degrees = fov_y as f64;
        left_eye.field_of_view.down_degrees = fov_y as f64;

        right_eye.field_of_view.left_degrees = fov_x as f64;
        right_eye.field_of_view.right_degrees = fov_x as f64;
        right_eye.field_of_view.up_degrees = fov_y as f64;
        right_eye.field_of_view.down_degrees = fov_y as f64;

        let render_size = self.recommended_render_size();

        left_eye.render_width = render_size.0;
        left_eye.render_height = render_size.1;
        right_eye.render_width = render_size.0;
        right_eye.render_height = render_size.1;
    }

    fn recommended_render_size(&self) -> (u32, u32) {
        let w = unsafe {
            ovr::vrapi_GetSystemPropertyInt(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH)
        };
        let h = unsafe {
            ovr::vrapi_GetSystemPropertyInt(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT)
        };

        (w as u32, h as u32)
    }

    fn fetch_frame_data(&self,
                        tracking: &ovr::ovrTracking,
                        out: &mut VRFrameData,
                        near: f32,
                        far: f32) {
        let fov_x = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X)
        };
        let fov_y = unsafe {
            ovr::vrapi_GetSystemPropertyFloat(self.ovr_java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y)
        };

        // Projection Matrix
        let projection = ovr::helpers::ovrMatrix4f_CreateProjectionFov(fov_x, fov_y, 0.0, 0.0, near, far);
        let projection = ovr_mat4_to_array(&projection);

        out.left_projection_matrix = projection;
        out.right_projection_matrix = projection;

        // View Matrix
        let model_params = ovr::helpers::vrapi_DefaultHeadModelParms();
        let tracking = ovr::helpers::vrapi_ApplyHeadModel(&model_params, tracking);

        // Timestamp
        out.timestamp = utils::timestamp();
    }
}

#[inline]
fn ovr_mat4_to_array(matrix: &ovr::ovrMatrix4f) -> [f32; 16] {
    [matrix.M[0][0], matrix.M[1][0], matrix.M[2][0], matrix.M[3][0],
     matrix.M[0][1], matrix.M[1][1], matrix.M[2][1], matrix.M[3][1],
     matrix.M[0][2], matrix.M[1][2], matrix.M[2][2], matrix.M[3][2],
     matrix.M[0][3], matrix.M[1][3], matrix.M[2][3], matrix.M[3][3]]
}
<|endoftext|>


<commit_before>//! Writes wav files for every Oscillator waveform for analysis

extern crate oxcable;

#[cfg(not(test))]
fn main() {
    use std::vec::Vec;
    use oxcable::types::Device;
    use oxcable::io::wav::WavWriter;
    use oxcable::oscillator;
    use oxcable::oscillator::Oscillator;

    // Initialize objects
    println!("Initializing signal chain...");
    let freq = 8000.0;
    let mut oscs = Vec::<oscillator::Oscillator>::new();
    let mut wavs = Vec::<WavWriter>::new();
    oscs.push(Oscillator::new(oscillator::Sine, freq));
    wavs.push(WavWriter::new("wav/test_sine.wav", 1));
    oscs.push(Oscillator::new(oscillator::Saw(oscillator::Aliased), freq));
    wavs.push(WavWriter::new("wav/test_saw_naive.wav", 1));
    oscs.push(Oscillator::new(oscillator::Saw(oscillator::PolyBlep), freq));
    wavs.push(WavWriter::new("wav/test_saw_blep.wav", 1));
    oscs.push(Oscillator::new(oscillator::Square(oscillator::Aliased), freq));
    wavs.push(WavWriter::new("wav/test_square_naive.wav", 1));
    oscs.push(Oscillator::new(oscillator::Square(oscillator::PolyBlep), freq));
    wavs.push(WavWriter::new("wav/test_square_blep.wav", 1));
    oscs.push(Oscillator::new(oscillator::Tri(oscillator::Aliased), freq));
    wavs.push(WavWriter::new("wav/test_tri_naive.wav", 1));
    oscs.push(Oscillator::new(oscillator::Tri(oscillator::PolyBlep), freq));
    wavs.push(WavWriter::new("wav/test_tri_blep.wav", 1));
    oscs.push(Oscillator::new(oscillator::WhiteNoise, freq));
    wavs.push(WavWriter::new("wav/test_white_noise.wav", 1));
    oscs.push(Oscillator::new(oscillator::PulseTrain, freq));
    wavs.push(WavWriter::new("wav/test_pulse_train.wav", 1));

    // Link oscillators to wav outs
    println!("Writing oscillators to wav files...");
    for i in (0 .. oscs.len()) {
        wavs[i].inputs.set_channel(0, oscs[i].output.get_channel());
    }

    // Write files
    for t in (0u64 .. 44100) {
        for i in (0 .. oscs.len()) {
            oscs[i].tick(t);
            wavs[i].tick(t);
        }
    }
    println!("Done");
}
<commit_msg>Upgrade test oscillators to use chains<commit_after>//! Writes wav files for every Oscillator waveform for analysis

extern crate oxcable;

#[cfg(not(test))]
fn main() {
    use oxcable::chain::DeviceChain;
    use oxcable::io::wav::WavWriter;
    use oxcable::oscillator::{self, Oscillator};

    // Initialize objects
    println!("Initializing signal chain...");
    let freq = 8000.0;
    let mut chains: Vec<DeviceChain> = Vec::new();
    chains.push(DeviceChain::from(Oscillator::new(oscillator::Sine, freq))
        .into(WavWriter::new("wav/test_sine.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Saw(oscillator::Aliased), freq))
        .into(WavWriter::new("wav/test_saw_naive.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Saw(oscillator::PolyBlep), freq))
        .into(WavWriter::new("wav/test_saw_blep.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Square(oscillator::Aliased), freq))
        .into(WavWriter::new("wav/test_square_naive.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Square(oscillator::PolyBlep), freq))
        .into(WavWriter::new("wav/test_square_blep.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Tri(oscillator::Aliased), freq))
        .into(WavWriter::new("wav/test_tri_naive.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::Tri(oscillator::PolyBlep), freq))
        .into(WavWriter::new("wav/test_tri_blep.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::WhiteNoise, freq))
        .into(WavWriter::new("wav/test_white_noise.wav", 1)));
    chains.push(DeviceChain::from(
            Oscillator::new(oscillator::PulseTrain, freq))
        .into(WavWriter::new("wav/test_pulse_train.wav", 1)));

    // Write files
    println!("Writing oscillators to wav files...");
    for _ in (0u64 .. 44100) {
        for chain in chains.iter_mut() {
            chain.tick();
        }
    }
    println!("Done");
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io::Result;

pub trait SocketOpt {
    fn set_send_buffer_size(&self, _size: usize) -> Result<()>;
    fn send_buffer_size(&self) -> Result<usize>;
    fn set_recv_buffer_size(&self, _size: usize) -> Result<()>;
    fn recv_buffer_size(&self) -> Result<usize>;
}

#[cfg(unix)]
mod unix {
    use super::SocketOpt;

    use std::io::{Result, Error};
    use std::os::unix::io::AsRawFd;

    use std::net::TcpStream as MioTcpStream;
    use mio::tcp::TcpStream as StdTcpStream;
    use nix::Error as NixError;
    use nix::sys::socket;
    use nix::sys::socket::sockopt;

    impl SocketOpt for MioTcpStream {
        fn set_send_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::SndBuf, &size).map_err(from_nix_error)
        }

        fn send_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::SndBuf).map_err(from_nix_error)
        }

        fn set_recv_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::RcvBuf, &size).map_err(from_nix_error)
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::RcvBuf).map_err(from_nix_error)
        }
    }

    impl SocketOpt for StdTcpStream {
        fn set_send_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::SndBuf, &size).map_err(from_nix_error)
        }

        fn send_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::SndBuf).map_err(from_nix_error)
        }

        fn set_recv_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::RcvBuf, &size).map_err(from_nix_error)
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::RcvBuf).map_err(from_nix_error)
        }
    }

    fn from_nix_error(err: NixError) -> Error {
        Error::from_raw_os_error(err.errno() as i32)
    }
}

#[cfg(windows)]
mod windows {
    use std::net::TcpStream as MioTcpStream;
    use mio::tcp::TcpStream as StdTcpStream;
    use std::io::Result;

    impl SocketOpt for MioTcpStream {
        fn set_send_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_send_buffer_size is not supported in windows now");
            Ok(())
        }

        fn send_buffer_size(&self) -> Result<usize> {
            error!("send_buffer_size is not supported in windows now");
            Ok(0)
        }

        fn set_recv_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_recv_buffer_size is not supported in windows now");
            Ok(())
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            error!("recv_buffer_size is not supported in windows now");
            Ok(0)
        }
    }

    impl SocketOpt for StdTcpStream {
        fn set_send_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_send_buffer_size is not supported in windows now");
            Ok(())
        }

        fn send_buffer_size(&self) -> Result<usize> {
            error!("send_buffer_size is not supported in windows now");
            Ok(0)
        }

        fn set_recv_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_recv_buffer_size is not supported in windows now");
            Ok(())
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            error!("recv_buffer_size is not supported in windows now");
            Ok(0)
        }
    }
}

#[cfg(unix)]
pub use self::unix::*;

#[cfg(windows)]
pub use self::windows::*;

#[cfg(test)]
mod tests {
    use std::net::{SocketAddr, TcpListener as StdTcpListener, TcpStream as StdTcpStream};
    use mio::tcp::{TcpListener as MioTcpListener, TcpStream as MioTcpStream};

    use super::SocketOpt;

    #[cfg(unix)]
    #[test]
    fn test_mio_sock_opt() {
        let addr = "127.0.0.1:0".parse().unwrap();

        let server = MioTcpListener::bind(&addr).unwrap();
        let addr = &format!("{}", server.local_addr().unwrap());

        let sock = MioTcpStream::connect(&addr.parse().unwrap()).unwrap();

        // For linux, getsockopt will return doubled value set by setsockopt.
        // But for Mac OS X, getsockopt may return the same value. So we can only
        // check value changed.
        sock.set_send_buffer_size(4096).unwrap();
        let s1 = sock.send_buffer_size().unwrap();
        sock.set_send_buffer_size(8192).unwrap();
        let s2 = sock.send_buffer_size().unwrap();
        assert!(s2 != s1, format!("{} should not equal {}", s2, s1));

        sock.set_recv_buffer_size(4096).unwrap();
        let r1 = sock.recv_buffer_size().unwrap();
        sock.set_recv_buffer_size(8192).unwrap();
        let r2 = sock.recv_buffer_size().unwrap();
        assert!(r2 != r1, format!("{} should not equal {}", r2, r1));
    }

    #[cfg(unix)]
    #[test]
    fn test_std_sock_opt() {
        let server = StdTcpListener::bind("127.0.0.1:0").unwrap();
        let addr: SocketAddr = format!("{}", server.local_addr().unwrap()).parse().unwrap();

        let sock = StdTcpStream::connect(addr).unwrap();

        sock.set_send_buffer_size(4096).unwrap();
        let s1 = sock.send_buffer_size().unwrap();
        sock.set_send_buffer_size(8192).unwrap();
        let s2 = sock.send_buffer_size().unwrap();
        assert!(s2 != s1, format!("{} should not equal {}", s2, s1));

        sock.set_recv_buffer_size(4096).unwrap();
        let r1 = sock.recv_buffer_size().unwrap();
        sock.set_recv_buffer_size(8192).unwrap();
        let r2 = sock.recv_buffer_size().unwrap();
        assert!(r2 != r1, format!("{} should not equal {}", r2, r1));
    }
}
<commit_msg>Address comment<commit_after>// Copyright 2016 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io::Result;

pub trait SocketOpt {
    fn set_send_buffer_size(&self, _size: usize) -> Result<()>;
    fn send_buffer_size(&self) -> Result<usize>;
    fn set_recv_buffer_size(&self, _size: usize) -> Result<()>;
    fn recv_buffer_size(&self) -> Result<usize>;
}

#[cfg(unix)]
mod unix {
    use super::SocketOpt;

    use std::io::{Result, Error};
    use std::os::unix::io::AsRawFd;

    use nix::Error as NixError;
    use nix::sys::socket;
    use nix::sys::socket::sockopt;

    impl<T: AsRawFd> SocketOpt for T {
        fn set_send_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::SndBuf, &size).map_err(from_nix_error)
        }

        fn send_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::SndBuf).map_err(from_nix_error)
        }

        fn set_recv_buffer_size(&self, size: usize) -> Result<()> {
            socket::setsockopt(self.as_raw_fd(), sockopt::RcvBuf, &size).map_err(from_nix_error)
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            socket::getsockopt(self.as_raw_fd(), sockopt::RcvBuf).map_err(from_nix_error)
        }
    }

    fn from_nix_error(err: NixError) -> Error {
        Error::from_raw_os_error(err.errno() as i32)
    }
}

#[cfg(windows)]
mod windows {
    use std::io::Result;

    impl<T: AsRawFd> SocketOpt for T {
        fn set_send_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_send_buffer_size is not supported in windows now");
            Ok(())
        }

        fn send_buffer_size(&self) -> Result<usize> {
            error!("send_buffer_size is not supported in windows now");
            Ok(0)
        }

        fn set_recv_buffer_size(&self, _size: usize) -> Result<()> {
            error!("set_recv_buffer_size is not supported in windows now");
            Ok(())
        }

        fn recv_buffer_size(&self) -> Result<usize> {
            error!("recv_buffer_size is not supported in windows now");
            Ok(0)
        }
    }
}

#[cfg(unix)]
pub use self::unix::*;

#[cfg(windows)]
pub use self::windows::*;

#[cfg(test)]
mod tests {
    use std::net::{SocketAddr, TcpListener as StdTcpListener, TcpStream as StdTcpStream};
    use mio::tcp::{TcpListener as MioTcpListener, TcpStream as MioTcpStream};

    use super::SocketOpt;

    #[cfg(unix)]
    #[test]
    fn test_mio_sock_opt() {
        let addr = "127.0.0.1:0".parse().unwrap();

        let server = MioTcpListener::bind(&addr).unwrap();
        let addr = &format!("{}", server.local_addr().unwrap());

        let sock = MioTcpStream::connect(&addr.parse().unwrap()).unwrap();

        // For linux, getsockopt will return doubled value set by setsockopt.
        // But for Mac OS X, getsockopt may return the same value. So we can only
        // check value changed.
        sock.set_send_buffer_size(4096).unwrap();
        let s1 = sock.send_buffer_size().unwrap();
        sock.set_send_buffer_size(8192).unwrap();
        let s2 = sock.send_buffer_size().unwrap();
        assert!(s2 != s1, format!("{} should not equal {}", s2, s1));

        sock.set_recv_buffer_size(4096).unwrap();
        let r1 = sock.recv_buffer_size().unwrap();
        sock.set_recv_buffer_size(8192).unwrap();
        let r2 = sock.recv_buffer_size().unwrap();
        assert!(r2 != r1, format!("{} should not equal {}", r2, r1));
    }

    #[cfg(unix)]
    #[test]
    fn test_std_sock_opt() {
        let server = StdTcpListener::bind("127.0.0.1:0").unwrap();
        let addr: SocketAddr = format!("{}", server.local_addr().unwrap()).parse().unwrap();

        let sock = StdTcpStream::connect(addr).unwrap();

        sock.set_send_buffer_size(4096).unwrap();
        let s1 = sock.send_buffer_size().unwrap();
        sock.set_send_buffer_size(8192).unwrap();
        let s2 = sock.send_buffer_size().unwrap();
        assert!(s2 != s1, format!("{} should not equal {}", s2, s1));

        sock.set_recv_buffer_size(4096).unwrap();
        let r1 = sock.recv_buffer_size().unwrap();
        sock.set_recv_buffer_size(8192).unwrap();
        let r2 = sock.recv_buffer_size().unwrap();
        assert!(r2 != r1, format!("{} should not equal {}", r2, r1));
    }
}
<|endoftext|>


<commit_before>fn main() {
    let x = 9;

    if x < 4 {
        println!("Number less than 4!");
    } else if x > 10 {
        println!("Number greater than 10!");
    } else {
        println!("Number between 4 and 10!");
    }
}
<commit_msg>Example from assignment from if expression<commit_after>fn main() {
    let x = 9;

    if x < 4 {
        println!("Number less than 4!");
    } else if x > 10 {
        println!("Number greater than 10!");
    } else {
        println!("Number between 4 and 10!");
    }

    let condition = true;

    let assigned = if condition {
        5
    } else {
        6
    };
    println!("Value assigned from if expression is equal to: {}", assigned);
}
<|endoftext|>


<commit_before>use super::Hash256;

#[derive(Clone, Debug, PartialEq)]
pub struct CrosslinkRecord {
    pub slot: u64,
    pub shard_block_hash: Hash256,
}

impl CrosslinkRecord {
    /// Generates a new instance where `dynasty` and `hash` are both zero.
    pub fn zero() -> Self {
        Self {
            slot: 0,
            shard_block_hash: Hash256::zero(),
        }
    }
}
<commit_msg>Update `CrosslinkRecord` to latest spec<commit_after>use super::Hash256;

#[derive(Clone, Debug, PartialEq)]
pub struct CrosslinkRecord {
    pub slot: u64,
    pub shard_block_root: Hash256,
}

impl CrosslinkRecord {
    /// Generates a new instance where `dynasty` and `hash` are both zero.
    pub fn zero() -> Self {
        Self {
            slot: 0,
            shard_block_root: Hash256::zero(),
        }
    }
}
<|endoftext|>