<commit_before>use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token, Type};

ast_enum_of_structs! {
    /// A pattern in a local binding, function signature, match expression, or
    /// various other places.
    ///
    /// # Syntax tree enum
    ///
    /// This type is a [syntax tree enum].
    ///
    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
    pub enum Pat {
        /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
        Ident(PatIdent),

        /// A path pattern like `Color::Red`.
        Path(PatPath),

        /// A reference pattern: `&mut var`.
        Reference(PatReference),

        /// A struct or struct variant pattern: `Variant { x, y, .. }`.
        Struct(PatStruct),

        /// A tuple pattern: `(a, b)`.
        Tuple(PatTuple),

        /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
        TupleStruct(PatTupleStruct),

        /// A type ascription pattern: `foo: f64`.
        Type(PatType),

        /// A pattern that matches any value: `_`.
        Wild(PatWild),

        #[doc(hidden)]
        __Nonexhaustive,
    }
}

ast_struct! {
    /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
    pub struct PatIdent {
        pub attrs: Vec<Attribute>,
        pub by_ref: Option<Token![ref]>,
        pub mutability: Option<Token![mut]>,
        pub ident: Ident,
    }
}

ast_struct! {
    /// A path pattern like `Color::Red`.
    pub struct PatPath {
        pub attrs: Vec<Attribute>,
        pub path: Path,
    }
}

ast_struct! {
    /// A reference pattern: `&mut var`.
    pub struct PatReference {
        pub attrs: Vec<Attribute>,
        pub and_token: Token![&],
        pub mutability: Option<Token![mut]>,
        pub pat: Box<Pat>,
    }
}

ast_struct! {
    /// A struct or struct variant pattern: `Variant { x, y, .. }`.
    pub struct PatStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub brace_token: token::Brace,
        pub fields: Punctuated<FieldPat, Token![,]>,
        pub dot2_token: Option<Token![..]>,
    }
}

ast_struct! {
    /// A tuple pattern: `(a, b)`.
    pub struct PatTuple {
        pub attrs: Vec<Attribute>,
        pub paren_token: token::Paren,
        pub elems: Punctuated<Pat, Token![,]>,
    }
}

ast_struct! {
    /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
    pub struct PatTupleStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub pat: PatTuple,
    }
}

ast_struct! {
    /// A type ascription pattern: `foo: f64`.
    pub struct PatType {
        pub attrs: Vec<Attribute>,
        pub pat: Box<Pat>,
        pub colon_token: Token![:],
        pub ty: Box<Type>,
    }
}

ast_struct! {
    /// A pattern that matches any value: `_`.
    pub struct PatWild {
        pub attrs: Vec<Attribute>,
        pub underscore_token: Token![_],
    }
}

ast_struct! {
    /// A single field in a struct pattern.
    ///
    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
    /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
    pub struct FieldPat {
        pub attrs: Vec<Attribute>,
        pub member: Member,
        pub colon_token: Option<Token![:]>,
        pub pat: Box<Pat>,
    }
}

mod parsing {
    use syn::{
        braced,
        ext::IdentExt,
        parenthesized,
        parse::{Parse, ParseStream, Result},
        punctuated::Punctuated,
        token, Attribute, Ident, Member, Path, Token,
    };

    use super::{
        FieldPat, Pat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct,
        PatWild,
    };
    use crate::path;

    impl Parse for Pat {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let lookahead = input.lookahead1();
            if lookahead.peek(Ident)
                && ({
                    input.peek2(Token![::])
                        || input.peek2(token::Brace)
                        || input.peek2(token::Paren)
                })
                || input.peek(Token![self]) && input.peek2(Token![::])
                || lookahead.peek(Token![::])
                || lookahead.peek(Token![<])
                || input.peek(Token![Self])
                || input.peek(Token![super])
                || input.peek(Token![extern])
                || input.peek(Token![crate])
            {
                pat_path_or_struct(input)
            } else if lookahead.peek(Token![_]) {
                input.call(pat_wild).map(Pat::Wild)
            } else if lookahead.peek(Token![ref])
                || lookahead.peek(Token![mut])
                || input.peek(Token![self])
                || input.peek(Ident)
            {
                input.call(pat_ident).map(Pat::Ident)
            } else if lookahead.peek(Token![&]) {
                input.call(pat_reference).map(Pat::Reference)
            } else if lookahead.peek(token::Paren) {
                input.call(pat_tuple).map(Pat::Tuple)
            } else {
                Err(lookahead.error())
            }
        }
    }

    fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> {
        let path = path::parse_path(input)?;

        if input.peek(token::Brace) {
            pat_struct(input, path).map(Pat::Struct)
        } else if input.peek(token::Paren) {
            pat_tuple_struct(input, path).map(Pat::TupleStruct)
        } else {
            Ok(Pat::Path(PatPath { attrs: Vec::new(), path }))
        }
    }

    fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> {
        Ok(PatWild { attrs: Vec::new(), underscore_token: input.parse()? })
    }

    fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> {
        Ok(PatIdent {
            attrs: Vec::new(),
            by_ref: input.parse()?,
            mutability: input.parse()?,
            ident: input.call(Ident::parse_any)?,
        })
    }

    fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> {
        Ok(PatTupleStruct { attrs: Vec::new(), path, pat: input.call(pat_tuple)? })
    }

    fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> {
        let content;
        let brace_token = braced!(content in input);

        let mut fields = Punctuated::new();
        while !content.is_empty() && !content.peek(Token![..]) {
            let value = content.call(field_pat)?;
            fields.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct: Token![,] = content.parse()?;
            fields.push_punct(punct);
        }

        let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
            Some(content.parse()?)
        } else {
            None
        };

        Ok(PatStruct { attrs: Vec::new(), path, brace_token, fields, dot2_token })
    }

    fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> {
        let attrs = input.call(Attribute::parse_outer)?;
        let boxed: Option<Token![box]> = input.parse()?;
        let by_ref: Option<Token![ref]> = input.parse()?;
        let mutability: Option<Token![mut]> = input.parse()?;
        let member: Member = input.parse()?;

        if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
            || is_unnamed(&member)
        {
            return Ok(FieldPat {
                attrs,
                member,
                colon_token: input.parse()?,
                pat: input.parse()?,
            });
        }

        let ident = match member {
            Member::Named(ident) => ident,
            Member::Unnamed(_) => unreachable!(),
        };

        let pat =
            Pat::Ident(PatIdent { attrs: Vec::new(), by_ref, mutability, ident: ident.clone() });

        Ok(FieldPat { attrs, member: Member::Named(ident), colon_token: None, pat: Box::new(pat) })
    }

    fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> {
        let content;
        let paren_token = parenthesized!(content in input);

        let mut elems = Punctuated::new();
        while !content.is_empty() {
            let value: Pat = content.parse()?;
            elems.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            elems.push_punct(punct);
        }

        Ok(PatTuple { attrs: Vec::new(), paren_token, elems })
    }

    fn pat_reference(input: ParseStream<'_>) -> Result<PatReference> {
        Ok(PatReference {
            attrs: Vec::new(),
            and_token: input.parse()?,
            mutability: input.parse()?,
            pat: input.parse()?,
        })
    }

    fn is_unnamed(member: &Member) -> bool {
        match member {
            Member::Named(_) => false,
            Member::Unnamed(_) => true,
        }
    }
}

mod printing {
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};
    use syn::Token;

    use super::{
        FieldPat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType,
        PatWild,
    };

    impl ToTokens for PatWild {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.underscore_token.to_tokens(tokens);
        }
    }

    impl ToTokens for PatIdent {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.by_ref.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.ident.to_tokens(tokens);
        }
    }

    impl ToTokens for PatStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.brace_token.surround(tokens, |tokens| {
                self.fields.to_tokens(tokens);
                // NOTE: We need a comma before the dot2 token if it is present.
                if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
                    <Token![,]>::default().to_tokens(tokens);
                }
                self.dot2_token.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatTupleStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatType {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(&self.attrs);
            self.pat.to_tokens(tokens);
            self.colon_token.to_tokens(tokens);
            self.ty.to_tokens(tokens);
        }
    }

    impl ToTokens for PatPath {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens)
        }
    }

    impl ToTokens for PatTuple {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.paren_token.surround(tokens, |tokens| {
                self.elems.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatReference {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.and_token.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for FieldPat {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            if let Some(colon_token) = &self.colon_token {
                self.member.to_tokens(tokens);
                colon_token.to_tokens(tokens);
            }
            self.pat.to_tokens(tokens);
        }
    }
}
<commit_msg>Fix a link<commit_after>use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token, Type};

ast_enum_of_structs! {
    /// A pattern in a local binding, function signature, match expression, or
    /// various other places.
    ///
    /// # Syntax tree enum
    ///
    /// This type is a [syntax tree enum].
    ///
    /// [syntax tree enum]: https://docs.rs/syn/1/syn/enum.Expr.html#syntax-tree-enums
    pub enum Pat {
        /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
        Ident(PatIdent),

        /// A path pattern like `Color::Red`.
        Path(PatPath),

        /// A reference pattern: `&mut var`.
        Reference(PatReference),

        /// A struct or struct variant pattern: `Variant { x, y, .. }`.
        Struct(PatStruct),

        /// A tuple pattern: `(a, b)`.
        Tuple(PatTuple),

        /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
        TupleStruct(PatTupleStruct),

        /// A type ascription pattern: `foo: f64`.
        Type(PatType),

        /// A pattern that matches any value: `_`.
        Wild(PatWild),

        #[doc(hidden)]
        __Nonexhaustive,
    }
}

ast_struct! {
    /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
    pub struct PatIdent {
        pub attrs: Vec<Attribute>,
        pub by_ref: Option<Token![ref]>,
        pub mutability: Option<Token![mut]>,
        pub ident: Ident,
    }
}

ast_struct! {
    /// A path pattern like `Color::Red`.
    pub struct PatPath {
        pub attrs: Vec<Attribute>,
        pub path: Path,
    }
}

ast_struct! {
    /// A reference pattern: `&mut var`.
    pub struct PatReference {
        pub attrs: Vec<Attribute>,
        pub and_token: Token![&],
        pub mutability: Option<Token![mut]>,
        pub pat: Box<Pat>,
    }
}

ast_struct! {
    /// A struct or struct variant pattern: `Variant { x, y, .. }`.
    pub struct PatStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub brace_token: token::Brace,
        pub fields: Punctuated<FieldPat, Token![,]>,
        pub dot2_token: Option<Token![..]>,
    }
}

ast_struct! {
    /// A tuple pattern: `(a, b)`.
    pub struct PatTuple {
        pub attrs: Vec<Attribute>,
        pub paren_token: token::Paren,
        pub elems: Punctuated<Pat, Token![,]>,
    }
}

ast_struct! {
    /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
    pub struct PatTupleStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub pat: PatTuple,
    }
}

ast_struct! {
    /// A type ascription pattern: `foo: f64`.
    pub struct PatType {
        pub attrs: Vec<Attribute>,
        pub pat: Box<Pat>,
        pub colon_token: Token![:],
        pub ty: Box<Type>,
    }
}

ast_struct! {
    /// A pattern that matches any value: `_`.
    pub struct PatWild {
        pub attrs: Vec<Attribute>,
        pub underscore_token: Token![_],
    }
}

ast_struct! {
    /// A single field in a struct pattern.
    ///
    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
    /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
    pub struct FieldPat {
        pub attrs: Vec<Attribute>,
        pub member: Member,
        pub colon_token: Option<Token![:]>,
        pub pat: Box<Pat>,
    }
}

mod parsing {
    use syn::{
        braced,
        ext::IdentExt,
        parenthesized,
        parse::{Parse, ParseStream, Result},
        punctuated::Punctuated,
        token, Attribute, Ident, Member, Path, Token,
    };

    use super::{
        FieldPat, Pat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct,
        PatWild,
    };
    use crate::path;

    impl Parse for Pat {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let lookahead = input.lookahead1();
            if lookahead.peek(Ident)
                && ({
                    input.peek2(Token![::])
                        || input.peek2(token::Brace)
                        || input.peek2(token::Paren)
                })
                || input.peek(Token![self]) && input.peek2(Token![::])
                || lookahead.peek(Token![::])
                || lookahead.peek(Token![<])
                || input.peek(Token![Self])
                || input.peek(Token![super])
                || input.peek(Token![extern])
                || input.peek(Token![crate])
            {
                pat_path_or_struct(input)
            } else if lookahead.peek(Token![_]) {
                input.call(pat_wild).map(Pat::Wild)
            } else if lookahead.peek(Token![ref])
                || lookahead.peek(Token![mut])
                || input.peek(Token![self])
                || input.peek(Ident)
            {
                input.call(pat_ident).map(Pat::Ident)
            } else if lookahead.peek(Token![&]) {
                input.call(pat_reference).map(Pat::Reference)
            } else if lookahead.peek(token::Paren) {
                input.call(pat_tuple).map(Pat::Tuple)
            } else {
                Err(lookahead.error())
            }
        }
    }

    fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> {
        let path = path::parse_path(input)?;

        if input.peek(token::Brace) {
            pat_struct(input, path).map(Pat::Struct)
        } else if input.peek(token::Paren) {
            pat_tuple_struct(input, path).map(Pat::TupleStruct)
        } else {
            Ok(Pat::Path(PatPath { attrs: Vec::new(), path }))
        }
    }

    fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> {
        Ok(PatWild { attrs: Vec::new(), underscore_token: input.parse()? })
    }

    fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> {
        Ok(PatIdent {
            attrs: Vec::new(),
            by_ref: input.parse()?,
            mutability: input.parse()?,
            ident: input.call(Ident::parse_any)?,
        })
    }

    fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> {
        Ok(PatTupleStruct { attrs: Vec::new(), path, pat: input.call(pat_tuple)? })
    }

    fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> {
        let content;
        let brace_token = braced!(content in input);

        let mut fields = Punctuated::new();
        while !content.is_empty() && !content.peek(Token![..]) {
            let value = content.call(field_pat)?;
            fields.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct: Token![,] = content.parse()?;
            fields.push_punct(punct);
        }

        let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
            Some(content.parse()?)
        } else {
            None
        };

        Ok(PatStruct { attrs: Vec::new(), path, brace_token, fields, dot2_token })
    }

    fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> {
        let attrs = input.call(Attribute::parse_outer)?;
        let boxed: Option<Token![box]> = input.parse()?;
        let by_ref: Option<Token![ref]> = input.parse()?;
        let mutability: Option<Token![mut]> = input.parse()?;
        let member: Member = input.parse()?;

        if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
            || is_unnamed(&member)
        {
            return Ok(FieldPat {
                attrs,
                member,
                colon_token: input.parse()?,
                pat: input.parse()?,
            });
        }

        let ident = match member {
            Member::Named(ident) => ident,
            Member::Unnamed(_) => unreachable!(),
        };

        let pat =
            Pat::Ident(PatIdent { attrs: Vec::new(), by_ref, mutability, ident: ident.clone() });

        Ok(FieldPat { attrs, member: Member::Named(ident), colon_token: None, pat: Box::new(pat) })
    }

    fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> {
        let content;
        let paren_token = parenthesized!(content in input);

        let mut elems = Punctuated::new();
        while !content.is_empty() {
            let value: Pat = content.parse()?;
            elems.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            elems.push_punct(punct);
        }

        Ok(PatTuple { attrs: Vec::new(), paren_token, elems })
    }

    fn pat_reference(input: ParseStream<'_>) -> Result<PatReference> {
        Ok(PatReference {
            attrs: Vec::new(),
            and_token: input.parse()?,
            mutability: input.parse()?,
            pat: input.parse()?,
        })
    }

    fn is_unnamed(member: &Member) -> bool {
        match member {
            Member::Named(_) => false,
            Member::Unnamed(_) => true,
        }
    }
}

mod printing {
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};
    use syn::Token;

    use super::{
        FieldPat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType,
        PatWild,
    };

    impl ToTokens for PatWild {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.underscore_token.to_tokens(tokens);
        }
    }

    impl ToTokens for PatIdent {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.by_ref.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.ident.to_tokens(tokens);
        }
    }

    impl ToTokens for PatStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.brace_token.surround(tokens, |tokens| {
                self.fields.to_tokens(tokens);
                // NOTE: We need a comma before the dot2 token if it is present.
                if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
                    <Token![,]>::default().to_tokens(tokens);
                }
                self.dot2_token.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatTupleStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatType {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(&self.attrs);
            self.pat.to_tokens(tokens);
            self.colon_token.to_tokens(tokens);
            self.ty.to_tokens(tokens);
        }
    }

    impl ToTokens for PatPath {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens)
        }
    }

    impl ToTokens for PatTuple {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.paren_token.surround(tokens, |tokens| {
                self.elems.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatReference {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.and_token.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for FieldPat {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            if let Some(colon_token) = &self.colon_token {
                self.member.to_tokens(tokens);
                colon_token.to_tokens(tokens);
            }
            self.pat.to_tokens(tokens);
        }
    }
}
<|endoftext|>


<commit_before>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

use sys::Termios;
use sys::attr::{get_terminal_attr, raw_terminal_attr, set_terminal_attr};

/// The timeout of an escape code control sequence, in milliseconds.
pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        set_terminal_attr(&self.prev_ios).unwrap();
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
        let mut ios = get_terminal_attr()?;
        let prev_ios = ios;

        raw_terminal_attr(&mut ios);

        set_terminal_attr(&ios)?;

        Ok(RawTerminal {
            prev_ios: prev_ios,
            output: self,
        })
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write_all(b"this is a test, muahhahahah\r\n").unwrap();

        drop(out);
    }
}
<commit_msg>Add ability to suspend/activate raw mode on RawTerminal<commit_after>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

use sys::Termios;
use sys::attr::{get_terminal_attr, raw_terminal_attr, set_terminal_attr};

/// The timeout of an escape code control sequence, in milliseconds.
pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        set_terminal_attr(&self.prev_ios).unwrap();
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
        let mut ios = get_terminal_attr()?;
        let prev_ios = ios;

        raw_terminal_attr(&mut ios);

        set_terminal_attr(&ios)?;

        Ok(RawTerminal {
            prev_ios: prev_ios,
            output: self,
        })
    }
}

impl<W: Write> RawTerminal<W> {
    pub fn suspend_raw_mode(&self) -> io::Result<()> {
        set_terminal_attr(&self.prev_ios)?;
        Ok(())
    }

    pub fn activate_raw_mode(&self) -> io::Result<()> {
        let mut ios = get_terminal_attr()?;
        raw_terminal_attr(&mut ios);
        set_terminal_attr(&ios)?;
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write_all(b"this is a test, muahhahahah\r\n").unwrap();

        drop(out);
    }
}
<|endoftext|>


<commit_before>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,ignore
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
#[cfg(target_os = "redox")]
pub struct RawTerminal<W: Write> {
    output: W,
}

#[cfg(target_os = "redox")]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        write!(self, csi!("?82l")).unwrap();
    }
}

#[cfg(not(target_os = "redox"))]
use termios::Termios;
/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
#[cfg(not(target_os = "redox"))]
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

#[cfg(not(target_os = "redox"))]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        use termios::set_terminal_attr;
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    #[cfg(not(target_os = "redox"))]
    fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
        use termios::{cfmakeraw, get_terminal_attr, set_terminal_attr};

        let (mut ios, exit) = get_terminal_attr();
        let prev_ios = ios;
        if exit != 0 {
            return Err(io::Error::new(io::ErrorKind::Other, "Unable to get Termios attribute."));
        }

        unsafe {
            cfmakeraw(&mut ios);
        }

        if set_terminal_attr(&mut ios as *mut _) != 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to set Termios attribute."))
        } else {
            let res = RawTerminal {
                prev_ios: prev_ios,
                output: self,
            };
            Ok(res)
        }
    }

    #[cfg(target_os = "redox")]
    fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
        write!(self, csi!("?82h")).map(|_| {
            RawTerminal { output: self }
        })
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write(b"this is a test, muahhahahah").unwrap();
    }
}
<commit_msg>Added true terminal restoration (#66)<commit_after>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,ignore
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
#[cfg(target_os = "redox")]
pub struct RawTerminal<W: Write> {
    output: W,
}

#[cfg(target_os = "redox")]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        write!(self, csi!("?82l")).unwrap();
    }
}

#[cfg(not(target_os = "redox"))]
use termios::Termios;
/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
#[cfg(not(target_os = "redox"))]
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

#[cfg(not(target_os = "redox"))]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        write!(self, csi!("r")).unwrap();
        write!(self, csi!("?1049l")).unwrap();
        use termios::set_terminal_attr;
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    #[cfg(not(target_os = "redox"))]
    fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
        use termios::{cfmakeraw, get_terminal_attr, set_terminal_attr};

        let (mut ios, exit) = get_terminal_attr();
        let prev_ios = ios;
        if exit != 0 {
            return Err(io::Error::new(io::ErrorKind::Other, "Unable to get Termios attribute."));
        }

        unsafe {
            cfmakeraw(&mut ios);
        }

        if set_terminal_attr(&mut ios as *mut _) != 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to set Termios attribute."))
        } else {
            write!(self, csi!("?1049h")).unwrap();
            let res = RawTerminal {
                prev_ios: prev_ios,
                output: self,
            };
            Ok(res)
        }
    }

    #[cfg(target_os = "redox")]
    fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
        write!(self, csi!("?82h")).map(|_| {
            RawTerminal { output: self }
        })
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write(b"this is a test, muahhahahah").unwrap();
    }
}
<|endoftext|>


<commit_before>//! Rust representations of Github API data structures

use super::{SortDirection, Error, State as StdState};
use super::issues::Sort as IssueSort;
use super::search::SearchIssuesSort;
use super::repositories::{Sort as RepoSort, Affiliation, Type as RepoType,
                          Visibility as RepoVisibility, OrgRepoType};
use std::collections::HashMap;
use std::hash::Hash;
use std::option::Option;
use url::form_urlencoded;

use super::url;
extern crate serializable_enum;
extern crate serde;
extern crate serde_json;

include!(concat!(env!("OUT_DIR"), "/rep.rs"));

serializable_enum! {
    /// representation of deployment and commit status states
    #[derive(Clone, Debug, PartialEq)]
    pub enum StatusState {
        /// pending
        Pending,
        /// success
        Success,
        /// error
        Error,
        /// failure
        Failure,
    }
    StatusStateVisitor
}

impl_as_ref_from_str! {
    StatusState {
        Pending => "pending",
        Success => "success",
        Error => "error",
        Failure => "failure",
    }
    Error::Parse
}

impl Default for StatusState {
    fn default() -> StatusState {
        StatusState::Pending
    }
}

#[cfg(test)]
mod tests {
    use super::super::State as StdState;
    use serde::ser::Serialize;
    use std::collections::{HashMap, BTreeMap};
    use super::*;
    use super::serde_json;

    fn test_encoding<E: Serialize>(tests: Vec<(E, &str)>) {
        for test in tests {
            match test {
                (k, v) => assert_eq!(serde_json::to_string(&k).unwrap(), v),
            }
        }
    }

    #[test]
    fn gist_reqs() {
        let mut files = HashMap::new();
        files.insert("foo", "bar");
        let tests = vec![(GistOptions::new(None as Option<String>, true, files.clone()),
                  r#"{"public":true,"files":{"foo":{"content":"bar"}}}"#),
                 (GistOptions::new(Some("desc"), true, files.clone()),
                  r#"{"description":"desc","public":true,"files":{"foo":{"content":"bar"}}}"#)];
        test_encoding(tests);
    }

    #[test]
    fn deserialize_client_field_errors() {
        for (json, expect) in vec![
            // see https://github.com/softprops/hubcaps/issues/31
            (
                r#"{"message": "Validation Failed","errors": [{"resource": "Release","code": "custom","message": "Published releases must have a valid tag"}]}"#,
                ClientError {
                    message:"Validation Failed".to_owned(),
                    errors: Some(vec![
                        FieldErr {
                            resource: "Release".to_owned(),
                            code:"custom".to_owned(),
                            field: None,
                            message: Some("Published releases must have a valid tag".to_owned()),
                            documentation_url: None
                        }
                     ])
                }
             )
        ] {
            assert_eq!(serde_json::from_str::<ClientError>(json).unwrap(), expect);
        }
    }

    #[test]
    fn deserialize_status_state() {
        for (json, expect) in vec![("\"pending\"", StatusState::Pending),
                                   ("\"success\"", StatusState::Success),
                                   ("\"error\"", StatusState::Error),
                                   ("\"failure\"", StatusState::Failure)] {
            assert_eq!(serde_json::from_str::<StatusState>(json).unwrap(), expect)
        }
    }

    #[test]
    fn deployment_reqs() {
        let mut payload = BTreeMap::new();
        payload.insert("user", "atmos");
        payload.insert("room_id", "123456");
        let tests = vec![
            (
                DeploymentOptions::builder("test").build(),
                r#"{"ref":"test"}"#
            ),
            (
                DeploymentOptions::builder("test").task("launchit").build(),
                r#"{"ref":"test","task":"launchit"}"#
            ),
            (
                DeploymentOptions::builder("topic-branch").description("description").payload(payload).build(),
                r#"{"ref":"topic-branch","payload":"{\"room_id\":\"123456\",\"user\":\"atmos\"}","description":"description"}"#
            )
        ];
        test_encoding(tests)
    }

    #[test]
    fn deployment_status_reqs() {
        let tests = vec![
            (
                DeploymentStatusOptions::builder(StatusState::Pending).build(),
                r#"{"state":"pending"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").build(),
                r#"{"state":"pending","target_url":"http://host.com"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").description("desc").build(),
                r#"{"state":"pending","target_url":"http://host.com","description":"desc"}"#
            ),
        ];
        test_encoding(tests)
    }

    #[test]
    fn gist_req() {
        let mut files = HashMap::new();
        files.insert("test", "foo");
        let tests = vec![(GistOptions::builder(files.clone()).build(),
                  r#"{"files":{"test":{"content":"foo"}}}"#),
                 (GistOptions::builder(files.clone()).description("desc").build(),
                  r#"{"description":"desc","files":{"test":{"content":"foo"}}}"#),
                 (GistOptions::builder(files.clone()).description("desc").public(false).build(),
                  r#"{"description":"desc","public":false,"files":{"test":{"content":"foo"}}}"#)];
        test_encoding(tests)
    }

    #[test]
    fn pullreq_edits() {
        let tests = vec![(PullEditOptions::builder().title("test").build(), r#"{"title":"test"}"#),
                         (PullEditOptions::builder().title("test").body("desc").build(),
                          r#"{"title":"test","body":"desc"}"#),
                         (PullEditOptions::builder().state("closed").build(),
                          r#"{"state":"closed"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn status_reqs() {
        let tests = vec![(StatusOptions::builder(StatusState::Pending).build(),
                  r#"{"state":"pending"}"#),
                 (StatusOptions::builder(StatusState::Success)
                      .target_url("http://acme.com")
                      .build(),
                  r#"{"state":"success","target_url":"http://acme.com"}"#),
                 (StatusOptions::builder(StatusState::Error).description("desc").build(),
                  r#"{"state":"error","description":"desc"}"#),
                 (StatusOptions::builder(StatusState::Failure)
                      .target_url("http://acme.com")
                      .description("desc")
                      .build(),
                  r#"{"state":"failure","target_url":"http://acme.com","description":"desc"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn issue_list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (
                IssueListOptions::builder().build(),
                None
            ),
            (
                IssueListOptions::builder().state(StdState::Closed).build(),
                Some("state=closed".to_owned())
             ),
            (
                IssueListOptions::builder().labels(vec!["foo", "bar"]).build(),
                Some("labels=foo%2Cbar".to_owned())
            ),
        ];
        test_serialize(tests)
    }

    #[test]
    fn pull_list_reqs() {
        fn test_serialize(tests: Vec<(PullListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![(PullListOptions::builder().build(), None),
                         (PullListOptions::builder().state(StdState::Closed).build(),
                          Some("state=closed".to_owned()))];
        test_serialize(tests)
    }
}
<commit_msg>add missing btree map import<commit_after>//! Rust representations of Github API data structures

use super::{SortDirection, Error, State as StdState};
use super::issues::Sort as IssueSort;
use super::search::SearchIssuesSort;
use super::repositories::{Sort as RepoSort, Affiliation, Type as RepoType,
                          Visibility as RepoVisibility, OrgRepoType};
use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
use std::option::Option;
use url::form_urlencoded;

use super::url;
extern crate serializable_enum;
extern crate serde;
extern crate serde_json;

include!(concat!(env!("OUT_DIR"), "/rep.rs"));

serializable_enum! {
    /// representation of deployment and commit status states
    #[derive(Clone, Debug, PartialEq)]
    pub enum StatusState {
        /// pending
        Pending,
        /// success
        Success,
        /// error
        Error,
        /// failure
        Failure,
    }
    StatusStateVisitor
}

impl_as_ref_from_str! {
    StatusState {
        Pending => "pending",
        Success => "success",
        Error => "error",
        Failure => "failure",
    }
    Error::Parse
}

impl Default for StatusState {
    fn default() -> StatusState {
        StatusState::Pending
    }
}

#[cfg(test)]
mod tests {
    use super::super::State as StdState;
    use serde::ser::Serialize;
    use std::collections::{HashMap, BTreeMap};
    use super::*;
    use super::serde_json;

    fn test_encoding<E: Serialize>(tests: Vec<(E, &str)>) {
        for test in tests {
            match test {
                (k, v) => assert_eq!(serde_json::to_string(&k).unwrap(), v),
            }
        }
    }

    #[test]
    fn gist_reqs() {
        let mut files = HashMap::new();
        files.insert("foo", "bar");
        let tests = vec![(GistOptions::new(None as Option<String>, true, files.clone()),
                  r#"{"public":true,"files":{"foo":{"content":"bar"}}}"#),
                 (GistOptions::new(Some("desc"), true, files.clone()),
                  r#"{"description":"desc","public":true,"files":{"foo":{"content":"bar"}}}"#)];
        test_encoding(tests);
    }

    #[test]
    fn deserialize_client_field_errors() {
        for (json, expect) in vec![
            // see https://github.com/softprops/hubcaps/issues/31
            (
                r#"{"message": "Validation Failed","errors": [{"resource": "Release","code": "custom","message": "Published releases must have a valid tag"}]}"#,
                ClientError {
                    message:"Validation Failed".to_owned(),
                    errors: Some(vec![
                        FieldErr {
                            resource: "Release".to_owned(),
                            code:"custom".to_owned(),
                            field: None,
                            message: Some("Published releases must have a valid tag".to_owned()),
                            documentation_url: None
                        }
                     ])
                }
             )
        ] {
            assert_eq!(serde_json::from_str::<ClientError>(json).unwrap(), expect);
        }
    }

    #[test]
    fn deserialize_status_state() {
        for (json, expect) in vec![("\"pending\"", StatusState::Pending),
                                   ("\"success\"", StatusState::Success),
                                   ("\"error\"", StatusState::Error),
                                   ("\"failure\"", StatusState::Failure)] {
            assert_eq!(serde_json::from_str::<StatusState>(json).unwrap(), expect)
        }
    }

    #[test]
    fn deployment_reqs() {
        let mut payload = BTreeMap::new();
        payload.insert("user", "atmos");
        payload.insert("room_id", "123456");
        let tests = vec![
            (
                DeploymentOptions::builder("test").build(),
                r#"{"ref":"test"}"#
            ),
            (
                DeploymentOptions::builder("test").task("launchit").build(),
                r#"{"ref":"test","task":"launchit"}"#
            ),
            (
                DeploymentOptions::builder("topic-branch").description("description").payload(payload).build(),
                r#"{"ref":"topic-branch","payload":"{\"room_id\":\"123456\",\"user\":\"atmos\"}","description":"description"}"#
            )
        ];
        test_encoding(tests)
    }

    #[test]
    fn deployment_status_reqs() {
        let tests = vec![
            (
                DeploymentStatusOptions::builder(StatusState::Pending).build(),
                r#"{"state":"pending"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").build(),
                r#"{"state":"pending","target_url":"http://host.com"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").description("desc").build(),
                r#"{"state":"pending","target_url":"http://host.com","description":"desc"}"#
            ),
        ];
        test_encoding(tests)
    }

    #[test]
    fn gist_req() {
        let mut files = HashMap::new();
        files.insert("test", "foo");
        let tests = vec![(GistOptions::builder(files.clone()).build(),
                  r#"{"files":{"test":{"content":"foo"}}}"#),
                 (GistOptions::builder(files.clone()).description("desc").build(),
                  r#"{"description":"desc","files":{"test":{"content":"foo"}}}"#),
                 (GistOptions::builder(files.clone()).description("desc").public(false).build(),
                  r#"{"description":"desc","public":false,"files":{"test":{"content":"foo"}}}"#)];
        test_encoding(tests)
    }

    #[test]
    fn pullreq_edits() {
        let tests = vec![(PullEditOptions::builder().title("test").build(), r#"{"title":"test"}"#),
                         (PullEditOptions::builder().title("test").body("desc").build(),
                          r#"{"title":"test","body":"desc"}"#),
                         (PullEditOptions::builder().state("closed").build(),
                          r#"{"state":"closed"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn status_reqs() {
        let tests = vec![(StatusOptions::builder(StatusState::Pending).build(),
                  r#"{"state":"pending"}"#),
                 (StatusOptions::builder(StatusState::Success)
                      .target_url("http://acme.com")
                      .build(),
                  r#"{"state":"success","target_url":"http://acme.com"}"#),
                 (StatusOptions::builder(StatusState::Error).description("desc").build(),
                  r#"{"state":"error","description":"desc"}"#),
                 (StatusOptions::builder(StatusState::Failure)
                      .target_url("http://acme.com")
                      .description("desc")
                      .build(),
                  r#"{"state":"failure","target_url":"http://acme.com","description":"desc"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn issue_list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (
                IssueListOptions::builder().build(),
                None
            ),
            (
                IssueListOptions::builder().state(StdState::Closed).build(),
                Some("state=closed".to_owned())
             ),
            (
                IssueListOptions::builder().labels(vec!["foo", "bar"]).build(),
                Some("labels=foo%2Cbar".to_owned())
            ),
        ];
        test_serialize(tests)
    }

    #[test]
    fn pull_list_reqs() {
        fn test_serialize(tests: Vec<(PullListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![(PullListOptions::builder().build(), None),
                         (PullListOptions::builder().state(StdState::Closed).build(),
                          Some("state=closed".to_owned()))];
        test_serialize(tests)
    }
}
<|endoftext|>


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

#![feature(plugin, rustc_private)]
#![plugin(quasi_macros)]

extern crate syntax;
extern crate quasi;

use syntax::ext::base::ExtCtxt;
use syntax::ext::expand;
use syntax::parse;
use syntax::print::pprust;

fn make_ext_ctxt(sess: &parse::ParseSess) -> ExtCtxt {
    let info = syntax::codemap::ExpnInfo {
        call_site: syntax::codemap::DUMMY_SP,
        callee: syntax::codemap::NameAndSpan {
            name: "test".to_string(),
            format: syntax::codemap::MacroAttribute,
            allow_internal_unstable: false,
            span: None
        }
    };

    let cfg = vec![];
    let ecfg = expand::ExpansionConfig {
        crate_name: String::new(),
        features: None,
        recursion_limit: 64,
    };

    let mut cx = ExtCtxt::new(&sess, cfg, ecfg);
    cx.bt_push(info);

    cx
}

#[test]
fn test_quote_tokens() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let tts = quote_tokens!(&cx, (+ 2 3));
    assert_eq!(pprust::tts_to_string(&tts), "( + 2 3 )");
}

#[test]
fn test_quote_ty() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let ty = quote_ty!(&cx, isize);
    assert_eq!(pprust::ty_to_string(&ty), "isize");
}

#[test]
fn test_quote_expr() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let expr = quote_expr!(&cx, 23);
    assert_eq!(pprust::expr_to_string(&expr), "23");

    let value = 24;
    let expr = quote_expr!(&cx, $value);
    assert_eq!(pprust::expr_to_string(&expr), "24i32");
}

#[test]
fn test_quote_stmt() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let stmt = quote_stmt!(&cx, let x = 20;).unwrap();
    assert_eq!(pprust::stmt_to_string(&stmt), "let x = 20;");
}

#[test]
fn test_quote_pat() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let pat = quote_pat!(&cx, Some(_));
    assert_eq!(pprust::pat_to_string(&pat), "Some(_)");
}

#[test]
fn test_quote_arm() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let arm = quote_arm!(&cx, (ref x, ref y) => (x, y),);
    assert_eq!(pprust::arm_to_string(&arm), " (ref x, ref y) => (x, y),");
}

#[test]
fn test_quote_attr() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let attr = quote_attr!(&cx, #![cfg(foo = "bar")]);
    assert_eq!(
        pprust::to_string(|s| s.print_attribute(&attr)),
        "#![cfg(foo = \"bar\")]");
}

#[test]
fn test_quote_block() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let block = quote_block!(&cx, {
        let x = 5;
        let y = 6;
        x + y
    }).ok().unwrap();

    assert_eq!(
        pprust::block_to_string(&block),
        "{ let x = 5; let y = 6; x + y }");
}

#[test]
fn test_quote_item() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let item = quote_item!(&cx, static x : int = 10;).unwrap();
    assert_eq!(pprust::item_to_string(&item), "static x: int = 10;");
}

#[test]
fn test_quote_impl_item() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let impl_item = quote_impl_item!(&cx, fn method(&mut self, x: u32) -> u32 { x });
    let impl_item = impl_item.ok().unwrap();
    assert_eq!(
        pprust::to_string(|s| s.print_impl_item(&impl_item)),
        "fn method(&mut self, x: u32) -> u32 { x }"
    );
}

#[test]
fn test_quote_matcher() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let tts = quote_matcher!(&cx, $($foo:tt,)* bar);
    assert_eq!(pprust::tts_to_string(&tts), "$($foo:tt,)* bar");
}

/*
#[test]
fn test_quote_where_clause() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let where_clause = quote_where_clause!(&cx, where A, B: T);
    assert_eq!(
        pprust::to_string(|s| s.print_where_clause(&where_clause)),
        "where A, B: T"
    );
}
*/

#[test]
fn test_quote_with_macro() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let block = quote_block!(&cx, {
        macro_rules! value { () => 6 }
        value!()
    }).ok().unwrap();

    assert_eq!(
        pprust::block_to_string(&block),
        "{\n    macro_rules! value((  ) => 6);\n    value!()\n}");

    // Make sure we don't expand macros in the quote.
    macro_rules! value { () => 5 }
    let block = quote_block!(&cx, { value!() }).ok().unwrap();

    assert_eq!(pprust::block_to_string(&block), "{ value!() }");
}
<commit_msg>Update where_clause_to_string! test<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(plugin, rustc_private)]
#![plugin(quasi_macros)]

extern crate syntax;
extern crate quasi;

use syntax::ext::base::ExtCtxt;
use syntax::ext::expand;
use syntax::parse;
use syntax::print::pprust;

fn make_ext_ctxt(sess: &parse::ParseSess) -> ExtCtxt {
    let info = syntax::codemap::ExpnInfo {
        call_site: syntax::codemap::DUMMY_SP,
        callee: syntax::codemap::NameAndSpan {
            name: "test".to_string(),
            format: syntax::codemap::MacroAttribute,
            allow_internal_unstable: false,
            span: None
        }
    };

    let cfg = vec![];
    let ecfg = expand::ExpansionConfig {
        crate_name: String::new(),
        features: None,
        recursion_limit: 64,
    };

    let mut cx = ExtCtxt::new(&sess, cfg, ecfg);
    cx.bt_push(info);

    cx
}

#[test]
fn test_quote_tokens() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let tts = quote_tokens!(&cx, (+ 2 3));
    assert_eq!(pprust::tts_to_string(&tts), "( + 2 3 )");
}

#[test]
fn test_quote_ty() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let ty = quote_ty!(&cx, isize);
    assert_eq!(pprust::ty_to_string(&ty), "isize");
}

#[test]
fn test_quote_expr() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let expr = quote_expr!(&cx, 23);
    assert_eq!(pprust::expr_to_string(&expr), "23");

    let value = 24;
    let expr = quote_expr!(&cx, $value);
    assert_eq!(pprust::expr_to_string(&expr), "24i32");
}

#[test]
fn test_quote_stmt() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let stmt = quote_stmt!(&cx, let x = 20;).unwrap();
    assert_eq!(pprust::stmt_to_string(&stmt), "let x = 20;");
}

#[test]
fn test_quote_pat() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let pat = quote_pat!(&cx, Some(_));
    assert_eq!(pprust::pat_to_string(&pat), "Some(_)");
}

#[test]
fn test_quote_arm() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let arm = quote_arm!(&cx, (ref x, ref y) => (x, y),);
    assert_eq!(pprust::arm_to_string(&arm), " (ref x, ref y) => (x, y),");
}

#[test]
fn test_quote_attr() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let attr = quote_attr!(&cx, #![cfg(foo = "bar")]);
    assert_eq!(
        pprust::to_string(|s| s.print_attribute(&attr)),
        "#![cfg(foo = \"bar\")]");
}

#[test]
fn test_quote_block() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let block = quote_block!(&cx, {
        let x = 5;
        let y = 6;
        x + y
    }).ok().unwrap();

    assert_eq!(
        pprust::block_to_string(&block),
        "{ let x = 5; let y = 6; x + y }");
}

#[test]
fn test_quote_item() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let item = quote_item!(&cx, static x : int = 10;).unwrap();
    assert_eq!(pprust::item_to_string(&item), "static x: int = 10;");
}

#[test]
fn test_quote_impl_item() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let impl_item = quote_impl_item!(&cx, fn method(&mut self, x: u32) -> u32 { x });
    let impl_item = impl_item.ok().unwrap();
    assert_eq!(
        pprust::to_string(|s| s.print_impl_item(&impl_item)),
        "fn method(&mut self, x: u32) -> u32 { x }"
    );
}

#[test]
fn test_quote_matcher() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let tts = quote_matcher!(&cx, $($foo:tt,)* bar);
    assert_eq!(pprust::tts_to_string(&tts), "$($foo:tt,)* bar");
}

/*
#[test]
fn test_quote_where_clause() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let where_clause = quote_where_clause!(&cx, where A, B: T).ok().unwrap();

    assert_eq!(
        pprust::where_clause_to_string(&where_clause),
        "where A, B: T"
    );
}
*/

#[test]
fn test_quote_with_macro() {
    let sess = parse::new_parse_sess();
    let cx = make_ext_ctxt(&sess);

    let block = quote_block!(&cx, {
        macro_rules! value { () => 6 }
        value!()
    }).ok().unwrap();

    assert_eq!(
        pprust::block_to_string(&block),
        "{\n    macro_rules! value((  ) => 6);\n    value!()\n}");

    // Make sure we don't expand macros in the quote.
    macro_rules! value { () => 5 }
    let block = quote_block!(&cx, { value!() }).ok().unwrap();

    assert_eq!(pprust::block_to_string(&block), "{ value!() }");
}
<|endoftext|>


<commit_before>extern crate libc;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate mio;
extern crate mio_aio;
extern crate nix;
extern crate tempfile;

use mio::deprecated::{EventLoop, Handler};
use mio::{PollOpt, Ready, Token};
use tempfile::tempfile;
use nix::sys::aio;
use std::os::unix::io::AsRawFd;
use std::io::{Read, Seek, SeekFrom, Write};

const UDATA: Token = Token(0xdeadbeef);

struct TestHandler {
    pub last_token: Token,
    pub count: usize,
}

impl TestHandler {
    fn new() -> TestHandler {
        TestHandler {
            count: 0,
            last_token: Token(0)
        }
    }
}

impl Handler for TestHandler {
    type Timeout = usize;
    type Message = String;

    fn ready(&mut self, _event_loop: &mut EventLoop<TestHandler>, token: Token,
             events: Ready) {
        debug!("READY: {:?} - {:?}", token, events);
        if events.is_aio() {
            debug!("Handler::ready() aio event");
            self.last_token = token;
            self.count += 1;
        }
    }
}

#[test]
pub fn test_cancel() {
    const WBUF: &'static [u8] = b"abcdef";
    let mut event_loop = EventLoop::<TestHandler>::new().unwrap();
    let mut handler = TestHandler::new();
    let f = tempfile().unwrap();
    let mut aiocb = mio_aio::AioCb::from_slice(f.as_raw_fd(),
        0,   //offset
        &WBUF,
        0,   //priority
        aio::LioOpcode::LIO_NOP);
    event_loop.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .ok().expect("registration failed");

    aiocb.write().unwrap();
    aiocb.cancel().ok().expect("aio_cancel failed");
    event_loop.run_once(&mut handler, None).unwrap();
    assert_eq!(handler.count, 1);
    assert_eq!(handler.last_token, UDATA);

    // Since we cancelled the I/O, we musn't care whether it succeeded.
    let _ = aiocb.aio_return();
}

#[test]
pub fn test_fsync() {
    const INITIAL: &'static [u8] = b"abcdef123456";
    let mut f = tempfile().unwrap();
    f.write(INITIAL).unwrap();
    let mut event_loop = EventLoop::<TestHandler>::new().unwrap();

    let mut handler = TestHandler::new();
    let mut aiocb = mio_aio::AioCb::from_fd( f.as_raw_fd(), 0);
    event_loop.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .ok().expect("registration failed");

    aiocb.fsync(aio::AioFsyncMode::O_SYNC).unwrap();
    event_loop.run_once(&mut handler, None).unwrap();
    assert_eq!(handler.count, 1);
    assert_eq!(handler.last_token, UDATA);

    aiocb.aio_return().unwrap();
}

#[test]
pub fn test_read() {
    debug!("Starting TEST_AIO");
    const INITIAL: &'static [u8] = b"abcdef123456";
    let mut rbuf = vec![0; 4];
    const EXPECT: &'static [u8] = b"cdef";
    let mut f = tempfile().unwrap();
    f.write(INITIAL).unwrap();

    let mut event_loop = EventLoop::<TestHandler>::new().unwrap();
    let mut handler = TestHandler::new();
    {
        let mut aiocb = mio_aio::AioCb::from_mut_slice(f.as_raw_fd(),
            2,   //offset
            &mut rbuf,
            0,   //priority
            aio::LioOpcode::LIO_NOP);
        event_loop.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
            .ok().expect("registration failed");

        aiocb.read().unwrap();
        event_loop.run_once(&mut handler, None).unwrap();
        assert_eq!(handler.count, 1);
        assert_eq!(handler.last_token, UDATA);

        assert_eq!(aiocb.aio_return().unwrap(), EXPECT.len() as isize);
    }
    assert!(rbuf == EXPECT);
}

#[test]
pub fn test_write() {
    debug!("Starting TEST_AIO");
    const WBUF: &'static [u8] = b"abcdef";
    let mut rbuf = Vec::new();
    let mut event_loop = EventLoop::<TestHandler>::new().unwrap();
    let mut handler = TestHandler::new();
    let mut f = tempfile().unwrap();
    let mut aiocb = mio_aio::AioCb::from_slice(f.as_raw_fd(),
        0,   //offset
        &WBUF,
        0,   //priority
        aio::LioOpcode::LIO_NOP);
    event_loop.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .ok().expect("registration failed");

    aiocb.write().unwrap();
    event_loop.run_once(&mut handler, None).unwrap();
    assert_eq!(handler.count, 1);
    assert_eq!(handler.last_token, UDATA);

    assert_eq!(aiocb.aio_return().unwrap(), WBUF.len() as isize);
    f.seek(SeekFrom::Start(0)).unwrap();
    let len = f.read_to_end(&mut rbuf).unwrap();
    assert!(len == WBUF.len());
    assert!(rbuf == WBUF);
}
<commit_msg>Remove deprecated bits of mio from tests<commit_after>extern crate libc;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate mio;
extern crate mio_aio;
extern crate nix;
extern crate tempfile;

use mio::{Events, Poll, PollOpt, Ready, Token};
use tempfile::tempfile;
use nix::sys::aio;
use std::os::unix::io::AsRawFd;
use std::io::{Read, Seek, SeekFrom, Write};

const UDATA: Token = Token(0xdeadbeef);

#[test]
pub fn test_cancel() {
    const WBUF: &'static [u8] = b"abcdef";
    let f = tempfile().unwrap();

    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);
    let aiocb = mio_aio::AioCb::from_slice(f.as_raw_fd(),
        0,   //offset
        &WBUF,
        0,   //priority
        aio::LioOpcode::LIO_NOP);
    poll.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .expect("registration failed");

    aiocb.write().unwrap();
    aiocb.cancel().ok().expect("aio_cancel failed");

    poll.poll(&mut events, None).expect("poll failed");
    assert_eq!(events.len(), 1);
    let ev = events.get(0).unwrap();
    assert_eq!(ev.token(), UDATA);
    assert!(ev.readiness().is_aio());

    // Since we cancelled the I/O, we musn't care whether it succeeded.
    let _ = aiocb.aio_return();
}

#[test]
pub fn test_fsync() {
    const INITIAL: &'static [u8] = b"abcdef123456";
    let mut f = tempfile().unwrap();
    f.write(INITIAL).unwrap();
    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);

    //let mut handler = TestHandler::new();
    let aiocb = mio_aio::AioCb::from_fd( f.as_raw_fd(), 0);
    poll.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .expect("registration failed");

    aiocb.fsync(aio::AioFsyncMode::O_SYNC).unwrap();
    poll.poll(&mut events, None).expect("poll failed");
    assert_eq!(events.len(), 1);
    let ev = events.get(0).unwrap();
    assert_eq!(ev.token(), UDATA);
    assert!(ev.readiness().is_aio());

    aiocb.aio_return().unwrap();
}

#[test]
pub fn test_read() {
    debug!("Starting TEST_AIO");
    const INITIAL: &'static [u8] = b"abcdef123456";
    let mut rbuf = vec![0; 4];
    const EXPECT: &'static [u8] = b"cdef";
    let mut f = tempfile().unwrap();
    f.write(INITIAL).unwrap();

    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);
    {
        let aiocb = mio_aio::AioCb::from_mut_slice(f.as_raw_fd(),
            2,   //offset
            &mut rbuf,
            0,   //priority
            aio::LioOpcode::LIO_NOP);
        poll.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
            .ok().expect("registration failed");

        aiocb.read().unwrap();

        poll.poll(&mut events, None).expect("poll failed");
        assert_eq!(events.len(), 1);
        let ev = events.get(0).unwrap();
        assert_eq!(ev.token(), UDATA);
        assert!(ev.readiness().is_aio());

        assert_eq!(aiocb.aio_return().unwrap(), EXPECT.len() as isize);
    }
    assert!(rbuf == EXPECT);
}

#[test]
pub fn test_write() {
    debug!("Starting TEST_AIO");
    const WBUF: &'static [u8] = b"abcdef";
    let mut f = tempfile().unwrap();
    let mut rbuf = Vec::new();

    let poll = Poll::new().unwrap();
    let mut events = Events::with_capacity(1024);
    let aiocb = mio_aio::AioCb::from_slice(f.as_raw_fd(),
        0,   //offset
        &WBUF,
        0,   //priority
        aio::LioOpcode::LIO_NOP);
    poll.register(&aiocb, UDATA, Ready::aio(), PollOpt::empty())
        .expect("registration failed");

    aiocb.write().unwrap();

    poll.poll(&mut events, None).expect("poll failed");
    assert_eq!(events.len(), 1);
    let ev = events.get(0).unwrap();
    assert_eq!(ev.token(), UDATA);
    assert!(ev.readiness().is_aio());

    assert_eq!(aiocb.aio_return().unwrap(), WBUF.len() as isize);
    f.seek(SeekFrom::Start(0)).unwrap();
    let len = f.read_to_end(&mut rbuf).unwrap();
    assert!(len == WBUF.len());
    assert!(rbuf == WBUF);
}
<|endoftext|>


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

use jsapi::JSTracer;

use serialize::Encoder;

impl Encoder for JSTracer {
    fn emit_nil(&mut self) {}
    fn emit_uint(&mut self, _v: uint) {}
    fn emit_u64(&mut self, _v: u64) {}
    fn emit_u32(&mut self, __v: u32) {}
    fn emit_u16(&mut self, _v: u16) {}
    fn emit_u8(&mut self, _v: u8) {}
    fn emit_int(&mut self, _v: int) {}
    fn emit_i64(&mut self, _v: i64) {}
    fn emit_i32(&mut self, _v: i32) {}
    fn emit_i16(&mut self, _v: i16) {}
    fn emit_i8(&mut self, _v: i8) {}
    fn emit_bool(&mut self, _v: bool) {}
    fn emit_f64(&mut self, _v: f64) {}
    fn emit_f32(&mut self, _v: f32) {}
    fn emit_char(&mut self, _v: char) {}
    fn emit_str(&mut self, _v: &str) {}
    fn emit_enum(&mut self, _name: &str, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_enum_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_enum_variant_arg(&mut self, _a_idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_enum_struct_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_struct_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_tuple(&mut self, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_tuple_arg(&mut self, _idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_tuple_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_tuple_struct_arg(&mut self, _f_idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_option(&mut self, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_option_none(&mut self) {}
    fn emit_option_some(&mut self, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_seq(&mut self, _len: uint, f: |this: &mut JSTracer|) {
        f(self);
    }
    fn emit_seq_elt(&mut self, _idx: uint, f: |this: &mut JSTracer|) {
        f(self);
    }
    fn emit_map(&mut self, _len: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut JSTracer|) {
        f(self);
    }
}<commit_msg>Update to current rust: update to Encoder changes.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use jsapi::JSTracer;

use serialize::Encoder;

impl Encoder<()> for JSTracer {
    fn emit_nil(&mut self) -> Result<(), ()> { Ok(()) }
    fn emit_uint(&mut self, _v: uint) -> Result<(), ()> { Ok(()) }
    fn emit_u64(&mut self, _v: u64) -> Result<(), ()> { Ok(()) }
    fn emit_u32(&mut self, __v: u32) -> Result<(), ()> { Ok(()) }
    fn emit_u16(&mut self, _v: u16) -> Result<(), ()> { Ok(()) }
    fn emit_u8(&mut self, _v: u8) -> Result<(), ()> { Ok(()) }
    fn emit_int(&mut self, _v: int) -> Result<(), ()> { Ok(()) }
    fn emit_i64(&mut self, _v: i64) -> Result<(), ()> { Ok(()) }
    fn emit_i32(&mut self, _v: i32) -> Result<(), ()> { Ok(()) }
    fn emit_i16(&mut self, _v: i16) -> Result<(), ()> { Ok(()) }
    fn emit_i8(&mut self, _v: i8) -> Result<(), ()> { Ok(()) }
    fn emit_bool(&mut self, _v: bool) -> Result<(), ()> { Ok(()) }
    fn emit_f64(&mut self, _v: f64) -> Result<(), ()> { Ok(()) }
    fn emit_f32(&mut self, _v: f32) -> Result<(), ()> { Ok(()) }
    fn emit_char(&mut self, _v: char) -> Result<(), ()> { Ok(()) }
    fn emit_str(&mut self, _v: &str) -> Result<(), ()> { Ok(()) }
    fn emit_enum(&mut self, _name: &str, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_variant_arg(&mut self, _a_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_struct_variant(&mut self, _v_name: &str, _v_id: uint, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_struct_field(&mut self, _f_name: &str, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_arg(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_struct(&mut self, _name: &str, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_tuple_struct_arg(&mut self, _f_idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_option(&mut self, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_option_none(&mut self) -> Result<(), ()> { Ok(()) }
    fn emit_option_some(&mut self, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_seq(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_seq_elt(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map(&mut self, _len: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut JSTracer| -> Result<(), ()>) -> Result<(), ()> {
        f(self)
    }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::fmt;
use std::str::from_utf8;

use header::{Header, Raw};
use header::internals::VecMap;

/// `Cookie` header, defined in [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.4)
///
/// If the user agent does attach a Cookie header field to an HTTP
/// request, the user agent must send the cookie-string
/// as the value of the header field.
///
/// When the user agent generates an HTTP request, the user agent MUST NOT
/// attach more than one Cookie header field.
///
/// # Example values
/// * `SID=31d4d96e407aad42`
/// * `SID=31d4d96e407aad42; lang=en-US`
///
/// # Example
/// ```
/// use hyper::header::{Headers, Cookie};
///
/// let mut headers = Headers::new();
/// let mut cookie = Cookie::new();
/// cookie.append("foo", "bar");
///
/// assert_eq!(cookie.get("foo"), Some("bar"));
///
/// headers.set(cookie);
/// ```
#[derive(Clone)]
pub struct Cookie(VecMap<Cow<'static, str>, Cow<'static, str>>);

impl Cookie {
    /// Creates a new `Cookie` header.
    pub fn new() -> Cookie {
        Cookie(VecMap::with_capacity(0))
    }

    /// Sets a name and value for the `Cookie`.
    ///
    /// # Note
    ///
    /// This will remove all other instances with the same name,
    /// and insert the new value.
    pub fn set<K, V>(&mut self, key: K, value: V)
        where K: Into<Cow<'static, str>>,
              V: Into<Cow<'static, str>>
    {
        let key = key.into();
        let value = value.into();
        self.0.remove_all(&key);
        self.0.append(key, value);
    }

    /// Append a name and value for the `Cookie`.
    ///
    /// # Note
    ///
    /// Cookies are allowed to set a name with a
    /// a value multiple times. For example:
    ///
    /// ```
    /// use hyper::header::Cookie;
    /// let mut cookie = Cookie::new();
    /// cookie.append("foo", "bar");
    /// cookie.append("foo", "quux");
    /// assert_eq!(cookie.to_string(), "foo=bar; foo=quux");
    pub fn append<K, V>(&mut self, key: K, value: V)
        where K: Into<Cow<'static, str>>,
              V: Into<Cow<'static, str>>
    {
        self.0.append(key.into(), value.into());
    }

    /// Get a value for the name, if it exists.
    ///
    /// # Note
    ///
    /// Only returns the first instance found. To access
    /// any other values associated with the name, parse
    /// the `str` representation.
    pub fn get(&self, key: &str) -> Option<&str> {
        self.0.get(key).map(AsRef::as_ref)
    }
}

impl Header for Cookie {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Cookie";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<Cookie> {
        let mut vec_map = VecMap::with_capacity(raw.len());
        for cookies_raw in raw.iter() {
            let cookies_str = try!(from_utf8(&cookies_raw[..]));
            for cookie_str in cookies_str.split(';') {
                let mut key_val = cookie_str.splitn(2, '=');
                let key_val = (key_val.next(), key_val.next());
                if let (Some(key), Some(val)) = key_val {
                    vec_map.insert(key.trim().to_owned().into(), val.trim().to_owned().into());
                } else {
                    return Err(::Error::Header);
                }
            }
        }

        if vec_map.len() != 0 {
            Ok(Cookie(vec_map))
        } else {
            Err(::Error::Header)
        }
    }

    fn fmt_header(&self, f: &mut ::header::Formatter) -> fmt::Result {
        f.fmt_line(self)
    }
}

impl PartialEq for Cookie {
    fn eq(&self, other: &Cookie) -> bool {
        if self.0.len() == other.0.len() {
            for &(ref k, ref v) in self.0.iter() {
                if other.get(k) != Some(v) {
                    return false;
                }
            }
            true
        } else {
            false
        }
    }
}

impl fmt::Debug for Cookie {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_map()
            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
            .finish()
    }
}

impl fmt::Display for Cookie {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut iter = self.0.iter();
        if let Some(&(ref key, ref val)) = iter.next() {
            try!(write!(f, "{}={}", key, val));
        }
        for &(ref key, ref val) in iter {
            try!(write!(f, "; {}={}", key, val));
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use header::Header;
    use super::Cookie;

    #[test]
    fn test_set_and_get() {
        let mut cookie = Cookie::new();
        cookie.append("foo", "bar");
        cookie.append(String::from("dyn"), String::from("amic"));

        assert_eq!(cookie.get("foo"), Some("bar"));
        assert_eq!(cookie.get("dyn"), Some("amic"));
        assert!(cookie.get("nope").is_none());

        cookie.append("foo", "notbar");
        assert_eq!(cookie.get("foo"), Some("bar"));

        cookie.set("foo", "hi");
        assert_eq!(cookie.get("foo"), Some("hi"));
        assert_eq!(cookie.get("dyn"), Some("amic"));
    }

    #[test]
    fn test_eq() {
        let mut cookie = Cookie::new();
        let mut cookie2 = Cookie::new();

        // empty is equal
        assert_eq!(cookie, cookie2);

        // left has more params
        cookie.append("foo", "bar");
        assert!(cookie != cookie2);

        // same len, different params
        cookie2.append("bar", "foo");
        assert!(cookie != cookie2);

        // right has more params, and matching KV
        cookie2.append("foo", "bar");
        assert!(cookie != cookie2);

        // same params, different order
        cookie.append("bar", "foo");
        assert_eq!(cookie, cookie2);
    }

    #[test]
    fn test_parse() {
        let mut cookie = Cookie::new();

        let parsed = Cookie::parse_header(&b"foo=bar".to_vec().into()).unwrap();
        cookie.append("foo", "bar");
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar; baz=quux".to_vec().into()).unwrap();
        cookie.append("baz", "quux");
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b" foo  =    bar;baz= quux  ".to_vec().into()).unwrap();
        assert_eq!(cookie, parsed);

        let parsed =
            Cookie::parse_header(&vec![b"foo  =    bar".to_vec(), b"baz= quux  ".to_vec()].into())
                .unwrap();
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar; baz=quux ; empty=".to_vec().into()).unwrap();
        cookie.append("empty", "");
        assert_eq!(cookie, parsed);

        let mut cookie = Cookie::new();

        let parsed = Cookie::parse_header(&b"middle=equals=in=the=middle".to_vec().into()).unwrap();
        cookie.append("middle", "equals=in=the=middle");
        assert_eq!(cookie, parsed);

        let parsed =
            Cookie::parse_header(&b"middle=equals=in=the=middle; double==2".to_vec().into())
                .unwrap();
        cookie.append("double", "=2");
        assert_eq!(cookie, parsed);

        Cookie::parse_header(&b"foo;bar=baz;quux".to_vec().into()).unwrap_err();

    }
}

bench_header!(bench, Cookie, {
    vec![b"foo=bar; baz=quux".to_vec()]
});
<commit_msg>fix(header): ignore invalid cookies<commit_after>use std::borrow::Cow;
use std::fmt;
use std::str::from_utf8;

use header::{Header, Raw};
use header::internals::VecMap;

/// `Cookie` header, defined in [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.4)
///
/// If the user agent does attach a Cookie header field to an HTTP
/// request, the user agent must send the cookie-string
/// as the value of the header field.
///
/// When the user agent generates an HTTP request, the user agent MUST NOT
/// attach more than one Cookie header field.
///
/// # Example values
/// * `SID=31d4d96e407aad42`
/// * `SID=31d4d96e407aad42; lang=en-US`
///
/// # Example
/// ```
/// use hyper::header::{Headers, Cookie};
///
/// let mut headers = Headers::new();
/// let mut cookie = Cookie::new();
/// cookie.append("foo", "bar");
///
/// assert_eq!(cookie.get("foo"), Some("bar"));
///
/// headers.set(cookie);
/// ```
#[derive(Clone)]
pub struct Cookie(VecMap<Cow<'static, str>, Cow<'static, str>>);

impl Cookie {
    /// Creates a new `Cookie` header.
    pub fn new() -> Cookie {
        Cookie(VecMap::with_capacity(0))
    }

    /// Sets a name and value for the `Cookie`.
    ///
    /// # Note
    ///
    /// This will remove all other instances with the same name,
    /// and insert the new value.
    pub fn set<K, V>(&mut self, key: K, value: V)
        where K: Into<Cow<'static, str>>,
              V: Into<Cow<'static, str>>
    {
        let key = key.into();
        let value = value.into();
        self.0.remove_all(&key);
        self.0.append(key, value);
    }

    /// Append a name and value for the `Cookie`.
    ///
    /// # Note
    ///
    /// Cookies are allowed to set a name with a
    /// a value multiple times. For example:
    ///
    /// ```
    /// use hyper::header::Cookie;
    /// let mut cookie = Cookie::new();
    /// cookie.append("foo", "bar");
    /// cookie.append("foo", "quux");
    /// assert_eq!(cookie.to_string(), "foo=bar; foo=quux");
    pub fn append<K, V>(&mut self, key: K, value: V)
        where K: Into<Cow<'static, str>>,
              V: Into<Cow<'static, str>>
    {
        self.0.append(key.into(), value.into());
    }

    /// Get a value for the name, if it exists.
    ///
    /// # Note
    ///
    /// Only returns the first instance found. To access
    /// any other values associated with the name, parse
    /// the `str` representation.
    pub fn get(&self, key: &str) -> Option<&str> {
        self.0.get(key).map(AsRef::as_ref)
    }
}

impl Header for Cookie {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Cookie";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<Cookie> {
        let mut vec_map = VecMap::with_capacity(raw.len());
        for cookies_raw in raw.iter() {
            let cookies_str = try!(from_utf8(&cookies_raw[..]));
            for cookie_str in cookies_str.split(';') {
                let mut key_val = cookie_str.splitn(2, '=');
                let key_val = (key_val.next(), key_val.next());
                if let (Some(key), Some(val)) = key_val {
                    vec_map.insert(key.trim().to_owned().into(), val.trim().to_owned().into());
                }
            }
        }

        if vec_map.len() != 0 {
            Ok(Cookie(vec_map))
        } else {
            Err(::Error::Header)
        }
    }

    fn fmt_header(&self, f: &mut ::header::Formatter) -> fmt::Result {
        f.fmt_line(self)
    }
}

impl PartialEq for Cookie {
    fn eq(&self, other: &Cookie) -> bool {
        if self.0.len() == other.0.len() {
            for &(ref k, ref v) in self.0.iter() {
                if other.get(k) != Some(v) {
                    return false;
                }
            }
            true
        } else {
            false
        }
    }
}

impl fmt::Debug for Cookie {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_map()
            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
            .finish()
    }
}

impl fmt::Display for Cookie {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut iter = self.0.iter();
        if let Some(&(ref key, ref val)) = iter.next() {
            try!(write!(f, "{}={}", key, val));
        }
        for &(ref key, ref val) in iter {
            try!(write!(f, "; {}={}", key, val));
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use header::Header;
    use super::Cookie;

    #[test]
    fn test_set_and_get() {
        let mut cookie = Cookie::new();
        cookie.append("foo", "bar");
        cookie.append(String::from("dyn"), String::from("amic"));

        assert_eq!(cookie.get("foo"), Some("bar"));
        assert_eq!(cookie.get("dyn"), Some("amic"));
        assert!(cookie.get("nope").is_none());

        cookie.append("foo", "notbar");
        assert_eq!(cookie.get("foo"), Some("bar"));

        cookie.set("foo", "hi");
        assert_eq!(cookie.get("foo"), Some("hi"));
        assert_eq!(cookie.get("dyn"), Some("amic"));
    }

    #[test]
    fn test_eq() {
        let mut cookie = Cookie::new();
        let mut cookie2 = Cookie::new();

        // empty is equal
        assert_eq!(cookie, cookie2);

        // left has more params
        cookie.append("foo", "bar");
        assert!(cookie != cookie2);

        // same len, different params
        cookie2.append("bar", "foo");
        assert!(cookie != cookie2);

        // right has more params, and matching KV
        cookie2.append("foo", "bar");
        assert!(cookie != cookie2);

        // same params, different order
        cookie.append("bar", "foo");
        assert_eq!(cookie, cookie2);
    }

    #[test]
    fn test_parse() {
        let mut cookie = Cookie::new();

        let parsed = Cookie::parse_header(&b"foo=bar".to_vec().into()).unwrap();
        cookie.append("foo", "bar");
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar;".to_vec().into()).unwrap();
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar; baz=quux".to_vec().into()).unwrap();
        cookie.append("baz", "quux");
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar;; baz=quux".to_vec().into()).unwrap();
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar; invalid ; bad; ;; baz=quux".to_vec().into())
            .unwrap();
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b" foo  =    bar;baz= quux  ".to_vec().into()).unwrap();
        assert_eq!(cookie, parsed);

        let parsed =
            Cookie::parse_header(&vec![b"foo  =    bar".to_vec(), b"baz= quux  ".to_vec()].into())
                .unwrap();
        assert_eq!(cookie, parsed);

        let parsed = Cookie::parse_header(&b"foo=bar; baz=quux ; empty=".to_vec().into()).unwrap();
        cookie.append("empty", "");
        assert_eq!(cookie, parsed);

        let mut cookie = Cookie::new();

        let parsed = Cookie::parse_header(&b"middle=equals=in=the=middle".to_vec().into()).unwrap();
        cookie.append("middle", "equals=in=the=middle");
        assert_eq!(cookie, parsed);

        let parsed =
            Cookie::parse_header(&b"middle=equals=in=the=middle; double==2".to_vec().into())
                .unwrap();
        cookie.append("double", "=2");
        assert_eq!(cookie, parsed);
    }
}

bench_header!(bench, Cookie, {
    vec![b"foo=bar; baz=quux".to_vec()]
});
<|endoftext|>