<commit_before>use syntax::ast::punc::*;
use syntax::ast::token::*;
use std::io::{BufReader, BufferedReader, Buffer, IoError, IoResult, EndOfFile};
use std::char::from_u32;
use std::num::from_str_radix;
use std::from_str::FromStr;
/// A Javascript lexer
pub struct Lexer<B> {
    /// The list of tokens generated so far
    pub tokens : Vec<Token>,
    /// The current line number in the script
    line_number : uint,
    /// The current column number in the script
    column_number : uint,
    /// The reader
    buffer: B,
    /// The peeked character buffer
    peek_buffer: String
}
impl<B:Buffer> Lexer<B> {
    /// Creates a new lexer with empty buffers
    pub fn new(buffer: B) -> Lexer<B> {
        Lexer {
            tokens: Vec::new(),
            line_number: 1,
            column_number: 0,
            buffer: buffer,
            peek_buffer: String::new()
        }
    }
    #[inline(always)]
    fn push_token(&mut self, tk:TokenData) {
        self.tokens.push(Token::new(tk, self.line_number, self.column_number))
    }
    #[inline(always)]
    fn push_punc(&mut self, punc:Punctuator) {
        self.push_token(TPunctuator(punc));
    }
    /// Processes an input stream from a string into an array of tokens
    pub fn lex_str(script:&str) -> Vec<Token> {
        let script_bytes:&[u8] = script.as_bytes();
        let reader = BufReader::new(script_bytes);
        let buf_reader = BufferedReader::new(reader);
        let mut lexer = Lexer::new(buf_reader);
        lexer.lex().unwrap();
        lexer.tokens
    }
    fn next(&mut self) -> IoResult<char> {
        if self.peek_buffer.len() == 0 {
            self.buffer.read_char()
        } else {
            Ok(match self.peek_buffer.pop_char() {
                Some(v) => v,
                None => unreachable!()
            })
        }
    }
    fn next_is(&mut self, peek:char) -> bool {
        if self.peek_buffer.len() > 0 {
            let matched = self.peek_buffer.as_slice().char_at(self.peek_buffer.len() - 1) == peek;
            if matched {
                self.peek_buffer.pop_char();
            }
            matched
        } else {
            match self.buffer.read_char() {
                Ok(ch) if ch == peek => {
                    self.column_number += 1;
                    true
                },
                Ok(ch) if ch != peek => {
                    self.peek_buffer.push_char(ch);
                    false
                },
                _ => false
            }
        }
    }
    /// Processes an input stream from the `buffer` into a vector of tokens
    pub fn lex(&mut self) -> IoResult<()> {
        loop {
            let ch = match self.next() {
                Ok(ch) => ch,
                Err(IoError {kind: EndOfFile, ..}) => break,
                Err(err) => return Err(err)
            };
            self.column_number += 1;
            match ch {
                '"' | '\'' => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\'' if ch == '\'' => {
                                break;
                            },
                            '"' if ch == '"' => {
                                break;
                            },
                            '\\' => {
                                let escape = try!(self.next());
                                if escape != '\n' {
                                    let escaped_ch = match escape {
                                        'n' => '\n',
                                        'r' => '\r',
                                        't' => '\t',
                                        'b' => '\x08',
                                        'f' => '\x0c',
                                        '0' => '\0',
                                        'x' => {
                                            let mut nums = String::with_capacity(2);
                                            for _ in range(0u, 2u) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 2;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        'u' => {
                                            let mut nums = String::new();
                                            for _ in range(0, 4) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 4;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        '\'' | '"' => escape,
                                        _ => fail!("{}:{}: Invalid escape `{}`", self.line_number, self.column_number, ch)
                                    };
                                    buf.push_char(escaped_ch);
                                }
                            },
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TStringLiteral(buf))
                },
                '0' if self.next_is('x') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            ch if ch.is_digit_radix(16) => buf.push_char(ch),
                            ch => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str_radix(buf.as_slice(), 16).unwrap()));
                },
                '0' => {
                    let mut buf = "0".into_string();
                    let mut gone_decimal = false;
                    loop {
                        let ch = self.next();
                        match ch {
                            Ok(ch) if ch.is_digit_radix(8) =>
                                buf.push_char(ch),
                            Ok('8') | Ok('9') | Ok('.') => {
                                gone_decimal = true;
                                buf.push_char(ch.unwrap());
                            },
                            Ok(ch) => {
                                self.peek_buffer.push_char(ch);
                                break;
                            },
                            Err(IoError {kind: EndOfFile, ..}) =>
                                break,
                            Err(err) =>
                                return Err(err)
                        }
                    }
                    self.push_token(TNumericLiteral(if gone_decimal {
                        from_str(buf.as_slice())
                    } else {
                        from_str_radix(buf.as_slice(), 8)
                    }.unwrap()));
                },
                _ if ch.is_digit() => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            '.' => buf.push_char(ch),
                            _ if ch.is_digit() => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str(buf.as_slice()).unwrap()));
                },
                _ if ch.is_alphabetic() || ch == '$' || ch == '_' => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            _ if ch.is_alphabetic() || ch.is_digit() || ch == '_' => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(match buf.as_slice() {
                        "true" => TBooleanLiteral(true),
                        "false" => TBooleanLiteral(false),
                        "null" => TNullLiteral,
                        slice => match FromStr::from_str(slice) {
                            Some(keyword) => TKeyword(keyword),
                            None => TIdentifier(buf.clone())
                        }
                    });
                },
                ';' => self.push_punc(PSemicolon),
                ':' => self.push_punc(PColon),
                '.' => self.push_punc(PDot),
                '(' => self.push_punc(POpenParen),
                ')' => self.push_punc(PCloseParen),
                ',' => self.push_punc(PComma),
                '{' => self.push_punc(POpenBlock),
                '}' => self.push_punc(PCloseBlock),
                '[' => self.push_punc(POpenBracket),
                ']' => self.push_punc(PCloseBracket),
                '?' => self.push_punc(PQuestion),
                '/' if self.next_is('/') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('*') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            '*' if self.next_is('/') => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('=') =>
                    self.push_punc(PAssignDiv),
                '/' => self.push_punc(PDiv),
                '*' if self.next_is('=') =>
                    self.push_punc(PAssignMul),
                '*' => self.push_punc(PMul),
                '+' if self.next_is('=') =>
                    self.push_punc(PAssignAdd),
                '+' if self.next_is('+') =>
                    self.push_punc(PInc),
                '+' => self.push_punc(PAdd),
                '-' if self.next_is('=') =>
                    self.push_punc(PAssignSub),
                '-' if self.next_is('-') =>
                    self.push_punc(PDec),
                '-' => self.push_punc(PSub),
                '%' if self.next_is('=') =>
                    self.push_punc(PAssignMod),
                '%' => self.push_punc(PMod),
                '|' if self.next_is('|') =>
                    self.push_punc(PBoolOr),
                '|' if self.next_is('=') =>
                    self.push_punc(PAssignOr),
                '|' => self.push_punc(POr),
                '&' if self.next_is('&') =>
                    self.push_punc(PBoolAnd),
                '&' if self.next_is('=') =>
                    self.push_punc(PAssignAnd),
                '&' => self.push_punc(PAnd),
                '^' if self.next_is('=') =>
                    self.push_punc(PAssignXor),
                '^' => self.push_punc(PXor),
                '=' if self.next_is('>') =>
                    self.push_punc(PArrow),
                '=' if self.next_is('=') => {
                    let punc = if self.next_is('=') {
                        PStrictEq
                    } else {
                        PEq
                    };
                    self.push_punc(punc)
                },
                '=' => self.push_punc(PAssign),
                '<' if self.next_is('=') =>
                    self.push_punc(PLessThanOrEq),
                '<' if self.next_is('<') => {
                    let punc = if self.next_is('=') {
                        PAssignLeftSh
                    } else {
                        PLeftSh
                    };
                    self.push_punc(punc)
                },
                '<' => self.push_punc(PLessThan),
                '>' if self.next_is('=') =>
                    self.push_punc(PGreaterThanOrEq),
                '>' if self.next_is('>') => {
                    let punc = if self.next_is('=') {
                        PAssignRightSh
                    } else if self.next_is('>') {
                        if self.next_is('=') {
                            PAssignURightSh
                        } else {
                            PURightSh
                        }
                    } else {
                        PRightSh
                    };
                    self.push_punc(punc)
                },
                '>' => self.push_punc(PGreaterThan),
                '!' if self.next_is('=') => {
                    let punc = if self.next_is('=') {
                        PStrictNotEq
                    } else {
                        PNotEq
                    };
                    self.push_punc(punc)
                },
                '!' => self.push_punc(PNot),
                '~' => self.push_punc(PNeg),
                '\n' | '\u2028'|'\u2029' => {
                    self.line_number += 1;
                    self.column_number = 0;
                },
                '\r' => {
                    self.column_number = 0;
                },
                ' ' => (),
                ch => fail!("{}:{}: Unexpected '{}'", self.line_number, self.column_number, ch)
            };
        };
        Ok(())
    }
}<commit_msg>Use explicit types in another `range` in Lexer<commit_after>use syntax::ast::punc::*;
use syntax::ast::token::*;
use std::io::{BufReader, BufferedReader, Buffer, IoError, IoResult, EndOfFile};
use std::char::from_u32;
use std::num::from_str_radix;
use std::from_str::FromStr;
/// A Javascript lexer
pub struct Lexer<B> {
    /// The list of tokens generated so far
    pub tokens : Vec<Token>,
    /// The current line number in the script
    line_number : uint,
    /// The current column number in the script
    column_number : uint,
    /// The reader
    buffer: B,
    /// The peeked character buffer
    peek_buffer: String
}
impl<B:Buffer> Lexer<B> {
    /// Creates a new lexer with empty buffers
    pub fn new(buffer: B) -> Lexer<B> {
        Lexer {
            tokens: Vec::new(),
            line_number: 1,
            column_number: 0,
            buffer: buffer,
            peek_buffer: String::new()
        }
    }
    #[inline(always)]
    fn push_token(&mut self, tk:TokenData) {
        self.tokens.push(Token::new(tk, self.line_number, self.column_number))
    }
    #[inline(always)]
    fn push_punc(&mut self, punc:Punctuator) {
        self.push_token(TPunctuator(punc));
    }
    /// Processes an input stream from a string into an array of tokens
    pub fn lex_str(script:&str) -> Vec<Token> {
        let script_bytes:&[u8] = script.as_bytes();
        let reader = BufReader::new(script_bytes);
        let buf_reader = BufferedReader::new(reader);
        let mut lexer = Lexer::new(buf_reader);
        lexer.lex().unwrap();
        lexer.tokens
    }
    fn next(&mut self) -> IoResult<char> {
        if self.peek_buffer.len() == 0 {
            self.buffer.read_char()
        } else {
            Ok(match self.peek_buffer.pop_char() {
                Some(v) => v,
                None => unreachable!()
            })
        }
    }
    fn next_is(&mut self, peek:char) -> bool {
        if self.peek_buffer.len() > 0 {
            let matched = self.peek_buffer.as_slice().char_at(self.peek_buffer.len() - 1) == peek;
            if matched {
                self.peek_buffer.pop_char();
            }
            matched
        } else {
            match self.buffer.read_char() {
                Ok(ch) if ch == peek => {
                    self.column_number += 1;
                    true
                },
                Ok(ch) if ch != peek => {
                    self.peek_buffer.push_char(ch);
                    false
                },
                _ => false
            }
        }
    }
    /// Processes an input stream from the `buffer` into a vector of tokens
    pub fn lex(&mut self) -> IoResult<()> {
        loop {
            let ch = match self.next() {
                Ok(ch) => ch,
                Err(IoError {kind: EndOfFile, ..}) => break,
                Err(err) => return Err(err)
            };
            self.column_number += 1;
            match ch {
                '"' | '\'' => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\'' if ch == '\'' => {
                                break;
                            },
                            '"' if ch == '"' => {
                                break;
                            },
                            '\\' => {
                                let escape = try!(self.next());
                                if escape != '\n' {
                                    let escaped_ch = match escape {
                                        'n' => '\n',
                                        'r' => '\r',
                                        't' => '\t',
                                        'b' => '\x08',
                                        'f' => '\x0c',
                                        '0' => '\0',
                                        'x' => {
                                            let mut nums = String::with_capacity(2);
                                            for _ in range(0u, 2u) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 2;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        'u' => {
                                            let mut nums = String::new();
                                            for _ in range(0u, 4u) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 4;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        '\'' | '"' => escape,
                                        _ => fail!("{}:{}: Invalid escape `{}`", self.line_number, self.column_number, ch)
                                    };
                                    buf.push_char(escaped_ch);
                                }
                            },
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TStringLiteral(buf))
                },
                '0' if self.next_is('x') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            ch if ch.is_digit_radix(16) => buf.push_char(ch),
                            ch => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str_radix(buf.as_slice(), 16).unwrap()));
                },
                '0' => {
                    let mut buf = "0".into_string();
                    let mut gone_decimal = false;
                    loop {
                        let ch = self.next();
                        match ch {
                            Ok(ch) if ch.is_digit_radix(8) =>
                                buf.push_char(ch),
                            Ok('8') | Ok('9') | Ok('.') => {
                                gone_decimal = true;
                                buf.push_char(ch.unwrap());
                            },
                            Ok(ch) => {
                                self.peek_buffer.push_char(ch);
                                break;
                            },
                            Err(IoError {kind: EndOfFile, ..}) =>
                                break,
                            Err(err) =>
                                return Err(err)
                        }
                    }
                    self.push_token(TNumericLiteral(if gone_decimal {
                        from_str(buf.as_slice())
                    } else {
                        from_str_radix(buf.as_slice(), 8)
                    }.unwrap()));
                },
                _ if ch.is_digit() => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            '.' => buf.push_char(ch),
                            _ if ch.is_digit() => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str(buf.as_slice()).unwrap()));
                },
                _ if ch.is_alphabetic() || ch == '$' || ch == '_' => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            _ if ch.is_alphabetic() || ch.is_digit() || ch == '_' => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(match buf.as_slice() {
                        "true" => TBooleanLiteral(true),
                        "false" => TBooleanLiteral(false),
                        "null" => TNullLiteral,
                        slice => match FromStr::from_str(slice) {
                            Some(keyword) => TKeyword(keyword),
                            None => TIdentifier(buf.clone())
                        }
                    });
                },
                ';' => self.push_punc(PSemicolon),
                ':' => self.push_punc(PColon),
                '.' => self.push_punc(PDot),
                '(' => self.push_punc(POpenParen),
                ')' => self.push_punc(PCloseParen),
                ',' => self.push_punc(PComma),
                '{' => self.push_punc(POpenBlock),
                '}' => self.push_punc(PCloseBlock),
                '[' => self.push_punc(POpenBracket),
                ']' => self.push_punc(PCloseBracket),
                '?' => self.push_punc(PQuestion),
                '/' if self.next_is('/') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('*') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            '*' if self.next_is('/') => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('=') =>
                    self.push_punc(PAssignDiv),
                '/' => self.push_punc(PDiv),
                '*' if self.next_is('=') =>
                    self.push_punc(PAssignMul),
                '*' => self.push_punc(PMul),
                '+' if self.next_is('=') =>
                    self.push_punc(PAssignAdd),
                '+' if self.next_is('+') =>
                    self.push_punc(PInc),
                '+' => self.push_punc(PAdd),
                '-' if self.next_is('=') =>
                    self.push_punc(PAssignSub),
                '-' if self.next_is('-') =>
                    self.push_punc(PDec),
                '-' => self.push_punc(PSub),
                '%' if self.next_is('=') =>
                    self.push_punc(PAssignMod),
                '%' => self.push_punc(PMod),
                '|' if self.next_is('|') =>
                    self.push_punc(PBoolOr),
                '|' if self.next_is('=') =>
                    self.push_punc(PAssignOr),
                '|' => self.push_punc(POr),
                '&' if self.next_is('&') =>
                    self.push_punc(PBoolAnd),
                '&' if self.next_is('=') =>
                    self.push_punc(PAssignAnd),
                '&' => self.push_punc(PAnd),
                '^' if self.next_is('=') =>
                    self.push_punc(PAssignXor),
                '^' => self.push_punc(PXor),
                '=' if self.next_is('>') =>
                    self.push_punc(PArrow),
                '=' if self.next_is('=') => {
                    let punc = if self.next_is('=') {
                        PStrictEq
                    } else {
                        PEq
                    };
                    self.push_punc(punc)
                },
                '=' => self.push_punc(PAssign),
                '<' if self.next_is('=') =>
                    self.push_punc(PLessThanOrEq),
                '<' if self.next_is('<') => {
                    let punc = if self.next_is('=') {
                        PAssignLeftSh
                    } else {
                        PLeftSh
                    };
                    self.push_punc(punc)
                },
                '<' => self.push_punc(PLessThan),
                '>' if self.next_is('=') =>
                    self.push_punc(PGreaterThanOrEq),
                '>' if self.next_is('>') => {
                    let punc = if self.next_is('=') {
                        PAssignRightSh
                    } else if self.next_is('>') {
                        if self.next_is('=') {
                            PAssignURightSh
                        } else {
                            PURightSh
                        }
                    } else {
                        PRightSh
                    };
                    self.push_punc(punc)
                },
                '>' => self.push_punc(PGreaterThan),
                '!' if self.next_is('=') => {
                    let punc = if self.next_is('=') {
                        PStrictNotEq
                    } else {
                        PNotEq
                    };
                    self.push_punc(punc)
                },
                '!' => self.push_punc(PNot),
                '~' => self.push_punc(PNeg),
                '\n' | '\u2028'|'\u2029' => {
                    self.line_number += 1;
                    self.column_number = 0;
                },
                '\r' => {
                    self.column_number = 0;
                },
                ' ' => (),
                ch => fail!("{}:{}: Unexpected '{}'", self.line_number, self.column_number, ch)
            };
        };
        Ok(())
    }
}<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
use num::complex::{
    Complex32,
    Complex64,
};
use libc::c_int;
use ll::*;
use matrix::{
    Matrix,
    BandMatrix,
    SymmetricMatrix,
    TridiagonalMatrix,
};
use scalar::Scalar;
use types::Symmetry;

pub trait Gesv {
    fn gesv(a: &mut Matrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Gbsv {
    fn gbsv(a: &mut BandMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Gtsv {
    fn gtsv(a: &mut TridiagonalMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Posv {
    fn posv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Ppsv {
    fn ppsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Pbsv<M>: Sized where M: SymmetricMatrix<Self> + BandMatrix<Self> {
    fn pbsv(a: &mut M, b: &mut Matrix<Self>);
}

pub trait Ptsv<M>: Sized where M: TridiagonalMatrix<Self> + SymmetricMatrix<Self> {
    fn ptsv(a: &mut M, b: &mut Matrix<Self>);
}

pub trait Sysv {
    fn sysv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Hesv {
    fn hesv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Spsv {
    fn spsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Hpsv {
    fn hpsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

macro_rules! lin_eq_impl(($($t: ident), +) => ($(
    impl Gesv for $t {
        fn gesv(a: &mut Matrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, gesv_)(a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Gbsv for $t {
        fn gbsv(a: &mut BandMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, gbsv_)(a.cols().as_mut(),
                    a.sub_diagonals().as_mut(), a.sup_diagonals().as_mut(),
                    b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Gtsv for $t {
        fn gtsv(a: &mut TridiagonalMatrix<Self>, b: &mut Matrix<Self>) {
            unsafe {
                let mut info: c_int = 0;

                let (sup, diag, sub) = a.as_mut_ptrs();

                prefix!($t, gtsv_)(a.cols().as_mut(), b.cols().as_mut(),
                    sup, diag, sub,
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Posv for $t {
        fn posv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, posv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Ppsv for $t {
        fn ppsv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, ppsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl<M> Pbsv<M> for $t where M: SymmetricMatrix<$t> + BandMatrix<$t> {
        fn pbsv(a: &mut M, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                let diag = match a.symmetry() {
                    Symmetry::Upper => a.sup_diagonals(),
                    Symmetry::Lower => a.sub_diagonals(),
                };

                prefix!($t, pbsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), diag.as_mut(),
                    b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Sysv for $t {
        fn sysv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                let n = a.cols() as usize;
                let mut work: Vec<$t> = Vec::with_capacity(n);

                prefix!($t, sysv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    (&mut work[..]).as_mut_ptr(), a.cols().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Spsv for $t {
        fn spsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, spsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }
)+));

macro_rules! complex_lin_eq_impl(($($t: ident), +) => ($(
    impl Hesv for $t {
        fn hesv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                let n = a.cols() as usize;
                let mut work: Vec<$t> = Vec::with_capacity(n);

                prefix!($t, hesv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    (&mut work[..]).as_mut_ptr(), a.cols().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Hpsv for $t {
        fn hpsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, hpsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }
)+));

lin_eq_impl!(f32, f64, Complex32, Complex64);
complex_lin_eq_impl!(Complex32, Complex64);

#[cfg(test)]
mod gesv_tests {

    use linear_equations::Gesv;

    #[test]
    fn real() {
        let mut a = (2i32, 2i32, vec![1.0f64, 4.0, 1.0, 2.0]);
        let mut b = (2i32, 1i32, vec![-2.0f64, 2.0]);
        let mut p = (2i32, 2i32, vec![0i32, 0]);

        Gesv::gesv(&mut a, &mut b, &mut p);

        let (_, _, x) = b;
        assert_eq!(x, vec![3.0f64, -5.0]);
    }
}
<commit_msg>Add work function to gesv<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
use std::cmp;
use num::complex::{
    Complex32,
    Complex64,
};
use libc::c_int;
use error::Error;
use ll::*;
use matrix::{
    Matrix,
    BandMatrix,
    SymmetricMatrix,
    TridiagonalMatrix,
};
use scalar::Scalar;
use types::{Symmetry, Layout};
use util::transpose_data;

pub trait Gesv {
    fn gesv(a: &mut Matrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
    fn gesv_work(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>)
        -> Result<Vec<usize>, Error>;
}

pub trait Gbsv {
    fn gbsv(a: &mut BandMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Gtsv {
    fn gtsv(a: &mut TridiagonalMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Posv {
    fn posv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Ppsv {
    fn ppsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>);
}

pub trait Pbsv<M>: Sized where M: SymmetricMatrix<Self> + BandMatrix<Self> {
    fn pbsv(a: &mut M, b: &mut Matrix<Self>);
}

pub trait Ptsv<M>: Sized where M: TridiagonalMatrix<Self> + SymmetricMatrix<Self> {
    fn ptsv(a: &mut M, b: &mut Matrix<Self>);
}

pub trait Sysv {
    fn sysv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Hesv {
    fn hesv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Spsv {
    fn spsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

pub trait Hpsv {
    fn hpsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>);
}

macro_rules! lin_eq_impl(($($t: ident), +) => ($(
    impl Gesv for $t {
        fn gesv(a: &mut Matrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, gesv_)(a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }

        fn gesv_work(layout: Layout, a: &mut Matrix<$t>, b: &mut Matrix<$t>) -> Result<Vec<usize>, Error> {
            let mut info: c_int = 0;

            let n = a.rows();
            if n != a.cols() {
                return Err(Error::DimensionMismatch);
            }

            let nrhs = b.cols();
            let mut pivot_indices: Vec<usize> = Vec::with_capacity(n as usize);
            unsafe { pivot_indices.set_len(n as usize); }

            match layout {
                Layout::ColMajor => unsafe {
                    let lda = n;
                    let ldb = b.rows();

                    prefix!($t, gesv_)(
                        n.as_mut(), nrhs.as_mut(),
                        a.as_mut_ptr(), lda.as_mut(),
                        pivot_indices.as_mut_ptr() as *mut c_int,
                        b.as_mut_ptr(), ldb.as_mut(),
                        &mut info as *mut c_int);
                },
                Layout::RowMajor => {
                    let lda = n;
                    let ldb = nrhs;
                    let lda_t = cmp::max(1, n);
                    let ldb_t = cmp::max(1, n);

                    let a_t_len = (lda_t * cmp::max(1, n)) as usize;
                    let b_t_len = (ldb_t * cmp::max(1, nrhs)) as usize;
                    let mut a_t = Vec::with_capacity(a_t_len);
                    let mut b_t = Vec::with_capacity(b_t_len);

                    unsafe {
                        a_t.set_len(a_t_len);
                        b_t.set_len(b_t_len);

                        transpose_data(Layout::RowMajor, n as isize, n as isize, a.as_ptr(), lda as isize, a_t.as_mut_ptr(), lda_t as isize);
                        transpose_data(Layout::RowMajor, n as isize, nrhs as isize, b.as_ptr(), ldb as isize, b_t.as_mut_ptr(), ldb_t as isize);

                        prefix!($t, gesv_)(
                            n.as_mut(), nrhs.as_mut(),
                            a_t.as_mut_ptr(), lda_t.as_mut(),
                            pivot_indices.as_mut_ptr() as *mut c_int,
                            b_t.as_mut_ptr(), ldb_t.as_mut(),
                            &mut info as *mut c_int);

                        transpose_data(Layout::ColMajor, n as isize, n as isize, a_t.as_ptr(), lda_t as isize, a.as_mut_ptr(), lda as isize);
                        transpose_data(Layout::ColMajor, n as isize, nrhs as isize, b_t.as_ptr(), ldb_t as isize, b.as_mut_ptr(), ldb as isize);
                    }
                }
            }

            match info {
                0 => Ok(pivot_indices),
                x if x < 0 => Err(Error::IllegalParameter(-x as usize)),
                x => Err(Error::DiagonalElementZero(x as usize)),
            }
        }
    }

    impl Gbsv for $t {
        fn gbsv(a: &mut BandMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, gbsv_)(a.cols().as_mut(),
                    a.sub_diagonals().as_mut(), a.sup_diagonals().as_mut(),
                    b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Gtsv for $t {
        fn gtsv(a: &mut TridiagonalMatrix<Self>, b: &mut Matrix<Self>) {
            unsafe {
                let mut info: c_int = 0;

                let (sup, diag, sub) = a.as_mut_ptrs();

                prefix!($t, gtsv_)(a.cols().as_mut(), b.cols().as_mut(),
                    sup, diag, sub,
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Posv for $t {
        fn posv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, posv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Ppsv for $t {
        fn ppsv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, ppsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl<M> Pbsv<M> for $t where M: SymmetricMatrix<$t> + BandMatrix<$t> {
        fn pbsv(a: &mut M, b: &mut Matrix<$t>) {
            unsafe {
                let mut info: c_int = 0;

                let diag = match a.symmetry() {
                    Symmetry::Upper => a.sup_diagonals(),
                    Symmetry::Lower => a.sub_diagonals(),
                };

                prefix!($t, pbsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), diag.as_mut(),
                    b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Sysv for $t {
        fn sysv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                let n = a.cols() as usize;
                let mut work: Vec<$t> = Vec::with_capacity(n);

                prefix!($t, sysv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    (&mut work[..]).as_mut_ptr(), a.cols().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Spsv for $t {
        fn spsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, spsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }
)+));

macro_rules! complex_lin_eq_impl(($($t: ident), +) => ($(
    impl Hesv for $t {
        fn hesv(a: &mut SymmetricMatrix<$t>, b: &mut Matrix<$t>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                let n = a.cols() as usize;
                let mut work: Vec<$t> = Vec::with_capacity(n);

                prefix!($t, hesv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(), a.rows().as_mut(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    (&mut work[..]).as_mut_ptr(), a.cols().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }

    impl Hpsv for $t {
        fn hpsv(a: &mut SymmetricMatrix<Self>, b: &mut Matrix<Self>, p: &mut Matrix<c_int>) {
            unsafe {
                let mut info: c_int = 0;

                prefix!($t, hpsv_)(a.symmetry().as_i8().as_mut(),
                    a.cols().as_mut(), b.cols().as_mut(),
                    a.as_mut_ptr(),
                    p.as_mut_ptr(),
                    b.as_mut_ptr(), b.rows().as_mut(),
                    &mut info as *mut c_int);
            }
        }
    }
)+));

lin_eq_impl!(f32, f64, Complex32, Complex64);
complex_lin_eq_impl!(Complex32, Complex64);

#[cfg(test)]
mod gesv_tests {

    use linear_equations::Gesv;

    #[test]
    fn real() {
        let mut a = (2i32, 2i32, vec![1.0f64, 4.0, 1.0, 2.0]);
        let mut b = (2i32, 1i32, vec![-2.0f64, 2.0]);
        let mut p = (2i32, 2i32, vec![0i32, 0]);

        Gesv::gesv(&mut a, &mut b, &mut p);

        let (_, _, x) = b;
        assert_eq!(x, vec![3.0f64, -5.0]);
    }
}
<|endoftext|>


<commit_before>/**
Expose GraphQL interfaces

Mapping interfaces to GraphQL can be tricky: there is no direct counterpart to
GraphQL interfaces in Rust, and downcasting is not possible in the general case.
Many other GraphQL implementations in other languages use instance checks and
either dynamic typing or forced downcasts to support these features.

A GraphQL interface defines fields that the implementing types also need to
implement. A GraphQL interface also needs to be able to determine the concrete
type name as well as downcast the general type to the actual concrete type.

## Syntax

See the documentation for [`graphql_object!`][1] on the general item and type
syntax. `graphql_interface!` requires an additional `instance_resolvers` item,
and does _not_ support the `interfaces` item.

`instance_resolvers` is a list/lambda hybrid used to resolve the concrete
instance type of the interface. It starts with a context argument and continues
with an array of expressions, each resolving into an `Option<T>` of the possible
instances:

```rust,ignore
instance_resolvers: |&context| [
    context.get_human(self.id()), // returns Option<Human>
    context.get_droid(self.id()), // returns Option<Droid>
],
```

Each item in the array will be executed in order when the concrete type is
required.

## Example

A simplified extract from the StarWars schema example shows how to use the
shared context to implement downcasts.

```rust
# #[macro_use] extern crate juniper;
# use juniper::FieldResult;
# use std::collections::HashMap;
struct Human { id: String }
struct Droid { id: String }
struct Database {
    humans: HashMap<String, Human>,
    droids: HashMap<String, Droid>,
}

trait Character {
    fn id(&self) -> &str;
}

impl Character for Human {
    fn id(&self) -> &str { &self.id }
}

impl Character for Droid {
    fn id(&self) -> &str { &self.id }
}

graphql_object!(Human: Database as "Human" |&self| {
    field id() -> FieldResult<&str> { Ok(&self.id) }
});

graphql_object!(Droid: Database as "Droid" |&self| {
    field id() -> FieldResult<&str> { Ok(&self.id) }
});

// You can introduce lifetimes or generic parameters by < > before the name.
graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
    field id() -> FieldResult<&str> { Ok(self.id()) }

    instance_resolvers: |&context| [
        context.humans.get(self.id()),
        context.droids.get(self.id()),
    ]
});

# fn main() { }
```

[1]: macro.graphql_object!.html

*/
#[macro_export]
macro_rules! graphql_interface {
    ( @as_item, $i:item) => { $i };
    ( @as_expr, $e:expr) => { $e };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        field $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
    ) => {
        $acc.push(__graphql__args!(
            @apply_args,
            $reg,
            $reg.field_inside_result(
                &$crate::to_snake_case(stringify!($name)),
                Err("dummy".to_owned()) as $t)
                .description($desc),
            $args));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        $acc.push(__graphql__args!(
            @apply_args,
            $reg,
            $reg.field_inside_result(
                &$crate::to_snake_case(stringify!($name)),
                Err("dummy".to_owned()) as $t),
            $args));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        description : $value:tt $( $rest:tt )*
    ) => {
        $descr = Some(graphql_interface!(@as_expr, $value));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*)
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        instance_resolvers: | $execvar:pat | $resolvers:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*)
    };

    ( @gather_meta, $reg:expr, $acc:expr, $descr:expr, $(,)* ) => {};

    (
        @resolve_into_type,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt, description : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt, interfaces : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt, description : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt, interfaces : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        ($outname:tt, $ctxtarg:ident, $ctxttype:ty),
        instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr , )* ] $( $rest:tt )*
    ) => {
        let $ctxtvar = &$ctxtarg;

        fn inner_type_of<T>(_: T) -> String where T: $crate::GraphQLType<$ctxttype> {
            T::name().unwrap().to_owned()
        }

        $(
            if let Some(ref v) = $resolver {
                return inner_type_of(v);
            }
        )*

        panic!("Concrete type not handled by instance resolvers on {}", $outname);
    };

    ( @concrete_type_name, $buildargs:tt, ) => {
        ()
    };

    (
        @resolve_into_type,
        ($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
        instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr , )* ] $( $rest:tt )*
    ) => {
        let $ctxtvar = &$execarg.context();

        fn inner_type_of<T>(_: T) -> String where T: $crate::GraphQLType<$ctxttype> {
            T::name().unwrap().to_owned()
        }

        $(
            if let Some(ref v) = $resolver {
                if inner_type_of(v) == $typenamearg {
                    return $execarg.resolve(v);
                }
            }
        )*

        panic!("Concrete type not handled by instance resolvers on {}", $outname);
    };

    ( @resolve_into_type, $buildargs:tt, ) => {
        ()
    };

    (
        ( $($lifetime:tt),* ) $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(@as_item, impl<$($lifetime)*> $crate::GraphQLType<$ctxt> for $name {
            fn name() -> Option<&'static str> {
                Some($outname)
            }

            #[allow(unused_assignments)]
            #[allow(unused_mut)]
            fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType {
                let mut fields = Vec::new();
                let mut description = None;
                graphql_interface!(@gather_meta, registry, fields, description, $($items)*);
                let mut mt = registry.build_interface_type::<$name>()(&fields);

                if let Some(description) = description {
                    mt = mt.description(description);
                }

                mt.into_meta()
            }

            #[allow(unused_variables)]
            #[allow(unused_mut)]
            fn resolve_field(&$mainself, field: &str, args: &$crate::Arguments, mut executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult {
                __graphql__build_field_matches!(($outname, $mainself, field, args, executor), (), $($items)*);
            }

            fn concrete_type_name(&$mainself, context: &$ctxt) -> String {
                graphql_interface!(
                    @concrete_type_name,
                    ($outname, context, $ctxt),
                    $($items)*);
            }

            fn resolve_into_type(&$mainself, type_name: &str, _: Option<Vec<$crate::Selection>>, executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult {
                graphql_interface!(
                    @resolve_into_type,
                    ($outname, type_name, executor, $ctxt),
                    $($items)*);
            }
        });
    };

    (
        <$($lifetime:tt),*> $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(
            ($($lifetime),*) $name : $ctxt as $outname | &$mainself | { $( $items )* });
    };

    (
        $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(() $name : $ctxt as $outname | &$mainself | { $( $items )* });
    };
}
<commit_msg>Fix concrete resolution macro<commit_after>/**
Expose GraphQL interfaces

Mapping interfaces to GraphQL can be tricky: there is no direct counterpart to
GraphQL interfaces in Rust, and downcasting is not possible in the general case.
Many other GraphQL implementations in other languages use instance checks and
either dynamic typing or forced downcasts to support these features.

A GraphQL interface defines fields that the implementing types also need to
implement. A GraphQL interface also needs to be able to determine the concrete
type name as well as downcast the general type to the actual concrete type.

## Syntax

See the documentation for [`graphql_object!`][1] on the general item and type
syntax. `graphql_interface!` requires an additional `instance_resolvers` item,
and does _not_ support the `interfaces` item.

`instance_resolvers` is a list/lambda hybrid used to resolve the concrete
instance type of the interface. It starts with a context argument and continues
with an array of expressions, each resolving into an `Option<T>` of the possible
instances:

```rust,ignore
instance_resolvers: |&context| [
    context.get_human(self.id()), // returns Option<Human>
    context.get_droid(self.id()), // returns Option<Droid>
],
```

Each item in the array will be executed in order when the concrete type is
required.

## Example

A simplified extract from the StarWars schema example shows how to use the
shared context to implement downcasts.

```rust
# #[macro_use] extern crate juniper;
# use juniper::FieldResult;
# use std::collections::HashMap;
struct Human { id: String }
struct Droid { id: String }
struct Database {
    humans: HashMap<String, Human>,
    droids: HashMap<String, Droid>,
}

trait Character {
    fn id(&self) -> &str;
}

impl Character for Human {
    fn id(&self) -> &str { &self.id }
}

impl Character for Droid {
    fn id(&self) -> &str { &self.id }
}

graphql_object!(Human: Database as "Human" |&self| {
    field id() -> FieldResult<&str> { Ok(&self.id) }
});

graphql_object!(Droid: Database as "Droid" |&self| {
    field id() -> FieldResult<&str> { Ok(&self.id) }
});

// You can introduce lifetimes or generic parameters by < > before the name.
graphql_interface!(<'a> &'a Character: Database as "Character" |&self| {
    field id() -> FieldResult<&str> { Ok(self.id()) }

    instance_resolvers: |&context| [
        context.humans.get(self.id()),
        context.droids.get(self.id()),
    ]
});

# fn main() { }
```

[1]: macro.graphql_object!.html

*/
#[macro_export]
macro_rules! graphql_interface {
    ( @as_item, $i:item) => { $i };
    ( @as_expr, $e:expr) => { $e };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        field $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
    ) => {
        $acc.push(__graphql__args!(
            @apply_args,
            $reg,
            $reg.field_inside_result(
                &$crate::to_snake_case(stringify!($name)),
                Err("dummy".to_owned()) as $t)
                .description($desc),
            $args));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        $acc.push(__graphql__args!(
            @apply_args,
            $reg,
            $reg.field_inside_result(
                &$crate::to_snake_case(stringify!($name)),
                Err("dummy".to_owned()) as $t),
            $args));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*);
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        description : $value:tt $( $rest:tt )*
    ) => {
        $descr = Some(graphql_interface!(@as_expr, $value));

        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*)
    };

    (
        @gather_meta,
        $reg:expr, $acc:expr, $descr:expr,
        instance_resolvers: | $execvar:pat | $resolvers:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@gather_meta, $reg, $acc, $descr, $( $rest )*)
    };

    ( @gather_meta, $reg:expr, $acc:expr, $descr:expr, $(,)* ) => {};

    (
        @resolve_into_type,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt, description : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @resolve_into_type,
        $buildargs:tt, interfaces : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@resolve_into_type, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty as $descr:tt $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt,
        field $name:ident $args:tt -> $t:ty $body:block $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt, description : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        $buildargs:tt, interfaces : $value:tt $( $rest:tt )*
    ) => {
        graphql_interface!(@concrete_type_name, $buildargs, $( $rest )*)
    };

    (
        @concrete_type_name,
        ($outname:tt, $ctxtarg:ident, $ctxttype:ty),
        instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr , )* ] $( $rest:tt )*
    ) => {
        let $ctxtvar = &$ctxtarg;

        fn inner_type_of<T>(_: T) -> String where T: $crate::GraphQLType<$ctxttype> {
            T::name().unwrap().to_owned()
        }

        $(
            if let Some(ref v) = $resolver {
                return inner_type_of(v);
            }
        )*

        panic!("Concrete type not handled by instance resolvers on {}", $outname);
    };

    ( @concrete_type_name, $buildargs:tt, ) => {
        ()
    };

    (
        @resolve_into_type,
        ($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
        instance_resolvers : | $ctxtvar:pat | [ $( $resolver:expr , )* ] $( $rest:tt )*
    ) => {
        let $ctxtvar = &$execarg.context();

        fn inner_type_of<T>(_: T) -> String where T: $crate::GraphQLType<$ctxttype> {
            T::name().unwrap().to_owned()
        }

        $(
            if let Some(ref v) = $resolver {
                if inner_type_of(v) == $typenamearg {
                    return $execarg.resolve(v);
                }
            }
        )*

        return Ok($crate::Value::null());
    };

    ( @resolve_into_type, $buildargs:tt, ) => {
        ()
    };

    (
        ( $($lifetime:tt),* ) $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(@as_item, impl<$($lifetime)*> $crate::GraphQLType<$ctxt> for $name {
            fn name() -> Option<&'static str> {
                Some($outname)
            }

            #[allow(unused_assignments)]
            #[allow(unused_mut)]
            fn meta(registry: &mut $crate::Registry<$ctxt>) -> $crate::meta::MetaType {
                let mut fields = Vec::new();
                let mut description = None;
                graphql_interface!(@gather_meta, registry, fields, description, $($items)*);
                let mut mt = registry.build_interface_type::<$name>()(&fields);

                if let Some(description) = description {
                    mt = mt.description(description);
                }

                mt.into_meta()
            }

            #[allow(unused_variables)]
            #[allow(unused_mut)]
            fn resolve_field(&$mainself, field: &str, args: &$crate::Arguments, mut executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult {
                __graphql__build_field_matches!(($outname, $mainself, field, args, executor), (), $($items)*);
            }

            fn concrete_type_name(&$mainself, context: &$ctxt) -> String {
                graphql_interface!(
                    @concrete_type_name,
                    ($outname, context, $ctxt),
                    $($items)*);
            }

            fn resolve_into_type(&$mainself, type_name: &str, _: Option<Vec<$crate::Selection>>, executor: &mut $crate::Executor<$ctxt>) -> $crate::ExecutionResult {
                graphql_interface!(
                    @resolve_into_type,
                    ($outname, type_name, executor, $ctxt),
                    $($items)*);
            }
        });
    };

    (
        <$($lifetime:tt),*> $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(
            ($($lifetime),*) $name : $ctxt as $outname | &$mainself | { $( $items )* });
    };

    (
        $name:ty : $ctxt:ty as $outname:tt | &$mainself:ident | {
            $( $items:tt )*
        }
    ) => {
        graphql_interface!(() $name : $ctxt as $outname | &$mainself | { $( $items )* });
    };
}
<|endoftext|>


<commit_before>// This function takes ownership of the heap allocated memory
fn destroy_box(c: Box<i32>) {
    println!("Destroying a box that contains {}", c);

    // `c` is destroyed and the memory freed
}

fn notdestroy_uint(c: u32) {
    println!("Mot destroying a value that contains [0b{:b} = {}]", c, c);
}

pub fn main() {
    // _Stack_ allocated integer
    let x = 5u32;

    // *Copy* `x` into `y` - no resources are moved
    let y = x;
    let mut z = x;
    z = 3;

    // Both values can be independently used
    println!("x is {}, and y is {}, z is {}", x, y, z);
    notdestroy_uint(z);
    println!("{}", z);

    // `a` is a pointer to a _heap_ allocated integer
    let a = Box::new(5i32);

    println!("a contains: {}", a);

    // *Move* `a` into `b`
    let b = a;
    // The pointer address of `a` is copied (not the data) into `b`.
    // Both are now pointers to the same heap allocated data, but
    // `b` now owns it.

    // Error! `a` can no longer access the data, because it no longer owns the
    // heap memory
    //println!("a contains: {}", a);
    // TODO ^ Try uncommenting this line

    // This function takes ownership of the heap allocated memory from `b`
    destroy_box(b);

    // Since the heap memory has been freed at this point, this action would
    // result in dereferencing freed memory, but it's forbidden by the compiler
    // Error! Same reason as the previous Error
    //println!("b contains: {}", b);
    // TODO ^ Try uncommenting this line
}<commit_msg>Rust By Examples [RBE] - 13.2.1 Mutability<commit_after>// This function takes ownership of the heap allocated memory
fn destroy_box(c: Box<i32>) {
    println!("Destroying a box that contains {}", c);

    // `c` is destroyed and the memory freed
}

fn notdestroy_uint(c: u32) {
    println!("Mot destroying a value that contains [0b{:b} = {}]", c, c);
}

pub fn main() {
    // _Stack_ allocated integer
    let x = 5u32;

    // *Copy* `x` into `y` - no resources are moved
    let y = x;
    let mut z = x;

    // Both values can be independently used
    println!("x is {}, and y is {}, z is {}", x, y, z);

    z = 3;
    notdestroy_uint(z);
    println!("{}", z);

    // `a` is a pointer to a _heap_ allocated integer
    let mut a = Box::new(5i32);
    *a = 10;

    println!("a contains: {}", a);

    // *Move* `a` into `b`
    let b = a;
    // The pointer address of `a` is copied (not the data) into `b`.
    // Both are now pointers to the same heap allocated data, but
    // `b` now owns it.

    // Error! `a` can no longer access the data, because it no longer owns the
    // heap memory
    //println!("a contains: {}", a);
    // TODO ^ Try uncommenting this line

    // This function takes ownership of the heap allocated memory from `b`
    destroy_box(b);

    // Since the heap memory has been freed at this point, this action would
    // result in dereferencing freed memory, but it's forbidden by the compiler
    // Error! Same reason as the previous Error
    //println!("b contains: {}", b);
    // TODO ^ Try uncommenting this line

    //=================================
    let immutable_box = Box::new(5u32);

    println!("immutable_box contains {}", immutable_box);

    // Mutability error
    //*immutable_box = 4;

    // *Move* the box, changing the ownership (and mutability)
    let mut mutable_box = immutable_box;

    println!("mutable_box contains {}", mutable_box);

    // Modify the contents of the box
    *mutable_box = 4;

    println!("mutable_box now contains {}", mutable_box);
}<|endoftext|>


<commit_before>// xfail-stage0

use std;
import std._vec;

fn main() {
    auto v = vec(1, 2, 3);
    check (_vec.refcount[int](v) == 1u);
    check (_vec.refcount[int](v) == 1u);
}

<commit_msg>Change vec-ref-count to handle 1 or 2, so long as non-leaky and non-creeping. un-XFAIL.<commit_after>use std;
import std._vec;

fn main() {
    auto v = vec(1, 2, 3);
    log_err _vec.refcount[int](v);
    log_err _vec.refcount[int](v);
    log_err _vec.refcount[int](v);
    check (_vec.refcount[int](v) == 1u || _vec.refcount[int](v) == 2u);
    check (_vec.refcount[int](v) == 1u || _vec.refcount[int](v) == 2u);
}

<|endoftext|>


<commit_before>//! Super fast HTML template engine.

#![allow(unstable)]

use std::fmt;
use std::io::{IoError, IoErrorKind, IoResult};

/// Escape an HTML value.
pub fn escape(s: &str) -> String {
    use std::fmt::Writer;
    let mut buf = String::new();
    rt::Escaper { inner: &mut buf }.write_str(s).unwrap();
    buf
}

/// A block of HTML markup, as returned by the `html!` macro.
pub struct Markup<'a> {
    callback: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a),
}

impl<'a> Markup<'a> {
    /// Render the markup to a `String`.
    pub fn render(&self) -> String {
        let mut buf = String::new();
        self.render_fmt(&mut buf).unwrap();
        buf
    }

    /// Render the markup to a `std::io::Writer`.
    pub fn render_to(&self, w: &mut Writer) -> IoResult<()> {
        struct WriterWrapper<'a, 'b: 'a> {
            inner: &'a mut (Writer + 'b),
        }
        impl<'a, 'b> fmt::Writer for WriterWrapper<'a, 'b> {
            fn write_str(&mut self, s: &str) -> fmt::Result {
                self.inner.write_str(s).map_err(|_| fmt::Error)
            }
        }
        self.render_fmt(&mut WriterWrapper { inner: w })
            .map_err(|_| IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "formatting error",
                detail: None,
            })
    }

    /// Render the markup to a `std::fmt::Writer`.
    pub fn render_fmt(&self, w: &mut fmt::Writer) -> fmt::Result {
        (self.callback)(w)
    }
}

/// Internal functions used by the `maud_macros` package. You should
/// never need to call these directly.
#[doc(hidden)]
pub mod rt {
    use std::fmt;
    use super::Markup;

    #[inline]
    pub fn make_markup<'a>(f: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a)) -> Markup<'a> {
        Markup { callback: f }
    }

    /// rustc is a butt and doesn't let us quote macro invocations
    /// directly. So we factor the `write!` call into a separate
    /// function and use that instead.
    ///
    /// See <https://github.com/rust-lang/rust/issues/16617>
    #[inline]
    pub fn write_fmt<T: fmt::String>(w: &mut fmt::Writer, value: T) -> fmt::Result {
        write!(w, "{}", value)
    }

    pub struct Escaper<'a, 'b: 'a> {
        pub inner: &'a mut (fmt::Writer + 'b),
    }

    impl<'a, 'b> fmt::Writer for Escaper<'a, 'b> {
        fn write_str(&mut self, s: &str) -> fmt::Result {
            for c in s.chars() {
                try!(match c {
                    '&' => self.inner.write_str("&"),
                    '<' => self.inner.write_str("<"),
                    '>' => self.inner.write_str(">"),
                    '"' => self.inner.write_str("""),
                    '\'' => self.inner.write_str("'"),
                    _ => write!(self.inner, "{}", c),
                });
            }
            Ok(())
        }
    }
}
<commit_msg>Document the whole thing<commit_after>//! A macro for writing HTML templates.
//!
//! This crate, along with its sister `maud_macros`, lets you generate
//! HTML markup from within Rust. It exposes a single macro, `html!`,
//! which compiles your markup to specialized Rust code.
//!
//! # Dependencies
//!
//! To get started, add `maud` and `maud_macros` to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! # ...
//! maud = "*"
//! maud_macros = "*"
//! ```
//!
//! # Example
//!
//! ```rust
//! #![feature(plugin)]
//! #![allow(unstable)]
//!
//! extern crate maud;
//! #[plugin] #[no_link] extern crate maud_macros;
//!
//! fn main() {
//!     let name = "Lyra";
//!     let markup = html! {
//!         p { "Hi, " $name "!" }
//!     };
//!     assert_eq!(markup.render(), "<p>Hi, Lyra!</p>");
//! }
//! ```
//!
//! # Syntax
//!
//! Maud uses its own syntax, loosely inspired by HTML and Rust.
//!
//! ## Literals
//!
//! ```
//! html! {
//!     "Oatmeal, are you crazy?\n"
//!     "<script>alert(\"XSS\")</script>\n"
//!     $$"<script>alert(\"XSS\")</script>\n"
//! }
//! ```
//!
//! ```html
//! Oatmeal, are you crazy?
//! <script>alert("XSS")</script>
//! <script>alert("XSS")</script>
//! ```
//!
//! Literal strings use the same syntax as Rust.
//!
//! By default, HTML special characters are escaped automatically. Add a
//! `$$` prefix to disable this escaping.
//!
//! ## Elements
//!
//! ```
//! html! {
//!     h1 "Pinkie's Brew"
//!     p {
//!         "Watch as I work my gypsy magic"
//!         br /
//!         "Eye of a newt and cinnamon"
//!     }
//!     p small em "squee"
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie's Brew</h1>
//! <p>
//!   Watch as I work my gypsy magic
//!   <br>
//!   Eye of a newt and cinnamon
//! </p>
//! <p><small><em>squee</em></small></p>
//! ```
//!
//! Write an element using curly braces (`p {}`).
//!
//! Terminate a void element using a slash (`br /`).
//!
//! If the element has only a single child, you can omit the brackets
//! (`h1 "Pinkie's Brew"`). This shorthand works with nested elements
//! too.
//!
//! ## Attributes
//!
//! ```
//! html! {
//!     form method="POST" {
//!         label for="waffles" "Do you like waffles?"
//!         input name="waffles" type="checkbox" checked=! /
//!     }
//! }
//! ```
//!
//! ```html
//! <form method="POST">
//!   <label for="waffles">Do you like waffles?</label>
//!   <input name="waffles" type="checkbox" checked>
//! </form>
//! ```
//!
//! Add attributes using the syntax `attr="value"`. Attributes must be
//! quoted: they are parsed as string literals.
//!
//! To declare an empty attribute, use `!` for the value: `checked=!`.
//!
//! ## Splices
//!
//! ```
//! let best_pony = "Pinkie Pie";
//! let numbers = [1, 2, 3, 4];
//! let secret_message = "Surprise!";
//! let pre_escaped = "<p>Pre-escaped</p>";
//! html! {
//!     h1 { $best_pony " says:" }
//!     p {
//!         "I have " $numbers.len() " numbers, "
//!         "and the first one is " $numbers[0]
//!     }
//!     p title=$secret_message {
//!         "1 + 1 = " $(1 + 1)
//!     }
//!     $$pre_escaped
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie Pie says:</h1>
//! <p>I have 4 numbers, and the first one is 1</p>
//! <p title="Surprise!">1 + 1 = 2</p>
//! <p>Pre-escaped</p>
//! ```
//!
//! Use `$(expr)` syntax to splice a Rust expression into the output.
//! You can omit the brackets if it's just a variable (`$var`), indexing
//! operation (`$var[0]`), method call (`$var.method()`), or property
//! lookup (`$var.property`).
//!
//! As with literals, expression values are escaped by default. Use a
//! `$$` prefix to disable this behavior.

#![allow(unstable)]

use std::fmt;
use std::io::{IoError, IoErrorKind, IoResult};

/// Escape an HTML value.
pub fn escape(s: &str) -> String {
    use std::fmt::Writer;
    let mut buf = String::new();
    rt::Escaper { inner: &mut buf }.write_str(s).unwrap();
    buf
}

/// A block of HTML markup, as returned by the `html!` macro.
pub struct Markup<'a> {
    callback: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a),
}

impl<'a> Markup<'a> {
    /// Render the markup to a `String`.
    pub fn render(&self) -> String {
        let mut buf = String::new();
        self.render_fmt(&mut buf).unwrap();
        buf
    }

    /// Render the markup to a `std::io::Writer`.
    pub fn render_to(&self, w: &mut Writer) -> IoResult<()> {
        struct WriterWrapper<'a, 'b: 'a> {
            inner: &'a mut (Writer + 'b),
        }
        impl<'a, 'b> fmt::Writer for WriterWrapper<'a, 'b> {
            fn write_str(&mut self, s: &str) -> fmt::Result {
                self.inner.write_str(s).map_err(|_| fmt::Error)
            }
        }
        self.render_fmt(&mut WriterWrapper { inner: w })
            .map_err(|_| IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "formatting error",
                detail: None,
            })
    }

    /// Render the markup to a `std::fmt::Writer`.
    pub fn render_fmt(&self, w: &mut fmt::Writer) -> fmt::Result {
        (self.callback)(w)
    }
}

/// Internal functions used by the `maud_macros` package. You should
/// never need to call these directly.
#[doc(hidden)]
pub mod rt {
    use std::fmt;
    use super::Markup;

    #[inline]
    pub fn make_markup<'a>(f: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a)) -> Markup<'a> {
        Markup { callback: f }
    }

    /// rustc is a butt and doesn't let us quote macro invocations
    /// directly. So we factor the `write!` call into a separate
    /// function and use that instead.
    ///
    /// See <https://github.com/rust-lang/rust/issues/16617>
    #[inline]
    pub fn write_fmt<T: fmt::String>(w: &mut fmt::Writer, value: T) -> fmt::Result {
        write!(w, "{}", value)
    }

    pub struct Escaper<'a, 'b: 'a> {
        pub inner: &'a mut (fmt::Writer + 'b),
    }

    impl<'a, 'b> fmt::Writer for Escaper<'a, 'b> {
        fn write_str(&mut self, s: &str) -> fmt::Result {
            for c in s.chars() {
                try!(match c {
                    '&' => self.inner.write_str("&"),
                    '<' => self.inner.write_str("<"),
                    '>' => self.inner.write_str(">"),
                    '"' => self.inner.write_str("""),
                    '\'' => self.inner.write_str("'"),
                    _ => write!(self.inner, "{}", c),
                });
            }
            Ok(())
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>rust operation traits<commit_after><|endoftext|>


<commit_before>extern crate gluon;
use gluon::new_vm;
use gluon::vm::Variants;
use gluon::vm::internal::Value;
use gluon::vm::api::Getable;

#[cfg_attr(rustfmt, rustfmt_skip)]
fn main() {
    unsafe {
        let vm = new_vm();
        let v = Value::Int(0);
        let v = Variants::new(&v);
        let _: Option<&'static str> = <&'static str>::from_value(&vm, v);
        //~^ Error `vm` does not live long enough
    }
}
<commit_msg>Fix tests/compile-fail/get-reference.rs<commit_after>extern crate gluon;
use gluon::new_vm;
use gluon::vm::Variants;
use gluon::vm::internal::Value;
use gluon::vm::api::Getable;

#[cfg_attr(rustfmt, rustfmt_skip)]
fn main() {
    unsafe {
        let vm = new_vm();
        let v = Value::Int(0);
        let v = Variants::new(&v);
        let _: &'static str = <&'static str>::from_value(&vm, v);
        //~^ Error `vm` does not live long enough
    }
}
<|endoftext|>