<commit_before>// Copyright 2014 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// 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.

#![feature(plugin_registrar, quote)]

extern crate rustc;
extern crate syntax;

use std::gc::{Gc, GC};
use std::io::Command;
use std::mem;
use std::str;
use syntax::ast;
use syntax::codemap;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use intern_str = syntax::parse::token::intern_and_get_ident;

#[plugin_registrar]
pub fn registrar(reg: &mut rustc::plugin::Registry) {
    reg.register_syntax_extension(token::intern("link_glfw"),
                                  base::ItemModifier(expand));
}

fn lit_str(s: token::InternedString) -> ast::Lit_ {
    ast::LitStr(s, ast::CookedStr)
}

enum LinkKind {
    Unknown,
    Framework,
}

fn attr_link(context: &mut base::ExtCtxt, span: codemap::Span,
             name: token::InternedString, kind: LinkKind) -> ast::Attribute {
    let mut meta_items = vec![
        context.meta_name_value(span, intern_str("name"), lit_str(name)),
    ];
    match kind {
        Framework => {
            meta_items.push(context.meta_name_value(
                span, intern_str("kind"),
                lit_str(intern_str("framework"))
            ));
        },
        _ => {},
    }
    let meta_list = context.meta_list(span, intern_str("link"), meta_items);
    context.attribute(span, meta_list)
}

pub fn expand(context: &mut base::ExtCtxt, span: codemap::Span,
              meta_item: Gc<ast::MetaItem>, item: Gc<ast::Item>
              ) -> Gc<ast::Item> {
    let out = Command::new("pkg-config")
        .arg("--static")
        .arg("--libs-only-l")
        .arg("--libs-only-other")
        .arg("glfw3")
        .output();
    match out {
        Ok(out) => {
            if out.status.success() {
                let mut item = (*item).clone();
                str::from_utf8(out.output.as_slice()).map(|output| {
                    let mut expect_framework = false;
                    for word in output.words() {
                        if word.starts_with("-l") {
                            item.attrs.push(attr_link(
                                context, span,
                                intern_str(word.slice_from(2)),
                                Unknown,
                            ));
                        } else if expect_framework {
                            expect_framework = false;
                            item.attrs.push(attr_link(
                                context, span,
                                intern_str(word),
                                Framework,
                            ));
                        } else if word.starts_with("-framework") {
                            expect_framework = true;
                        }
                    }
                });
                box (GC) item
            } else {
                context.span_err(span, format!("error returned by \
                    `pkg-config`: ({})", out.status).as_slice());
                item
            }
        },
        Err(e) => {
            context.span_err(span, format!("io error: {}", e).as_slice());
            item
        },
    }
}
<commit_msg>Improve pkg-config error reporting<commit_after>// Copyright 2014 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// 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.

#![feature(plugin_registrar, quote)]

extern crate rustc;
extern crate syntax;

use std::gc::{Gc, GC};
use std::io::Command;
use std::mem;
use std::str;
use syntax::ast;
use syntax::codemap;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use intern_str = syntax::parse::token::intern_and_get_ident;

#[plugin_registrar]
pub fn registrar(reg: &mut rustc::plugin::Registry) {
    reg.register_syntax_extension(token::intern("link_glfw"),
                                  base::ItemModifier(expand));
}

fn lit_str(s: token::InternedString) -> ast::Lit_ {
    ast::LitStr(s, ast::CookedStr)
}

enum LinkKind {
    Unknown,
    Framework,
}

fn attr_link(context: &mut base::ExtCtxt, span: codemap::Span,
             name: token::InternedString, kind: LinkKind) -> ast::Attribute {
    let mut meta_items = vec![
        context.meta_name_value(span, intern_str("name"), lit_str(name)),
    ];
    match kind {
        Framework => {
            meta_items.push(context.meta_name_value(
                span, intern_str("kind"),
                lit_str(intern_str("framework"))
            ));
        },
        _ => {},
    }
    let meta_list = context.meta_list(span, intern_str("link"), meta_items);
    context.attribute(span, meta_list)
}

pub fn expand(context: &mut base::ExtCtxt, span: codemap::Span,
              meta_item: Gc<ast::MetaItem>, item: Gc<ast::Item>
              ) -> Gc<ast::Item> {
    let out = Command::new("pkg-config")
        .arg("--static")
        .arg("--libs-only-l")
        .arg("--libs-only-other")
        .arg("--print-errors")
        .arg("glfw3")
        .output();
    match out {
        Ok(out) => {
            if out.status.success() {
                let mut item = (*item).clone();
                str::from_utf8(out.output.as_slice()).map(|output| {
                    let mut expect_framework = false;
                    for word in output.words() {
                        if word.starts_with("-l") {
                            item.attrs.push(attr_link(
                                context, span,
                                intern_str(word.slice_from(2)),
                                Unknown,
                            ));
                        } else if expect_framework {
                            expect_framework = false;
                            item.attrs.push(attr_link(
                                context, span,
                                intern_str(word),
                                Framework,
                            ));
                        } else if word.starts_with("-framework") {
                            expect_framework = true;
                        }
                    }
                });
                box (GC) item
            } else {
                context.span_err(
                    span,
                    format!(
                        "error returned by \
                        `pkg-config`: ({})\n\
                        `pkg-config stdout`: {}\n\
                        `pkg-config stderr`: {}",
                        out.status,
                        String::from_utf8(out.output).unwrap(),
                        String::from_utf8(out.error).unwrap())
                        .as_slice());
                item
            }
        },
        Err(e) => {
            context.span_err(span, format!("io error: {}", e).as_slice());
            item
        },
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement Read and BufRead for PageReader.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix unreadable literals<commit_after><|endoftext|>


<commit_before><commit_msg>Fix sparkle_default_filtering<commit_after><|endoftext|>


<commit_before><commit_msg>Initial added output mod<commit_after><|endoftext|>


<commit_before><commit_msg>correct docs<commit_after><|endoftext|>


<commit_before><commit_msg>Add run-pass test for reinitialized unions.<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.

// compile-pass

#![feature(untagged_unions)]

struct A;
struct B;

union U {
    a: A,
    b: B,
}

fn main() {
    unsafe {
        {
            let mut u = U { a: A };
            let a = u.a;
            u.a = A;
            let a = u.a; // OK
        }
        {
            let mut u = U { a: A };
            let a = u.a;
            u.b = B;
            let a = u.a; // OK
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>servo: Add missing util.rs<commit_after>pub use gfx::util::cache;
pub use gfx::util::time;

<|endoftext|>


<commit_before><commit_msg>Added Traveling Salesman Problem example<commit_after>/*

Traveling Salesman Problem

Find a closed route between cities with the shortest length.

This solver looks for the choice of roads that has the greatest
potential for reducing distance compared to the next best alternative.
Looks at pair of roads instead of considering each single road.
The choice of roads can not lead to cycle.

The algorithm is exact, and therefore not efficient.

*/

extern crate quickbacktrack;

use std::sync::Arc;
use quickbacktrack::{BackTrackSolver, Puzzle, SolveSettings};

#[derive(Clone, Debug)]
pub struct Tsp {
    /// Choose a pair of roads for each city.
    pub slots: Vec<Option<(usize, usize)>>,
    /// Distances between cities.
    /// Stores `from` in first index, `to` in second index.
    pub distances: Arc<Vec<Vec<f64>>>,
    /// Find a distance less than the target.
    pub target: Option<f64>,
}

impl Tsp {
    pub fn new_2d(map: &Vec<Vec<u8>>) -> Tsp {
        let mut cities: Vec<(usize, usize)> = vec![];
        for i in 0..map.len() {
            for j in 0..map[i].len() {
                if map[i][j] != 0 {
                    cities.push((i, j));
                }
            }
        }

        let mut distances: Vec<Vec<f64>> = vec![];
        for a in &cities {
            let mut a_distances = vec![];
            for b in &cities {
                let dx = b.0 as f64 - a.0 as f64;
                let dy = b.1 as f64 - a.1 as f64;
                a_distances.push((dx * dx + dy * dy).sqrt());
            }
            distances.push(a_distances);
        }

        Tsp {
            slots: vec![None; cities.len()],
            distances: Arc::new(distances),
            target: None,
        }
    }

    /// Get possible choices, sorted by local distance.
    pub fn possible(&self, pos: usize) -> Vec<Option<(usize, usize)>> {
        if self.slots[pos].is_some() { return vec![self.slots[pos]]; }
        if let Some(target) = self.target {
            if target <= self.distance() { return vec![]; }
        }

        let n = self.slots.len();
        let mut res: Vec<Option<(usize, usize)>> = vec![];
        let mut local_distances: Vec<(usize, f64)> = vec![];
        for i in 0..n {
            if i == pos { continue; }

            // Other cities must point to this edge.
            if let Some((i_a, i_b)) = self.slots[i] {
                if i_a != pos && i_b != pos { continue; }
            }

            'j: for j in i + 1..n {
                if j == pos { continue; }

                // Other cities must point to this edge.
                if let Some((j_a, j_b)) = self.slots[j] {
                    if j_a != pos && j_b != pos { continue; }
                }

                // Check that each city is only referenced twice.
                let count_i = self.slots.iter()
                    .filter(|&&x| {
                        if let Some((x_a, x_b)) = x {
                            x_a == i || x_b == i
                        } else { false }
                    }).count();
                if count_i >= 2 { continue; }

                let count_j = self.slots.iter()
                    .filter(|&&x| {
                        if let Some((x_a, x_b)) = x {
                            x_a == j || x_b == j
                        } else { false }
                    }).count();
                if count_j >= 2 { continue; }

                // Seems sufficient to point other slots to this.
                /*
                let mut visited: HashSet<usize> = HashSet::new();
                visited.insert(pos);
                visited.insert(i);
                visited.insert(j);
                if self.detect_loop(&mut visited, j) { continue 'j; }
                */

                // All other slots that point to this must
                // be pointed back to.
                for (ind, s) in self.slots.iter().enumerate() {
                    if let &Some((a, b)) = s {
                        if a == pos || b == pos {
                            if i != ind && j != ind {
                                continue 'j;
                            }
                        }
                    }
                }

                local_distances.push((res.len(),
                    self.distances[pos][i] + self.distances[pos][j]));
                res.push(Some((i, j)));
            }
        }

        if res.len() > 2 {
            use std::cmp::PartialOrd;

            // Try the pair by order of local distance.
            local_distances.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap());
            res = local_distances.iter().rev().map(|p| res[p.0]).collect();
        }

        res
    }

    /*
    fn detect_loop(&self, visited: &mut HashSet<usize>, pos: usize) -> bool {
        if let Some((a, b)) = self.slots[pos] {
            if !visited.contains(&a) {
                visited.insert(a);
                self.detect_loop(visited, a)
            } else if !visited.contains(&b) {
                visited.insert(b);
                self.detect_loop(visited, b)
            } else {
                true
            }
        } else {
            false
        }
    }
    */

    pub fn find_empty(&self) -> Option<usize> {
        for i in 0..self.slots.len() {
            if self.slots[i].is_none() { return Some(i); }
        }
        None
    }

    // Pick empty slot with maximum potential of reducing distance
    // between first and second choice.
    pub fn find_min_empty(&self) -> Option<usize> {
        let mut max_potential: Option<f64> = None;
        let mut min_i: Option<usize> = None;
        for i in 0..self.slots.len() {
            if self.slots[i].is_some() { continue; }

            let possible = self.possible(i);
            if possible.len() == 0 { return None; }
            if possible.len() == 1 { return Some(i); }
            if possible.len() >= 2 {
                let n = possible.len();
                let (aa, ab) = possible[n - 1].unwrap();
                let (ba, bb) = possible[n - 2].unwrap();
                let potential =
                    -self.distances[i][aa] +
                    -self.distances[i][ab] +
                    self.distances[i][ba] +
                    self.distances[i][bb];
                if max_potential.is_none() ||
                    max_potential.unwrap() < potential {
                    min_i = Some(i);
                    max_potential = Some(potential);
                }
            }
        }
        min_i
    }

    pub fn distance(&self) -> f64 {
        use std::collections::HashSet;
        use std::cmp::{max, min};

        let mut counted: HashSet<(usize, usize)> = HashSet::new();
        let mut dist = 0.0;
        for i in 0..self.slots.len() {
            if let Some((a, b)) = self.slots[i] {
                let i_a = (min(i, a), max(i, a));
                if !counted.contains(&i_a) {
                    counted.insert(i_a);
                    dist += self.distances[i][a];
                }

                let i_b = (min(i, b), max(i, b));
                if !counted.contains(&i_b) {
                    counted.insert(i_b);
                    dist += self.distances[i][b];
                }
            }
        }
        dist
    }

    /// Computes lower bound by summing the minimum pair of distances
    /// from each city and then divide by 2.
    /// When the optimal route equals the lower bound, each edge
    /// is counted twice, so therefore we divide by 2.
    pub fn lower_bound(&self) -> f64 {
        let mut sum = 0.0;
        for s in 0..self.slots.len() {
            let mut min_dist: Option<f64> = None;
            for i in 0..self.slots.len() {
                for j in i + 1..self.slots.len() {
                    let dist = self.distances[s][i] + self.distances[s][j];
                    if min_dist.is_none() || min_dist.unwrap() > dist {
                        min_dist = Some(dist);
                    }
                }
            }
            sum += min_dist.unwrap_or(0.0);
        }
        sum / 2.0
    }

    pub fn upper_bound(&self) -> f64 {
        let mut sum = 0.0;
        for s in 0..self.slots.len() {
            let mut max_dist: Option<f64> = None;
            for i in 0..self.slots.len() {
                for j in i + 1..self.slots.len() {
                    let dist = self.distances[s][i] + self.distances[s][j];
                    if max_dist.is_none() || max_dist.unwrap() < dist {
                        max_dist = Some(dist);
                    }
                }
            }
            sum += max_dist.unwrap_or(0.0);
        }
        sum / 2.0
    }
}

impl Puzzle for Tsp {
    type Pos = usize;
    type Val = Option<(usize, usize)>;

    fn solve_simple(&mut self) {}

    fn set(&mut self, pos: usize, val: Option<(usize, usize)>) {
        self.slots[pos] = val;
    }

    fn print(&self) {
        println!("{:?}", self.slots);
        println!("Distance {}", self.distance());
    }

    fn remove(&mut self, other: &Tsp) {
        for i in 0..self.slots.len() {
            if other.slots[i].is_some() {
                self.slots[i] = None;
            }
        }
    }

    fn is_solved(&self) -> bool {
        if let Some(target) = self.target {
            if target <= self.distance() {
                return false;
            }
        }

        self.slots.iter().all(|d| d.is_some())
    }
}

fn main() {
    let x = Tsp::new_2d(&vec![
            vec![0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
            vec![0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            vec![0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
            vec![1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
            vec![0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
            vec![0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0],
            vec![0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
            vec![0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            vec![0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
            vec![1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
            vec![0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
            vec![0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0],
        ]);

    // Compute lower bound.
    println!("Lower bound: {}", x.lower_bound());
    println!("Upper bound: {}", x.upper_bound());

    let settings = SolveSettings::new()
		.solve_simple(false)
		.debug(false)
		.difference(true)
		.sleep_ms(500)
	;

	let solver = BackTrackSolver::new(x, settings);
	let difference = solver.solve(|s| s.find_min_empty(), |s, p| s.possible(p))
		.expect("Expected solution").puzzle;
	println!("Difference:");
	difference.print();
}
<|endoftext|>


<commit_before><commit_msg>Add test for derive(PartialOrd) correctness<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.

// Original issue: #49650

#[derive(PartialOrd, PartialEq)]
struct FloatWrapper(f64);

fn main() {
    assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(0.0)))
}
<|endoftext|>


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

// no-pretty-expanded unnecessary unsafe block generated

#![deny(warnings)]
#![allow(unused_must_use)]
#![allow(unknown_features)]
#![feature(box_syntax)]

use std::fmt;
use std::usize;

struct A;
struct B;
struct C;

impl fmt::LowerHex for A {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("aloha")
    }
}
impl fmt::UpperHex for B {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("adios")
    }
}
impl fmt::Display for C {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad_integral(true, "☃", "123")
    }
}

macro_rules! t {
    ($a:expr, $b:expr) => { assert_eq!($a, $b) }
}

pub fn main() {
    // Various edge cases without formats
    t!(format!(""), "");
    t!(format!("hello"), "hello");
    t!(format!("hello {{"), "hello {");

    // default formatters should work
    t!(format!("{}", 1.0f32), "1");
    t!(format!("{}", 1.0f64), "1");
    t!(format!("{}", "a"), "a");
    t!(format!("{}", "a".to_string()), "a");
    t!(format!("{}", false), "false");
    t!(format!("{}", 'a'), "a");

    // At least exercise all the formats
    t!(format!("{}", true), "true");
    t!(format!("{}", '☃'), "☃");
    t!(format!("{}", 10), "10");
    t!(format!("{}", 10_usize), "10");
    t!(format!("{:?}", '☃'), "'\\u{2603}'");
    t!(format!("{:?}", 10), "10");
    t!(format!("{:?}", 10_usize), "10");
    t!(format!("{:?}", "true"), "\"true\"");
    t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\"");
    t!(format!("{:o}", 10_usize), "12");
    t!(format!("{:x}", 10_usize), "a");
    t!(format!("{:X}", 10_usize), "A");
    t!(format!("{}", "foo"), "foo");
    t!(format!("{}", "foo".to_string()), "foo");
    if cfg!(target_pointer_width = "32") {
        t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234");
        t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234");
    } else {
        t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234");
        t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234");
    }
    t!(format!("{:p}", 0x1234 as *const isize), "0x1234");
    t!(format!("{:p}", 0x1234 as *mut isize), "0x1234");
    t!(format!("{:x}", A), "aloha");
    t!(format!("{:X}", B), "adios");
    t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
    t!(format!("{1} {0}", 0, 1), "1 0");
    t!(format!("{foo} {bar}", foo=0, bar=1), "0 1");
    t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
    t!(format!("{} {0}", "a"), "a a");
    t!(format!("{foo_bar}", foo_bar=1), "1");
    t!(format!("{}", 5 + 5), "10");
    t!(format!("{:#4}", C), "☃123");

    let a: &fmt::Debug = &1;
    t!(format!("{:?}", a), "1");

    // Formatting strings and their arguments
    t!(format!("{}", "a"), "a");
    t!(format!("{:4}", "a"), "a   ");
    t!(format!("{:4}", "☃"), "☃   ");
    t!(format!("{:>4}", "a"), "   a");
    t!(format!("{:<4}", "a"), "a   ");
    t!(format!("{:^5}", "a"),  "  a  ");
    t!(format!("{:^5}", "aa"), " aa  ");
    t!(format!("{:^4}", "a"),  " a  ");
    t!(format!("{:^4}", "aa"), " aa ");
    t!(format!("{:.4}", "a"), "a");
    t!(format!("{:4.4}", "a"), "a   ");
    t!(format!("{:4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:<4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:>4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:^4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:>10.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:2.4}", "aaaaa"), "aaaa");
    t!(format!("{:2.4}", "aaaa"), "aaaa");
    t!(format!("{:2.4}", "aaa"), "aaa");
    t!(format!("{:2.4}", "aa"), "aa");
    t!(format!("{:2.4}", "a"), "a ");
    t!(format!("{:0>2}", "a"), "0a");
    t!(format!("{:.*}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:.1$}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa");
    t!(format!("{:.a$}", "aaaaaaaaaaaaaaaaaa", a=4), "aaaa");
    t!(format!("{:1$}", "a", 4), "a   ");
    t!(format!("{1:0$}", 4, "a"), "a   ");
    t!(format!("{:a$}", "a", a=4), "a   ");
    t!(format!("{:-#}", "a"), "a");
    t!(format!("{:+#}", "a"), "a");

    // Some float stuff
    t!(format!("{:}", 1.0f32), "1");
    t!(format!("{:}", 1.0f64), "1");
    t!(format!("{:.3}", 1.0f64), "1.000");
    t!(format!("{:10.3}", 1.0f64),   "     1.000");
    t!(format!("{:+10.3}", 1.0f64),  "    +1.000");
    t!(format!("{:+10.3}", -1.0f64), "    -1.000");

    t!(format!("{:e}", 1.2345e6f32), "1.2345e6");
    t!(format!("{:e}", 1.2345e6f64), "1.2345e6");
    t!(format!("{:E}", 1.2345e6f64), "1.2345E6");
    t!(format!("{:.3e}", 1.2345e6f64), "1.234e6");
    t!(format!("{:10.3e}", 1.2345e6f64),   "   1.234e6");
    t!(format!("{:+10.3e}", 1.2345e6f64),  "  +1.234e6");
    t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");

    // Float edge cases
    t!(format!("{}", -0.0), "0");
    t!(format!("{:?}", -0.0), "-0");
    t!(format!("{:?}", 0.0), "0");

    // Test that pointers don't get truncated.
    {
        let val = usize::MAX;
        let exp = format!("{:#x}", val);
        t!(format!("{:p}", val as *const isize), exp);
    }

    // Escaping
    t!(format!("{{"), "{");
    t!(format!("}}"), "}");

    test_write();
    test_print();
    test_order();

    // make sure that format! doesn't move out of local variables
    let a: Box<_> = box 3;
    format!("{}", a);
    format!("{}", a);

    // make sure that format! doesn't cause spurious unused-unsafe warnings when
    // it's inside of an outer unsafe block
    unsafe {
        let a: isize = ::std::mem::transmute(3_usize);
        format!("{}", a);
    }

    test_format_args();

    // test that trailing commas are acceptable
    format!("{}", "test",);
    format!("{foo}", foo="test",);
}

// Basic test to make sure that we can invoke the `write!` macro with an
// fmt::Write instance.
fn test_write() {
    use std::fmt::Write;
    let mut buf = String::new();
    write!(&mut buf, "{}", 3);
    {
        let w = &mut buf;
        write!(w, "{foo}", foo=4);
        write!(w, "{}", "hello");
        writeln!(w, "{}", "line");
        writeln!(w, "{foo}", foo="bar");
    }

    t!(buf, "34helloline\nbar\n");
}

// Just make sure that the macros are defined, there's not really a lot that we
// can do with them just yet (to test the output)
fn test_print() {
    print!("hi");
    print!("{:?}", vec!(0u8));
    println!("hello");
    println!("this is a {}", "test");
    println!("{foo}", foo="bar");
}

// Just make sure that the macros are defined, there's not really a lot that we
// can do with them just yet (to test the output)
fn test_format_args() {
    use std::fmt::Write;
    let mut buf = String::new();
    {
        let w = &mut buf;
        write!(w, "{}", format_args!("{}", 1));
        write!(w, "{}", format_args!("test"));
        write!(w, "{}", format_args!("{test}", test=3));
    }
    let s = buf;
    t!(s, "1test3");

    let s = fmt::format(format_args!("hello {}", "world"));
    t!(s, "hello world");
    let s = format!("{}: {}", "args were", format_args!("hello {}", "world"));
    t!(s, "args were: hello world");
}

fn test_order() {
    // Make sure format!() arguments are always evaluated in a left-to-right
    // ordering
    fn foo() -> isize {
        static mut FOO: isize = 0;
        unsafe {
            FOO += 1;
            FOO
        }
    }
    assert_eq!(format!("{} {} {a} {b} {} {c}",
                       foo(), foo(), foo(), a=foo(), b=foo(), c=foo()),
               "1 2 4 5 3 6".to_string());
}
<commit_msg>Rollup merge of #24688 - SimonSapin:fmt-write-char, r=alexcrichton<commit_after>// Copyright 2014-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.

// no-pretty-expanded unnecessary unsafe block generated

#![deny(warnings)]
#![allow(unused_must_use)]
#![allow(unknown_features)]
#![feature(box_syntax)]

use std::fmt;
use std::usize;

struct A;
struct B;
struct C;

impl fmt::LowerHex for A {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("aloha")
    }
}
impl fmt::UpperHex for B {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("adios")
    }
}
impl fmt::Display for C {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad_integral(true, "☃", "123")
    }
}

macro_rules! t {
    ($a:expr, $b:expr) => { assert_eq!($a, $b) }
}

pub fn main() {
    // Various edge cases without formats
    t!(format!(""), "");
    t!(format!("hello"), "hello");
    t!(format!("hello {{"), "hello {");

    // default formatters should work
    t!(format!("{}", 1.0f32), "1");
    t!(format!("{}", 1.0f64), "1");
    t!(format!("{}", "a"), "a");
    t!(format!("{}", "a".to_string()), "a");
    t!(format!("{}", false), "false");
    t!(format!("{}", 'a'), "a");

    // At least exercise all the formats
    t!(format!("{}", true), "true");
    t!(format!("{}", '☃'), "☃");
    t!(format!("{}", 10), "10");
    t!(format!("{}", 10_usize), "10");
    t!(format!("{:?}", '☃'), "'\\u{2603}'");
    t!(format!("{:?}", 10), "10");
    t!(format!("{:?}", 10_usize), "10");
    t!(format!("{:?}", "true"), "\"true\"");
    t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\"");
    t!(format!("{:o}", 10_usize), "12");
    t!(format!("{:x}", 10_usize), "a");
    t!(format!("{:X}", 10_usize), "A");
    t!(format!("{}", "foo"), "foo");
    t!(format!("{}", "foo".to_string()), "foo");
    if cfg!(target_pointer_width = "32") {
        t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234");
        t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234");
    } else {
        t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234");
        t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234");
    }
    t!(format!("{:p}", 0x1234 as *const isize), "0x1234");
    t!(format!("{:p}", 0x1234 as *mut isize), "0x1234");
    t!(format!("{:x}", A), "aloha");
    t!(format!("{:X}", B), "adios");
    t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
    t!(format!("{1} {0}", 0, 1), "1 0");
    t!(format!("{foo} {bar}", foo=0, bar=1), "0 1");
    t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
    t!(format!("{} {0}", "a"), "a a");
    t!(format!("{foo_bar}", foo_bar=1), "1");
    t!(format!("{}", 5 + 5), "10");
    t!(format!("{:#4}", C), "☃123");

    let a: &fmt::Debug = &1;
    t!(format!("{:?}", a), "1");

    // Formatting strings and their arguments
    t!(format!("{}", "a"), "a");
    t!(format!("{:4}", "a"), "a   ");
    t!(format!("{:4}", "☃"), "☃   ");
    t!(format!("{:>4}", "a"), "   a");
    t!(format!("{:<4}", "a"), "a   ");
    t!(format!("{:^5}", "a"),  "  a  ");
    t!(format!("{:^5}", "aa"), " aa  ");
    t!(format!("{:^4}", "a"),  " a  ");
    t!(format!("{:^4}", "aa"), " aa ");
    t!(format!("{:.4}", "a"), "a");
    t!(format!("{:4.4}", "a"), "a   ");
    t!(format!("{:4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:<4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:>4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:^4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:>10.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:2.4}", "aaaaa"), "aaaa");
    t!(format!("{:2.4}", "aaaa"), "aaaa");
    t!(format!("{:2.4}", "aaa"), "aaa");
    t!(format!("{:2.4}", "aa"), "aa");
    t!(format!("{:2.4}", "a"), "a ");
    t!(format!("{:0>2}", "a"), "0a");
    t!(format!("{:.*}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa");
    t!(format!("{:.1$}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa");
    t!(format!("{:.a$}", "aaaaaaaaaaaaaaaaaa", a=4), "aaaa");
    t!(format!("{:1$}", "a", 4), "a   ");
    t!(format!("{1:0$}", 4, "a"), "a   ");
    t!(format!("{:a$}", "a", a=4), "a   ");
    t!(format!("{:-#}", "a"), "a");
    t!(format!("{:+#}", "a"), "a");

    // Some float stuff
    t!(format!("{:}", 1.0f32), "1");
    t!(format!("{:}", 1.0f64), "1");
    t!(format!("{:.3}", 1.0f64), "1.000");
    t!(format!("{:10.3}", 1.0f64),   "     1.000");
    t!(format!("{:+10.3}", 1.0f64),  "    +1.000");
    t!(format!("{:+10.3}", -1.0f64), "    -1.000");

    t!(format!("{:e}", 1.2345e6f32), "1.2345e6");
    t!(format!("{:e}", 1.2345e6f64), "1.2345e6");
    t!(format!("{:E}", 1.2345e6f64), "1.2345E6");
    t!(format!("{:.3e}", 1.2345e6f64), "1.234e6");
    t!(format!("{:10.3e}", 1.2345e6f64),   "   1.234e6");
    t!(format!("{:+10.3e}", 1.2345e6f64),  "  +1.234e6");
    t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");

    // Float edge cases
    t!(format!("{}", -0.0), "0");
    t!(format!("{:?}", -0.0), "-0");
    t!(format!("{:?}", 0.0), "0");

    // Test that pointers don't get truncated.
    {
        let val = usize::MAX;
        let exp = format!("{:#x}", val);
        t!(format!("{:p}", val as *const isize), exp);
    }

    // Escaping
    t!(format!("{{"), "{");
    t!(format!("}}"), "}");

    test_write();
    test_print();
    test_order();

    // make sure that format! doesn't move out of local variables
    let a: Box<_> = box 3;
    format!("{}", a);
    format!("{}", a);

    // make sure that format! doesn't cause spurious unused-unsafe warnings when
    // it's inside of an outer unsafe block
    unsafe {
        let a: isize = ::std::mem::transmute(3_usize);
        format!("{}", a);
    }

    test_format_args();

    // test that trailing commas are acceptable
    format!("{}", "test",);
    format!("{foo}", foo="test",);
}

// Basic test to make sure that we can invoke the `write!` macro with an
// fmt::Write instance.
fn test_write() {
    use std::fmt::Write;
    let mut buf = String::new();
    write!(&mut buf, "{}", 3);
    {
        let w = &mut buf;
        write!(w, "{foo}", foo=4);
        write!(w, "{}", "hello");
        writeln!(w, "{}", "line");
        writeln!(w, "{foo}", foo="bar");
        w.write_char('☃');
        w.write_str("str");
    }

    t!(buf, "34helloline\nbar\n☃str");
}

// Just make sure that the macros are defined, there's not really a lot that we
// can do with them just yet (to test the output)
fn test_print() {
    print!("hi");
    print!("{:?}", vec!(0u8));
    println!("hello");
    println!("this is a {}", "test");
    println!("{foo}", foo="bar");
}

// Just make sure that the macros are defined, there's not really a lot that we
// can do with them just yet (to test the output)
fn test_format_args() {
    use std::fmt::Write;
    let mut buf = String::new();
    {
        let w = &mut buf;
        write!(w, "{}", format_args!("{}", 1));
        write!(w, "{}", format_args!("test"));
        write!(w, "{}", format_args!("{test}", test=3));
    }
    let s = buf;
    t!(s, "1test3");

    let s = fmt::format(format_args!("hello {}", "world"));
    t!(s, "hello world");
    let s = format!("{}: {}", "args were", format_args!("hello {}", "world"));
    t!(s, "args were: hello world");
}

fn test_order() {
    // Make sure format!() arguments are always evaluated in a left-to-right
    // ordering
    fn foo() -> isize {
        static mut FOO: isize = 0;
        unsafe {
            FOO += 1;
            FOO
        }
    }
    assert_eq!(format!("{} {} {a} {b} {} {c}",
                       foo(), foo(), foo(), a=foo(), b=foo(), c=foo()),
               "1 2 4 5 3 6".to_string());
}
<|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.

use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
use rustc_data_structures::stable_hasher;
use rustc_data_structures::ToHex;

const FINGERPRINT_LENGTH: usize = 16;

#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]);

impl Fingerprint {
    #[inline]
    pub fn zero() -> Fingerprint {
        Fingerprint([0; FINGERPRINT_LENGTH])
    }

    pub fn from_smaller_hash(hash: u64) -> Fingerprint {
        let mut result = Fingerprint::zero();
        result.0[0] = (hash >>  0) as u8;
        result.0[1] = (hash >>  8) as u8;
        result.0[2] = (hash >> 16) as u8;
        result.0[3] = (hash >> 24) as u8;
        result.0[4] = (hash >> 32) as u8;
        result.0[5] = (hash >> 40) as u8;
        result.0[6] = (hash >> 48) as u8;
        result.0[7] = (hash >> 56) as u8;
        result
    }

    pub fn to_smaller_hash(&self) -> u64 {
        ((self.0[0] as u64) <<  0) |
        ((self.0[1] as u64) <<  8) |
        ((self.0[2] as u64) << 16) |
        ((self.0[3] as u64) << 24) |
        ((self.0[4] as u64) << 32) |
        ((self.0[5] as u64) << 40) |
        ((self.0[6] as u64) << 48) |
        ((self.0[7] as u64) << 56)
    }

    pub fn to_hex(&self) -> String {
        self.0.to_hex()
    }
}

impl Encodable for Fingerprint {
    #[inline]
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        for &byte in &self.0 {
            s.emit_u8(byte)?;
        }
        Ok(())
    }
}

impl Decodable for Fingerprint {
    #[inline]
    fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
        let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]);
        for byte in &mut result.0 {
            *byte = d.read_u8()?;
        }
        Ok(result)
    }
}

impl ::std::fmt::Display for Fingerprint {
    fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        for i in 0 .. self.0.len() {
            if i > 0 {
                write!(formatter, "::")?;
            }

            write!(formatter, "{}", self.0[i])?;
        }
        Ok(())
    }
}

impl stable_hasher::StableHasherResult for Fingerprint {
    fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
        let mut fingerprint = Fingerprint::zero();
        fingerprint.0.copy_from_slice(hasher.finalize());
        fingerprint
    }
}

impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
    fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
                                          _: &mut CTX,
                                          hasher: &mut stable_hasher::StableHasher<W>) {
        ::std::hash::Hash::hash(&self.0, hasher);
    }
}
<commit_msg>Use in-memory representation for Fingerprint that is more amenable to hashing.<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.

use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
use rustc_data_structures::stable_hasher;
use std::mem;
use std::slice;

#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
pub struct Fingerprint(u64, u64);

impl Fingerprint {
    #[inline]
    pub fn zero() -> Fingerprint {
        Fingerprint(0, 0)
    }

    #[inline]
    pub fn from_smaller_hash(hash: u64) -> Fingerprint {
        Fingerprint(hash, hash)
    }

    #[inline]
    pub fn to_smaller_hash(&self) -> u64 {
        self.0
    }

    pub fn to_hex(&self) -> String {
        format!("{:x}{:x}", self.0, self.1)
    }
}

impl Encodable for Fingerprint {
    #[inline]
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u64(self.0.to_le())?;
        s.emit_u64(self.1.to_le())
    }
}

impl Decodable for Fingerprint {
    #[inline]
    fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
        let _0 = u64::from_le(d.read_u64()?);
        let _1 = u64::from_le(d.read_u64()?);
        Ok(Fingerprint(_0, _1))
    }
}

impl ::std::fmt::Display for Fingerprint {
    fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        write!(formatter, "{:x}-{:x}", self.0, self.1)
    }
}

impl stable_hasher::StableHasherResult for Fingerprint {
    fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
        let hash_bytes: &[u8] = hasher.finalize();

        assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2);
        let hash_bytes: &[u64] = unsafe {
            slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2)
        };

        // The bytes returned bytes the Blake2B hasher are always little-endian.
        Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1]))
    }
}

impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
    #[inline]
    fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
                                          _: &mut CTX,
                                          hasher: &mut stable_hasher::StableHasher<W>) {
        ::std::hash::Hash::hash(self, hasher);
    }
}
<|endoftext|>


<commit_before><commit_msg>Clean up imports<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary lifetime parameter from check_path<commit_after><|endoftext|>


<commit_before>use std::thread;
use std::sync::{Arc, Mutex};
use request;

pub fn release(threads: i32, requests: i32, host: &str) {
    let request = Arc::new(Mutex::new(Vec::new()));
    let mut child_threads = Vec::new();

    for _x in 0..threads {
        let request_clone = request.clone();
        let host_clone = host.to_owned();

        let handle = thread::spawn(move || {
            for _y in 0..requests {
                println!("Spawning virtual user {}", _y);
                let host_str = &host_clone;
                request_clone.lock().unwrap().push((request::Request::new(request::Request::create_request(host_str))));
            }
        });

        child_threads.push(handle);
    }

    for t in child_threads.into_iter() {
        let _child_threads = t.join();
    }

    let lock_request = &mut request.lock().unwrap();
    let mean = request::Request::calculate_mean(lock_request);
    let requests = request::Request::total_requests_made(lock_request);

    println!("I made a total of {} requests, the mean response time was: {} seconds.", requests, mean);
}<commit_msg>Fixing user spawn output<commit_after>use std::thread;
use std::sync::{Arc, Mutex};
use request;

pub fn release(threads: i32, requests: i32, host: &str) {
    let request = Arc::new(Mutex::new(Vec::new()));
    let mut child_threads = Vec::new();

    for _x in 0..threads {
        let request_clone = request.clone();
        let host_clone = host.to_owned();

        let handle = thread::spawn(move || {
            for _y in 0..requests {
                println!("Spawning virtual user {}", _x);
                let host_str = &host_clone;
                request_clone.lock().unwrap().push((request::Request::new(request::Request::create_request(host_str))));
            }
        });

        child_threads.push(handle);
    }

    for t in child_threads.into_iter() {
        let _child_threads = t.join();
    }

    let lock_request = &mut request.lock().unwrap();
    let mean = request::Request::calculate_mean(lock_request);
    let requests = request::Request::total_requests_made(lock_request);

    println!("I made a total of {} requests, the mean response time was: {} seconds.", requests, mean);
}<|endoftext|>


<commit_before><commit_msg>Support const<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed voltage averaging<commit_after><|endoftext|>


<commit_before><commit_msg>Remove duplicate recipient declaration<commit_after><|endoftext|>


<commit_before><commit_msg>General improvements to Interpreter code<commit_after><|endoftext|>


<commit_before><commit_msg>Map text channel IDs to server IDs<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before>//! Details of the `ruma_api` procedural macro.

use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{
    braced,
    parse::{Parse, ParseStream, Result},
    Field, FieldValue, Ident, Meta, Token,
};

mod attribute;
mod metadata;
mod request;
mod response;

use self::{metadata::Metadata, request::Request, response::Response};

/// Removes `serde` attributes from struct fields.
pub fn strip_serde_attrs(field: &Field) -> Field {
    let mut field = field.clone();

    field.attrs = field
        .attrs
        .into_iter()
        .filter(|attr| {
            let meta = attr
                .parse_meta()
                .expect("ruma_api! could not parse field attributes");

            match meta {
                Meta::List(meta_list) => {
                    let segments = &meta_list.path.segments;
                    segments.len() != 1 || segments[0].ident != "serde"
                }
                _ => true,
            }
        })
        .collect();

    field
}

/// The result of processing the `ruma_api` macro, ready for output back to source code.
pub struct Api {
    /// The `metadata` section of the macro.
    metadata: Metadata,
    /// The `request` section of the macro.
    request: Request,
    /// The `response` section of the macro.
    response: Response,
}

impl From<RawApi> for Api {
    fn from(raw_api: RawApi) -> Self {
        Self {
            metadata: raw_api.metadata.into(),
            request: raw_api.request.into(),
            response: raw_api.response.into(),
        }
    }
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        // We don't (currently) use this literal as a literal in the generated code. Instead we just
        // put it into doc comments, for which the span information is irrelevant. So we can work
        // with only the literal's value from here on.
        let name = &self.metadata.name.value();
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request = &self.request;
        let request_types = quote! { #request };
        let response = &self.response;
        let response_types = quote! { #response };

        let set_request_path = if self.request.has_path_fields() {
            let path_str = path.value();

            assert!(path_str.starts_with('/'), "path needs to start with '/'");
            assert!(
                path_str.chars().filter(|c| *c == ':').count() == self.request.path_field_count(),
                "number of declared path parameters needs to match amount of placeholders in path"
            );

            let request_path_init_fields = self.request.request_path_init_fields();

            let path_segments = path_str[1..].split('/');
            let path_segment_push = path_segments.clone().map(|segment| {
                let arg = if segment.starts_with(':') {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    quote!(&request_path.#path_var_ident.to_string())
                } else {
                    quote!(#segment)
                };

                quote! {
                    path_segments.push(#arg);
                }
            });

            quote! {
                let request_path = RequestPath {
                    #request_path_init_fields
                };

                // This `unwrap()` can only fail when the url is a
                // cannot-be-base url like `mailto:` or `data:`, which is not
                // the case for our placeholder url.
                let mut path_segments = url.path_segments_mut().unwrap();
                #(#path_segment_push)*
            }
        } else {
            quote! {
                url.set_path(metadata.path);
            }
        };

        let set_request_query = if self.request.has_query_fields() {
            let request_query_init_fields = self.request.request_query_init_fields();

            quote! {
                let request_query = RequestQuery {
                    #request_query_init_fields
                };

                url.set_query(Some(&ruma_api::exports::serde_urlencoded::to_string(request_query)?));
            }
        } else {
            TokenStream::new()
        };

        let add_headers_to_request = if self.request.has_header_fields() {
            let add_headers = self.request.add_headers_to_request();
            quote! {
                let headers = http_request.headers_mut();
                #add_headers
            }
        } else {
            TokenStream::new()
        };

        let create_http_request = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                let request_body = RequestBody(request.#field_name);

                let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
            }
        } else if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
            }
        } else {
            quote! {
                let mut http_request = ruma_api::exports::http::Request::new(Vec::new());
            }
        };

        let try_deserialize_response_body = if let Some(field) = self.response.newtype_body_field()
        {
            let field_type = &field.ty;

            quote! {
                ruma_api::exports::serde_json::from_slice::<#field_type>(http_response.into_body().as_slice())?
            }
        } else if self.response.has_body_fields() {
            quote! {
                ruma_api::exports::serde_json::from_slice::<ResponseBody>(http_response.into_body().as_slice())?
            }
        } else {
            quote! {
                ()
            }
        };

        let extract_response_headers = if self.response.has_header_fields() {
            quote! {
                let mut headers = http_response.headers().clone();
            }
        } else {
            TokenStream::new()
        };

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            TokenStream::new()
        };

        let request_doc = format!(
            "Data for a request to the `{}` API endpoint.\n\n{}",
            name,
            description.value()
        );
        let response_doc = format!("Data in the response from the `{}` API endpoint.", name);

        let api = quote! {
            use ruma_api::Endpoint as _;
            use ruma_api::exports::serde::Deserialize as _;
            use ruma_api::exports::serde::de::{Error as _, IntoDeserializer as _};

            use std::convert::{TryInto as _};

            #[doc = #request_doc]
            #request_types

            impl std::convert::TryFrom<Request> for ruma_api::exports::http::Request<Vec<u8>> {
                type Error = ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Request::METADATA;

                    // Use dummy homeserver url which has to be overwritten in
                    // the calling code. Previously (with http::Uri) this was
                    // not required, but Url::parse only accepts absolute urls.
                    let mut url = ruma_api::exports::url::Url::parse("http://invalid-host-please-change/").unwrap();

                    { #set_request_path }
                    { #set_request_query }

                    #create_http_request

                    *http_request.method_mut() = ruma_api::exports::http::Method::#method;
                    *http_request.uri_mut() = url.into_string().parse().unwrap();

                    { #add_headers_to_request }

                    Ok(http_request)
                }
            }

            #[doc = #response_doc]
            #response_types

            impl std::convert::TryFrom<ruma_api::exports::http::Response<Vec<u8>>> for Response {
                type Error = ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(http_response: ruma_api::exports::http::Response<Vec<u8>>) -> Result<Self, Self::Error> {
                    if http_response.status().is_success() {
                        #extract_response_headers

                        let response_body = #try_deserialize_response_body;
                        Ok(Response {
                            #response_init_fields
                        })
                    } else {
                        Err(http_response.status().clone().into())
                    }
                }
            }

            impl ruma_api::Endpoint for Request {
                type Response = Response;

                /// Metadata for the `#name` endpoint.
                const METADATA: ruma_api::Metadata = ruma_api::Metadata {
                    description: #description,
                    method: ruma_api::exports::http::Method::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        };

        api.to_tokens(tokens);
    }
}

/// Custom keyword macros for syn.
mod kw {
    use syn::custom_keyword;

    custom_keyword!(metadata);
    custom_keyword!(request);
    custom_keyword!(response);
}

/// The entire `ruma_api!` macro structure directly as it appears in the source code..
pub struct RawApi {
    /// The `metadata` section of the macro.
    pub metadata: Vec<FieldValue>,
    /// The `request` section of the macro.
    pub request: Vec<Field>,
    /// The `response` section of the macro.
    pub response: Vec<Field>,
}

impl Parse for RawApi {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        input.parse::<kw::metadata>()?;
        let metadata;
        braced!(metadata in input);

        input.parse::<kw::request>()?;
        let request;
        braced!(request in input);

        input.parse::<kw::response>()?;
        let response;
        braced!(response in input);

        Ok(Self {
            metadata: metadata
                .parse_terminated::<FieldValue, Token![,]>(FieldValue::parse)?
                .into_iter()
                .collect(),
            request: request
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
            response: response
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
        })
    }
}
<commit_msg>Disallow body fields in GET endpoints<commit_after>//! Details of the `ruma_api` procedural macro.

use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{
    braced,
    parse::{Parse, ParseStream, Result},
    Field, FieldValue, Ident, Meta, Token,
};

mod attribute;
mod metadata;
mod request;
mod response;

use self::{metadata::Metadata, request::Request, response::Response};

/// Removes `serde` attributes from struct fields.
pub fn strip_serde_attrs(field: &Field) -> Field {
    let mut field = field.clone();

    field.attrs = field
        .attrs
        .into_iter()
        .filter(|attr| {
            let meta = attr
                .parse_meta()
                .expect("ruma_api! could not parse field attributes");

            match meta {
                Meta::List(meta_list) => {
                    let segments = &meta_list.path.segments;
                    segments.len() != 1 || segments[0].ident != "serde"
                }
                _ => true,
            }
        })
        .collect();

    field
}

/// The result of processing the `ruma_api` macro, ready for output back to source code.
pub struct Api {
    /// The `metadata` section of the macro.
    metadata: Metadata,
    /// The `request` section of the macro.
    request: Request,
    /// The `response` section of the macro.
    response: Response,
}

impl From<RawApi> for Api {
    fn from(raw_api: RawApi) -> Self {
        let res = Self {
            metadata: raw_api.metadata.into(),
            request: raw_api.request.into(),
            response: raw_api.response.into(),
        };

        assert!(
            !(res.metadata.method == "GET"
                && (res.request.has_body_fields() || res.request.newtype_body_field().is_some())),
            "GET endpoints can't have body fields"
        );

        res
    }
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        // We don't (currently) use this literal as a literal in the generated code. Instead we just
        // put it into doc comments, for which the span information is irrelevant. So we can work
        // with only the literal's value from here on.
        let name = &self.metadata.name.value();
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request = &self.request;
        let request_types = quote! { #request };
        let response = &self.response;
        let response_types = quote! { #response };

        let set_request_path = if self.request.has_path_fields() {
            let path_str = path.value();

            assert!(path_str.starts_with('/'), "path needs to start with '/'");
            assert!(
                path_str.chars().filter(|c| *c == ':').count() == self.request.path_field_count(),
                "number of declared path parameters needs to match amount of placeholders in path"
            );

            let request_path_init_fields = self.request.request_path_init_fields();

            let path_segments = path_str[1..].split('/');
            let path_segment_push = path_segments.clone().map(|segment| {
                let arg = if segment.starts_with(':') {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    quote!(&request_path.#path_var_ident.to_string())
                } else {
                    quote!(#segment)
                };

                quote! {
                    path_segments.push(#arg);
                }
            });

            quote! {
                let request_path = RequestPath {
                    #request_path_init_fields
                };

                // This `unwrap()` can only fail when the url is a
                // cannot-be-base url like `mailto:` or `data:`, which is not
                // the case for our placeholder url.
                let mut path_segments = url.path_segments_mut().unwrap();
                #(#path_segment_push)*
            }
        } else {
            quote! {
                url.set_path(metadata.path);
            }
        };

        let set_request_query = if self.request.has_query_fields() {
            let request_query_init_fields = self.request.request_query_init_fields();

            quote! {
                let request_query = RequestQuery {
                    #request_query_init_fields
                };

                url.set_query(Some(&ruma_api::exports::serde_urlencoded::to_string(request_query)?));
            }
        } else {
            TokenStream::new()
        };

        let add_headers_to_request = if self.request.has_header_fields() {
            let add_headers = self.request.add_headers_to_request();
            quote! {
                let headers = http_request.headers_mut();
                #add_headers
            }
        } else {
            TokenStream::new()
        };

        let create_http_request = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                let request_body = RequestBody(request.#field_name);

                let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
            }
        } else if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                let mut http_request = ruma_api::exports::http::Request::new(ruma_api::exports::serde_json::to_vec(&request_body)?);
            }
        } else {
            quote! {
                let mut http_request = ruma_api::exports::http::Request::new(Vec::new());
            }
        };

        let try_deserialize_response_body = if let Some(field) = self.response.newtype_body_field()
        {
            let field_type = &field.ty;

            quote! {
                ruma_api::exports::serde_json::from_slice::<#field_type>(http_response.into_body().as_slice())?
            }
        } else if self.response.has_body_fields() {
            quote! {
                ruma_api::exports::serde_json::from_slice::<ResponseBody>(http_response.into_body().as_slice())?
            }
        } else {
            quote! {
                ()
            }
        };

        let extract_response_headers = if self.response.has_header_fields() {
            quote! {
                let mut headers = http_response.headers().clone();
            }
        } else {
            TokenStream::new()
        };

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            TokenStream::new()
        };

        let request_doc = format!(
            "Data for a request to the `{}` API endpoint.\n\n{}",
            name,
            description.value()
        );
        let response_doc = format!("Data in the response from the `{}` API endpoint.", name);

        let api = quote! {
            use ruma_api::Endpoint as _;
            use ruma_api::exports::serde::Deserialize as _;
            use ruma_api::exports::serde::de::{Error as _, IntoDeserializer as _};

            use std::convert::{TryInto as _};

            #[doc = #request_doc]
            #request_types

            impl std::convert::TryFrom<Request> for ruma_api::exports::http::Request<Vec<u8>> {
                type Error = ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Request::METADATA;

                    // Use dummy homeserver url which has to be overwritten in
                    // the calling code. Previously (with http::Uri) this was
                    // not required, but Url::parse only accepts absolute urls.
                    let mut url = ruma_api::exports::url::Url::parse("http://invalid-host-please-change/").unwrap();

                    { #set_request_path }
                    { #set_request_query }

                    #create_http_request

                    *http_request.method_mut() = ruma_api::exports::http::Method::#method;
                    *http_request.uri_mut() = url.into_string().parse().unwrap();

                    { #add_headers_to_request }

                    Ok(http_request)
                }
            }

            #[doc = #response_doc]
            #response_types

            impl std::convert::TryFrom<ruma_api::exports::http::Response<Vec<u8>>> for Response {
                type Error = ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(http_response: ruma_api::exports::http::Response<Vec<u8>>) -> Result<Self, Self::Error> {
                    if http_response.status().is_success() {
                        #extract_response_headers

                        let response_body = #try_deserialize_response_body;
                        Ok(Response {
                            #response_init_fields
                        })
                    } else {
                        Err(http_response.status().clone().into())
                    }
                }
            }

            impl ruma_api::Endpoint for Request {
                type Response = Response;

                /// Metadata for the `#name` endpoint.
                const METADATA: ruma_api::Metadata = ruma_api::Metadata {
                    description: #description,
                    method: ruma_api::exports::http::Method::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        };

        api.to_tokens(tokens);
    }
}

/// Custom keyword macros for syn.
mod kw {
    use syn::custom_keyword;

    custom_keyword!(metadata);
    custom_keyword!(request);
    custom_keyword!(response);
}

/// The entire `ruma_api!` macro structure directly as it appears in the source code..
pub struct RawApi {
    /// The `metadata` section of the macro.
    pub metadata: Vec<FieldValue>,
    /// The `request` section of the macro.
    pub request: Vec<Field>,
    /// The `response` section of the macro.
    pub response: Vec<Field>,
}

impl Parse for RawApi {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        input.parse::<kw::metadata>()?;
        let metadata;
        braced!(metadata in input);

        input.parse::<kw::request>()?;
        let request;
        braced!(request in input);

        input.parse::<kw::response>()?;
        let response;
        braced!(response in input);

        Ok(Self {
            metadata: metadata
                .parse_terminated::<FieldValue, Token![,]>(FieldValue::parse)?
                .into_iter()
                .collect(),
            request: request
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
            response: response
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example for ClassedHTMLGenerator<commit_after>//! Prints highlighted HTML with CSS classes for a Rust and a C++ file to stdout.
//! Run with ```cargo run --example synhtml-css-classes```
use syntect::html::ClassedHTMLGenerator;
use syntect::parsing::SyntaxSet;

fn main() {
    let ss = SyntaxSet::load_defaults_newlines();

    // Rust
    let code_rs = "// Rust source
    fn main() {
        println!(\"Hello World!\");
    }";

    let sr_rs = ss.find_syntax_by_extension("rs").unwrap();
    let mut html_generator = ClassedHTMLGenerator::new(&sr_rs, &ss);
    for line in code_rs.lines() {
        html_generator.parse_html_for_line(&line);
    }
    let html = html_generator.finalize();
    println!("{}", html);

    println!("");

    // C++
    let code_cpp = "// C++ source
    #include <iostream>
    int main() {
        std::cout << \"Hello World!\" << std::endl;
    }";

    let sr_cpp = ss.find_syntax_by_extension("cpp").unwrap();
    let mut html_generator = ClassedHTMLGenerator::new(&sr_cpp, &ss);
    for line in code_cpp.lines() {
        html_generator.parse_html_for_line(&line);
    }
    let html = html_generator.finalize();
    println!("{}", html);
}
<|endoftext|>