<commit_before>// Copyright 2014-2015 Johannes Köster, Vadim Nazarov, Patrick Marks
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Various alignment and distance computing algorithms.

use utils::TextSlice;

pub mod pairwise;
pub mod distance;

/// Alignment operations (Match, Subst, Del and Ins).
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum AlignmentOperation {
    Match,
    Subst,
    Del,
    Ins,
}

/// An alignment, consisting of a score, the start and end position of the alignment on
/// sequence x and sequence y, the length of sequence x,
/// and the alignment edit operations (see `alignment::pairwise` for meaning of x and y).
#[derive(Debug)]
pub struct Alignment {
    pub score: i32,
    pub ystart: usize,
    pub xstart: usize,
    pub yend: usize,
    pub xend: usize,
    pub xlen: usize,
    pub operations: Vec<AlignmentOperation>,
}

impl Alignment {
    /// Calculate the cigar string.
    pub fn cigar(&self, hard_clip: bool) -> String {
        let add_op = |op, k, cigar: &mut String| {
            cigar.push_str(&format!("{}{}",
                                    k,
                                    match op {
                                        AlignmentOperation::Match => "=",
                                        AlignmentOperation::Subst => "X",
                                        AlignmentOperation::Del => "D",
                                        AlignmentOperation::Ins => "I",
                                    }));
        };

        let op_len = |op: AlignmentOperation| {
            (op == AlignmentOperation::Match || op == AlignmentOperation::Subst ||
             op == AlignmentOperation::Ins) as usize
        };

        let clip_str = if hard_clip { "H" } else { "S" };

        let mut cigar = String::new();

        if self.operations.is_empty() {
            cigar.push_str(&format!("{}{}", self.xlen, clip_str));
        } else {
            if self.xstart > 0 {
                cigar.push_str(&format!("{}{}", self.xstart, clip_str));
            }

            let mut last = self.operations[0];
            let mut k = 1;
            let mut alen = op_len(last);
            for &op in self.operations[1..].iter() {
                if op == last {
                    k += 1;
                } else {
                    add_op(last, k, &mut cigar);
                    k = 1;
                }
                last = op;
                alen += op_len(op);
            }
            add_op(last, k, &mut cigar);

            let clip = self.xlen - alen;
            if clip > 0 {
                cigar.push_str(&format!("{}{}", clip, clip_str));
            }
        }

        cigar
    }

    /// Return the pretty formatted alignment as a String.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alignment::pairwise::*;
    ///
    /// let x = b"CCGTCCGGCAA";
    /// let y = b"AAAAACCGTTGACGCAA";
    /// let score = |a: u8, b: u8| if a == b {1i32} else {-1i32};
    ///
    /// // ------CCGTCCGGCAA
    /// //       |  |   ||||
    /// // AAAAACCGTTGACGCAA
    /// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, &score);
    /// let alignment = aligner.semiglobal(x, y);
    /// println!("Semiglobal: \n{}\n", alignment.pretty(x, y));
    ///
    /// // -----CCGTCCGGCAA-
    /// //      ||||
    /// // AAAAACCGTTGACGCAA
    /// let alignment = aligner.local(x, y);
    /// println!("Local: \n{}\n", alignment.pretty(x, y));
    ///
    /// // ------CCGTCCGGCAA
    /// //       |  |   ||||
    /// // AAAAACCGTTGACGCAA
    /// let alignment = aligner.global(x, y);
    /// println!("Global: \n{}\n", alignment.pretty(x, y));
    /// ```
    pub fn pretty(&self, x: TextSlice, y: TextSlice) -> String {
        let mut x_pretty = String::new();
        let mut y_pretty = String::new();
        let mut inb_pretty = String::new();

        if !self.operations.is_empty() {
            let mut x_i: usize = self.xstart;
            let mut y_i: usize = self.ystart;

            // Add '-' before aligned subsequences and un-aligned 5' substrings of sequences.
            if x_i > y_i {
                let diff = x_i - y_i;
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                for _ in 0..diff {
                    y_pretty.push('-');
                }
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..y_i])));
            } else if x_i < y_i {
                let diff = y_i - x_i;
                for _ in 0..diff {
                    x_pretty.push('-');
                }
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&y[0..y_i])));
            } else {
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&y[0..y_i])));
            }
            for _ in 0..x_pretty.len() {
                inb_pretty.push(' ');
            }

            // Process the alignment.
            for i in 0..self.operations.len() {
                match self.operations[i] {
                    AlignmentOperation::Match => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push_str("|");

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Subst => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push(' ');

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Del => {
                        x_pretty.push('-');

                        inb_pretty.push(' ');

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Ins => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push(' ');

                        y_pretty.push('-');
                    }
                }
            }

            // Add un-aligned 3' substrings of sequences.
            for &item in x.iter().skip(x_i) {
                x_pretty.push_str(&String::from_utf8_lossy(&[item]));
            }
            for &item in y.iter().skip(y_i) {
                y_pretty.push_str(&String::from_utf8_lossy(&[item]));
            }

            // Add trailing '-'.
            if x_pretty.len() > y_pretty.len() {
                for _ in y_pretty.len()..x_pretty.len() {
                    y_pretty.push('-');
                }
            } else {
                for _ in x_pretty.len()..y_pretty.len() {
                    x_pretty.push('-');
                }
            }
        }

        format!("{}\n{}\n{}", x_pretty, inb_pretty, y_pretty)
    }
}

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

    #[test]
    fn test_cigar() {
        let alignment = Alignment {
            score: 5,
            xstart: 3,
            ystart: 0,
            xend: 10,
            yend: 10,
            xlen: 10,
            operations: vec![Match, Match, Match, Subst, Ins, Ins, Del, Del],
        };
        assert_eq!(alignment.cigar(false), "3S3=1X2I2D4S");
    }
}
<commit_msg>Clarify which sequence is reference for Del and Ins (#149)<commit_after>// Copyright 2014-2015 Johannes Köster, Vadim Nazarov, Patrick Marks
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Various alignment and distance computing algorithms.

use utils::TextSlice;

pub mod pairwise;
pub mod distance;

/// Alignment operations (Match, Subst, Del and Ins).
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum AlignmentOperation {
    Match,
    Subst,
    Del,
    Ins,
}

/// An alignment, consisting of a score, the start and end position of the alignment on
/// sequence x and sequence y, the length of sequence x,
/// and the alignment edit operations (see `alignment::pairwise` for meaning of x and y).
///
/// The `Del` edit operation corresponds to a gap in the sequence x, while the `Ins`
/// edit operation corresponds to a gap in the sequence y.
#[derive(Debug)]
pub struct Alignment {
    pub score: i32,
    pub ystart: usize,
    pub xstart: usize,
    pub yend: usize,
    pub xend: usize,
    pub xlen: usize,
    pub operations: Vec<AlignmentOperation>,
}

impl Alignment {
    /// Calculate the cigar string.
    pub fn cigar(&self, hard_clip: bool) -> String {
        let add_op = |op, k, cigar: &mut String| {
            cigar.push_str(&format!("{}{}",
                                    k,
                                    match op {
                                        AlignmentOperation::Match => "=",
                                        AlignmentOperation::Subst => "X",
                                        AlignmentOperation::Del => "D",
                                        AlignmentOperation::Ins => "I",
                                    }));
        };

        let op_len = |op: AlignmentOperation| {
            (op == AlignmentOperation::Match || op == AlignmentOperation::Subst ||
             op == AlignmentOperation::Ins) as usize
        };

        let clip_str = if hard_clip { "H" } else { "S" };

        let mut cigar = String::new();

        if self.operations.is_empty() {
            cigar.push_str(&format!("{}{}", self.xlen, clip_str));
        } else {
            if self.xstart > 0 {
                cigar.push_str(&format!("{}{}", self.xstart, clip_str));
            }

            let mut last = self.operations[0];
            let mut k = 1;
            let mut alen = op_len(last);
            for &op in self.operations[1..].iter() {
                if op == last {
                    k += 1;
                } else {
                    add_op(last, k, &mut cigar);
                    k = 1;
                }
                last = op;
                alen += op_len(op);
            }
            add_op(last, k, &mut cigar);

            let clip = self.xlen - alen;
            if clip > 0 {
                cigar.push_str(&format!("{}{}", clip, clip_str));
            }
        }

        cigar
    }

    /// Return the pretty formatted alignment as a String.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alignment::pairwise::*;
    ///
    /// let x = b"CCGTCCGGCAA";
    /// let y = b"AAAAACCGTTGACGCAA";
    /// let score = |a: u8, b: u8| if a == b {1i32} else {-1i32};
    ///
    /// // ------CCGTCCGGCAA
    /// //       |  |   ||||
    /// // AAAAACCGTTGACGCAA
    /// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, &score);
    /// let alignment = aligner.semiglobal(x, y);
    /// println!("Semiglobal: \n{}\n", alignment.pretty(x, y));
    ///
    /// // -----CCGTCCGGCAA-
    /// //      ||||
    /// // AAAAACCGTTGACGCAA
    /// let alignment = aligner.local(x, y);
    /// println!("Local: \n{}\n", alignment.pretty(x, y));
    ///
    /// // ------CCGTCCGGCAA
    /// //       |  |   ||||
    /// // AAAAACCGTTGACGCAA
    /// let alignment = aligner.global(x, y);
    /// println!("Global: \n{}\n", alignment.pretty(x, y));
    /// ```
    pub fn pretty(&self, x: TextSlice, y: TextSlice) -> String {
        let mut x_pretty = String::new();
        let mut y_pretty = String::new();
        let mut inb_pretty = String::new();

        if !self.operations.is_empty() {
            let mut x_i: usize = self.xstart;
            let mut y_i: usize = self.ystart;

            // Add '-' before aligned subsequences and un-aligned 5' substrings of sequences.
            if x_i > y_i {
                let diff = x_i - y_i;
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                for _ in 0..diff {
                    y_pretty.push('-');
                }
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..y_i])));
            } else if x_i < y_i {
                let diff = y_i - x_i;
                for _ in 0..diff {
                    x_pretty.push('-');
                }
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&y[0..y_i])));
            } else {
                x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&x[0..x_i])));
                y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&y[0..y_i])));
            }
            for _ in 0..x_pretty.len() {
                inb_pretty.push(' ');
            }

            // Process the alignment.
            for i in 0..self.operations.len() {
                match self.operations[i] {
                    AlignmentOperation::Match => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push_str("|");

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Subst => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push(' ');

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Del => {
                        x_pretty.push('-');

                        inb_pretty.push(' ');

                        y_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[y[y_i]])));
                        y_i += 1;
                    }
                    AlignmentOperation::Ins => {
                        x_pretty.push_str(&format!("{}", String::from_utf8_lossy(&[x[x_i]])));
                        x_i += 1;

                        inb_pretty.push(' ');

                        y_pretty.push('-');
                    }
                }
            }

            // Add un-aligned 3' substrings of sequences.
            for &item in x.iter().skip(x_i) {
                x_pretty.push_str(&String::from_utf8_lossy(&[item]));
            }
            for &item in y.iter().skip(y_i) {
                y_pretty.push_str(&String::from_utf8_lossy(&[item]));
            }

            // Add trailing '-'.
            if x_pretty.len() > y_pretty.len() {
                for _ in y_pretty.len()..x_pretty.len() {
                    y_pretty.push('-');
                }
            } else {
                for _ in x_pretty.len()..y_pretty.len() {
                    x_pretty.push('-');
                }
            }
        }

        format!("{}\n{}\n{}", x_pretty, inb_pretty, y_pretty)
    }
}

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

    #[test]
    fn test_cigar() {
        let alignment = Alignment {
            score: 5,
            xstart: 3,
            ystart: 0,
            xend: 10,
            yend: 10,
            xlen: 10,
            operations: vec![Match, Match, Match, Subst, Ins, Ins, Del, Del],
        };
        assert_eq!(alignment.cigar(false), "3S3=1X2I2D4S");
    }
}
<|endoftext|>


<commit_before>use super::super::super::error::{Result, PathfinderError};

use jsonwebtoken::{decode, TokenData, Validation};

pub const DEFAULT_ISSUER: &'static str = "pathfinder";

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub iss: String,
    pub exp: i64,
}

pub fn validate(token: &str, secret_key: &str, validation_struct: &Validation) -> Result<TokenData<Claims>> {
    match decode::<Claims>(token, secret_key.as_bytes(), &validation_struct) {
        Ok(valid_token) => Ok(valid_token),
        Err(err) => Err(PathfinderError::from(err))
    }
}
<commit_msg>Added documentation for auth/token/jwt.rs<commit_after>//! Wrappers for validating a JSON Web Token
//!

use super::super::super::error::{Result, PathfinderError};

use jsonwebtoken::{decode, TokenData, Validation};

/// A default issuer in JSON Web Token
pub const DEFAULT_ISSUER: &'static str = "pathfinder";

/// A struct with validated fields in JSON Web Token
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub iss: String,
    pub exp: i64,
}

/// Validates a passed token with the certain secret key and a validation structure.
pub fn validate(token: &str, secret_key: &str, validation_struct: &Validation) -> Result<TokenData<Claims>> {
    match decode::<Claims>(token, secret_key.as_bytes(), &validation_struct) {
        Ok(valid_token) => Ok(valid_token),
        Err(err) => Err(PathfinderError::from(err))
    }
}
<|endoftext|>


<commit_before>use std::fmt;

use futures::{Stream, Poll, Async};
use bytes::Bytes;

/// An asynchronous `Stream`.
pub struct Body {
    inner: Inner,
}

enum Inner {
    Reusable(Bytes),
    Hyper(::hyper::Body),
}

impl Body {
    fn poll_inner(&mut self) -> &mut ::hyper::Body {
        match self.inner {
            Inner::Hyper(ref mut body) => body,
            Inner::Reusable(_) => unreachable!(),
        }
    }
}

impl Stream for Body {
    type Item = Chunk;
    type Error = ::Error;

    #[inline]
    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match try_!(self.poll_inner().poll()) {
            Async::Ready(opt) => Ok(Async::Ready(opt.map(|chunk| Chunk {
                inner: chunk,
            }))),
            Async::NotReady => Ok(Async::NotReady),
        }
    }
}

impl From<Bytes> for Body {
    #[inline]
    fn from(bytes: Bytes) -> Body {
        reusable(bytes)
    }
}

impl From<Vec<u8>> for Body {
    #[inline]
    fn from(vec: Vec<u8>) -> Body {
        reusable(vec.into())
    }
}

impl From<String> for Body {
    #[inline]
    fn from(s: String) -> Body {
        reusable(s.into())
    }
}

/// A chunk of bytes for a `Body`.
///
/// A `Chunk` can be treated like `&[u8]`.
#[derive(Default)]
pub struct Chunk {
    inner: ::hyper::Chunk,
}

impl AsRef<[u8]> for Chunk {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        &*self
    }
}

impl ::std::ops::Deref for Chunk {
    type Target = [u8];
    #[inline]
    fn deref(&self) -> &Self::Target {
        self.inner.as_ref()
    }
}

impl Extend<u8> for Chunk {
    fn extend<T>(&mut self, iter: T)
    where T: IntoIterator<Item=u8> {
        self.inner.extend(iter)
    }
}

impl IntoIterator for Chunk {
    type Item = u8;
    //XXX: exposing type from hyper!
    type IntoIter = <::hyper::Chunk as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self.inner.into_iter()
    }
}

impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Body")
            .finish()
    }
}

impl fmt::Debug for Chunk {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

// pub(crate)

#[inline]
pub fn wrap(body: ::hyper::Body) -> Body {
    Body {
        inner: Inner::Hyper(body),
    }
}

#[inline]
pub fn take(body: &mut Body) -> Body {
    use std::mem;
    let inner = mem::replace(&mut body.inner, Inner::Hyper(::hyper::Body::empty()));
    Body {
        inner: inner,
    }
}

#[inline]
pub fn empty() -> Body {
    Body {
        inner: Inner::Hyper(::hyper::Body::empty()),
    }
}

#[inline]
pub fn chunk(chunk: Bytes) -> Chunk {
    Chunk {
        inner: ::hyper::Chunk::from(chunk)
    }
}

#[inline]
pub fn reusable(chunk: Bytes) -> Body {
    Body {
        inner: Inner::Reusable(chunk),
    }
}

#[inline]
pub fn into_hyper(body: Body) -> (Option<Bytes>, ::hyper::Body) {
    match body.inner {
        Inner::Reusable(chunk) => (Some(chunk.clone()), chunk.into()),
        Inner::Hyper(b) => (None, b),
    }
}
<commit_msg>async: Add conversions from static slices to Body<commit_after>use std::fmt;

use futures::{Stream, Poll, Async};
use bytes::Bytes;

/// An asynchronous `Stream`.
pub struct Body {
    inner: Inner,
}

enum Inner {
    Reusable(Bytes),
    Hyper(::hyper::Body),
}

impl Body {
    fn poll_inner(&mut self) -> &mut ::hyper::Body {
        match self.inner {
            Inner::Hyper(ref mut body) => body,
            Inner::Reusable(_) => unreachable!(),
        }
    }
}

impl Stream for Body {
    type Item = Chunk;
    type Error = ::Error;

    #[inline]
    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match try_!(self.poll_inner().poll()) {
            Async::Ready(opt) => Ok(Async::Ready(opt.map(|chunk| Chunk {
                inner: chunk,
            }))),
            Async::NotReady => Ok(Async::NotReady),
        }
    }
}

impl From<Bytes> for Body {
    #[inline]
    fn from(bytes: Bytes) -> Body {
        reusable(bytes)
    }
}

impl From<Vec<u8>> for Body {
    #[inline]
    fn from(vec: Vec<u8>) -> Body {
        reusable(vec.into())
    }
}

impl From<&'static [u8]> for Body {
    #[inline]
    fn from(s: &'static [u8]) -> Body {
        reusable(Bytes::from_static(s))
    }
}

impl From<String> for Body {
    #[inline]
    fn from(s: String) -> Body {
        reusable(s.into())
    }
}

impl From<&'static str> for Body {
    #[inline]
    fn from(s: &'static str) -> Body {
        s.as_bytes().into()
    }
}

/// A chunk of bytes for a `Body`.
///
/// A `Chunk` can be treated like `&[u8]`.
#[derive(Default)]
pub struct Chunk {
    inner: ::hyper::Chunk,
}

impl AsRef<[u8]> for Chunk {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        &*self
    }
}

impl ::std::ops::Deref for Chunk {
    type Target = [u8];
    #[inline]
    fn deref(&self) -> &Self::Target {
        self.inner.as_ref()
    }
}

impl Extend<u8> for Chunk {
    fn extend<T>(&mut self, iter: T)
    where T: IntoIterator<Item=u8> {
        self.inner.extend(iter)
    }
}

impl IntoIterator for Chunk {
    type Item = u8;
    //XXX: exposing type from hyper!
    type IntoIter = <::hyper::Chunk as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self.inner.into_iter()
    }
}

impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Body")
            .finish()
    }
}

impl fmt::Debug for Chunk {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

// pub(crate)

#[inline]
pub fn wrap(body: ::hyper::Body) -> Body {
    Body {
        inner: Inner::Hyper(body),
    }
}

#[inline]
pub fn take(body: &mut Body) -> Body {
    use std::mem;
    let inner = mem::replace(&mut body.inner, Inner::Hyper(::hyper::Body::empty()));
    Body {
        inner: inner,
    }
}

#[inline]
pub fn empty() -> Body {
    Body {
        inner: Inner::Hyper(::hyper::Body::empty()),
    }
}

#[inline]
pub fn chunk(chunk: Bytes) -> Chunk {
    Chunk {
        inner: ::hyper::Chunk::from(chunk)
    }
}

#[inline]
pub fn reusable(chunk: Bytes) -> Body {
    Body {
        inner: Inner::Reusable(chunk),
    }
}

#[inline]
pub fn into_hyper(body: Body) -> (Option<Bytes>, ::hyper::Body) {
    match body.inner {
        Inner::Reusable(chunk) => (Some(chunk.clone()), chunk.into()),
        Inner::Hyper(b) => (None, b),
    }
}
<|endoftext|>


<commit_before>
// silence warnings while still a WIP
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_imports)]

use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::cell::{Cell, RefCell};
use std::ops::{Index, IndexMut};

// Pythonesque Counter implementation
// XXX Move to a separate module
static ZERO: usize = 0;
pub struct Counter<T: Hash + Eq + Clone> {
    pub map: HashMap<T, Cell<usize>>,
}
impl<T: Hash + Eq + Clone> Counter<T> {
    pub fn new() -> Self {
        Counter { map: HashMap::new() }
    }
    pub fn len(&self) -> usize {
        self.map.len()
    }
    pub fn remove(&mut self, idx: &T) {
        self.map.remove(idx);
    }
}
impl<T: Hash + Eq + Clone> Index<T> for Counter<T> {
    type Output = usize;
    fn index(&self, idx: T) -> &Self::Output {
        if self.map.contains_key(&idx) {
            let cntp = self.map[&idx].as_ptr();
            unsafe { &*cntp }
        } else {
            //map.insert(idx, Cell::new(0));
            //let mut cntp = map[&idx].as_ptr();
            //unsafe {& *cntp}
            &ZERO
        }
    }
}
impl<T: Hash + Eq + Clone> IndexMut<T> for Counter<T> {
    fn index_mut(&mut self, idx: T) -> &mut Self::Output {
        if self.map.contains_key(&idx) {
            let cntp = self.map[&idx].as_ptr();
            unsafe { &mut *cntp }
        } else {
            self.map.insert(idx.clone(), Cell::new(0));
            let cntp = self.map[&idx].as_ptr();
            unsafe { &mut *cntp }
        }
    }
}

#[allow(non_snake_case)]
pub mod ExecutionEngine {
    use autograd::{Variable, Function, FuncId, FuncIntf, RootKind, VarId};
    use tensor::{Tensor, TensorKind, TensorKindList};
    use std::collections::{HashSet, HashMap, VecDeque};
    use std::cell::RefCell;
    use itertools;
    use super::Counter;

    type FnRefs = RefCell<Vec<Counter<FuncId>>>;
    type FnDependencies = HashMap<FuncId, FnRefs>;

    fn fn_ref_init(count: usize) -> FnRefs {
        let mut v = Vec::new();
        for _ in 0..count {
            v.push(Counter::new())
        }
        RefCell::new(v)
    }

    fn _compute_dependencies(function: &Function) -> FnDependencies {
        let mut dependencies = FnDependencies::new();
        let mut seen: HashSet<FuncId> = HashSet::new();
        let mut queue = VecDeque::new();
        seen.insert(function.id);
        queue.push_back(function);
        while !queue.is_empty() {
            let func = queue.pop_front().unwrap();
            for &(ref prev_func_, ref arg_id) in func.previous_functions().iter() {
                let prev_func = match prev_func_ {
                    &RootKind::RootVar(_) => continue,
                    &RootKind::RootFunc(ref f) => f,
                };
                if !dependencies.contains_key(&prev_func.id) {
                    dependencies.insert(prev_func.id, fn_ref_init(prev_func.output_ids().len()));
                }
                let output_idx = prev_func.output_ids()[arg_id];
                let mut fnrefs = dependencies[&prev_func.id].borrow_mut();
                fnrefs[output_idx][func.id] += 1;
                if !seen.contains(&prev_func.id) {
                    queue.push_back(prev_func);
                    seen.insert(prev_func.id);
                }
            }
        }
        dependencies
    }
    fn _free_backward_dependency(dependencies: &FnDependencies,
                                 prev_func: &Function,
                                 func: &Function,
                                 arg_id: i32)
                                 -> usize {
        let mut deps = dependencies[&prev_func.id].borrow_mut();
        let output_idx = prev_func.output_ids()[&arg_id];
        let mut output_deps = &mut deps[output_idx];
        output_deps[func.id] -= 1;
        if output_deps[func.id] == 0 {
            output_deps.remove(&func.id)
        }
        output_idx
    }
    fn _is_ready_for_backward(dependencies: &FnDependencies, function: &Function) -> bool {
        for ref deps in dependencies[&function.id].borrow().iter() {
            if deps.len() > 0 {
                return false;
            }
        }
        return true;
    }
    fn _add_grad(need_copy: &mut HashSet<TensorKind>,
                 prev_grad: &mut Vec<Option<TensorKind>>,
                 output_nr: usize,
                 d_prev_func: &TensorKind) {
        // We can't match and operate on the vector at
        // the same time because that would be performing
        // a mutable borrow in the middle of an immutable
        // borrow so we use a boolean
        // d_prev_func is just used as a placeholder so that
        // both arms match
        let (mut grad_tensor, matched) = match prev_grad[output_nr] {
            Some(ref t) => (t.clone(), true),
            None => (d_prev_func.clone(), false),
        };
        if matched {
            if need_copy.contains(&grad_tensor) {
                need_copy.remove(&grad_tensor);
                grad_tensor = grad_tensor.copy();
                // we perform the add before the assignment
                // in order to avoid an extra clone since
                // creation of the Option and subsequent
                // assignment moves the grad_tensor
                grad_tensor.add_(&d_prev_func[0]);
                prev_grad[output_nr] = Some(grad_tensor);
            } else {
                grad_tensor.add_(&d_prev_func[0]);
            }
        } else {
            // We need to clone twice here as the compiler
            // can't determine the lifetime dependency
            // between the two
            need_copy.insert(d_prev_func.clone());
            prev_grad[output_nr] = Some(d_prev_func.clone());
        }

    }
    pub fn run_backward<T: Copy>(var: &mut Variable<T>, grad: TensorKind, retain_variables: bool) {
        let grad_fn;
        match var.grad_fn() {
            Some(v) => grad_fn = v,
            None => {
                let mut grad_tensor = Tensor::<T>::from(grad);
                var._do_backward(&mut grad_tensor);
                return;
            }
        }
        let mut ready = VecDeque::new();
        ready.push_back((grad_fn.clone(), vec![grad]));
        let mut need_copy: HashSet<TensorKind> = HashSet::new();
        let mut not_ready: HashMap<FuncId, Vec<Option<TensorKind>>> = HashMap::new();

        let dependencies = _compute_dependencies(&grad_fn);
        while !ready.is_empty() {
            let (mut func, mut grad) = ready.pop_front().unwrap();
            let grad_input = func._do_backward(&mut grad, retain_variables);
            for (&(ref prev_func_, ref arg_id), ref d_prev_func) in
                itertools::zip(func.previous_functions(), grad_input) {
                if !prev_func_.requires_grad() {
                    continue;
                }
                let prev_func = match prev_func_ {
                    &RootKind::RootVar(ref v) => {
                        v.clone()._do_backward(&d_prev_func);
                        return;
                    }
                    &RootKind::RootFunc(ref f) => f,
                };
                let output_nr = _free_backward_dependency(&dependencies, prev_func, &func, *arg_id);
                let is_ready = _is_ready_for_backward(&dependencies, prev_func);
                if is_ready {
                    let prev_grad = if not_ready.contains_key(&prev_func.id) {
                        let mut prev_grad = not_ready[&prev_func.id].clone();
                        _add_grad(&mut need_copy, &mut prev_grad, output_nr, &d_prev_func);
                        prev_grad
                            .iter()
                            .map(|sv| if let &Some(ref v) = sv {
                                     v.clone()
                                 } else {
                                     panic!("found None")
                                 })
                            .collect()
                    } else {
                        vec![d_prev_func.clone()]
                    };
                    ready.push_front((prev_func.clone(), prev_grad))
                } else {
                    let mut prev_grad = if not_ready.contains_key(&prev_func.id) {
                        not_ready[&prev_func.id].clone()
                    } else {
                        prev_func.output_ids().iter().map(|_| None).collect()
                    };
                    _add_grad(&mut need_copy, &mut prev_grad, output_nr, &d_prev_func);
                    not_ready.insert(prev_func.id, prev_grad.clone());
                }
            }
        }
    }
}
<commit_msg>re-enable warnings<commit_after>use std::collections::HashMap;
use std::hash::Hash;
use std::cell::Cell;
use std::ops::{Index, IndexMut};

// Pythonesque Counter implementation
// XXX Move to a separate module
static ZERO: usize = 0;
pub struct Counter<T: Hash + Eq + Clone> {
    pub map: HashMap<T, Cell<usize>>,
}
impl<T: Hash + Eq + Clone> Counter<T> {
    pub fn new() -> Self {
        Counter { map: HashMap::new() }
    }
    pub fn len(&self) -> usize {
        self.map.len()
    }
    pub fn remove(&mut self, idx: &T) {
        self.map.remove(idx);
    }
}
impl<T: Hash + Eq + Clone> Index<T> for Counter<T> {
    type Output = usize;
    fn index(&self, idx: T) -> &Self::Output {
        if self.map.contains_key(&idx) {
            let cntp = self.map[&idx].as_ptr();
            unsafe { &*cntp }
        } else {
            //map.insert(idx, Cell::new(0));
            //let mut cntp = map[&idx].as_ptr();
            //unsafe {& *cntp}
            &ZERO
        }
    }
}
impl<T: Hash + Eq + Clone> IndexMut<T> for Counter<T> {
    fn index_mut(&mut self, idx: T) -> &mut Self::Output {
        if self.map.contains_key(&idx) {
            let cntp = self.map[&idx].as_ptr();
            unsafe { &mut *cntp }
        } else {
            self.map.insert(idx.clone(), Cell::new(0));
            let cntp = self.map[&idx].as_ptr();
            unsafe { &mut *cntp }
        }
    }
}

#[allow(non_snake_case)]
pub mod ExecutionEngine {
    use autograd::{Variable, Function, FuncId, RootKind};
    use tensor::{Tensor, TensorKind};
    use std::collections::{HashSet, HashMap, VecDeque};
    use std::cell::RefCell;
    use itertools;
    use super::Counter;

    type FnRefs = RefCell<Vec<Counter<FuncId>>>;
    type FnDependencies = HashMap<FuncId, FnRefs>;

    fn fn_ref_init(count: usize) -> FnRefs {
        let mut v = Vec::new();
        for _ in 0..count {
            v.push(Counter::new())
        }
        RefCell::new(v)
    }

    fn _compute_dependencies(function: &Function) -> FnDependencies {
        let mut dependencies = FnDependencies::new();
        let mut seen: HashSet<FuncId> = HashSet::new();
        let mut queue = VecDeque::new();
        seen.insert(function.id);
        queue.push_back(function);
        while !queue.is_empty() {
            let func = queue.pop_front().unwrap();
            for &(ref prev_func_, ref arg_id) in func.previous_functions().iter() {
                let prev_func = match prev_func_ {
                    &RootKind::RootVar(_) => continue,
                    &RootKind::RootFunc(ref f) => f,
                };
                if !dependencies.contains_key(&prev_func.id) {
                    dependencies.insert(prev_func.id, fn_ref_init(prev_func.output_ids().len()));
                }
                let output_idx = prev_func.output_ids()[arg_id];
                let mut fnrefs = dependencies[&prev_func.id].borrow_mut();
                fnrefs[output_idx][func.id] += 1;
                if !seen.contains(&prev_func.id) {
                    queue.push_back(prev_func);
                    seen.insert(prev_func.id);
                }
            }
        }
        dependencies
    }
    fn _free_backward_dependency(dependencies: &FnDependencies,
                                 prev_func: &Function,
                                 func: &Function,
                                 arg_id: i32)
                                 -> usize {
        let mut deps = dependencies[&prev_func.id].borrow_mut();
        let output_idx = prev_func.output_ids()[&arg_id];
        let mut output_deps = &mut deps[output_idx];
        output_deps[func.id] -= 1;
        if output_deps[func.id] == 0 {
            output_deps.remove(&func.id)
        }
        output_idx
    }
    fn _is_ready_for_backward(dependencies: &FnDependencies, function: &Function) -> bool {
        for ref deps in dependencies[&function.id].borrow().iter() {
            if deps.len() > 0 {
                return false;
            }
        }
        return true;
    }
    fn _add_grad(need_copy: &mut HashSet<TensorKind>,
                 prev_grad: &mut Vec<Option<TensorKind>>,
                 output_nr: usize,
                 d_prev_func: &TensorKind) {
        // We can't match and operate on the vector at
        // the same time because that would be performing
        // a mutable borrow in the middle of an immutable
        // borrow so we use a boolean
        // d_prev_func is just used as a placeholder so that
        // both arms match
        let (mut grad_tensor, matched) = match prev_grad[output_nr] {
            Some(ref t) => (t.clone(), true),
            None => (d_prev_func.clone(), false),
        };
        if matched {
            if need_copy.contains(&grad_tensor) {
                need_copy.remove(&grad_tensor);
                grad_tensor = grad_tensor.copy();
                // we perform the add before the assignment
                // in order to avoid an extra clone since
                // creation of the Option and subsequent
                // assignment moves the grad_tensor
                grad_tensor.add_(&d_prev_func[0]);
                prev_grad[output_nr] = Some(grad_tensor);
            } else {
                grad_tensor.add_(&d_prev_func[0]);
            }
        } else {
            // We need to clone twice here as the compiler
            // can't determine the lifetime dependency
            // between the two
            need_copy.insert(d_prev_func.clone());
            prev_grad[output_nr] = Some(d_prev_func.clone());
        }

    }
    pub fn run_backward<T: Copy>(var: &mut Variable<T>, grad: TensorKind, retain_variables: bool) {
        let grad_fn;
        match var.grad_fn() {
            Some(v) => grad_fn = v,
            None => {
                let mut grad_tensor = Tensor::<T>::from(grad);
                var._do_backward(&mut grad_tensor);
                return;
            }
        }
        let mut ready = VecDeque::new();
        ready.push_back((grad_fn.clone(), vec![grad]));
        let mut need_copy: HashSet<TensorKind> = HashSet::new();
        let mut not_ready: HashMap<FuncId, Vec<Option<TensorKind>>> = HashMap::new();

        let dependencies = _compute_dependencies(&grad_fn);
        while !ready.is_empty() {
            let (mut func, mut grad) = ready.pop_front().unwrap();
            let grad_input = func._do_backward(&mut grad, retain_variables);
            for (&(ref prev_func_, ref arg_id), ref d_prev_func) in
                itertools::zip(func.previous_functions(), grad_input) {
                if !prev_func_.requires_grad() {
                    continue;
                }
                let prev_func = match prev_func_ {
                    &RootKind::RootVar(ref v) => {
                        v.clone()._do_backward(&d_prev_func);
                        return;
                    }
                    &RootKind::RootFunc(ref f) => f,
                };
                let output_nr = _free_backward_dependency(&dependencies, prev_func, &func, *arg_id);
                let is_ready = _is_ready_for_backward(&dependencies, prev_func);
                if is_ready {
                    let prev_grad = if not_ready.contains_key(&prev_func.id) {
                        let mut prev_grad = not_ready[&prev_func.id].clone();
                        _add_grad(&mut need_copy, &mut prev_grad, output_nr, &d_prev_func);
                        prev_grad
                            .iter()
                            .map(|sv| if let &Some(ref v) = sv {
                                     v.clone()
                                 } else {
                                     panic!("found None")
                                 })
                            .collect()
                    } else {
                        vec![d_prev_func.clone()]
                    };
                    ready.push_front((prev_func.clone(), prev_grad))
                } else {
                    let mut prev_grad = if not_ready.contains_key(&prev_func.id) {
                        not_ready[&prev_func.id].clone()
                    } else {
                        prev_func.output_ids().iter().map(|_| None).collect()
                    };
                    _add_grad(&mut need_copy, &mut prev_grad, output_nr, &d_prev_func);
                    not_ready.insert(prev_func.id, prev_grad.clone());
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use serde_json::builder::ObjectBuilder;
use serde_json::Value;
use std::default::Default;
use ::model::{ChannelId, Region, VerificationLevel};

/// A builder to optionally edit certain fields of a [`Guild`]. This is meant
/// for usage with [`Context::edit_guild`] and [`LiveGuild::edit`].
///
/// **Note**: Editing a guild requires that the current user have the
/// [Manage Guild] permission.
///
/// [`Context::edit_guild`]: ../../client/struct.Context.html
/// [`Guild`]: ../../model/struct.Guild.html
/// [`LiveGuild::edit`]: ../../model/struct.LiveGuild.html#method.edit
/// [Manage Guild]: ../../model/permissions/constant.MANAGE_GUILD.html
pub struct EditGuild(pub ObjectBuilder);

impl EditGuild {
    /// Set the "AFK voice channel" that users are to move to if they have been
    /// AFK for an amount of time, configurable by [`afk_timeout`].
    ///
    /// The given channel must be either some valid voice channel, or `None` to
    /// not set an AFK channel. The library does not check if a channel is
    /// valid.
    ///
    /// [`afk_timeout`]: #method.afk_timeout
    pub fn afk_channel<C: Into<ChannelId>>(self, channel: Option<C>) -> Self {
        EditGuild(self.0.insert("afk_channel_id", match channel {
            Some(channel) => Value::U64(channel.into().0),
            None => Value::Null,
        }))
    }

    /// Set the amount of time a user is to be moved to the AFK channel -
    /// configured via [`afk_channel`] - after being AFK.
    ///
    /// [`afk_channel`]: #method.afk_channel
    pub fn afk_timeout(self, timeout: u64) -> Self {
        EditGuild(self.0.insert("afk_timeout", timeout))
    }

    /// Set the icon of the guild. Pass `None` to remove the icon.
    ///
    /// # Examples
    ///
    /// Using the utility function - [`utils::read_image`] - to read an image
    /// from the cwd and encode it in base64 to send to Discord.
    ///
    /// ```rust,ignore
    /// use serenity::utils;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let base64_icon = utils::read_image("./guild_icon.png")
    ///     .expect("Failed to read image");
    ///
    /// let _ = guild.edit(|g| g.icon(base64_icon));
    /// ```
    ///
    /// [`utils::read_image`]: ../../utils/fn.read_image.html
    pub fn icon(self, icon: Option<&str>) -> Self {
        EditGuild(self.0
            .insert("icon",
                    icon.map_or_else(|| Value::Null,
                                     |x| Value::String(x.to_owned()))))
    }

    /// Set the name of the guild.
    ///
    /// **Note**: Must be between (and including) 2-100 chracters.
    pub fn name(self, name: &str) -> Self {
        EditGuild(self.0.insert("name", name))
    }

    /// Set the voice region of the server.
    ///
    /// # Examples
    ///
    /// Setting the region to [`Region::UsWest`]:
    ///
    /// ```rust,ignore
    /// use serenity::model::Region;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// if let Err(why) = guild.edit(|g| g.region(Region::UsWest)) {
    ///     println!("Error editing guild's region: {:?}", why);
    /// }
    /// ```
    ///
    /// [`Region::UsWest`]: ../../model/enum.Region.html#variant.UsWest
    pub fn region(self, region: Region) -> Self {
        EditGuild(self.0.insert("region", region.name()))
    }

    /// Set the splash image of the guild on the invitation page.
    ///
    /// Requires that the guild have the [`InviteSplash`] feature enabled.
    /// You can check this through a guild's [`features`] list.
    ///
    /// [`InviteSplash`]: ../../model/enum.Feature.html#variant.InviteSplash
    /// [`features`]: ../../model/struct.LiveGuild.html#structfield.features
    pub fn splash(self, splash: Option<&str>) -> Self {
        EditGuild(self.0
            .insert("splash",
                    splash.map_or_else(|| Value::Null,
                                       |x| Value::String(x.to_owned()))))
    }

    /// Set the verification level of the guild. This can restrict what a
    /// user must have prior to being able to send messages in a guild.
    ///
    /// Refer to the documentation for [`VerificationLevel`] for more
    /// information on each variant.
    ///
    /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html
    ///
    /// # Examples
    ///
    /// Setting the verification level to [`High`][`VerificationLevel::High`]:
    ///
    /// ```rust,ignore
    /// use serenity::model::VerificationLevel;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// if let Err(why) = guild.edit(|g| g.verification_level(VerificationLevel::High)) {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    ///
    /// // additionally, you may pass in just an integer of the verification
    /// // level
    ///
    /// if let Err(why) = guild.edit(|g| g.verification_level(3)) {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    /// ```
    ///
    /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html
    /// [`VerificationLevel::High`]: ../../model/enum.VerificationLevel.html#variant.High
    pub fn verification_level<V>(self, verification_level: V) -> Self
        where V: Into<VerificationLevel> {
        EditGuild(self.0.insert("verification_level",
                                verification_level.into().num()))
    }
}

impl Default for EditGuild {
    fn default() -> EditGuild {
        EditGuild(ObjectBuilder::new())
    }
}
<commit_msg>Add method to EditGuild to transfer ownership<commit_after>use serde_json::builder::ObjectBuilder;
use serde_json::Value;
use std::default::Default;
use ::model::{ChannelId, Region, UserId, VerificationLevel};

/// A builder to optionally edit certain fields of a [`Guild`]. This is meant
/// for usage with [`Context::edit_guild`] and [`LiveGuild::edit`].
///
/// **Note**: Editing a guild requires that the current user have the
/// [Manage Guild] permission.
///
/// [`Context::edit_guild`]: ../../client/struct.Context.html
/// [`Guild`]: ../../model/struct.Guild.html
/// [`LiveGuild::edit`]: ../../model/struct.LiveGuild.html#method.edit
/// [Manage Guild]: ../../model/permissions/constant.MANAGE_GUILD.html
pub struct EditGuild(pub ObjectBuilder);

impl EditGuild {
    /// Set the "AFK voice channel" that users are to move to if they have been
    /// AFK for an amount of time, configurable by [`afk_timeout`].
    ///
    /// The given channel must be either some valid voice channel, or `None` to
    /// not set an AFK channel. The library does not check if a channel is
    /// valid.
    ///
    /// [`afk_timeout`]: #method.afk_timeout
    pub fn afk_channel<C: Into<ChannelId>>(self, channel: Option<C>) -> Self {
        EditGuild(self.0.insert("afk_channel_id", match channel {
            Some(channel) => Value::U64(channel.into().0),
            None => Value::Null,
        }))
    }

    /// Set the amount of time a user is to be moved to the AFK channel -
    /// configured via [`afk_channel`] - after being AFK.
    ///
    /// [`afk_channel`]: #method.afk_channel
    pub fn afk_timeout(self, timeout: u64) -> Self {
        EditGuild(self.0.insert("afk_timeout", timeout))
    }

    /// Set the icon of the guild. Pass `None` to remove the icon.
    ///
    /// # Examples
    ///
    /// Using the utility function - [`utils::read_image`] - to read an image
    /// from the cwd and encode it in base64 to send to Discord.
    ///
    /// ```rust,ignore
    /// use serenity::utils;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let base64_icon = utils::read_image("./guild_icon.png")
    ///     .expect("Failed to read image");
    ///
    /// let _ = guild.edit(|g| g.icon(base64_icon));
    /// ```
    ///
    /// [`utils::read_image`]: ../../utils/fn.read_image.html
    pub fn icon(self, icon: Option<&str>) -> Self {
        EditGuild(self.0
            .insert("icon",
                    icon.map_or_else(|| Value::Null,
                                     |x| Value::String(x.to_owned()))))
    }

    /// Set the name of the guild.
    ///
    /// **Note**: Must be between (and including) 2-100 chracters.
    pub fn name(self, name: &str) -> Self {
        EditGuild(self.0.insert("name", name))
    }

    /// Transfers the ownership of the guild to another user by Id.
    ///
    /// **Note**: The current user must be the owner of the guild.
    pub fn owner<U: Into<UserId>>(self, user_id: U) -> Self {
        EditGuild(self.0.insert("owner_id", user_id.into().0))
    }

    /// Set the voice region of the server.
    ///
    /// # Examples
    ///
    /// Setting the region to [`Region::UsWest`]:
    ///
    /// ```rust,ignore
    /// use serenity::model::Region;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// if let Err(why) = guild.edit(|g| g.region(Region::UsWest)) {
    ///     println!("Error editing guild's region: {:?}", why);
    /// }
    /// ```
    ///
    /// [`Region::UsWest`]: ../../model/enum.Region.html#variant.UsWest
    pub fn region(self, region: Region) -> Self {
        EditGuild(self.0.insert("region", region.name()))
    }

    /// Set the splash image of the guild on the invitation page.
    ///
    /// Requires that the guild have the [`InviteSplash`] feature enabled.
    /// You can check this through a guild's [`features`] list.
    ///
    /// [`InviteSplash`]: ../../model/enum.Feature.html#variant.InviteSplash
    /// [`features`]: ../../model/struct.LiveGuild.html#structfield.features
    pub fn splash(self, splash: Option<&str>) -> Self {
        EditGuild(self.0
            .insert("splash",
                    splash.map_or_else(|| Value::Null,
                                       |x| Value::String(x.to_owned()))))
    }

    /// Set the verification level of the guild. This can restrict what a
    /// user must have prior to being able to send messages in a guild.
    ///
    /// Refer to the documentation for [`VerificationLevel`] for more
    /// information on each variant.
    ///
    /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html
    ///
    /// # Examples
    ///
    /// Setting the verification level to [`High`][`VerificationLevel::High`]:
    ///
    /// ```rust,ignore
    /// use serenity::model::VerificationLevel;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// if let Err(why) = guild.edit(|g| g.verification_level(VerificationLevel::High)) {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    ///
    /// // additionally, you may pass in just an integer of the verification
    /// // level
    ///
    /// if let Err(why) = guild.edit(|g| g.verification_level(3)) {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    /// ```
    ///
    /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html
    /// [`VerificationLevel::High`]: ../../model/enum.VerificationLevel.html#variant.High
    pub fn verification_level<V>(self, verification_level: V) -> Self
        where V: Into<VerificationLevel> {
        EditGuild(self.0.insert("verification_level",
                                verification_level.into().num()))
    }
}

impl Default for EditGuild {
    fn default() -> EditGuild {
        EditGuild(ObjectBuilder::new())
    }
}
<|endoftext|>


<commit_before>
// silence warnings while still a WIP
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_assignments)]

use autograd::{Variable, Function, FuncId, FuncIntf, RootKind};
use tensor::{Tensor, TensorKind};
use std::collections::{HashSet, HashMap, VecDeque};
use itertools;

pub struct ExecutionEngine {}

type FnRefs = HashMap<Function, u32>;
type FnDependencies = HashMap<Function, FnRefs>;

impl ExecutionEngine {
    fn _compute_dependencies(function: &Function) -> FnDependencies {
        unimplemented!()
    }
    fn _free_backward_dependency(dependencies: FnDependencies,
                                 prev_fn: FuncId,
                                 fn_: FuncId,
                                 arg_id: u32)
                                 -> usize {
        unimplemented!();
    }
    fn _is_ready_for_backward(dependencies: FnDependencies, function: FuncId) -> bool {
        unimplemented!()
    }
    fn _add_grad<T>(need_copy: HashSet<Function>,
                    prev_grad: HashMap<u32, &Tensor<T>>,
                    output_nr: u32,
                    d_prev_grad: &Tensor<T>) {
        unimplemented!()
    }
    pub fn run_backward<T: Copy>(var: &mut Variable<T>, grad: TensorKind, retain_variables: bool) {
        let grad_fn;
        match var.grad_fn() {
            Some(v) => grad_fn = v,
            None => {
                let grad_tensor = Tensor::<T>::from(grad);
                var._do_backward(&grad_tensor);
                return;
            }
        }
        let mut ready = VecDeque::new();
        ready.push_back((grad_fn.clone(), vec![grad]));
        let mut need_copy: HashSet<TensorKind> = HashSet::new();

        let dependencies = Self::_compute_dependencies(&grad_fn);
        while !ready.is_empty() {
            let (func, grad) = ready.pop_front().unwrap();
            let grad_input = func.clone()._do_backward(&grad, retain_variables);
            for (&(ref prev_fn_, ref arg_id), ref d_prev_fn) in
                itertools::zip(func.previous_functions(), grad_input) {
                if !prev_fn_.requires_grad() {
                    continue;
                }
                let prev_fn = match prev_fn_ {
                    &RootKind::RootVar(ref v) => {
                        v.clone()._do_backward(d_prev_fn);
                        return;
                    }
                    &RootKind::RootFunc(ref f) => f,
                };
            }
        }
    }
}
<commit_msg>implement run_backward, fix signatures of some of the subroutines<commit_after>
// silence warnings while still a WIP
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_imports)]

use autograd::{Variable, Function, FuncId, FuncIntf, RootKind};
use tensor::{Tensor, TensorKind, TensorKindList};
use std::collections::{HashSet, HashMap, VecDeque};
use itertools;

pub struct ExecutionEngine {}

type FnRefs = HashMap<Function, u32>;
type FnDependencies = HashMap<Function, FnRefs>;

impl ExecutionEngine {
    fn _compute_dependencies(function: &Function) -> FnDependencies {
        unimplemented!()
    }
    fn _free_backward_dependency(dependencies: &FnDependencies,
                                 prev_func: &Function,
                                 func: &Function,
                                 arg_id: i32)
                                 -> usize {
        unimplemented!();
    }
    fn _is_ready_for_backward(dependencies: &FnDependencies, function: &Function) -> bool {
        unimplemented!()
    }
    fn _add_grad(need_copy: &mut HashSet<TensorKind>,
                 prev_grad: &Vec<Option<TensorKind>>,
                 output_nr: usize,
                 d_prev_grad: &TensorKind) {
        unimplemented!()
    }
    pub fn run_backward<T: Copy>(var: &mut Variable<T>, grad: TensorKind, retain_variables: bool) {
        let grad_fn;
        match var.grad_fn() {
            Some(v) => grad_fn = v,
            None => {
                let grad_tensor = Tensor::<T>::from(grad);
                var._do_backward(&grad_tensor);
                return;
            }
        }
        let mut ready = VecDeque::new();
        ready.push_back((grad_fn.clone(), vec![grad]));
        let mut need_copy: HashSet<TensorKind> = HashSet::new();
        let mut not_ready: HashMap<FuncId, Vec<Option<TensorKind>>> = HashMap::new();

        let dependencies = Self::_compute_dependencies(&grad_fn);
        while !ready.is_empty() {
            let (mut func, grad) = ready.pop_front().unwrap();
            let grad_input = func._do_backward(&grad, retain_variables);
            for (&(ref prev_func_, ref arg_id), ref d_prev_func) in
                itertools::zip(func.previous_functions(), grad_input) {
                if !prev_func_.requires_grad() {
                    continue;
                }
                let prev_func = match prev_func_ {
                    &RootKind::RootVar(ref v) => {
                        v.clone()._do_backward(&d_prev_func);
                        return;
                    }
                    &RootKind::RootFunc(ref f) => f,
                };
                let output_nr =
                    Self::_free_backward_dependency(&dependencies, prev_func, &func, *arg_id);
                let is_ready = Self::_is_ready_for_backward(&dependencies, prev_func);
                if is_ready {
                    let prev_grad = if not_ready.contains_key(&prev_func.id) {
                        let prev_grad = not_ready[&prev_func.id].clone();
                        Self::_add_grad(&mut need_copy, &prev_grad, output_nr, &d_prev_func);
                        prev_grad
                            .iter()
                            .map(|sv| if let &Some(ref v) = sv {
                                     v.clone()
                                 } else {
                                     panic!("found None")
                                 })
                            .collect()
                    } else {
                        vec![d_prev_func.clone()]
                    };
                    ready.push_front((prev_func.clone(), prev_grad))
                } else {
                    let prev_grad = if not_ready.contains_key(&prev_func.id) {
                        not_ready[&prev_func.id].clone()
                    } else {
                        prev_func.output_ids().iter().map(|_| None).collect()
                    };
                    Self::_add_grad(&mut need_copy, &prev_grad, output_nr, &d_prev_func);
                    not_ready.insert(prev_func.id, prev_grad.clone());
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::io::Write;
use std::path;

use failure::ResultExt;

use crate::error::*;

pub fn get_config_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: _cobalt.yml]")
            .takes_value(true),
        clap::Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Site destination folder [default: ./]")
            .takes_value(true),
        clap::Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .takes_value(false),
        clap::Arg::with_name("no-drafts")
            .long("no-drafts")
            .help("Ignore drafts.")
            .conflicts_with("drafts")
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_config(matches: &clap::ArgMatches) -> Result<cobalt_config::Config> {
    let config_path = matches.value_of("config");

    // Fetch config information if available
    let mut config = if let Some(config_path) = config_path {
        cobalt_config::Config::from_file(config_path)
            .with_context(|_| failure::format_err!("Error reading config file {:?}", config_path))?
    } else {
        let cwd = env::current_dir().expect("How does this fail?");
        cobalt_config::Config::from_cwd(cwd)?
    };

    config.abs_dest = matches.value_of("destination").map(path::PathBuf::from);

    if matches.is_present("drafts") {
        config.include_drafts = true;
    }
    if matches.is_present("no-drafts") {
        config.include_drafts = false;
    }

    Ok(config)
}

pub fn get_logging_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true),
        clap::Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false),
        clap::Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_logging(
    global_matches: &clap::ArgMatches,
    matches: &clap::ArgMatches,
) -> Result<env_logger::Builder> {
    let mut builder = env_logger::Builder::new();

    let level = if matches.is_present("trace") {
        log::LevelFilter::Trace
    } else if matches.is_present("silent") {
        log::LevelFilter::Off
    } else {
        match matches
            .value_of("log-level")
            .or_else(|| global_matches.value_of("log-level"))
        {
            Some("error") => log::LevelFilter::Error,
            Some("warn") => log::LevelFilter::Warn,
            Some("debug") => log::LevelFilter::Debug,
            Some("trace") => log::LevelFilter::Trace,
            Some("off") => log::LevelFilter::Off,
            Some("info") => log::LevelFilter::Info,
            _ => log::LevelFilter::Info,
        }
    };
    builder.filter(None, level);

    if level == log::LevelFilter::Trace {
        builder.format_timestamp_secs();
    } else {
        builder.format(|f, record| {
            writeln!(
                f,
                "[{}] {}",
                record.level().to_string().to_lowercase(),
                record.args()
            )
        });
    }

    Ok(builder)
}
<commit_msg>fix(cli): Ignore `--destination` path<commit_after>use std::env;
use std::io::Write;
use std::path;

use failure::ResultExt;

use crate::error::*;

pub fn get_config_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: _cobalt.yml]")
            .takes_value(true),
        clap::Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Site destination folder [default: ./]")
            .takes_value(true),
        clap::Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .takes_value(false),
        clap::Arg::with_name("no-drafts")
            .long("no-drafts")
            .help("Ignore drafts.")
            .conflicts_with("drafts")
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_config(matches: &clap::ArgMatches) -> Result<cobalt_config::Config> {
    let config_path = matches.value_of("config");

    // Fetch config information if available
    let mut config = if let Some(config_path) = config_path {
        cobalt_config::Config::from_file(config_path)
            .with_context(|_| failure::format_err!("Error reading config file {:?}", config_path))?
    } else {
        let cwd = env::current_dir().expect("How does this fail?");
        cobalt_config::Config::from_cwd(cwd)?
    };

    config.abs_dest = matches
        .value_of("destination")
        .map(|d| {
            let d = path::PathBuf::from(d);
            std::fs::create_dir_all(&d)?;
            d.canonicalize()
        })
        .transpose()?;

    if matches.is_present("drafts") {
        config.include_drafts = true;
    }
    if matches.is_present("no-drafts") {
        config.include_drafts = false;
    }

    Ok(config)
}

pub fn get_logging_args() -> Vec<clap::Arg<'static, 'static>> {
    [
        clap::Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true),
        clap::Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false),
        clap::Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false),
    ]
    .to_vec()
}

pub fn get_logging(
    global_matches: &clap::ArgMatches,
    matches: &clap::ArgMatches,
) -> Result<env_logger::Builder> {
    let mut builder = env_logger::Builder::new();

    let level = if matches.is_present("trace") {
        log::LevelFilter::Trace
    } else if matches.is_present("silent") {
        log::LevelFilter::Off
    } else {
        match matches
            .value_of("log-level")
            .or_else(|| global_matches.value_of("log-level"))
        {
            Some("error") => log::LevelFilter::Error,
            Some("warn") => log::LevelFilter::Warn,
            Some("debug") => log::LevelFilter::Debug,
            Some("trace") => log::LevelFilter::Trace,
            Some("off") => log::LevelFilter::Off,
            Some("info") => log::LevelFilter::Info,
            _ => log::LevelFilter::Info,
        }
    };
    builder.filter(None, level);

    if level == log::LevelFilter::Trace {
        builder.format_timestamp_secs();
    } else {
        builder.format(|f, record| {
            writeln!(
                f,
                "[{}] {}",
                record.level().to_string().to_lowercase(),
                record.args()
            )
        });
    }

    Ok(builder)
}
<|endoftext|>


<commit_before>extern crate octobuild;
extern crate hyper;
extern crate rustc_serialize;
extern crate rand;
extern crate tempdir;
#[macro_use]
extern crate log;

use octobuild::vs::compiler::VsCompiler;
use octobuild::io::statistic::Statistic;
use octobuild::compiler::*;
use octobuild::cache::Cache;
use octobuild::config::Config;
use octobuild::cluster::common::{BuilderInfo, RPC_BUILDER_LIST};

use tempdir::TempDir;
use hyper::{Client, Url};
use rustc_serialize::json;

use std::collections::HashMap;
use std::env;
use std::error::Error;
use std::io;
use std::io::{Read, Write};
use std::iter::FromIterator;
use std::path::Path;
use std::sync::{Arc, RwLock};
use std::process;

fn main() {
    octobuild::utils::init_logger();

    let client = Client::new();
    match client
    .get(Url::parse("http://localhost:3000").unwrap().join(RPC_BUILDER_LIST).unwrap())
    .send()
    {
        Ok(mut response) => {
            let mut payload = String::new();
            response.read_to_string(&mut payload).unwrap();

            let builders: Vec<BuilderInfo> = json::decode(&payload).unwrap();
            let builder = get_random_builder(&builders).unwrap();
            info!("  builder: {} {}", builder.name, builder.endpoint);
        }
        Err(e) => {
            info!("Builder: can't send info to coordinator: {}", e.description());
        }
    };
}

fn get_random_builder(builders: &Vec<BuilderInfo>) -> Option<&BuilderInfo> {
    if builders.len() > 0 {
        Some(&builders[rand::random::<usize>() % builders.len()])
    } else {
        None
    }
}<commit_msg>Simple client-server messaging<commit_after>extern crate octobuild;
extern crate hyper;
extern crate rustc_serialize;
extern crate rand;
extern crate tempdir;
#[macro_use]
extern crate log;

use octobuild::vs::compiler::VsCompiler;
use octobuild::io::statistic::Statistic;
use octobuild::compiler::*;
use octobuild::cache::Cache;
use octobuild::config::Config;
use octobuild::cluster::common::{BuilderInfo, RPC_BUILDER_LIST};

use tempdir::TempDir;
use hyper::{Client, Url};
use rustc_serialize::json;

use std::collections::HashMap;
use std::env;
use std::error::Error;
use std::io;
use std::io::{Read, Write};
use std::iter::FromIterator;
use std::path::Path;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::net::{SocketAddr, TcpStream};
use std::process;

fn main() {
    octobuild::utils::init_logger();

    let client = Client::new();
    match client
    .get(Url::parse("http://localhost:3000").unwrap().join(RPC_BUILDER_LIST).unwrap())
    .send()
    {
        Ok(mut response) => {
            let mut payload = String::new();
            response.read_to_string(&mut payload).unwrap();

            let builders: Vec<BuilderInfo> = json::decode(&payload).unwrap();
            let builder = get_random_builder(&builders).unwrap();
            info!("Builder: {} {}", builder.name, builder.endpoint);
            let addr = SocketAddr::from_str(&builder.endpoint).unwrap();

            let mut stream = TcpStream::connect(addr).unwrap();
            let mut payload = String::new();
            stream.read_to_string(&mut payload).unwrap();
            info!("{}", payload);
        }
        Err(e) => {
            info!("Builder: can't send info to coordinator: {}", e.description());
        }
    };
}

fn get_random_builder(builders: &Vec<BuilderInfo>) -> Option<&BuilderInfo> {
    if builders.len() > 0 {
        Some(&builders[rand::random::<usize>() % builders.len()])
    } else {
        None
    }
}<|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.

#![feature(plugin)]
#![cfg_attr(feature = "dev", plugin(clippy))]

extern crate tikv;
extern crate getopts;
#[macro_use]
extern crate log;
extern crate rocksdb;
extern crate mio;

use std::env;
use std::fs;
use std::path::Path;
use std::sync::{Arc, RwLock};

use getopts::{Options, Matches};
use log::LogLevelFilter;
use rocksdb::{DB, Options as RocksdbOptions, BlockBasedOptions, DBCompressionType};
use mio::tcp::TcpListener;

use tikv::storage::{Storage, Dsn};
use tikv::util::{self, logger};
use tikv::server::{DEFAULT_LISTENING_ADDR, SendCh, Server, Node, Config, bind, create_event_loop,
                   create_raft_storage};
use tikv::server::{ServerTransport, ServerRaftStoreRouter, MockRaftStoreRouter};
use tikv::server::{MockStoreAddrResolver, PdStoreAddrResolver};
use tikv::pd::{new_rpc_client, PdRpcClient};

const MEM_DSN: &'static str = "mem";
const ROCKSDB_DSN: &'static str = "rocksdb";
const RAFTKV_DSN: &'static str = "raftkv";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn initial_log(matches: &Matches) {
    let log_filter = match matches.opt_str("L") {
        Some(level) => logger::get_level_by_string(&level),
        None => LogLevelFilter::Info,
    };
    util::init_log(log_filter).unwrap();
}

fn build_raftkv(matches: &Matches,
                ch: SendCh,
                cluster_id: u64,
                addr: String,
                pd_client: Arc<RwLock<PdRpcClient>>)
                -> (Storage, Arc<RwLock<ServerRaftStoreRouter>>) {
    let trans = Arc::new(RwLock::new(ServerTransport::new(ch)));

    let path = get_store_path(matches);
    let mut opts = RocksdbOptions::new();
    let mut block_base_opts = BlockBasedOptions::new();
    block_base_opts.set_block_size(64 * 1024);
    opts.set_block_based_table_factory(&block_base_opts);
    opts.compression(DBCompressionType::DBNo);
    opts.set_target_file_size_base(64 * 1024 * 1024);
    opts.create_if_missing(true);

    let engine = Arc::new(DB::open(&opts, &path).unwrap());
    let mut cfg = Config::new();
    cfg.cluster_id = cluster_id;

    cfg.addr = addr.clone();

    // Set advertise address for outer node and client use.
    // If no advertise listening address set, use the associated listening address.
    cfg.advertise_addr = matches.opt_str("advertise-addr")
                                .unwrap_or_else(|| addr);

    let mut node = Node::new(&cfg, pd_client, trans.clone());
    node.start(engine.clone()).unwrap();
    let raft_router = node.raft_store_router();

    (create_raft_storage(node, engine).unwrap(), raft_router)
}

fn get_store_path(matches: &Matches) -> String {
    let path = matches.opt_str("s").expect("need store path, but none is specified!");

    let p = Path::new(&path);
    if p.exists() && p.is_file() {
        panic!("{} is not a directory!", path);
    }
    if !p.exists() {
        fs::create_dir_all(p).unwrap();
    }
    let absolute_path = p.canonicalize().unwrap();
    format!("{}", absolute_path.display())
}

fn run_local_server(listener: TcpListener, store: Storage) {
    let mut event_loop = create_event_loop().unwrap();
    let router = Arc::new(RwLock::new(MockRaftStoreRouter));
    let mut svr = Server::new(&mut event_loop,
                              listener,
                              store,
                              router,
                              MockStoreAddrResolver)
                      .unwrap();
    svr.run(&mut event_loop).unwrap();
}

fn run_raft_server(listener: TcpListener, matches: &Matches) {
    let mut event_loop = create_event_loop().unwrap();
    let ch = SendCh::new(event_loop.channel());

    let id = matches.opt_str("I").expect("raftkv requires cluster id");
    let cluster_id = u64::from_str_radix(&id, 10).expect("invalid cluster id");

    let pd_addr = matches.opt_str("pd").expect("raftkv needs pd client");
    let pd_client = Arc::new(RwLock::new(new_rpc_client(&pd_addr).unwrap()));
    let resolver = PdStoreAddrResolver::new(cluster_id, pd_client.clone()).unwrap();

    let (store, raft_router) = build_raftkv(&matches,
                                            ch,
                                            cluster_id,
                                            format!("{}", listener.local_addr().unwrap()),
                                            pd_client);

    let mut svr = Server::new(&mut event_loop, listener, store, raft_router, resolver).unwrap();
    svr.run(&mut event_loop).unwrap();
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("A",
                "addr",
                "set listening address",
                "default is 127.0.0.1:20160");
    opts.optopt("",
                "advertise-addr",
                "set advertise listening address for client communication",
                "127.0.0.1:20160, if not set, use addr instead.");
    opts.optopt("L",
                "log",
                "set log level",
                "log level: trace, debug, info, warn, error, off");
    opts.optflag("h", "help", "print this help menu");
    // TODO: support loading config file
    // opts.optopt("C", "config", "set configuration file", "file path");
    opts.optopt("s",
                "store",
                "set the path to rocksdb directory",
                "/tmp/tikv/store");
    opts.optopt("S",
                "dsn",
                "set which dsn to use, default is mem",
                "dsn: mem, rocksdb, raftkv");
    opts.optopt("I", "cluster-id", "set cluster id", "must greater than 0.");
    opts.optopt("", "pd", "set pd address", "host:port");
    let matches = opts.parse(&args[1..]).expect("opts parse failed");
    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }
    initial_log(&matches);

    let addr = matches.opt_str("A").unwrap_or_else(|| DEFAULT_LISTENING_ADDR.to_owned());
    info!("Start listening on {}...", addr);
    let listener = bind(&addr).unwrap();

    let dsn_name = matches.opt_str("S").unwrap_or_else(|| MEM_DSN.to_owned());

    match dsn_name.as_ref() {
        MEM_DSN => {
            let store = Storage::new(Dsn::Memory).unwrap();
            run_local_server(listener, store);
        }
        ROCKSDB_DSN => {
            let path = get_store_path(&matches);
            let store = Storage::new(Dsn::RocksDBPath(&path)).unwrap();
            run_local_server(listener, store);
        }
        RAFTKV_DSN => {
            run_raft_server(listener, &matches);
        }
        n => panic!("unrecognized dns name: {}", n),
    };
}
<commit_msg>bin: Fix compile. (#453)<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.

#![feature(plugin)]
#![cfg_attr(feature = "dev", plugin(clippy))]

extern crate tikv;
extern crate getopts;
#[macro_use]
extern crate log;
extern crate rocksdb;
extern crate mio;

use std::env;
use std::fs;
use std::path::Path;
use std::sync::{Arc, RwLock};

use getopts::{Options, Matches};
use log::LogLevelFilter;
use rocksdb::{DB, Options as RocksdbOptions, BlockBasedOptions, DBCompressionType};
use mio::tcp::TcpListener;

use tikv::storage::{Storage, Dsn};
use tikv::util::{self, logger};
use tikv::server::{DEFAULT_LISTENING_ADDR, SendCh, Server, Node, Config, bind, create_event_loop,
                   create_raft_storage};
use tikv::server::{ServerTransport, ServerRaftStoreRouter, MockRaftStoreRouter};
use tikv::server::{MockStoreAddrResolver, PdStoreAddrResolver};
use tikv::pd::{new_rpc_client, RpcClient};

const MEM_DSN: &'static str = "mem";
const ROCKSDB_DSN: &'static str = "rocksdb";
const RAFTKV_DSN: &'static str = "raftkv";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn initial_log(matches: &Matches) {
    let log_filter = match matches.opt_str("L") {
        Some(level) => logger::get_level_by_string(&level),
        None => LogLevelFilter::Info,
    };
    util::init_log(log_filter).unwrap();
}

fn build_raftkv(matches: &Matches,
                ch: SendCh,
                cluster_id: u64,
                addr: String,
                pd_client: Arc<RwLock<RpcClient>>)
                -> (Storage, Arc<RwLock<ServerRaftStoreRouter>>) {
    let trans = Arc::new(RwLock::new(ServerTransport::new(ch)));

    let path = get_store_path(matches);
    let mut opts = RocksdbOptions::new();
    let mut block_base_opts = BlockBasedOptions::new();
    block_base_opts.set_block_size(64 * 1024);
    opts.set_block_based_table_factory(&block_base_opts);
    opts.compression(DBCompressionType::DBNo);
    opts.set_target_file_size_base(64 * 1024 * 1024);
    opts.create_if_missing(true);

    let engine = Arc::new(DB::open(&opts, &path).unwrap());
    let mut cfg = Config::new();
    cfg.cluster_id = cluster_id;

    cfg.addr = addr.clone();

    // Set advertise address for outer node and client use.
    // If no advertise listening address set, use the associated listening address.
    cfg.advertise_addr = matches.opt_str("advertise-addr")
                                .unwrap_or_else(|| addr);

    let mut node = Node::new(&cfg, pd_client, trans.clone());
    node.start(engine.clone()).unwrap();
    let raft_router = node.raft_store_router();

    (create_raft_storage(node, engine).unwrap(), raft_router)
}

fn get_store_path(matches: &Matches) -> String {
    let path = matches.opt_str("s").expect("need store path, but none is specified!");

    let p = Path::new(&path);
    if p.exists() && p.is_file() {
        panic!("{} is not a directory!", path);
    }
    if !p.exists() {
        fs::create_dir_all(p).unwrap();
    }
    let absolute_path = p.canonicalize().unwrap();
    format!("{}", absolute_path.display())
}

fn run_local_server(listener: TcpListener, store: Storage) {
    let mut event_loop = create_event_loop().unwrap();
    let router = Arc::new(RwLock::new(MockRaftStoreRouter));
    let mut svr = Server::new(&mut event_loop,
                              listener,
                              store,
                              router,
                              MockStoreAddrResolver)
                      .unwrap();
    svr.run(&mut event_loop).unwrap();
}

fn run_raft_server(listener: TcpListener, matches: &Matches) {
    let mut event_loop = create_event_loop().unwrap();
    let ch = SendCh::new(event_loop.channel());

    let id = matches.opt_str("I").expect("raftkv requires cluster id");
    let cluster_id = u64::from_str_radix(&id, 10).expect("invalid cluster id");

    let pd_addr = matches.opt_str("pd").expect("raftkv needs pd client");
    let pd_client = Arc::new(RwLock::new(new_rpc_client(&pd_addr).unwrap()));
    let resolver = PdStoreAddrResolver::new(cluster_id, pd_client.clone()).unwrap();

    let (store, raft_router) = build_raftkv(&matches,
                                            ch,
                                            cluster_id,
                                            format!("{}", listener.local_addr().unwrap()),
                                            pd_client);

    let mut svr = Server::new(&mut event_loop, listener, store, raft_router, resolver).unwrap();
    svr.run(&mut event_loop).unwrap();
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("A",
                "addr",
                "set listening address",
                "default is 127.0.0.1:20160");
    opts.optopt("",
                "advertise-addr",
                "set advertise listening address for client communication",
                "127.0.0.1:20160, if not set, use addr instead.");
    opts.optopt("L",
                "log",
                "set log level",
                "log level: trace, debug, info, warn, error, off");
    opts.optflag("h", "help", "print this help menu");
    // TODO: support loading config file
    // opts.optopt("C", "config", "set configuration file", "file path");
    opts.optopt("s",
                "store",
                "set the path to rocksdb directory",
                "/tmp/tikv/store");
    opts.optopt("S",
                "dsn",
                "set which dsn to use, default is mem",
                "dsn: mem, rocksdb, raftkv");
    opts.optopt("I", "cluster-id", "set cluster id", "must greater than 0.");
    opts.optopt("", "pd", "set pd address", "host:port");
    let matches = opts.parse(&args[1..]).expect("opts parse failed");
    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }
    initial_log(&matches);

    let addr = matches.opt_str("A").unwrap_or_else(|| DEFAULT_LISTENING_ADDR.to_owned());
    info!("Start listening on {}...", addr);
    let listener = bind(&addr).unwrap();

    let dsn_name = matches.opt_str("S").unwrap_or_else(|| MEM_DSN.to_owned());

    match dsn_name.as_ref() {
        MEM_DSN => {
            let store = Storage::new(Dsn::Memory).unwrap();
            run_local_server(listener, store);
        }
        ROCKSDB_DSN => {
            let path = get_store_path(&matches);
            let store = Storage::new(Dsn::RocksDBPath(&path)).unwrap();
            run_local_server(listener, store);
        }
        RAFTKV_DSN => {
            run_raft_server(listener, &matches);
        }
        n => panic!("unrecognized dns name: {}", n),
    };
}
<|endoftext|>


<commit_before>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! Currently, there is no way to define filters outside this module.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use std::fmt;

use super::Result;
use escaping::{self, MarkupDisplay};

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 11] = [
    "e",
    "escape",
    "format",
    "join",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "upper",
    "uppercase",
    "json", // Optional feature; reserve the name anyway
];

pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() {}

/// Converts to lowercase.
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter.
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase.
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter.
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace.
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
where
    T: fmt::Display,
    I: Iterator<Item = T>,
    S: AsRef<str>,
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(
            join((&["hello", "world"]).into_iter(), ", ").unwrap(),
            "hello, world"
        );
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(
            join((&input).into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":").unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(
            join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(),
            "foo, bar"
        );
    }
}
<commit_msg>Add support for 'truncate' filter (see #95)<commit_after>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! Currently, there is no way to define filters outside this module.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use std::fmt;

use super::Result;
use escaping::{self, MarkupDisplay};

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 12] = [
    "e",
    "escape",
    "format",
    "join",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "truncate",
    "upper",
    "uppercase",
    "json", // Optional feature; reserve the name anyway
];

pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>,
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() {}

/// Converts to lowercase.
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter.
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase.
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter.
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace.
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Limit string length, appens '...' if truncated {
pub fn truncate(s: &fmt::Display, len: &usize) -> Result<String> {
    let mut s = format!("{}", s);
    if s.len() < *len {
        Ok(s)
    } else {
        s.truncate(*len);
        s.push_str("...");
        Ok(s)
    }
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
where
    T: fmt::Display,
    I: Iterator<Item = T>,
    S: AsRef<str>,
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(
            join((&["hello", "world"]).into_iter(), ", ").unwrap(),
            "hello, world"
        );
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(
            join((&input).into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":").unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(
            join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(),
            "foo, bar"
        );
    }
}
<|endoftext|>