<commit_before>// Copyright 2017 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.

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// thatthat the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    /// Return the opening delimiter (possibly `NoDelim`).
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    /// Return the closing delimiter (possibly `NoDelim`).
    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the opening delimiter.
    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the closing delimiter.
    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene star (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    /// Return the number of tokens in the tree.
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    /// Returns true if the given token tree contains no other tokens. This is vacuously true for
    /// single tokens or metavar/decls, but may be false for delimited trees or sequences.
    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    /// Get the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
/// collection of `TokenTree` for use in parsing a macro.
///
/// # Parameters
///
/// - `input`: a token stream to read from, the contents of which we are parsing.
/// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
///   macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
///   their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
///   `ident` are "matchers". They are not present in the body of a macro rule -- just in the
///   pattern, so we pass a parameter to indicate whether to expect them or not.
/// - `sess`: the parsing session. Any errors will be emitted to this session.
///
/// # Returns
///
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    // Will contain the final collection of `self::TokenTree`
    let mut result = Vec::new();

    // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
    // additional trees if need be.
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);

        // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }

            // Not a metavar or no matchers allowed, so just return the tree
            _ => result.push(tree),
        }
    }
    result
}

/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
/// for use in parsing a macro.
///
/// Converting the given tree may involve reading more tokens.
///
/// # Parameters
///
/// - `tree`: the tree wish to convert.
/// - `trees`: an iterator over trees. We may need to read more tokens from it in order to finish
///   converting `tree`
/// - `expect_matchers`: same as for `parse` (see above).
/// - `sess`: the parsing session. Any errors will be emitted to this session.
fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    // Depending on what `tree` is, we could be parsing different parts of a macro
    match tree {
        // `tree` is a `$` token. Look at the next token in `trees`
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            // `tree` is followed by a delimited set of token trees. This indicates the beginning
            // of a repetition sequence in the macro (e.g. `$(pat)*`).
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                // Must have `(` not `{` or `[`
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                // Parse the contents of the sequence itself
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                // Get the Kleen operator and optional separator
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                // Count the number of captured "names" (i.e. named metavars)
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }

            // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
            // metavariable that names the crate of the invokation.
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }

            // `tree` is followed by a random token. This is an error.
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }

            // There are no more tokens. Just return the `$` we already have.
            None => TokenTree::Token(span, token::Dollar),
        },

        // `tree` is an arbitrary token. Keep it.
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),

        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
        // descend into the delimited set and further parse it.
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _macro_ itself, rather than trying to match some
/// stream of tokens in an invokation of a macro.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<commit_msg>Fix typos<commit_after>// Copyright 2017 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.

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// that the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    /// Return the opening delimiter (possibly `NoDelim`).
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    /// Return the closing delimiter (possibly `NoDelim`).
    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the opening delimiter.
    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the closing delimiter.
    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene plus (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    /// Return the number of tokens in the tree.
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    /// Returns true if the given token tree contains no other tokens. This is vacuously true for
    /// single tokens or metavar/decls, but may be false for delimited trees or sequences.
    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    /// Get the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
/// collection of `TokenTree` for use in parsing a macro.
///
/// # Parameters
///
/// - `input`: a token stream to read from, the contents of which we are parsing.
/// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
///   macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
///   their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
///   `ident` are "matchers". They are not present in the body of a macro rule -- just in the
///   pattern, so we pass a parameter to indicate whether to expect them or not.
/// - `sess`: the parsing session. Any errors will be emitted to this session.
///
/// # Returns
///
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    // Will contain the final collection of `self::TokenTree`
    let mut result = Vec::new();

    // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
    // additional trees if need be.
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);

        // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }

            // Not a metavar or no matchers allowed, so just return the tree
            _ => result.push(tree),
        }
    }
    result
}

/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
/// for use in parsing a macro.
///
/// Converting the given tree may involve reading more tokens.
///
/// # Parameters
///
/// - `tree`: the tree wish to convert.
/// - `trees`: an iterator over trees. We may need to read more tokens from it in order to finish
///   converting `tree`
/// - `expect_matchers`: same as for `parse` (see above).
/// - `sess`: the parsing session. Any errors will be emitted to this session.
fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    // Depending on what `tree` is, we could be parsing different parts of a macro
    match tree {
        // `tree` is a `$` token. Look at the next token in `trees`
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            // `tree` is followed by a delimited set of token trees. This indicates the beginning
            // of a repetition sequence in the macro (e.g. `$(pat)*`).
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                // Must have `(` not `{` or `[`
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                // Parse the contents of the sequence itself
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                // Get the Kleene operator and optional separator
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                // Count the number of captured "names" (i.e. named metavars)
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }

            // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
            // metavariable that names the crate of the invokation.
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }

            // `tree` is followed by a random token. This is an error.
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }

            // There are no more tokens. Just return the `$` we already have.
            None => TokenTree::Token(span, token::Dollar),
        },

        // `tree` is an arbitrary token. Keep it.
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),

        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
        // descend into the delimited set and further parse it.
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _macro_ itself, rather than trying to match some
/// stream of tokens in an invokation of a macro.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #9397 - alexcrichton:fix-hash, r=ehuss<commit_after><|endoftext|>


<commit_before><commit_msg>converted more macros to generics<commit_after><|endoftext|>


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

use self::SmallVectorRepr::*;
use self::IntoIterRepr::*;

use std::iter::{IntoIterator, FromIterator};
use std::mem;
use std::slice;
use std::vec;

use fold::MoveMap;

/// A vector type optimized for cases where the size is almost always 0 or 1
pub struct SmallVector<T> {
    repr: SmallVectorRepr<T>,
}

enum SmallVectorRepr<T> {
    Zero,
    One(T),
    Many(Vec<T>),
}

impl<T> FromIterator<T> for SmallVector<T> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> SmallVector<T> {
        let mut v = SmallVector::zero();
        v.extend(iter);
        v
    }
}

impl<T> Extend<T> for SmallVector<T> {
    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
        for val in iter {
            self.push(val);
        }
    }
}

impl<T> SmallVector<T> {
    pub fn zero() -> SmallVector<T> {
        SmallVector { repr: Zero }
    }

    pub fn one(v: T) -> SmallVector<T> {
        SmallVector { repr: One(v) }
    }

    pub fn many(vs: Vec<T>) -> SmallVector<T> {
        SmallVector { repr: Many(vs) }
    }

    pub fn as_slice<'a>(&'a self) -> &'a [T] {
        match self.repr {
            Zero => {
                let result: &[T] = &[];
                result
            }
            One(ref v) => slice::ref_slice(v),
            Many(ref vs) => vs
        }
    }

    pub fn pop(&mut self) -> Option<T> {
        match self.repr {
            Zero => None,
            One(..) => {
                let one = mem::replace(&mut self.repr, Zero);
                match one {
                    One(v1) => Some(v1),
                    _ => unreachable!()
                }
            }
            Many(ref mut vs) => vs.pop(),
        }
    }

    pub fn push(&mut self, v: T) {
        match self.repr {
            Zero => self.repr = One(v),
            One(..) => {
                let one = mem::replace(&mut self.repr, Zero);
                match one {
                    One(v1) => mem::replace(&mut self.repr, Many(vec!(v1, v))),
                    _ => unreachable!()
                };
            }
            Many(ref mut vs) => vs.push(v)
        }
    }

    pub fn push_all(&mut self, other: SmallVector<T>) {
        for v in other.into_iter() {
            self.push(v);
        }
    }

    pub fn get<'a>(&'a self, idx: usize) -> &'a T {
        match self.repr {
            One(ref v) if idx == 0 => v,
            Many(ref vs) => &vs[idx],
            _ => panic!("out of bounds access")
        }
    }

    pub fn expect_one(self, err: &'static str) -> T {
        match self.repr {
            One(v) => v,
            Many(v) => {
                if v.len() == 1 {
                    v.into_iter().next().unwrap()
                } else {
                    panic!(err)
                }
            }
            _ => panic!(err)
        }
    }

    /// Deprecated: use `into_iter`.
    #[unstable(feature = "rustc_private")]
    #[deprecated(since = "1.0.0", reason = "use into_iter")]
    pub fn move_iter(self) -> IntoIter<T> {
        self.into_iter()
    }

    pub fn into_iter(self) -> IntoIter<T> {
        let repr = match self.repr {
            Zero => ZeroIterator,
            One(v) => OneIterator(v),
            Many(vs) => ManyIterator(vs.into_iter())
        };
        IntoIter { repr: repr }
    }

    pub fn len(&self) -> usize {
        match self.repr {
            Zero => 0,
            One(..) => 1,
            Many(ref vals) => vals.len()
        }
    }

    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

pub struct IntoIter<T> {
    repr: IntoIterRepr<T>,
}

enum IntoIterRepr<T> {
    ZeroIterator,
    OneIterator(T),
    ManyIterator(vec::IntoIter<T>),
}

impl<T> Iterator for IntoIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        match self.repr {
            ZeroIterator => None,
            OneIterator(..) => {
                let mut replacement = ZeroIterator;
                mem::swap(&mut self.repr, &mut replacement);
                match replacement {
                    OneIterator(v) => Some(v),
                    _ => unreachable!()
                }
            }
            ManyIterator(ref mut inner) => inner.next()
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.repr {
            ZeroIterator => (0, Some(0)),
            OneIterator(..) => (1, Some(1)),
            ManyIterator(ref inner) => inner.size_hint()
        }
    }
}

impl<T> MoveMap<T> for SmallVector<T> {
    fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T {
        let repr = match self.repr {
            Zero => Zero,
            One(v) => One(f(v)),
            Many(vs) => Many(vs.move_map(f))
        };
        SmallVector { repr: repr }
    }
}

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

    #[test]
    fn test_len() {
        let v: SmallVector<isize> = SmallVector::zero();
        assert_eq!(0, v.len());

        assert_eq!(1, SmallVector::one(1).len());
        assert_eq!(5, SmallVector::many(vec![1, 2, 3, 4, 5]).len());
    }

    #[test]
    fn test_push_get() {
        let mut v = SmallVector::zero();
        v.push(1);
        assert_eq!(1, v.len());
        assert_eq!(&1, v.get(0));
        v.push(2);
        assert_eq!(2, v.len());
        assert_eq!(&2, v.get(1));
        v.push(3);
        assert_eq!(3, v.len());
        assert_eq!(&3, v.get(2));
    }

    #[test]
    fn test_from_iter() {
        let v: SmallVector<isize> = (vec![1, 2, 3]).into_iter().collect();
        assert_eq!(3, v.len());
        assert_eq!(&1, v.get(0));
        assert_eq!(&2, v.get(1));
        assert_eq!(&3, v.get(2));
    }

    #[test]
    fn test_move_iter() {
        let v = SmallVector::zero();
        let v: Vec<isize> = v.into_iter().collect();
        assert_eq!(v, Vec::new());

        let v = SmallVector::one(1);
        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1]);

        let v = SmallVector::many(vec![1, 2, 3]);
        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1, 2, 3]);
    }

    #[test]
    #[should_panic]
    fn test_expect_one_zero() {
        let _: isize = SmallVector::zero().expect_one("");
    }

    #[test]
    #[should_panic]
    fn test_expect_one_many() {
        SmallVector::many(vec!(1, 2)).expect_one("");
    }

    #[test]
    fn test_expect_one_one() {
        assert_eq!(1, SmallVector::one(1).expect_one(""));
        assert_eq!(1, SmallVector::many(vec!(1)).expect_one(""));
    }
}
<commit_msg>syntax: Don't use unstable fn to convert single element to a slice<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use self::SmallVectorRepr::*;
use self::IntoIterRepr::*;

use std::iter::{IntoIterator, FromIterator};
use std::mem;
use std::slice;
use std::vec;

use fold::MoveMap;

/// A vector type optimized for cases where the size is almost always 0 or 1
pub struct SmallVector<T> {
    repr: SmallVectorRepr<T>,
}

enum SmallVectorRepr<T> {
    Zero,
    One(T),
    Many(Vec<T>),
}

impl<T> FromIterator<T> for SmallVector<T> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> SmallVector<T> {
        let mut v = SmallVector::zero();
        v.extend(iter);
        v
    }
}

impl<T> Extend<T> for SmallVector<T> {
    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
        for val in iter {
            self.push(val);
        }
    }
}

impl<T> SmallVector<T> {
    pub fn zero() -> SmallVector<T> {
        SmallVector { repr: Zero }
    }

    pub fn one(v: T) -> SmallVector<T> {
        SmallVector { repr: One(v) }
    }

    pub fn many(vs: Vec<T>) -> SmallVector<T> {
        SmallVector { repr: Many(vs) }
    }

    pub fn as_slice<'a>(&'a self) -> &'a [T] {
        match self.repr {
            Zero => {
                let result: &[T] = &[];
                result
            }
            One(ref v) => {
                // FIXME: Could be replaced with `slice::ref_slice(v)` when it is stable.
                unsafe { slice::from_raw_parts(v, 1) }
            }
            Many(ref vs) => vs
        }
    }

    pub fn pop(&mut self) -> Option<T> {
        match self.repr {
            Zero => None,
            One(..) => {
                let one = mem::replace(&mut self.repr, Zero);
                match one {
                    One(v1) => Some(v1),
                    _ => unreachable!()
                }
            }
            Many(ref mut vs) => vs.pop(),
        }
    }

    pub fn push(&mut self, v: T) {
        match self.repr {
            Zero => self.repr = One(v),
            One(..) => {
                let one = mem::replace(&mut self.repr, Zero);
                match one {
                    One(v1) => mem::replace(&mut self.repr, Many(vec!(v1, v))),
                    _ => unreachable!()
                };
            }
            Many(ref mut vs) => vs.push(v)
        }
    }

    pub fn push_all(&mut self, other: SmallVector<T>) {
        for v in other.into_iter() {
            self.push(v);
        }
    }

    pub fn get<'a>(&'a self, idx: usize) -> &'a T {
        match self.repr {
            One(ref v) if idx == 0 => v,
            Many(ref vs) => &vs[idx],
            _ => panic!("out of bounds access")
        }
    }

    pub fn expect_one(self, err: &'static str) -> T {
        match self.repr {
            One(v) => v,
            Many(v) => {
                if v.len() == 1 {
                    v.into_iter().next().unwrap()
                } else {
                    panic!(err)
                }
            }
            _ => panic!(err)
        }
    }

    /// Deprecated: use `into_iter`.
    #[unstable(feature = "rustc_private")]
    #[deprecated(since = "1.0.0", reason = "use into_iter")]
    pub fn move_iter(self) -> IntoIter<T> {
        self.into_iter()
    }

    pub fn into_iter(self) -> IntoIter<T> {
        let repr = match self.repr {
            Zero => ZeroIterator,
            One(v) => OneIterator(v),
            Many(vs) => ManyIterator(vs.into_iter())
        };
        IntoIter { repr: repr }
    }

    pub fn len(&self) -> usize {
        match self.repr {
            Zero => 0,
            One(..) => 1,
            Many(ref vals) => vals.len()
        }
    }

    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

pub struct IntoIter<T> {
    repr: IntoIterRepr<T>,
}

enum IntoIterRepr<T> {
    ZeroIterator,
    OneIterator(T),
    ManyIterator(vec::IntoIter<T>),
}

impl<T> Iterator for IntoIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        match self.repr {
            ZeroIterator => None,
            OneIterator(..) => {
                let mut replacement = ZeroIterator;
                mem::swap(&mut self.repr, &mut replacement);
                match replacement {
                    OneIterator(v) => Some(v),
                    _ => unreachable!()
                }
            }
            ManyIterator(ref mut inner) => inner.next()
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.repr {
            ZeroIterator => (0, Some(0)),
            OneIterator(..) => (1, Some(1)),
            ManyIterator(ref inner) => inner.size_hint()
        }
    }
}

impl<T> MoveMap<T> for SmallVector<T> {
    fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T {
        let repr = match self.repr {
            Zero => Zero,
            One(v) => One(f(v)),
            Many(vs) => Many(vs.move_map(f))
        };
        SmallVector { repr: repr }
    }
}

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

    #[test]
    fn test_len() {
        let v: SmallVector<isize> = SmallVector::zero();
        assert_eq!(0, v.len());

        assert_eq!(1, SmallVector::one(1).len());
        assert_eq!(5, SmallVector::many(vec![1, 2, 3, 4, 5]).len());
    }

    #[test]
    fn test_push_get() {
        let mut v = SmallVector::zero();
        v.push(1);
        assert_eq!(1, v.len());
        assert_eq!(&1, v.get(0));
        v.push(2);
        assert_eq!(2, v.len());
        assert_eq!(&2, v.get(1));
        v.push(3);
        assert_eq!(3, v.len());
        assert_eq!(&3, v.get(2));
    }

    #[test]
    fn test_from_iter() {
        let v: SmallVector<isize> = (vec![1, 2, 3]).into_iter().collect();
        assert_eq!(3, v.len());
        assert_eq!(&1, v.get(0));
        assert_eq!(&2, v.get(1));
        assert_eq!(&3, v.get(2));
    }

    #[test]
    fn test_move_iter() {
        let v = SmallVector::zero();
        let v: Vec<isize> = v.into_iter().collect();
        assert_eq!(v, Vec::new());

        let v = SmallVector::one(1);
        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1]);

        let v = SmallVector::many(vec![1, 2, 3]);
        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1, 2, 3]);
    }

    #[test]
    #[should_panic]
    fn test_expect_one_zero() {
        let _: isize = SmallVector::zero().expect_one("");
    }

    #[test]
    #[should_panic]
    fn test_expect_one_many() {
        SmallVector::many(vec!(1, 2)).expect_one("");
    }

    #[test]
    fn test_expect_one_one() {
        assert_eq!(1, SmallVector::one(1).expect_one(""));
        assert_eq!(1, SmallVector::many(vec!(1)).expect_one(""));
    }
}
<|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/.

// Functions for dealing with device mapper names.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, DmUuidBuf};

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

#[derive(Clone, Copy)]
pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// The various roles taken on by DM devices in the cache tier.
#[derive(Clone, Copy)]
pub enum CacheRole {
    /// The DM cache device, contains the other three devices.
    #[allow(dead_code)]
    Cache,
    /// The cache sub-device of the DM cache device.
    #[allow(dead_code)]
    CacheSub,
    /// The meta sub-device of the DM cache device.
    #[allow(dead_code)]
    MetaSub,
    /// The origin sub-device of the DM cache device, holds the actual data.
    OriginSub,
}

impl Display for CacheRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CacheRole::Cache => write!(f, "cache"),
            CacheRole::CacheSub => write!(f, "cachesub"),
            CacheRole::MetaSub => write!(f, "metasub"),
            CacheRole::OriginSub => write!(f, "originsub"),
        }
    }
}

/// Format a name & uuid for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_ids(pool_uuid: PoolUuid, role: FlexRole) -> (DmNameBuf, DmUuidBuf) {
    (DmNameBuf::new(format!("stratis-{}-{}-flex-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display length < 72"),
     DmUuidBuf::new(format!("stratis-{}-{}-flex-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display length < 72"))

}

/// Format a name & uuid for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_ids(pool_uuid: PoolUuid, role: ThinRole) -> (DmNameBuf, DmUuidBuf) {
    (DmNameBuf::new(format!("stratis-{}-{}-thin-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display length < 50"),
     DmUuidBuf::new(format!("stratis-{}-{}-thin-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display length < 50"))
}

/// Format a name & uuid for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_ids(pool_uuid: PoolUuid, role: ThinPoolRole) -> (DmNameBuf, DmUuidBuf) {
    (DmNameBuf::new(format!("stratis-{}-{}-thinpool-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display_length < 81"),
     DmUuidBuf::new(format!("stratis-{}-{}-thinpool-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display_length < 81"))
}

/// Format a name & uuid for dm devices in the backstore.
/// Prerequisite: len(format!("{}", FORMAT_VERSION) < 76
pub fn format_backstore_ids(pool_uuid: PoolUuid, role: CacheRole) -> (DmNameBuf, DmUuidBuf) {
    (DmNameBuf::new(format!("stratis-{}-{}-physical-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display_length < 76"),
     DmUuidBuf::new(format!("stratis-{}-{}-physical-{}",
                            FORMAT_VERSION,
                            pool_uuid.simple().to_string(),
                            role))
             .expect("FORMAT_VERSION display_length < 76"))
}
<commit_msg>Tighten up format_* methods for DM names<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/.

// Functions for dealing with device mapper names.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, DmUuidBuf};

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

#[derive(Clone, Copy)]
pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// The various roles taken on by DM devices in the cache tier.
#[derive(Clone, Copy)]
pub enum CacheRole {
    /// The DM cache device, contains the other three devices.
    #[allow(dead_code)]
    Cache,
    /// The cache sub-device of the DM cache device.
    #[allow(dead_code)]
    CacheSub,
    /// The meta sub-device of the DM cache device.
    #[allow(dead_code)]
    MetaSub,
    /// The origin sub-device of the DM cache device, holds the actual data.
    OriginSub,
}

impl Display for CacheRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CacheRole::Cache => write!(f, "cache"),
            CacheRole::CacheSub => write!(f, "cachesub"),
            CacheRole::MetaSub => write!(f, "metasub"),
            CacheRole::OriginSub => write!(f, "originsub"),
        }
    }
}

/// Format a name & uuid for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_ids(pool_uuid: PoolUuid, role: FlexRole) -> (DmNameBuf, DmUuidBuf) {
    let value = format!("stratis-{}-{}-flex-{}",
                        FORMAT_VERSION,
                        pool_uuid.simple().to_string(),
                        role);
    (DmNameBuf::new(value.clone()).expect("FORMAT_VERSION display length < 72"),
     DmUuidBuf::new(value).expect("FORMAT_VERSION display length < 73"))

}

/// Format a name & uuid for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_ids(pool_uuid: PoolUuid, role: ThinRole) -> (DmNameBuf, DmUuidBuf) {
    let value = format!("stratis-{}-{}-thin-{}",
                        FORMAT_VERSION,
                        pool_uuid.simple().to_string(),
                        role);
    (DmNameBuf::new(value.clone()).expect("FORMAT_VERSION display length < 50"),
     DmUuidBuf::new(value).expect("FORMAT_VERSION display length < 51"))
}

/// Format a name & uuid for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_ids(pool_uuid: PoolUuid, role: ThinPoolRole) -> (DmNameBuf, DmUuidBuf) {
    let value = format!("stratis-{}-{}-thinpool-{}",
                        FORMAT_VERSION,
                        pool_uuid.simple().to_string(),
                        role);
    (DmNameBuf::new(value.clone()).expect("FORMAT_VERSION display_length < 81"),
     DmUuidBuf::new(value).expect("FORMAT_VERSION display_length < 82"))
}

/// Format a name & uuid for dm devices in the backstore.
/// Prerequisite: len(format!("{}", FORMAT_VERSION) < 76
pub fn format_backstore_ids(pool_uuid: PoolUuid, role: CacheRole) -> (DmNameBuf, DmUuidBuf) {
    let value = format!("stratis-{}-{}-physical-{}",
                        FORMAT_VERSION,
                        pool_uuid.simple().to_string(),
                        role);
    (DmNameBuf::new(value.clone()).expect("FORMAT_VERSION display_length < 76"),
     DmUuidBuf::new(value).expect("FORMAT_VERSION display_length < 77"))
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

fn main() {
    struct X { x: (), }
    let x = Some((X { x: () }, X { x: () }));
    match x {
        Some((y, ref z)) => {},
        //~^ ERROR E0009
        //~| NOTE by-move pattern here
        //~| NOTE both by-ref and by-move used
        None => panic!()
    }
}
<commit_msg>Remove trailing white space<commit_after>// Copyright 2016 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.

fn main() {
    struct X { x: (), }
    let x = Some((X { x: () }, X { x: () }));
    match x {
        Some((y, ref z)) => {},
        //~^ ERROR E0009
        //~| NOTE by-move pattern here
        //~| NOTE both by-ref and by-move used
        None => panic!()
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}

use foo::MyTrait::do_something;
    //~^ ERROR E0253
    //~|NOTE not directly importable

fn main() {}
<commit_msg>Update E0253.rs<commit_after>// Copyright 2016 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.

mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}

use foo::MyTrait::do_something;
    //~^ ERROR E0253
    //~|NOTE cannot be imported directly

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Generate completion for imag-git<commit_after><|endoftext|>


<commit_before>// Copyright 2017 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(conservative_impl_trait)]

pub fn g() -> impl Iterator<Item=u8> {
    Some(1u8).into_iter()
}

pub fn h() -> (impl Iterator<Item=u8>) {
    Some(1u8).into_iter()
}

pub fn i() -> impl Iterator<Item=u8> + 'static {
    Some(1u8).into_iter()
}

pub fn j() -> impl Iterator<Item=u8> + Clone {
    Some(1u8).into_iter()
}

pub fn k() -> [impl Clone; 2] {
    [123u32, 456u32]
}

pub fn l() -> (impl Clone, impl Default) {
    (789u32, -123i32)
}

pub fn m() -> &'static impl Clone {
    &1u8
}

pub fn n() -> *const impl Clone {
    &1u8
}

pub fn o() -> &'static [impl Clone] {
    b":)"
}

// issue #44731
pub fn test_44731_0() -> Box<impl Iterator<Item=u8>> {
    Box::new(g())
}

pub fn test_44731_1() -> Result<Box<impl Clone>, ()> {
    Ok(Box::new(j()))
}

pub fn test_44731_3() -> Box<Fn() -> impl Clone> {
    Box::new(|| 0u32)
}

pub fn test_44731_4() -> Box<Iterator<Item=impl Clone>> {
    Box::new(g())
}

// @has issue_43869/fn.g.html
// @has issue_43869/fn.h.html
// @has issue_43869/fn.i.html
// @has issue_43869/fn.j.html
// @has issue_43869/fn.k.html
// @has issue_43869/fn.l.html
// @has issue_43869/fn.m.html
// @has issue_43869/fn.n.html
// @has issue_43869/fn.o.html
// @has issue_43869/fn.test_44731_0.html
// @has issue_43869/fn.test_44731_1.html
// @has issue_43869/fn.test_44731_3.html
// @has issue_43869/fn.test_44731_4.html
<commit_msg>Remove Fn trait + impl Trait rustdoc tests<commit_after>// Copyright 2017 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(conservative_impl_trait)]

pub fn g() -> impl Iterator<Item=u8> {
    Some(1u8).into_iter()
}

pub fn h() -> (impl Iterator<Item=u8>) {
    Some(1u8).into_iter()
}

pub fn i() -> impl Iterator<Item=u8> + 'static {
    Some(1u8).into_iter()
}

pub fn j() -> impl Iterator<Item=u8> + Clone {
    Some(1u8).into_iter()
}

pub fn k() -> [impl Clone; 2] {
    [123u32, 456u32]
}

pub fn l() -> (impl Clone, impl Default) {
    (789u32, -123i32)
}

pub fn m() -> &'static impl Clone {
    &1u8
}

pub fn n() -> *const impl Clone {
    &1u8
}

pub fn o() -> &'static [impl Clone] {
    b":)"
}

// issue #44731
pub fn test_44731_0() -> Box<impl Iterator<Item=u8>> {
    Box::new(g())
}

pub fn test_44731_1() -> Result<Box<impl Clone>, ()> {
    Ok(Box::new(j()))
}

// NOTE these involve Fn sugar, where impl Trait is disallowed for now, see issue #45994
//
//pub fn test_44731_2() -> Box<Fn(impl Clone)> {
//    Box::new(|_: u32| {})
//}
//
//pub fn test_44731_3() -> Box<Fn() -> impl Clone> {
//    Box::new(|| 0u32)
//}

pub fn test_44731_4() -> Box<Iterator<Item=impl Clone>> {
    Box::new(g())
}

// @has issue_43869/fn.g.html
// @has issue_43869/fn.h.html
// @has issue_43869/fn.i.html
// @has issue_43869/fn.j.html
// @has issue_43869/fn.k.html
// @has issue_43869/fn.l.html
// @has issue_43869/fn.m.html
// @has issue_43869/fn.n.html
// @has issue_43869/fn.o.html
// @has issue_43869/fn.test_44731_0.html
// @has issue_43869/fn.test_44731_1.html
// @has issue_43869/fn.test_44731_4.html
<|endoftext|>


<commit_before><commit_msg>Fix: Only sized `Reader`s can implement `CReader`<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed Object<T>::new failing because of the new field<commit_after><|endoftext|>


<commit_before><commit_msg>Add functions to get buffer as LF and to move cursor<commit_after><|endoftext|>


<commit_before>use common::*;

/// An installable package for Ox
pub struct Package {
    // TODO: Many of these uses String where other types can be used (when integreting with octavo)
    /// The host (where the package can be found)
    pub host: String,
    /// The name of this package
    pub name: String,
    /// The version of this package
    pub version: String,
    /// Description
    pub desc: String,
    //    /// The developer's public key
    //    pub dev: String,
    //    /// The developer's signature of this package
    //    pub dev_signature: String,
    //    /// Signatures of the developers public key from people who trusts the developers.
    //    pub trust: Vec<String>,
    //    /// The signatures of this package
    //    pub signatures: Vec<String>,
    /// The files this package will create on the computer.
    pub files: Vec<String>,
}

pub fn get_package(host: String, name: String, version: String) -> Package {
    let con = File::open("tcp://".to_string() + host);

    con.write("GET /ox/".to_string() + version + "-".to_string() + name + " HTTP/1.1".to_string());

    let resp;

    {
        let res = Vec::new();
        con.read_to_end(&mut res);

        resp = String::from_utf8(&res).split("\n".to_string());
    }

    let mut name = "".to_string();
    let mut desc = "".to_string();
    let mut host = "".to_string();
    let mut files = "".to_string();
    let mut version = "".to_string();

    for i in resp {
        let data = i.substr(5, i.len() - 5);
        let key = i.substr(0, 4);

        if key == "name".to_string() {
            name = data;
        } else if key == "desc".to_string() {
            desc = data;
        } else if key == "host".to_string() {
            host = data;
        } else if key == "file".to_string() {
            files = data;
        } else if key == "vers".to_string() {
            version = data;
        }
    }

    Package {
        host: host,
        name: name,
        desc: desc,
        files: files.split(",".to_string()).collect::<Vec<_>>(),
        version: version,
    }
}
<commit_msg>Add temporary rsa implementation<commit_after>use common::*;

mod rsa;

/// An installable package for Ox
pub struct Package {
    // TODO: Many of these uses String where other types can be used (when integreting with octavo)
    /// The host (where the package can be found)
    pub host: String,
    /// The name of this package
    pub name: String,
    /// The version of this package
    pub version: String,
    /// Description
    pub desc: String,
    //    /// The developer's public key
    //    pub dev: String,
    //    /// The developer's signature of this package
    //    pub dev_signature: String,
    //    /// Signatures of the developers public key from people who trusts the developers.
    //    pub trust: Vec<String>,
    //    /// The signatures of this package
    //    pub signatures: Vec<String>,
    /// The files this package will create on the computer.
    pub files: Vec<String>,
}

pub fn get_package(host: String, name: String, version: String) -> Package {
    let con = File::open("tcp://".to_string() + host);

    con.write("GET /ox/".to_string() + version + "-".to_string() + name + " HTTP/1.1".to_string());

    let resp;

    {
        let res = Vec::new();
        con.read_to_end(&mut res);

        resp = String::from_utf8(&res).split("\n".to_string());
    }

    let mut name = "".to_string();
    let mut desc = "".to_string();
    let mut host = "".to_string();
    let mut files = "".to_string();
    let mut version = "".to_string();

    for i in resp {
        let data = i.substr(5, i.len() - 5);
        let key = i.substr(0, 4);

        if key == "name".to_string() {
            name = data;
        } else if key == "desc".to_string() {
            desc = data;
        } else if key == "host".to_string() {
            host = data;
        } else if key == "file".to_string() {
            files = data;
        } else if key == "vers".to_string() {
            version = data;
        }
    }

    Package {
        host: host,
        name: name,
        desc: desc,
        files: files.split(",".to_string()).collect::<Vec<_>>(),
        version: version,
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a test case for previous commit<commit_after>// -*- rust -*-
// xfail-pretty

enum color {
    red,
    green,
    blue
}

fn main() {
    log(error, alt red {
        red => { 1 }
        green => { 2 }
        blue => { 3 }
    });
}

<|endoftext|>


<commit_before><commit_msg>Zigzag implementation.<commit_after>pub struct Zigzag<T> {
    x: T,
    y: T
}

impl Zigzag<i32> {
    pub fn new() -> Zigzag<i32> {
        Zigzag {
            x: 0,
            y: 0
        }
    }

    fn next_state(&mut self) {
        if self.y == 0 {
            if self.x <= 0 {
                self.y += 1;
            } else {
                self.x -= 1;
                self.y -= 1;
            }
        } else if self.x == 0 {
            if self.y <= 0 {
                self.x -= 1;
                self.y += 1;
            } else {
                self.x += 1;
                self.y -= 1;
            }
        } else if self.y < 0 {
            if self.x < 0 {
                self.y += 1;
            } else {
                self.y -= 1;
            }
            self.x -= 1;
        } else {
            if self.x < 0 {
                self.y += 1;
            } else {
                self.y -= 1;
            }
            self.x += 1;
        }
    }
}

impl Iterator for Zigzag<i32> {
    type Item = (i32, i32);
    fn next(&mut self) -> Option<(i32, i32)> {
        let result = Some((self.x, self.y));
        self.next_state();
        result
    }
}
<|endoftext|>


<commit_before><commit_msg>rename play_from_pause to resume<commit_after><|endoftext|>


<commit_before><commit_msg>Very simple tx/rx example using tokio::core::UdpSocket<commit_after>//! This is a basic example of leveraging `UdpCodec` to create a simple UDP
//! client and server which speak a custom protocol.
//!
//! Here we're using the a custom codec to convert a UDP socket to a stream of
//! client messages. These messages are then processed and returned back as a
//! new message with a new destination. Overall, we then use this to construct a
//! "ping pong" pair where two sockets are sending messages back and forth.

extern crate tokio_core;
extern crate env_logger;
extern crate futures;

use std::io;
use std::net::SocketAddr;
use std::str;

use futures::{Future, Stream, Sink};
use tokio_core::net::{UdpSocket, UdpCodec};
use tokio_core::reactor::Core;

pub struct PacketCodec;

impl UdpCodec for PacketCodec {
    type In = (SocketAddr, Vec<u8>);
    type Out = (SocketAddr, Vec<u8>);

    fn decode(&mut self, addr: &SocketAddr, buf: &[u8]) -> io::Result<Self::In> {
        Ok((*addr, buf.to_vec()))
    }

    fn encode(&mut self, (addr, buf): Self::Out, into: &mut Vec<u8>) -> SocketAddr {
        into.extend(buf);
        addr
    }
}

fn main() {
    drop(env_logger::init());

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let addr: SocketAddr = "0.0.0.0:12345".parse().unwrap();

    // Bind both our sockets and then figure out what ports we got.
    let socket = UdpSocket::bind(&addr, &handle).unwrap();

    // We're parsing each socket with the `PacketCodec` defined above, and then we
    // `split` each codec into the sink/stream halves.
    let (writer, reader) = socket.framed(PacketCodec).split();

    // Listen for new messages and then send back a modified responses
    let reader = reader.and_then(|(socket, data)| {
        let stringy = String::from_utf8(data);
        println!("socket: {:?}, data: {:?}", socket, stringy);

        Ok(())
    });

    let writer = writer.send((addr, "I am a packet sent from within.".to_string().into_bytes())).then(|_| {
        println!("Sent message");
        Ok(())
    });

    let reader = reader.for_each(|_| {
        Ok(())
    });

    handle.spawn( writer);

    core.run(reader).unwrap();

}
<|endoftext|>


<commit_before><commit_msg>Add a test for unique boxes as fn args<commit_after>fn f(i: ~int) {
    assert *i == 100;
}

fn main() {
    f(~100);
    let i = ~100;
    f(i);
}<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2383<commit_after>// https://leetcode.com/problems/minimum-hours-of-training-to-win-a-competition/
pub fn min_number_of_hours(
    initial_energy: i32,
    initial_experience: i32,
    energy: Vec<i32>,
    experience: Vec<i32>,
) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        min_number_of_hours(5, 3, vec![1, 4, 3, 2], vec![2, 6, 3, 1])
    ); // 8
    println!("{}", min_number_of_hours(2, 4, vec![1], vec![3])); // 0
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2432<commit_after>// https://leetcode.com/problems/the-employee-that-worked-on-the-longest-task/
pub fn hardest_worker(n: i32, logs: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        hardest_worker(10, vec![vec![0, 3], vec![2, 5], vec![0, 9], vec![1, 15]])
    ); // 1
    println!(
        "{}",
        hardest_worker(26, vec![vec![1, 1], vec![3, 7], vec![2, 12], vec![7, 17]])
    ); // 3
    println!("{}", hardest_worker(2, vec![vec![0, 10], vec![1, 20]])); // 0
}
<|endoftext|>


<commit_before><commit_msg>Add regression tests for #13727.<commit_after>// Copyright 2016 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.

fn test(val: u8) {
  match val {
    256 => print!("0b1110\n"),
    512 => print!("0b1111\n"),
    //~^ ERROR: unreachable pattern
    _   => print!("fail\n"),
  }
}

fn main() {
  test(1);
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #34052 - jonas-schievink:issue-32829, r=brson<commit_after>// Copyright 2016 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.

// error-pattern: calls in statics are limited

static S : u64 = { { panic!("foo"); 0 } };

fn main() {
    println!("{:?}", S);
}
<|endoftext|>


<commit_before><commit_msg>squash<commit_after><|endoftext|>


<commit_before>// xfail-pretty

// An example of the bank protocol from eholk's blog post.
//
// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/

import pipes::try_recv;

type username = ~str;
type password = ~str;
type money = float;
type amount = float;

proto! bank {
    login:send {
        login(username, password) -> login_response
    }

    login_response:recv {
        ok -> connected,
        invalid -> login
    }

    connected:send {
        deposit(money) -> connected,
        withdrawal(amount) -> withdrawal_response
    }

    withdrawal_response:recv {
        money(money) -> connected,
        insufficient_funds -> connected
    }
}

macro_rules! move_it {
    { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
}

fn switch<T: send, U>(+endp: pipes::recv_packet<T>,
                      f: fn(+option<T>) -> U) -> U {
    f(pipes::try_recv(endp))
}

fn move_it<T>(-x: T) -> T { x }

macro_rules! follow {
    {
        $($message:path($($x: ident),+) => $next:ident $e:expr)+
    } => (
        |m| match move_it(m) {
          $(some($message($($x,)* next)) {
            let $next = move_it!{next};
            $e })+
          _ { fail }
        }
    );

    {
        $($message:path => $next:ident $e:expr)+
    } => (
        |m| match move_it(m) {
            $(some($message(next)) {
                let $next = move_it!{next};
                $e })+
                _ { fail }
        }
    )
}

/*
fn client_follow(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = switch(bank, follow! {
        ok => connected { connected }
        invalid => _next { fail ~"bank closed the connected" }
    });

    /* // potential alternate syntax
    let bank = recv_alt! {
        bank => {
            | ok -> connected { connected }
            | invalid -> _next { fail }
        }
        bank2 => {
            | foo -> _n { fail }
        }
    }
    */

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    match try_recv(bank) {
      some(money(m, _)) {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) {
        fail ~"someone stole my money"
      }
      none {
        fail ~"bank closed the connection"
      }
    }
}
*/

fn bank_client(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = match try_recv(bank) {
      some(ok(connected)) => {
        move_it!{connected}
      }
      some(invalid(_)) => { fail ~"login unsuccessful" }
      none => { fail ~"bank closed the connection" }
    };

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    match try_recv(bank) {
      some(money(m, _)) => {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) => {
        fail ~"someone stole my money"
      }
      none => {
        fail ~"bank closed the connection"
      }
    }
}

fn main() {
}
<commit_msg>Nifty macros for receiving from a protocol.<commit_after>// xfail-pretty

// An example of the bank protocol from eholk's blog post.
//
// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/

import pipes::try_recv;

type username = ~str;
type password = ~str;
type money = float;
type amount = float;

proto! bank {
    login:send {
        login(username, password) -> login_response
    }

    login_response:recv {
        ok -> connected,
        invalid -> login
    }

    connected:send {
        deposit(money) -> connected,
        withdrawal(amount) -> withdrawal_response
    }

    withdrawal_response:recv {
        money(money) -> connected,
        insufficient_funds -> connected
    }
}

macro_rules! move_it {
    { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
}

fn switch<T: send, U>(+endp: pipes::recv_packet<T>,
                      f: fn(+option<T>) -> U) -> U {
    f(pipes::try_recv(endp))
}

fn move_it<T>(-x: T) -> T { x }

macro_rules! follow {
    {
        $($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+
    } => (
        |m| match move m {
          $(some($message($($($x,)+)* next)) => {
            let $next = move_it!{next};
            $e })+
          _ => { fail }
        }
    );
}

fn client_follow(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = switch(bank, follow! {
        ok -> connected { connected }
        invalid -> _next { fail ~"bank closed the connected" }
    });

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    switch(bank, follow! {
        money(m) -> _next {
            io::println(~"Yay! I got money!");
        }
        insufficient_funds -> _next {
            fail ~"someone stole my money"
        }
    });
}

fn bank_client(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = match try_recv(bank) {
      some(ok(connected)) => {
        move_it!{connected}
      }
      some(invalid(_)) => { fail ~"login unsuccessful" }
      none => { fail ~"bank closed the connection" }
    };

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    match try_recv(bank) {
      some(money(m, _)) => {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) => {
        fail ~"someone stole my money"
      }
      none => {
        fail ~"bank closed the connection"
      }
    }
}

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Add test for assoc consts.<commit_after>// Copyright 2015 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(associated_consts)]

trait Foo {
    const ID: i32;
}

impl Foo for i32 {
    const ID: i32 = 1;
}

fn main() {
    assert_eq!(1, <i32 as Foo>::ID);
}
<|endoftext|>


<commit_before><commit_msg>Use consistent log formatting.<commit_after><|endoftext|>


<commit_before>//! Tests for packages/target filter flags giving suggestions on which
//! packages/targets are available.

use cargo_test_support::project;

const EXAMPLE: u8 = 1 << 0;
const BIN: u8 = 1 << 1;
const TEST: u8 = 1 << 2;
const BENCH: u8 = 1 << 3;
const PACKAGE: u8 = 1 << 4;

fn list_availables_test(command: &str, targets: u8) {
    let full_project = project()
        .file("examples/a.rs", "fn main() { }")
        .file("examples/b.rs", "fn main() { }")
        .file("benches/bench1.rs", "")
        .file("benches/bench2.rs", "")
        .file("tests/test1.rs", "")
        .file("tests/test2.rs", "")
        .file("src/main.rs", "fn main() { }")
        .build();

    if targets & EXAMPLE != 0 {
        full_project
            .cargo(&format!("{} --example", command))
            .with_stderr(
                "\
error: \"--example\" takes one argument.
Available examples:
    a
    b

",
            )
            .with_status(101)
            .run();
    }

    if targets & BIN != 0 {
        full_project
            .cargo(&format!("{} --bin", command))
            .with_stderr(
                "\
error: \"--bin\" takes one argument.
Available binaries:
    foo

",
            )
            .with_status(101)
            .run();
    }

    if targets & BENCH != 0 {
        full_project
            .cargo(&format!("{} --bench", command))
            .with_stderr(
                "\
error: \"--bench\" takes one argument.
Available benches:
    bench1
    bench2

",
            )
            .with_status(101)
            .run();
    }

    if targets & TEST != 0 {
        full_project
            .cargo(&format!("{} --test", command))
            .with_stderr(
                "\
error: \"--test\" takes one argument.
Available tests:
    test1
    test2

",
            )
            .with_status(101)
            .run();
    }

    if targets & PACKAGE != 0 {
        full_project
            .cargo(&format!("{} -p", command))
            .with_stderr(
                "\
[ERROR] \"--package <SPEC>\" requires a SPEC format value, \
which can be any package ID specifier in the dependency graph.
Run `cargo help pkgid` for more information about SPEC format.

Possible packages/workspace members:
    foo

",
            )
            .with_status(101)
            .run();
    }

    let empty_project = project().file("src/lib.rs", "").build();

    if targets & EXAMPLE != 0 {
        empty_project
            .cargo(&format!("{} --example", command))
            .with_stderr(
                "\
error: \"--example\" takes one argument.
No examples available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & BIN != 0 {
        empty_project
            .cargo(&format!("{} --bin", command))
            .with_stderr(
                "\
error: \"--bin\" takes one argument.
No binaries available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & BENCH != 0 {
        empty_project
            .cargo(&format!("{} --bench", command))
            .with_stderr(
                "\
error: \"--bench\" takes one argument.
No benches available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & TEST != 0 {
        empty_project
            .cargo(&format!("{} --test", command))
            .with_stderr(
                "\
error: \"--test\" takes one argument.
No tests available.

",
            )
            .with_status(101)
            .run();
    }
}

#[cargo_test]
fn build_list_availables() {
    list_availables_test("build", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn check_list_availables() {
    list_availables_test("check", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn doc_list_availables() {
    list_availables_test("doc", BIN | PACKAGE);
}

#[cargo_test]
fn fix_list_availables() {
    list_availables_test("fix", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn run_list_availables() {
    list_availables_test("run", EXAMPLE | BIN);
}

#[cargo_test]
fn test_list_availables() {
    list_availables_test("test", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn bench_list_availables() {
    list_availables_test("bench", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn install_list_availables() {
    list_availables_test("install", EXAMPLE | BIN);
}

#[cargo_test]
fn rustdoc_list_availables() {
    list_availables_test("rustdoc", EXAMPLE | BIN | TEST | BENCH);
}

#[cargo_test]
fn rustc_list_availables() {
    list_availables_test("rustc", EXAMPLE | BIN | TEST | BENCH);
}
<commit_msg>test: list availables for rustc,rustdoc,run,pkgid<commit_after>//! Tests for packages/target filter flags giving suggestions on which
//! packages/targets are available.

use cargo_test_support::project;

const EXAMPLE: u8 = 1 << 0;
const BIN: u8 = 1 << 1;
const TEST: u8 = 1 << 2;
const BENCH: u8 = 1 << 3;
const PACKAGE: u8 = 1 << 4;

fn list_availables_test(command: &str, targets: u8) {
    let full_project = project()
        .file("examples/a.rs", "fn main() { }")
        .file("examples/b.rs", "fn main() { }")
        .file("benches/bench1.rs", "")
        .file("benches/bench2.rs", "")
        .file("tests/test1.rs", "")
        .file("tests/test2.rs", "")
        .file("src/main.rs", "fn main() { }")
        .file("Cargo.lock", "") // for `cargo pkgid`
        .build();

    if targets & EXAMPLE != 0 {
        full_project
            .cargo(&format!("{} --example", command))
            .with_stderr(
                "\
error: \"--example\" takes one argument.
Available examples:
    a
    b

",
            )
            .with_status(101)
            .run();
    }

    if targets & BIN != 0 {
        full_project
            .cargo(&format!("{} --bin", command))
            .with_stderr(
                "\
error: \"--bin\" takes one argument.
Available binaries:
    foo

",
            )
            .with_status(101)
            .run();
    }

    if targets & BENCH != 0 {
        full_project
            .cargo(&format!("{} --bench", command))
            .with_stderr(
                "\
error: \"--bench\" takes one argument.
Available benches:
    bench1
    bench2

",
            )
            .with_status(101)
            .run();
    }

    if targets & TEST != 0 {
        full_project
            .cargo(&format!("{} --test", command))
            .with_stderr(
                "\
error: \"--test\" takes one argument.
Available tests:
    test1
    test2

",
            )
            .with_status(101)
            .run();
    }

    if targets & PACKAGE != 0 {
        full_project
            .cargo(&format!("{} -p", command))
            .with_stderr(
                "\
[ERROR] \"--package <SPEC>\" requires a SPEC format value, \
which can be any package ID specifier in the dependency graph.
Run `cargo help pkgid` for more information about SPEC format.

Possible packages/workspace members:
    foo

",
            )
            .with_status(101)
            .run();
    }

    let empty_project = project().file("src/lib.rs", "").build();

    if targets & EXAMPLE != 0 {
        empty_project
            .cargo(&format!("{} --example", command))
            .with_stderr(
                "\
error: \"--example\" takes one argument.
No examples available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & BIN != 0 {
        empty_project
            .cargo(&format!("{} --bin", command))
            .with_stderr(
                "\
error: \"--bin\" takes one argument.
No binaries available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & BENCH != 0 {
        empty_project
            .cargo(&format!("{} --bench", command))
            .with_stderr(
                "\
error: \"--bench\" takes one argument.
No benches available.

",
            )
            .with_status(101)
            .run();
    }

    if targets & TEST != 0 {
        empty_project
            .cargo(&format!("{} --test", command))
            .with_stderr(
                "\
error: \"--test\" takes one argument.
No tests available.

",
            )
            .with_status(101)
            .run();
    }
}

#[cargo_test]
fn build_list_availables() {
    list_availables_test("build", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn check_list_availables() {
    list_availables_test("check", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn doc_list_availables() {
    list_availables_test("doc", BIN | PACKAGE);
}

#[cargo_test]
fn fix_list_availables() {
    list_availables_test("fix", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn run_list_availables() {
    list_availables_test("run", EXAMPLE | BIN | PACKAGE);
}

#[cargo_test]
fn test_list_availables() {
    list_availables_test("test", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn bench_list_availables() {
    list_availables_test("bench", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn install_list_availables() {
    list_availables_test("install", EXAMPLE | BIN);
}

#[cargo_test]
fn rustdoc_list_availables() {
    list_availables_test("rustdoc", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn rustc_list_availables() {
    list_availables_test("rustc", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
}

#[cargo_test]
fn pkgid_list_availables() {
    list_availables_test("pkgid", PACKAGE);
}
<|endoftext|>


<commit_before><commit_msg>chore(tests): cleanup util::parse_port<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for 39bb1254d.<commit_after>// This test is intended to guard against the problem described in commit
// 39bb1254d1eaf74f45a4e741097e33fc942168d5.
//
// As written, it might be considered UB in compiled Rust, but of course Miri gives it a safe,
// deterministic behaviour (one that might not correspond with how an eventual Rust spec would
// defined this).
//
// An alternative way to write the test without `unsafe` would be to use `Cell<i32>`, but it would
// only surface the bug described by the above commit if `Cell<i32>` on the stack got represented
// as a primitive `PrimVal::I32` which is not yet the case.

fn main() {
    let mut x = 0;
    let y: *const i32 = &x;
    x = 1;

    // When the described bug is in place, this results in `0`, not observing the `x = 1` line.
    assert_eq!(unsafe { *y }, 1);

    assert_eq!(x, 1);
}
<|endoftext|>


<commit_before><commit_msg>Add append example<commit_after>// Hound -- A wav encoding and decoding library in Rust
// Copyright 2018 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This example appends one second of a 440 Hz sine wave to the file "sine.wav".
// If the file does not exist, it is created instead.

use std::f32::consts::PI;
use std::i16;
use std::path::Path;

extern crate hound;

fn main() {
    let spec = hound::WavSpec {
        channels: 1,
        sample_rate: 44100,
        bits_per_sample: 16,
        sample_format: hound::SampleFormat::Int,
    };

    let path: &Path = "sine.wav".as_ref();

    let mut writer = match path.is_file() {
        true => hound::WavWriter::append(path).unwrap(),
        false => hound::WavWriter::create(path, spec).unwrap(),
    };

    // We should not append blindly, we should make sure that the existing file
    // has the right spec, because that is what we assume when writing.
    assert_eq!(spec, writer.spec());

    for t in (0 .. 44100).map(|x| x as f32 / 44100.0) {
        let sample = (t * 440.0 * 2.0 * PI).sin();
        let amplitude = i16::MAX as f32;
        writer.write_sample((sample * amplitude) as i16).unwrap();
    }

    writer.finalize().unwrap();
}
<|endoftext|>


<commit_before>#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate glutin;

use glutin::{Event, ElementState, MouseCursor};

mod support;

#[cfg(target_os = "android")]
android_start!(main);

fn main() {
    let window = glutin::WindowBuilder::new().build().unwrap();
    window.set_title("A fantastic window!");
    unsafe { window.make_current() };

    let context = support::load(&window);
    let cursors = [MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand, MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text, MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress, MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::NoneCursor, MouseCursor::Cell, MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy, MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing, MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut, MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize, MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize, MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize, MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize, MouseCursor::ColResize, MouseCursor::RowResize];
    let mut cursor_idx = 0;

    for event in window.wait_events() {
        match event {
            Event::KeyboardInput(ElementState::Pressed, _, _) => {
                println!("Setting cursor to \"{:?}\"", cursors[cursor_idx]);
                window.set_cursor(cursors[cursor_idx]);
                if cursor_idx < cursors.len() - 1 {
                    cursor_idx += 1;
                } else {
                    cursor_idx = 0;
                }
            },
            Event::Closed => break,
            _ => (),
        }

        context.draw_frame((0.0, 1.0, 0.0, 1.0));
        window.swap_buffers();
    }
}
<commit_msg>unwrap to fix unused result warning<commit_after>#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate glutin;

use glutin::{Event, ElementState, MouseCursor};

mod support;

#[cfg(target_os = "android")]
android_start!(main);

fn main() {
    let window = glutin::WindowBuilder::new().build().unwrap();
    window.set_title("A fantastic window!");
    unsafe { window.make_current().unwrap() };

    let context = support::load(&window);
    let cursors = [MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand, MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text, MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress, MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::NoneCursor, MouseCursor::Cell, MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy, MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing, MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut, MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize, MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize, MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize, MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize, MouseCursor::ColResize, MouseCursor::RowResize];
    let mut cursor_idx = 0;

    for event in window.wait_events() {
        match event {
            Event::KeyboardInput(ElementState::Pressed, _, _) => {
                println!("Setting cursor to \"{:?}\"", cursors[cursor_idx]);
                window.set_cursor(cursors[cursor_idx]);
                if cursor_idx < cursors.len() - 1 {
                    cursor_idx += 1;
                } else {
                    cursor_idx = 0;
                }
            },
            Event::Closed => break,
            _ => (),
        }

        context.draw_frame((0.0, 1.0, 0.0, 1.0));
        window.swap_buffers().unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Added encoding example<commit_after>extern crate rustc_serialize;
extern crate ron;

#[allow(dead_code)]
#[derive(RustcEncodable)]
enum Foo<'a> {
    Var1(u8),
    Var2([&'a str; 2]),
}

#[derive(RustcEncodable)]
struct Bar<'a> {
    q: Option<(f32, bool)>,
    w: Foo<'a>,
}

fn main() {
    let bar = Bar {
        q: Some((0.4, true)),
        w: Foo::Var2(["a", "b"])
    };
    let s = ron::encode(&bar, true).unwrap();
    println!("{}", s);
}
<|endoftext|>


<commit_before>#[deriving(Show, PartialEq, Eq)]
pub struct Token(pub uint);

impl Token {
    #[inline]
    pub fn as_uint(self) -> uint {
        let Token(inner) = self;
        inner
    }
}

// Work around for https://github.com/rust-lang/rust/issues/17169
pub static TOKEN_0:Token = Token(0);
pub static TOKEN_1:Token = Token(1);
<commit_msg>Make Tokens hashable<commit_after>#[deriving(Show, PartialEq, Eq, Hash)]
pub struct Token(pub uint);

impl Token {
    #[inline]
    pub fn as_uint(self) -> uint {
        let Token(inner) = self;
        inner
    }
}

// Work around for https://github.com/rust-lang/rust/issues/17169
pub static TOKEN_0:Token = Token(0);
pub static TOKEN_1:Token = Token(1);
<|endoftext|>


<commit_before><commit_msg>SSSSSStringssssssss<commit_after><|endoftext|>