<commit_before>pub mod utils;
pub mod vertex;

use self::vertex::Vertex;
use self::vertex::Normal;

extern crate winit;
extern crate vulkano;
extern crate vulkano_win;
extern crate cgmath;
extern crate time;

use vulkano_win::VkSurfaceBuild;
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::PrimaryCommandBufferBuilder;
use vulkano::command_buffer::Submission;
use vulkano::device::Device;
use vulkano::framebuffer::Framebuffer;
use vulkano::framebuffer::Subpass;
use vulkano::instance::Instance;
use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::GraphicsPipelineParams;
use vulkano::pipeline::blend::Blend;
use vulkano::pipeline::depth_stencil::DepthStencil;
use vulkano::pipeline::input_assembly::InputAssembly;
use vulkano::pipeline::multisample::Multisample;
use vulkano::pipeline::vertex::TwoBuffersDefinition;
use vulkano::pipeline::viewport::ViewportsState;
use vulkano::pipeline::viewport::Viewport;
use vulkano::pipeline::viewport::Scissor;
use vulkano::swapchain::SurfaceTransform;
use vulkano::swapchain::Swapchain;
use vulkano::pipeline::input_assembly::PrimitiveTopology;
use vulkano::image::SwapchainImage;
use vulkano::device::QueuesIter;
use vulkano::device::Queue;

use std::sync::Arc;
use std::time::Duration;

use std::collections::VecDeque;

use self::utils::fps;

use game_state::{Renderer, Renderable};

//TODO: compile these elsewhere, at build time?
// These shaders are a PITA, generated by build.rs, dependent on OUT_DIR... *barf
// More importantly, these are actually compiled SPIR-V, ignore the glsl file extension on them
mod vs { include!{concat!(env!("OUT_DIR"), "/shaders/assets/shaders/triangle_vs.glsl") }}
mod fs { include!{concat!(env!("OUT_DIR"), "/shaders/assets/shaders/triangle_fs.glsl") }}

// TODO: do we want clearcolor settable?
const CLEAR_COLOR: [f32;4] = [0.0, 0.0, 0.0, 1.0];

// TODO: explore more complex options for renderpasses
pub mod render_pass {
	use vulkano::format::Format;
	single_pass_renderpass!{
		attachments: {
			color: {
				load:Clear,
				store:Store,
				format:Format,
			},
			depth: {
			    load: Clear,
			    store: DontCare,
			    format: ::vulkano::format::D16Unorm,
			}
		},
		pass: {
			color: [color],
			depth_stencil: {depth}
		}
	}
}

pub mod pipeline_layout {
    pipeline_layout! {
        set0: {
            uniforms: UniformBuffer<::renderer::vs::ty::Data>
        }
    }
}

pub struct VulkanRenderer {
	instance: Arc<Instance>,
	window: vulkano_win::Window,
	device: Arc<Device>,
	queues: QueuesIter,
	queue: Arc<Queue>,
	swapchain: Arc<Swapchain>,
	images: Vec<Arc<SwapchainImage>>,
	submissions: Vec<Arc<Submission>>,
	pipeline: Arc<GraphicsPipeline<TwoBuffersDefinition<Vertex, Normal>, pipeline_layout::CustomPipeline, render_pass::CustomRenderPass>>,
	framebuffers: Vec<Arc<Framebuffer<render_pass::CustomRenderPass>>>,
	render_pass: Arc<render_pass::CustomRenderPass>,
	fps: fps::FPS,
    renderable_queue: VecDeque<Arc<Box<Renderable>>>,
    pipeline_set: Arc<pipeline_layout::set0::Set>,
    uniform_buffer: Arc<CpuAccessibleBuffer<::renderer::vs::ty::Data>>
}

impl VulkanRenderer {
	pub fn new(title: &str, h: u32, w: u32) -> Self {
		// Vulkan
		let instance = {
			let extensions = vulkano_win::required_extensions();
			Instance::new(None, &extensions, None).expect("Failed to create Vulkan instance.")
		};

		let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
			.next().expect("No device available.");

		let window = winit::WindowBuilder::new()
            .with_title(title)
            .with_dimensions(h,w)
            .build_vk_surface(&instance).unwrap();

		let queue = physical.queue_families().find(|q| {
			q.supports_graphics() && window.surface().is_supported(q).unwrap_or(false)
		}).expect("Couldn't find a graphical queue family.");

		let (device, mut queues) = {
			let device_ext = vulkano::device::DeviceExtensions {
				khr_swapchain: true,
				.. vulkano::device::DeviceExtensions::none()
			};

			Device::new(&physical, physical.supported_features(), &device_ext,
				[(queue, 0.5)].iter().cloned()
			).expect("Failed to create device.")
		};

		let queue = queues.next().unwrap();

		let (swapchain, images) = {
			let caps = window.surface().get_capabilities(&physical).expect("Failed to get surface capabilities");
			let dimensions = caps.current_extent.unwrap_or([1280, 800]);
			let present = caps.present_modes.iter().next().unwrap();
			let alpha = caps.supported_composite_alpha.iter().next().unwrap();
			let format = caps.supported_formats[0].0;
			Swapchain::new(
				&device,
				&window.surface(),
				2,
				format,
				dimensions,
				1,
				&caps.supported_usage_flags,
				&queue,
				SurfaceTransform::Identity,
				alpha,
				present,
				true,
				None
			).expect("Failed to create swapchain.")
		};

		let vs = vs::Shader::load(&device).expect("failed to create vs shader module");
		let fs = fs::Shader::load(&device).expect("failed to create fs shader module");

		let render_pass = render_pass::CustomRenderPass::new(&device, &render_pass::Formats {
			color: (images[0].format(), 1),
            depth: (vulkano::format::D16Unorm, 1)
		}).unwrap();

        let proj = cgmath::perspective(
            cgmath::Rad(::std::f32::consts::FRAC_PI_2),
            { let d = images[0].dimensions(); d[0] as f32 / d[1] as f32 },
            0.01,
            5.0
        );

        // Vulkan uses right-handed coordinates, y positive is down
        let view = cgmath::Matrix4::look_at(
            cgmath::Point3::new(0.5, -1.0, 1.0),   // eye
            cgmath::Point3::new(0.0, 0.5, -1.0),  // center
            cgmath::Vector3::new(0.0, 1.0, 0.0)  // up
        );

        let scale = cgmath::Matrix4::from_scale(1.0);

        let uniform_buffer = CpuAccessibleBuffer::<vs::ty::Data>::from_data(
            &device,
            &vulkano::buffer::BufferUsage::all(),
            Some(queue.family()),
            vs::ty::Data {
                world : <cgmath::Matrix4<f32> as cgmath::SquareMatrix>::identity().into(),
                view : (view * scale).into(),
                proj : proj.into(),
            }).expect("failed to create buffer");

        let descriptor_pool = vulkano::descriptor::descriptor_set::DescriptorPool::new(&device);
        let pipeline_layout = pipeline_layout::CustomPipeline::new(&device).unwrap();
        let pipeline_set = pipeline_layout::set0::Set::new(&descriptor_pool, &pipeline_layout, &pipeline_layout::set0::Descriptors {
            uniforms: &uniform_buffer
        });

		let pipeline = GraphicsPipeline::new(&device, GraphicsPipelineParams {
			vertex_input: TwoBuffersDefinition::new(),
			vertex_shader: vs.main_entry_point(),
			input_assembly: InputAssembly {
				topology: PrimitiveTopology::TriangleList,
				primitive_restart_enable: false,
			},
			tessellation: None,
			geometry_shader: None, //&geometry_shader,
			viewport: ViewportsState::Fixed {
				data: vec![(
					Viewport {
						origin: [0.0, 0.0],
						depth_range: 0.0 .. 1.0,
						dimensions: [images[0].dimensions()[0] as f32,
						images[0].dimensions()[1] as f32],
					},
					Scissor::irrelevant()
				)],
			},
			raster: Default::default(),
			multisample: Multisample::disabled(),
			fragment_shader: fs.main_entry_point(),
			depth_stencil: DepthStencil::disabled(),
			blend: Blend::pass_through(),
			layout: &pipeline_layout,
			render_pass: Subpass::from(&render_pass, 0).unwrap(),
		}).unwrap();

        let depth_buffer = vulkano::image::attachment::AttachmentImage::transient(
            &device,
            images[0].dimensions(),
            vulkano::format::D16Unorm
        ).unwrap();

		let framebuffers = images.iter().map(|image| {
			let dimensions = [image.dimensions()[0], image.dimensions()[1], 1];
			Framebuffer::new(&render_pass, dimensions, render_pass::AList {
				color: &image,
                depth: &depth_buffer
			}).unwrap()
		}).collect::<Vec<_>>();

		let submissions:Vec<Arc<Submission>> = Vec::new();

		VulkanRenderer {
			// render
			device: device,
			queue: queue,
			swapchain: swapchain,
			submissions: submissions,
			pipeline: pipeline,
			framebuffers: framebuffers,
			render_pass: render_pass,

			//individually exposed
			images: images,
			queues: queues,
			instance: instance.clone(),
			fps: fps::FPS::new(),
			window: window,
            renderable_queue: VecDeque::new(),
            pipeline_set: pipeline_set,
            uniform_buffer: uniform_buffer,
		}

	}

	pub fn instance(&self) -> Arc<Instance> {
		self.instance.clone()
	}

	pub fn queues(&mut self) -> &mut QueuesIter {
		&mut self.queues
	}

	pub fn images(&mut self) -> &Vec<Arc<SwapchainImage>> {
		&mut self.images
	}

	pub fn window(&self) -> &vulkano_win::Window {
		&self.window
	}

	pub fn native_window(&self) -> &winit::Window {
		&self.window.window()
	}

    fn render(&mut self) {

        // TODO: create buffers for and setup draw calls

        self.submissions.retain(|s| s.destroying_would_block());
        let image_num = self.swapchain.acquire_next_image(Duration::new(1, 0)).unwrap();

        // begin the command buffer
        let mut cmd_buffer_build = PrimaryCommandBufferBuilder::new(&self.device, self.queue.family())
            .draw_inline(
                &self.render_pass,
                &self.framebuffers[image_num],
                render_pass::ClearValues {
                    color: CLEAR_COLOR,
                    depth: 1.0,
                });

        let mut rad = 0.00001;

        loop {
            match self.renderable_queue.pop_front() {
                Some(next_renderable) => {
                    // println!("got renderable");
                    let mesh = next_renderable.get_mesh();

                    let world_mat = next_renderable.get_world_matrix();
                    let view_mat = next_renderable.get_view_matrix();

                    let vertices: Vec<Vertex> = mesh.vertices.iter().map(|x| {
                        Vertex::from_vector(x.clone())
                    }).collect();

                    let normals: Vec<Normal> = mesh.normals.iter().map(|x| {
                        Normal::from_normal(x.clone())
                    }).collect();

                    let indices = &mesh.indices;

                    let vert_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        vertices.iter().cloned()
                    ).expect("Unable to set vertex buffer");

                    let normal_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        normals.iter().cloned()
                    ).expect("Unable to set normal buffer");

                    let index_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        indices.iter().cloned()
                    ).expect("Unable to set index buffer");

                    let mut buffer_content = self.uniform_buffer.write(
                        Duration::new(1, 0)
                    ).unwrap();

                    rad += 0.1;
                    let current_view: cgmath::Matrix4<f32> = buffer_content.view.into();
                    let rotation = cgmath::Matrix4::from_angle_y(cgmath::Rad(rad));
                    buffer_content.view = (current_view * rotation).into();
                    buffer_content.world = world_mat.clone().into();

                    //println!("building indexed command buffer");
                    cmd_buffer_build = cmd_buffer_build.draw_indexed(
                        &self.pipeline,
                        (&vert_buffer, &normal_buffer),
                        &index_buffer,
                        &DynamicState::none(), &self.pipeline_set, &()
                    );
                },
                None => { break; }
            }
        }
        //println!("draw_end() for command buffer");
        let cmd_buffer_build = cmd_buffer_build.draw_end();

        //println!("finalizing command buffer");
        let cmd_buffer = cmd_buffer_build.build();

        //println!("submitting command buffer");
        self.submissions.push(command_buffer::submit(&cmd_buffer, &self.queue).unwrap());

        //println!("presenting");
        self.swapchain.present(&self.queue, image_num).unwrap();

        self.fps.update();
    }

    #[allow(dead_code)]
    fn fps(&self) -> f32 {
        self.fps.get()
    }

}

impl Renderer for VulkanRenderer {
    fn queue_renderable(&mut self, renderable: Arc<Box<Renderable>>) {
        self.renderable_queue.push_back(renderable);
    }

    fn present(&mut self) {
        self.render();
    }
}

<commit_msg>stuff<commit_after>pub mod utils;
pub mod vertex;

use self::vertex::Vertex;
use self::vertex::Normal;

extern crate winit;
extern crate vulkano;
extern crate vulkano_win;
extern crate cgmath;
extern crate time;

use vulkano_win::VkSurfaceBuild;
use vulkano::buffer::BufferUsage;
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer;
use vulkano::command_buffer::DynamicState;
use vulkano::command_buffer::PrimaryCommandBufferBuilder;
use vulkano::command_buffer::Submission;
use vulkano::device::Device;
use vulkano::framebuffer::Framebuffer;
use vulkano::framebuffer::Subpass;
use vulkano::instance::Instance;
use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::GraphicsPipelineParams;
use vulkano::pipeline::blend::Blend;
use vulkano::pipeline::depth_stencil::DepthStencil;
use vulkano::pipeline::input_assembly::InputAssembly;
use vulkano::pipeline::multisample::Multisample;
use vulkano::pipeline::vertex::TwoBuffersDefinition;
use vulkano::pipeline::viewport::ViewportsState;
use vulkano::pipeline::viewport::Viewport;
use vulkano::pipeline::viewport::Scissor;
use vulkano::swapchain::SurfaceTransform;
use vulkano::swapchain::Swapchain;
use vulkano::pipeline::input_assembly::PrimitiveTopology;
use vulkano::image::SwapchainImage;
use vulkano::device::QueuesIter;
use vulkano::device::Queue;

use std::sync::Arc;
use std::time::Duration;

use std::collections::VecDeque;

use self::utils::fps;

use game_state::{Renderer, Renderable};

//TODO: compile these elsewhere, at build time?
// These shaders are a PITA, generated by build.rs, dependent on OUT_DIR... *barf
// More importantly, these are actually compiled SPIR-V, ignore the glsl file extension on them
mod vs { include!{concat!(env!("OUT_DIR"), "/shaders/assets/shaders/triangle_vs.glsl") }}
mod fs { include!{concat!(env!("OUT_DIR"), "/shaders/assets/shaders/triangle_fs.glsl") }}

// TODO: do we want clearcolor settable?
const CLEAR_COLOR: [f32;4] = [0.0, 0.0, 0.0, 1.0];

// TODO: explore more complex options for renderpasses
pub mod render_pass {
	use vulkano::format::Format;
	single_pass_renderpass!{
		attachments: {
			color: {
				load:Clear,
				store:Store,
				format:Format,
			},
			depth: {
			    load: Clear,
			    store: DontCare,
			    format: ::vulkano::format::D16Unorm,
			}
		},
		pass: {
			color: [color],
			depth_stencil: {depth}
		}
	}
}

pub mod pipeline_layout {
    pipeline_layout! {
        set0: {
            uniforms: UniformBuffer<::renderer::vs::ty::Data>
        }
    }
}

pub struct VulkanRenderer {
	instance: Arc<Instance>,
	window: vulkano_win::Window,
	device: Arc<Device>,
	queues: QueuesIter,
	queue: Arc<Queue>,
	swapchain: Arc<Swapchain>,
	images: Vec<Arc<SwapchainImage>>,
	submissions: Vec<Arc<Submission>>,
	pipeline: Arc<GraphicsPipeline<TwoBuffersDefinition<Vertex, Normal>, pipeline_layout::CustomPipeline, render_pass::CustomRenderPass>>,
	framebuffers: Vec<Arc<Framebuffer<render_pass::CustomRenderPass>>>,
	render_pass: Arc<render_pass::CustomRenderPass>,
	fps: fps::FPS,
    renderable_queue: VecDeque<Arc<Box<Renderable>>>,
    pipeline_set: Arc<pipeline_layout::set0::Set>,
    uniform_buffer: Arc<CpuAccessibleBuffer<::renderer::vs::ty::Data>>
}

impl VulkanRenderer {
	pub fn new(title: &str, h: u32, w: u32) -> Self {
		// Vulkan
		let instance = {
			let extensions = vulkano_win::required_extensions();
			Instance::new(None, &extensions, None).expect("Failed to create Vulkan instance.")
		};

		let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
			.next().expect("No device available.");

		let window = winit::WindowBuilder::new()
            .with_title(title)
            .with_dimensions(h,w)
            .build_vk_surface(&instance).unwrap();

		let queue = physical.queue_families().find(|q| {
			q.supports_graphics() && window.surface().is_supported(q).unwrap_or(false)
		}).expect("Couldn't find a graphical queue family.");

		let (device, mut queues) = {
			let device_ext = vulkano::device::DeviceExtensions {
				khr_swapchain: true,
				.. vulkano::device::DeviceExtensions::none()
			};

			Device::new(&physical, physical.supported_features(), &device_ext,
				[(queue, 0.5)].iter().cloned()
			).expect("Failed to create device.")
		};

		let queue = queues.next().unwrap();

		let (swapchain, images) = {
			let caps = window.surface().get_capabilities(&physical).expect("Failed to get surface capabilities");
			let dimensions = caps.current_extent.unwrap_or([1280, 800]);
			let present = caps.present_modes.iter().next().unwrap();
			let alpha = caps.supported_composite_alpha.iter().next().unwrap();
			let format = caps.supported_formats[0].0;
			Swapchain::new(
				&device,
				&window.surface(),
				2,
				format,
				dimensions,
				1,
				&caps.supported_usage_flags,
				&queue,
				SurfaceTransform::Identity,
				alpha,
				present,
				true,
				None
			).expect("Failed to create swapchain.")
		};

		let vs = vs::Shader::load(&device).expect("failed to create vs shader module");
		let fs = fs::Shader::load(&device).expect("failed to create fs shader module");

		let render_pass = render_pass::CustomRenderPass::new(&device, &render_pass::Formats {
			color: (images[0].format(), 1),
            depth: (vulkano::format::D16Unorm, 1)
		}).unwrap();

        let proj = cgmath::perspective(
            cgmath::Rad(::std::f32::consts::FRAC_PI_2),
            { let d = images[0].dimensions(); d[0] as f32 / d[1] as f32 },
            0.01,
            5.0
        );

        // Vulkan uses right-handed coordinates, y positive is down
        let view = cgmath::Matrix4::look_at(
            cgmath::Point3::new(0.5, -1.0, 1.0),   // eye
            cgmath::Point3::new(0.0, 0.5, -1.0),  // center
            cgmath::Vector3::new(0.0, 1.0, 0.0)  // up
        );

        let scale = cgmath::Matrix4::from_scale(1.0);

        let uniform_buffer = CpuAccessibleBuffer::<vs::ty::Data>::from_data(
            &device,
            &vulkano::buffer::BufferUsage::all(),
            Some(queue.family()),
            vs::ty::Data {
                world : <cgmath::Matrix4<f32> as cgmath::SquareMatrix>::identity().into(),
                view : (view * scale).into(),
                proj : proj.into(),
            }).expect("failed to create buffer");

        let descriptor_pool = vulkano::descriptor::descriptor_set::DescriptorPool::new(&device);
        let pipeline_layout = pipeline_layout::CustomPipeline::new(&device).unwrap();
        let pipeline_set = pipeline_layout::set0::Set::new(&descriptor_pool, &pipeline_layout, &pipeline_layout::set0::Descriptors {
            uniforms: &uniform_buffer
        });

		let pipeline = GraphicsPipeline::new(&device, GraphicsPipelineParams {
			vertex_input: TwoBuffersDefinition::new(),
			vertex_shader: vs.main_entry_point(),
			input_assembly: InputAssembly {
				topology: PrimitiveTopology::TriangleList,
				primitive_restart_enable: false,
			},
			tessellation: None,
			geometry_shader: None, //&geometry_shader,
			viewport: ViewportsState::Fixed {
				data: vec![(
					Viewport {
						origin: [0.0, 0.0],
						depth_range: 0.0 .. 1.0,
						dimensions: [images[0].dimensions()[0] as f32,
						images[0].dimensions()[1] as f32],
					},
					Scissor::irrelevant()
				)],
			},
			raster: Default::default(),
			multisample: Multisample::disabled(),
			fragment_shader: fs.main_entry_point(),
			depth_stencil: DepthStencil::disabled(),
			blend: Blend::pass_through(),
			layout: &pipeline_layout,
			render_pass: Subpass::from(&render_pass, 0).unwrap(),
		}).unwrap();

        let depth_buffer = vulkano::image::attachment::AttachmentImage::transient(
            &device,
            images[0].dimensions(),
            vulkano::format::D16Unorm
        ).unwrap();

		let framebuffers = images.iter().map(|image| {
			let dimensions = [image.dimensions()[0], image.dimensions()[1], 1];
			Framebuffer::new(&render_pass, dimensions, render_pass::AList {
				color: &image,
                depth: &depth_buffer
			}).unwrap()
		}).collect::<Vec<_>>();

		let submissions:Vec<Arc<Submission>> = Vec::new();

		VulkanRenderer {
			// render
			device: device,
			queue: queue,
			swapchain: swapchain,
			submissions: submissions,
			pipeline: pipeline,
			framebuffers: framebuffers,
			render_pass: render_pass,

			//individually exposed
			images: images,
			queues: queues,
			instance: instance.clone(),
			fps: fps::FPS::new(),
			window: window,
            renderable_queue: VecDeque::new(),
            pipeline_set: pipeline_set,
            uniform_buffer: uniform_buffer,
		}

	}

	pub fn instance(&self) -> Arc<Instance> {
		self.instance.clone()
	}

	pub fn queues(&mut self) -> &mut QueuesIter {
		&mut self.queues
	}

	pub fn images(&mut self) -> &Vec<Arc<SwapchainImage>> {
		&mut self.images
	}

	pub fn window(&self) -> &vulkano_win::Window {
		&self.window
	}

	pub fn native_window(&self) -> &winit::Window {
		&self.window.window()
	}

    fn render(&mut self) {

        // TODO: create buffers for and setup draw calls

        self.submissions.retain(|s| s.destroying_would_block());
        let image_num = self.swapchain.acquire_next_image(Duration::new(1, 0)).unwrap();

        // begin the command buffer
        let mut cmd_buffer_build = PrimaryCommandBufferBuilder::new(&self.device, self.queue.family())
            .draw_inline(
                &self.render_pass,
                &self.framebuffers[image_num],
                render_pass::ClearValues {
                    color: CLEAR_COLOR,
                    depth: 1.0,
                });

        let mut rad = 0.00001;

        loop {
            match self.renderable_queue.pop_front() {
                Some(next_renderable) => {
                    // println!("got renderable");
                    let mesh = next_renderable.get_mesh();

                    let world_mat = next_renderable.get_world_matrix();
                    let view_mat = next_renderable.get_view_matrix();

                    let vertices: Vec<Vertex> = mesh.vertices.iter().map(|x| {
                        Vertex::from_vector(x.clone())
                    }).collect();

                    let normals: Vec<Normal> = mesh.normals.iter().map(|x| {
                        Normal::from_normal(x.clone())
                    }).collect();

                    let indices = &mesh.indices;

										// TODO: move buffers into Model
                    let vert_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        vertices.iter().cloned()
                    ).expect("Unable to set vertex buffer");

                    let normal_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        normals.iter().cloned()
                    ).expect("Unable to set normal buffer");

                    let index_buffer = CpuAccessibleBuffer::from_iter(
                        &self.device,
                        &BufferUsage::all(),
                        Some(self.queue.family()),
                        indices.iter().cloned()
                    ).expect("Unable to set index buffer");

                    let mut buffer_content = self.uniform_buffer.write(
                        Duration::new(1, 0)
                    ).unwrap();

                    rad += 0.1;
                    let current_view: cgmath::Matrix4<f32> = buffer_content.view.into();
                    let rotation = cgmath::Matrix4::from_angle_y(cgmath::Rad(rad));
                    buffer_content.view = (current_view * rotation).into();
                    buffer_content.world = world_mat.clone().into();

                    //println!("building indexed command buffer");
                    cmd_buffer_build = cmd_buffer_build.draw_indexed(
                        &self.pipeline,
                        (&vert_buffer, &normal_buffer),
                        &index_buffer,
                        &DynamicState::none(), &self.pipeline_set, &()
                    );
                },
                None => { break; }
            }
        }
        //println!("draw_end() for command buffer");
        let cmd_buffer_build = cmd_buffer_build.draw_end();

        //println!("finalizing command buffer");
        let cmd_buffer = cmd_buffer_build.build();

        //println!("submitting command buffer");
        self.submissions.push(command_buffer::submit(&cmd_buffer, &self.queue).unwrap());

        //println!("presenting");
        self.swapchain.present(&self.queue, image_num).unwrap();

        self.fps.update();
    }

    #[allow(dead_code)]
    fn fps(&self) -> f32 {
        self.fps.get()
    }

}

impl Renderer for VulkanRenderer {
    fn queue_renderable(&mut self, renderable: Arc<Box<Renderable>>) {
        self.renderable_queue.push_back(renderable);
    }

    fn present(&mut self) {
        self.render();
    }
}

<|endoftext|>


<commit_before>use event::Event;

#[derive(Debug,Clone)]
pub struct SassComment<'a> {
    pub comment: Event<'a>,
}

impl <'a> SassComment<'a> {
    pub fn expanded(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }

    pub fn nested(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }

    pub fn compact(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }

    pub fn compressed(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }
}
<commit_msg>Remove newlines in comments for compact output<commit_after>use event::Event;

#[derive(Debug,Clone)]
pub struct SassComment<'a> {
    pub comment: Event<'a>,
}

impl <'a> SassComment<'a> {
    pub fn expanded(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }

    pub fn nested(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }

    pub fn compact(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string().lines().map(|s| s.trim()).collect::<Vec<_>>().connect(" "),
            _ => unreachable!(),
        }
    }

    pub fn compressed(&self) -> String {
        match &self.comment {
            &Event::Comment(ref c) => (*c).to_string(),
            _ => unreachable!(),
        }
    }
}
<|endoftext|>


<commit_before>//! A layer of abstraction over a SMT solver

use engine::util::*;
use error::*;
use il;
use regex;
use std::collections::BTreeSet;
use std::io::{Read, Write};
use std::process;

pub struct Solver {
    child: process::Child
}

impl Solver {
    pub fn new() -> Result<Solver> {
        let mut child = process::Command::new("z3")
            .arg("-in")
            .stdin(process::Stdio::piped())
            .stdout(process::Stdio::piped())
            .stderr(process::Stdio::piped())
            .spawn()
            .expect("Failed to invoke solver");

        if let Some(ref mut stdin) = child.stdin {
            stdin.write("(set-option :produce-models true)\n".as_bytes())?;
            stdin.write("(set-logic QF_AUFBV)\n".as_bytes())?;
            stdin.write("(set-info :smt-lib-version 2.0)\n".as_bytes())?;
        }
        else {
            bail!("Failed to get stdout for child");
        }

        Ok(Solver {
            child: child
        })
    }

    pub fn solve(&mut self, expr: &il::Expression, constraints: Vec<il::Expression>)
    -> Result<Option<il::Constant>> {

        // We need to collect all of the scalars so we can declare them
        let mut scalars: BTreeSet<(String, usize)> = BTreeSet::new();

        // Collect all scalars from constraints
        for constraint in &constraints {
            for scalar in constraint.collect_scalars() {
                scalars.insert((scalar.name().to_string(), scalar.bits()));
            }
        }

        // And all scalars from the expression we are solving
        for scalar in expr.collect_scalars() {
            scalars.insert((scalar.name().to_string(), scalar.bits()));
        }

        // And a scalar for our result
        scalars.insert(("EVAL_RESULT".to_string(), expr.bits()));

        // Push state
        let mut solver_lines = vec!["(push)".to_string()];

        // Declare all variables
        for scalar in scalars {
            solver_lines.push(format!("(declare-fun {} () (_ BitVec {}))",
                scalar.0, scalar.1));
        }

        // Assert Constraints
        for constraint in constraints {
            solver_lines.push(format!("(assert (= #b1 {}))",
                expr_to_smtlib2(&constraint)));
        }

        // Assert the expression
        solver_lines.push(format!("(assert (= EVAL_RESULT {}))",
            expr_to_smtlib2(expr)));

        // Get value and pop this state
        solver_lines.push("(check-sat)".to_string());
        solver_lines.push("(get-value (EVAL_RESULT))".to_string());
        solver_lines.push("(pop)\n".to_string());

        let solver_input = solver_lines.join("\n");

        match self.child.stdin {
            Some(ref mut stdin) => {
                stdin.write_all(solver_input.as_bytes())?;
                stdin.flush()?;
            },
            None => bail!("Failed to get stdin from solver process")
        }

        for _ in 0..5 {
            let mut buf = [0; 2048];

            // read from stdout
            let bytes_read = match self.child.stdout {
                Some(ref mut stdout) => stdout.read(&mut buf)?,
                None => bail!("Failed to get stdout from solver proces")
            };

            let buf = if bytes_read == 0 {
                bail!("Read 0 bytes from solver")
            } else {
                buf.split_at(bytes_read).0.to_vec()
            };

            let solver_output = String::from_utf8(buf)?;

            // check if we got unsat
            if solver_output.contains("unsat") {
                return Ok(None);
            }

            lazy_static!{
                static ref RE16: regex::Regex = regex::Regex::new("EVAL_RESULT #x([0-9a-f]+)").unwrap();
                static ref RE2: regex::Regex = regex::Regex::new("EVAL_RESULT #b([0-1]+)").unwrap();
            }

            // check for base16-encoded value
            if let Some(caps) = RE16.captures(&solver_output) {
                let value = u64::from_str_radix(&caps[1], 16)?;
                return Ok(Some(il::const_(value, expr.bits())));
            }

            // check for base2-encoded value
            if let Some(caps) = RE2.captures(&solver_output) {
                let value = u64::from_str_radix(&caps[1], 2)?;
                return Ok(Some(il::const_(value, expr.bits())));
            }

            // thread::sleep(time::Duration::from_millis(1000));
        }

        bail!("Read from solver 5 times, did not find a result");
    }
}

impl Clone for Solver {
    fn clone(&self) -> Solver {
        Solver::new().expect("Failed to create new Solver while cloning Solver")
    }
}

impl Default for Solver {
    fn default() -> Solver {
        Solver::new().unwrap()
    }
}

impl Drop for Solver {
    fn drop(&mut self) {
        self.child.kill().expect("Failed to kill solver during drop");
        self.child.wait().expect("Error waiting on solver after drop kill");
    }
}<commit_msg>comment out cow solver for now<commit_after>//! A layer of abstraction over a SMT solver

use engine::util::*;
use error::*;
use il;
use regex;
use std::collections::BTreeSet;
use std::io::{Read, Write};
use std::process;

// pub struct Solver {
//     child: process::Child
// }

pub struct Solver;

impl Solver {
    pub fn new() -> Result<Solver> {
        // let mut child = process::Command::new("z3")
        //     .arg("-in")
        //     .stdin(process::Stdio::piped())
        //     .stdout(process::Stdio::piped())
        //     .stderr(process::Stdio::piped())
        //     .spawn()
        //     .expect("Failed to invoke solver");

        // if let Some(ref mut stdin) = child.stdin {
        //     stdin.write("(set-option :produce-models true)\n".as_bytes())?;
        //     stdin.write("(set-logic QF_AUFBV)\n".as_bytes())?;
        //     stdin.write("(set-info :smt-lib-version 2.0)\n".as_bytes())?;
        // }
        // else {
        //     bail!("Failed to get stdout for child");
        // }

        // Ok(Solver {
        //     child: child
        // })

        Ok(Solver)
    }

    pub fn get_child(&mut self) -> Result<process::Child> {
        let mut child = process::Command::new("z3")
            .arg("-in")
            .stdin(process::Stdio::piped())
            .stdout(process::Stdio::piped())
            .stderr(process::Stdio::piped())
            .spawn()
            .expect("Failed to invoke solver");

        if let Some(ref mut stdin) = child.stdin {
            stdin.write("(set-option :produce-models true)\n".as_bytes())?;
            stdin.write("(set-logic QF_AUFBV)\n".as_bytes())?;
            stdin.write("(set-info :smt-lib-version 2.0)\n".as_bytes())?;
        }
        else {
            bail!("Failed to get stdout for child");
        }

        Ok(child)
    }

    pub fn cleanup_child(&mut self, mut child: &mut process::Child) -> Result<()> {
        child.kill().expect("Failed to kill solver during drop");
        child.wait().expect("Error waiting on solver after drop kill");

        Ok(())
    }

    pub fn solve(&mut self, expr: &il::Expression, constraints: Vec<il::Expression>)
    -> Result<Option<il::Constant>> {

        // We need to collect all of the scalars so we can declare them
        let mut scalars: BTreeSet<(String, usize)> = BTreeSet::new();

        // Collect all scalars from constraints
        for constraint in &constraints {
            for scalar in constraint.collect_scalars() {
                scalars.insert((scalar.name().to_string(), scalar.bits()));
            }
        }

        // And all scalars from the expression we are solving
        for scalar in expr.collect_scalars() {
            scalars.insert((scalar.name().to_string(), scalar.bits()));
        }

        // And a scalar for our result
        scalars.insert(("EVAL_RESULT".to_string(), expr.bits()));

        // Push state
        let mut solver_lines = vec!["(push)".to_string()];

        // Declare all variables
        for scalar in scalars {
            solver_lines.push(format!("(declare-fun {} () (_ BitVec {}))",
                scalar.0, scalar.1));
        }

        // Assert Constraints
        for constraint in constraints {
            solver_lines.push(format!("(assert (= #b1 {}))",
                expr_to_smtlib2(&constraint)));
        }

        // Assert the expression
        solver_lines.push(format!("(assert (= EVAL_RESULT {}))",
            expr_to_smtlib2(expr)));

        // Get value and pop this state
        solver_lines.push("(check-sat)".to_string());
        solver_lines.push("(get-value (EVAL_RESULT))".to_string());
        solver_lines.push("(pop)\n".to_string());

        let solver_input = solver_lines.join("\n");

        let mut child = self.get_child()?;

        // match self.child.stdin {
        match child.stdin {
            Some(ref mut stdin) => {
                stdin.write_all(solver_input.as_bytes())?;
                stdin.flush()?;
            },
            None => {
                self.cleanup_child(&mut child)?;
                bail!("Failed to get stdin from solver process")
            }
        }

        for _ in 0..5 {
            let mut buf = [0; 2048];

            // read from stdout
            // let bytes_read = match self.child.stdout {
            let bytes_read = match child.stdout {
                Some(ref mut stdout) => stdout.read(&mut buf)?,
                None => {
                    self.cleanup_child(&mut child)?;
                    bail!("Failed to get stdout from solver proces")
                }
            };

            let buf = if bytes_read == 0 {
                self.cleanup_child(&mut child)?;
                bail!("Read 0 bytes from solver")
            } else {
                buf.split_at(bytes_read).0.to_vec()
            };

            let solver_output = String::from_utf8(buf)?;

            // check if we got unsat
            if solver_output.contains("unsat") {
                self.cleanup_child(&mut child)?;
                return Ok(None);
            }

            lazy_static!{
                static ref RE16: regex::Regex = regex::Regex::new("EVAL_RESULT #x([0-9a-f]+)").unwrap();
                static ref RE2: regex::Regex = regex::Regex::new("EVAL_RESULT #b([0-1]+)").unwrap();
            }

            // check for base16-encoded value
            if let Some(caps) = RE16.captures(&solver_output) {
                let value = u64::from_str_radix(&caps[1], 16)?;
                self.cleanup_child(&mut child)?;
                return Ok(Some(il::const_(value, expr.bits())));
            }

            // check for base2-encoded value
            if let Some(caps) = RE2.captures(&solver_output) {
                let value = u64::from_str_radix(&caps[1], 2)?;
                self.cleanup_child(&mut child)?;
                return Ok(Some(il::const_(value, expr.bits())));
            }

        }

        self.cleanup_child(&mut child)?;
        bail!("Read from solver 5 times, did not find a result");
    }
}

impl Clone for Solver {
    fn clone(&self) -> Solver {
        Solver::new().expect("Failed to create new Solver while cloning Solver")
    }
}

impl Default for Solver {
    fn default() -> Solver {
        Solver::new().unwrap()
    }
}

impl Drop for Solver {
    fn drop(&mut self) {
        // self.child.kill().expect("Failed to kill solver during drop");
        // self.child.wait().expect("Error waiting on solver after drop kill");
    }
}<|endoftext|>


<commit_before>use ext::TokenStreamExt;
pub use proc_macro2::*;

fn is_ident_start(c: u8) -> bool {
    (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_'
}

fn is_ident_continue(c: u8) -> bool {
    (b'a' <= c && c <= b'z')
        || (b'A' <= c && c <= b'Z')
        || c == b'_'
        || (b'0' <= c && c <= b'9')
}

fn is_ident(token: &str) -> bool {
    if token.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
        return false;
    }

    let mut bytes = token.bytes();
    let first = bytes.next().unwrap();
    if !is_ident_start(first) {
        return false;
    }
    for ch in bytes {
        if !is_ident_continue(ch) {
            return false;
        }
    }
    true
}

pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) {
    if is_ident(s) {
        // Fast path, since idents are the most common token.
        tokens.append(Ident::new(s, span));
    } else {
        let s: TokenStream = s.parse().expect("invalid token stream");
        tokens.extend(s.into_iter().map(|mut t| {
            t.set_span(span);
            t
        }));
    }
}

macro_rules! push_punct {
    ($name:ident $char1:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
    ($name:ident $char1:tt $char2:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char2, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
    ($name:ident $char1:tt $char2:tt $char3:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char2, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char3, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
}

push_punct!(push_add '+');
push_punct!(push_add_eq '+' '=');
push_punct!(push_and '&');
push_punct!(push_and_and '&' '&');
push_punct!(push_and_eq '&' '=');
push_punct!(push_at '@');
push_punct!(push_bang '!');
push_punct!(push_caret '^');
push_punct!(push_caret_eq '^' '=');
push_punct!(push_colon ':');
push_punct!(push_colon2 ':' ':');
push_punct!(push_comma ',');
push_punct!(push_div '/');
push_punct!(push_div_eq '/' '=');
push_punct!(push_dot '.');
push_punct!(push_dot2 '.' '.');
push_punct!(push_dot3 '.' '.' '.');
push_punct!(push_dot_dot_eq '.' '.' '=');
push_punct!(push_eq '=');
push_punct!(push_eq_eq '=' '=');
push_punct!(push_ge '>' '=');
push_punct!(push_gt '>');
push_punct!(push_le '<' '=');
push_punct!(push_lt '<');
push_punct!(push_mul_eq '*' '=');
push_punct!(push_ne '!' '=');
push_punct!(push_or '|');
push_punct!(push_or_eq '|' '=');
push_punct!(push_or_or '|' '|');
push_punct!(push_pound '#');
push_punct!(push_question '?');
push_punct!(push_rarrow '-' '>');
push_punct!(push_larrow '<' '-');
push_punct!(push_rem '%');
push_punct!(push_rem_eq '%' '=');
push_punct!(push_fat_arrow '=' '>');
push_punct!(push_semi ';');
push_punct!(push_shl '<' '<');
push_punct!(push_shl_eq '<' '<' '=');
push_punct!(push_shr '>' '>');
push_punct!(push_shr_eq '>' '>' '=');
push_punct!(push_star '*');
push_punct!(push_sub '-');
push_punct!(push_sub_eq '-' '=');
<commit_msg>Format with rustfmt 2018-12-10<commit_after>use ext::TokenStreamExt;
pub use proc_macro2::*;

fn is_ident_start(c: u8) -> bool {
    (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_'
}

fn is_ident_continue(c: u8) -> bool {
    (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_' || (b'0' <= c && c <= b'9')
}

fn is_ident(token: &str) -> bool {
    if token.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
        return false;
    }

    let mut bytes = token.bytes();
    let first = bytes.next().unwrap();
    if !is_ident_start(first) {
        return false;
    }
    for ch in bytes {
        if !is_ident_continue(ch) {
            return false;
        }
    }
    true
}

pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) {
    if is_ident(s) {
        // Fast path, since idents are the most common token.
        tokens.append(Ident::new(s, span));
    } else {
        let s: TokenStream = s.parse().expect("invalid token stream");
        tokens.extend(s.into_iter().map(|mut t| {
            t.set_span(span);
            t
        }));
    }
}

macro_rules! push_punct {
    ($name:ident $char1:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
    ($name:ident $char1:tt $char2:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char2, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
    ($name:ident $char1:tt $char2:tt $char3:tt) => {
        pub fn $name(tokens: &mut TokenStream, span: Span) {
            let mut punct = Punct::new($char1, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char2, Spacing::Joint);
            punct.set_span(span);
            tokens.append(punct);
            let mut punct = Punct::new($char3, Spacing::Alone);
            punct.set_span(span);
            tokens.append(punct);
        }
    };
}

push_punct!(push_add '+');
push_punct!(push_add_eq '+' '=');
push_punct!(push_and '&');
push_punct!(push_and_and '&' '&');
push_punct!(push_and_eq '&' '=');
push_punct!(push_at '@');
push_punct!(push_bang '!');
push_punct!(push_caret '^');
push_punct!(push_caret_eq '^' '=');
push_punct!(push_colon ':');
push_punct!(push_colon2 ':' ':');
push_punct!(push_comma ',');
push_punct!(push_div '/');
push_punct!(push_div_eq '/' '=');
push_punct!(push_dot '.');
push_punct!(push_dot2 '.' '.');
push_punct!(push_dot3 '.' '.' '.');
push_punct!(push_dot_dot_eq '.' '.' '=');
push_punct!(push_eq '=');
push_punct!(push_eq_eq '=' '=');
push_punct!(push_ge '>' '=');
push_punct!(push_gt '>');
push_punct!(push_le '<' '=');
push_punct!(push_lt '<');
push_punct!(push_mul_eq '*' '=');
push_punct!(push_ne '!' '=');
push_punct!(push_or '|');
push_punct!(push_or_eq '|' '=');
push_punct!(push_or_or '|' '|');
push_punct!(push_pound '#');
push_punct!(push_question '?');
push_punct!(push_rarrow '-' '>');
push_punct!(push_larrow '<' '-');
push_punct!(push_rem '%');
push_punct!(push_rem_eq '%' '=');
push_punct!(push_fat_arrow '=' '>');
push_punct!(push_semi ';');
push_punct!(push_shl '<' '<');
push_punct!(push_shl_eq '<' '<' '=');
push_punct!(push_shr '>' '>');
push_punct!(push_shr_eq '>' '>' '=');
push_punct!(push_star '*');
push_punct!(push_sub '-');
push_punct!(push_sub_eq '-' '=');
<|endoftext|>


<commit_before>use std::{fmt, error, io};

use regex;

pub struct Error;

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Internal error")
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Internal error")
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        "Something happened!"
    }
}

impl From<regex::Error> for Error {
    fn from(_error: regex::Error) -> Self {
        Error
    }
}

impl From<io::Error> for Error {
    fn from(_error: io::Error) -> Self {
        Error
    }
}
<commit_msg>Use the original error messages in the new Error type<commit_after>use std::{fmt, error, io};
use regex;

pub struct Error {
    display: String,
    debug: String,
    description: String,
}

impl Error {
    pub fn import<E: fmt::Display + fmt::Debug + error::Error>(error: E) -> Self {
        let display = format!("{}", error);
        let debug = format!("{:?}", error);
        let description = error.description().to_owned();

        Error {
            display,
            debug,
            description,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.display)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.debug)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        &self.description
    }
}

impl From<regex::Error> for Error {
    fn from(error: regex::Error) -> Self {
        Error::import(error)
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Error::import(error)
    }
}
<|endoftext|>


<commit_before>//! Provides types and functions related to working with PostgreSQL
//!
//! Much of this module is re-exported from database agnostic locations.
//! However, if you are writing code specifically to extend Diesel on
//! PostgreSQL, you may need to work with this module directly.

pub mod expression;
pub mod types;

mod backend;
mod connection;
mod metadata_lookup;
pub(crate) mod query_builder;
pub(crate) mod serialize;
mod transaction;
mod value;

pub use self::backend::{Pg, PgTypeMetadata};
pub use self::connection::PgConnection;
pub use self::query_builder::DistinctOnClause;
pub use self::query_builder::PgQueryBuilder;
pub use self::transaction::TransactionBuilder;
pub use self::value::PgValue;
#[doc(hidden)]
pub use self::metadata_lookup::{PgMetadataLookup, GetPgMetadataCache, PgMetadataCache};
#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[deprecated(since = "2.0.0", note = "Use `diesel::upsert` instead")]
pub use crate::upsert;

/// Data structures for PG types which have no corresponding Rust type
///
/// Most of these types are used to implement `ToSql` and `FromSql` for higher
/// level types.
pub mod data_types {
    #[doc(inline)]
    pub use super::types::date_and_time::{PgDate, PgInterval, PgTime, PgTimestamp};
    #[doc(inline)]
    pub use super::types::floats::PgNumeric;
    #[doc(inline)]
    pub use super::types::money::PgMoney;
    pub use super::types::money::PgMoney as Cents;
}
<commit_msg>style: :art: cargo fmt<commit_after>//! Provides types and functions related to working with PostgreSQL
//!
//! Much of this module is re-exported from database agnostic locations.
//! However, if you are writing code specifically to extend Diesel on
//! PostgreSQL, you may need to work with this module directly.

pub mod expression;
pub mod types;

mod backend;
mod connection;
mod metadata_lookup;
pub(crate) mod query_builder;
pub(crate) mod serialize;
mod transaction;
mod value;

pub use self::backend::{Pg, PgTypeMetadata};
pub use self::connection::PgConnection;
#[doc(hidden)]
pub use self::metadata_lookup::{GetPgMetadataCache, PgMetadataCache, PgMetadataLookup};
pub use self::query_builder::DistinctOnClause;
pub use self::query_builder::PgQueryBuilder;
pub use self::transaction::TransactionBuilder;
pub use self::value::PgValue;
#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[deprecated(since = "2.0.0", note = "Use `diesel::upsert` instead")]
pub use crate::upsert;

/// Data structures for PG types which have no corresponding Rust type
///
/// Most of these types are used to implement `ToSql` and `FromSql` for higher
/// level types.
pub mod data_types {
    #[doc(inline)]
    pub use super::types::date_and_time::{PgDate, PgInterval, PgTime, PgTimestamp};
    #[doc(inline)]
    pub use super::types::floats::PgNumeric;
    #[doc(inline)]
    pub use super::types::money::PgMoney;
    pub use super::types::money::PgMoney as Cents;
}
<|endoftext|>


<commit_before>
pub struct Scanner {
    source: String,
    tokens: Vec<Token>,
    start: usize,
    current: usize,
    line: i32,
}

impl Scanner {
    pub fn new(source: String) -> Self {
        Scanner {
            source: source,
            tokens: Vec::new(),
            start: 0,
            current: 0,
            line: 1,
        }
    }

    pub fn scan_tokens(&mut self) -> Vec<Token> {
        while !self.is_at_end() {
            self.start = self.current;
            match self.scan_token() {
                Ok(token) => self.tokens.push(token),
                Err(s) => {}
            }
        }
        self.tokens.push(Token::new(TokenType::EOF, "", self.line));
        self.tokens.to_vec()
    }

    fn is_at_end(&self) -> bool {
        self.current >= self.source.len()
    }

    fn scan_token(&mut self) -> Result<Token, ScanError> {
        let c = self.advance();
        match c {
            '(' => Ok(self.create_token(TokenType::LEFT_PAREN)),
            ')' => Ok(self.create_token(TokenType::RIGHT_PAREN)),
            '{' => Ok(self.create_token(TokenType::LEFT_BRACE)),
            '}' => Ok(self.create_token(TokenType::RIGHT_BRACE)),
            ',' => Ok(self.create_token(TokenType::COMMA)),
            '.' => Ok(self.create_token(TokenType::DOT)),
            '-' => Ok(self.create_token(TokenType::MINUS)),
            '+' => Ok(self.create_token(TokenType::PLUS)),
            ';' => Ok(self.create_token(TokenType::SEMICOLON)),
            '*' => Ok(self.create_token(TokenType::STAR)),
            '!' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::BANG_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::BANG))
                }
            }
            '=' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::EQUAL_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::EQUAL))
                }
            }
            '<' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::LESS_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::LESS))
                }
            }
            '>' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::GREATER_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::GREATER))
                }
            }
            _ => Err(ScanError::new(self.line, "Unexpected character.")),
        }
    }

    fn match_char(&self, c: char) -> bool {
        if self.is_at_end() {
            return false;
        }
        let b = self.source.as_bytes();
        b[self.current] as char == c
    }

    fn advance(&mut self) -> char {
        self.current += 1;
        let b = self.source.as_bytes();
        b[self.current - 1] as char
    }

    fn create_token(&self, token_type: TokenType) -> Token {
        let s = &self.source[self.start as usize..self.current as usize];
        Token::new(token_type, s, self.line)
    }
}

#[derive(Clone, Debug)]
pub struct Token {
    token_type: TokenType,
    lexeme: String,
    line: i32,
}

impl Token {
    pub fn new(token_type: TokenType, lexeme: &str, line: i32) -> Self {
        Token {
            token_type: token_type,
            lexeme: lexeme.to_owned(),
            line: line,
        }
    }
}

#[derive(Clone, Debug)]
#[allow(non_camel_case_types)]
pub enum TokenType {
    // Single-character tokens.
    LEFT_PAREN,
    RIGHT_PAREN,
    LEFT_BRACE,
    RIGHT_BRACE,
    COMMA,
    DOT,
    MINUS,
    PLUS,
    SEMICOLON,
    SLASH,
    STAR,

    // One or two character tokens.
    BANG,
    BANG_EQUAL,
    EQUAL,
    EQUAL_EQUAL,
    GREATER,
    GREATER_EQUAL,
    LESS,
    LESS_EQUAL,

    // Literals.
    IDENTIFIER,
    STRING,
    NUMBER,

    // Keywords.
    AND,
    CLASS,
    ELSE,
    FALSE,
    FUN,
    FOR,
    IF,
    NIL,
    OR,
    PRINT,
    RETURN,
    SUPER,
    THIS,
    TRUE,
    VAR,
    WHILE,

    EOF,
}

struct ScanError {
    line: i32,
    message: String,
}

impl ScanError {
    fn new(line: i32, message: &str) -> Self {
        ScanError {
            line: line,
            message: message.to_owned(),
        }
    }
}
<commit_msg>Scan error should be public<commit_after>
pub struct Scanner {
    source: String,
    tokens: Vec<Token>,
    start: usize,
    current: usize,
    line: i32,
}

impl Scanner {
    pub fn new(source: String) -> Self {
        Scanner {
            source: source,
            tokens: Vec::new(),
            start: 0,
            current: 0,
            line: 1,
        }
    }

    pub fn scan_tokens(&mut self) -> Vec<Token> {
        while !self.is_at_end() {
            self.start = self.current;
            match self.scan_token() {
                Ok(token) => self.tokens.push(token),
                Err(s) => {}
            }
        }
        self.tokens.push(Token::new(TokenType::EOF, "", self.line));
        self.tokens.to_vec()
    }

    fn is_at_end(&self) -> bool {
        self.current >= self.source.len()
    }

    fn scan_token(&mut self) -> Result<Token, ScanError> {
        let c = self.advance();
        match c {
            '(' => Ok(self.create_token(TokenType::LEFT_PAREN)),
            ')' => Ok(self.create_token(TokenType::RIGHT_PAREN)),
            '{' => Ok(self.create_token(TokenType::LEFT_BRACE)),
            '}' => Ok(self.create_token(TokenType::RIGHT_BRACE)),
            ',' => Ok(self.create_token(TokenType::COMMA)),
            '.' => Ok(self.create_token(TokenType::DOT)),
            '-' => Ok(self.create_token(TokenType::MINUS)),
            '+' => Ok(self.create_token(TokenType::PLUS)),
            ';' => Ok(self.create_token(TokenType::SEMICOLON)),
            '*' => Ok(self.create_token(TokenType::STAR)),
            '!' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::BANG_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::BANG))
                }
            }
            '=' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::EQUAL_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::EQUAL))
                }
            }
            '<' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::LESS_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::LESS))
                }
            }
            '>' => {
                if self.match_char('=') {
                    self.advance();
                    Ok(self.create_token(TokenType::GREATER_EQUAL))
                } else {
                    Ok(self.create_token(TokenType::GREATER))
                }
            }
            _ => Err(ScanError::new(self.line, "Unexpected character.")),
        }
    }

    fn match_char(&self, c: char) -> bool {
        if self.is_at_end() {
            return false;
        }
        let b = self.source.as_bytes();
        b[self.current] as char == c
    }

    fn advance(&mut self) -> char {
        self.current += 1;
        let b = self.source.as_bytes();
        b[self.current - 1] as char
    }

    fn create_token(&self, token_type: TokenType) -> Token {
        let s = &self.source[self.start as usize..self.current as usize];
        Token::new(token_type, s, self.line)
    }
}

#[derive(Clone, Debug)]
pub struct Token {
    token_type: TokenType,
    lexeme: String,
    line: i32,
}

impl Token {
    pub fn new(token_type: TokenType, lexeme: &str, line: i32) -> Self {
        Token {
            token_type: token_type,
            lexeme: lexeme.to_owned(),
            line: line,
        }
    }
}

#[derive(Clone, Debug)]
#[allow(non_camel_case_types)]
pub enum TokenType {
    // Single-character tokens.
    LEFT_PAREN,
    RIGHT_PAREN,
    LEFT_BRACE,
    RIGHT_BRACE,
    COMMA,
    DOT,
    MINUS,
    PLUS,
    SEMICOLON,
    SLASH,
    STAR,

    // One or two character tokens.
    BANG,
    BANG_EQUAL,
    EQUAL,
    EQUAL_EQUAL,
    GREATER,
    GREATER_EQUAL,
    LESS,
    LESS_EQUAL,

    // Literals.
    IDENTIFIER,
    STRING,
    NUMBER,

    // Keywords.
    AND,
    CLASS,
    ELSE,
    FALSE,
    FUN,
    FOR,
    IF,
    NIL,
    OR,
    PRINT,
    RETURN,
    SUPER,
    THIS,
    TRUE,
    VAR,
    WHILE,

    EOF,
}

pub struct ScanError {
    line: i32,
    message: String,
}

impl ScanError {
    fn new(line: i32, message: &str) -> Self {
        ScanError {
            line: line,
            message: message.to_owned(),
        }
    }
}
<|endoftext|>


<commit_before>use crate::session::error::TimeMicrosConversionError;

/// Coverts time from protobuf micros (defined as microseconds from epoch
/// time: 1970-01-01T00:00:00.000000000Z) to `std::time::SystemTime`.
pub fn time_from_micros(
    micros: u64,
) -> Result<std::time::SystemTime, TimeMicrosConversionError> {
    let result = std::time::UNIX_EPOCH
        .checked_add(std::time::Duration::from_micros(micros));

    result.ok_or(TimeMicrosConversionError { micros })
}
<commit_msg>Add a TODO comment.<commit_after>use crate::session::error::TimeMicrosConversionError;

// TODO: What is this function doing here? This module has nothing in common
// with the `session` module.

/// Coverts time from protobuf micros (defined as microseconds from epoch
/// time: 1970-01-01T00:00:00.000000000Z) to `std::time::SystemTime`.
pub fn time_from_micros(
    micros: u64,
) -> Result<std::time::SystemTime, TimeMicrosConversionError> {
    let result = std::time::UNIX_EPOCH
        .checked_add(std::time::Duration::from_micros(micros));

    result.ok_or(TimeMicrosConversionError { micros })
}
<|endoftext|>


<commit_before>/* Function pointer types */
// Will have to be changed once we can do external C callbacks nicely

pub type GLFWglproc             = *u8;  // typedef void (*GLFWglproc)(void);

pub type GLFWerrorfun           = *u8;  // typedef void (* GLFWerrorfun)(int,const char*);
pub type GLFWwindowposfun       = *u8;  // typedef void (* GLFWwindowposfun)(*GLFWwindow,int,int);
pub type GLFWwindowsizefun      = *u8;  // typedef void (* GLFWwindowsizefun)(*GLFWwindow,int,int);
pub type GLFWwindowclosefun     = *u8;  // typedef void (* GLFWwindowclosefun)(*GLFWwindow);
pub type GLFWwindowrefreshfun   = *u8;  // typedef void (* GLFWwindowrefreshfun)(*GLFWwindow);
pub type GLFWwindowfocusfun     = *u8;  // typedef void (* GLFWwindowfocusfun)(*GLFWwindow,int);
pub type GLFWwindowiconifyfun   = *u8;  // typedef void (* GLFWwindowiconifyfun)(*GLFWwindow,int);
pub type GLFWmousebuttonfun     = *u8;  // typedef void (* GLFWmousebuttonfun)(*GLFWwindow,int,int);
pub type GLFWcursorposfun       = *u8;  // typedef void (* GLFWcursorposfun)(*GLFWwindow,int,int);
pub type GLFWcursorenterfun     = *u8;  // typedef void (* GLFWcursorenterfun)(*GLFWwindow,int);
pub type GLFWscrollfun          = *u8;  // typedef void (* GLFWscrollfun)(*GLFWwindow,double,double);
pub type GLFWkeyfun             = *u8;  // typedef void (* GLFWkeyfun)(*GLFWwindow,int,int);
pub type GLFWcharfun            = *u8;  // typedef void (* GLFWcharfun)(*GLFWwindow,unsigned int);
pub type GLFWmonitorfun         = *u8;  // typedef void (* GLFWmonitorfun)(*GLFWmonitor,int);

/* Monitor handle type */
pub struct GLFWmonitor {}

/* Window handle type */
pub struct GLFWwindow {}

pub type GLFWgammaramp = ::hl::GammaRamp;
pub type GLFWvidmode   = ::hl::VidMode;<commit_msg>Use unit structs for monitor and window handles<commit_after>/* Function pointer types */
// Will have to be changed once we can do external C callbacks nicely

pub type GLFWglproc             = *u8;  // typedef void (*GLFWglproc)(void);

pub type GLFWerrorfun           = *u8;  // typedef void (* GLFWerrorfun)(int,const char*);
pub type GLFWwindowposfun       = *u8;  // typedef void (* GLFWwindowposfun)(*GLFWwindow,int,int);
pub type GLFWwindowsizefun      = *u8;  // typedef void (* GLFWwindowsizefun)(*GLFWwindow,int,int);
pub type GLFWwindowclosefun     = *u8;  // typedef void (* GLFWwindowclosefun)(*GLFWwindow);
pub type GLFWwindowrefreshfun   = *u8;  // typedef void (* GLFWwindowrefreshfun)(*GLFWwindow);
pub type GLFWwindowfocusfun     = *u8;  // typedef void (* GLFWwindowfocusfun)(*GLFWwindow,int);
pub type GLFWwindowiconifyfun   = *u8;  // typedef void (* GLFWwindowiconifyfun)(*GLFWwindow,int);
pub type GLFWmousebuttonfun     = *u8;  // typedef void (* GLFWmousebuttonfun)(*GLFWwindow,int,int);
pub type GLFWcursorposfun       = *u8;  // typedef void (* GLFWcursorposfun)(*GLFWwindow,int,int);
pub type GLFWcursorenterfun     = *u8;  // typedef void (* GLFWcursorenterfun)(*GLFWwindow,int);
pub type GLFWscrollfun          = *u8;  // typedef void (* GLFWscrollfun)(*GLFWwindow,double,double);
pub type GLFWkeyfun             = *u8;  // typedef void (* GLFWkeyfun)(*GLFWwindow,int,int);
pub type GLFWcharfun            = *u8;  // typedef void (* GLFWcharfun)(*GLFWwindow,unsigned int);
pub type GLFWmonitorfun         = *u8;  // typedef void (* GLFWmonitorfun)(*GLFWmonitor,int);

/* Monitor handle type */
pub struct GLFWmonitor;

/* Window handle type */
pub struct GLFWwindow;

pub type GLFWgammaramp = ::hl::GammaRamp;
pub type GLFWvidmode   = ::hl::VidMode;<|endoftext|>


<commit_before>extern crate mdbook;
#[macro_use]
extern crate lazy_static;

mod dummy_book;

use dummy_book::DummyBook;

use mdbook::MDBook;
use mdbook::preprocess::{Preprocessor, PreprocessorContext};
use mdbook::book::Book;
use mdbook::config::Config;
use mdbook::errors::*;

use std::sync::Mutex;

#[test]
fn mdbook_can_correctly_test_a_passing_book() {
    let temp = DummyBook::new().with_passing_test(true).build().unwrap();
    let mut md = MDBook::load(temp.path()).unwrap();

    assert!(md.test(vec![]).is_ok());
}

#[test]
fn mdbook_detects_book_with_failing_tests() {
    let temp = DummyBook::new().with_passing_test(false).build().unwrap();
    let mut md: MDBook = MDBook::load(temp.path()).unwrap();

    assert!(md.test(vec![]).is_err());
}

#[test]
fn mdbook_runs_preprocessors() {

    lazy_static! {
        static ref HAS_RUN: Mutex<bool> = Mutex::new(false);
    }

    struct DummyPreprocessor;

    impl Preprocessor for DummyPreprocessor {
        fn name(&self) -> &str {
            "dummy"
        }

        fn run(&self, _ctx: &PreprocessorContext, _book: &mut Book) -> Result<()> {
            *HAS_RUN.lock().unwrap() = true;
            Ok(())
        }
    }

    let temp = DummyBook::new().build().unwrap();
    let cfg = Config::default();

    let mut book = MDBook::load_with_config(temp.path(), cfg).unwrap();
    book.with_preprecessor(DummyPreprocessor);
    book.build().unwrap();

    assert!(*HAS_RUN.lock().unwrap())
}
<commit_msg>Use Arc instead of lazy_static for dummy preprocessor<commit_after>extern crate mdbook;

mod dummy_book;

use dummy_book::DummyBook;

use mdbook::MDBook;
use mdbook::preprocess::{Preprocessor, PreprocessorContext};
use mdbook::book::Book;
use mdbook::config::Config;
use mdbook::errors::*;

use std::sync::{Arc, Mutex};

#[test]
fn mdbook_can_correctly_test_a_passing_book() {
    let temp = DummyBook::new().with_passing_test(true).build().unwrap();
    let mut md = MDBook::load(temp.path()).unwrap();

    assert!(md.test(vec![]).is_ok());
}

#[test]
fn mdbook_detects_book_with_failing_tests() {
    let temp = DummyBook::new().with_passing_test(false).build().unwrap();
    let mut md: MDBook = MDBook::load(temp.path()).unwrap();

    assert!(md.test(vec![]).is_err());
}

#[test]
fn mdbook_runs_preprocessors() {

    let has_run: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));

    struct DummyPreprocessor(Arc<Mutex<bool>>);

    impl Preprocessor for DummyPreprocessor {
        fn name(&self) -> &str {
            "dummy"
        }

        fn run(&self, _ctx: &PreprocessorContext, _book: &mut Book) -> Result<()> {
            *self.0.lock().unwrap() = true;
            Ok(())
        }
    }

    let temp = DummyBook::new().build().unwrap();
    let cfg = Config::default();

    let mut book = MDBook::load_with_config(temp.path(), cfg).unwrap();
    book.with_preprecessor(DummyPreprocessor(Arc::clone(&has_run)));
    book.build().unwrap();

    assert!(*has_run.lock().unwrap())
}
<|endoftext|>


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

//! Base64 binary-to-text encoding

use core::iter;
use core::str;
use core::vec;

pub trait ToBase64 {
    fn to_base64(&self) -> ~str;
}

static CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     * }
     * ~~~~
     */
    fn to_base64(&self) -> ~str {
        let mut s = ~"";
        let len = self.len();
        str::reserve(&mut s, ((len + 3u) / 4u) * 3u);

        let mut i = 0u;

        while i < len - (len % 3u) {
            let n = (self[i] as uint) << 16u |
                    (self[i + 1u] as uint) << 8u |
                    (self[i + 2u] as uint);

            // This 24-bit number gets separated into four 6-bit numbers.
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, CHARS[n & 63u]);

            i += 3u;
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
          0 => (),
          1 => {
            let n = (self[i] as uint) << 16u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, '=');
            str::push_char(&mut s, '=');
          }
          2 => {
            let n = (self[i] as uint) << 16u |
                (self[i + 1u] as uint) << 8u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, '=');
          }
          _ => fail!(~"Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = "Hello, World".to_base64();
     *     println(fmt!("%s",str));
     * }
     * ~~~~
     *
     */
    fn to_base64(&self) -> ~str {
        str::to_bytes(*self).to_base64()
    }
}

pub trait FromBase64 {
    fn from_base64(&self) -> ~[u8];
}

impl FromBase64 for ~[u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, rem padding.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        if self.len() % 4u != 0u { fail!(~"invalid base64 length"); }

        let len = self.len();
        let mut padding = 0u;

        if len != 0u {
            if self[len - 1u] == '=' as u8 { padding += 1u; }
            if self[len - 2u] == '=' as u8 { padding += 1u; }
        }

        let mut r = vec::with_capacity((len / 4u) * 3u - padding);

        let mut i = 0u;
        while i < len {
            let mut n = 0u;

            for iter::repeat(4u) {
                let ch = self[i] as char;
                n <<= 6u;

                if ch >= 'A' && ch <= 'Z' {
                    n |= (ch as uint) - 0x41u;
                } else if ch >= 'a' && ch <= 'z' {
                    n |= (ch as uint) - 0x47u;
                } else if ch >= '0' && ch <= '9' {
                    n |= (ch as uint) + 0x04u;
                } else if ch == '+' {
                    n |= 0x3Eu;
                } else if ch == '/' {
                    n |= 0x3Fu;
                } else if ch == '=' {
                    match len - i {
                      1u => {
                        r.push(((n >> 16u) & 0xFFu) as u8);
                        r.push(((n >> 8u ) & 0xFFu) as u8);
                        return copy r;
                      }
                      2u => {
                        r.push(((n >> 10u) & 0xFFu) as u8);
                        return copy r;
                      }
                      _ => fail!(~"invalid base64 padding")
                    }
                } else {
                    fail!(~"invalid base64 character");
                }

                i += 1u;
            };

            r.push(((n >> 16u) & 0xFFu) as u8);
            r.push(((n >> 8u ) & 0xFFu) as u8);
            r.push(((n       ) & 0xFFu) as u8);
        }
        r
    }
}

impl FromBase64 for ~str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `core::str`
     * to turn a `[u8]` into a string with characters corresponding to those values.
     *
     * *Example*:
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     * use core::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64();
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        str::to_bytes(*self).from_base64()
    }
}

#[cfg(test)]
mod tests {
    use core::str;

    #[test]
    fn test_to_base64() {
        assert!((~"").to_base64()       == ~"");
        assert!((~"f").to_base64()      == ~"Zg==");
        assert!((~"fo").to_base64()     == ~"Zm8=");
        assert!((~"foo").to_base64()    == ~"Zm9v");
        assert!((~"foob").to_base64()   == ~"Zm9vYg==");
        assert!((~"fooba").to_base64()  == ~"Zm9vYmE=");
        assert!((~"foobar").to_base64() == ~"Zm9vYmFy");
    }

    #[test]
    fn test_from_base64() {
        assert!((~"").from_base64() == str::to_bytes(~""));
        assert!((~"Zg==").from_base64() == str::to_bytes(~"f"));
        assert!((~"Zm8=").from_base64() == str::to_bytes(~"fo"));
        assert!((~"Zm9v").from_base64() == str::to_bytes(~"foo"));
        assert!((~"Zm9vYg==").from_base64() == str::to_bytes(~"foob"));
        assert!((~"Zm9vYmE=").from_base64() == str::to_bytes(~"fooba"));
        assert!((~"Zm9vYmFy").from_base64() == str::to_bytes(~"foobar"));
    }
}
<commit_msg>Fix incorrect replacement of `modulo` with `rem`<commit_after>// Copyright 2012-2013 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.

//! Base64 binary-to-text encoding

use core::iter;
use core::str;
use core::vec;

pub trait ToBase64 {
    fn to_base64(&self) -> ~str;
}

static CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     * }
     * ~~~~
     */
    fn to_base64(&self) -> ~str {
        let mut s = ~"";
        let len = self.len();
        str::reserve(&mut s, ((len + 3u) / 4u) * 3u);

        let mut i = 0u;

        while i < len - (len % 3u) {
            let n = (self[i] as uint) << 16u |
                    (self[i + 1u] as uint) << 8u |
                    (self[i + 2u] as uint);

            // This 24-bit number gets separated into four 6-bit numbers.
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, CHARS[n & 63u]);

            i += 3u;
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
          0 => (),
          1 => {
            let n = (self[i] as uint) << 16u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, '=');
            str::push_char(&mut s, '=');
          }
          2 => {
            let n = (self[i] as uint) << 16u |
                (self[i + 1u] as uint) << 8u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, '=');
          }
          _ => fail!(~"Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = "Hello, World".to_base64();
     *     println(fmt!("%s",str));
     * }
     * ~~~~
     *
     */
    fn to_base64(&self) -> ~str {
        str::to_bytes(*self).to_base64()
    }
}

pub trait FromBase64 {
    fn from_base64(&self) -> ~[u8];
}

impl FromBase64 for ~[u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, modulo padding.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        if self.len() % 4u != 0u { fail!(~"invalid base64 length"); }

        let len = self.len();
        let mut padding = 0u;

        if len != 0u {
            if self[len - 1u] == '=' as u8 { padding += 1u; }
            if self[len - 2u] == '=' as u8 { padding += 1u; }
        }

        let mut r = vec::with_capacity((len / 4u) * 3u - padding);

        let mut i = 0u;
        while i < len {
            let mut n = 0u;

            for iter::repeat(4u) {
                let ch = self[i] as char;
                n <<= 6u;

                if ch >= 'A' && ch <= 'Z' {
                    n |= (ch as uint) - 0x41u;
                } else if ch >= 'a' && ch <= 'z' {
                    n |= (ch as uint) - 0x47u;
                } else if ch >= '0' && ch <= '9' {
                    n |= (ch as uint) + 0x04u;
                } else if ch == '+' {
                    n |= 0x3Eu;
                } else if ch == '/' {
                    n |= 0x3Fu;
                } else if ch == '=' {
                    match len - i {
                      1u => {
                        r.push(((n >> 16u) & 0xFFu) as u8);
                        r.push(((n >> 8u ) & 0xFFu) as u8);
                        return copy r;
                      }
                      2u => {
                        r.push(((n >> 10u) & 0xFFu) as u8);
                        return copy r;
                      }
                      _ => fail!(~"invalid base64 padding")
                    }
                } else {
                    fail!(~"invalid base64 character");
                }

                i += 1u;
            };

            r.push(((n >> 16u) & 0xFFu) as u8);
            r.push(((n >> 8u ) & 0xFFu) as u8);
            r.push(((n       ) & 0xFFu) as u8);
        }
        r
    }
}

impl FromBase64 for ~str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `core::str`
     * to turn a `[u8]` into a string with characters corresponding to those values.
     *
     * *Example*:
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     * use core::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64();
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        str::to_bytes(*self).from_base64()
    }
}

#[cfg(test)]
mod tests {
    use core::str;

    #[test]
    fn test_to_base64() {
        assert!((~"").to_base64()       == ~"");
        assert!((~"f").to_base64()      == ~"Zg==");
        assert!((~"fo").to_base64()     == ~"Zm8=");
        assert!((~"foo").to_base64()    == ~"Zm9v");
        assert!((~"foob").to_base64()   == ~"Zm9vYg==");
        assert!((~"fooba").to_base64()  == ~"Zm9vYmE=");
        assert!((~"foobar").to_base64() == ~"Zm9vYmFy");
    }

    #[test]
    fn test_from_base64() {
        assert!((~"").from_base64() == str::to_bytes(~""));
        assert!((~"Zg==").from_base64() == str::to_bytes(~"f"));
        assert!((~"Zm8=").from_base64() == str::to_bytes(~"fo"));
        assert!((~"Zm9v").from_base64() == str::to_bytes(~"foo"));
        assert!((~"Zm9vYg==").from_base64() == str::to_bytes(~"foob"));
        assert!((~"Zm9vYmE=").from_base64() == str::to_bytes(~"fooba"));
        assert!((~"Zm9vYmFy").from_base64() == str::to_bytes(~"foobar"));
    }
}
<|endoftext|>