<commit_before>#![deny(missing_docs)]

//! Low-level graphics abstraction for Rust. Mostly operates on data, not types.
//! Designed for use by libraries and higher-level abstractions only.

#[macro_use]
extern crate bitflags;
extern crate draw_state;
//#[macro_use]
//extern crate log;
extern crate smallvec;

#[cfg(feature = "mint")]
extern crate mint;

#[cfg(feature = "serialize")]
#[macro_use]
extern crate serde_derive;

use std::any::Any;
use std::error::Error;
use std::fmt::{self, Debug};
use std::hash::Hash;

pub use self::adapter::{Adapter, AdapterInfo};
pub use self::command::{RawCommandBuffer};
pub use self::device::Device;
pub use self::pool::{CommandPool, RawCommandPool, SubpassCommandPool};
pub use self::pso::{DescriptorPool};
pub use self::queue::{
    CommandQueue, QueueFamily, QueueType, RawCommandQueue, RawSubmission, Submission,
    General, Graphics, Compute, Transfer,
};
pub use self::window::{
    Backbuffer, Frame, FrameSync, Surface, Swapchain, SwapchainConfig};
pub use draw_state::{state, target};

pub mod adapter;
pub mod buffer;
pub mod command;
pub mod device;
pub mod format;
pub mod image;
pub mod mapping;
pub mod memory;
pub mod pass;
pub mod pool;
pub mod pso;
pub mod queue;
pub mod window;

/// Draw vertex count.
pub type VertexCount = u32;
/// Draw vertex base offset.
pub type VertexOffset = i32;
/// Draw number of indices.
pub type IndexCount = u32;
/// Draw number of instances
pub type InstanceCount = u32;
/// Number of vertices in a patch
pub type PatchSize = u8;

/// Slot for an attribute.
pub type AttributeSlot = u8;
/// Slot for a constant buffer object.
pub type ConstantBufferSlot = u8;
/// Slot for a shader resource view.
pub type ResourceViewSlot = u8;
/// Slot for an unordered access object.
pub type UnorderedViewSlot = u8;
/// Slot for an active color buffer.
pub type ColorSlot = u8;
/// Slot for a sampler.
pub type SamplerSlot = u8;

///
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
pub struct Viewport {
    pub x: u16,
    pub y: u16,
    pub w: u16,
    pub h: u16,
    pub near: f32,
    pub far: f32,
}

/// Features that the device supports.
/// These only include features of the core interface and not API extensions.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Features {
    /// Support indirect drawing and dispatching.
    pub indirect_execution: bool,
    /// Support instanced drawing.
    pub draw_instanced: bool,
    /// Support offsets for instanced drawing with base instance.
    pub draw_instanced_base: bool,
    /// Support indexed drawing with base vertex.
    pub draw_indexed_base: bool,
    /// Support indexed, instanced drawing.
    pub draw_indexed_instanced: bool,
    /// Support indexed, instanced drawing with base vertex only.
    pub draw_indexed_instanced_base_vertex: bool,
    /// Support indexed, instanced drawing with base vertex and instance.
    pub draw_indexed_instanced_base: bool,
    /// Support manually specified vertex attribute rates (divisors).
    pub instance_rate: bool,
    /// Support base vertex offset for indexed drawing.
    pub vertex_base: bool,
    /// Support sRGB textures and rendertargets.
    pub srgb_color: bool,
    /// Support constant buffers.
    pub constant_buffer: bool,
    /// Support unordered-access views.
    pub unordered_access_view: bool,
    /// Support specifying the blend function and equation for each color target.
    pub separate_blending_slots: bool,
    /// Support accelerated buffer copy.
    pub copy_buffer: bool,
    /// Support separation of textures and samplers.
    pub sampler_objects: bool,
    /// Support sampler LOD bias.
    pub sampler_lod_bias: bool,
    /// Support anisotropic filtering.
    pub sampler_anisotropy: bool,
    /// Support setting border texel colors.
    pub sampler_border_color: bool,
}

/// Limits of the device.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Limits {
    /// Maximum supported texture size.
    pub max_texture_size: usize,
    /// Maximum number of vertices for each patch.
    pub max_patch_size: PatchSize,
    /// Maximum number of viewports.
    pub max_viewports: usize,

    /// The alignment of the start of the buffer used as a GPU copy source, in bytes, non-zero.
    pub min_buffer_copy_offset_alignment: usize,
    /// The alignment of the row pitch of the texture data stored in a buffer that is
    /// used in a GPU copy operation, in bytes, non-zero.
    pub min_buffer_copy_pitch_alignment: usize,
}

/// Describes what geometric primitives are created from vertex data.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum Primitive {
    /// Each vertex represents a single point.
    PointList,
    /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
    /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
    LineList,
    /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
    /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
    /// line, and `b` and `c` form a line.
    LineStrip,
    /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
    /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
    TriangleList,
    /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
    /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
    TriangleStrip,
    /// Each quadtruplet of vertices represent a single line segment with adjacency information.
    /// For example, with `[a, b, c, d]`, `b` and `c` form a line, and `a` and `d` are the adjacent
    /// vertices.
    LineListAdjacency,
    /// Every four consecutive vertices represent a single line segment with adjacency information.
    /// For example, with `[a, b, c, d, e]`, `[a, b, c, d]` form a line segment with adjacency, and
    /// `[b, c, d, e]` form a line segment with adjacency.
    LineStripAdjacency,
    /// Each sextuplet of vertices represent a single traingle with adjacency information. For
    /// example, with `[a, b, c, d, e, f]`, `a`, `c`, and `e` form a traingle, and `b`, `d`, and
    /// `f` are the adjacent vertices, where `b` is adjacent to the edge formed by `a` and `c`, `d`
    /// is adjacent to the edge `c` and `e`, and `f` is adjacent to the edge `e` and `a`.
    TriangleListAdjacency,
    /// Every even-numbered vertex (every other starting from the first) represents an additional
    /// vertex for the triangle strip, while odd-numbered vertices (every other starting from the
    /// second) represent adjacent vertices. For example, with `[a, b, c, d, e, f, g, h]`, `[a, c,
    /// e, g]` form a triangle strip, and `[b, d, f, h]` are the adjacent vertices, where `b`, `d`,
    /// and `f` are adjacent to the first triangle in the strip, and `d`, `f`, and `h` are adjacent
    /// to the second.
    TriangleStripAdjacency,
    /// Patch list,
    /// used with shaders capable of producing primitives on their own (tessellation)
    PatchList(PatchSize),
}

/// A type of each index value in the slice's index buffer
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum IndexType {
    U16,
    U32,
}

///
#[derive(Copy, Clone, Debug)]
pub struct HeapType {
    /// Id of the heap type.
    pub id: usize,
    /// Properties of the associated heap memory.
    pub properties: memory::HeapProperties,
    /// Index to the underlying memory heap.
    pub heap_index: usize,
}

/// Basic backend instance trait.
pub trait Instance<B: Backend> {
    /// Enumerate all available adapters.
    fn enumerate_adapters(&self) -> Vec<B::Adapter>;
}

/// Different types of a specific API.
#[allow(missing_docs)]
pub trait Backend: 'static + Sized + Eq + Clone + Hash + Debug + Any {
    //type Instance:          Instance<Self>;
    type Adapter:             Adapter<Self>;
    type Device:              Device<Self>;

    type Surface:             Surface<Self>;
    type Swapchain:           Swapchain<Self>;

    type CommandQueue:        RawCommandQueue<Self>;
    type CommandBuffer:       RawCommandBuffer<Self>;
    type SubpassCommandBuffer;
    type QueueFamily:         QueueFamily;

    type ShaderLib:           Debug + Any + Send + Sync;
    type RenderPass:          Debug + Any + Send + Sync;
    type FrameBuffer:         Debug + Any + Send + Sync;

    type Heap:                Debug + Any;
    type Mapping:             Debug + Any + Send + Sync;
    type CommandPool:         RawCommandPool<Self>;
    type SubpassCommandPool:  SubpassCommandPool<Self>;

    type UnboundBuffer:       Debug + Any + Send + Sync;
    type Buffer:              Debug + Any + Send + Sync;
    type UnboundImage:        Debug + Any + Send + Sync;
    type Image:               Debug + Any + Send + Sync;
    type Sampler:             Debug + Any + Send + Sync;

    type ConstantBufferView:  Debug + Any + Send + Sync;
    type ShaderResourceView:  Debug + Any + Send + Sync;
    type UnorderedAccessView: Debug + Any + Send + Sync;
    type RenderTargetView:    Debug + Any + Send + Sync;
    type DepthStencilView:    Debug + Any + Send + Sync;

    type ComputePipeline:     Debug + Any + Send + Sync;
    type GraphicsPipeline:    Debug + Any + Send + Sync;
    type PipelineLayout:      Debug + Any + Send + Sync;
    type DescriptorPool:      DescriptorPool<Self>;
    type DescriptorSet:       Debug + Any + Send + Sync;
    type DescriptorSetLayout: Debug + Any;

    type Fence:               Debug + Any + Send + Sync;
    type Semaphore:           Debug + Any + Send + Sync;
}

#[allow(missing_docs)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum SubmissionError {
    AccessOverlap,
}

impl fmt::Display for SubmissionError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::SubmissionError::*;
        match *self {
            AccessOverlap => write!(f, "{}", self.description()),
        }
    }
}

impl Error for SubmissionError {
    fn description(&self) -> &str {
        use self::SubmissionError::*;
        match *self {
            AccessOverlap => "A resource access overlaps with another",
        }
    }
}

#[allow(missing_docs)]
pub type SubmissionResult<T> = Result<T, SubmissionError>;

/// Represents a handle to a physical device.
///
/// This structure is typically created using an `Adapter`.
pub struct Gpu<B: Backend> {
    /// Logical device.
    pub device: B::Device,
    /// General command queues.
    pub general_queues: Vec<CommandQueue<B, General>>,
    /// Graphics command queues.
    pub graphics_queues: Vec<CommandQueue<B, Graphics>>,
    /// Compute command queues.
    pub compute_queues: Vec<CommandQueue<B, Compute>>,
    /// Transfer command queues.
    pub transfer_queues: Vec<CommandQueue<B, Transfer>>,
    /// Types of memory heaps.
    pub heap_types: Vec<HeapType>,
    /// Memory heaps.
    pub memory_heaps: Vec<u64>,
}
<commit_msg>[ll] core: Improve memory heap types doc<commit_after>#![deny(missing_docs)]

//! Low-level graphics abstraction for Rust. Mostly operates on data, not types.
//! Designed for use by libraries and higher-level abstractions only.

#[macro_use]
extern crate bitflags;
extern crate draw_state;
//#[macro_use]
//extern crate log;
extern crate smallvec;

#[cfg(feature = "mint")]
extern crate mint;

#[cfg(feature = "serialize")]
#[macro_use]
extern crate serde_derive;

use std::any::Any;
use std::error::Error;
use std::fmt::{self, Debug};
use std::hash::Hash;

pub use self::adapter::{Adapter, AdapterInfo};
pub use self::command::{RawCommandBuffer};
pub use self::device::Device;
pub use self::pool::{CommandPool, RawCommandPool, SubpassCommandPool};
pub use self::pso::{DescriptorPool};
pub use self::queue::{
    CommandQueue, QueueFamily, QueueType, RawCommandQueue, RawSubmission, Submission,
    General, Graphics, Compute, Transfer,
};
pub use self::window::{
    Backbuffer, Frame, FrameSync, Surface, Swapchain, SwapchainConfig};
pub use draw_state::{state, target};

pub mod adapter;
pub mod buffer;
pub mod command;
pub mod device;
pub mod format;
pub mod image;
pub mod mapping;
pub mod memory;
pub mod pass;
pub mod pool;
pub mod pso;
pub mod queue;
pub mod window;

/// Draw vertex count.
pub type VertexCount = u32;
/// Draw vertex base offset.
pub type VertexOffset = i32;
/// Draw number of indices.
pub type IndexCount = u32;
/// Draw number of instances
pub type InstanceCount = u32;
/// Number of vertices in a patch
pub type PatchSize = u8;

/// Slot for an attribute.
pub type AttributeSlot = u8;
/// Slot for a constant buffer object.
pub type ConstantBufferSlot = u8;
/// Slot for a shader resource view.
pub type ResourceViewSlot = u8;
/// Slot for an unordered access object.
pub type UnorderedViewSlot = u8;
/// Slot for an active color buffer.
pub type ColorSlot = u8;
/// Slot for a sampler.
pub type SamplerSlot = u8;

///
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
pub struct Viewport {
    pub x: u16,
    pub y: u16,
    pub w: u16,
    pub h: u16,
    pub near: f32,
    pub far: f32,
}

/// Features that the device supports.
/// These only include features of the core interface and not API extensions.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Features {
    /// Support indirect drawing and dispatching.
    pub indirect_execution: bool,
    /// Support instanced drawing.
    pub draw_instanced: bool,
    /// Support offsets for instanced drawing with base instance.
    pub draw_instanced_base: bool,
    /// Support indexed drawing with base vertex.
    pub draw_indexed_base: bool,
    /// Support indexed, instanced drawing.
    pub draw_indexed_instanced: bool,
    /// Support indexed, instanced drawing with base vertex only.
    pub draw_indexed_instanced_base_vertex: bool,
    /// Support indexed, instanced drawing with base vertex and instance.
    pub draw_indexed_instanced_base: bool,
    /// Support manually specified vertex attribute rates (divisors).
    pub instance_rate: bool,
    /// Support base vertex offset for indexed drawing.
    pub vertex_base: bool,
    /// Support sRGB textures and rendertargets.
    pub srgb_color: bool,
    /// Support constant buffers.
    pub constant_buffer: bool,
    /// Support unordered-access views.
    pub unordered_access_view: bool,
    /// Support specifying the blend function and equation for each color target.
    pub separate_blending_slots: bool,
    /// Support accelerated buffer copy.
    pub copy_buffer: bool,
    /// Support separation of textures and samplers.
    pub sampler_objects: bool,
    /// Support sampler LOD bias.
    pub sampler_lod_bias: bool,
    /// Support anisotropic filtering.
    pub sampler_anisotropy: bool,
    /// Support setting border texel colors.
    pub sampler_border_color: bool,
}

/// Limits of the device.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Limits {
    /// Maximum supported texture size.
    pub max_texture_size: usize,
    /// Maximum number of vertices for each patch.
    pub max_patch_size: PatchSize,
    /// Maximum number of viewports.
    pub max_viewports: usize,

    /// The alignment of the start of the buffer used as a GPU copy source, in bytes, non-zero.
    pub min_buffer_copy_offset_alignment: usize,
    /// The alignment of the row pitch of the texture data stored in a buffer that is
    /// used in a GPU copy operation, in bytes, non-zero.
    pub min_buffer_copy_pitch_alignment: usize,
}

/// Describes what geometric primitives are created from vertex data.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum Primitive {
    /// Each vertex represents a single point.
    PointList,
    /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
    /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
    LineList,
    /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
    /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
    /// line, and `b` and `c` form a line.
    LineStrip,
    /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
    /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
    TriangleList,
    /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
    /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
    TriangleStrip,
    /// Each quadtruplet of vertices represent a single line segment with adjacency information.
    /// For example, with `[a, b, c, d]`, `b` and `c` form a line, and `a` and `d` are the adjacent
    /// vertices.
    LineListAdjacency,
    /// Every four consecutive vertices represent a single line segment with adjacency information.
    /// For example, with `[a, b, c, d, e]`, `[a, b, c, d]` form a line segment with adjacency, and
    /// `[b, c, d, e]` form a line segment with adjacency.
    LineStripAdjacency,
    /// Each sextuplet of vertices represent a single traingle with adjacency information. For
    /// example, with `[a, b, c, d, e, f]`, `a`, `c`, and `e` form a traingle, and `b`, `d`, and
    /// `f` are the adjacent vertices, where `b` is adjacent to the edge formed by `a` and `c`, `d`
    /// is adjacent to the edge `c` and `e`, and `f` is adjacent to the edge `e` and `a`.
    TriangleListAdjacency,
    /// Every even-numbered vertex (every other starting from the first) represents an additional
    /// vertex for the triangle strip, while odd-numbered vertices (every other starting from the
    /// second) represent adjacent vertices. For example, with `[a, b, c, d, e, f, g, h]`, `[a, c,
    /// e, g]` form a triangle strip, and `[b, d, f, h]` are the adjacent vertices, where `b`, `d`,
    /// and `f` are adjacent to the first triangle in the strip, and `d`, `f`, and `h` are adjacent
    /// to the second.
    TriangleStripAdjacency,
    /// Patch list,
    /// used with shaders capable of producing primitives on their own (tessellation)
    PatchList(PatchSize),
}

/// A type of each index value in the slice's index buffer
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum IndexType {
    U16,
    U32,
}

///
#[derive(Copy, Clone, Debug)]
pub struct HeapType {
    /// Id of the heap type.
    pub id: usize,
    /// Properties of the associated heap memory.
    pub properties: memory::HeapProperties,
    /// Index to the underlying memory heap.
    pub heap_index: usize,
}

/// Basic backend instance trait.
pub trait Instance<B: Backend> {
    /// Enumerate all available adapters.
    fn enumerate_adapters(&self) -> Vec<B::Adapter>;
}

/// Different types of a specific API.
#[allow(missing_docs)]
pub trait Backend: 'static + Sized + Eq + Clone + Hash + Debug + Any {
    //type Instance:          Instance<Self>;
    type Adapter:             Adapter<Self>;
    type Device:              Device<Self>;

    type Surface:             Surface<Self>;
    type Swapchain:           Swapchain<Self>;

    type CommandQueue:        RawCommandQueue<Self>;
    type CommandBuffer:       RawCommandBuffer<Self>;
    type SubpassCommandBuffer;
    type QueueFamily:         QueueFamily;

    type ShaderLib:           Debug + Any + Send + Sync;
    type RenderPass:          Debug + Any + Send + Sync;
    type FrameBuffer:         Debug + Any + Send + Sync;

    type Heap:                Debug + Any;
    type Mapping:             Debug + Any + Send + Sync;
    type CommandPool:         RawCommandPool<Self>;
    type SubpassCommandPool:  SubpassCommandPool<Self>;

    type UnboundBuffer:       Debug + Any + Send + Sync;
    type Buffer:              Debug + Any + Send + Sync;
    type UnboundImage:        Debug + Any + Send + Sync;
    type Image:               Debug + Any + Send + Sync;
    type Sampler:             Debug + Any + Send + Sync;

    type ConstantBufferView:  Debug + Any + Send + Sync;
    type ShaderResourceView:  Debug + Any + Send + Sync;
    type UnorderedAccessView: Debug + Any + Send + Sync;
    type RenderTargetView:    Debug + Any + Send + Sync;
    type DepthStencilView:    Debug + Any + Send + Sync;

    type ComputePipeline:     Debug + Any + Send + Sync;
    type GraphicsPipeline:    Debug + Any + Send + Sync;
    type PipelineLayout:      Debug + Any + Send + Sync;
    type DescriptorPool:      DescriptorPool<Self>;
    type DescriptorSet:       Debug + Any + Send + Sync;
    type DescriptorSetLayout: Debug + Any;

    type Fence:               Debug + Any + Send + Sync;
    type Semaphore:           Debug + Any + Send + Sync;
}

#[allow(missing_docs)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum SubmissionError {
    AccessOverlap,
}

impl fmt::Display for SubmissionError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::SubmissionError::*;
        match *self {
            AccessOverlap => write!(f, "{}", self.description()),
        }
    }
}

impl Error for SubmissionError {
    fn description(&self) -> &str {
        use self::SubmissionError::*;
        match *self {
            AccessOverlap => "A resource access overlaps with another",
        }
    }
}

#[allow(missing_docs)]
pub type SubmissionResult<T> = Result<T, SubmissionError>;

/// Represents a handle to a physical device.
///
/// This structure is typically created using an `Adapter`.
pub struct Gpu<B: Backend> {
    /// Logical device.
    pub device: B::Device,
    /// General command queues.
    pub general_queues: Vec<CommandQueue<B, General>>,
    /// Graphics command queues.
    pub graphics_queues: Vec<CommandQueue<B, Graphics>>,
    /// Compute command queues.
    pub compute_queues: Vec<CommandQueue<B, Compute>>,
    /// Transfer command queues.
    pub transfer_queues: Vec<CommandQueue<B, Transfer>>,
    /// Types of memory heaps.
    ///
    /// Each heap type is associated with one heap of `memory_heaps`.
    /// Multiple types can point to the same heap.
    pub heap_types: Vec<HeapType>,
    /// Memory heaps with their size in bytes.
    pub memory_heaps: Vec<u64>,
}
<|endoftext|>


<commit_before>extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

const LIBMODBUS_DIR: &'static str = "libmodbus";

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();

    let build_dir = Path::new(LIBMODBUS_DIR);
    let prefix    = Path::new(&out_dir).join("libmodbus-root");
    let include   = Path::new(&prefix).join("include")
                                      .join("modbus");

    // if `pkg-config` is present and the libmodbus headers are found
    // we use `pkg-config` to find the include_path and call bindgen with it.
    //

    if let Ok(library) = pkg_config::find_library("libmodbus") {
        if let Some(include) = library.include_paths.get(0) {
            run_bindgen(&include);
        }

        return
    }

    // pkg-config is not found. We build libmodbus (source is in git submodule) from source
    // and run bindgen with that folder as include path.
    //

    // If autogen.sh is not present, initalize git submodules
    if !Path::new("libmodbus/autogen.sh").exists() {
        run_command("", Command::new("git").args(&["submodule", "update", "--init"]));
    }

    // Generate configure, run configure, make, make install
    run_command("Generating configure",
        Command::new("./autogen.sh")
            .current_dir(&build_dir));

    run_command("Configuring libmodbus",
        Command::new("./configure")
            .arg("--prefix")
            .arg(prefix)
            .arg("--without-documentation")
            .current_dir(&build_dir));

    run_command("Building libmodbus",
        Command::new("make")
            .arg("install")
            .current_dir(&build_dir));

    run_bindgen(&include);
}

fn run_bindgen(include: &PathBuf) {
    let include_path = format!("-I{}", include.display());

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // Do not generate unstable Rust code that
        // requires a nightly rustc and enabling
        // unstable features.
        .no_unstable_rust()
        // The input header we would like to generate
        // bindings for.
        .header("wrapper.h")
        .clang_arg(include_path)
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

// Helper which run a given command, and check it's success
fn run_command(which: &'static str, cmd: &mut Command) {
    assert!(cmd.status().expect(which).success(), which);
}
<commit_msg>Little changes, no function changes<commit_after>extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

const LIBMODBUS_DIR: &'static str = "libmodbus";

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();

    let build_dir = Path::new(LIBMODBUS_DIR);
    let prefix    = Path::new(&out_dir).join("libmodbus-root");
    let include   = Path::new(&prefix).join("include")
                                      .join("modbus");

    // if `pkg-config` is present and the libmodbus headers are found
    // we use `pkg-config` to find the include_path and call bindgen with it.
    //
    if let Ok(library) = pkg_config::find_library("libmodbus") {
        if let Some(include) = library.include_paths.get(0) {
            run_bindgen(&include);
        }

        return
    }

    // pkg-config is not found. We build libmodbus from source (source are in a git submodule)
    // and run bindgen with that folder as include path set.
    //

    // If autogen.sh is not present, initalize git submodules
    if !Path::new("libmodbus/autogen.sh").exists() {
        run_command("", Command::new("git").args(&["submodule", "update", "--init"]));
    }

    // Generate configure, run configure, make, make install
    run_command("Generating configure",
        Command::new("./autogen.sh")
            .current_dir(&build_dir));

    run_command("Configuring libmodbus",
        Command::new("./configure")
            .arg("--prefix")
            .arg(prefix)
            .arg("--without-documentation")
            .current_dir(&build_dir));

    run_command("Building libmodbus",
        Command::new("make")
            .arg("install")
            .current_dir(&build_dir));

    run_bindgen(&include);
}

fn run_bindgen(include: &PathBuf) {
    let include_path = format!("-I{}", include.display());

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // Do not generate unstable Rust code that
        // requires a nightly rustc and enabling
        // unstable features.
        .no_unstable_rust()
        // The input header we would like to generate
        // bindings for.
        .header("wrapper.h")
        .clang_arg(include_path)
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

// Helper which run a given command, and check it's success
fn run_command(which: &'static str, cmd: &mut Command) {
    assert!(cmd.status().expect(which).success(), which);
}
<|endoftext|>


<commit_before>// These just test that serde_codegen is able to produce code that compiles
// successfully when there are a variety of generics and non-(de)serializable
// types involved.

#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]

#[macro_use]
extern crate serde_derive;

extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{DeserializeOwned, Deserializer};

use std::borrow::Cow;
use std::marker::PhantomData;
use std::result::Result as StdResult;

// Try to trip up the generated code if it fails to use fully qualified paths.
#[allow(dead_code)]
struct Result;
#[allow(dead_code)]
struct Ok;
#[allow(dead_code)]
struct Err;

//////////////////////////////////////////////////////////////////////////

#[test]
fn test_gen() {
    #[derive(Serialize, Deserialize)]
    struct With<T> {
        t: T,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        x: X,
    }
    assert::<With<i32>>();

    #[derive(Serialize, Deserialize)]
    struct WithTogether<T> {
        t: T,
        #[serde(with="both_x")]
        x: X,
    }
    assert::<WithTogether<i32>>();

    #[derive(Serialize, Deserialize)]
    struct WithRef<'a, T: 'a> {
        #[serde(skip_deserializing)]
        t: Option<&'a T>,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        x: X,
    }
    assert::<WithRef<i32>>();

    #[derive(Serialize, Deserialize)]
    struct PhantomX {
        x: PhantomData<X>,
    }
    assert::<PhantomX>();

    #[derive(Serialize, Deserialize)]
    struct PhantomT<T> {
        t: PhantomData<T>,
    }
    assert::<PhantomT<X>>();

    #[derive(Serialize, Deserialize)]
    struct NoBounds<T> {
        t: T,
        option: Option<T>,
        boxed: Box<T>,
        option_boxed: Option<Box<T>>,
    }
    assert::<NoBounds<i32>>();

    #[derive(Serialize, Deserialize)]
    enum EnumWith<T> {
        Unit,
        Newtype(
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            X),
        Tuple(
            T,
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            X),
        Struct {
            t: T,
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            x: X },
    }
    assert::<EnumWith<i32>>();

    #[derive(Serialize)]
    struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
        t: T,
        rrrt: &'a &'b &'c T,
    }
    assert_ser::<MultipleRef<i32>>();

    #[derive(Serialize, Deserialize)]
    struct Newtype(
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        X
    );
    assert::<Newtype>();

    #[derive(Serialize, Deserialize)]
    struct Tuple<T>(
        T,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        X,
    );
    assert::<Tuple<i32>>();

    #[derive(Serialize, Deserialize)]
    enum TreeNode<D> {
        Split {
            left: Box<TreeNode<D>>,
            right: Box<TreeNode<D>>,
        },
        Leaf {
            data: D,
        },
    }
    assert::<TreeNode<i32>>();

    #[derive(Serialize, Deserialize)]
    struct ListNode<D> {
        data: D,
        next: Box<ListNode<D>>,
    }
    assert::<ListNode<i32>>();

    #[derive(Serialize, Deserialize)]
    struct RecursiveA {
        b: Box<RecursiveB>,
    }
    assert::<RecursiveA>();

    #[derive(Serialize, Deserialize)]
    enum RecursiveB {
        A(RecursiveA),
    }
    assert::<RecursiveB>();

    #[derive(Serialize, Deserialize)]
    struct RecursiveGenericA<T> {
        t: T,
        b: Box<RecursiveGenericB<T>>,
    }
    assert::<RecursiveGenericA<i32>>();

    #[derive(Serialize, Deserialize)]
    enum RecursiveGenericB<T> {
        T(T),
        A(RecursiveGenericA<T>),
    }
    assert::<RecursiveGenericB<i32>>();

    #[derive(Serialize)]
    struct OptionStatic<'a> {
        a: Option<&'a str>,
        b: Option<&'static str>,
    }
    assert_ser::<OptionStatic>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound="D: SerializeWith + DeserializeWith")]
    struct WithTraits1<D, E> {
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with")]
        d: D,
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with",
                bound="E: SerializeWith + DeserializeWith")]
        e: E,
    }
    assert::<WithTraits1<X, X>>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound(serialize="D: SerializeWith",
                deserialize="D: DeserializeWith"))]
    struct WithTraits2<D, E> {
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with")]
        d: D,
        #[serde(serialize_with="SerializeWith::serialize_with",
                bound(serialize="E: SerializeWith"))]
        #[serde(deserialize_with="DeserializeWith::deserialize_with",
                bound(deserialize="E: DeserializeWith"))]
        e: E,
    }
    assert::<WithTraits2<X, X>>();

    #[derive(Serialize, Deserialize)]
    struct CowStr<'a>(Cow<'a, str>);
    assert::<CowStr>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound(deserialize = "T::Owned: DeserializeOwned"))]
    struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>);
    assert::<CowT<str>>();

    #[derive(Serialize, Deserialize)]
    struct EmptyStruct {}
    assert::<EmptyStruct>();

    #[derive(Serialize, Deserialize)]
    enum EmptyEnumVariant {
        EmptyStruct {},
    }
    assert::<EmptyEnumVariant>();

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    struct NonAsciiIdents {
        σ: f64
    }

    #[derive(Serialize, Deserialize)]
    struct EmptyBraced {}

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct EmptyBracedDenyUnknown {}

    #[derive(Serialize, Deserialize)]
    struct BracedSkipAll {
        #[serde(skip_deserializing)]
        f: u8,
    }

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct BracedSkipAllDenyUnknown {
        #[serde(skip_deserializing)]
        f: u8,
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    struct EmptyTuple();

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct EmptyTupleDenyUnknown();

    #[derive(Serialize, Deserialize)]
    struct TupleSkipAll(#[serde(skip_deserializing)] u8);

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);

    #[derive(Serialize, Deserialize)]
    enum EmptyEnum {}

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    enum EmptyEnumDenyUnknown {}

    #[derive(Serialize, Deserialize)]
    enum EnumSkipAll {
        #[serde(skip_deserializing)]
        #[allow(dead_code)]
        Variant,
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    enum EmptyVariants {
        Braced {},
        Tuple(),
        BracedSkip {
            #[serde(skip_deserializing)]
            f: u8,
        },
        TupleSkip(#[serde(skip_deserializing)] u8),
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    enum EmptyVariantsDenyUnknown {
        Braced {},
        Tuple(),
        BracedSkip {
            #[serde(skip_deserializing)]
            f: u8,
        },
        TupleSkip(#[serde(skip_deserializing)] u8),
    }

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct UnitDenyUnknown;

    #[derive(Serialize, Deserialize)]
    struct EmptyArray {
        empty: [X; 0],
    }
}

//////////////////////////////////////////////////////////////////////////

fn assert<T: Serialize + DeserializeOwned>() {}
fn assert_ser<T: Serialize>() {}

trait SerializeWith {
    fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error>;
}

trait DeserializeWith: Sized {
    fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error>;
}

// Implements neither Serialize nor Deserialize
pub struct X;

pub fn ser_x<S: Serializer>(_: &X, _: S) -> StdResult<S::Ok, S::Error> {
    unimplemented!()
}

pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult<X, D::Error> {
    unimplemented!()
}

mod both_x {
    pub use super::{ser_x as serialize, de_x as deserialize};
}

impl SerializeWith for X {
    fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error> {
        unimplemented!()
    }
}

impl DeserializeWith for X {
    fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error> {
        unimplemented!()
    }
}
<commit_msg>Ignore clippy false positive<commit_after>// These just test that serde_codegen is able to produce code that compiles
// successfully when there are a variety of generics and non-(de)serializable
// types involved.

#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]

// Clippy false positive
// https://github.com/Manishearth/rust-clippy/issues/292
#![cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]

#[macro_use]
extern crate serde_derive;

extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{DeserializeOwned, Deserializer};

use std::borrow::Cow;
use std::marker::PhantomData;
use std::result::Result as StdResult;

// Try to trip up the generated code if it fails to use fully qualified paths.
#[allow(dead_code)]
struct Result;
#[allow(dead_code)]
struct Ok;
#[allow(dead_code)]
struct Err;

//////////////////////////////////////////////////////////////////////////

#[test]
fn test_gen() {
    #[derive(Serialize, Deserialize)]
    struct With<T> {
        t: T,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        x: X,
    }
    assert::<With<i32>>();

    #[derive(Serialize, Deserialize)]
    struct WithTogether<T> {
        t: T,
        #[serde(with="both_x")]
        x: X,
    }
    assert::<WithTogether<i32>>();

    #[derive(Serialize, Deserialize)]
    struct WithRef<'a, T: 'a> {
        #[serde(skip_deserializing)]
        t: Option<&'a T>,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        x: X,
    }
    assert::<WithRef<i32>>();

    #[derive(Serialize, Deserialize)]
    struct PhantomX {
        x: PhantomData<X>,
    }
    assert::<PhantomX>();

    #[derive(Serialize, Deserialize)]
    struct PhantomT<T> {
        t: PhantomData<T>,
    }
    assert::<PhantomT<X>>();

    #[derive(Serialize, Deserialize)]
    struct NoBounds<T> {
        t: T,
        option: Option<T>,
        boxed: Box<T>,
        option_boxed: Option<Box<T>>,
    }
    assert::<NoBounds<i32>>();

    #[derive(Serialize, Deserialize)]
    enum EnumWith<T> {
        Unit,
        Newtype(
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            X),
        Tuple(
            T,
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            X),
        Struct {
            t: T,
            #[serde(serialize_with="ser_x", deserialize_with="de_x")]
            x: X },
    }
    assert::<EnumWith<i32>>();

    #[derive(Serialize)]
    struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
        t: T,
        rrrt: &'a &'b &'c T,
    }
    assert_ser::<MultipleRef<i32>>();

    #[derive(Serialize, Deserialize)]
    struct Newtype(
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        X
    );
    assert::<Newtype>();

    #[derive(Serialize, Deserialize)]
    struct Tuple<T>(
        T,
        #[serde(serialize_with="ser_x", deserialize_with="de_x")]
        X,
    );
    assert::<Tuple<i32>>();

    #[derive(Serialize, Deserialize)]
    enum TreeNode<D> {
        Split {
            left: Box<TreeNode<D>>,
            right: Box<TreeNode<D>>,
        },
        Leaf {
            data: D,
        },
    }
    assert::<TreeNode<i32>>();

    #[derive(Serialize, Deserialize)]
    struct ListNode<D> {
        data: D,
        next: Box<ListNode<D>>,
    }
    assert::<ListNode<i32>>();

    #[derive(Serialize, Deserialize)]
    struct RecursiveA {
        b: Box<RecursiveB>,
    }
    assert::<RecursiveA>();

    #[derive(Serialize, Deserialize)]
    enum RecursiveB {
        A(RecursiveA),
    }
    assert::<RecursiveB>();

    #[derive(Serialize, Deserialize)]
    struct RecursiveGenericA<T> {
        t: T,
        b: Box<RecursiveGenericB<T>>,
    }
    assert::<RecursiveGenericA<i32>>();

    #[derive(Serialize, Deserialize)]
    enum RecursiveGenericB<T> {
        T(T),
        A(RecursiveGenericA<T>),
    }
    assert::<RecursiveGenericB<i32>>();

    #[derive(Serialize)]
    struct OptionStatic<'a> {
        a: Option<&'a str>,
        b: Option<&'static str>,
    }
    assert_ser::<OptionStatic>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound="D: SerializeWith + DeserializeWith")]
    struct WithTraits1<D, E> {
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with")]
        d: D,
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with",
                bound="E: SerializeWith + DeserializeWith")]
        e: E,
    }
    assert::<WithTraits1<X, X>>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound(serialize="D: SerializeWith",
                deserialize="D: DeserializeWith"))]
    struct WithTraits2<D, E> {
        #[serde(serialize_with="SerializeWith::serialize_with",
                deserialize_with="DeserializeWith::deserialize_with")]
        d: D,
        #[serde(serialize_with="SerializeWith::serialize_with",
                bound(serialize="E: SerializeWith"))]
        #[serde(deserialize_with="DeserializeWith::deserialize_with",
                bound(deserialize="E: DeserializeWith"))]
        e: E,
    }
    assert::<WithTraits2<X, X>>();

    #[derive(Serialize, Deserialize)]
    struct CowStr<'a>(Cow<'a, str>);
    assert::<CowStr>();

    #[derive(Serialize, Deserialize)]
    #[serde(bound(deserialize = "T::Owned: DeserializeOwned"))]
    struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>);
    assert::<CowT<str>>();

    #[derive(Serialize, Deserialize)]
    struct EmptyStruct {}
    assert::<EmptyStruct>();

    #[derive(Serialize, Deserialize)]
    enum EmptyEnumVariant {
        EmptyStruct {},
    }
    assert::<EmptyEnumVariant>();

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    struct NonAsciiIdents {
        σ: f64
    }

    #[derive(Serialize, Deserialize)]
    struct EmptyBraced {}

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct EmptyBracedDenyUnknown {}

    #[derive(Serialize, Deserialize)]
    struct BracedSkipAll {
        #[serde(skip_deserializing)]
        f: u8,
    }

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct BracedSkipAllDenyUnknown {
        #[serde(skip_deserializing)]
        f: u8,
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    struct EmptyTuple();

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct EmptyTupleDenyUnknown();

    #[derive(Serialize, Deserialize)]
    struct TupleSkipAll(#[serde(skip_deserializing)] u8);

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);

    #[derive(Serialize, Deserialize)]
    enum EmptyEnum {}

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    enum EmptyEnumDenyUnknown {}

    #[derive(Serialize, Deserialize)]
    enum EnumSkipAll {
        #[serde(skip_deserializing)]
        #[allow(dead_code)]
        Variant,
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    enum EmptyVariants {
        Braced {},
        Tuple(),
        BracedSkip {
            #[serde(skip_deserializing)]
            f: u8,
        },
        TupleSkip(#[serde(skip_deserializing)] u8),
    }

    #[cfg(feature = "unstable")]
    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    enum EmptyVariantsDenyUnknown {
        Braced {},
        Tuple(),
        BracedSkip {
            #[serde(skip_deserializing)]
            f: u8,
        },
        TupleSkip(#[serde(skip_deserializing)] u8),
    }

    #[derive(Serialize, Deserialize)]
    #[serde(deny_unknown_fields)]
    struct UnitDenyUnknown;

    #[derive(Serialize, Deserialize)]
    struct EmptyArray {
        empty: [X; 0],
    }
}

//////////////////////////////////////////////////////////////////////////

fn assert<T: Serialize + DeserializeOwned>() {}
fn assert_ser<T: Serialize>() {}

trait SerializeWith {
    fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error>;
}

trait DeserializeWith: Sized {
    fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error>;
}

// Implements neither Serialize nor Deserialize
pub struct X;

pub fn ser_x<S: Serializer>(_: &X, _: S) -> StdResult<S::Ok, S::Error> {
    unimplemented!()
}

pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult<X, D::Error> {
    unimplemented!()
}

mod both_x {
    pub use super::{ser_x as serialize, de_x as deserialize};
}

impl SerializeWith for X {
    fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error> {
        unimplemented!()
    }
}

impl DeserializeWith for X {
    fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error> {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>use std::iter::FromIterator;

use serde::{
    Deserialize,
    Serialize,
};

use thiserror::Error;

use rnc_core::{
    urs,
    urs_taxid,
};

use crate::normalize::utils;

use crate::normalize::ds::{
    accession::{
        AccessionVec,
        CrossReference,
        RawAccession,
        ReferenceVec,
    },
    basic::Basic,
    crs::{
        Crs,
        CrsVec,
    },
    feedback::{
        Feedback,
        FeedbackVec,
    },
    go_annotation::GoAnnotation,
    interacting_protein::{
        InteractingProtein,
        InteractingProteinVec,
    },
    interacting_rna::{
        InteractingRna,
        InteractingRnaVec,
    },
    precompute::{
        Precompute,
        PrecomputeSummary,
    },
    qa_status::QaStatus,
    r2dt::R2dt,
    rfam_hit::{
        RfamHit,
        RfamHitVec,
    },
    so_tree,
};

#[derive(Error, Debug)]
pub enum NormalizationError {
    #[error("Could not ungroup {0}")]
    CountError(#[from] utils::Error),

    #[error("Could not parse {0}")]
    UrsParsingError(#[from] urs::Error),

    #[error("Could not parse {0}")]
    UrsTaxidParsingError(#[from] urs_taxid::Error),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Raw {
    pub id: usize,
    pub base: Basic,
    pub crs: Vec<Crs>,
    pub feedback: Vec<Feedback>,
    pub go_annotations: Vec<GoAnnotation>,
    pub interacting_proteins: Vec<InteractingProtein>,
    pub interacting_rnas: Vec<InteractingRna>,
    pub precompute: Precompute,
    pub qa_status: QaStatus,
    pub r2dt: Option<R2dt>,
    pub rfam_hits: Vec<RfamHit>,
    pub so_tree: so_tree::SoTree,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Normalized {
    urs: String,
    taxid: usize,
    urs_taxid: String,
    short_urs: String,
    deleted: String,

    so_rna_type_tree: so_tree::SoTree,

    #[serde(flatten)]
    pre_summary: PrecomputeSummary,

    #[serde(flatten)]
    basic: Basic,

    // #[serde(flatten)]
    // dates: Dates,
    qa_status: QaStatus,
    secondary_structure: Option<R2dt>,

    accessions: AccessionVec,
    cross_references: Vec<CrossReference>,
    crs: CrsVec,
    feedback: FeedbackVec,
    go_annotations: Vec<GoAnnotation>,
    interacting_proteins: InteractingProteinVec,
    interacting_rnas: InteractingRnaVec,
    references: ReferenceVec,
    rfam_hits: RfamHitVec,
}

impl Raw {
    pub fn urs_taxid(&self) -> String {
        return self.base.urs_taxid.to_owned();
    }

    pub fn urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.to_string())
    }

    pub fn taxid(&self) -> Result<u64, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.taxid())
    }

    pub fn short_urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.short_urs())
    }

    pub fn short_urs_taxid(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.short())
    }
}

impl Normalized {
    pub fn new(
        raw: Raw,
        accessions: Vec<RawAccession>,
    ) -> Result<Self, NormalizationError> {
        let pre_summary = PrecomputeSummary::from(raw.precompute);
        let base = raw.base.clone();

        let urs_taxid = base.urs_taxid.to_owned();
        let parts: Vec<&str> = urs_taxid.split("_").collect();
        let urs = parts[0].to_owned();
        let taxid = parts[1].parse::<usize>().unwrap();
        let parsed: urs_taxid::UrsTaxid = urs_taxid.parse()?;
        let references = ReferenceVec::from_iter(accessions.into_iter());

        Ok(Self {
            urs_taxid,
            urs,
            taxid,
            short_urs: parsed.short(),
            deleted: String::from("N"),

            so_rna_type_tree: raw.so_tree,

            pre_summary,
            basic: base,
            qa_status: raw.qa_status,
            secondary_structure: raw.r2dt.into(),

            accessions: AccessionVec::from_iter(accessions),
            cross_references: accessions.into_iter().map(CrossReference::from).collect(),
            crs: CrsVec::from_iter(raw.crs.clone()),
            feedback: FeedbackVec::from_iter(raw.feedback.clone()),
            go_annotations: raw.go_annotations.clone(),
            interacting_proteins: InteractingProteinVec::from_iter(
                raw.interacting_proteins.clone(),
            ),
            interacting_rnas: InteractingRnaVec::from_iter(raw.interacting_rnas.clone()),
            references,
            rfam_hits: RfamHitVec::from_iter(raw.rfam_hits.clone()),
        })
    }
}
<commit_msg>More clones<commit_after>use std::iter::FromIterator;

use serde::{
    Deserialize,
    Serialize,
};

use thiserror::Error;

use rnc_core::{
    urs,
    urs_taxid,
};

use crate::normalize::utils;

use crate::normalize::ds::{
    accession::{
        AccessionVec,
        CrossReference,
        RawAccession,
        ReferenceVec,
    },
    basic::Basic,
    crs::{
        Crs,
        CrsVec,
    },
    feedback::{
        Feedback,
        FeedbackVec,
    },
    go_annotation::GoAnnotation,
    interacting_protein::{
        InteractingProtein,
        InteractingProteinVec,
    },
    interacting_rna::{
        InteractingRna,
        InteractingRnaVec,
    },
    precompute::{
        Precompute,
        PrecomputeSummary,
    },
    qa_status::QaStatus,
    r2dt::R2dt,
    rfam_hit::{
        RfamHit,
        RfamHitVec,
    },
    so_tree,
};

#[derive(Error, Debug)]
pub enum NormalizationError {
    #[error("Could not ungroup {0}")]
    CountError(#[from] utils::Error),

    #[error("Could not parse {0}")]
    UrsParsingError(#[from] urs::Error),

    #[error("Could not parse {0}")]
    UrsTaxidParsingError(#[from] urs_taxid::Error),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Raw {
    pub id: usize,
    pub base: Basic,
    pub crs: Vec<Crs>,
    pub feedback: Vec<Feedback>,
    pub go_annotations: Vec<GoAnnotation>,
    pub interacting_proteins: Vec<InteractingProtein>,
    pub interacting_rnas: Vec<InteractingRna>,
    pub precompute: Precompute,
    pub qa_status: QaStatus,
    pub r2dt: Option<R2dt>,
    pub rfam_hits: Vec<RfamHit>,
    pub so_tree: so_tree::SoTree,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Normalized {
    urs: String,
    taxid: usize,
    urs_taxid: String,
    short_urs: String,
    deleted: String,

    so_rna_type_tree: so_tree::SoTree,

    #[serde(flatten)]
    pre_summary: PrecomputeSummary,

    #[serde(flatten)]
    basic: Basic,

    // #[serde(flatten)]
    // dates: Dates,
    qa_status: QaStatus,
    secondary_structure: Option<R2dt>,

    accessions: AccessionVec,
    cross_references: Vec<CrossReference>,
    crs: CrsVec,
    feedback: FeedbackVec,
    go_annotations: Vec<GoAnnotation>,
    interacting_proteins: InteractingProteinVec,
    interacting_rnas: InteractingRnaVec,
    references: ReferenceVec,
    rfam_hits: RfamHitVec,
}

impl Raw {
    pub fn urs_taxid(&self) -> String {
        return self.base.urs_taxid.to_owned();
    }

    pub fn urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.to_string())
    }

    pub fn taxid(&self) -> Result<u64, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.taxid())
    }

    pub fn short_urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.short_urs())
    }

    pub fn short_urs_taxid(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.short())
    }
}

impl Normalized {
    pub fn new(
        raw: Raw,
        accessions: Vec<RawAccession>,
    ) -> Result<Self, NormalizationError> {
        let pre_summary = PrecomputeSummary::from(raw.precompute);
        let base = raw.base.clone();

        let urs_taxid = base.urs_taxid.to_owned();
        let parts: Vec<&str> = urs_taxid.split("_").collect();
        let urs = parts[0].to_owned();
        let taxid = parts[1].parse::<usize>().unwrap();
        let parsed: urs_taxid::UrsTaxid = urs_taxid.parse()?;
        let references = ReferenceVec::from_iter(accessions.clone());

        Ok(Self {
            urs_taxid,
            urs,
            taxid,
            short_urs: parsed.short(),
            deleted: String::from("N"),

            so_rna_type_tree: raw.so_tree,

            pre_summary,
            basic: base,
            qa_status: raw.qa_status,
            secondary_structure: raw.r2dt.into(),

            accessions: AccessionVec::from_iter(accessions.clone()),
            cross_references: accessions.into_iter().map(CrossReference::from).collect(),
            crs: CrsVec::from_iter(raw.crs.clone()),
            feedback: FeedbackVec::from_iter(raw.feedback.clone()),
            go_annotations: raw.go_annotations.clone(),
            interacting_proteins: InteractingProteinVec::from_iter(
                raw.interacting_proteins.clone(),
            ),
            interacting_rnas: InteractingRnaVec::from_iter(raw.interacting_rnas.clone()),
            references,
            rfam_hits: RfamHitVec::from_iter(raw.rfam_hits.clone()),
        })
    }
}
<|endoftext|>


<commit_before>#![feature(plugin, inclusive_range_syntax)]
#![feature(dotdot_in_tuple_patterns)]
#![plugin(clippy)]

#![allow(dead_code, no_effect, unnecessary_operation)]
#![allow(let_and_return)]
#![allow(needless_return)]
#![allow(unused_variables)]
#![allow(cyclomatic_complexity)]
#![allow(blacklisted_name)]
#![allow(collapsible_if)]

fn bar<T>(_: T) {}
fn foo() -> bool { unimplemented!() }

struct Foo {
    bar: u8,
}

#[deny(if_same_then_else)]
#[deny(match_same_arms)]
fn if_same_then_else() -> Result<&'static str, ()> {
    if true {
        //~^NOTE same as this
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }
    else { //~ERROR this `if` has identical blocks
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }

    if true {
        Foo { bar: 42 };
    }
    else {
        Foo { bar: 43 };
    }

    if true {
        0..10;
    }
    else {
        0...10;
    }

    if true {
        foo();
        foo();
    }
    else {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        foo();
        42
    }
    else { //~ERROR this `if` has identical blocks
        foo();
        42
    };

    if true {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        42
    }
    else { //~ERROR this `if` has identical blocks
        42
    };

    if true {
        //~^NOTE same as this
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }
    else { //~ERROR this `if` has identical blocks
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }

    if true {
        //~^NOTE same as this
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }
    else if false {
        foo();
    }
    else if foo() { //~ERROR this `if` has identical blocks
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }

    if true {
        //~^NOTE same as this
        if let Some(a) = Some(42) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let Some(a) = Some(42) {}
    }

    if true {
        //~^NOTE same as this
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let (1, .., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 4) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 1, 3) = (1, 2, 3) {}
    }

    if true {
        if let Some(a) = Some(42) {}
    }
    else {
        if let Some(a) = Some(43) {}
    }

    let _ = match 42 {
        42 => foo(),
        //~^NOTE same as this
        //~|NOTE `42 | 51`
        51 => foo(), //~ERROR this `match` has identical arm bodies
        _ => true,
    };

    let _ = match Some(42) {
        Some(_) => 24,
        //~^NOTE same as this
        //~|NOTE `Some(_) | None`
        None => 24, //~ERROR this `match` has identical arm bodies
    };

    let _ = match Some(42) {
        Some(foo) => 24,
        None => 24,
    };

    let _ = match Some(42) {
        Some(42) => 24,
        Some(a) => 24, // bindings are different
        None => 0,
    };

    let _ = match Some(42) {
        Some(a) if a > 0 => 24,
        Some(a) => 24, // one arm has a guard
        None => 0,
    };

    match (Some(42), Some(42)) {
        (Some(a), None) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), None) | (None, Some(a))`
        (None, Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (Some(42), Some(42)) {
        (Some(a), ..) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), ..) | (.., Some(a))`
        (.., Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (1, 2, 3) {
        (1, .., 3) => 42,
        //~^NOTE same as this
        //~|NOTE `(1, .., 3) | (.., 3)`
        (.., 3) => 42, //~ERROR this `match` has identical arm bodies
        _ => 0,
    };

    let _ = if true {
        //~^NOTE same as this
        0.0
    } else { //~ERROR this `if` has identical blocks
        0.0
    };

    let _ = if true {
        //~^NOTE same as this
        -0.0
    } else { //~ERROR this `if` has identical blocks
        -0.0
    };

    let _ = if true {
        0.0
    } else {
        -0.0
    };

    // Different NaNs
    let _ = if true {
        1.0 / 0.0
    } else {
        (-5f32).sqrt()
    };

    // Same NaNs
    let _ = if true {
        //~^NOTE same as this
        std::f32::NAN
    } else { //~ERROR this `if` has identical blocks
        std::f32::NAN
    };

    let _ = match Some(()) {
        Some(()) => 0.0,
        None => -0.0
    };

    match (Some(42), Some("")) {
        (Some(a), None) => bar(a),
        (None, Some(a)) => bar(a), // bindings have different types
        _ => (),
    }

    if true {
        //~^NOTE same as this
        try!(Ok("foo"));
    }
    else { //~ERROR this `if` has identical blocks
        try!(Ok("foo"));
    }

    if true {
        //~^NOTE same as this
        let foo = "";
        return Ok(&foo[0..]);
    }
    else if false {
        let foo = "bar";
        return Ok(&foo[0..]);
    }
    else { //~ERROR this `if` has identical blocks
        let foo = "";
        return Ok(&foo[0..]);
    }
}

#[deny(ifs_same_cond)]
#[allow(if_same_then_else)] // all empty blocks
fn ifs_same_cond() {
    let a = 0;
    let b = false;

    if b {
        //~^NOTE same as this
    }
    else if b { //~ERROR this `if` has the same condition as a previous if
    }

    if a == 1 {
        //~^NOTE same as this
    }
    else if a == 1 { //~ERROR this `if` has the same condition as a previous if
    }

    if 2*a == 1 {
        //~^NOTE same as this
    }
    else if 2*a == 2 {
    }
    else if 2*a == 1 { //~ERROR this `if` has the same condition as a previous if
    }
    else if a == 1 {
    }

    // See #659
    if cfg!(feature = "feature1-659") {
        1
    } else if cfg!(feature = "feature2-659") {
        2
    } else {
        3
    };

    let mut v = vec![1];
    if v.pop() == None { // ok, functions
    }
    else if v.pop() == None {
    }

    if v.len() == 42 { // ok, functions
    }
    else if v.len() == 42 {
    }
}

fn main() {}
<commit_msg>Fix different NaNs in if const expressions test<commit_after>#![feature(plugin, inclusive_range_syntax)]
#![feature(dotdot_in_tuple_patterns)]
#![plugin(clippy)]

#![allow(dead_code, no_effect, unnecessary_operation)]
#![allow(let_and_return)]
#![allow(needless_return)]
#![allow(unused_variables)]
#![allow(cyclomatic_complexity)]
#![allow(blacklisted_name)]
#![allow(collapsible_if)]
#![allow(zero_divided_by_zero, eq_op)]

fn bar<T>(_: T) {}
fn foo() -> bool { unimplemented!() }

struct Foo {
    bar: u8,
}

#[deny(if_same_then_else)]
#[deny(match_same_arms)]
fn if_same_then_else() -> Result<&'static str, ()> {
    if true {
        //~^NOTE same as this
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }
    else { //~ERROR this `if` has identical blocks
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }

    if true {
        Foo { bar: 42 };
    }
    else {
        Foo { bar: 43 };
    }

    if true {
        0..10;
    }
    else {
        0...10;
    }

    if true {
        foo();
        foo();
    }
    else {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        foo();
        42
    }
    else { //~ERROR this `if` has identical blocks
        foo();
        42
    };

    if true {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        42
    }
    else { //~ERROR this `if` has identical blocks
        42
    };

    if true {
        //~^NOTE same as this
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }
    else { //~ERROR this `if` has identical blocks
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }

    if true {
        //~^NOTE same as this
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }
    else if false {
        foo();
    }
    else if foo() { //~ERROR this `if` has identical blocks
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }

    if true {
        //~^NOTE same as this
        if let Some(a) = Some(42) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let Some(a) = Some(42) {}
    }

    if true {
        //~^NOTE same as this
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let (1, .., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 4) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 1, 3) = (1, 2, 3) {}
    }

    if true {
        if let Some(a) = Some(42) {}
    }
    else {
        if let Some(a) = Some(43) {}
    }

    let _ = match 42 {
        42 => foo(),
        //~^NOTE same as this
        //~|NOTE `42 | 51`
        51 => foo(), //~ERROR this `match` has identical arm bodies
        _ => true,
    };

    let _ = match Some(42) {
        Some(_) => 24,
        //~^NOTE same as this
        //~|NOTE `Some(_) | None`
        None => 24, //~ERROR this `match` has identical arm bodies
    };

    let _ = match Some(42) {
        Some(foo) => 24,
        None => 24,
    };

    let _ = match Some(42) {
        Some(42) => 24,
        Some(a) => 24, // bindings are different
        None => 0,
    };

    let _ = match Some(42) {
        Some(a) if a > 0 => 24,
        Some(a) => 24, // one arm has a guard
        None => 0,
    };

    match (Some(42), Some(42)) {
        (Some(a), None) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), None) | (None, Some(a))`
        (None, Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (Some(42), Some(42)) {
        (Some(a), ..) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), ..) | (.., Some(a))`
        (.., Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (1, 2, 3) {
        (1, .., 3) => 42,
        //~^NOTE same as this
        //~|NOTE `(1, .., 3) | (.., 3)`
        (.., 3) => 42, //~ERROR this `match` has identical arm bodies
        _ => 0,
    };

    let _ = if true {
        //~^NOTE same as this
        0.0
    } else { //~ERROR this `if` has identical blocks
        0.0
    };

    let _ = if true {
        //~^NOTE same as this
        -0.0
    } else { //~ERROR this `if` has identical blocks
        -0.0
    };

    let _ = if true {
        0.0
    } else {
        -0.0
    };

    // Different NaNs
    let _ = if true {
        0.0 / 0.0
    } else {
        std::f32::NAN
    };

    // Same NaNs
    let _ = if true {
        //~^NOTE same as this
        std::f32::NAN
    } else { //~ERROR this `if` has identical blocks
        std::f32::NAN
    };

    let _ = match Some(()) {
        Some(()) => 0.0,
        None => -0.0
    };

    match (Some(42), Some("")) {
        (Some(a), None) => bar(a),
        (None, Some(a)) => bar(a), // bindings have different types
        _ => (),
    }

    if true {
        //~^NOTE same as this
        try!(Ok("foo"));
    }
    else { //~ERROR this `if` has identical blocks
        try!(Ok("foo"));
    }

    if true {
        //~^NOTE same as this
        let foo = "";
        return Ok(&foo[0..]);
    }
    else if false {
        let foo = "bar";
        return Ok(&foo[0..]);
    }
    else { //~ERROR this `if` has identical blocks
        let foo = "";
        return Ok(&foo[0..]);
    }
}

#[deny(ifs_same_cond)]
#[allow(if_same_then_else)] // all empty blocks
fn ifs_same_cond() {
    let a = 0;
    let b = false;

    if b {
        //~^NOTE same as this
    }
    else if b { //~ERROR this `if` has the same condition as a previous if
    }

    if a == 1 {
        //~^NOTE same as this
    }
    else if a == 1 { //~ERROR this `if` has the same condition as a previous if
    }

    if 2*a == 1 {
        //~^NOTE same as this
    }
    else if 2*a == 2 {
    }
    else if 2*a == 1 { //~ERROR this `if` has the same condition as a previous if
    }
    else if a == 1 {
    }

    // See #659
    if cfg!(feature = "feature1-659") {
        1
    } else if cfg!(feature = "feature2-659") {
        2
    } else {
        3
    };

    let mut v = vec![1];
    if v.pop() == None { // ok, functions
    }
    else if v.pop() == None {
    }

    if v.len() == 42 { // ok, functions
    }
    else if v.len() == 42 {
    }
}

fn main() {}
<|endoftext|>


<commit_before>use ra_db::{FileId, LocalSyntaxPtr, Cancelable};
use ra_syntax::{
    SyntaxNode, AstNode, SmolStr,
    ast
};
use hir::{Def, ModuleSource};

use crate::{
    NavigationTarget,
    FileSymbol,
    db::RootDatabase,
};

impl NavigationTarget {
    pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
        NavigationTarget {
            file_id: symbol.file_id,
            name: symbol.name.clone(),
            kind: symbol.ptr.kind(),
            range: symbol.ptr.range(),
            ptr: Some(symbol.ptr.clone()),
        }
    }

    // TODO once Def::Item is gone, this should be able to always return a NavigationTarget
    pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable<Option<NavigationTarget>> {
        let res = match def {
            Def::Struct(s) => {
                let (file_id, node) = s.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Enum(e) => {
                let (file_id, node) = e.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::EnumVariant(ev) => {
                let (file_id, node) = ev.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Function(f) => {
                let (file_id, node) = f.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Module(m) => {
                let (file_id, source) = m.definition_source(db)?;
                let name = m
                    .name(db)?
                    .map(|it| it.to_string().into())
                    .unwrap_or_else(|| SmolStr::new(""));
                match source {
                    ModuleSource::SourceFile(node) => {
                        NavigationTarget::from_syntax(file_id, name, node.syntax())
                    }
                    ModuleSource::Module(node) => {
                        NavigationTarget::from_syntax(file_id, name, node.syntax())
                    }
                }
            }
            Def::Item => return Ok(None),
        };
        Ok(Some(res))
    }

    fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
        let name = node
            .name()
            .map(|it| it.text().clone())
            .unwrap_or_else(|| SmolStr::new(""));
        NavigationTarget::from_syntax(file_id, name, node.syntax())
    }

    fn from_syntax(file_id: FileId, name: SmolStr, node: &SyntaxNode) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name,
            kind: node.kind(),
            range: node.range(),
            ptr: Some(LocalSyntaxPtr::new(node)),
        }
    }
}
<commit_msg>simplify<commit_after>use ra_db::{FileId, LocalSyntaxPtr, Cancelable};
use ra_syntax::{
    SyntaxNode, AstNode, SmolStr,
    ast
};
use hir::{Def, ModuleSource};

use crate::{
    NavigationTarget,
    FileSymbol,
    db::RootDatabase,
};

impl NavigationTarget {
    pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
        NavigationTarget {
            file_id: symbol.file_id,
            name: symbol.name.clone(),
            kind: symbol.ptr.kind(),
            range: symbol.ptr.range(),
            ptr: Some(symbol.ptr.clone()),
        }
    }

    // TODO once Def::Item is gone, this should be able to always return a NavigationTarget
    pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable<Option<NavigationTarget>> {
        let res = match def {
            Def::Struct(s) => {
                let (file_id, node) = s.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Enum(e) => {
                let (file_id, node) = e.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::EnumVariant(ev) => {
                let (file_id, node) = ev.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Function(f) => {
                let (file_id, node) = f.source(db)?;
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            Def::Module(m) => {
                let (file_id, source) = m.definition_source(db)?;
                let name = m
                    .name(db)?
                    .map(|it| it.to_string().into())
                    .unwrap_or_default();
                match source {
                    ModuleSource::SourceFile(node) => {
                        NavigationTarget::from_syntax(file_id, name, node.syntax())
                    }
                    ModuleSource::Module(node) => {
                        NavigationTarget::from_syntax(file_id, name, node.syntax())
                    }
                }
            }
            Def::Item => return Ok(None),
        };
        Ok(Some(res))
    }

    fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
        let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
        NavigationTarget::from_syntax(file_id, name, node.syntax())
    }

    fn from_syntax(file_id: FileId, name: SmolStr, node: &SyntaxNode) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name,
            kind: node.kind(),
            range: node.range(),
            ptr: Some(LocalSyntaxPtr::new(node)),
        }
    }
}
<|endoftext|>


<commit_before>//! Mountain biome

use cgmath::{Point3, Vector3, EuclideanVector};
use noise::{Seed, Brownian2, Brownian3, perlin2, perlin3};

use voxel;
use voxel_base;

#[allow(missing_docs)]
pub struct T {
  pub height: Brownian2<f64, fn (&Seed, &[f64; 2]) -> f64>,
  pub features: Brownian3<f64, fn (&Seed, &[f64; 3]) -> f64>,
  pub seed: Seed,
}

#[allow(missing_docs)]
pub fn new(seed: Seed) -> T {
  let perlin2: fn(&Seed, &[f64; 2]) -> f64 = perlin2;
  let perlin3: fn(&Seed, &[f64; 3]) -> f64 = perlin3;
  T {
    seed: seed,
    height:
      Brownian2::new(perlin2, 5)
      .frequency(1.0 / 4.0)
      .persistence(2.0)
      .lacunarity(1.0 / 2.0)
    ,
    features:
      Brownian3::new(perlin3, 2)
      .frequency(1.0 / 32.0)
      .persistence(8.0)
      .lacunarity(1.0 / 4.0)
    ,
  }
}

impl voxel_base::field::T for T {
  fn density(&self, p: &Point3<f32>) -> f32 {
    let height = self.height.apply(&self.seed, &[p.x as f64, p.z as f64]);
    let height = height as f32;
    let heightmap_density = height - p.y;

    let feature_density = self.features.apply(&self.seed, &[p.x as f64, p.y as f64, p.z as f64]) * 8.0;
    let feature_density = feature_density as f32;

    heightmap_density + feature_density
  }

  fn normal(&self, p: &Point3<f32>) -> Vector3<f32> {
    // Use density differential in each dimension as an approximation of the normal.

    let delta = 0.01;

    macro_rules! differential(($d:ident) => {{
      let high: f32 = {
        let mut p = *p;
        p.$d += delta;
        voxel_base::field::T::density(self, &p)
      };
      let low: f32 = {
        let mut p = *p;
        p.$d -= delta;
        voxel_base::field::T::density(self, &p)
      };
      high - low
    }});

    let v = Vector3::new(differential!(x), differential!(y), differential!(z));
    // Negate because we're leaving the volume when density is decreasing.
    let v = -v;
    v.normalize()
  }
}

impl voxel_base::mosaic::T for T {
  type Material = voxel::Material;

  fn material(&self, p: &Point3<f32>) -> Option<voxel::Material> {
    Some(
      if voxel_base::field::T::density(self, p) >= 0.0 {
        voxel::Material::Stone
      } else {
        voxel::Material::Empty
      }
    )
  }
}
<commit_msg>diferentiate mountain biome more<commit_after>//! Mountain biome

use cgmath::{Point3, Vector3, EuclideanVector};
use noise::{Seed, Brownian2, Brownian3, perlin2, perlin3};

use voxel;
use voxel_base;

#[allow(missing_docs)]
pub struct T {
  pub height: Brownian2<f64, fn (&Seed, &[f64; 2]) -> f64>,
  pub features: Brownian3<f64, fn (&Seed, &[f64; 3]) -> f64>,
  pub seed: Seed,
}

#[allow(missing_docs)]
pub fn new(seed: Seed) -> T {
  let perlin2: fn(&Seed, &[f64; 2]) -> f64 = perlin2;
  let perlin3: fn(&Seed, &[f64; 3]) -> f64 = perlin3;
  T {
    seed: seed,
    height:
      Brownian2::new(perlin2, 5)
      .frequency(1.0 / 4.0)
      .persistence(4.0)
      .lacunarity(1.0 / 4.0)
    ,
    features:
      Brownian3::new(perlin3, 2)
      .frequency(1.0 / 32.0)
      .persistence(8.0)
      .lacunarity(1.0 / 4.0)
    ,
  }
}

impl voxel_base::field::T for T {
  fn density(&self, p: &Point3<f32>) -> f32 {
    let height = self.height.apply(&self.seed, &[p.x as f64, p.z as f64]);
    let height = height as f32;
    let heightmap_density = height - p.y;

    let feature_density = self.features.apply(&self.seed, &[p.x as f64, p.y as f64, p.z as f64]) * 8.0;
    let feature_density = feature_density as f32;
    let feature_density = feature_density * 2.0;

    heightmap_density + feature_density
  }

  fn normal(&self, p: &Point3<f32>) -> Vector3<f32> {
    // Use density differential in each dimension as an approximation of the normal.

    let delta = 0.01;

    macro_rules! differential(($d:ident) => {{
      let high: f32 = {
        let mut p = *p;
        p.$d += delta;
        voxel_base::field::T::density(self, &p)
      };
      let low: f32 = {
        let mut p = *p;
        p.$d -= delta;
        voxel_base::field::T::density(self, &p)
      };
      high - low
    }});

    let v = Vector3::new(differential!(x), differential!(y), differential!(z));
    // Negate because we're leaving the volume when density is decreasing.
    let v = -v;
    v.normalize()
  }
}

impl voxel_base::mosaic::T for T {
  type Material = voxel::Material;

  fn material(&self, p: &Point3<f32>) -> Option<voxel::Material> {
    Some(
      if voxel_base::field::T::density(self, p) >= 0.0 {
        voxel::Material::Stone
      } else {
        voxel::Material::Empty
      }
    )
  }
}
<|endoftext|>


<commit_before>use ide_db::defs::{Definition, NameRefClass};
use syntax::{ast, AstNode, SyntaxKind, T};

use crate::{
    assist_context::{AssistContext, Assists},
    AssistId, AssistKind,
};

// Assist: add_turbo_fish
//
// Adds `::<_>` to a call of a generic method or function.
//
// ```
// fn make<T>() -> T { todo!() }
// fn main() {
//     let x = make$0();
// }
// ```
// ->
// ```
// fn make<T>() -> T { todo!() }
// fn main() {
//     let x = make::<${0:_}>();
// }
// ```
pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let ident = ctx.find_token_syntax_at_offset(SyntaxKind::IDENT).or_else(|| {
        let arg_list = ctx.find_node_at_offset::<ast::ArgList>()?;
        if arg_list.args().next().is_some() {
            return None;
        }
        cov_mark::hit!(add_turbo_fish_after_call);
        cov_mark::hit!(add_type_ascription_after_call);
        arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT)
    })?;
    let next_token = ident.next_token()?;
    if next_token.kind() == T![::] {
        cov_mark::hit!(add_turbo_fish_one_fish_is_enough);
        return None;
    }
    let name_ref = ast::NameRef::cast(ident.parent()?)?;
    let def = match NameRefClass::classify(&ctx.sema, &name_ref)? {
        NameRefClass::Definition(def) => def,
        NameRefClass::FieldShorthand { .. } => return None,
    };
    let fun = match def {
        Definition::Function(it) => it,
        _ => return None,
    };
    let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
    if generics.is_empty() {
        cov_mark::hit!(add_turbo_fish_non_generic);
        return None;
    }

    if let Some(let_stmt) = ctx.find_node_at_offset::<ast::LetStmt>() {
        if let_stmt.colon_token().is_none() {
            let type_pos = let_stmt.pat()?.syntax().last_token()?.text_range().end();
            let semi_pos = let_stmt.syntax().last_token()?.text_range().end();

            acc.add(
                AssistId("add_type_ascription", AssistKind::RefactorRewrite),
                "Add `: _` before assignment operator",
                ident.text_range(),
                |builder| {
                    if let_stmt.semicolon_token().is_none() {
                        builder.insert(semi_pos, ";");
                    }
                    match ctx.config.snippet_cap {
                        Some(cap) => builder.insert_snippet(cap, type_pos, ": ${0:_}"),
                        None => builder.insert(type_pos, ": _"),
                    }
                },
            )?
        } else {
            cov_mark::hit!(add_type_ascription_already_typed);
        }
    }

    let number_of_arguments = generics.len();
    let fish_head = std::iter::repeat("_").take(number_of_arguments).collect::<Vec<_>>().join(",");

    acc.add(
        AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
        "Add `::<>`",
        ident.text_range(),
        |builder| match ctx.config.snippet_cap {
            Some(cap) => {
                let snip = format!("::<${{0:{}}}>", fish_head);
                builder.insert_snippet(cap, ident.text_range().end(), snip)
            }
            None => {
                let snip = format!("::<{}>", fish_head);
                builder.insert(ident.text_range().end(), snip);
            }
        },
    )
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable};

    use super::*;

    #[test]
    fn add_turbo_fish_function() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_function_multiple_generic_types() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T, A>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T, A>() -> T {}
fn main() {
    make::<${0:_,_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_function_many_generic_types() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T, A, B, C, D, E, F>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T, A, B, C, D, E, F>() -> T {}
fn main() {
    make::<${0:_,_,_,_,_,_,_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_after_call() {
        cov_mark::check!(add_turbo_fish_after_call);
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make()$0;
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_method() {
        check_assist(
            add_turbo_fish,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    S.make$0();
}
"#,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    S.make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_one_fish_is_enough() {
        cov_mark::check!(add_turbo_fish_one_fish_is_enough);
        check_assist_not_applicable(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make$0::<()>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_non_generic() {
        cov_mark::check!(add_turbo_fish_non_generic);
        check_assist_not_applicable(
            add_turbo_fish,
            r#"
fn make() -> () {}
fn main() {
    make$0();
}
"#,
        );
    }

    #[test]
    fn add_type_ascription_function() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_after_call() {
        cov_mark::check!(add_type_ascription_after_call);
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make()$0;
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_method() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    let x = S.make$0();
}
"#,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    let x: ${0:_} = S.make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_already_typed() {
        cov_mark::check!(add_type_ascription_already_typed);
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: () = make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: () = make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_type_ascription_append_semicolon() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make$0()
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }
}
<commit_msg>Count the type parameters only<commit_after>use ide_db::defs::{Definition, NameRefClass};
use syntax::{ast, AstNode, SyntaxKind, T};

use crate::{
    assist_context::{AssistContext, Assists},
    AssistId, AssistKind,
};

// Assist: add_turbo_fish
//
// Adds `::<_>` to a call of a generic method or function.
//
// ```
// fn make<T>() -> T { todo!() }
// fn main() {
//     let x = make$0();
// }
// ```
// ->
// ```
// fn make<T>() -> T { todo!() }
// fn main() {
//     let x = make::<${0:_}>();
// }
// ```
pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let ident = ctx.find_token_syntax_at_offset(SyntaxKind::IDENT).or_else(|| {
        let arg_list = ctx.find_node_at_offset::<ast::ArgList>()?;
        if arg_list.args().next().is_some() {
            return None;
        }
        cov_mark::hit!(add_turbo_fish_after_call);
        cov_mark::hit!(add_type_ascription_after_call);
        arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT)
    })?;
    let next_token = ident.next_token()?;
    if next_token.kind() == T![::] {
        cov_mark::hit!(add_turbo_fish_one_fish_is_enough);
        return None;
    }
    let name_ref = ast::NameRef::cast(ident.parent()?)?;
    let def = match NameRefClass::classify(&ctx.sema, &name_ref)? {
        NameRefClass::Definition(def) => def,
        NameRefClass::FieldShorthand { .. } => return None,
    };
    let fun = match def {
        Definition::Function(it) => it,
        _ => return None,
    };
    let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
    if generics.is_empty() {
        cov_mark::hit!(add_turbo_fish_non_generic);
        return None;
    }

    if let Some(let_stmt) = ctx.find_node_at_offset::<ast::LetStmt>() {
        if let_stmt.colon_token().is_none() {
            let type_pos = let_stmt.pat()?.syntax().last_token()?.text_range().end();
            let semi_pos = let_stmt.syntax().last_token()?.text_range().end();

            acc.add(
                AssistId("add_type_ascription", AssistKind::RefactorRewrite),
                "Add `: _` before assignment operator",
                ident.text_range(),
                |builder| {
                    if let_stmt.semicolon_token().is_none() {
                        builder.insert(semi_pos, ";");
                    }
                    match ctx.config.snippet_cap {
                        Some(cap) => builder.insert_snippet(cap, type_pos, ": ${0:_}"),
                        None => builder.insert(type_pos, ": _"),
                    }
                },
            )?
        } else {
            cov_mark::hit!(add_type_ascription_already_typed);
        }
    }

    let number_of_arguments = generics
        .iter()
        .filter(|param| match param {
            hir::GenericParam::TypeParam(_) => true,
            _ => false,
        })
        .count();
    let fish_head = std::iter::repeat("_").take(number_of_arguments).collect::<Vec<_>>().join(",");

    acc.add(
        AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
        "Add `::<>`",
        ident.text_range(),
        |builder| match ctx.config.snippet_cap {
            Some(cap) => {
                let snip = format!("::<${{0:{}}}>", fish_head);
                builder.insert_snippet(cap, ident.text_range().end(), snip)
            }
            None => {
                let snip = format!("::<{}>", fish_head);
                builder.insert(ident.text_range().end(), snip);
            }
        },
    )
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable};

    use super::*;

    #[test]
    fn add_turbo_fish_function() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_function_multiple_generic_types() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T, A>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T, A>() -> T {}
fn main() {
    make::<${0:_,_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_function_many_generic_types() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<T, A, B, C, D, E, F>() -> T {}
fn main() {
    make$0();
}
"#,
            r#"
fn make<T, A, B, C, D, E, F>() -> T {}
fn main() {
    make::<${0:_,_,_,_,_,_,_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_after_call() {
        cov_mark::check!(add_turbo_fish_after_call);
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make()$0;
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_method() {
        check_assist(
            add_turbo_fish,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    S.make$0();
}
"#,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    S.make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_one_fish_is_enough() {
        cov_mark::check!(add_turbo_fish_one_fish_is_enough);
        check_assist_not_applicable(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    make$0::<()>();
}
"#,
        );
    }

    #[test]
    fn add_turbo_fish_non_generic() {
        cov_mark::check!(add_turbo_fish_non_generic);
        check_assist_not_applicable(
            add_turbo_fish,
            r#"
fn make() -> () {}
fn main() {
    make$0();
}
"#,
        );
    }

    #[test]
    fn add_type_ascription_function() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_after_call() {
        cov_mark::check!(add_type_ascription_after_call);
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make()$0;
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_method() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    let x = S.make$0();
}
"#,
            r#"
struct S;
impl S {
    fn make<T>(&self) -> T {}
}
fn main() {
    let x: ${0:_} = S.make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_type_ascription_already_typed() {
        cov_mark::check!(add_type_ascription_already_typed);
        check_assist(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: () = make$0();
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: () = make::<${0:_}>();
}
"#,
        );
    }

    #[test]
    fn add_type_ascription_append_semicolon() {
        check_assist_by_label(
            add_turbo_fish,
            r#"
fn make<T>() -> T {}
fn main() {
    let x = make$0()
}
"#,
            r#"
fn make<T>() -> T {}
fn main() {
    let x: ${0:_} = make();
}
"#,
            "Add `: _` before assignment operator",
        );
    }

    #[test]
    fn add_turbo_fish_function_lifetime_parameter() {
        check_assist(
            add_turbo_fish,
            r#"
fn make<'a, T, A>(t: T, a: A) {}
fn main() {
    make$0(5, 2);
}
"#,
            r#"
fn make<'a, T, A>(t: T, a: A) {}
fn main() {
    make::<${0:_,_}>(5, 2);
}
"#,
        );
    }
}
<|endoftext|>