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

#![allow(unsafe_code)]

//! A drop-in replacement for string_cache, but backed by Gecko `nsIAtom`s.

use gecko_bindings::bindings::Gecko_AddRefAtom;
use gecko_bindings::bindings::Gecko_Atomize;
use gecko_bindings::bindings::Gecko_Atomize16;
use gecko_bindings::bindings::Gecko_ReleaseAtom;
use gecko_bindings::structs::nsIAtom;
use nsstring::nsAString;
use precomputed_hash::PrecomputedHash;
use std::ascii::AsciiExt;
use std::borrow::{Cow, Borrow};
use std::char::{self, DecodeUtf16};
use std::fmt::{self, Write};
use std::hash::{Hash, Hasher};
use std::iter::Cloned;
use std::mem;
use std::ops::Deref;
use std::slice;

#[macro_use]
#[allow(improper_ctypes, non_camel_case_types, missing_docs)]
pub mod atom_macro {
    include!(concat!(env!("OUT_DIR"), "/gecko/atom_macro.rs"));
}

#[macro_use]
pub mod namespace;

pub use self::namespace::{Namespace, WeakNamespace};

macro_rules! local_name {
    ($s: tt) => { atom!($s) }
}

/// A strong reference to a Gecko atom.
#[derive(PartialEq, Eq)]
pub struct Atom(*mut WeakAtom);

/// An atom *without* a strong reference.
///
/// Only usable as `&'a WeakAtom`,
/// where `'a` is the lifetime of something that holds a strong reference to that atom.
pub struct WeakAtom(nsIAtom);

/// A BorrowedAtom for Gecko is just a weak reference to a `nsIAtom`, that
/// hasn't been bumped.
pub type BorrowedAtom<'a> = &'a WeakAtom;

impl Deref for Atom {
    type Target = WeakAtom;

    #[inline]
    fn deref(&self) -> &WeakAtom {
        unsafe {
            &*self.0
        }
    }
}

impl PrecomputedHash for Atom {
    #[inline]
    fn precomputed_hash(&self) -> u32 {
        self.get_hash()
    }
}

impl Borrow<WeakAtom> for Atom {
    #[inline]
    fn borrow(&self) -> &WeakAtom {
        self
    }
}

impl Eq for WeakAtom {}
impl PartialEq for WeakAtom {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        let weak: *const WeakAtom = self;
        let other: *const WeakAtom = other;
        weak == other
    }
}

unsafe impl Send for Atom {}
unsafe impl Sync for Atom {}
unsafe impl Sync for WeakAtom {}

impl WeakAtom {
    /// Construct a `WeakAtom` from a raw `nsIAtom`.
    #[inline]
    pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a mut Self {
        &mut *(atom as *mut WeakAtom)
    }

    /// Clone this atom, bumping the refcount if the atom is not static.
    #[inline]
    pub fn clone(&self) -> Atom {
        Atom::from(self.as_ptr())
    }

    /// Get the atom hash.
    #[inline]
    pub fn get_hash(&self) -> u32 {
        self.0.mHash
    }

    /// Get the atom as a slice of utf-16 chars.
    #[inline]
    pub fn as_slice(&self) -> &[u16] {
        unsafe {
            slice::from_raw_parts((*self.as_ptr()).mString, self.len() as usize)
        }
    }

    // NOTE: don't expose this, since it's slow, and easy to be misused.
    fn chars(&self) -> DecodeUtf16<Cloned<slice::Iter<u16>>> {
        char::decode_utf16(self.as_slice().iter().cloned())
    }

    /// Execute `cb` with the string that this atom represents.
    ///
    /// Find alternatives to this function when possible, please, since it's
    /// pretty slow.
    pub fn with_str<F, Output>(&self, cb: F) -> Output
        where F: FnOnce(&str) -> Output
    {
        // FIXME(bholley): We should measure whether it makes more sense to
        // cache the UTF-8 version in the Gecko atom table somehow.
        let owned = self.to_string();
        cb(&owned)
    }

    /// Convert this Atom into a string, decoding the UTF-16 bytes.
    ///
    /// Find alternatives to this function when possible, please, since it's
    /// pretty slow.
    #[inline]
    pub fn to_string(&self) -> String {
        String::from_utf16(self.as_slice()).unwrap()
    }

    /// Returns whether this atom is static.
    #[inline]
    pub fn is_static(&self) -> bool {
        // FIXME(emilio): re-introduce bitfield accessors:
        //
        // https://github.com/servo/rust-bindgen/issues/519
        unsafe {
            ((*self.as_ptr())._bitfield_1 & (0x80000000 as u32)) != 0
        }
    }

    /// Returns the length of the atom string.
    #[inline]
    pub fn len(&self) -> u32 {
        // FIXME(emilio): re-introduce bitfield accessors:
        //
        // https://github.com/servo/rust-bindgen/issues/519
        unsafe {
            (*self.as_ptr())._bitfield_1 & 0x7FFFFFFF
        }
    }

    /// Returns whether this atom is the empty string.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns the atom as a mutable pointer.
    #[inline]
    pub fn as_ptr(&self) -> *mut nsIAtom {
        let const_ptr: *const nsIAtom = &self.0;
        const_ptr as *mut nsIAtom
    }
}

impl fmt::Debug for WeakAtom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        write!(w, "Gecko WeakAtom({:p}, {})", self, self)
    }
}

impl fmt::Display for WeakAtom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        for c in self.chars() {
            try!(w.write_char(c.unwrap_or(char::REPLACEMENT_CHARACTER)))
        }
        Ok(())
    }
}

impl Atom {
    /// Execute a callback with the atom represented by `ptr`.
    pub unsafe fn with<F, R>(ptr: *mut nsIAtom, callback: F) -> R where F: FnOnce(&Atom) -> R {
        let atom = Atom(WeakAtom::new(ptr));
        let ret = callback(&atom);
        mem::forget(atom);
        ret
    }

    /// Creates an atom from an static atom pointer without checking in release
    /// builds.
    ///
    /// Right now it's only used by the atom macro, and ideally it should keep
    /// that way, now we have sugar for is_static, creating atoms using
    /// Atom::from should involve almost no overhead.
    #[inline]
    unsafe fn from_static(ptr: *mut nsIAtom) -> Self {
        let atom = Atom(ptr as *mut WeakAtom);
        debug_assert!(atom.is_static(),
                      "Called from_static for a non-static atom!");
        atom
    }

    /// Creates an atom from a dynamic atom pointer that has already had AddRef
    /// called on it.
    #[inline]
    pub unsafe fn from_addrefed(ptr: *mut nsIAtom) -> Self {
        debug_assert!(!ptr.is_null());
        unsafe {
            Atom(WeakAtom::new(ptr))
        }
    }

    /// Convert this atom into an addrefed nsIAtom pointer.
    #[inline]
    pub fn into_addrefed(self) -> *mut nsIAtom {
        let ptr = self.as_ptr();
        mem::forget(self);
        ptr
    }

    /// Return whether two atoms are ASCII-case-insensitive matches
    pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
        let a = self.as_slice();
        let b = other.as_slice();
        a.len() == b.len() && a.iter().zip(b).all(|(&a16, &b16)| {
            if a16 <= 0x7F && b16 <= 0x7F {
                (a16 as u8).eq_ignore_ascii_case(&(b16 as u8))
            } else {
                a16 == b16
            }
        })
    }

    /// Return whether this atom is an ASCII-case-insensitive match for the given string
    pub fn eq_str_ignore_ascii_case(&self, other: &str) -> bool {
        self.chars().map(|r| r.map(|c: char| c.to_ascii_lowercase()))
        .eq(other.chars().map(|c: char| Ok(c.to_ascii_lowercase())))
    }
}

impl Hash for Atom {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        state.write_u32(self.get_hash());
    }
}

impl Hash for WeakAtom {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        state.write_u32(self.get_hash());
    }
}

impl Clone for Atom {
    #[inline(always)]
    fn clone(&self) -> Atom {
        Atom::from(self.as_ptr())
    }
}

impl Drop for Atom {
    #[inline]
    fn drop(&mut self) {
        if !self.is_static() {
            unsafe {
                Gecko_ReleaseAtom(self.as_ptr());
            }
        }
    }
}

impl Default for Atom {
    #[inline]
    fn default() -> Self {
        atom!("")
    }
}

impl fmt::Debug for Atom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        write!(w, "Gecko Atom({:p}, {})", self.0, self)
    }
}

impl fmt::Display for Atom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            (&*self.0).fmt(w)
        }
    }
}

impl<'a> From<&'a str> for Atom {
    #[inline]
    fn from(string: &str) -> Atom {
        debug_assert!(string.len() <= u32::max_value() as usize);
        unsafe {
            Atom(WeakAtom::new(
                Gecko_Atomize(string.as_ptr() as *const _, string.len() as u32)
            ))
        }
    }
}

impl<'a> From<&'a nsAString> for Atom {
    #[inline]
    fn from(string: &nsAString) -> Atom {
        unsafe {
            Atom(WeakAtom::new(
                Gecko_Atomize16(string)
            ))
        }
    }
}

impl<'a> From<Cow<'a, str>> for Atom {
    #[inline]
    fn from(string: Cow<'a, str>) -> Atom {
        Atom::from(&*string)
    }
}

impl From<String> for Atom {
    #[inline]
    fn from(string: String) -> Atom {
        Atom::from(&*string)
    }
}

impl From<*mut nsIAtom> for Atom {
    #[inline]
    fn from(ptr: *mut nsIAtom) -> Atom {
        debug_assert!(!ptr.is_null());
        unsafe {
            let ret = Atom(WeakAtom::new(ptr));
            if !ret.is_static() {
                Gecko_AddRefAtom(ptr);
            }
            ret
        }
    }
}
<commit_msg>Rollup merge of #17022 - bholley:atom_fast_path, r=nox<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![allow(unsafe_code)]

//! A drop-in replacement for string_cache, but backed by Gecko `nsIAtom`s.

use gecko_bindings::bindings::Gecko_AddRefAtom;
use gecko_bindings::bindings::Gecko_Atomize;
use gecko_bindings::bindings::Gecko_Atomize16;
use gecko_bindings::bindings::Gecko_ReleaseAtom;
use gecko_bindings::structs::nsIAtom;
use nsstring::nsAString;
use precomputed_hash::PrecomputedHash;
use std::ascii::AsciiExt;
use std::borrow::{Cow, Borrow};
use std::char::{self, DecodeUtf16};
use std::fmt::{self, Write};
use std::hash::{Hash, Hasher};
use std::iter::Cloned;
use std::mem;
use std::ops::Deref;
use std::slice;

#[macro_use]
#[allow(improper_ctypes, non_camel_case_types, missing_docs)]
pub mod atom_macro {
    include!(concat!(env!("OUT_DIR"), "/gecko/atom_macro.rs"));
}

#[macro_use]
pub mod namespace;

pub use self::namespace::{Namespace, WeakNamespace};

macro_rules! local_name {
    ($s: tt) => { atom!($s) }
}

/// A strong reference to a Gecko atom.
#[derive(PartialEq, Eq)]
pub struct Atom(*mut WeakAtom);

/// An atom *without* a strong reference.
///
/// Only usable as `&'a WeakAtom`,
/// where `'a` is the lifetime of something that holds a strong reference to that atom.
pub struct WeakAtom(nsIAtom);

/// A BorrowedAtom for Gecko is just a weak reference to a `nsIAtom`, that
/// hasn't been bumped.
pub type BorrowedAtom<'a> = &'a WeakAtom;

impl Deref for Atom {
    type Target = WeakAtom;

    #[inline]
    fn deref(&self) -> &WeakAtom {
        unsafe {
            &*self.0
        }
    }
}

impl PrecomputedHash for Atom {
    #[inline]
    fn precomputed_hash(&self) -> u32 {
        self.get_hash()
    }
}

impl Borrow<WeakAtom> for Atom {
    #[inline]
    fn borrow(&self) -> &WeakAtom {
        self
    }
}

impl Eq for WeakAtom {}
impl PartialEq for WeakAtom {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        let weak: *const WeakAtom = self;
        let other: *const WeakAtom = other;
        weak == other
    }
}

unsafe impl Send for Atom {}
unsafe impl Sync for Atom {}
unsafe impl Sync for WeakAtom {}

impl WeakAtom {
    /// Construct a `WeakAtom` from a raw `nsIAtom`.
    #[inline]
    pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a mut Self {
        &mut *(atom as *mut WeakAtom)
    }

    /// Clone this atom, bumping the refcount if the atom is not static.
    #[inline]
    pub fn clone(&self) -> Atom {
        Atom::from(self.as_ptr())
    }

    /// Get the atom hash.
    #[inline]
    pub fn get_hash(&self) -> u32 {
        self.0.mHash
    }

    /// Get the atom as a slice of utf-16 chars.
    #[inline]
    pub fn as_slice(&self) -> &[u16] {
        unsafe {
            slice::from_raw_parts((*self.as_ptr()).mString, self.len() as usize)
        }
    }

    // NOTE: don't expose this, since it's slow, and easy to be misused.
    fn chars(&self) -> DecodeUtf16<Cloned<slice::Iter<u16>>> {
        char::decode_utf16(self.as_slice().iter().cloned())
    }

    /// Execute `cb` with the string that this atom represents.
    ///
    /// Find alternatives to this function when possible, please, since it's
    /// pretty slow.
    pub fn with_str<F, Output>(&self, cb: F) -> Output
        where F: FnOnce(&str) -> Output
    {
        // FIXME(bholley): We should measure whether it makes more sense to
        // cache the UTF-8 version in the Gecko atom table somehow.
        let owned = self.to_string();
        cb(&owned)
    }

    /// Convert this Atom into a string, decoding the UTF-16 bytes.
    ///
    /// Find alternatives to this function when possible, please, since it's
    /// pretty slow.
    #[inline]
    pub fn to_string(&self) -> String {
        String::from_utf16(self.as_slice()).unwrap()
    }

    /// Returns whether this atom is static.
    #[inline]
    pub fn is_static(&self) -> bool {
        // FIXME(emilio): re-introduce bitfield accessors:
        //
        // https://github.com/servo/rust-bindgen/issues/519
        unsafe {
            ((*self.as_ptr())._bitfield_1 & (0x80000000 as u32)) != 0
        }
    }

    /// Returns the length of the atom string.
    #[inline]
    pub fn len(&self) -> u32 {
        // FIXME(emilio): re-introduce bitfield accessors:
        //
        // https://github.com/servo/rust-bindgen/issues/519
        unsafe {
            (*self.as_ptr())._bitfield_1 & 0x7FFFFFFF
        }
    }

    /// Returns whether this atom is the empty string.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns the atom as a mutable pointer.
    #[inline]
    pub fn as_ptr(&self) -> *mut nsIAtom {
        let const_ptr: *const nsIAtom = &self.0;
        const_ptr as *mut nsIAtom
    }
}

impl fmt::Debug for WeakAtom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        write!(w, "Gecko WeakAtom({:p}, {})", self, self)
    }
}

impl fmt::Display for WeakAtom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        for c in self.chars() {
            try!(w.write_char(c.unwrap_or(char::REPLACEMENT_CHARACTER)))
        }
        Ok(())
    }
}

impl Atom {
    /// Execute a callback with the atom represented by `ptr`.
    pub unsafe fn with<F, R>(ptr: *mut nsIAtom, callback: F) -> R where F: FnOnce(&Atom) -> R {
        let atom = Atom(WeakAtom::new(ptr));
        let ret = callback(&atom);
        mem::forget(atom);
        ret
    }

    /// Creates an atom from an static atom pointer without checking in release
    /// builds.
    ///
    /// Right now it's only used by the atom macro, and ideally it should keep
    /// that way, now we have sugar for is_static, creating atoms using
    /// Atom::from should involve almost no overhead.
    #[inline]
    unsafe fn from_static(ptr: *mut nsIAtom) -> Self {
        let atom = Atom(ptr as *mut WeakAtom);
        debug_assert!(atom.is_static(),
                      "Called from_static for a non-static atom!");
        atom
    }

    /// Creates an atom from a dynamic atom pointer that has already had AddRef
    /// called on it.
    #[inline]
    pub unsafe fn from_addrefed(ptr: *mut nsIAtom) -> Self {
        debug_assert!(!ptr.is_null());
        unsafe {
            Atom(WeakAtom::new(ptr))
        }
    }

    /// Convert this atom into an addrefed nsIAtom pointer.
    #[inline]
    pub fn into_addrefed(self) -> *mut nsIAtom {
        let ptr = self.as_ptr();
        mem::forget(self);
        ptr
    }

    /// Return whether two atoms are ASCII-case-insensitive matches
    pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
        if self == other {
            return true;
        }

        let a = self.as_slice();
        let b = other.as_slice();
        a.len() == b.len() && a.iter().zip(b).all(|(&a16, &b16)| {
            if a16 <= 0x7F && b16 <= 0x7F {
                (a16 as u8).eq_ignore_ascii_case(&(b16 as u8))
            } else {
                a16 == b16
            }
        })
    }

    /// Return whether this atom is an ASCII-case-insensitive match for the given string
    pub fn eq_str_ignore_ascii_case(&self, other: &str) -> bool {
        self.chars().map(|r| r.map(|c: char| c.to_ascii_lowercase()))
        .eq(other.chars().map(|c: char| Ok(c.to_ascii_lowercase())))
    }
}

impl Hash for Atom {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        state.write_u32(self.get_hash());
    }
}

impl Hash for WeakAtom {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        state.write_u32(self.get_hash());
    }
}

impl Clone for Atom {
    #[inline(always)]
    fn clone(&self) -> Atom {
        Atom::from(self.as_ptr())
    }
}

impl Drop for Atom {
    #[inline]
    fn drop(&mut self) {
        if !self.is_static() {
            unsafe {
                Gecko_ReleaseAtom(self.as_ptr());
            }
        }
    }
}

impl Default for Atom {
    #[inline]
    fn default() -> Self {
        atom!("")
    }
}

impl fmt::Debug for Atom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        write!(w, "Gecko Atom({:p}, {})", self.0, self)
    }
}

impl fmt::Display for Atom {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            (&*self.0).fmt(w)
        }
    }
}

impl<'a> From<&'a str> for Atom {
    #[inline]
    fn from(string: &str) -> Atom {
        debug_assert!(string.len() <= u32::max_value() as usize);
        unsafe {
            Atom(WeakAtom::new(
                Gecko_Atomize(string.as_ptr() as *const _, string.len() as u32)
            ))
        }
    }
}

impl<'a> From<&'a nsAString> for Atom {
    #[inline]
    fn from(string: &nsAString) -> Atom {
        unsafe {
            Atom(WeakAtom::new(
                Gecko_Atomize16(string)
            ))
        }
    }
}

impl<'a> From<Cow<'a, str>> for Atom {
    #[inline]
    fn from(string: Cow<'a, str>) -> Atom {
        Atom::from(&*string)
    }
}

impl From<String> for Atom {
    #[inline]
    fn from(string: String) -> Atom {
        Atom::from(&*string)
    }
}

impl From<*mut nsIAtom> for Atom {
    #[inline]
    fn from(ptr: *mut nsIAtom) -> Atom {
        debug_assert!(!ptr.is_null());
        unsafe {
            let ret = Atom(WeakAtom::new(ptr));
            if !ret.is_static() {
                Gecko_AddRefAtom(ptr);
            }
            ret
        }
    }
}
<|endoftext|>


<commit_before>//! This modules contains an implementation of [r2d2](https://github.com/sfackler/r2d2)
//! functionality of connection pools. To get more details about creating r2d2 pools
//! please refer to original documentation.
use std::iter::Iterator;
use query::QueryBuilder;
use client::{CDRS, Session};
use error::{Error as CError, Result as CResult};
use authenticators::Authenticator;
use compression::Compression;
use r2d2;
use transport::CDRSTransport;
use rand;
use std::sync::atomic::{AtomicUsize, Ordering};

/// Load balancing strategy
#[derive(PartialEq)]
pub enum LoadBalancingStrategy {
    /// Round Robin balancing strategy
    RoundRobin,
    /// Random balancing strategy
    Random,
}

impl LoadBalancingStrategy {
    /// Returns next value for selected load balancing strategy
    pub fn next<'a, N>(&'a self, nodes: &'a Vec<N>, i: usize) -> Option<&N> {
        match *self {
            LoadBalancingStrategy::Random => nodes.get(self.rnd_idx((0, Some(nodes.len())))),
            LoadBalancingStrategy::RoundRobin => {
                let mut cycle = nodes.iter().cycle().skip(i);
                cycle.next()
            }
        }
    }

    /// Returns random number from a range
    fn rnd_idx(&self, bounds: (usize, Option<usize>)) -> usize {
        let min = bounds.0;
        let max = bounds.1.unwrap_or(u8::max_value() as usize);
        let rnd = rand::random::<usize>();
        min + rnd * (max - min) / (u8::max_value() as usize)
    }
}

/// Load balancer
///
/// #Example
///
/// ```no_run
/// use cdrs::cluster::{LoadBalancingStrategy, LoadBalancer};
/// use cdrs::transport::TransportTcp;
/// let transports = vec![TransportTcp::new("127.0.0.1:9042"), TransportTcp::new("127.0.0.1:9042")];
/// let load_balancer = LoadBalancer::new(transports, LoadBalancingStrategy::RoundRobin);
/// let node = load_balancer.next().unwrap();
/// ```
pub struct LoadBalancer<T> {
    strategy: LoadBalancingStrategy,
    nodes: Vec<T>,
    i: AtomicUsize,
}

impl<T> LoadBalancer<T> {
    /// Factory function which creates new `LoadBalancer` with provided strategy.
    pub fn new(nodes: Vec<T>, strategy: LoadBalancingStrategy) -> LoadBalancer<T> {
        LoadBalancer {
            nodes: nodes,
            strategy: strategy,
            i: AtomicUsize::new(0),
        }
    }

    /// Returns next node basing on provided strategy.
    pub fn next(&self) -> Option<&T> {
        let next = self.strategy
            .next(&self.nodes, self.i.load(Ordering::Relaxed) as usize);
        if self.strategy == LoadBalancingStrategy::RoundRobin {
            self.i.fetch_add(1, Ordering::Relaxed);
            // prevent overflow
            let i = self.i.load(Ordering::Relaxed);
            match i.checked_rem(self.nodes.len() as usize) {
                Some(rem) => self.i.store(rem, Ordering::Relaxed),
                None => return None,
            }
        }
        next
    }
}

/// [r2d2](https://github.com/sfackler/r2d2) `ManageConnection`.
pub struct ClusterConnectionManager<T, X> {
    load_balancer: LoadBalancer<X>,
    authenticator: T,
    compression: Compression,
}

impl<T, X> ClusterConnectionManager<T, X>
    where T: Authenticator + Send + Sync + 'static
{
    /// Creates a new instance of `ConnectionManager`.
    /// It requires transport, authenticator and compression as inputs.
    pub fn new(load_balancer: LoadBalancer<X>,
               authenticator: T,
               compression: Compression)
               -> ClusterConnectionManager<T, X> {
        ClusterConnectionManager {
            load_balancer: load_balancer,
            authenticator: authenticator,
            compression: compression,
        }
    }
}

impl<T: Authenticator + Send + Sync + 'static,
     X: CDRSTransport + Send + Sync + 'static> r2d2::ManageConnection
    for ClusterConnectionManager<T, X> {
    type Connection = Session<T, X>;
    type Error = CError;

    fn connect(&self) -> Result<Self::Connection, Self::Error> {
        let transport_res: CResult<X> = self.load_balancer
            .next()
            .ok_or_else(|| "Cannot get next node".into())
            .and_then(|x| x.try_clone().map_err(|e| e.into()));
        let transport = try!(transport_res);
        let compression = self.compression;
        let cdrs = CDRS::new(transport, self.authenticator.clone());

        cdrs.start(compression)
    }

    fn is_valid(&self, connection: &mut Self::Connection) -> Result<(), Self::Error> {
        let query = QueryBuilder::new("SELECT * FROM system.peers;").finalize();

        connection.query(query, false, false).map(|_| ())
    }

    fn has_broken(&self, _connection: &mut Self::Connection) -> bool {
        false
    }
}

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

    #[test]
    fn round_robin() {
        let nodes = vec!["a", "b", "c"];
        let nodes_c = nodes.clone();
        let load_balancer = LoadBalancer::new(nodes, LoadBalancingStrategy::RoundRobin);
        for i in 0..10 {
            assert_eq!(&nodes_c[i % 3], load_balancer.next().unwrap());
        }
    }
}
<commit_msg>alter rnd range calculation to avoid overflow<commit_after>//! This modules contains an implementation of [r2d2](https://github.com/sfackler/r2d2)
//! functionality of connection pools. To get more details about creating r2d2 pools
//! please refer to original documentation.
use std::iter::Iterator;
use query::QueryBuilder;
use client::{CDRS, Session};
use error::{Error as CError, Result as CResult};
use authenticators::Authenticator;
use compression::Compression;
use r2d2;
use transport::CDRSTransport;
use rand;
use std::sync::atomic::{AtomicUsize, Ordering};

/// Load balancing strategy
#[derive(PartialEq)]
pub enum LoadBalancingStrategy {
    /// Round Robin balancing strategy
    RoundRobin,
    /// Random balancing strategy
    Random,
}

impl LoadBalancingStrategy {
    /// Returns next value for selected load balancing strategy
    pub fn next<'a, N>(&'a self, nodes: &'a Vec<N>, i: usize) -> Option<&N> {
        match *self {
            LoadBalancingStrategy::Random => nodes.get(self.rnd_idx((0, Some(nodes.len())))),
            LoadBalancingStrategy::RoundRobin => {
                let mut cycle = nodes.iter().cycle().skip(i);
                cycle.next()
            }
        }
    }

    /// Returns random number from a range
    fn rnd_idx(&self, bounds: (usize, Option<usize>)) -> usize {
        let min = bounds.0;
        let max = bounds.1.unwrap_or(u8::max_value() as usize);
        let rnd = rand::random::<usize>();
        rnd % (max - min) + min
    }
}

/// Load balancer
///
/// #Example
///
/// ```no_run
/// use cdrs::cluster::{LoadBalancingStrategy, LoadBalancer};
/// use cdrs::transport::TransportTcp;
/// let transports = vec![TransportTcp::new("127.0.0.1:9042"), TransportTcp::new("127.0.0.1:9042")];
/// let load_balancer = LoadBalancer::new(transports, LoadBalancingStrategy::RoundRobin);
/// let node = load_balancer.next().unwrap();
/// ```
pub struct LoadBalancer<T> {
    strategy: LoadBalancingStrategy,
    nodes: Vec<T>,
    i: AtomicUsize,
}

impl<T> LoadBalancer<T> {
    /// Factory function which creates new `LoadBalancer` with provided strategy.
    pub fn new(nodes: Vec<T>, strategy: LoadBalancingStrategy) -> LoadBalancer<T> {
        LoadBalancer {
            nodes: nodes,
            strategy: strategy,
            i: AtomicUsize::new(0),
        }
    }

    /// Returns next node basing on provided strategy.
    pub fn next(&self) -> Option<&T> {
        let next = self.strategy
            .next(&self.nodes, self.i.load(Ordering::Relaxed) as usize);
        if self.strategy == LoadBalancingStrategy::RoundRobin {
            self.i.fetch_add(1, Ordering::Relaxed);
            // prevent overflow
            let i = self.i.load(Ordering::Relaxed);
            match i.checked_rem(self.nodes.len() as usize) {
                Some(rem) => self.i.store(rem, Ordering::Relaxed),
                None => return None,
            }
        }
        next
    }
}

/// [r2d2](https://github.com/sfackler/r2d2) `ManageConnection`.
pub struct ClusterConnectionManager<T, X> {
    load_balancer: LoadBalancer<X>,
    authenticator: T,
    compression: Compression,
}

impl<T, X> ClusterConnectionManager<T, X>
    where T: Authenticator + Send + Sync + 'static
{
    /// Creates a new instance of `ConnectionManager`.
    /// It requires transport, authenticator and compression as inputs.
    pub fn new(load_balancer: LoadBalancer<X>,
               authenticator: T,
               compression: Compression)
               -> ClusterConnectionManager<T, X> {
        ClusterConnectionManager {
            load_balancer: load_balancer,
            authenticator: authenticator,
            compression: compression,
        }
    }
}

impl<T: Authenticator + Send + Sync + 'static,
     X: CDRSTransport + Send + Sync + 'static> r2d2::ManageConnection
    for ClusterConnectionManager<T, X> {
    type Connection = Session<T, X>;
    type Error = CError;

    fn connect(&self) -> Result<Self::Connection, Self::Error> {
        let transport_res: CResult<X> = self.load_balancer
            .next()
            .ok_or_else(|| "Cannot get next node".into())
            .and_then(|x| x.try_clone().map_err(|e| e.into()));
        let transport = try!(transport_res);
        let compression = self.compression;
        let cdrs = CDRS::new(transport, self.authenticator.clone());

        cdrs.start(compression)
    }

    fn is_valid(&self, connection: &mut Self::Connection) -> Result<(), Self::Error> {
        let query = QueryBuilder::new("SELECT * FROM system.peers;").finalize();

        connection.query(query, false, false).map(|_| ())
    }

    fn has_broken(&self, _connection: &mut Self::Connection) -> bool {
        false
    }
}

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

    #[test]
    fn round_robin() {
        let nodes = vec!["a", "b", "c"];
        let nodes_c = nodes.clone();
        let load_balancer = LoadBalancer::new(nodes, LoadBalancingStrategy::RoundRobin);
        for i in 0..10 {
            assert_eq!(&nodes_c[i % 3], load_balancer.next().unwrap());
        }
    }
}
<|endoftext|>


<commit_before>use serde::{de, ser};
use serde::ser::SerializeMap;
use std::collections::HashMap;
use std::fmt;

use ::{GraphQLError, Value};
use ast::InputValue;
use executor::ExecutionError;
use parser::{ParseError, Spanning, SourcePosition};
use validation::RuleError;

impl ser::Serialize for ExecutionError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(3)));

        try!(map.serialize_key("message"));
        try!(map.serialize_value(self.message()));

        let locations = vec![self.location()];
        try!(map.serialize_key("locations"));
        try!(map.serialize_value(&locations));

        try!(map.serialize_key("path"));
        try!(map.serialize_value(self.path()));

        map.end()
    }
}

impl<'a> ser::Serialize for GraphQLError<'a> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            GraphQLError::ParseError(ref err) => vec![err].serialize(serializer),
            GraphQLError::ValidationError(ref errs) => errs.serialize(serializer),
            GraphQLError::NoOperationProvided => {
                serializer.serialize_str("Must provide an operation")
            },
            GraphQLError::MultipleOperationsProvided => {
                serializer.serialize_str("Must provide operation name if query contains multiple operations")
            },
            GraphQLError::UnknownOperationName => {
                serializer.serialize_str("Unknown operation")
            },
        }
    }
}

impl de::Deserialize for InputValue {
    fn deserialize<D>(deserializer: D) -> Result<InputValue, D::Error>
        where D: de::Deserializer,
    {
        struct InputValueVisitor;

        impl de::Visitor for InputValueVisitor {
            type Value = InputValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a valid input value")
            }

            fn visit_bool<E>(self, value: bool) -> Result<InputValue, E> {
                Ok(InputValue::boolean(value))
            }

            fn visit_i64<E>(self, value: i64) -> Result<InputValue, E> {
                Ok(InputValue::int(value))
            }

            fn visit_u64<E>(self, value: u64) -> Result<InputValue, E>
                where E: de::Error,
            {
                self.visit_f64(value as f64)
            }

            fn visit_f64<E>(self, value: f64) -> Result<InputValue, E> {
                Ok(InputValue::float(value))
            }

            fn visit_str<E>(self, value: &str) -> Result<InputValue, E>
                where E: de::Error,
            {
                self.visit_string(value.into())
            }

            fn visit_string<E>(self, value: String) -> Result<InputValue, E> {
                Ok(InputValue::string(value))
            }

            fn visit_none<E>(self) -> Result<InputValue, E> {
                Ok(InputValue::null())
            }

            fn visit_unit<E>(self) -> Result<InputValue, E> {
                Ok(InputValue::null())
            }

            fn visit_seq<V>(self, visitor: V) -> Result<InputValue, V::Error>
                where V: de::SeqVisitor,
            {
                let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
                Ok(InputValue::list(values))
            }

            fn visit_map<V>(self, visitor: V) -> Result<InputValue, V::Error>
                where V: de::MapVisitor,
            {
                let values = try!(de::impls::HashMapVisitor::<String, InputValue, _>::new()
                    .visit_map(visitor));
                Ok(InputValue::object(values))
            }
        }

        deserializer.deserialize(InputValueVisitor)
    }
}

impl ser::Serialize for InputValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(),
            InputValue::Int(v) => serializer.serialize_i64(v),
            InputValue::Float(v) => serializer.serialize_f64(v),
            InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v),
            InputValue::Boolean(v) => serializer.serialize_bool(v),
            InputValue::List(ref v) => {
                v.iter().map(|x| x.item.clone()).collect::<Vec<_>>().serialize(serializer)
            },
            InputValue::Object(ref v) => {
                v.iter()
                    .map(|&(ref k, ref v)| (k.item.clone(), v.item.clone()))
                    .collect::<HashMap<_, _>>()
                    .serialize(serializer)
            },
        }
    }
}

impl ser::Serialize for RuleError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        try!(map.serialize_key("message"));
        try!(map.serialize_value(self.message()));

        try!(map.serialize_key("locations"));
        try!(map.serialize_value(self.locations()));

        map.end()
    }
}

impl ser::Serialize for SourcePosition {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        let line = self.line() + 1;
        try!(map.serialize_key("line"));
        try!(map.serialize_value(&line));

        let column = self.column() + 1;
        try!(map.serialize_key("column"));
        try!(map.serialize_value(&column));

        map.end()
    }
}

impl<'a> ser::Serialize for Spanning<ParseError<'a>> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        let message = format!("{}", self.item);
        try!(map.serialize_key("message"));
        try!(map.serialize_value(&message));

        let mut location = HashMap::new();
        location.insert("line".to_owned(), self.start.line() + 1);
        location.insert("column".to_owned(), self.start.column() + 1);

        let locations = vec![location];

        try!(map.serialize_key("locations"));
        try!(map.serialize_value(&locations));

        map.end()
    }
}

impl ser::Serialize for Value {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            Value::Null => serializer.serialize_unit(),
            Value::Int(v) => serializer.serialize_i64(v),
            Value::Float(v) => serializer.serialize_f64(v),
            Value::String(ref v) => serializer.serialize_str(v),
            Value::Boolean(v) => serializer.serialize_bool(v),
            Value::List(ref v) => v.serialize(serializer),
            Value::Object(ref v) => v.serialize(serializer),
        }
    }
}
<commit_msg>Implemented from_json for InputValue.<commit_after>use serde::{de, ser};
use serde::ser::SerializeMap;
use std::fmt;
use std::collections::HashMap;

use ::{GraphQLError, Value};
use ast::InputValue;
use executor::ExecutionError;
use parser::{ParseError, Spanning, SourcePosition};
use validation::RuleError;
use serde_json::Value as Json;

impl InputValue {
    /// Converts serde_json::Value to juniper::InputValue
    pub fn from_json(json: Json) -> InputValue {
        match json {
          Json::Number(num) => {
              if let Some(number) = num.as_i64() {
                  InputValue::int(number)
              }
              else if let Some(number) = num.as_f64() {
                  InputValue::float(number)
              }
              else if let Some(number) = num.as_u64() {
                InputValue::float(number as f64)
              }
              else {
                  panic!("Invalid number data type was found.");
              }
          }
          Json::String(s) => InputValue::string(s),
          Json::Bool(b) => InputValue::boolean(b),
          Json::Array(a) => InputValue::list(a.into_iter().map(InputValue::from_json).collect()),
          Json::Object(o) => InputValue::object(o.into_iter().map(|(k, v)| (k, InputValue::from_json(v))).collect()),
          Json::Null => InputValue::null(),
       }
    }
}

impl ser::Serialize for ExecutionError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(3)));

        try!(map.serialize_key("message"));
        try!(map.serialize_value(self.message()));

        let locations = vec![self.location()];
        try!(map.serialize_key("locations"));
        try!(map.serialize_value(&locations));

        try!(map.serialize_key("path"));
        try!(map.serialize_value(self.path()));

        map.end()
    }
}

impl<'a> ser::Serialize for GraphQLError<'a> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            GraphQLError::ParseError(ref err) => vec![err].serialize(serializer),
            GraphQLError::ValidationError(ref errs) => errs.serialize(serializer),
            GraphQLError::NoOperationProvided => {
                serializer.serialize_str("Must provide an operation")
            },
            GraphQLError::MultipleOperationsProvided => {
                serializer.serialize_str("Must provide operation name if query contains multiple operations")
            },
            GraphQLError::UnknownOperationName => {
                serializer.serialize_str("Unknown operation")
            },
        }
    }
}

impl de::Deserialize for InputValue {
    fn deserialize<D>(deserializer: D) -> Result<InputValue, D::Error>
        where D: de::Deserializer,
    {
        struct InputValueVisitor;

        impl de::Visitor for InputValueVisitor {
            type Value = InputValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a valid input value")
            }

            fn visit_bool<E>(self, value: bool) -> Result<InputValue, E> {
                Ok(InputValue::boolean(value))
            }

            fn visit_i64<E>(self, value: i64) -> Result<InputValue, E> {
                Ok(InputValue::int(value))
            }

            fn visit_u64<E>(self, value: u64) -> Result<InputValue, E>
                where E: de::Error,
            {
                self.visit_f64(value as f64)
            }

            fn visit_f64<E>(self, value: f64) -> Result<InputValue, E> {
                Ok(InputValue::float(value))
            }

            fn visit_str<E>(self, value: &str) -> Result<InputValue, E>
                where E: de::Error,
            {
                self.visit_string(value.into())
            }

            fn visit_string<E>(self, value: String) -> Result<InputValue, E> {
                Ok(InputValue::string(value))
            }

            fn visit_none<E>(self) -> Result<InputValue, E> {
                Ok(InputValue::null())
            }

            fn visit_unit<E>(self) -> Result<InputValue, E> {
                Ok(InputValue::null())
            }

            fn visit_seq<V>(self, visitor: V) -> Result<InputValue, V::Error>
                where V: de::SeqVisitor,
            {
                let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
                Ok(InputValue::list(values))
            }

            fn visit_map<V>(self, visitor: V) -> Result<InputValue, V::Error>
                where V: de::MapVisitor,
            {
                let values = try!(de::impls::HashMapVisitor::<String, InputValue, _>::new()
                    .visit_map(visitor));
                Ok(InputValue::object(values))
            }
        }

        deserializer.deserialize(InputValueVisitor)
    }
}

impl ser::Serialize for InputValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(),
            InputValue::Int(v) => serializer.serialize_i64(v),
            InputValue::Float(v) => serializer.serialize_f64(v),
            InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v),
            InputValue::Boolean(v) => serializer.serialize_bool(v),
            InputValue::List(ref v) => {
                v.iter().map(|x| x.item.clone()).collect::<Vec<_>>().serialize(serializer)
            },
            InputValue::Object(ref v) => {
                v.iter()
                    .map(|&(ref k, ref v)| (k.item.clone(), v.item.clone()))
                    .collect::<HashMap<_, _>>()
                    .serialize(serializer)
            },
        }
    }
}

impl ser::Serialize for RuleError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        try!(map.serialize_key("message"));
        try!(map.serialize_value(self.message()));

        try!(map.serialize_key("locations"));
        try!(map.serialize_value(self.locations()));

        map.end()
    }
}

impl ser::Serialize for SourcePosition {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        let line = self.line() + 1;
        try!(map.serialize_key("line"));
        try!(map.serialize_value(&line));

        let column = self.column() + 1;
        try!(map.serialize_key("column"));
        try!(map.serialize_value(&column));

        map.end()
    }
}

impl<'a> ser::Serialize for Spanning<ParseError<'a>> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        let mut map = try!(serializer.serialize_map(Some(2)));

        let message = format!("{}", self.item);
        try!(map.serialize_key("message"));
        try!(map.serialize_value(&message));

        let mut location = HashMap::new();
        location.insert("line".to_owned(), self.start.line() + 1);
        location.insert("column".to_owned(), self.start.column() + 1);

        let locations = vec![location];

        try!(map.serialize_key("locations"));
        try!(map.serialize_value(&locations));

        map.end()
    }
}

impl ser::Serialize for Value {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer,
    {
        match *self {
            Value::Null => serializer.serialize_unit(),
            Value::Int(v) => serializer.serialize_i64(v),
            Value::Float(v) => serializer.serialize_f64(v),
            Value::String(ref v) => serializer.serialize_str(v),
            Value::Boolean(v) => serializer.serialize_bool(v),
            Value::List(ref v) => v.serialize(serializer),
            Value::Object(ref v) => v.serialize(serializer),
        }
    }
}
<|endoftext|>


<commit_before>use constants::*;
use std::ffi::OsString;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = ".kic";
    let path_to_dir = Path::new(dir_name);
    if path_to_dir.exists() && path_to_dir.is_dir() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config";
    let path_to_config = path_to_dir.clone().join(config_file);
    if path_to_config.exists() && path_to_config.is_file() {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                write_default_config(&mut fp);
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn write_default_config(fp: &mut File) {
    match fp.write(DEFAULT_CONFIG.as_bytes()) {
        Ok(_)    => {},
        Err(why) => panic!("{:?}", why),
    }
}

// You will be enable to use std::fs::walk_dir instead of this function in rust 1.6.0 or later
fn walk_dir<P: AsRef<Path>>(p: P) -> Vec<OsString> {
    let dirs = match fs::read_dir(p) {
        Ok(ds)   => ds,
        Err(why) => panic!("{:?}", why),
    };
    let dirs = dirs.filter(|d| d.is_ok())
        .flat_map(|d| {
            let p = d.unwrap().path();
            if IGNORED_NAMES.iter().any(|name| p.ends_with(name)) {
                Vec::new()
            } else if p.is_file() {
                vec![p.into_os_string()]
            } else {
                walk_dir(&p)
            }
        })
        .collect::<Vec<OsString>>();
    dirs
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<commit_msg>Create create_setting_file() and Delete write_default_config()<commit_after>use constants::*;
use std::ffi::OsString;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = ".kic";
    let path_to_dir = Path::new(dir_name);
    if path_to_dir.exists() && path_to_dir.is_dir() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config";
    let path_to_config = path_to_dir.clone().join(config_file);
    create_setting_file(&path_to_config, DEFAULT_CONFIG);
}

fn create_setting_file(path_to_file: &PathBuf, contents: &'static str) {
    if path_to_file.exists() && path_to_file.is_file() {
        println!("  OK: \"{:?}\" file has already exist.", path_to_file);
    } else {
        match File::create(path_to_file) {
            Ok(mut fp) => {
                println!("  OK: Created {:?} file.", path_to_file);
                match fp.write(contents.as_bytes()) {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

// You will be enable to use std::fs::walk_dir instead of this function in rust 1.6.0 or later
fn walk_dir<P: AsRef<Path>>(p: P) -> Vec<OsString> {
    let dirs = match fs::read_dir(p) {
        Ok(ds)   => ds,
        Err(why) => panic!("{:?}", why),
    };
    let dirs = dirs.filter(|d| d.is_ok())
        .flat_map(|d| {
            let p = d.unwrap().path();
            if IGNORED_NAMES.iter().any(|name| p.ends_with(name)) {
                Vec::new()
            } else if p.is_file() {
                vec![p.into_os_string()]
            } else {
                walk_dir(&p)
            }
        })
        .collect::<Vec<OsString>>();
    dirs
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<|endoftext|>


<commit_before>//! This example draws a crude version of the Rust logo.
//! The version is "crude" because it's all very approximate with plenty of guesswork.
//! If you can come up with a way to do this so that it exactly matches the logo, please
//! do submit it!
//! In any case, this is an excellent example of creatively using fills and some other
//! techniques to create a fairly complex drawing.

extern crate turtle;

use turtle::Turtle;

fn main() {
    let mut turtle = Turtle::new();

    turtle.set_speed(10);
    turtle.set_fill_color("black");

    turtle.begin_fill();
    turtle.pen_up();
    turtle.forward(130.0);
    turtle.pen_down();

    gear(&mut turtle);
    turtle.end_fill();

    turtle.pen_up();
    turtle.forward(45.0);
    turtle.left(90.0);
    turtle.pen_down();

    inner_gear(&mut turtle);

    letter(&mut turtle);

    turtle.hide();
}

fn gear(turtle: &mut Turtle) {
    // Much of this code was figured out by guessing and checking
    let teeth = 32.0;
    let tooth_size = 20.0;
    let angle = 360.0 / teeth;
    turtle.right(180.0 - angle * 6.0 / 2.0);
    for _ in 0..teeth as u64 {
        turtle.forward(tooth_size);
        turtle.left(180.0 - angle * 7.0);
        turtle.forward(tooth_size);
        turtle.right(180.0 - angle * 6.0);
    }

    turtle.right(angle * 6.0 / 2.0);
}

fn inner_gear(turtle: &mut Turtle) {
    inner_circle(turtle);
    inner_teeth(turtle);
}

fn inner_circle(turtle: &mut Turtle) {
    turtle.set_fill_color("white");
    turtle.begin_fill();
    for _ in 0..360 {
        turtle.forward(1.5);
        turtle.right(1.0);
    }
    turtle.end_fill();
    turtle.set_fill_color("black");
}

fn inner_teeth(turtle: &mut Turtle) {
    let tooth_size = 40.0;
    turtle.pen_up();
    turtle.left(90.0);
    turtle.forward(10.0);
    turtle.right(90.0);
    turtle.pen_down();

    for _ in 0..5 {
        turtle.pen_up();
        turtle.forward(tooth_size / 2.0);
        turtle.pen_down();

        turtle.begin_fill();
        turtle.right(120.0);
        turtle.forward(tooth_size);
        turtle.right(120.0);
        turtle.forward(tooth_size);
        turtle.right(120.0);
        turtle.end_fill();

        turtle.pen_up();
        turtle.forward(tooth_size / 2.0);
        turtle.right(90.0);
        turtle.forward(5.0);
        turtle.left(90.0);
        turtle.pen_down();

        inner_tooth_circle(turtle);

        turtle.pen_up();
        turtle.left(90.0);
        turtle.forward(5.0);
        turtle.right(90.0);
        for _ in 0..360/5/2 {
            turtle.forward(3.41);
            turtle.right(2.0);
        }
        turtle.pen_down();
    }
}

fn inner_tooth_circle(turtle: &mut Turtle) {
    turtle.set_fill_color("white");
    turtle.begin_fill();
    for _ in 0..360/8 {
        turtle.forward(1.0);
        turtle.right(8.0);
    }
    turtle.end_fill();
    turtle.set_fill_color("black");
}

fn letter(turtle: &mut Turtle) {
    turtle.pen_up();
    turtle.right(180.0);
    turtle.pen_down();
    for _ in 0..(360/5 - 7)/2 {
        turtle.forward(3.41);
        turtle.left(2.0);
    }
    // Trick for making the turtle face to the right
    let heading = turtle.heading();
    turtle.right(heading);

    turtle.set_pen_size(10.0);
    turtle.forward(180.0);
    turtle.backward(90.0);

    turtle.right(90.0);
    turtle.forward(100.0);
}
<commit_msg>Drawing the Rust letter R<commit_after>//! This example draws a crude version of the Rust logo.
//! The version is "crude" because it's all very approximate with plenty of guesswork.
//! If you can come up with a way to do this so that it exactly matches the logo, please
//! do submit it!
//! In any case, this is an excellent example of creatively using fills and some other
//! techniques to create a fairly complex drawing.

extern crate turtle;

use turtle::Turtle;

const SPEED: i32 = 10;

fn main() {
    let mut turtle = Turtle::new();

    turtle.set_speed(SPEED);
    turtle.set_fill_color("black");

    turtle.begin_fill();
    turtle.pen_up();
    turtle.forward(130.0);
    turtle.pen_down();

    gear(&mut turtle);
    turtle.end_fill();

    turtle.pen_up();
    turtle.forward(45.0);
    turtle.left(90.0);
    turtle.pen_down();

    inner_gear(&mut turtle);

    letter(&mut turtle);

    turtle.hide();
}

fn gear(turtle: &mut Turtle) {
    // Much of this code was figured out by guessing and checking
    let teeth = 32.0;
    let tooth_size = 20.0;
    let angle = 360.0 / teeth;
    turtle.right(180.0 - angle * 6.0 / 2.0);
    for _ in 0..teeth as u64 {
        turtle.forward(tooth_size);
        turtle.left(180.0 - angle * 7.0);
        turtle.forward(tooth_size);
        turtle.right(180.0 - angle * 6.0);
    }

    turtle.right(angle * 6.0 / 2.0);
}

fn inner_gear(turtle: &mut Turtle) {
    inner_circle(turtle);
    inner_teeth(turtle);
}

fn inner_circle(turtle: &mut Turtle) {
    turtle.set_fill_color("white");
    turtle.begin_fill();
    for _ in 0..360 {
        turtle.forward(1.5);
        turtle.right(1.0);
    }
    turtle.end_fill();
    turtle.set_fill_color("black");
}

fn inner_teeth(turtle: &mut Turtle) {
    let tooth_size = 40.0;
    turtle.pen_up();
    turtle.left(90.0);
    turtle.forward(10.0);
    turtle.right(90.0);
    turtle.pen_down();

    for _ in 0..5 {
        turtle.pen_up();
        turtle.forward(tooth_size / 2.0);
        turtle.pen_down();

        turtle.begin_fill();
        turtle.right(120.0);
        turtle.forward(tooth_size);
        turtle.right(120.0);
        turtle.forward(tooth_size);
        turtle.right(120.0);
        turtle.end_fill();

        turtle.pen_up();
        turtle.forward(tooth_size / 2.0);
        turtle.right(90.0);
        turtle.forward(5.0);
        turtle.left(90.0);
        turtle.pen_down();

        inner_tooth_circle(turtle);

        turtle.pen_up();
        turtle.left(90.0);
        turtle.forward(5.0);
        turtle.right(90.0);
        for _ in 0..360/5/2 {
            turtle.forward(3.41);
            turtle.right(2.0);
        }
        turtle.pen_down();
    }
}

fn inner_tooth_circle(turtle: &mut Turtle) {
    turtle.set_fill_color("white");
    turtle.begin_fill();
    for _ in 0..360/8 {
        turtle.forward(1.0);
        turtle.right(8.0);
    }
    turtle.end_fill();
    turtle.set_fill_color("black");
}

fn letter(turtle: &mut Turtle) {
    turtle.pen_up();
    turtle.right(180.0);
    turtle.pen_down();
    for _ in 0..(360/5 - 8)/2 {
        turtle.forward(3.41);
        turtle.left(2.0);
    }
    // Trick for making the turtle face to the right
    let heading = turtle.heading();
    turtle.right(heading);

    turtle.set_pen_size(12.0);
    turtle.forward(110.0);
    for _ in 0..600 {
        // By going forward and then backward, we avoid any "gaps" between the very small movements
        // To see why this is needed, try replacing this with a single movement of the difference
        // between the two.
        turtle.forward(0.5);
        turtle.set_speed("instant");
        turtle.backward(0.4);
        turtle.right(0.3);
        turtle.set_speed(SPEED);
    }

    turtle.forward(52.0);
    turtle.right(90.0);
    turtle.forward(50.0);
    turtle.backward(90.0);

    turtle.left(90.0);
    turtle.forward(65.0);
    turtle.backward(95.0);

    turtle.pen_up();
    turtle.backward(95.0);
    turtle.pen_down();

    turtle.forward(40.0);
    for _ in 0..400 {
        turtle.forward(0.5);
        turtle.set_speed("instant");
        turtle.backward(0.4);
        turtle.right(0.2);
        turtle.set_speed(SPEED);
    }

    for _ in 0..200 {
        turtle.forward(0.5);
        turtle.set_speed("instant");
        turtle.backward(0.4);
        turtle.left(0.1);
        turtle.set_speed(SPEED);
    }
}
<|endoftext|>


<commit_before>extern crate openvr;

fn print_matrix_4x4(offset: u32, mat: [[f32; 4]; 4]) {
    let off: String = (0..offset).map(|_| ' ').collect();
    println!("{:?}",        mat[0]);
    println!("{}{:?}", off, mat[1]);
    println!("{}{:?}", off, mat[2]);
    println!("{}{:?}", off, mat[3]);
}

fn print_matrix_4x3(offset: u32, mat: [[f32; 4]; 3]) {
    let off: String = (0..offset).map(|_| ' ').collect();
    println!("{:?}",        mat[0]);
    println!("{}{:?}", off, mat[1]);
    println!("{}{:?}", off, mat[2]);
}

fn main() {
    let ivr = match vr::IVRSystem::init() {
        Ok(ivr) => ivr,
        Err(err) => {
            println!("Failed to create IVR subsystem {:?}", err);
            return;
        }
    };

    println!("IVR was created");
    println!("\tbounds: {:?}", ivr.bounds());
    println!("\trecommended size: {:?}", ivr.recommended_render_target_size());
    println!("\teye output: {:?} {:?}", ivr.eye_viewport(vr::Eye::Left), ivr.eye_viewport(vr::Eye::Right));
    println!("\tvsync: {:?}", ivr.time_since_last_vsync());

    print!("\tprojection matrix left  ");
    print_matrix_4x4(31, ivr.projection_matrix(vr::Eye::Left, 0.1, 100.));
    print!("\tprojection matrix right ");
    print_matrix_4x4(31, ivr.projection_matrix(vr::Eye::Right, 0.1, 100.));

    print!("\teye_to_head ");
    print_matrix_4x3(8+12, ivr.eye_to_head_transform(vr::Eye::Left));

    print!("\tposes ");
    print_matrix_4x3(8+6, ivr.tracked_devices(0.).as_slice()[0].to_device);

    println!("Distortion example");
    for u in 0..2 {
        for v in 0..2 {
            let pos = ivr.compute_distortion(
                vr::Eye::Left,
                u as f32 / 4.,
                v as f32 / 4.,
            );
            print!("\t({:2.4}, {:2.4}) ", pos.red[0], pos.red[1]);
        }
        println!("");
    }

    println!("Trying to create a compositor");
    match ivr.compositor() {
        Err(err) => println!("Could not create compositor {:?}", err),
        Ok(comp) => {
            println!("\tCreated one!");
            println!("\tis fullscreen    = {}", comp.is_fullscreen());
            println!("\tis vsync         = {}", comp.get_vsync());
            println!("\tcan render scene = {}", comp.can_render_scene());
            println!("\tgamma value      = {}", comp.get_gamma());
        }
    }

    println!("Done! \\o/");

}
<commit_msg>fixed lib name 3<commit_after>extern crate openvr;

fn print_matrix_4x4(offset: u32, mat: [[f32; 4]; 4]) {
    let off: String = (0..offset).map(|_| ' ').collect();
    println!("{:?}",        mat[0]);
    println!("{}{:?}", off, mat[1]);
    println!("{}{:?}", off, mat[2]);
    println!("{}{:?}", off, mat[3]);
}

fn print_matrix_4x3(offset: u32, mat: [[f32; 4]; 3]) {
    let off: String = (0..offset).map(|_| ' ').collect();
    println!("{:?}",        mat[0]);
    println!("{}{:?}", off, mat[1]);
    println!("{}{:?}", off, mat[2]);
}

fn main() {
    let ivr = match openvr::IVRSystem::init() {
        Ok(ivr) => ivr,
        Err(err) => {
            println!("Failed to create IVR subsystem {:?}", err);
            return;
        }
    };

    println!("IVR was created");
    println!("\tbounds: {:?}", ivr.bounds());
    println!("\trecommended size: {:?}", ivr.recommended_render_target_size());
    println!("\teye output: {:?} {:?}", ivr.eye_viewport(openvr::Eye::Left), ivr.eye_viewport(openvr::Eye::Right));
    println!("\tvsync: {:?}", ivr.time_since_last_vsync());

    print!("\tprojection matrix left  ");
    print_matrix_4x4(31, ivr.projection_matrix(openvr::Eye::Left, 0.1, 100.));
    print!("\tprojection matrix right ");
    print_matrix_4x4(31, ivr.projection_matrix(openvr::Eye::Right, 0.1, 100.));

    print!("\teye_to_head ");
    print_matrix_4x3(8+12, ivr.eye_to_head_transform(openvr::Eye::Left));

    print!("\tposes ");
    print_matrix_4x3(8+6, ivr.tracked_devices(0.).as_slice()[0].to_device);

    println!("Distortion example");
    for u in 0..2 {
        for v in 0..2 {
            let pos = ivr.compute_distortion(
                openvr::Eye::Left,
                u as f32 / 4.,
                v as f32 / 4.,
            );
            print!("\t({:2.4}, {:2.4}) ", pos.red[0], pos.red[1]);
        }
        println!("");
    }

    println!("Trying to create a compositor");
    match ivr.compositor() {
        Err(err) => println!("Could not create compositor {:?}", err),
        Ok(comp) => {
            println!("\tCreated one!");
            println!("\tis fullscreen    = {}", comp.is_fullscreen());
            println!("\tis vsync         = {}", comp.get_vsync());
            println!("\tcan render scene = {}", comp.can_render_scene());
            println!("\tgamma value      = {}", comp.get_gamma());
        }
    }

    println!("Done! \\o/");

}
<|endoftext|>


<commit_before>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<AvlNodeId>, // ID for left node
    right: Option<AvlNodeId>, // ID for right node
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T>(&self, avl: &'a Avl<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }

    pub fn get_mut<'a, T>(&self, avl: &'a mut Avl<T>) -> Option<&'a mut AvlNode<T>> {
        avl.nodes
           .get_mut(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_mut()
               } else {
                   None
               }
           })
    }
}

pub struct Avl<T> {
    root: usize, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T> Avl<T> {
    pub fn new() -> Self {
        Avl {
            root: 0,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    pub fn insert(&mut self, value: T) -> AvlNodeId {
        // TODO this is just a placeholder, we need to deal with all the fancy rotation stuff that
        // AVL trees do
        self.allocate_node(value)
    }

    // Performs a left rotation on a tree/subtree.
    fn rotate_left(&mut self, node: &mut AvlNodeId) {
        // Keep track of the original node positions
        // For a rotate left, the right child node must exist
        let mut original = *node;
        let r = node.get(self).unwrap().right.unwrap();
        let rl = r.get(self).unwrap().left;

        *node = r;
        original.get_mut(self).unwrap().right = rl;
        node.get_mut(self).unwrap().left = Some(original);
    }

    // Performs a right rotation on a tree/subtree.
    fn rotate_right(&mut self, node: &mut AvlNodeId) {
        // Keep track of the original node positions
        // For a rotate right, the left child node must exist
        let mut original = *node;
        let l = original.get(self).unwrap().left.unwrap();
        let lr = l.get(self).unwrap().right;

        *node = l;
        original.get_mut(self).unwrap().left = lr;
        node.get_mut(self).unwrap().right = Some(original);
    }

    // performs a left-right double rotation on a tree/subtree.
    fn rotate_leftright(&mut self, node: &mut AvlNodeId) {
        self.rotate_left(node.get_mut(self).unwrap().left.as_mut().unwrap()); // Left node needs to exist
        self.rotate_right(node);
    }

    // performs a right-left double rotation on a tree/subtree.
    fn rotate_rightleft(&mut self, node: &mut AvlNodeId) {
        self.rotate_right(node.get_mut(self).unwrap().right.as_mut().unwrap()); // Right node needs to exist
        self.rotate_left(node);
    }

    // _ins is the implementation of the binary tree insert function. Lesser values will be stored on
    // the left, while greater values will be stored on the right. No duplicates are allowed.
    /*fn _ins(int n, Node*& node) {
        if (!node) {
            // The node doesn't exist, create it here.

            node = new Node;
            node->val = n;
            node->left = 0;
            node->right = 0;
        }
        else
        {
            // Node exists, check which way to branch.

            if (n == node->val)
                return;
            else if (n < node->val)
                _ins(n, node->left);
            else if (n > node->val)
                _ins(n, node->right);
        }

        rebalance(node);
    }

    // _rebalance rebalances the provided node
    fn rebalance(Node*& node) {
        if (!node)
        {
            return;
        }

        int balance = _height(node->left) - _height(node->right);
        if (balance == 2) // left
        {
            int lbalance = _height(node->left->left) - _height(node->left->right);
            if (lbalance == 0 || lbalance == 1) // left left - need to rotate right
            {
                rotate_right(node);
            }
            else if (lbalance == -1) // left right
            {
                rotate_leftright(node); // function name is just a coincidence
            }
        }
        else if (balance == -2) // right
        {
            int rbalance = _height(node->right->left) - _height(node->right->right);
            if (rbalance == 1) // right left
            {
                rotate_rightleft(node); // function name is just a coincidence
            }
            else if (rbalance == 0 || rbalance == -1) // right right - need to rotate left
            {
                rotate_left(node);
            }
        }
    }

    // _height gets the height of a tree or subtree
    fn _height(node: AvlNodeId) -> usize {
        if (!node)
            return -1;

        int left_height = _height(node->left);
        int right_height = _height(node->right);

        if (left_height > right_height)
            return left_height+1;
        else
            return right_height+1;
    }*/

    fn allocate_node(&mut self, value: T) -> AvlNodeId {
        match self.free_list.pop() {
            Some(index) => {
                AvlNodeId { time_stamp: self.nodes[index].time_stamp+1, index: index }
            },
            None => {
                // No free slots, create a new one
                let id = AvlNodeId { index: self.nodes.len(), time_stamp: 0 };
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                id
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<commit_msg>Finished rotations<commit_after>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<AvlNodeId>, // ID for left node
    right: Option<AvlNodeId>, // ID for right node
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T>(&self, avl: &'a Avl<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }

    pub fn get_mut<'a, T>(&self, avl: &'a mut Avl<T>) -> Option<&'a mut AvlNode<T>> {
        avl.nodes
           .get_mut(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_mut()
               } else {
                   None
               }
           })
    }
}

pub struct Avl<T> {
    root: usize, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T> Avl<T> {
    pub fn new() -> Self {
        Avl {
            root: 0,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    pub fn insert(&mut self, value: T) -> AvlNodeId {
        // TODO this is just a placeholder, we need to deal with all the fancy rotation stuff that
        // AVL trees do
        self.allocate_node(value)
    }

    // Performs a left rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_left(&mut self, node: AvlNodeId) -> AvlNodeId {
        // Keep track of the original node positions
        // For a rotate left, the right child node must exist
        let r = node.get(self).unwrap().right.unwrap();
        let rl = r.get(self).unwrap().left;

        let ret = r;
        node.get_mut(self).unwrap().right = rl;
        ret.get_mut(self).unwrap().left = Some(node);

        ret
    }

    // Performs a right rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_right(&mut self, node: AvlNodeId) -> AvlNodeId {
        // Keep track of the original node positions
        // For a rotate right, the left child node must exist
        let l = node.get(self).unwrap().left.unwrap();
        let lr = l.get(self).unwrap().right;

        let ret = l;
        node.get_mut(self).unwrap().left = lr;
        ret.get_mut(self).unwrap().right = Some(node);

        ret
    }

    // performs a left-right double rotation on a tree/subtree.
    fn rotate_leftright(&mut self, node: AvlNodeId) -> AvlNodeId {
        let l = node.get(self).unwrap().left.unwrap();
        let new_l = self.rotate_left(l); // Left node needs to exist
        node.get_mut(self).unwrap().left = Some(new_l);
        self.rotate_right(node)
    }

    // performs a right-left double rotation on a tree/subtree.
    fn rotate_rightleft(&mut self, node: AvlNodeId) -> AvlNodeId {
        let r = node.get(self).unwrap().right.unwrap();
        let new_r = self.rotate_right(r); // Right node needs to exist
        node.get_mut(self).unwrap().right = Some(new_r);
        self.rotate_left(node)
    }

    // _ins is the implementation of the binary tree insert function. Lesser values will be stored on
    // the left, while greater values will be stored on the right. No duplicates are allowed.
    /*fn _ins(&mut self, node_index: Option<AvlNodeId>, value: T) -> AvlNodeId {
        let node =
            match node_index {
                Some(node) => {
                    // Node exists, check which way to branch.
                    if n == node->val {
                        return node;
                    else if (n < node->val)
                        _ins(n, node->left);
                    else if (n > node->val)
                        _ins(n, node->right);
                },
                None => {
                    // The node doesn't exist, create it here.
                    self.allocate_node(value)
                },
            };

        rebalance(node);
    }*/

    // _rebalance rebalances the provided node
    /*fn rebalance(Node*& node) {
        if (!node)
        {
            return;
        }

        int balance = _height(node->left) - _height(node->right);
        if (balance == 2) // left
        {
            int lbalance = _height(node->left->left) - _height(node->left->right);
            if (lbalance == 0 || lbalance == 1) // left left - need to rotate right
            {
                rotate_right(node);
            }
            else if (lbalance == -1) // left right
            {
                rotate_leftright(node); // function name is just a coincidence
            }
        }
        else if (balance == -2) // right
        {
            int rbalance = _height(node->right->left) - _height(node->right->right);
            if (rbalance == 1) // right left
            {
                rotate_rightleft(node); // function name is just a coincidence
            }
            else if (rbalance == 0 || rbalance == -1) // right right - need to rotate left
            {
                rotate_left(node);
            }
        }
    }

    // _height gets the height of a tree or subtree
    fn _height(node: AvlNodeId) -> usize {
        if (!node)
            return -1;

        int left_height = _height(node->left);
        int right_height = _height(node->right);

        if (left_height > right_height)
            return left_height+1;
        else
            return right_height+1;
    }*/

    fn allocate_node(&mut self, value: T) -> AvlNodeId {
        match self.free_list.pop() {
            Some(index) => {
                AvlNodeId { time_stamp: self.nodes[index].time_stamp+1, index: index }
            },
            None => {
                // No free slots, create a new one
                let id = AvlNodeId { index: self.nodes.len(), time_stamp: 0 };
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                id
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate quote;
extern crate reqwest;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use std::fs::File;
use serde_json::{ Value, Map };
use std::collections::HashSet;

mod util;

use util::*;

pub enum SampleSource<'a> {
    Url(&'a str),
    File(&'a str),
    Text(&'a str),
}

#[derive(Debug)]
pub enum CodeGenError {
    ReqwestError(reqwest::Error),
    JsonError(serde_json::Error),
    IoError(std::io::Error),
    MissingSource,
    ExistingType(String)
}

impl From<reqwest::Error> for CodeGenError {
    fn from(err: reqwest::Error) -> Self {
        CodeGenError::ReqwestError(err)
    }
}

impl From<serde_json::Error> for CodeGenError {
    fn from(err: serde_json::Error) -> Self {
        CodeGenError::JsonError(err)
    }
}

impl From<std::io::Error> for CodeGenError {
    fn from(err: std::io::Error) -> Self {
        CodeGenError::IoError(err)
    }
}

pub fn codegen_from_sample(name: &str, source: SampleSource) -> Result<quote::Tokens, CodeGenError> {
    let value = get_sample(source)?;
    let (type_name, type_def) = generate_type_from_value(name, &value);

    match type_def {
        Some(tokens) => Ok(tokens),
        None => Err(CodeGenError::ExistingType(String::from(type_name.as_str())))
    }
}

fn generate_type_from_value(path: &str, value: &Value) -> (quote::Tokens, Option<quote::Tokens>) {
    match *value {
        Value::Null => (quote!{ Option<::serde_json::Value> }, None),
        Value::Bool(_) => (quote!{ bool }, None),
        Value::Number(ref n) => {
            if n.is_i64() {
                (quote!{ i64 }, None)
            } else {
                (quote!{ f64 }, None)
            }
        },
        Value::String(_) => (quote!{ String }, None),
        Value::Array(ref values) => {
            generate_type_for_array(path, values)
        },
        Value::Object(ref map) => {
            generate_struct_from_object(path, map)
        }
    }
}

fn generate_type_for_array(path: &str, values: &Vec<Value>) -> (quote::Tokens, Option<quote::Tokens>) {
    let mut defs = Vec::new();
    let mut types = HashSet::new();

    for value in values.iter() {
        let (elemtype, elemtype_def) = generate_type_from_value(path, value);
        types.insert(elemtype.into_string());
        if let Some(def) = elemtype_def {
            defs.push(def);
        }
    }

    if types.len() == 1 {
        let ident = quote::Ident::new(types.into_iter().next().unwrap());
        (quote! { Vec<#ident> }, defs.into_iter().next())
    } else {
        (quote! { Vec<::serde_json::Value> }, None)
    }
}

fn generate_struct_from_object(path: &str, map: &Map<String, Value>) -> (quote::Tokens, Option<quote::Tokens>) {
    let type_name = type_case(path);
    let ident = quote::Ident::new(&type_name as &str);
    let mut defs = Vec::new();

    let fields: Vec<quote::Tokens> = map.iter()
        .map(|(name, value)| {
            let field_name = snake_case(name);
            let field_ident = quote::Ident::new(&field_name as &str);
            let (fieldtype, fieldtype_def) = generate_type_from_value(name, value);
            if let Some(def) = fieldtype_def {
                defs.push(def);
            }
            quote! {
                #field_ident: #fieldtype
            }
        })
        .collect();

    let code = quote! {
        struct #ident {
            #(#fields),*
        }

        #(#defs)*
    };

    (quote! { #ident }, Some(code))
}

fn get_sample(source: SampleSource) -> Result<Value, CodeGenError> {
    let parse_result = match source {
        SampleSource::Url(url) => serde_json::de::from_reader(reqwest::get(url)?),
        SampleSource::File(path) => serde_json::de::from_reader(File::open(path)?),
        SampleSource::Text(text) => serde_json::from_str(text),
    };
    parse_result.map_err(CodeGenError::JsonError)
}
<commit_msg>shared: Add Options and Ctxt, and thread context<commit_after>#[macro_use]
extern crate quote;
extern crate reqwest;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use std::fs::File;
use serde_json::{ Value, Map };
use std::collections::HashSet;

mod util;

use util::*;

pub enum SampleSource<'a> {
    Url(&'a str),
    File(&'a str),
    Text(&'a str),
}

#[derive(Debug)]
pub enum CodeGenError {
    ReqwestError(reqwest::Error),
    JsonError(serde_json::Error),
    IoError(std::io::Error),
    MissingSource,
    ExistingType(String)
}

impl From<reqwest::Error> for CodeGenError {
    fn from(err: reqwest::Error) -> Self {
        CodeGenError::ReqwestError(err)
    }
}

impl From<serde_json::Error> for CodeGenError {
    fn from(err: serde_json::Error) -> Self {
        CodeGenError::JsonError(err)
    }
}

impl From<std::io::Error> for CodeGenError {
    fn from(err: std::io::Error) -> Self {
        CodeGenError::IoError(err)
    }
}

pub struct Options {
    use_serde: bool
}

impl Default for Options {
    fn default() -> Options {
        Options {
            use_serde: true
        }
    }
}

struct Ctxt {
    options: Options
}

pub fn codegen_from_sample(name: &str, source: SampleSource) -> Result<quote::Tokens, CodeGenError> {
    let sample = get_and_parse_sample(source)?;
    let mut ctxt = Ctxt {
        options: Options::default()
    };
    let (type_name, type_def) = generate_type_from_value(&mut ctxt, name, &sample);

    match type_def {
        Some(tokens) => Ok(tokens),
        None => Err(CodeGenError::ExistingType(String::from(type_name.as_str())))
    }
}

fn generate_type_from_value(ctxt: &mut Ctxt, path: &str, value: &Value) -> (quote::Tokens, Option<quote::Tokens>) {
    match *value {
        Value::Null => (quote!{ Option<::serde_json::Value> }, None),
        Value::Bool(_) => (quote!{ bool }, None),
        Value::Number(ref n) => {
            if n.is_i64() {
                (quote!{ i64 }, None)
            } else {
                (quote!{ f64 }, None)
            }
        },
        Value::String(_) => (quote!{ String }, None),
        Value::Array(ref values) => {
            generate_type_for_array(ctxt, path, values)
        },
        Value::Object(ref map) => {
            generate_struct_from_object(ctxt, path, map)
        }
    }
}

fn generate_type_for_array(ctxt: &mut Ctxt, path: &str, values: &Vec<Value>) -> (quote::Tokens, Option<quote::Tokens>) {
    let mut defs = Vec::new();
    let mut types = HashSet::new();

    for value in values.iter() {
        let (elemtype, elemtype_def) = generate_type_from_value(ctxt, path, value);
        types.insert(elemtype.into_string());
        if let Some(def) = elemtype_def {
            defs.push(def);
        }
    }

    if types.len() == 1 {
        let ident = quote::Ident::new(types.into_iter().next().unwrap());
        (quote! { Vec<#ident> }, defs.into_iter().next())
    } else {
        (quote! { Vec<::serde_json::Value> }, None)
    }
}

fn generate_struct_from_object(ctxt: &mut Ctxt, path: &str, map: &Map<String, Value>) -> (quote::Tokens, Option<quote::Tokens>) {
    let type_name = type_case(path);
    let ident = quote::Ident::new(&type_name as &str);
    let mut defs = Vec::new();

    let fields: Vec<quote::Tokens> = map.iter()
        .map(|(name, value)| {
            let field_name = snake_case(name);
            let field_ident = quote::Ident::new(&field_name as &str);
            let (fieldtype, fieldtype_def) = generate_type_from_value(ctxt, name, value);
            if let Some(def) = fieldtype_def {
                defs.push(def);
            }
            quote! {
                #field_ident: #fieldtype
            }
        })
        .collect();

    let derives = if ctxt.options.use_serde {
        quote! { #[derive(Debug, Clone, Serialize, Deserialize)] }
    } else {
        quote! { #[derive(Debug, Clone)] }
    };

    let code = quote! {
        #derives
        struct #ident {
            #(#fields),*
        }

        #(#defs)*
    };

    (quote! { #ident }, Some(code))
}

fn get_and_parse_sample(source: SampleSource) -> Result<Value, CodeGenError> {
    let parse_result = match source {
        SampleSource::Url(url) => serde_json::de::from_reader(reqwest::get(url)?),
        SampleSource::File(path) => serde_json::de::from_reader(File::open(path)?),
        SampleSource::Text(text) => serde_json::from_str(text),
    };
    parse_result.map_err(CodeGenError::JsonError)
}
<|endoftext|>


<commit_before>//! User access tokens.

use base64::u8en;
use chrono::{Duration, UTC};
use diesel::{LoadDsl, insert};
use diesel::pg::PgConnection;
use diesel::pg::data_types::PgTimestamp;
use macaroons::caveat::{Caveat, Predicate};
use macaroons::token::Token;

use error::APIError;
use schema::access_tokens;

/// A User access token.
#[derive(Debug, Queryable)]
pub struct AccessToken {
    /// The access token's ID.
    pub id: i64,
    /// The ID of the user who owns the access token.
    pub user_id: String,
    /// The value of the access token. This is a macaroon.
    pub value: String,
    /// The time the access token was created.
    pub created_at: PgTimestamp,
}

/// A new access token, not yet saved.
#[derive(Debug)]
#[insertable_into(access_tokens)]
pub struct NewAccessToken {
    /// The ID of the user who owns the access token.
    pub user_id: String,
    /// The value of the access token. This is a macaroon.
    pub value: String,
}

/// Create a new access token for the given user.
pub fn create_access_token(
    connection: &PgConnection,
    user_id: &str,
    macaroon_secret_key: &Vec<u8>,
) -> Result<AccessToken, APIError> {
    let new_access_token = NewAccessToken {
        user_id: user_id.to_string(),
        value: try!(create_macaroon(macaroon_secret_key, user_id)),
    };

    insert(&new_access_token)
        .into(access_tokens::table)
        .get_result(connection)
        .map_err(APIError::from)
}

fn create_macaroon(macaroon_secret_key: &Vec<u8>, user_id: &str) -> Result<String, APIError> {
    let expiration = match UTC::now().checked_add(Duration::hours(1)) {
        Some(datetime) => datetime,
        None => return Err(APIError::unknown_from_string(
            "Failed to generate access token expiration datetime.".to_string()
        )),
    };

    let token = Token::new(macaroon_secret_key, "key".as_bytes().to_owned(), vec![])
        .add_caveat(&Caveat::first_party(Predicate(
            format!("user_id = {}", user_id).as_bytes().to_owned()
        )))
        .add_caveat(&Caveat::first_party(Predicate("type = access".as_bytes().to_owned())))
        .add_caveat(&Caveat::first_party(Predicate(
            format!("time < {}", expiration).as_bytes().to_owned()
        )));

    let serialized = token.serialize();
    let encoded = try!(u8en(&serialized));

    String::from_utf8(encoded).map_err(APIError::from)
}
<commit_msg>Document that macaroons are stored in the DB Base64-encoded.<commit_after>//! User access tokens.

use base64::u8en;
use chrono::{Duration, UTC};
use diesel::{LoadDsl, insert};
use diesel::pg::PgConnection;
use diesel::pg::data_types::PgTimestamp;
use macaroons::caveat::{Caveat, Predicate};
use macaroons::token::Token;

use error::APIError;
use schema::access_tokens;

/// A User access token.
#[derive(Debug, Queryable)]
pub struct AccessToken {
    /// The access token's ID.
    pub id: i64,
    /// The ID of the user who owns the access token.
    pub user_id: String,
    /// The value of the access token. This is a Base64-encoded macaroon.
    pub value: String,
    /// The time the access token was created.
    pub created_at: PgTimestamp,
}

/// A new access token, not yet saved.
#[derive(Debug)]
#[insertable_into(access_tokens)]
pub struct NewAccessToken {
    /// The ID of the user who owns the access token.
    pub user_id: String,
    /// The value of the access token. This is a Base64-encoded macaroon.
    pub value: String,
}

/// Create a new access token for the given user.
pub fn create_access_token(
    connection: &PgConnection,
    user_id: &str,
    macaroon_secret_key: &Vec<u8>,
) -> Result<AccessToken, APIError> {
    let new_access_token = NewAccessToken {
        user_id: user_id.to_string(),
        value: try!(create_macaroon(macaroon_secret_key, user_id)),
    };

    insert(&new_access_token)
        .into(access_tokens::table)
        .get_result(connection)
        .map_err(APIError::from)
}

fn create_macaroon(macaroon_secret_key: &Vec<u8>, user_id: &str) -> Result<String, APIError> {
    let expiration = match UTC::now().checked_add(Duration::hours(1)) {
        Some(datetime) => datetime,
        None => return Err(APIError::unknown_from_string(
            "Failed to generate access token expiration datetime.".to_string()
        )),
    };

    let token = Token::new(macaroon_secret_key, "key".as_bytes().to_owned(), vec![])
        .add_caveat(&Caveat::first_party(Predicate(
            format!("user_id = {}", user_id).as_bytes().to_owned()
        )))
        .add_caveat(&Caveat::first_party(Predicate("type = access".as_bytes().to_owned())))
        .add_caveat(&Caveat::first_party(Predicate(
            format!("time < {}", expiration).as_bytes().to_owned()
        )));

    let serialized = token.serialize();
    let encoded = try!(u8en(&serialized));

    String::from_utf8(encoded).map_err(APIError::from)
}
<|endoftext|>