<commit_before>#[derive(Debug)]
struct Node {
    next: Option<Box<Node>>,
    data: Option<i32>,
}

#[derive(Debug)]
struct List {
    head: Option<Box<Node>>,
    length: i32,
}

impl Node {
    fn new() -> Node {
        Node {
            next: None,
            data: None,
        }
    }

    fn new_with_data(d: i32) -> Node {
        Node {
            next: None,
            data: Some(d),
        }
    }
}

impl List {
    fn new() -> List {
        List {
            head: None,
            length: 0,
        }
    }

    fn push_front(&mut self, d: i32) {
        let mut node = Node::new_with_data(d);
        let head = self.head.take();
        match head {
            Some(t) =>
                { node.next = Some(t); self.head = Some(Box::new(node)); self.length += 1; }
            None => { self.head = Some(Box::new(node)); self.length += 1; }
        }
    }

    fn pop_front(&mut self) {
        self.head.take().map(|node| {
            self.head = node.next;
        });
        self.length -= 1;
    }
}

fn main() {
    let mut list = List::new();
    list.push_front(1);
    list.push_front(2);
    list.push_front(3);
    list.pop_front();
    println!("{:?}", list)
}
<commit_msg>some modify<commit_after>#[derive(Debug)]
struct Node {
    next: Option<Box<Node>>,
    data: Option<i32>,
}

#[derive(Debug)]
struct List {
    head: Option<Box<Node>>,
    length: u32,
}

impl Node {
    fn new() -> Node {
        Node {
            next: None,
            data: None,
        }
    }

    fn new_with_data(d: i32) -> Node {
        Node {
            next: None,
            data: Some(d),
        }
    }
}

impl List {
    fn new() -> List {
        List {
            head: None,
            length: 0,
        }
    }

    fn push(&mut self, d: i32) {
        let mut node = Node::new_with_data(d);
        let head = self.head.take();
        match head {
            Some(t) =>
                { node.next = Some(t); self.head = Some(Box::new(node)); self.length += 1; }
            None => { self.head = Some(Box::new(node)); self.length += 1; }
        }
    }

    fn pop(&mut self) {
        self.head.take().map(|node| {
            self.head = node.next;
        });
        self.length -= 1;
    }
}

fn main() {
    let mut list = List::new();
    list.push(1);
    list.push(2);
    list.push(3);
    list.pop();
    println!("{:?}", list)
}
<|endoftext|>


<commit_before>use std::fs;
use std::env;
use std::path::Path;

fn main() {
    let tab: Vec<_> = env::args().collect();

    if tab.len()==1 {
        for entry in fs::read_dir("./").unwrap() {
            match entry {
                Ok(n) => println!("> {:?}", n.path()),
                Err(err) => println!("Error: {}", err),
            }
        }
    } else {
        for n in tab[1..].iter() {
            let dir = Path::new(n);
            if dir.is_dir() {
                for entry in fs::read_dir(dir).unwrap() {
                    match entry {
                        Ok(i) => println!("> {:?}", i.path()),
                        Err(err) => println!("Err: {}", err),
                    }
                }
            } else {
                println!("{:?} unknown file or directory", dir);
            }
        }
    }
}
<commit_msg>exit program in case of no file found<commit_after>use std::fs;
use std::env;
use std::path::Path;
use std::process;

fn main() {
    let tab: Vec<_> = env::args().collect();

    if tab.len()==1 {
        for entry in fs::read_dir("./").unwrap() {
            match entry {
                Ok(n) => println!("> {:?}", n.path()),
                Err(err) => println!("Error: {}", err),
            }
        }
    } else {
        for n in tab[1..].iter() {
            let dir = Path::new(n);
            if dir.is_dir() {
                for entry in fs::read_dir(dir).unwrap() {
                    match entry {
                        Ok(i) => println!("> {:?}", i.path()),
                        Err(err) => println!("Err: {}", err),
                    }
                }
            } else {
                println!("{:?} unknown file or directory", dir);
                process::exit(1);
            }
        }
    }
}
<|endoftext|>


<commit_before>use piston_window;
use gfx_device_gl::{Resources, Output, CommandBuffer};
use gfx_graphics::GfxGraphics;
use piston_window::Transformed;

pub struct Object {
    x: f64,
    y: f64,
    sprite: Option<piston_window::Texture<Resources>>,
}

impl Object {
    pub fn new() -> Object {
        Object { x: 0., y: 0., sprite: None }
    }

    pub fn mov(&mut self, x: f64, y: f64) {
        self.x += x;
        self.y += y;
    }

    pub fn mov_to(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }

    pub fn set_sprite(&mut self, sprite: piston_window::Texture<Resources>) {
        self.sprite = Some(sprite);
    }

    pub fn render(&self, graphic: &mut GfxGraphics<Resources, CommandBuffer<Resources>, Output>, view: &piston_window::math::Matrix2d) {
        match self.sprite {
            None => {
                let red = [1.0, 0.0, 0.0, 1.0];
                let square = piston_window::rectangle::square(0.0, 0.0, 100.0);
                piston_window::rectangle(red, square, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
            Some(ref sprite) => {
                piston_window::image(sprite, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
        }
    }
}

#[test]
fn object_new() {
    let object = Object::new();
    assert_eq!(object.x, 0.0);
    assert_eq!(object.y, 0.0);
}

#[test]
fn object_mov() {
    let mut object = Object::new();
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov(0., 0.);
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov(1., 1.);
    assert_eq!(object.x, 1.);
    assert_eq!(object.y, 1.);

    object.mov(-3., -3.);
    assert_eq!(object.x, -2.);
    assert_eq!(object.y, -2.);
}

#[test]
fn object_mov_to() {
    let mut object = Object::new();
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov_to(0., 0.);
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov_to(10., 10.);
    assert_eq!(object.x, 10.);
    assert_eq!(object.y, 10.);

    object.mov_to(-30., -30.);
    assert_eq!(object.x, -30.);
    assert_eq!(object.y, -30.);
}
<commit_msg>use ImageSize<commit_after>use piston_window;
use gfx_device_gl::{Resources, Output, CommandBuffer};
use gfx_graphics::GfxGraphics;

use piston_window::Transformed;
use piston_window::ImageSize;

pub struct Object {
    x: f64,
    y: f64,
    sprite: Option<piston_window::Texture<Resources>>,
}

impl Object {
    pub fn new() -> Object {
        Object { x: 0., y: 0., sprite: None }
    }

    pub fn mov(&mut self, x: f64, y: f64) {
        self.x += x;
        self.y += y;
    }

    pub fn mov_to(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }

    pub fn set_sprite(&mut self, sprite: piston_window::Texture<Resources>) {
        self.sprite = Some(sprite);
    }

    pub fn render(&self, graphic: &mut GfxGraphics<Resources, CommandBuffer<Resources>, Output>, view: &piston_window::math::Matrix2d) {
        match self.sprite {
            None => {
                let red = [1.0, 0.0, 0.0, 1.0];
                let square = piston_window::rectangle::square(0.0, 0.0, 100.0);
                piston_window::rectangle(red, square, view.trans(self.x, self.y).trans(-50.0, -50.0), graphic);
            }
            Some(ref sprite) => {
                let (x, y) = sprite.get_size();
                let (x, y) = (x / 2, y / 2);
                piston_window::image(sprite, view.trans(self.x, self.y).trans(-(x as f64), -(y as f64)), graphic);
            }
        }
    }
}

#[test]
fn object_new() {
    let object = Object::new();
    assert_eq!(object.x, 0.0);
    assert_eq!(object.y, 0.0);
}

#[test]
fn object_mov() {
    let mut object = Object::new();
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov(0., 0.);
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov(1., 1.);
    assert_eq!(object.x, 1.);
    assert_eq!(object.y, 1.);

    object.mov(-3., -3.);
    assert_eq!(object.x, -2.);
    assert_eq!(object.y, -2.);
}

#[test]
fn object_mov_to() {
    let mut object = Object::new();
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov_to(0., 0.);
    assert_eq!(object.x, 0.);
    assert_eq!(object.y, 0.);

    object.mov_to(10., 10.);
    assert_eq!(object.x, 10.);
    assert_eq!(object.y, 10.);

    object.mov_to(-30., -30.);
    assert_eq!(object.x, -30.);
    assert_eq!(object.y, -30.);
}
<|endoftext|>


<commit_before>/*
ゴール：
1. データをコピーしなくても、greetを呼び出せるようにしてください
2. "Hello dear rustecians"ではなく、"Hello rustecians"となるように、
   2回目のgreetの呼び出しを行なってください
3. 2をスライスを使って実現してください
*/

fn main() {
    let name = format!("dear rustecians");
    greet(name.clone());
    greet(name);
}

fn greet(name: String) {
    println!("Hello {}", name);
}

<commit_msg>Rustecians -> rustaceans<commit_after>/*
ゴール：
1. データをコピーしなくても、greetを呼び出せるようにしてください
2. "Hello dear rustaceans"ではなく、"Hello rustaceans"となるように、
   2回目のgreetの呼び出しを行なってください
3. 2をスライスを使って実現してください
*/

fn main() {
    let name = format!("dear rustaceans");
    greet(name.clone());
    greet(name);
}

fn greet(name: String) {
    println!("Hello {}", name);
}

<|endoftext|>


<commit_before>use std;
use std::path::Path;

use sdl2::event::Event;
use sdl2::gfx::primitives::DrawRenderer;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::{Point, Rect};
use sdl2::render::{BlendMode, Renderer, Texture, TextureQuery};
use sdl2::surface::Surface;
use sdl2::ttf::{Font, Sdl2TtfContext, STYLE_BOLD};

use position::Position;
use text::Text;

const BORDER_COLOR: Color = Color::RGBA(255, 255, 255, 64);

const PADDING: i32 = 10;

const FONT_FILE: &'static str = "../assets/FantasqueSansMono-Bold.ttf";
const FONT_COLOR: Color = Color::RGBA(45, 200, 45, 255);
const FONT_SIZE: u16 = 18;

pub struct Console<'a> {
    pub visible: bool,

    leader: Text,
    input_buffer: String,
    last_command: String,
    command_history: Vec<String>,
    cursor_position: usize,
    buffer: Vec<String>,
    backbuffer_y: i32,
    texture: Texture,
    backbuffer_texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
    size: (u32, u32),
    font: Font<'a>,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, mut renderer: &mut Renderer) -> Console<'a> {
        let (width, height) = renderer.window().unwrap().size();
        let mut texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, width / 2, height)
                .unwrap();
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..height {
                    for x in 0..width / 2 {
                        let x = x as usize;
                        let y = y as usize;
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut backbuffer_texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, width / 2, height)
                .unwrap();
        backbuffer_texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..height {
                    for x in 0..width / 2 {
                        let x = x as usize;
                        let y = y as usize;
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut font = ttf_context.load_font(Path::new(FONT_FILE), FONT_SIZE).unwrap();
        font.set_style(STYLE_BOLD);

        Console {
            visible: false,
            leader: Text::new(&ttf_context,
                              &mut renderer,
                              "hakka>",
                              Position::XY(PADDING, height as i32 - FONT_SIZE as i32 - PADDING),
                              FONT_SIZE,
                              FONT_COLOR,
                              FONT_FILE),
            input_buffer: "".into(),
            last_command: "".into(),
            command_history: Vec::new(),
            cursor_position: 0,
            buffer: Vec::new(),
            backbuffer_y: 0,
            texture: texture,
            backbuffer_texture: backbuffer_texture,
            ttf_context: ttf_context,
            size: (width / 2, height),
            font: font,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::TextInput { ref text, .. } => {
                if self.visible {
                    if text == "`" {
                        return;
                    }
                    self.add_text(text);
                }
            }
            &Event::MouseWheel { y, .. } => {
                if self.visible {
                    if self.buffer.len() * FONT_SIZE as usize >
                       (self.size.1 - (FONT_SIZE as u32 * 2)) as usize {
                        self.backbuffer_y += y * 2;
                        if self.backbuffer_y < 0 {
                            self.backbuffer_y = 0;
                        }
                    }
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => {
                if self.visible {
                    self.cursor_left();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => {
                if self.visible {
                    self.cursor_right();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Return), .. } => {
                if self.visible {
                    self.commit();
                }
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Backspace), .. } => {
                if self.visible {
                    self.backspace();
                }
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Delete), .. } => {
                if self.visible {
                    if self.cursor_position < self.input_buffer.len() {
                        self.cursor_position += 1;
                        self.backspace();
                    }
                }
            }
            _ => (),
        }
    }

    pub fn process_command(&mut self) {
        let command = self.input_buffer.clone();
        self.command_history.push(command.clone());
        self.last_command = command.clone();

        if command == "exit" {
            std::process::exit(0);
        }
    }

    pub fn clear(&mut self) {
        self.buffer.clear();
    }

    pub fn try_process_command(&mut self) -> Option<String> {
        if self.last_command.len() > 0 {
            let cmd = self.last_command.clone();
            self.last_command.clear();
            Some(cmd)
        } else {
            None
        }
    }

    pub fn print<S>(&mut self, text: S)
        where S: Into<String>
    {
        for line in text.into().lines() {
            self.println(line);
        }
    }

    pub fn println<S>(&mut self, text: S)
        where S: Into<String>
    {
        self.buffer.push(text.into());
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        self.input_buffer.insert(self.cursor_position, input.chars().next().unwrap());
        self.cursor_position += 1;
    }

    pub fn commit(&mut self) {
        self.buffer.push(format!("hakka> {}", self.input_buffer.clone()));
        self.process_command();
        self.input_buffer.clear();
        self.cursor_position = 0;
    }

    pub fn cursor_left(&mut self) {
        if self.cursor_position > 0 {
            self.cursor_position -= 1;
        }
    }

    pub fn cursor_right(&mut self) {
        if self.cursor_position < self.input_buffer.len() {
            self.cursor_position += 1;
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            if self.cursor_position > 0 {
                self.input_buffer.remove(self.cursor_position - 1);
                self.cursor_position -= 1;
            }
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture,
                      None,
                      Some(Rect::new(0, 0, self.size.0, self.size.1)))
                .unwrap();
            self.render_leader(&mut renderer);
            self.generate_backbuffer_texture(&mut renderer);

            // Insert the cursor via a dodgy vertical line
            let mut output_text = self.input_buffer.clone();
            let cursor_x =
                60 + PADDING as i16 +
                self.font.size_of(&self.input_buffer[..self.cursor_position]).unwrap().0 as i16;
            // Draw a dodgy cursor
            renderer.thick_line(cursor_x,
                            self.size.1 as i16 - FONT_SIZE as i16 - PADDING as i16,
                            cursor_x,
                            self.size.1 as i16 - PADDING as i16,
                            1,
                            FONT_COLOR)
                .unwrap();

            if output_text.len() > 0 {
                let text = Text::new(&self.ttf_context,
                                     &mut renderer,
                                     &output_text[..],
                                     Position::XY(60 + PADDING,
                                                  self.size.1 as i32 - FONT_SIZE as i32 - PADDING),
                                     FONT_SIZE,
                                     FONT_COLOR,
                                     FONT_FILE);
                text.render(&mut renderer);
            }

            self.render_border(&mut renderer);
        }
    }

    fn render_border(&self, mut renderer: &mut Renderer) {
        // Render the border
        renderer.set_draw_color(Color::RGBA(255, 255, 255, 255));
        // North
        renderer.thick_line(0, 0, self.size.0 as i16, 0, 1, BORDER_COLOR);

        // East
        renderer.thick_line(self.size.0 as i16,
                            0,
                            self.size.0 as i16,
                            self.size.1 as i16,
                            1,
                            BORDER_COLOR);

        // South
        renderer.thick_line(0,
                            self.size.1 as i16 - 1,
                            self.size.0 as i16,
                            self.size.1 as i16 - 1,
                            1,
                            BORDER_COLOR);
    }

    fn render_leader(&self, mut renderer: &mut Renderer) {
        self.leader.render(&mut renderer);
    }

    fn generate_backbuffer_texture(&mut self, mut renderer: &mut Renderer) {
        let mut main_surface = Surface::new(self.size.0,
                                            (self.size.1 - (FONT_SIZE as u32)),
                                            PixelFormatEnum::RGBA8888)
            .unwrap();
        let mut counter = 2;
        for line in self.buffer.iter().rev().take(100) {
            let mut y_pos = self.size.1 as i32 - (FONT_SIZE as i32 * counter) + self.backbuffer_y;
            counter += 1;

            if line.trim().len() == 0 {
                continue;
            }

            let surface = self.font
                .render(&line)
                .blended(FONT_COLOR)
                .unwrap();
            surface.blit(None,
                      &mut main_surface,
                      Some(Rect::new(PADDING, y_pos - PADDING, self.size.1, FONT_SIZE as u32)))
                .unwrap();
        }
        let texture = renderer.create_texture_from_surface(&main_surface)
            .unwrap();

        let TextureQuery { width, height, .. } = texture.query();

        renderer.copy(&texture, None, Some(Rect::new(0, 0, width, height)));
    }
}<commit_msg>Clean up console input processing<commit_after>use std;
use std::path::Path;

use sdl2::event::Event;
use sdl2::gfx::primitives::DrawRenderer;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::{Point, Rect};
use sdl2::render::{BlendMode, Renderer, Texture, TextureQuery};
use sdl2::surface::Surface;
use sdl2::ttf::{Font, Sdl2TtfContext, STYLE_BOLD};

use position::Position;
use text::Text;

const BORDER_COLOR: Color = Color::RGBA(255, 255, 255, 64);

const PADDING: i32 = 10;

const FONT_FILE: &'static str = "../assets/FantasqueSansMono-Bold.ttf";
const FONT_COLOR: Color = Color::RGBA(45, 200, 45, 255);
const FONT_SIZE: u16 = 18;

pub struct Console<'a> {
    pub visible: bool,

    leader: Text,
    input_buffer: String,
    last_command: String,
    command_history: Vec<String>,
    history_position: usize,
    cursor_position: usize,
    buffer: Vec<String>,
    backbuffer_y: i32,
    texture: Texture,
    backbuffer_texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
    size: (u32, u32),
    font: Font<'a>,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, mut renderer: &mut Renderer) -> Console<'a> {
        let (width, height) = renderer.window().unwrap().size();
        let mut texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, width / 2, height)
                .unwrap();
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..height {
                    for x in 0..width / 2 {
                        let x = x as usize;
                        let y = y as usize;
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut backbuffer_texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, width / 2, height)
                .unwrap();
        backbuffer_texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..height {
                    for x in 0..width / 2 {
                        let x = x as usize;
                        let y = y as usize;
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut font = ttf_context.load_font(Path::new(FONT_FILE), FONT_SIZE).unwrap();
        font.set_style(STYLE_BOLD);

        Console {
            visible: false,
            leader: Text::new(&ttf_context,
                              &mut renderer,
                              "hakka>",
                              Position::XY(PADDING, height as i32 - FONT_SIZE as i32 - PADDING),
                              FONT_SIZE,
                              FONT_COLOR,
                              FONT_FILE),
            input_buffer: "".into(),
            last_command: "".into(),
            command_history: Vec::new(),
            history_position: 0,
            cursor_position: 0,
            buffer: Vec::new(),
            backbuffer_y: 0,
            texture: texture,
            backbuffer_texture: backbuffer_texture,
            ttf_context: ttf_context,
            size: (width / 2, height),
            font: font,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::TextInput { ref text, .. } => {
                if self.visible {
                    if text == "`" {
                        return;
                    }
                    self.add_text(text);
                }
            }
            &Event::MouseWheel { y, .. } => {
                if self.visible {
                    if self.buffer.len() * FONT_SIZE as usize >
                       (self.size.1 - (FONT_SIZE as u32 * 2)) as usize {
                        self.backbuffer_y += y * 2;
                        if self.backbuffer_y < 0 {
                            self.backbuffer_y = 0;
                        }
                    }
                }
            }
            &Event::KeyUp { keycode, .. } => {
                if self.visible {
                    match keycode {
                        Some(Keycode::Left) => {
                            self.cursor_left();
                        }
                        Some(Keycode::Right) => {
                            self.cursor_right();
                        }
                        Some(Keycode::Return) => {
                            self.commit();
                        }
                        Some(Keycode::Backspace) => {
                            self.backspace();
                        }
                        Some(Keycode::Delete) => {
                            if self.cursor_position < self.input_buffer.len() {
                                self.cursor_position += 1;
                                self.backspace();
                            }
                        }
                        _ => (),
                    }
                }
            }
            _ => (),
        }
    }

    pub fn process_command(&mut self) {
        let command = self.input_buffer.clone();
        self.command_history.push(command.clone());
        self.last_command = command.clone();

        if command == "exit" {
            std::process::exit(0);
        }
    }

    pub fn clear(&mut self) {
        self.buffer.clear();
    }

    pub fn try_process_command(&mut self) -> Option<String> {
        if self.last_command.len() > 0 {
            let cmd = self.last_command.clone();
            self.last_command.clear();
            Some(cmd)
        } else {
            None
        }
    }

    pub fn print<S>(&mut self, text: S)
        where S: Into<String>
    {
        for line in text.into().lines() {
            self.println(line);
        }
    }

    pub fn println<S>(&mut self, text: S)
        where S: Into<String>
    {
        self.buffer.push(text.into());
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        self.input_buffer.insert(self.cursor_position, input.chars().next().unwrap());
        self.cursor_position += 1;
    }

    pub fn commit(&mut self) {
        self.buffer.push(format!("hakka> {}", self.input_buffer.clone()));
        self.process_command();
        self.input_buffer.clear();
        self.cursor_position = 0;
    }

    pub fn cursor_left(&mut self) {
        if self.cursor_position > 0 {
            self.cursor_position -= 1;
        }
    }

    pub fn cursor_right(&mut self) {
        if self.cursor_position < self.input_buffer.len() {
            self.cursor_position += 1;
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            if self.cursor_position > 0 {
                self.input_buffer.remove(self.cursor_position - 1);
                self.cursor_position -= 1;
            }
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture,
                      None,
                      Some(Rect::new(0, 0, self.size.0, self.size.1)))
                .unwrap();
            self.render_leader(&mut renderer);
            self.generate_backbuffer_texture(&mut renderer);

            // Insert the cursor via a dodgy vertical line
            let mut output_text = self.input_buffer.clone();
            let cursor_x =
                60 + PADDING as i16 +
                self.font.size_of(&self.input_buffer[..self.cursor_position]).unwrap().0 as i16;
            // Draw a dodgy cursor
            renderer.thick_line(cursor_x,
                            self.size.1 as i16 - FONT_SIZE as i16 - PADDING as i16,
                            cursor_x,
                            self.size.1 as i16 - PADDING as i16,
                            1,
                            FONT_COLOR)
                .unwrap();

            if output_text.len() > 0 {
                let text = Text::new(&self.ttf_context,
                                     &mut renderer,
                                     &output_text[..],
                                     Position::XY(60 + PADDING,
                                                  self.size.1 as i32 - FONT_SIZE as i32 - PADDING),
                                     FONT_SIZE,
                                     FONT_COLOR,
                                     FONT_FILE);
                text.render(&mut renderer);
            }

            self.render_border(&mut renderer);
        }
    }

    fn render_border(&self, mut renderer: &mut Renderer) {
        // Render the border
        renderer.set_draw_color(Color::RGBA(255, 255, 255, 255));
        // North
        renderer.thick_line(0, 0, self.size.0 as i16, 0, 1, BORDER_COLOR);

        // East
        renderer.thick_line(self.size.0 as i16,
                            0,
                            self.size.0 as i16,
                            self.size.1 as i16,
                            1,
                            BORDER_COLOR);

        // South
        renderer.thick_line(0,
                            self.size.1 as i16 - 1,
                            self.size.0 as i16,
                            self.size.1 as i16 - 1,
                            1,
                            BORDER_COLOR);
    }

    fn render_leader(&self, mut renderer: &mut Renderer) {
        self.leader.render(&mut renderer);
    }

    fn generate_backbuffer_texture(&mut self, mut renderer: &mut Renderer) {
        let mut main_surface = Surface::new(self.size.0,
                                            (self.size.1 - (FONT_SIZE as u32)),
                                            PixelFormatEnum::RGBA8888)
            .unwrap();
        let mut counter = 2;
        for line in self.buffer.iter().rev().take(100) {
            let mut y_pos = self.size.1 as i32 - (FONT_SIZE as i32 * counter) + self.backbuffer_y;
            counter += 1;

            if line.trim().len() == 0 {
                continue;
            }

            let surface = self.font
                .render(&line)
                .blended(FONT_COLOR)
                .unwrap();
            surface.blit(None,
                      &mut main_surface,
                      Some(Rect::new(PADDING, y_pos - PADDING, self.size.1, FONT_SIZE as u32)))
                .unwrap();
        }
        let texture = renderer.create_texture_from_surface(&main_surface)
            .unwrap();

        let TextureQuery { width, height, .. } = texture.query();

        renderer.copy(&texture, None, Some(Rect::new(0, 0, width, height)));
    }
}<|endoftext|>


<commit_before>///! Encoding-decoding tests
///!
///! These integration tests check that for each format the
///! `encode` and `decode` functions are consistent by doing a
///! round trip conversion of arbitrary instances of nodes.
///!
///! Uses `serde_json::to_value` for assertions because currently unable
///! to compare nodes directly. `serde_json::Value` provides most readable
///! way to compare.
use pretty_assertions::assert_eq;
use proptest::prelude::*;
use stencila::methods::{decode, encode};

mod strategies;
use strategies::{article, node, Freedom};

proptest! {
    // Tests for generic data serialization formats

    // Given the high confidence for encoding/decoding for the
    // following formats the number of test cases is minimal
    #![proptest_config(ProptestConfig::with_cases(5))]

    #[test]
    fn json(input in node(Freedom::Max)) {
        let content = encode::json::encode(&input).unwrap();
        let output = decode::json::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[test]
    fn yaml(input in node(Freedom::Max)) {
        let content = encode::yaml::encode(&input).unwrap();
        let output = decode::yaml::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for article formats

    // Given the relatively high randomness and complexity of each input
    // we reduce the number of test cases from the default of 256
    #![proptest_config(ProptestConfig::with_cases(100))]

    #[test]
    fn html(input in article(Freedom::Max)) {
        let content = encode::html::encode(&input).unwrap();
        let output = decode::html::decode(&content, decode::html::Options::default()).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[ignore]
    #[test]
    fn md(input in article(Freedom::Min)) {
        let content = encode::md::encode(&input).unwrap();
        let output = decode::md::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[ignore]
    #[test]
    fn pandoc(input in article(Freedom::Min)) {
        let pandoc = encode::pandoc::encode_node(&input).unwrap();
        let output = decode::pandoc::decode_pandoc(pandoc, &decode::pandoc::Options::default()).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

}
<commit_msg>test(Ende): Fix call<commit_after>///! Encoding-decoding tests
///!
///! These integration tests check that for each format the
///! `encode` and `decode` functions are consistent by doing a
///! round trip conversion of arbitrary instances of nodes.
///!
///! Uses `serde_json::to_value` for assertions because currently unable
///! to compare nodes directly. `serde_json::Value` provides most readable
///! way to compare.
use pretty_assertions::assert_eq;
use proptest::prelude::*;
use stencila::methods::{decode, encode};

mod strategies;
use strategies::{article, node, Freedom};

proptest! {
    // Tests for generic data serialization formats

    // Given the high confidence for encoding/decoding for the
    // following formats the number of test cases is minimal
    #![proptest_config(ProptestConfig::with_cases(5))]

    #[test]
    fn json(input in node(Freedom::Max)) {
        let content = encode::json::encode(&input).unwrap();
        let output = decode::json::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[test]
    fn yaml(input in node(Freedom::Max)) {
        let content = encode::yaml::encode(&input).unwrap();
        let output = decode::yaml::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for article formats

    // Given the relatively high randomness and complexity of each input
    // we reduce the number of test cases from the default of 256
    #![proptest_config(ProptestConfig::with_cases(100))]

    #[test]
    fn html(input in article(Freedom::Max)) {
        let content = encode::html::encode(&input, false, "").unwrap();
        let output = decode::html::decode(&content, decode::html::Options::default()).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[ignore]
    #[test]
    fn md(input in article(Freedom::Min)) {
        let content = encode::md::encode(&input).unwrap();
        let output = decode::md::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[ignore]
    #[test]
    fn pandoc(input in article(Freedom::Min)) {
        let pandoc = encode::pandoc::encode_node(&input).unwrap();
        let output = decode::pandoc::decode_pandoc(pandoc, &decode::pandoc::Options::default()).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

}
<|endoftext|>


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

use libc::{c_int};
use std::mem;
use std::slice;
use string::cef_string_utf16_set;
use types::{cef_string_list_t,cef_string_t};

use rustc_unicode::str::Utf16Encoder;

fn string_list_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<String> {
    lt as *mut Vec<String>
}

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    unsafe {
         let lt: Box<Vec<String>> = box vec!();
         mem::transmute(lt)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if lt.is_null() { return 0; }
        let v = string_list_to_vec(lt);
        (*v).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if lt.is_null() { return; }
        let v = string_list_to_vec(lt);
        (*v).push(String::from_utf16(slice::from_raw_parts((*value).str, (*value).length as usize)).unwrap());
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || lt.is_null() { return 0; }
        let v = string_list_to_vec(lt);
        if index as usize > (*v).len() - 1 { return 0; }
        let ref string = (*v)[index as usize];
        let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect();
        cef_string_utf16_set(mem::transmute(utf16_chars.as_ptr()), utf16_chars.len() as u64, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        let v = string_list_to_vec(lt);
        (*v).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        let v: Box<Vec<String>> = mem::transmute(lt);
        cef_string_list_clear(lt);
        drop(v);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if lt.is_null() { return 0 as *mut cef_string_list_t; }
        let v = string_list_to_vec(lt);
        let copy = (*v).clone();
        mem::transmute(box copy)
    }
}
<commit_msg>Use Box and boxed functions to manage cef_string_list_t memory.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use libc::{c_int};
use std::boxed;
use std::mem;
use std::slice;
use string::cef_string_utf16_set;
use types::{cef_string_list_t,cef_string_t};

use rustc_unicode::str::Utf16Encoder;

fn string_list_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<String> {
    lt as *mut Vec<String>
}

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    boxed::into_raw(box vec!())
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if lt.is_null() { return 0; }
        let v = string_list_to_vec(lt);
        (*v).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if lt.is_null() { return; }
        let v = string_list_to_vec(lt);
        (*v).push(String::from_utf16(slice::from_raw_parts((*value).str, (*value).length as usize)).unwrap());
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || lt.is_null() { return 0; }
        let v = string_list_to_vec(lt);
        if index as usize > (*v).len() - 1 { return 0; }
        let ref string = (*v)[index as usize];
        let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect();
        cef_string_utf16_set(mem::transmute(utf16_chars.as_ptr()), utf16_chars.len() as u64, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        let v = string_list_to_vec(lt);
        (*v).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        cef_string_list_clear(lt);
        drop(Box::from_raw(lt));
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if lt.is_null() { return 0 as *mut cef_string_list_t; }
        let v = string_list_to_vec(lt);
        let copy = (*v).clone();
        boxed::into_raw(box copy)
    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::fmt;
use std::hash::{Hash, Hasher};

use super::inputs::{Input, position, Position, Span};

/// An `enum` which defines possible errors.
#[derive(Debug)]
pub enum Error<R, I: Input> {
    /// Generated parsing error with expected and unexpected `Rule`s and a position
    ParsingError {
        /// Positive attempts
        positives: Vec<R>,
        /// Negative attempts
        negatives: Vec<R>,
        /// Deepest position of attempts
        pos: Position<I>
    },
    /// Custom error with a message and a position
    CustomErrorPos {
        /// Short explanation
        message: String,
        /// Error `Position` for formatting
        pos: Position<I>
    },
    /// Custom error with a message and a span defined by a start and end position
    CustomErrorSpan {
        /// Short explanation
        message: String,
        /// Error `Span` for formatting
        span: Span<I>
    }
}

fn message<R: fmt::Debug, I: Input>(error: &Error<R, I>) -> String {
    match *error {
        Error::ParsingError { ref positives, ref negatives, .. } => {
            match (negatives.is_empty(), positives.is_empty()) {
                (false, false) => {
                    format!(
                        "unexpected {}; expected {}",
                        enumerate(negatives),
                        enumerate(positives)
                    )
                }
                (false, true) => format!("unexpected {}", enumerate(negatives)),
                (true, false) => format!("expected {}", enumerate(positives)),
                (true, true) => "unknown parsing error".to_owned()
            }
        }
        Error::CustomErrorPos { ref message, .. } => message.to_owned(),
        Error::CustomErrorSpan { ref message, .. } => message.to_owned()
    }
}

fn enumerate<R: fmt::Debug>(rules: &Vec<R>) -> String {
    match rules.len() {
        1 => format!("{:?}", rules[0]),
        2 => format!("{:?} or {:?}", rules[0], rules[1]),
        l => {
            let separated = rules.iter()
                                 .take(l - 1)
                                 .map(|r| format!("{:?}", r))
                                 .collect::<Vec<_>>()
                                 .join(", ");
            format!("{}, or {:?}", separated, rules[l - 1])
        }
    }
}

fn underline<R: fmt::Debug, I: Input>(error: &Error<R, I>, offset: usize) -> String {
    let mut underline = String::new();

    for _ in 0..offset { underline.push(' '); }

    match *error {
        Error::CustomErrorSpan { ref span, .. } => {
            underline.push('^');
            for _ in 2..(span.end() - span.start()) { underline.push('-'); }
            underline.push('^');
        }
        _ => underline.push_str("^---")
    };

    underline
}

fn format<R: fmt::Debug, I: Input>(error: &Error<R, I>) -> String {
    let pos = match *error {
        Error::ParsingError { ref pos, .. } => pos.clone(),
        Error::CustomErrorPos { ref pos, .. } => pos.clone(),
        Error::CustomErrorSpan { ref span, .. } => span.clone().split().0.clone()
    };
    let (line, col) = pos.line_col();
    let line_str_len = format!("{}", line).len();

    let mut spacing = String::new();
    for _ in 0..line_str_len { spacing.push(' '); }

    let filename = position::into_input(&pos).file_name();

    let mut result = match filename {
        Some(filename) => format!("{}--> {}:{}:{}\n", spacing, filename.to_string_lossy(), line,
                                  col),
        None => format!("{}--> {}:{}\n", spacing, line, col)
    };

    result.push_str(&format!("{} |\n", spacing));
    result.push_str(&format!("{} | ", line));

    let line = pos.line_of();
    result.push_str(&format!("{}\n", line));
    result.push_str(&format!("{} | {}\n", spacing, underline(error, col - 1)));
    result.push_str(&format!("{} |\n", spacing));
    result.push_str(&format!("{} = {}", spacing, message(error)));

    result
}

impl<R: fmt::Debug, I: Input> fmt::Display for Error<R, I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", format(self))
    }
}

// We don't want to enforce derivable traits on the Input which forces to implement them manually.

impl<R: Clone, I: Input> Clone for Error<R, I> {
    fn clone(&self) -> Error<R, I> {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                Error::ParsingError {
                    positives: positives.clone(),
                    negatives: negatives.clone(),
                    pos: pos.clone()
                }
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                Error::CustomErrorPos {
                    message: message.clone(),
                    pos: pos.clone()
                }
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                Error::CustomErrorSpan {
                    message: message.clone(),
                    span: span.clone()
                }
            }
        }
    }
}

impl<R: PartialEq, I: Input> PartialEq for Error<R, I> {
    fn eq(&self, other: &Error<R, I>) -> bool {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                match *other {
                    Error::ParsingError {
                        positives: ref other_positives,
                        negatives: ref other_negatives,
                        pos: ref other_pos
                    } => {
                        positives == other_positives && negatives == other_negatives &&
                            pos == other_pos
                    }
                    _ => false
                }
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                match *other {
                    Error::CustomErrorPos {
                        message: ref other_message,
                        pos: ref other_pos
                    } => {
                        message == other_message && pos == other_pos
                    }
                    _ => false
                }
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                match *other {
                    Error::CustomErrorSpan {
                        message: ref other_message,
                        span: ref other_span
                    } => {
                        message == other_message && span == other_span
                    }
                    _ => false
                }
            }
        }
    }
}

impl<R: Eq, I: Input> Eq for Error<R, I> {}

impl<R: Hash, I: Input> Hash for Error<R, I> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                positives.hash(state);
                negatives.hash(state);
                pos.hash(state);
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                message.hash(state);
                pos.hash(state);
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                message.hash(state);
                span.hash(state);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::rc::Rc;

    use super::*;
    use super::super::inputs::{position, StringInput};

    #[test]
    fn display_parsing_error() {
        let input = StringInput::new("ab\ncd\nef".to_owned());
        let pos = position::new(Rc::new(input), 4);
        let error: Error<u32, _> = Error::ParsingError {
            positives: vec![1, 2, 3],
            negatives: vec![4, 5, 6],
            pos: pos
        };

        assert_eq!(format!("{}", error), vec![
            " --> 2:2",
            "  |",
            "2 | cd",
            "  |  ^---",
            "  |",
            "  = unexpected 4, 5, or 6; expected 1, 2, or 3"
        ].join("\n"));
    }

    #[test]
    fn display_custom() {
        let input = StringInput::new("ab\ncd\nef".to_owned());
        let pos = position::new(Rc::new(input), 4);
        let error: Error<&str, _> = Error::CustomErrorPos {
            message: "error: big one".to_owned(),
            pos: pos
        };

        assert_eq!(format!("{}", error), vec![
            " --> 2:2",
            "  |",
            "2 | cd",
            "  |  ^---",
            "  |",
            "  = error: big one"
        ].join("\n"));
    }
}
<commit_msg>Added rule renaming in errors.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::fmt;
use std::hash::{Hash, Hasher};

use super::inputs::{Input, position, Position, Span};
use super::RuleType;

/// An `enum` which defines possible errors.
#[derive(Debug)]
pub enum Error<R, I: Input> {
    /// Generated parsing error with expected and unexpected `Rule`s and a position
    ParsingError {
        /// Positive attempts
        positives: Vec<R>,
        /// Negative attempts
        negatives: Vec<R>,
        /// Deepest position of attempts
        pos: Position<I>
    },
    /// Custom error with a message and a position
    CustomErrorPos {
        /// Short explanation
        message: String,
        /// Error `Position` for formatting
        pos: Position<I>
    },
    /// Custom error with a message and a span defined by a start and end position
    CustomErrorSpan {
        /// Short explanation
        message: String,
        /// Error `Span` for formatting
        span: Span<I>
    }
}

impl <R: RuleType, I: Input> Error<R, I> {
    /// Renames all `Rule`s from a `ParsingError` variant returning a `CustomErrorPos`. It does
    /// nothing when called on `CustomErrorPos` and `CustomErrorSpan` variants.
    ///
    /// Useful in order to rename verbose rules or have detailed per-`Rule` formatting.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest::Error;
    /// # use pest::inputs::{Position, StringInput};
    /// # #[allow(non_camel_case_types)]
    /// # #[allow(dead_code)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// # enum Rule {
    /// #     open_paren,
    /// #     closed_paren
    /// # }
    /// # let input = Rc::new(StringInput::new("".to_owned()));
    /// # let pos = Position::from_start(input);
    /// Error::ParsingError {
    ///     positives: vec![Rule::open_paren],
    ///     negatives: vec![Rule::closed_paren],
    ///     pos: pos
    /// }.renamed_rules(|rule| {
    ///     match *rule {
    ///         Rule::open_paren => "(".to_owned(),
    ///         Rule::closed_paren => "closed paren".to_owned()
    ///     }
    /// });
    /// ```
    pub fn renamed_rules<F>(self, f: F) -> Error<R, I>
    where
        F: FnMut(&R) -> String
    {
        match self {
            Error::ParsingError { positives, negatives, pos } => {
                let message = parsing_error_message(&positives, &negatives, f);
                Error::CustomErrorPos {
                    message,
                    pos
                }
            }
            error => error
        }
    }
}

fn message<R: fmt::Debug, I: Input>(error: &Error<R, I>) -> String {
    match *error {
        Error::ParsingError { ref positives, ref negatives, .. } => {
            parsing_error_message(positives, negatives, |r| format!("{:?}", r))
        }
        Error::CustomErrorPos { ref message, .. } => message.to_owned(),
        Error::CustomErrorSpan { ref message, .. } => message.to_owned()
    }
}

fn parsing_error_message<R: fmt::Debug, F>(
    positives: &Vec<R>,
    negatives: &Vec<R>,
    mut f: F
) -> String
where
    F: FnMut(&R) -> String
{
    match (negatives.is_empty(), positives.is_empty()) {
        (false, false) => {
            format!(
                "unexpected {}; expected {}",
                enumerate(negatives, &mut f),
                enumerate(positives, &mut f)
            )
        }
        (false, true) => format!("unexpected {}", enumerate(negatives, &mut f)),
        (true, false) => format!("expected {}", enumerate(positives, &mut f)),
        (true, true) => "unknown parsing error".to_owned()
    }
}

fn enumerate<R: fmt::Debug, F>(rules: &Vec<R>, f: &mut F) -> String
where
    F: FnMut(&R) -> String
{
    match rules.len() {
        1 => f(&rules[0]),
        2 => format!("{} or {}", f(&rules[0]), f(&rules[1])),
        l => {
            let separated = rules.iter()
                                 .take(l - 1)
                                 .map(|r| f(r))
                                 .collect::<Vec<_>>()
                                 .join(", ");
            format!("{}, or {}", separated, f(&rules[l - 1]))
        }
    }
}

fn underline<R: fmt::Debug, I: Input>(error: &Error<R, I>, offset: usize) -> String {
    let mut underline = String::new();

    for _ in 0..offset { underline.push(' '); }

    match *error {
        Error::CustomErrorSpan { ref span, .. } => {
            underline.push('^');
            for _ in 2..(span.end() - span.start()) { underline.push('-'); }
            underline.push('^');
        }
        _ => underline.push_str("^---")
    };

    underline
}

fn format<R: fmt::Debug, I: Input>(error: &Error<R, I>) -> String {
    let pos = match *error {
        Error::ParsingError { ref pos, .. } => pos.clone(),
        Error::CustomErrorPos { ref pos, .. } => pos.clone(),
        Error::CustomErrorSpan { ref span, .. } => span.clone().split().0.clone()
    };
    let (line, col) = pos.line_col();
    let line_str_len = format!("{}", line).len();

    let mut spacing = String::new();
    for _ in 0..line_str_len { spacing.push(' '); }

    let filename = position::into_input(&pos).file_name();

    let mut result = match filename {
        Some(filename) => format!("{}--> {}:{}:{}\n", spacing, filename.to_string_lossy(), line,
                                  col),
        None => format!("{}--> {}:{}\n", spacing, line, col)
    };

    result.push_str(&format!("{} |\n", spacing));
    result.push_str(&format!("{} | ", line));

    let line = pos.line_of();
    result.push_str(&format!("{}\n", line));
    result.push_str(&format!("{} | {}\n", spacing, underline(error, col - 1)));
    result.push_str(&format!("{} |\n", spacing));
    result.push_str(&format!("{} = {}", spacing, message(error)));

    result
}

impl<R: fmt::Debug, I: Input> fmt::Display for Error<R, I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", format(self))
    }
}

// We don't want to enforce derivable traits on the Input which forces to implement them manually.

impl<R: Clone, I: Input> Clone for Error<R, I> {
    fn clone(&self) -> Error<R, I> {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                Error::ParsingError {
                    positives: positives.clone(),
                    negatives: negatives.clone(),
                    pos: pos.clone()
                }
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                Error::CustomErrorPos {
                    message: message.clone(),
                    pos: pos.clone()
                }
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                Error::CustomErrorSpan {
                    message: message.clone(),
                    span: span.clone()
                }
            }
        }
    }
}

impl<R: PartialEq, I: Input> PartialEq for Error<R, I> {
    fn eq(&self, other: &Error<R, I>) -> bool {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                match *other {
                    Error::ParsingError {
                        positives: ref other_positives,
                        negatives: ref other_negatives,
                        pos: ref other_pos
                    } => {
                        positives == other_positives && negatives == other_negatives &&
                            pos == other_pos
                    }
                    _ => false
                }
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                match *other {
                    Error::CustomErrorPos {
                        message: ref other_message,
                        pos: ref other_pos
                    } => {
                        message == other_message && pos == other_pos
                    }
                    _ => false
                }
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                match *other {
                    Error::CustomErrorSpan {
                        message: ref other_message,
                        span: ref other_span
                    } => {
                        message == other_message && span == other_span
                    }
                    _ => false
                }
            }
        }
    }
}

impl<R: Eq, I: Input> Eq for Error<R, I> {}

impl<R: Hash, I: Input> Hash for Error<R, I> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self {
            Error::ParsingError { ref positives, ref negatives, ref pos } => {
                positives.hash(state);
                negatives.hash(state);
                pos.hash(state);
            }
            Error::CustomErrorPos { ref message, ref pos } => {
                message.hash(state);
                pos.hash(state);
            }
            Error::CustomErrorSpan { ref message, ref span } => {
                message.hash(state);
                span.hash(state);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::rc::Rc;

    use super::*;
    use super::super::inputs::{position, StringInput};

    #[test]
    fn display_parsing_error() {
        let input = StringInput::new("ab\ncd\nef".to_owned());
        let pos = position::new(Rc::new(input), 4);
        let error: Error<u32, _> = Error::ParsingError {
            positives: vec![1, 2, 3],
            negatives: vec![4, 5, 6],
            pos: pos
        };

        assert_eq!(format!("{}", error), vec![
            " --> 2:2",
            "  |",
            "2 | cd",
            "  |  ^---",
            "  |",
            "  = unexpected 4, 5, or 6; expected 1, 2, or 3"
        ].join("\n"));
    }

    #[test]
    fn display_custom() {
        let input = StringInput::new("ab\ncd\nef".to_owned());
        let pos = position::new(Rc::new(input), 4);
        let error: Error<&str, _> = Error::CustomErrorPos {
            message: "error: big one".to_owned(),
            pos: pos
        };

        assert_eq!(format!("{}", error), vec![
            " --> 2:2",
            "  |",
            "2 | cd",
            "  |  ^---",
            "  |",
            "  = error: big one"
        ].join("\n"));
    }

    #[test]
    fn mapped_parsing_error() {
        let input = StringInput::new("ab\ncd\nef".to_owned());
        let pos = position::new(Rc::new(input), 4);
        let error: Error<u32, _> = Error::ParsingError {
            positives: vec![1, 2, 3],
            negatives: vec![4, 5, 6],
            pos: pos
        }.renamed_rules(|n| format!("{}", n + 1));

        assert_eq!(format!("{}", error), vec![
            " --> 2:2",
            "  |",
            "2 | cd",
            "  |  ^---",
            "  |",
            "  = unexpected 5, 6, or 7; expected 2, 3, or 4"
        ].join("\n"));
    }
}
<|endoftext|>


<commit_before>//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! # How to use the core library
//!
//! Please note that all of these details are currently not considered stable.
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
//!
//! * `rust_begin_panic` - This function takes four arguments, a
//!   `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
//!   dictate the panic message, the file at which panic was invoked, and the
//!   line and column inside the file. It is up to consumers of this core
//!   library to define this panic function; it is only required to never
//!   return. This requires a `lang` attribute named `panic_impl`.
//!
//! * `rust_eh_personality` - is used by the failure mechanisms of the
//!    compiler. This is often mapped to GCC's personality function, but crates
//!    which do not trigger a panic can be assured that this function is never
//!    called. The `lang` attribute is called `eh_personality`.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
//
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
// this, both the generated test artifact and the linked libtest (which
// transitively includes libcore) will both define the same set of lang items,
// and this will cause the E0152 "duplicate lang item found" error. See
// discussion in #50466 for details.
//
// This cfg won't affect doc tests.
#![cfg(not(test))]

#![stable(feature = "core", since = "1.6.0")]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
#![no_core]

#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(intra_doc_link_resolution_failure)]
#![warn(missing_debug_implementations)]

#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
#![feature(associated_type_defaults)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(is_sorted)]
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stmt_expr_attributes)]
#![feature(unboxed_closures)]
#![feature(unsized_locals)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(doc_alias)]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#![feature(wasm_target_feature)]
#![feature(avx512_target_feature)]
#![feature(cmpxchg16b_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]
#![feature(const_int_conversion)]
#![feature(const_transmute)]
#![feature(reverse_bits)]
#![feature(non_exhaustive)]
#![feature(structural_match)]
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
#![feature(maybe_uninit)]
#![feature(unrestricted_attribute_tokens)]

#[prelude_import]
#[allow(unused)]
use prelude::v1::*;

#[macro_use]
mod macros;

#[macro_use]
mod internal_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"] pub mod isize;
#[path = "num/i8.rs"]    pub mod i8;
#[path = "num/i16.rs"]   pub mod i16;
#[path = "num/i32.rs"]   pub mod i32;
#[path = "num/i64.rs"]   pub mod i64;
#[path = "num/i128.rs"]  pub mod i128;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]    pub mod u8;
#[path = "num/u16.rs"]   pub mod u16;
#[path = "num/u32.rs"]   pub mod u32;
#[path = "num/u64.rs"]   pub mod u64;
#[path = "num/u128.rs"]  pub mod u128;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;
pub mod hint;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod ascii;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panic;
pub mod panicking;
pub mod pin;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod ffi;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod time;

pub mod unicode;

/* Async */
pub mod future;
pub mod task;

/* Heap memory allocator trait */
#[allow(missing_docs)]
pub mod alloc;

// note: does not need to be public
mod tuple;
mod unit;

// Pull in the `core_arch` crate directly into libcore. The contents of
// `core_arch` are in a different repository: rust-lang-nursery/stdsimd.
//
// `core_arch` depends on libcore, but the contents of this module are
// set up in such a way that directly pulling it here works such that the
// crate uses the this crate as its libcore.
#[allow(unused_macros)]
macro_rules! test_v16 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v32 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v64 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v128 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v256 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v512 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
#[path = "../stdsimd/crates/core_arch/src/mod.rs"]
#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
#[unstable(feature = "stdsimd", issue = "48556")]
mod core_arch;

#[stable(feature = "simd_arch", since = "1.27.0")]
pub use core_arch::arch;
<commit_msg>Rollup merge of #58405 - gnzlbg:remove_unused_macros, r=alexcrichton<commit_after>//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! # How to use the core library
//!
//! Please note that all of these details are currently not considered stable.
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
//!
//! * `rust_begin_panic` - This function takes four arguments, a
//!   `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
//!   dictate the panic message, the file at which panic was invoked, and the
//!   line and column inside the file. It is up to consumers of this core
//!   library to define this panic function; it is only required to never
//!   return. This requires a `lang` attribute named `panic_impl`.
//!
//! * `rust_eh_personality` - is used by the failure mechanisms of the
//!    compiler. This is often mapped to GCC's personality function, but crates
//!    which do not trigger a panic can be assured that this function is never
//!    called. The `lang` attribute is called `eh_personality`.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
//
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
// this, both the generated test artifact and the linked libtest (which
// transitively includes libcore) will both define the same set of lang items,
// and this will cause the E0152 "duplicate lang item found" error. See
// discussion in #50466 for details.
//
// This cfg won't affect doc tests.
#![cfg(not(test))]

#![stable(feature = "core", since = "1.6.0")]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
#![no_core]

#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(intra_doc_link_resolution_failure)]
#![warn(missing_debug_implementations)]

#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
#![feature(associated_type_defaults)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(is_sorted)]
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stmt_expr_attributes)]
#![feature(unboxed_closures)]
#![feature(unsized_locals)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(doc_alias)]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#![feature(wasm_target_feature)]
#![feature(avx512_target_feature)]
#![feature(cmpxchg16b_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]
#![feature(const_int_conversion)]
#![feature(const_transmute)]
#![feature(reverse_bits)]
#![feature(non_exhaustive)]
#![feature(structural_match)]
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
#![feature(maybe_uninit)]
#![feature(unrestricted_attribute_tokens)]

#[prelude_import]
#[allow(unused)]
use prelude::v1::*;

#[macro_use]
mod macros;

#[macro_use]
mod internal_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"] pub mod isize;
#[path = "num/i8.rs"]    pub mod i8;
#[path = "num/i16.rs"]   pub mod i16;
#[path = "num/i32.rs"]   pub mod i32;
#[path = "num/i64.rs"]   pub mod i64;
#[path = "num/i128.rs"]  pub mod i128;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]    pub mod u8;
#[path = "num/u16.rs"]   pub mod u16;
#[path = "num/u32.rs"]   pub mod u32;
#[path = "num/u64.rs"]   pub mod u64;
#[path = "num/u128.rs"]  pub mod u128;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;
pub mod hint;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod ascii;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panic;
pub mod panicking;
pub mod pin;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod ffi;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod time;

pub mod unicode;

/* Async */
pub mod future;
pub mod task;

/* Heap memory allocator trait */
#[allow(missing_docs)]
pub mod alloc;

// note: does not need to be public
mod tuple;
mod unit;

// Pull in the `core_arch` crate directly into libcore. The contents of
// `core_arch` are in a different repository: rust-lang-nursery/stdsimd.
//
// `core_arch` depends on libcore, but the contents of this module are
// set up in such a way that directly pulling it here works such that the
// crate uses the this crate as its libcore.
#[path = "../stdsimd/crates/core_arch/src/mod.rs"]
#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
#[unstable(feature = "stdsimd", issue = "48556")]
mod core_arch;

#[stable(feature = "simd_arch", since = "1.27.0")]
pub use core_arch::arch;
<|endoftext|>


<commit_before>use ::inflector::Inflector;
use ::quote::Tokens;
use ::syn::Ident;
use ::yaml_rust::Yaml;

use infer::auth;
use infer::body;
use infer::params;
use infer::query;
use infer::response;
use infer::InferResult;

const METHODS: &'static [&'static str] = &[
    "DELETE",
    "GET",
    "HEAD",
    "PATCH",
    "POST",
    "PUT",
];

pub(super) fn valid(method: &str) -> bool {
    METHODS.contains(&method.to_uppercase().as_str())
}

fn fn_ident(method: &str) -> Ident {
    assert!(valid(method), "Invalid method: {}", method);
    Ident::new(method.to_snake_case())
}

fn mod_ident(method: &str) -> Ident {
    assert!(valid(method), "Invalid method: {}", method);
    Ident::new(method.to_snake_case())
}

pub(super) fn infer_v3(method: &str, schema: &Yaml) -> InferResult<(Tokens, Option<Tokens>)> {
    let method_fn = fn_ident(&method);
    let method_mod = mod_ident(&method);

    let mut method_level_structs: Vec<Tokens> = Vec::new();
    let mut path_level_structs: Option<Tokens> = None;
    let mut bounds: Vec<Tokens> = Vec::new();
    let mut args: Vec<Tokens> = Vec::new();
    let mut url_transforms: Vec<Tokens> = Vec::new();
    let mut req_transforms: Vec<Tokens> = Vec::new();

    if let Some(parameters) = schema["parameters"].as_vec() {
        let query_parameters = parameters.iter().cloned()
            .filter(|p| p["in"] == Yaml::from_str("query"))
            .collect::<Vec<Yaml>>();

        let path_parameters = parameters.iter().cloned()
            .filter(|p| p["in"] == Yaml::from_str("path"))
            .collect::<Vec<Yaml>>();

        if !query_parameters.is_empty() {
            let (s, b, a, t) = query::infer_v3(&method_mod, &Yaml::Array(query_parameters))?;
            if let Some(method_struct) = s {
                method_level_structs.push(method_struct);
            }
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                url_transforms.push(transformation);
            }
        }

        if !path_parameters.is_empty() {
            let (s, b, a, t) = params::infer_v3(&method, &Yaml::Array(path_parameters))?;

            path_level_structs = path_level_structs.or(s);
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                url_transforms.push(transformation);
            }
        }
    }

    match schema["requestBody"] {
        Yaml::BadValue => (),
        ref schema => {
            let (s, b, a, t) = body::infer_v3(&method_mod, &schema)?;

            if let Some(method_struct) = s {
                method_level_structs.push(method_struct);
            }
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                req_transforms.push(transformation);
            }
        }
    }

    match schema["security"] {
        Yaml::BadValue => {
            args.push(quote!{ authentication: &ServerAuth });
            req_transforms.push(quote! {
                .header(authentication)
            });
        },
        ref schema => {
            let struct_ident = Ident::new("OperationAuth");

            method_level_structs.push(auth::infer_v3(&struct_ident, &schema)?);
            args.push(quote!{ authentication: &#method_mod::#struct_ident });
            req_transforms.push(quote! {
                .header(authentication)
            });
        },
    }

    method_level_structs.push(response::infer_v3(&schema["responses"])?);

    Ok((
        quote! {
            pub mod #method_mod {
                #[allow(unused_imports)]
                use super::schema_ref;

                #(#method_level_structs)*
            }

            #[allow(dead_code)]
            #[allow(unused_mut)]
            pub fn #method_fn<#(#bounds),*>(#(#args),*) -> #method_mod::ResponseResult {
                let mut url = Url::parse(
                    format!("{}{}", self::API_URL, self::API_PATH).as_str()
                ).expect("malformed server URL or path");
                #(url#url_transforms;)*

                let client = Client::new().unwrap();
                let request = client.#method_fn(url)
                    .header(header::Accept::json())
                    #(#req_transforms)*;

                let mut response = request.send().ok();
                <#method_mod::ResponseResult as Response>::from(&mut response.as_mut())
            }
        },
        path_level_structs,
    ))
}
<commit_msg>Fix taking auth headers by value<commit_after>use ::inflector::Inflector;
use ::quote::Tokens;
use ::syn::Ident;
use ::yaml_rust::Yaml;

use infer::auth;
use infer::body;
use infer::params;
use infer::query;
use infer::response;
use infer::InferResult;

const METHODS: &'static [&'static str] = &[
    "DELETE",
    "GET",
    "HEAD",
    "PATCH",
    "POST",
    "PUT",
];

pub(super) fn valid(method: &str) -> bool {
    METHODS.contains(&method.to_uppercase().as_str())
}

fn fn_ident(method: &str) -> Ident {
    assert!(valid(method), "Invalid method: {}", method);
    Ident::new(method.to_snake_case())
}

fn mod_ident(method: &str) -> Ident {
    assert!(valid(method), "Invalid method: {}", method);
    Ident::new(method.to_snake_case())
}

pub(super) fn infer_v3(method: &str, schema: &Yaml) -> InferResult<(Tokens, Option<Tokens>)> {
    let method_fn = fn_ident(&method);
    let method_mod = mod_ident(&method);

    let mut method_level_structs: Vec<Tokens> = Vec::new();
    let mut path_level_structs: Option<Tokens> = None;
    let mut bounds: Vec<Tokens> = Vec::new();
    let mut args: Vec<Tokens> = Vec::new();
    let mut url_transforms: Vec<Tokens> = Vec::new();
    let mut req_transforms: Vec<Tokens> = Vec::new();

    if let Some(parameters) = schema["parameters"].as_vec() {
        let query_parameters = parameters.iter().cloned()
            .filter(|p| p["in"] == Yaml::from_str("query"))
            .collect::<Vec<Yaml>>();

        let path_parameters = parameters.iter().cloned()
            .filter(|p| p["in"] == Yaml::from_str("path"))
            .collect::<Vec<Yaml>>();

        if !query_parameters.is_empty() {
            let (s, b, a, t) = query::infer_v3(&method_mod, &Yaml::Array(query_parameters))?;
            if let Some(method_struct) = s {
                method_level_structs.push(method_struct);
            }
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                url_transforms.push(transformation);
            }
        }

        if !path_parameters.is_empty() {
            let (s, b, a, t) = params::infer_v3(&method, &Yaml::Array(path_parameters))?;

            path_level_structs = path_level_structs.or(s);
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                url_transforms.push(transformation);
            }
        }
    }

    match schema["requestBody"] {
        Yaml::BadValue => (),
        ref schema => {
            let (s, b, a, t) = body::infer_v3(&method_mod, &schema)?;

            if let Some(method_struct) = s {
                method_level_structs.push(method_struct);
            }
            if let Some(bound) = b {
                bounds.push(bound);
            }
            if let Some(arg) = a {
                args.push(arg);
            }
            if let Some(transformation) = t {
                req_transforms.push(transformation);
            }
        }
    }

    match schema["security"] {
        Yaml::BadValue => {
            args.push(quote!{ authentication: ServerAuth });
            req_transforms.push(quote! {
                .header(authentication)
            });
        },
        ref schema => {
            let struct_ident = Ident::new("OperationAuth");

            method_level_structs.push(auth::infer_v3(&struct_ident, &schema)?);
            args.push(quote!{ authentication: #method_mod::#struct_ident });
            req_transforms.push(quote! {
                .header(authentication)
            });
        },
    }

    method_level_structs.push(response::infer_v3(&schema["responses"])?);

    Ok((
        quote! {
            pub mod #method_mod {
                #[allow(unused_imports)]
                use super::schema_ref;

                #(#method_level_structs)*
            }

            #[allow(dead_code)]
            #[allow(unused_mut)]
            pub fn #method_fn<#(#bounds),*>(#(#args),*) -> #method_mod::ResponseResult {
                let mut url = Url::parse(
                    format!("{}{}", self::API_URL, self::API_PATH).as_str()
                ).expect("malformed server URL or path");
                #(url#url_transforms;)*

                let client = Client::new().unwrap();
                let request = client.#method_fn(url)
                    .header(header::Accept::json())
                    #(#req_transforms)*;

                let mut response = request.send().ok();
                <#method_mod::ResponseResult as Response>::from(&mut response.as_mut())
            }
        },
        path_level_structs,
    ))
}
<|endoftext|>