<commit_before>use std::collections::{HashSet, HashMap};
use std::fmt;
use std::str;

use error::{Error, Result};
use parser;

#[derive(Clone, PartialEq, Eq)]
pub enum Chunk<'a> {
    Str(&'a [u8]),
    Var(&'a [u8]),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Template<'a> {
    chunks: Vec<Chunk<'a>>,
}

impl<'a> Template<'a> {
    pub fn parse(i: &'a [u8]) -> Result<Template<'a>> {
        Ok(Template { chunks: parser::template(i).to_full_result()? })
    }

    pub fn render(&self, vars: &HashMap<&[u8], String>) -> Result<Vec<u8>> {
        let mut buf = Vec::new();
        for chunk in &self.chunks {
            match *chunk {
                Chunk::Str(s) => buf.extend_from_slice(s),
                Chunk::Var(v) => {
                    buf.extend_from_slice(vars.get(v).ok_or(Error::VarNotFound)?.as_bytes())
                }
            }
        }
        Ok(buf)
    }

    pub fn extract_vars(&self, target: &mut HashSet<&'a [u8]>) {
        for chunk in &self.chunks {
            if let Chunk::Var(v) = *chunk {
                target.insert(v);
            }
        }
    }
}

impl<'a> fmt::Debug for Chunk<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let to_str = |body: &[u8]| {
            str::from_utf8(body).unwrap_or("[binary]").to_owned()
        };
        match *self {
            Chunk::Str(b) => write!(f, "Str({:?})", to_str(b)),
            Chunk::Var(b) => write!(f, "Var({:?})", to_str(b)),
        }
    }
}

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

    #[test]
    fn basic_parsing() {
        let parsed = Template::parse(b"Hello, {% who %}!").unwrap();
        let chunks = vec![Chunk::Str(b"Hello, "), Chunk::Var(b"who"), Chunk::Str(b"!")];
        assert_eq!(Template { chunks: chunks }, parsed);
    }
}

<commit_msg>Test escaped vars<commit_after>use std::collections::{HashSet, HashMap};
use std::fmt;
use std::str;

use error::{Error, Result};
use parser;

#[derive(Clone, PartialEq, Eq)]
pub enum Chunk<'a> {
    Str(&'a [u8]),
    Var(&'a [u8]),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Template<'a> {
    chunks: Vec<Chunk<'a>>,
}

impl<'a> Template<'a> {
    pub fn parse(i: &'a [u8]) -> Result<Template<'a>> {
        Ok(Template { chunks: parser::template(i).to_full_result()? })
    }

    pub fn render(&self, vars: &HashMap<&[u8], String>) -> Result<Vec<u8>> {
        let mut buf = Vec::new();
        for chunk in &self.chunks {
            match *chunk {
                Chunk::Str(s) => buf.extend_from_slice(s),
                Chunk::Var(v) => {
                    buf.extend_from_slice(vars.get(v).ok_or(Error::VarNotFound)?.as_bytes())
                }
            }
        }
        Ok(buf)
    }

    pub fn extract_vars(&self, target: &mut HashSet<&'a [u8]>) {
        for chunk in &self.chunks {
            if let Chunk::Var(v) = *chunk {
                target.insert(v);
            }
        }
    }
}

impl<'a> fmt::Debug for Chunk<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let to_str = |body: &[u8]| {
            str::from_utf8(body).unwrap_or("[binary]").to_owned()
        };
        match *self {
            Chunk::Str(b) => write!(f, "Str({:?})", to_str(b)),
            Chunk::Var(b) => write!(f, "Var({:?})", to_str(b)),
        }
    }
}

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

    #[test]
    fn basic_parsing() {
        let parsed = Template::parse(b"Hello, {% who %}!").unwrap();
        let chunks = vec![Chunk::Str(b"Hello, "), Chunk::Var(b"who"), Chunk::Str(b"!")];
        assert_eq!(Template { chunks: chunks }, parsed);
    }

    #[test]
    fn escaped_parsing() {
        let parsed = Template::parse(b"Hello, \\{% who %}!").unwrap();
        let chunks = vec![Chunk::Str(b"Hello, {% who %}!")];
        assert_eq!(Template { chunks: chunks }, parsed)
    }
}

<|endoftext|>


<commit_before>//! `TlsItem` represents item types that are serialized into TLS stream.
//!
//! There are several macros implementing common patterns:
//!
//! -   `tls_array` for fixed-length vector
//! -   `tls_vec` for variable-length vector
//! -   `tls_enum` for TLS enum type
//! -   `tls_struct` for TLS constructed type
//! -   `tls_option` for `Option<T>`

use std::io::prelude::*;

use util::{ReadExt, WriteExt};
use tls_result::TlsResult;

/// A trait for items that can be serialized at TLS stream.
pub trait TlsItem {
    /// Write an item into TLS stream.
    fn tls_write<W: WriteExt>(&self, writer: &mut W) -> TlsResult<()>;
    /// Read an item from TLS stream.
    fn tls_read<R: ReadExt>(reader: &mut R) -> TlsResult<Self>;
    /// Returns the length of serialized bytes.
    fn tls_size(&self) -> u64;
}

// implementation of `TlsItem` for primitive integer types like `u8`
macro_rules! tls_primitive {
    ($t:ident) => (
        impl TlsItem for $t {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                try_write_num!($t, writer, *self);
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$t> {
                let u = try_read_num!($t, reader);
                Ok(u)
            }

            fn tls_size(&self) -> u64 { num_size!($t) }
        }
    )
}

tls_primitive!(u8);
tls_primitive!(u16);
tls_primitive!(u32);
tls_primitive!(u64);

macro_rules! tls_struct {
    (
        struct $name:ident {
            $(
                $item:ident: $t:ty
            ),+
        }
    ) => (
        pub struct $name {
            $(
                pub $item: $t,
            )+
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                $(
                    try!(self.$item.tls_write(writer));
                )+

                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                $(
                    let $item: $t = try!(TlsItem::tls_read(reader));
                )+

                let result = $name {
                    $(
                        $item: $item,
                    )+
                };
                Ok(result)
            }

            fn tls_size(&self) -> u64 {
                let mut size = 0;
                $(
                    size += self.$item.tls_size();
                )+

                size
            }
        }
    )
}

macro_rules! tls_enum {
    (
        $repr_ty:ident,
        $(#[$a:meta])*
        enum $name:ident {
            $(
                $item:ident($n:expr)
            ),+
        }
    ) => (
        enum_from_primitive! {
            #[allow(non_camel_case_types)]
            #[derive(Copy, Clone, PartialEq)]
            $(#[$a])*
            pub enum $name {
                $(
                    $item = $n,
                )+
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                try_write_num!($repr_ty, writer, *self);
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                let num = try_read_num!($repr_ty, reader) as u64;
                let n: Option<$name> = ::num::traits::FromPrimitive::from_u64(num);
                match n {
                    Some(n) => Ok(n),
                    None => tls_err!(::tls_result::TlsErrorKind::DecodeError,
                                     "unexpected number: {}", num),
                }
            }

            fn tls_size(&self) -> u64 {
                num_size!($repr_ty)
            }
        }
    )
}

// fixed-sized u8/opaque array
macro_rules! tls_array {
    ($name:ident = [u8, ..$n:expr]) => (
        pub struct $name(Vec<u8>);

        impl $name {
            pub fn new(v: Vec<u8>) -> $crate::tls_result::TlsResult<$name> {
                let n: usize = $n;
                let len = v.len();
                if len != n {
                    return tls_err!($crate::tls_result::TlsErrorKind::InternalError,
                                    "bad size: {} != {}", len, n);
                } else {
                    Ok($name(v))
                }
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> $crate::tls_result::TlsResult<()> {
                try!(writer.write(&self.0));
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> $crate::tls_result::TlsResult<$name> {
                let data = try!(reader.read_exact($n));
                Ok($name(data))
            }

            fn tls_size(&self) -> u64 {
                $n
            }
        }

        impl ::std::ops::Deref for $name {
            type Target = [u8];
            fn deref<'a>(&'a self) -> &'a [u8] {
                &self.0
            }
        }
    )
}

macro_rules! tls_vec {
    // $item_ty must implement TlsItem
    ($name:ident = $item_ty:ident($size_min:expr, $size_max:expr)) => (
        pub struct $name(Vec<$item_ty>);
        impl $name {
            pub fn new(v: Vec<$item_ty>) -> $crate::tls_result::TlsResult<$name> {
                #![allow(unused_comparisons)] // disable warnings for e.g. `size < 0`

                let size_min: u64 = $size_min;
                let size_max: u64 = $size_max;

                let ret = $name(v);
                let size: u64 = ret.data_size();
                if size < size_min {
                    return tls_err!($crate::tls_result::TlsErrorKind::DecodeError,
                                    "bad size: {} < {}",
                                    size,
                                    size_min);
                } else if size > size_max {
                    return tls_err!($crate::tls_result::TlsErrorKind::DecodeError,
                    "bad size: {} > {}",
                    size,
                    size_max);
                } else {
                    Ok(ret)
                }
            }

            pub fn unwrap(self) -> Vec<$item_ty> {
                let $name(data) = self;
                data
            }

            fn data_size(&self) -> u64 {
                let mut size = 0u64;
                for item in (**self).iter() {
                    size += item.tls_size();
                }
                size
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                let len = self.data_size();

                let size_max: u64 = $size_max;

                if size_max < 1 << 8 {
                    try_write_num!(u8, writer, len);
                } else if size_max < 1 << 16 {
                    try_write_num!(u16, writer, len);
                } else if size_max < 1 << 24 {
                    try_write_num!(u24, writer, len);
                } else if size_max < 1 << 32 {
                    try_write_num!(u32, writer, len);
                } else {
                    try_write_num!(u64, writer, len);
                }

                for item in (**self).iter() {
                    try!(item.tls_write(writer));
                }

                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                let size_max: u64 = $size_max;

                let self_size = if size_max < 1 << 8 {
                    (try_read_num!(u8, reader)) as u64
                } else if size_max < 1 << 16 {
                    (try_read_num!(u16, reader)) as u64
                } else if size_max < 1 << 24 {
                    (try_read_num!(u24, reader)) as u64
                } else if size_max < 1 << 32 {
                    (try_read_num!(u32, reader)) as u64
                } else {
                    (try_read_num!(u64, reader)) as u64
                };

                let mut items_size = 0u64;
                let mut items = Vec::new();
                while items_size < self_size {
                    let item: $item_ty = try!(TlsItem::tls_read(reader));
                    items_size += item.tls_size();
                    items.push(item);
                }
                if items_size != self_size {
                    return tls_err!(::tls_result::TlsErrorKind::DecodeError,
                                    "wrong size: {} expected, {} found",
                                    self_size,
                                    items_size);
                }

                $name::new(items)
            }

            fn tls_size(&self) -> u64 {
                let mut size = 0;

                let size_max: u64 = $size_max;

                if size_max < 1 << 8 {
                    size += 1;
                } else if size_max < 1 << 16 {
                    size += 2;
                } else if size_max < 1 << 24 {
                    size += 3;
                } else if size_max < 1 << 32 {
                    size += 4;
                } else {
                    size += 8;
                }

                size += self.data_size();
                size
            }
        }

        impl ::std::ops::Deref for $name {
            type Target = [$item_ty];
            fn deref<'a>(&'a self) -> &'a [$item_ty] {
                &self.0
            }
        }
    )
}

// this only works when the item is at the last of stream
macro_rules! tls_option {
    ($t:ty) => (
        impl TlsItem for Option<$t> {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                match *self {
                    Some(ref data) => {
                        try!(data.tls_write(writer));
                    }
                    None => {}
                }
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<Option<$t>> {
                let mut rest = vec![];
                let len = try!(reader.read_to_end(&mut rest));
                if len == 0 {
                    return Ok(None);
                }

                let mut rest_reader = ::std::io::Cursor::new(rest);
                let extensions: $t = try!(TlsItem::tls_read(&mut rest_reader));
                Ok(Some(extensions))
            }

            fn tls_size(&self) -> u64 {
                match *self {
                    Some(ref data) => data.tls_size(),
                    None => 0,
                }
            }
        }
    )
}

// for macros
pub struct DummyItem;

impl TlsItem for DummyItem {
    fn tls_write<W: WriteExt>(&self, _writer: &mut W) -> TlsResult<()> { Ok(()) }
    fn tls_read<R: ReadExt>(_reader: &mut R) -> TlsResult<DummyItem> { Ok(DummyItem) }
    fn tls_size(&self) -> u64 { 0 }
}

// obsucre data received from TLS stream.
// since the semantic is unknown, it is only meaningful to read until end of stream is reached.
pub struct ObscureData(Vec<u8>);

impl TlsItem for ObscureData {
    fn tls_write<W: WriteExt>(&self, writer: &mut W) -> TlsResult<()> {
        try!(writer.write_all(&self.0));
        Ok(())
    }

    fn tls_read<R: ReadExt>(reader: &mut R) -> TlsResult<ObscureData> {
        let mut data = vec![];
        let _len = try!(reader.read_to_end(&mut data));
        Ok(ObscureData(data))
    }

    fn tls_size(&self) -> u64 { self.0.len() as u64 }
}

impl ObscureData {
    pub fn new(data: Vec<u8>) -> ObscureData {
        ObscureData(data)
    }

    pub fn unwrap(self) -> Vec<u8> {
        let ObscureData(data) = self;
        data
    }
}

impl ::std::ops::Deref for ObscureData {
    type Target = [u8];
    fn deref<'a>(&'a self) -> &'a [u8] {
        &self.0
    }
}
<commit_msg>fix(TlsItem): use Sized trait for Self. `TlsResult<Self> where Self: Sized`<commit_after>//! `TlsItem` represents item types that are serialized into TLS stream.
//!
//! There are several macros implementing common patterns:
//!
//! -   `tls_array` for fixed-length vector
//! -   `tls_vec` for variable-length vector
//! -   `tls_enum` for TLS enum type
//! -   `tls_struct` for TLS constructed type
//! -   `tls_option` for `Option<T>`

use std::io::prelude::*;

use util::{ReadExt, WriteExt};
use tls_result::TlsResult;

/// A trait for items that can be serialized at TLS stream.
pub trait TlsItem {
    /// Write an item into TLS stream.
    fn tls_write<W: WriteExt>(&self, writer: &mut W) -> TlsResult<()>;
    /// Read an item from TLS stream.
    fn tls_read<R: ReadExt>(reader: &mut R) -> TlsResult<Self> where Self: Sized;
    /// Returns the length of serialized bytes.
    fn tls_size(&self) -> u64;
}

// implementation of `TlsItem` for primitive integer types like `u8`
macro_rules! tls_primitive {
    ($t:ident) => (
        impl TlsItem for $t {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                try_write_num!($t, writer, *self);
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$t> {
                let u = try_read_num!($t, reader);
                Ok(u)
            }

            fn tls_size(&self) -> u64 { num_size!($t) }
        }
    )
}

tls_primitive!(u8);
tls_primitive!(u16);
tls_primitive!(u32);
tls_primitive!(u64);

macro_rules! tls_struct {
    (
        struct $name:ident {
            $(
                $item:ident: $t:ty
            ),+
        }
    ) => (
        pub struct $name {
            $(
                pub $item: $t,
            )+
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                $(
                    try!(self.$item.tls_write(writer));
                )+

                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                $(
                    let $item: $t = try!(TlsItem::tls_read(reader));
                )+

                let result = $name {
                    $(
                        $item: $item,
                    )+
                };
                Ok(result)
            }

            fn tls_size(&self) -> u64 {
                let mut size = 0;
                $(
                    size += self.$item.tls_size();
                )+

                size
            }
        }
    )
}

macro_rules! tls_enum {
    (
        $repr_ty:ident,
        $(#[$a:meta])*
        enum $name:ident {
            $(
                $item:ident($n:expr)
            ),+
        }
    ) => (
        enum_from_primitive! {
            #[allow(non_camel_case_types)]
            #[derive(Copy, Clone, PartialEq)]
            $(#[$a])*
            pub enum $name {
                $(
                    $item = $n,
                )+
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                try_write_num!($repr_ty, writer, *self);
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                let num = try_read_num!($repr_ty, reader) as u64;
                let n: Option<$name> = ::num::traits::FromPrimitive::from_u64(num);
                match n {
                    Some(n) => Ok(n),
                    None => tls_err!(::tls_result::TlsErrorKind::DecodeError,
                                     "unexpected number: {}", num),
                }
            }

            fn tls_size(&self) -> u64 {
                num_size!($repr_ty)
            }
        }
    )
}

// fixed-sized u8/opaque array
macro_rules! tls_array {
    ($name:ident = [u8, ..$n:expr]) => (
        pub struct $name(Vec<u8>);

        impl $name {
            pub fn new(v: Vec<u8>) -> $crate::tls_result::TlsResult<$name> {
                let n: usize = $n;
                let len = v.len();
                if len != n {
                    return tls_err!($crate::tls_result::TlsErrorKind::InternalError,
                                    "bad size: {} != {}", len, n);
                } else {
                    Ok($name(v))
                }
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> $crate::tls_result::TlsResult<()> {
                try!(writer.write(&self.0));
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> $crate::tls_result::TlsResult<$name> {
                let data = try!(reader.read_exact($n));
                Ok($name(data))
            }

            fn tls_size(&self) -> u64 {
                $n
            }
        }

        impl ::std::ops::Deref for $name {
            type Target = [u8];
            fn deref<'a>(&'a self) -> &'a [u8] {
                &self.0
            }
        }
    )
}

macro_rules! tls_vec {
    // $item_ty must implement TlsItem
    ($name:ident = $item_ty:ident($size_min:expr, $size_max:expr)) => (
        pub struct $name(Vec<$item_ty>);
        impl $name {
            pub fn new(v: Vec<$item_ty>) -> $crate::tls_result::TlsResult<$name> {
                #![allow(unused_comparisons)] // disable warnings for e.g. `size < 0`

                let size_min: u64 = $size_min;
                let size_max: u64 = $size_max;

                let ret = $name(v);
                let size: u64 = ret.data_size();
                if size < size_min {
                    return tls_err!($crate::tls_result::TlsErrorKind::DecodeError,
                                    "bad size: {} < {}",
                                    size,
                                    size_min);
                } else if size > size_max {
                    return tls_err!($crate::tls_result::TlsErrorKind::DecodeError,
                    "bad size: {} > {}",
                    size,
                    size_max);
                } else {
                    Ok(ret)
                }
            }

            pub fn unwrap(self) -> Vec<$item_ty> {
                let $name(data) = self;
                data
            }

            fn data_size(&self) -> u64 {
                let mut size = 0u64;
                for item in (**self).iter() {
                    size += item.tls_size();
                }
                size
            }
        }

        impl TlsItem for $name {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                let len = self.data_size();

                let size_max: u64 = $size_max;

                if size_max < 1 << 8 {
                    try_write_num!(u8, writer, len);
                } else if size_max < 1 << 16 {
                    try_write_num!(u16, writer, len);
                } else if size_max < 1 << 24 {
                    try_write_num!(u24, writer, len);
                } else if size_max < 1 << 32 {
                    try_write_num!(u32, writer, len);
                } else {
                    try_write_num!(u64, writer, len);
                }

                for item in (**self).iter() {
                    try!(item.tls_write(writer));
                }

                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<$name> {
                let size_max: u64 = $size_max;

                let self_size = if size_max < 1 << 8 {
                    (try_read_num!(u8, reader)) as u64
                } else if size_max < 1 << 16 {
                    (try_read_num!(u16, reader)) as u64
                } else if size_max < 1 << 24 {
                    (try_read_num!(u24, reader)) as u64
                } else if size_max < 1 << 32 {
                    (try_read_num!(u32, reader)) as u64
                } else {
                    (try_read_num!(u64, reader)) as u64
                };

                let mut items_size = 0u64;
                let mut items = Vec::new();
                while items_size < self_size {
                    let item: $item_ty = try!(TlsItem::tls_read(reader));
                    items_size += item.tls_size();
                    items.push(item);
                }
                if items_size != self_size {
                    return tls_err!(::tls_result::TlsErrorKind::DecodeError,
                                    "wrong size: {} expected, {} found",
                                    self_size,
                                    items_size);
                }

                $name::new(items)
            }

            fn tls_size(&self) -> u64 {
                let mut size = 0;

                let size_max: u64 = $size_max;

                if size_max < 1 << 8 {
                    size += 1;
                } else if size_max < 1 << 16 {
                    size += 2;
                } else if size_max < 1 << 24 {
                    size += 3;
                } else if size_max < 1 << 32 {
                    size += 4;
                } else {
                    size += 8;
                }

                size += self.data_size();
                size
            }
        }

        impl ::std::ops::Deref for $name {
            type Target = [$item_ty];
            fn deref<'a>(&'a self) -> &'a [$item_ty] {
                &self.0
            }
        }
    )
}

// this only works when the item is at the last of stream
macro_rules! tls_option {
    ($t:ty) => (
        impl TlsItem for Option<$t> {
            fn tls_write<W: WriteExt>(&self, writer: &mut W) -> ::tls_result::TlsResult<()> {
                match *self {
                    Some(ref data) => {
                        try!(data.tls_write(writer));
                    }
                    None => {}
                }
                Ok(())
            }

            fn tls_read<R: ReadExt>(reader: &mut R) -> ::tls_result::TlsResult<Option<$t>> {
                let mut rest = vec![];
                let len = try!(reader.read_to_end(&mut rest));
                if len == 0 {
                    return Ok(None);
                }

                let mut rest_reader = ::std::io::Cursor::new(rest);
                let extensions: $t = try!(TlsItem::tls_read(&mut rest_reader));
                Ok(Some(extensions))
            }

            fn tls_size(&self) -> u64 {
                match *self {
                    Some(ref data) => data.tls_size(),
                    None => 0,
                }
            }
        }
    )
}

// for macros
pub struct DummyItem;

impl TlsItem for DummyItem {
    fn tls_write<W: WriteExt>(&self, _writer: &mut W) -> TlsResult<()> { Ok(()) }
    fn tls_read<R: ReadExt>(_reader: &mut R) -> TlsResult<DummyItem> { Ok(DummyItem) }
    fn tls_size(&self) -> u64 { 0 }
}

// obsucre data received from TLS stream.
// since the semantic is unknown, it is only meaningful to read until end of stream is reached.
pub struct ObscureData(Vec<u8>);

impl TlsItem for ObscureData {
    fn tls_write<W: WriteExt>(&self, writer: &mut W) -> TlsResult<()> {
        try!(writer.write_all(&self.0));
        Ok(())
    }

    fn tls_read<R: ReadExt>(reader: &mut R) -> TlsResult<ObscureData> {
        let mut data = vec![];
        let _len = try!(reader.read_to_end(&mut data));
        Ok(ObscureData(data))
    }

    fn tls_size(&self) -> u64 { self.0.len() as u64 }
}

impl ObscureData {
    pub fn new(data: Vec<u8>) -> ObscureData {
        ObscureData(data)
    }

    pub fn unwrap(self) -> Vec<u8> {
        let ObscureData(data) = self;
        data
    }
}

impl ::std::ops::Deref for ObscureData {
    type Target = [u8];
    fn deref<'a>(&'a self) -> &'a [u8] {
        &self.0
    }
}
<|endoftext|>


<commit_before>fn main() {
    println(" ~~~ SNAKE ~~~ ")
    println("Press A and D to steer.")
    println("Reset with R.")
    println("You can modify \"source/piston_window/snake.rs\" while running.")

    {
        println("External functions:")
        println("===================")
        functions := unwrap(load("source/piston_window/functions.rs"))
        list := functions()
        call(functions, "print_functions", [list])
        println("===================")
    }

    render := unwrap(load("source/piston_window/render.rs"))
    source := "source/piston_window/snake.rs"
    m := unwrap(load(source: source, imports: [render]))

    settings := call_ret(m, "settings", [])
    data := init_data(settings)
    loader := new_loader(interval: settings.reload_interval)
    set(title: call_ret(m, "title", []))
    loop {
        if !next_event() { break }
        if render() {
            call(m, "render", [settings, data])
        }
        if update() {
            dt := unwrap(update_dt())
            // Slow down when window is unfocused.
            dt *= if data.focused { settings.focus_speed } else { settings.unfocus_speed }
            call(m, "update(mut,_,_)", [data, settings, dt])
        }
        event(loader: mut loader, source: source, settings: mut settings, module: mut m)
        key := press_keyboard_key()
        if key != none() {
            key := unwrap(key)
            if key == settings.reset_key {
                data = init_data(settings)
            } else if key == settings.turn_left {
                data.pressing_left = true
            } else if key == settings.turn_right {
                data.pressing_right = true
            }
        }

        key := release_keyboard_key()
        if key != none() {
            key := unwrap(key)
            if key == settings.turn_left {
                data.pressing_left = false
            } else if key == settings.turn_right {
                data.pressing_right = false
            }
        }

        if focus() {
            data.focused = focus_arg() == some(true)
        }
    }
}

fn init_data(settings) -> {
    data := {
        snake_body: init_snake_body(
            parts: settings.snake_parts,
            size: settings.snake_parts_size
        ),
        snake_angle: 1,
        pressing_left: false,
        pressing_right: false,
        focused: true,
    }
    data.next_snake_body := data.snake_body
    return clone(data)
}

fn init_snake_body_parts_size(parts, size) -> {
    body := []
    // end := [(parts - 1) * size, (parts - 1) * size]
    end := [0, 0]
    for i := 0; i < parts; i += 1 {
        push(mut body, [end[0] - i * size, end[1] - i * size])
    }
    return clone(body)
}

fn new_loader_interval(interval) -> {
    return {
        time: 0,
        last_reload: 0,
        reload_interval: clone(interval),
        got_error: false
    }
}

fn should_reload(loader) -> {
    return !loader.got_error
        && ((loader.last_reload + loader.reload_interval) < loader.time)
}

fn event_loader_source_settings_module(mut loader, source, mut settings, mut m) {
    if update() {
        dt := unwrap(update_dt())
        loader.time += dt
        if should_reload(loader) {
            loader.last_reload = clone(loader.time)
            new_m := load(source)
            if is_err(new_m) {
                loader.got_error = true
                println(unwrap_err(new_m))
                println(" ~~~ Hit F1 to reload ~~~ ")
            } else {
                loader.got_error = false
                m = unwrap(new_m)
                settings = call_ret(m, "settings", [])
                loader.reload_interval = clone(settings.reload_interval)
            }
        }
    }
    if press() {
        key := press_keyboard_key()
        if key == some(settings.reload_key) {
            println(" ~~~ Reloading ~~~ ")
            loader.got_error = false
        }
    }
}
<commit_msg>Fix bug piston_window example<commit_after>fn main() {
    println(" ~~~ SNAKE ~~~ ")
    println("Press A and D to steer.")
    println("Reset with R.")
    println("You can modify \"source/piston_window/snake.rs\" while running.")

    {
        println("External functions:")
        println("===================")
        functions := unwrap(load("source/piston_window/functions.rs"))
        list := functions()
        call(functions, "print_functions", [list])
        println("===================")
    }

    render := unwrap(load("source/piston_window/render.rs"))
    source := "source/piston_window/snake.rs"
    m := unwrap(load(source: source, imports: [render]))

    settings := call_ret(m, "settings", [])
    data := init_data(settings)
    loader := new_loader(interval: settings.reload_interval)
    set(title: call_ret(m, "title", []))
    loop {
        if !next_event() { break }
        if render() {
            call(m, "render", [settings, data])
        }
        if update() {
            dt := unwrap(update_dt())
            // Slow down when window is unfocused.
            dt *= if data.focused { settings.focus_speed } else { settings.unfocus_speed }
            call(m, "update(mut,_,_)", [data, settings, dt])
        }
        event(loader: mut loader, source: source,
              settings: mut settings, module: mut m,
              imports: [render])
        key := press_keyboard_key()
        if key != none() {
            key := unwrap(key)
            if key == settings.reset_key {
                data = init_data(settings)
            } else if key == settings.turn_left {
                data.pressing_left = true
            } else if key == settings.turn_right {
                data.pressing_right = true
            }
        }

        key := release_keyboard_key()
        if key != none() {
            key := unwrap(key)
            if key == settings.turn_left {
                data.pressing_left = false
            } else if key == settings.turn_right {
                data.pressing_right = false
            }
        }

        if focus() {
            data.focused = focus_arg() == some(true)
        }
    }
}

fn init_data(settings) -> {
    data := {
        snake_body: init_snake_body(
            parts: settings.snake_parts,
            size: settings.snake_parts_size
        ),
        snake_angle: 1,
        pressing_left: false,
        pressing_right: false,
        focused: true,
    }
    data.next_snake_body := data.snake_body
    return clone(data)
}

fn init_snake_body_parts_size(parts, size) -> {
    body := []
    // end := [(parts - 1) * size, (parts - 1) * size]
    end := [0, 0]
    for i := 0; i < parts; i += 1 {
        push(mut body, [end[0] - i * size, end[1] - i * size])
    }
    return clone(body)
}

fn new_loader_interval(interval) -> {
    return {
        time: 0,
        last_reload: 0,
        reload_interval: clone(interval),
        got_error: false
    }
}

fn should_reload(loader) -> {
    return !loader.got_error
        && ((loader.last_reload + loader.reload_interval) < loader.time)
}

fn event_loader_source_settings_module_imports(mut loader, source, mut settings, mut m, imports) {
    if update() {
        dt := unwrap(update_dt())
        loader.time += dt
        if should_reload(loader) {
            loader.last_reload = clone(loader.time)
            new_m := load(source: source, imports: imports)
            if is_err(new_m) {
                loader.got_error = true
                println(unwrap_err(new_m))
                println(" ~~~ Hit F1 to reload ~~~ ")
            } else {
                loader.got_error = false
                m = unwrap(new_m)
                settings = call_ret(m, "settings", [])
                loader.reload_interval = clone(settings.reload_interval)
            }
        }
    }
    if press() {
        key := press_keyboard_key()
        if key == some(settings.reload_key) {
            println(" ~~~ Reloading ~~~ ")
            loader.got_error = false
        }
    }
}
<|endoftext|>


<commit_before>// test double attrs

#![feature(plugin, custom_attribute)]
#![plugin(flamer)]
#![flame("e")]

extern crate flame;

#[flame]
fn a() {
    // nothing to do here
}

fn b() {
    a()
}

#[noflame]
fn c() {
    b()
}

#[test]
fn main() {
    c();
    let spans = flame::spans();
    assert_eq!(1, spans.len());
    let roots = &spans[0];
    println!("{:?}",roots);
    // if more than 2 roots, a() was flamed twice or c was flamed
    // main is missing because main isn't closed here
    assert_eq!("e::b", roots.name);
    assert_eq!(1, roots.children.len());
    assert_eq!("a", roots.children[0].name);
}
<commit_msg>Make test more useful<commit_after>// test optional prefix

#![feature(plugin, custom_attribute)]
#![plugin(flamer)]

extern crate flame;

#[flame("top")]
fn a() {
    let l = Lower {};
    l.a();
}

#[flame]
fn b() {
    a()
}

#[noflame]
fn c() {
    b()
}

pub struct Lower {

}

impl Lower {
    #[flame("lower")]
    pub fn a(self) {
        // nothing to do here
    }
}

#[test]
fn main() {
    c();
    let spans = flame::spans();
    assert_eq!(1, spans.len());
    let roots = &spans[0];
    println!("{:?}",roots);
    // if more than 2 roots, a() was flamed twice or c was flamed
    // main is missing because main isn't closed here
    assert_eq!("b", roots.name);
    assert_eq!(1, roots.children.len());
    assert_eq!("top::a", roots.children[0].name);
    assert_eq!(1, roots.children[0].children.len());
    assert_eq!("lower::a", roots.children[0].children[0].name);
}
<|endoftext|>


<commit_before>#![allow(clippy::if_then_panic, clippy::map_unwrap_or)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "ac2d9fc509e36d1b32513744adf58c34bcc4f43c";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // TODO: ~const in where-clause
    // https://github.com/dtolnay/syn/issues/1051
    "library/alloc/src/borrow.rs",
    "src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Resolve map_unwrap_or pedantic clippy lint<commit_after>#![allow(clippy::if_then_panic)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "ac2d9fc509e36d1b32513744adf58c34bcc4f43c";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // TODO: ~const in where-clause
    // https://github.com/dtolnay/syn/issues/1051
    "library/alloc/src/borrow.rs",
    "src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map_or(true, |e| e != "rs") {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate pastebin_rust_api;

#[cfg(test)]
mod tests {
    use pastebin_rust_api::{Paster, Access, Expiration, Format};

    #[test]
    fn test_post() {
        let paster = Paster::new(None);
        let response = paster.paste("",
                                    Some(&Access::Private),
                                    Some("TestHtml"),
                                    Some(&Expiration::TenMinutes),
                                    Some(&Format::HTML5),
                                    None);
        assert!(response.is_ok());
        if let Some(message) = response.ok() {
            println!("URL: {}", message.content);
        }
    }

    #[test]
    fn test_login() {
        let paster = Paster::new(None);
        let response = paster.login(None, None);
        assert!(response.is_ok());
        if let Some(user_key) = response.ok() {
            println!("user_key: {}", user_key.content);
        }
    }

    #[test]
    fn test_login_post() {
        let paster = Paster::new(None);
        let user_key_response = paster.login(None, None);
        assert!(user_key_response.is_ok());
        if let Some(user_key) = user_key_response.ok() {
            let url_response = paster.paste("",
                                            Some(&Access::Private),
                                            Some("TestHtml"),
                                            Some(&Expiration::TenMinutes),
                                            Some(&Format::HTML5),
                                            Some(&user_key.content));
            assert!(url_response.is_ok());
            if let Some(message) = url_response.ok() {
                println!("URL: {}", message.content);
            }
        }
    }

    #[test]
    fn test_file_post() {
        let paster = Paster::new(None);
        let response = paster.paste_from_file("test.html",
                                              Some(&Access::Private),
                                              Some("TestHtml"),
                                              Some(&Expiration::TenMinutes),
                                              Some(&Format::HTML5),
                                              None);
        assert!(response.is_ok());
        if let Some(message) = response.ok() {
            println!("URL: {}", message.content);
        }
    }

    #[test]
    fn test_trending() {
        let paster = Paster::new(None);
        let trending = paster.get_trending_posts();
        assert!(trending.is_ok());
        if let Some(trending) = trending.ok() {
            println!("URL: {}", trending[0].url);
        }
    }
}
<commit_msg>Changed private to unlisted<commit_after>extern crate pastebin_rust_api;

#[cfg(test)]
mod tests {
    use pastebin_rust_api::{Paster, Access, Expiration, Format};

    #[test]
    fn test_post() {
        let paster = Paster::new(None);
        let response = paster.paste("",
                                    Some(&Access::Unlisted),
                                    Some("TestHtml"),
                                    Some(&Expiration::TenMinutes),
                                    Some(&Format::HTML5),
                                    None);
        assert!(response.is_ok());
        if let Some(message) = response.ok() {
            println!("URL: {}", message.content);
        }
    }

    #[test]
    fn test_login() {
        let paster = Paster::new(None);
        let response = paster.login(None, None);
        assert!(response.is_ok());
        if let Some(user_key) = response.ok() {
            println!("user_key: {}", user_key.content);
        }
    }

    #[test]
    fn test_login_post() {
        let paster = Paster::new(None);
        let user_key_response = paster.login(None, None);
        assert!(user_key_response.is_ok());
        if let Some(user_key) = user_key_response.ok() {
            let url_response = paster.paste("",
                                            Some(&Access::Unlisted),
                                            Some("TestHtml"),
                                            Some(&Expiration::TenMinutes),
                                            Some(&Format::HTML5),
                                            Some(&user_key.content));
            assert!(url_response.is_ok());
            if let Some(message) = url_response.ok() {
                println!("URL: {}", message.content);
            }
        }
    }

    #[test]
    fn test_file_post() {
        let paster = Paster::new(None);
        let response = paster.paste_from_file("test.html",
                                              Some(&Access::Unlisted),
                                              Some("TestHtml"),
                                              Some(&Expiration::TenMinutes),
                                              Some(&Format::HTML5),
                                              None);
        assert!(response.is_ok());
        if let Some(message) = response.ok() {
            println!("URL: {}", message.content);
        }
    }

    #[test]
    fn test_trending() {
        let paster = Paster::new(None);
        let trending = paster.get_trending_posts();
        assert!(trending.is_ok());
        if let Some(trending) = trending.ok() {
            println!("URL: {}", trending[0].url);
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::Mutex;

macro_rules! cargo_script {
    ($($args:expr),* $(,)*) => {
        {
            extern crate tempdir;
            use std::process::Command;

            let cargo_lock = ::util::CARGO_MUTEX.lock().expect("could not acquire Cargo mutext");

            let temp_dir = tempdir::TempDir::new("cargo-script-test").unwrap();
            let cmd_str;
            let out = {
                let mut cmd = Command::new("target/debug/cargo-script");
                cmd.arg("script");
                cmd.arg("--pkg-path").arg(temp_dir.path());
                $(
                    cmd.arg($args);
                )*

                cmd_str = format!("{:?}", cmd);

                cmd.output()
                    .map(::util::Output::from)
            };

            if let Ok(out) = out.as_ref() {
                println!("cargo-script cmd: {}", cmd_str);
                println!("cargo-script stdout:");
                println!("-----");
                println!("{}", out.stdout);
                println!("-----");
                println!("cargo-script stderr:");
                println!("-----");
                println!("{}", out.stderr);
                println!("-----");
            }

            drop(temp_dir);
            drop(cargo_lock);

            out
        }
    };
}

macro_rules! with_output_marker {
    (prelude $p:expr; $e:expr) => {
        format!(concat!($p, "{}", $e), ::util::OUTPUT_MARKER_CODE)
    };

    ($e:expr) => {
        format!(concat!("{}", $e), ::util::OUTPUT_MARKER_CODE)
    };
}

lazy_static! {
    #[doc(hidden)]
    pub static ref CARGO_MUTEX: Mutex<()> = Mutex::new(());
}

pub const OUTPUT_MARKER: &'static str = "--output--";
pub const OUTPUT_MARKER_CODE: &'static str = "println!(\"--output--\");";

pub struct Output {
    pub status: ::std::process::ExitStatus,
    pub stdout: String,
    pub stderr: String,
}

impl Output {
    pub fn stdout_output(&self) -> &str {
        assert!(self.success());
        for marker in self.stdout.matches(OUTPUT_MARKER) {
            let i = subslice_offset(&self.stdout, marker).unwrap();
            let before_cp = self.stdout[..i].chars().rev().next().unwrap();
            if !(before_cp == '\r' || before_cp == '\n') { continue; }
            let after = &self.stdout[i+OUTPUT_MARKER.len()..];
            let after_cp = after.chars().next().unwrap();
            if !(after_cp == '\r' || after_cp == '\n') { continue; }
            return after;
        }
        panic!("could not find `{}` in script output", OUTPUT_MARKER);
    }

    pub fn success(&self) -> bool {
        self.status.success()
    }
}

impl From<::std::process::Output> for Output {
    fn from(v: ::std::process::Output) -> Self {
        Output {
            status: v.status,
            stdout: String::from_utf8(v.stdout).unwrap(),
            stderr: String::from_utf8(v.stderr).unwrap(),
        }
    }
}

fn subslice_offset(outer: &str, inner: &str) -> Option<usize> {
    let outer_beg = outer.as_ptr() as usize;
    let inner = inner.as_ptr() as usize;
    if inner < outer_beg || inner > outer_beg.wrapping_add(outer.len()) {
        None
    } else {
        Some(inner.wrapping_sub(outer_beg))
    }
}
<commit_msg>Improved test code to deal with newer cargo.<commit_after>use std::sync::Mutex;

macro_rules! cargo_script {
    ($($args:expr),* $(,)*) => {
        {
            extern crate tempdir;
            use std::process::Command;

            let cargo_lock = ::util::CARGO_MUTEX.lock().expect("could not acquire Cargo mutext");

            let temp_dir = tempdir::TempDir::new("cargo-script-test").unwrap();
            let cmd_str;
            let out = {
                let mut cmd = Command::new("target/debug/cargo-script");
                cmd.arg("script");
                cmd.arg("--pkg-path").arg(temp_dir.path());
                $(
                    cmd.arg($args);
                )*

                cmd_str = format!("{:?}", cmd);

                cmd.output()
                    .map(::util::Output::from)
            };

            if let Ok(out) = out.as_ref() {
                println!("cargo-script cmd: {}", cmd_str);
                println!("cargo-script stdout:");
                println!("-----");
                println!("{}", out.stdout);
                println!("-----");
                println!("cargo-script stderr:");
                println!("-----");
                println!("{}", out.stderr);
                println!("-----");
            }

            drop(temp_dir);
            drop(cargo_lock);

            out
        }
    };
}

macro_rules! with_output_marker {
    (prelude $p:expr; $e:expr) => {
        format!(concat!($p, "{}", $e), ::util::OUTPUT_MARKER_CODE)
    };

    ($e:expr) => {
        format!(concat!("{}", $e), ::util::OUTPUT_MARKER_CODE)
    };
}

lazy_static! {
    #[doc(hidden)]
    pub static ref CARGO_MUTEX: Mutex<()> = Mutex::new(());
}

pub const OUTPUT_MARKER: &'static str = "--output--";
pub const OUTPUT_MARKER_CODE: &'static str = "println!(\"--output--\");";

pub struct Output {
    pub status: ::std::process::ExitStatus,
    pub stdout: String,
    pub stderr: String,
}

impl Output {
    pub fn stdout_output(&self) -> &str {
        assert!(self.success());
        for marker in self.stdout.matches(OUTPUT_MARKER) {
            let i = subslice_offset(&self.stdout, marker)
                .expect("couldn't find marker in output");
            let before_cp = self.stdout[..i].chars().rev().next()
                .unwrap_or('\n');
            if !(before_cp == '\r' || before_cp == '\n') { continue; }
            let after = &self.stdout[i+OUTPUT_MARKER.len()..];
            let after_cp = after.chars().next()
                .expect("couldn't find cp after marker");
            if !(after_cp == '\r' || after_cp == '\n') { continue; }
            return after;
        }
        panic!("could not find `{}` in script output", OUTPUT_MARKER);
    }

    pub fn success(&self) -> bool {
        self.status.success()
    }
}

impl From<::std::process::Output> for Output {
    fn from(v: ::std::process::Output) -> Self {
        Output {
            status: v.status,
            stdout: String::from_utf8(v.stdout).unwrap(),
            stderr: String::from_utf8(v.stderr).unwrap(),
        }
    }
}

fn subslice_offset(outer: &str, inner: &str) -> Option<usize> {
    let outer_beg = outer.as_ptr() as usize;
    let inner = inner.as_ptr() as usize;
    if inner < outer_beg || inner > outer_beg.wrapping_add(outer.len()) {
        None
    } else {
        Some(inner.wrapping_sub(outer_beg))
    }
}
<|endoftext|>


<commit_before>use crate::borrow_check::location::{LocationIndex, LocationTable};
use crate::dataflow::indexes::MovePathIndex;
use crate::dataflow::move_paths::{LookupResult, MoveData};
use crate::util::liveness::{categorize, DefUse};
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
use rustc::ty::subst::GenericArg;
use rustc::ty::Ty;

use super::TypeChecker;

type VarPointRelations = Vec<(Local, LocationIndex)>;
type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;

struct UseFactsExtractor<'me> {
    var_defined: &'me mut VarPointRelations,
    var_used: &'me mut VarPointRelations,
    location_table: &'me LocationTable,
    var_drop_used: &'me mut Vec<(Local, Location)>,
    move_data: &'me MoveData<'me>,
    path_accessed_at: &'me mut MovePathPointRelations,
}

// A Visitor to walk through the MIR and extract point-wise facts
impl UseFactsExtractor<'_> {
    fn location_to_index(&self, location: Location) -> LocationIndex {
        self.location_table.mid_index(location)
    }

    fn insert_def(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_def()");
        self.var_defined.push((local, self.location_to_index(location)));
    }

    fn insert_use(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_use()");
        self.var_used.push((local, self.location_to_index(location)));
    }

    fn insert_drop_use(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_drop_use()");
        self.var_drop_used.push((local, location));
    }

    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
        debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
        self.path_accessed_at.push((path, self.location_to_index(location)));
    }

    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
        match self.move_data.rev_lookup.find(place.as_ref()) {
            LookupResult::Exact(mpi) => Some(mpi),
            LookupResult::Parent(mmpi) => mmpi,
        }
    }
}

impl Visitor<'tcx> for UseFactsExtractor<'_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
        match categorize(context) {
            Some(DefUse::Def) => self.insert_def(local, location),
            Some(DefUse::Use) => self.insert_use(local, location),
            Some(DefUse::Drop) => self.insert_drop_use(local, location),
            _ => (),
        }
    }

    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
        self.super_place(place, context, location);
        match context {
            PlaceContext::NonMutatingUse(_) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }

            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }
            _ => (),
        }
    }
}

fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty<'tcx>) {
    debug!("add_regions(local={:?}, type={:?})", local, ty);
    typeck.tcx().for_each_free_region(&ty, |region| {
        let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(region);
        debug!("add_regions for region {:?}", region_vid);
        if let Some(facts) = typeck.borrowck_context.all_facts {
            facts.var_uses_region.push((local, region_vid));
        }
    });
}

pub(super) fn populate_access_facts(
    typeck: &mut TypeChecker<'_, 'tcx>,
    body: ReadOnlyBodyAndCache<'_, 'tcx>,
    location_table: &LocationTable,
    move_data: &MoveData<'_>,
    drop_used: &mut Vec<(Local, Location)>,
) {
    debug!("populate_var_liveness_facts()");

    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        UseFactsExtractor {
            var_defined: &mut facts.var_defined,
            var_used: &mut facts.var_used,
            var_drop_used: drop_used,
            path_accessed_at: &mut facts.path_accessed_at,
            location_table,
            move_data,
        }
        .visit_body(body);

        facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
            (local, location_table.mid_index(location))
        }));
    }

    for (local, local_decl) in body.local_decls.iter_enumerated() {
        add_var_uses_regions(typeck, local, local_decl.ty);
    }
}

// For every potentially drop()-touched region `region` in `local`'s type
// (`kind`), emit a Polonius `var_drops_region(local, region)` fact.
pub(super) fn add_var_drops_regions(
    typeck: &mut TypeChecker<'_, 'tcx>,
    local: Local,
    kind: &GenericArg<'tcx>,
) {
    debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind);
    let tcx = typeck.tcx();

    tcx.for_each_free_region(kind, |drop_live_region| {
        let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(drop_live_region);
        if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
            facts.var_drops_region.push((local, region_vid));
        };
    });
}
<commit_msg>cleanup polonius liveness fact generation<commit_after>use crate::borrow_check::location::{LocationIndex, LocationTable};
use crate::dataflow::indexes::MovePathIndex;
use crate::dataflow::move_paths::{LookupResult, MoveData};
use crate::util::liveness::{categorize, DefUse};
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
use rustc::ty::subst::GenericArg;

use super::TypeChecker;

type VarPointRelations = Vec<(Local, LocationIndex)>;
type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;

struct UseFactsExtractor<'me> {
    var_defined: &'me mut VarPointRelations,
    var_used: &'me mut VarPointRelations,
    location_table: &'me LocationTable,
    var_drop_used: &'me mut Vec<(Local, Location)>,
    move_data: &'me MoveData<'me>,
    path_accessed_at: &'me mut MovePathPointRelations,
}

// A Visitor to walk through the MIR and extract point-wise facts
impl UseFactsExtractor<'_> {
    fn location_to_index(&self, location: Location) -> LocationIndex {
        self.location_table.mid_index(location)
    }

    fn insert_def(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_def()");
        self.var_defined.push((local, self.location_to_index(location)));
    }

    fn insert_use(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_use()");
        self.var_used.push((local, self.location_to_index(location)));
    }

    fn insert_drop_use(&mut self, local: Local, location: Location) {
        debug!("LivenessFactsExtractor::insert_drop_use()");
        self.var_drop_used.push((local, location));
    }

    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
        debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
        self.path_accessed_at.push((path, self.location_to_index(location)));
    }

    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
        match self.move_data.rev_lookup.find(place.as_ref()) {
            LookupResult::Exact(mpi) => Some(mpi),
            LookupResult::Parent(mmpi) => mmpi,
        }
    }
}

impl Visitor<'tcx> for UseFactsExtractor<'_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
        match categorize(context) {
            Some(DefUse::Def) => self.insert_def(local, location),
            Some(DefUse::Use) => self.insert_use(local, location),
            Some(DefUse::Drop) => self.insert_drop_use(local, location),
            _ => (),
        }
    }

    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
        self.super_place(place, context, location);
        match context {
            PlaceContext::NonMutatingUse(_) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }

            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }
            _ => (),
        }
    }
}

pub(super) fn populate_access_facts(
    typeck: &mut TypeChecker<'_, 'tcx>,
    body: ReadOnlyBodyAndCache<'_, 'tcx>,
    location_table: &LocationTable,
    move_data: &MoveData<'_>,
    drop_used: &mut Vec<(Local, Location)>,
) {
    debug!("populate_var_liveness_facts()");

    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        UseFactsExtractor {
            var_defined: &mut facts.var_defined,
            var_used: &mut facts.var_used,
            var_drop_used: drop_used,
            path_accessed_at: &mut facts.path_accessed_at,
            location_table,
            move_data,
        }
        .visit_body(body);

        facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
            (local, location_table.mid_index(location))
        }));

        for (local, local_decl) in body.local_decls.iter_enumerated() {
            debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty);
            let universal_regions = &typeck.borrowck_context.universal_regions;
            typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
                let region_vid = universal_regions.to_region_vid(region);
                facts.var_uses_region.push((local, region_vid));
            });
        }
    }
}

// For every potentially drop()-touched region `region` in `local`'s type
// (`kind`), emit a Polonius `var_drops_region(local, region)` fact.
pub(super) fn add_var_drops_regions(
    typeck: &mut TypeChecker<'_, 'tcx>,
    local: Local,
    kind: &GenericArg<'tcx>,
) {
    debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind);
    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        let universal_regions = &typeck.borrowck_context.universal_regions;
        typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| {
            let region_vid = universal_regions.to_region_vid(drop_live_region);
            facts.var_drops_region.push((local, region_vid));
        });
    }
}
<|endoftext|>


<commit_before>// error-pattern: deallocating while item is protected

use std::cell::Cell;

// Check that even `&Cell` are dereferencable.
// Also see <https://github.com/rust-lang/rust/issues/55005>.
fn inner(x: &Cell<i32>, f: fn(&Cell<i32>)) {
    // `f` may mutate, but it may not deallocate!
    f(x)
}

fn main() {
    inner(Box::leak(Box::new(Cell::new(0))), |x| {
        let raw = x as *const _ as *mut Cell<i32>;
        drop(unsafe { Box::from_raw(raw) });
    });
}
<commit_msg>Auto merge of #1069 - RalfJung:typo, r=RalfJung<commit_after>// error-pattern: deallocating while item is protected

use std::cell::Cell;

// Check that even `&Cell` are dereferenceable.
// Also see <https://github.com/rust-lang/rust/issues/55005>.
fn inner(x: &Cell<i32>, f: fn(&Cell<i32>)) {
    // `f` may mutate, but it may not deallocate!
    f(x)
}

fn main() {
    inner(Box::leak(Box::new(Cell::new(0))), |x| {
        let raw = x as *const _ as *mut Cell<i32>;
        drop(unsafe { Box::from_raw(raw) });
    });
}
<|endoftext|>


<commit_before>#![feature(convert)]
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate yak_client;
use std::env;

use yak_client::Client;

fn open_from_env(env_var: &str, name: &str) -> Client {
  let yak_url = env::var(env_var).ok()
    .expect(format!("env var {} not found", env_var).as_str());
  let full_url = format!("{}-{}", yak_url, name);
  Client::connect(&full_url).unwrap()
}

fn open_client(name: &str) -> (Client, Client) {
  let head = open_from_env("YAK_HEAD", name);
  let tail = open_from_env("YAK_TAIL", name);
  (head, tail)
}

#[test]
fn test_put_read_empty() {
  env_logger::init().unwrap_or(());

  let (mut head, mut tail) = open_client("test_put_read_empty");
  let key = "key";

  head.truncate().unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 0);
}

#[test]
fn test_put_read_single_value() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_put_read_single_value");
  let key = "key";
  let val = "value";

  head.truncate().unwrap();

  head.write(key.as_bytes(), val.as_bytes()).unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 1);
  assert_eq!(resp[0].content, val.as_bytes())
}

#[test]
fn test_put_read_persistence() {
  env_logger::init().unwrap_or(());
  let key = "key";
  let val = "value";
  {
    let (mut head, _) = open_client("test_put_read_persistence");

    head.truncate().unwrap();

    head.write(key.as_bytes(), val.as_bytes()).unwrap();
  }

  {
    let (_, mut tail) = open_client("test_put_read_persistence");
    let resp = tail.read(key.as_bytes()).unwrap();
    assert_eq!(resp.len(), 1);
    assert_eq!(resp[0].content, val.as_bytes())
  }
}

#[test]
fn test_put_read_two_values() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_put_read_two_values");
  let key = "key";
  let vals = vec!["a".as_bytes(), "b".as_bytes()];

  head.truncate().unwrap();

  for val in &vals {
    head.write(key.as_bytes(), &val).unwrap();
  }

  let resp = tail.read(key.as_bytes()).unwrap();
  let returned : Vec<Vec<u8>> = resp.iter().map(|v| v.content.clone()).collect();
  assert_eq!(returned, vals);
}

#[test]
fn test_truncate() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_truncate");
  let key = "key";
  let val = "value";

  head.truncate().unwrap();
  head.write(key.as_bytes(), val.as_bytes()).unwrap();
  head.truncate().unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 0);
}
<commit_msg>Remove now useless test.<commit_after>#![feature(convert)]
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate yak_client;
use std::env;

use yak_client::Client;

fn open_from_env(env_var: &str, name: &str) -> Client {
  let yak_url = env::var(env_var).ok()
    .expect(format!("env var {} not found", env_var).as_str());
  let full_url = format!("{}-{}", yak_url, name);
  Client::connect(&full_url).unwrap()
}

fn open_client(name: &str) -> (Client, Client) {
  let head = open_from_env("YAK_HEAD", name);
  let tail = open_from_env("YAK_TAIL", name);
  (head, tail)
}

#[test]
fn test_put_read_empty() {
  env_logger::init().unwrap_or(());

  let (mut head, mut tail) = open_client("test_put_read_empty");
  let key = "key";

  head.truncate().unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 0);
}

#[test]
fn test_put_read_single_value() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_put_read_single_value");
  let key = "key";
  let val = "value";

  head.truncate().unwrap();

  head.write(key.as_bytes(), val.as_bytes()).unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 1);
  assert_eq!(resp[0].content, val.as_bytes())
}

#[test]
fn test_put_read_two_values() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_put_read_two_values");
  let key = "key";
  let vals = vec!["a".as_bytes(), "b".as_bytes()];

  head.truncate().unwrap();

  for val in &vals {
    head.write(key.as_bytes(), &val).unwrap();
  }

  let resp = tail.read(key.as_bytes()).unwrap();
  let returned : Vec<Vec<u8>> = resp.iter().map(|v| v.content.clone()).collect();
  assert_eq!(returned, vals);
}

#[test]
fn test_truncate() {
  env_logger::init().unwrap_or(());
  let (mut head, mut tail) = open_client("test_truncate");
  let key = "key";
  let val = "value";

  head.truncate().unwrap();
  head.write(key.as_bytes(), val.as_bytes()).unwrap();
  head.truncate().unwrap();

  let resp = tail.read(key.as_bytes()).unwrap();
  assert_eq!(resp.len(), 0);
}
<|endoftext|>


<commit_before>extern crate time;
extern crate graphviz;
extern crate getopts;

use dot = graphviz;
use getopts::{optopt, optflag, getopts, OptGroup, Matches};
use std::io::File;
use std::os::args;
use std::rand::{SeedableRng, StdRng};
use time::precise_time_ns;
use std::from_str::FromStr;

use graph::Graph;
use population::Population;

pub mod edge;
pub mod graph;
pub mod nodept;
pub mod population;
pub mod tour;
pub mod graphviz_conv;

static DEFAULT_ITERS: uint = 800;
static DEFAULT_MUT_RATE: f64 = 0.02;
static DEFAULT_POP_SIZE: uint = 200;
static DEFAULT_TOURNAMENT_SIZE: uint = 15;

fn write_to_file(graph: &Graph, file_name: &str) {
    let mut f = File::create(&Path::new(file_name));
    render_to(&mut f, graph);
}

pub fn render_to<W: Writer>(output: &mut W, graph: &Graph) {
    dot::render(graph, output).unwrap()
}

fn usage(program: &str, opts: &[OptGroup]) {
    println!("Usage: {} [options]\n", program);
    for o in opts.iter() {
        println!("-{}\t--{}: {}", o.short_name, o.long_name, o.desc);
    }
}

fn parse_opt<T: FromStr>(matches: &Matches, opt: &str, default: T) -> T {
    match matches.opt_str(opt) {
        Some(o) => from_str::<T>(o.as_slice()).unwrap_or(default),
        None => default
    }
}

fn main() {
    let args: Vec<String> = args().iter().map(|x| x.to_string()).collect();
    let program = args.get(0).clone();

    let opts = [
        optflag("h", "help", "print this help menu"),
        optopt("m", "mutation_rate", "change the mutation rate (default: 0.015)", "MUTRATE"),
        optopt("i", "iters", "change the number of GA iterations (default: 50)", "ITERS"),
        optopt("p", "pop_size", "change the population size (default: 5000)", "POPSIZE"),
        optflag("v", "verbose", "print a lot of information, including timing."),
        optopt("r", "read", "read graph from a .tsp file", "READ"),
        optopt("t", "tournament_size", "change the number of specimens used for tournament selection", "TSIZE")
    ];

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };

    if matches.opt_present("h") {
        usage(program.as_slice(), opts);
        return;
    }
    let v_flag = matches.opt_present("v");

    let node_count = 15;
    let tournament_size = parse_opt::<uint>(&matches, "t", DEFAULT_TOURNAMENT_SIZE);
    let scale = 200.0;
    let mutation_rate = parse_opt::<f64>(&matches, "m", DEFAULT_MUT_RATE);
    let iter_count = parse_opt::<uint>(&matches, "i", DEFAULT_ITERS);
    let population_size = parse_opt::<uint>(&matches, "p", DEFAULT_POP_SIZE);

    let mut graph_opt: Option<Graph> = None;

    if matches.opt_present("r") {
        let file_path = parse_opt::<String>(&matches, "r", String::new());
        if file_path.is_empty() {
            fail!("failed to parse file path")
        }
        graph_opt = Some(Graph::from_file(file_path.as_slice()));
    }
    else {
        // make a seeded RNG for the random graph generation for consistent testing
        let mut s_rng: StdRng = SeedableRng::from_seed(&[12, 13, 14, 15]);
        graph_opt = Some(Graph::random_graph(&mut s_rng, node_count, scale, scale))
    }

    let graph = graph_opt.unwrap();

    if v_flag {
        println!("Running TSP-GA on a graph with |N| = {}, |E| = {}", graph.num_nodes, graph.all_edges().len())
        println!("GA parameters:")
        println!("\tMutation rate = {}", mutation_rate)
        println!("\tPopulation size = {}", population_size)
        println!("\tNumber of iterations = {}", iter_count)
        println!("\tTournament size = {}", tournament_size)
    }

    // RNG for the GA
    let rng: StdRng = match StdRng::new() {
        Ok(r) => r,
        Err(_) => fail!("failed to acquire RNG")
    };

    let mut pop = Population::new(population_size, box graph, mutation_rate, tournament_size, rng);
    let first_result = pop.fittest().total_weight;
    if v_flag {
        println!("Fittest at start: {}", first_result)
    }
    // Evolve the population
    let t0 = precise_time_ns();
    for _ in range(0, iter_count) {
        pop = pop.evolve();
    }
    let t1 = precise_time_ns();

    // Show the end result and the time it took.
    let result = pop.fittest();
    println!("Resulting tour: {}\nwith weight {}", result.nodes, result.total_weight)
    if v_flag {
        let dt = ((t1-t0) as f64) / 1e6;
        println!("t_avg = {} ms, t_overall = {} s", dt / iter_count as f64, dt / 1000.0);
        println!("Improvement factor from first solution: {}", (first_result / result.total_weight))
    }
}<commit_msg>added todo<commit_after>extern crate time;
extern crate graphviz;
extern crate getopts;

// TODO use terminal colors for nicer colored output
//extern crate term;

use dot = graphviz;
use getopts::{optopt, optflag, getopts, OptGroup, Matches};
use std::io::File;
use std::os::args;
use std::rand::{SeedableRng, StdRng};
use time::precise_time_ns;
use std::from_str::FromStr;

use graph::Graph;
use population::Population;

pub mod edge;
pub mod graph;
pub mod nodept;
pub mod population;
pub mod tour;
pub mod graphviz_conv;

static DEFAULT_ITERS: uint = 800;
static DEFAULT_MUT_RATE: f64 = 0.02;
static DEFAULT_POP_SIZE: uint = 200;
static DEFAULT_TOURNAMENT_SIZE: uint = 15;

fn write_to_file(graph: &Graph, file_name: &str) {
    let mut f = File::create(&Path::new(file_name));
    render_to(&mut f, graph);
}

pub fn render_to<W: Writer>(output: &mut W, graph: &Graph) {
    dot::render(graph, output).unwrap()
}

fn usage(program: &str, opts: &[OptGroup]) {
    println!("Usage: {} [options]\n", program);
    for o in opts.iter() {
        println!("-{}\t--{}: {}", o.short_name, o.long_name, o.desc);
    }
}

fn parse_opt<T: FromStr>(matches: &Matches, opt: &str, default: T) -> T {
    match matches.opt_str(opt) {
        Some(o) => from_str::<T>(o.as_slice()).unwrap_or(default),
        None => default
    }
}

fn main() {
    let args: Vec<String> = args().iter().map(|x| x.to_string()).collect();
    let program = args.get(0).clone();

    let opts = [
        optflag("h", "help", "print this help menu"),
        optopt("m", "mutation_rate", "change the mutation rate (default: 0.015)", "MUTRATE"),
        optopt("i", "iters", "change the number of GA iterations (default: 50)", "ITERS"),
        optopt("p", "pop_size", "change the population size (default: 5000)", "POPSIZE"),
        optflag("v", "verbose", "print a lot of information, including timing."),
        optopt("r", "read", "read graph from a .tsp file", "READ"),
        optopt("t", "tournament_size", "change the number of specimens used for tournament selection", "TSIZE")
    ];

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };

    if matches.opt_present("h") {
        usage(program.as_slice(), opts);
        return;
    }
    let v_flag = matches.opt_present("v");

    let node_count = 15;
    let tournament_size = parse_opt::<uint>(&matches, "t", DEFAULT_TOURNAMENT_SIZE);
    let scale = 200.0;
    let mutation_rate = parse_opt::<f64>(&matches, "m", DEFAULT_MUT_RATE);
    let iter_count = parse_opt::<uint>(&matches, "i", DEFAULT_ITERS);
    let population_size = parse_opt::<uint>(&matches, "p", DEFAULT_POP_SIZE);

    let mut graph_opt: Option<Graph> = None;

    if matches.opt_present("r") {
        let file_path = parse_opt::<String>(&matches, "r", String::new());
        if file_path.is_empty() {
            fail!("failed to parse file path")
        }
        graph_opt = Some(Graph::from_file(file_path.as_slice()));
    }
    else {
        // make a seeded RNG for the random graph generation for consistent testing
        let mut s_rng: StdRng = SeedableRng::from_seed(&[12, 13, 14, 15]);
        graph_opt = Some(Graph::random_graph(&mut s_rng, node_count, scale, scale))
    }

    let graph = graph_opt.unwrap();

    if v_flag {
        println!("Running TSP-GA on a graph with |N| = {}, |E| = {}", graph.num_nodes, graph.all_edges().len())
        println!("GA parameters:")
        println!("\tMutation rate = {}", mutation_rate)
        println!("\tPopulation size = {}", population_size)
        println!("\tNumber of iterations = {}", iter_count)
        println!("\tTournament size = {}", tournament_size)
    }

    // RNG for the GA
    let rng: StdRng = match StdRng::new() {
        Ok(r) => r,
        Err(_) => fail!("failed to acquire RNG")
    };

    let mut pop = Population::new(population_size, box graph, mutation_rate, tournament_size, rng);
    let first_result = pop.fittest().total_weight;
    if v_flag {
        println!("Fittest at start: {}", first_result)
    }
    // Evolve the population
    let t0 = precise_time_ns();
    for _ in range(0, iter_count) {
        pop = pop.evolve();
    }
    let t1 = precise_time_ns();

    // Show the end result and the time it took.
    let result = pop.fittest();
    println!("Resulting tour: {}\nwith weight {}", result.nodes, result.total_weight)
    if v_flag {
        let dt = ((t1-t0) as f64) / 1e6;
        println!("t_avg = {} ms, t_overall = {} s", dt / iter_count as f64, dt / 1000.0);
        println!("Improvement factor from first solution: {}", (first_result / result.total_weight))
    }
}<|endoftext|>