<commit_before>#![crate_name = "graphics"]
#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! A library for 2D graphics that works with multiple back-ends.
//!
//! Piston-Graphics was started in 2014 by Sven Nilsen to test
//! back-end agnostic design for 2D in Rust.
//! This means generic code can be reused across projects and platforms.
//!
//! ### Design
//!
//! A graphics back-end implements the `Graphics` trait.
//!
//! This library uses immediate design for flexibility.
//! By default, triangles are generated from 2D shapes and passed in chunks
//! to the back-end. This behavior can be overridden by a back-end library.
//!
//! The structures used for drawing 2D shapes contains settings for rendering.
//! The separation of shapes and settings allows more reuse and flexibility.
//! For example, to render an image, you use an `Image` object.
//!
//! The `math` module contains useful methods for 2D geometry.
//!
//! `Context` stores settings that are commonly shared when rendering.
//! It can be copied and changed without affecting any global state.
//!
//! At top level, there are some shortcut methods for common operations.
//! For example, `ellipse` is a simplified version of `Ellipse`.

extern crate vecmath;
extern crate texture;
extern crate read_color;
extern crate interpolation;
extern crate viewport;

pub use texture::ImageSize;
pub use viewport::Viewport;

pub use graphics::Graphics;
pub use character::{Character, CharacterCache};
pub use source_rectangled::SourceRectangled;
pub use rectangled::Rectangled;
pub use transformed::Transformed;
pub use colored::Colored;
pub use rectangle::Rectangle;
pub use line::Line;
pub use ellipse::Ellipse;
pub use circle_arc::CircleArc;
pub use image::Image;
pub use polygon::Polygon;
pub use text::Text;
pub use context::Context;
pub use draw_state::DrawState;

/// Any triangulation method called on the back-end
/// never exceeds this number of vertices.
/// This can be used to initialize buffers that fit the chunk size.
///
/// Must be a multiple of 3 because you need 3 vertices per triangle
/// in a triangle list.
pub const BACK_END_MAX_VERTEX_COUNT: usize = 1023;

mod graphics;
mod source_rectangled;
mod rectangled;
mod transformed;
mod colored;

pub mod draw_state;
pub mod character;
pub mod context;
pub mod color;
pub mod polygon;
pub mod line;
pub mod circle_arc;
pub mod ellipse;
pub mod rectangle;
pub mod image;
pub mod types;
pub mod modular_index;
pub mod text;
pub mod triangulation;
pub mod math;
pub mod grid;
pub mod glyph_cache;
pub mod texture_packer;

pub mod radians {
    //! Reexport radians helper trait from vecmath

    pub use vecmath::traits::Radians;
}

/// Clears the screen.
pub fn clear<G>(color: types::Color, g: &mut G)
    where G: Graphics
{
    g.clear_color(color);
    g.clear_stencil(0);
}

/// Draws image.
pub fn image<G>(image: &<G as Graphics>::Texture, transform: math::Matrix2d, g: &mut G)
    where G: Graphics
{
    Image::new().draw(image, &Default::default(), transform, g);
}

/// Draws ellipse by corners.
pub fn ellipse_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                        from: P,
                                        to: P,
                                        transform: math::Matrix2d,
                                        g: &mut G)
    where G: Graphics
{
    Ellipse::new(color).draw_from_to(from, to, &Default::default(), transform, g);
}

/// Draws ellipse.
pub fn ellipse<R: Into<types::Rectangle>, G>(color: types::Color,
                                             rect: R,
                                             transform: math::Matrix2d,
                                             g: &mut G)
    where G: Graphics
{
    Ellipse::new(color).draw(rect, &Default::default(), transform, g);
}

/// Draws arc
pub fn circle_arc<R: Into<types::Rectangle>, G>(color: types::Color,
                                                radius: types::Radius,
                                                start: types::Scalar,
                                                end: types::Scalar,
                                                rect: R,
                                                transform: math::Matrix2d,
                                                g: &mut G)
    where G: Graphics
{
    CircleArc::new(color, radius, start, end).draw(rect, &Default::default(), transform, g);
}

/// Draws rectangle.
pub fn rectangle_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                               from: P,
                                               to: P,
                                               transform: math::Matrix2d,
                                               g: &mut G)
    where G: Graphics
{
    Rectangle::new(color).draw_from_to(from, to, &Default::default(), transform, g);
}

/// Draws rectangle.
pub fn rectangle<R: Into<types::Rectangle>, G>(color: types::Color,
                                               rect: R,
                                               transform: math::Matrix2d,
                                               g: &mut G)
    where G: Graphics
{
    Rectangle::new(color).draw(rect, &Default::default(), transform, g);
}

/// Draws polygon.
pub fn polygon<G>(color: types::Color,
                  polygon: types::Polygon,
                  transform: math::Matrix2d,
                  g: &mut G)
    where G: Graphics
{
    Polygon::new(color).draw(polygon, &Default::default(), transform, g);
}

/// Draws line between points.
pub fn line_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                     radius: types::Radius,
                                     from: P,
                                     to: P,
                                     transform: math::Matrix2d,
                                     g: &mut G)
    where G: Graphics
{
    Line::new(color, radius).draw_from_to(from, to, &Default::default(), transform, g)
}

/// Draws line.
pub fn line<L: Into<types::Line>, G>(color: types::Color,
                                     radius: types::Radius,
                                     line: L,
                                     transform: math::Matrix2d,
                                     g: &mut G)
    where G: Graphics
{
    Line::new(color, radius).draw(line, &Default::default(), transform, g)
}

/// Draws text.
pub fn text<C, G>(
    color: types::Color,
    font_size: types::FontSize,
    text: &str,
    cache: &mut C,
    transform: math::Matrix2d,
    g: &mut G
) -> Result<(), C::Error>
    where
        C: character::CharacterCache,
        G: Graphics<Texture = <C as character::CharacterCache>::Texture>
{
    Text::new_color(color, font_size).draw(text, cache, &Default::default(), transform, g)
}
<commit_msg>Reexport `Radians` at top level<commit_after>#![crate_name = "graphics"]
#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! A library for 2D graphics that works with multiple back-ends.
//!
//! Piston-Graphics was started in 2014 by Sven Nilsen to test
//! back-end agnostic design for 2D in Rust.
//! This means generic code can be reused across projects and platforms.
//!
//! ### Design
//!
//! A graphics back-end implements the `Graphics` trait.
//!
//! This library uses immediate design for flexibility.
//! By default, triangles are generated from 2D shapes and passed in chunks
//! to the back-end. This behavior can be overridden by a back-end library.
//!
//! The structures used for drawing 2D shapes contains settings for rendering.
//! The separation of shapes and settings allows more reuse and flexibility.
//! For example, to render an image, you use an `Image` object.
//!
//! The `math` module contains useful methods for 2D geometry.
//!
//! `Context` stores settings that are commonly shared when rendering.
//! It can be copied and changed without affecting any global state.
//!
//! At top level, there are some shortcut methods for common operations.
//! For example, `ellipse` is a simplified version of `Ellipse`.

extern crate vecmath;
extern crate texture;
extern crate read_color;
extern crate interpolation;
extern crate viewport;

pub use texture::ImageSize;
pub use viewport::Viewport;

pub use graphics::Graphics;
pub use character::{Character, CharacterCache};
pub use source_rectangled::SourceRectangled;
pub use rectangled::Rectangled;
pub use transformed::Transformed;
pub use colored::Colored;
pub use rectangle::Rectangle;
pub use line::Line;
pub use ellipse::Ellipse;
pub use circle_arc::CircleArc;
pub use image::Image;
pub use polygon::Polygon;
pub use text::Text;
pub use context::Context;
pub use draw_state::DrawState;
pub use radians::Radians;

/// Any triangulation method called on the back-end
/// never exceeds this number of vertices.
/// This can be used to initialize buffers that fit the chunk size.
///
/// Must be a multiple of 3 because you need 3 vertices per triangle
/// in a triangle list.
pub const BACK_END_MAX_VERTEX_COUNT: usize = 1023;

mod graphics;
mod source_rectangled;
mod rectangled;
mod transformed;
mod colored;

pub mod draw_state;
pub mod character;
pub mod context;
pub mod color;
pub mod polygon;
pub mod line;
pub mod circle_arc;
pub mod ellipse;
pub mod rectangle;
pub mod image;
pub mod types;
pub mod modular_index;
pub mod text;
pub mod triangulation;
pub mod math;
pub mod grid;
pub mod glyph_cache;
pub mod texture_packer;

pub mod radians {
    //! Reexport radians helper trait from vecmath

    pub use vecmath::traits::Radians;
}

/// Clears the screen.
pub fn clear<G>(color: types::Color, g: &mut G)
    where G: Graphics
{
    g.clear_color(color);
    g.clear_stencil(0);
}

/// Draws image.
pub fn image<G>(image: &<G as Graphics>::Texture, transform: math::Matrix2d, g: &mut G)
    where G: Graphics
{
    Image::new().draw(image, &Default::default(), transform, g);
}

/// Draws ellipse by corners.
pub fn ellipse_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                        from: P,
                                        to: P,
                                        transform: math::Matrix2d,
                                        g: &mut G)
    where G: Graphics
{
    Ellipse::new(color).draw_from_to(from, to, &Default::default(), transform, g);
}

/// Draws ellipse.
pub fn ellipse<R: Into<types::Rectangle>, G>(color: types::Color,
                                             rect: R,
                                             transform: math::Matrix2d,
                                             g: &mut G)
    where G: Graphics
{
    Ellipse::new(color).draw(rect, &Default::default(), transform, g);
}

/// Draws arc
pub fn circle_arc<R: Into<types::Rectangle>, G>(color: types::Color,
                                                radius: types::Radius,
                                                start: types::Scalar,
                                                end: types::Scalar,
                                                rect: R,
                                                transform: math::Matrix2d,
                                                g: &mut G)
    where G: Graphics
{
    CircleArc::new(color, radius, start, end).draw(rect, &Default::default(), transform, g);
}

/// Draws rectangle.
pub fn rectangle_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                               from: P,
                                               to: P,
                                               transform: math::Matrix2d,
                                               g: &mut G)
    where G: Graphics
{
    Rectangle::new(color).draw_from_to(from, to, &Default::default(), transform, g);
}

/// Draws rectangle.
pub fn rectangle<R: Into<types::Rectangle>, G>(color: types::Color,
                                               rect: R,
                                               transform: math::Matrix2d,
                                               g: &mut G)
    where G: Graphics
{
    Rectangle::new(color).draw(rect, &Default::default(), transform, g);
}

/// Draws polygon.
pub fn polygon<G>(color: types::Color,
                  polygon: types::Polygon,
                  transform: math::Matrix2d,
                  g: &mut G)
    where G: Graphics
{
    Polygon::new(color).draw(polygon, &Default::default(), transform, g);
}

/// Draws line between points.
pub fn line_from_to<P: Into<types::Vec2d>, G>(color: types::Color,
                                     radius: types::Radius,
                                     from: P,
                                     to: P,
                                     transform: math::Matrix2d,
                                     g: &mut G)
    where G: Graphics
{
    Line::new(color, radius).draw_from_to(from, to, &Default::default(), transform, g)
}

/// Draws line.
pub fn line<L: Into<types::Line>, G>(color: types::Color,
                                     radius: types::Radius,
                                     line: L,
                                     transform: math::Matrix2d,
                                     g: &mut G)
    where G: Graphics
{
    Line::new(color, radius).draw(line, &Default::default(), transform, g)
}

/// Draws text.
pub fn text<C, G>(
    color: types::Color,
    font_size: types::FontSize,
    text: &str,
    cache: &mut C,
    transform: math::Matrix2d,
    g: &mut G
) -> Result<(), C::Error>
    where
        C: character::CharacterCache,
        G: Graphics<Texture = <C as character::CharacterCache>::Texture>
{
    Text::new_color(color, font_size).draw(text, cache, &Default::default(), transform, g)
}
<|endoftext|>


<commit_before>use vector::{Vector, P2d};

mod vector;

#[inline]
fn attractive_force<V>(p1: &V, p2: &V, k_s: f32) -> V where V: Vector<Scalar=f32>
{
    let mut force = p1.sub(p2);
    let length = force.length_squared().sqrt();
    let strength = length / k_s;
    force.scale(strength);
    return force;
}

#[inline]
fn repulsive_force<V>(p1: &V, p2: &V, k_r: f32) -> V where V: Vector<Scalar=f32>
{
    let mut force = p1.sub(p2);
    let length_squared = force.length_squared();
    if length_squared > 0.0 {
        let strength = k_r / length_squared;
        force.scale(strength);
    }
    return force;
}

fn calculate_node_forces<V>(forces: &mut[V], node_positions: &[V], node_neighbors: &[Vec<usize>],
                  k_r: f32, k_s: f32) where V: Vector<Scalar=f32> {
    let n = forces.len();
    assert!(node_positions.len() == n);
    assert!(node_neighbors.len() == n);

    // Reset all forces to zero.
    for force in &mut forces[..] {
        force.reset();
    }

    // Calculate repulsive force between all pairs.
    for i1 in 0 .. n - 1 {
        for i2 in i1 + 1 .. n {
            let force = repulsive_force(&node_positions[i1], &node_positions[i2], k_r);
            forces[i1].add_scaled(1.0, &force);
            forces[i2].add_scaled(-1.0, &force);
        }
    }

    // Calculate spring force between adjacent pairs.
    for i1 in 0 .. n {
        for i2 in node_neighbors[i1].iter().map(|&i| i as usize) {
            if i1 < i2 {
                let force = attractive_force(&node_positions[i1], &node_positions[i2], k_s);
                forces[i1].add_scaled(-1.0, &force);
                forces[i2].add_scaled(1.0, &force);
            }
        }
    }
}

fn update_node_positions<V>(forces: &[V], node_positions: &mut[V], step: f32, min_pos: &V, max_pos: &V) -> f32
where V: Vector<Scalar=f32> {
    let n = forces.len();
    assert!(node_positions.len() == n);

    let mut sum_distance = 0.0;

    for i in 0..n {
        let before = node_positions[i].clone();

        let length = forces[i].length_squared().sqrt();
        if length > 0.0 {
            // XXX: can we treat the scaled force as moved distance?
            node_positions[i].add_scaled(step / length, &forces[i]);
        }
        node_positions[i].clip_within(min_pos, max_pos);

        // add up the moved distance
        sum_distance += before.sub(&node_positions[i]).length_squared().sqrt();
    }

    return sum_distance;
}

pub fn fruchterman_reingold<F,V>(step_fn: F, max_iter: usize, converge_eps: f32, k_r: f32, k_s: f32, min_pos: &V, max_pos: &V,
                             node_positions: &mut[V], node_neighbors: &[Vec<usize>])
where V: Vector<Scalar=f32>, F: Fn(usize) -> f32
{
    let n = node_positions.len();
    assert!(node_neighbors.len() == n);

    // initialize forces
    let mut forces: Vec<V> = (0..n).map(|_| V::new()).collect();

    let mut iter: usize = 0;
    while iter < max_iter {
        let step = step_fn(iter);
        iter += 1;

        calculate_node_forces(&mut forces, node_positions, node_neighbors, k_r, k_s);
        let dist_moved = update_node_positions(&forces, node_positions, step, min_pos, max_pos);
        if dist_moved < converge_eps {
            break;
        }
    }
}

pub fn typical_fruchterman_reingold_2d(area: f32, node_positions: &mut[P2d], node_neighbors: &[Vec<usize>]) {
    let n = node_positions.len();
    assert!(node_neighbors.len() == n);

    const MAX_ITER: usize = 300;
    const EPS: f32 = 0.1;
    const OPT_PAIR_SQR_DIST_SCALE: f32 = 0.3;

    let min_pos = P2d(0.0, 0.0);
    let max_pos = P2d(1.0, 1.0);
    let step_fn = |iter| { 1.0 / (1.0 + (iter as f32) * 0.1) };

    let k_r: f32 = OPT_PAIR_SQR_DIST_SCALE * area / (n as f32);
    let k_s = k_r.sqrt();

    fruchterman_reingold(step_fn, MAX_ITER, EPS, k_r, k_s, &min_pos, &max_pos, node_positions, node_neighbors);
}
<commit_msg>pub use Vector and P2d<commit_after>pub use vector::{Vector, P2d};

mod vector;

#[inline]
fn attractive_force<V>(p1: &V, p2: &V, k_s: f32) -> V where V: Vector<Scalar=f32>
{
    let mut force = p1.sub(p2);
    let length = force.length_squared().sqrt();
    let strength = length / k_s;
    force.scale(strength);
    return force;
}

#[inline]
fn repulsive_force<V>(p1: &V, p2: &V, k_r: f32) -> V where V: Vector<Scalar=f32>
{
    let mut force = p1.sub(p2);
    let length_squared = force.length_squared();
    if length_squared > 0.0 {
        let strength = k_r / length_squared;
        force.scale(strength);
    }
    return force;
}

fn calculate_node_forces<V>(forces: &mut[V], node_positions: &[V], node_neighbors: &[Vec<usize>],
                  k_r: f32, k_s: f32) where V: Vector<Scalar=f32> {
    let n = forces.len();
    assert!(node_positions.len() == n);
    assert!(node_neighbors.len() == n);

    // Reset all forces to zero.
    for force in &mut forces[..] {
        force.reset();
    }

    // Calculate repulsive force between all pairs.
    for i1 in 0 .. n - 1 {
        for i2 in i1 + 1 .. n {
            let force = repulsive_force(&node_positions[i1], &node_positions[i2], k_r);
            forces[i1].add_scaled(1.0, &force);
            forces[i2].add_scaled(-1.0, &force);
        }
    }

    // Calculate spring force between adjacent pairs.
    for i1 in 0 .. n {
        for i2 in node_neighbors[i1].iter().map(|&i| i as usize) {
            if i1 < i2 {
                let force = attractive_force(&node_positions[i1], &node_positions[i2], k_s);
                forces[i1].add_scaled(-1.0, &force);
                forces[i2].add_scaled(1.0, &force);
            }
        }
    }
}

fn update_node_positions<V>(forces: &[V], node_positions: &mut[V], step: f32, min_pos: &V, max_pos: &V) -> f32
where V: Vector<Scalar=f32> {
    let n = forces.len();
    assert!(node_positions.len() == n);

    let mut sum_distance = 0.0;

    for i in 0..n {
        let before = node_positions[i].clone();

        let length = forces[i].length_squared().sqrt();
        if length > 0.0 {
            // XXX: can we treat the scaled force as moved distance?
            node_positions[i].add_scaled(step / length, &forces[i]);
        }
        node_positions[i].clip_within(min_pos, max_pos);

        // add up the moved distance
        sum_distance += before.sub(&node_positions[i]).length_squared().sqrt();
    }

    return sum_distance;
}

pub fn fruchterman_reingold<F,V>(step_fn: F, max_iter: usize, converge_eps: f32, k_r: f32, k_s: f32, min_pos: &V, max_pos: &V,
                             node_positions: &mut[V], node_neighbors: &[Vec<usize>])
where V: Vector<Scalar=f32>, F: Fn(usize) -> f32
{
    let n = node_positions.len();
    assert!(node_neighbors.len() == n);

    // initialize forces
    let mut forces: Vec<V> = (0..n).map(|_| V::new()).collect();

    let mut iter: usize = 0;
    while iter < max_iter {
        let step = step_fn(iter);
        iter += 1;

        calculate_node_forces(&mut forces, node_positions, node_neighbors, k_r, k_s);
        let dist_moved = update_node_positions(&forces, node_positions, step, min_pos, max_pos);
        if dist_moved < converge_eps {
            break;
        }
    }
}

pub fn typical_fruchterman_reingold_2d(area: f32, node_positions: &mut[P2d], node_neighbors: &[Vec<usize>]) {
    let n = node_positions.len();
    assert!(node_neighbors.len() == n);

    const MAX_ITER: usize = 300;
    const EPS: f32 = 0.1;
    const OPT_PAIR_SQR_DIST_SCALE: f32 = 0.3;

    let min_pos = P2d(0.0, 0.0);
    let max_pos = P2d(1.0, 1.0);
    let step_fn = |iter| { 1.0 / (1.0 + (iter as f32) * 0.1) };

    let k_r: f32 = OPT_PAIR_SQR_DIST_SCALE * area / (n as f32);
    let k_s = k_r.sqrt();

    fruchterman_reingold(step_fn, MAX_ITER, EPS, k_r, k_s, &min_pos, &max_pos, node_positions, node_neighbors);
}
<|endoftext|>


<commit_before>#![feature(rustc_private, decl_macro, type_alias_impl_trait, associated_type_bounds, never_type, try_blocks)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]

extern crate flate2;
#[cfg(feature = "jit")]
extern crate libc;
extern crate rustc_middle;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_fs_util;
extern crate rustc_hir;
extern crate rustc_incremental;
extern crate rustc_index;
extern crate rustc_mir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_symbol_mangling;
extern crate rustc_target;
extern crate rustc_ast;

// This prevents duplicating functions and statics that are already part of the host rustc process.
#[allow(unused_extern_crates)]
extern crate rustc_driver;

use std::any::Any;

use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{DepGraph, WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_session::Session;
use rustc_session::config::OutputFilenames;
use rustc_middle::ty::query::Providers;
use rustc_codegen_ssa::CodegenResults;
use rustc_codegen_ssa::traits::CodegenBackend;

use cranelift_codegen::settings::{self, Configurable};

use crate::constant::ConstantCx;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod atomic_shim;
mod base;
mod backend;
mod cast;
mod codegen_i128;
mod common;
mod constant;
mod debuginfo;
mod discriminant;
mod driver;
mod inline_asm;
mod intrinsics;
mod linkage;
mod main_shim;
mod metadata;
mod num;
mod optimize;
mod pointer;
mod pretty_clif;
mod target_features_whitelist;
mod toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

mod prelude {
    pub(crate) use std::convert::{TryFrom, TryInto};

    pub(crate) use rustc_ast::ast::{FloatTy, IntTy, UintTy};
    pub(crate) use rustc_span::Span;

    pub(crate) use rustc_middle::bug;
    pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
    pub(crate) use rustc_middle::mir::{self, *};
    pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout};
    pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx};
    pub(crate) use rustc_middle::ty::{
        self, FnSig, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable,
    };

    pub(crate) use rustc_data_structures::fx::FxHashMap;

    pub(crate) use rustc_index::vec::Idx;

    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_codegen::entity::EntitySet;
    pub(crate) use cranelift_codegen::ir::{AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value};
    pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
    pub(crate) use cranelift_codegen::ir::function::Function;
    pub(crate) use cranelift_codegen::ir::types;
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{
        self, Backend, DataContext, DataId, FuncId, Linkage, Module,
    };

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{trans_operand, trans_place};
    pub(crate) use crate::cast::*;
    pub(crate) use crate::common::*;
    pub(crate) use crate::debuginfo::{DebugContext, UnwindContext};
    pub(crate) use crate::pointer::Pointer;
    pub(crate) use crate::trap::*;
    pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
}

struct PrintOnPanic<F: Fn() -> String>(F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
    fn drop(&mut self) {
        if ::std::thread::panicking() {
            println!("{}", (self.0)());
        }
    }
}

struct CodegenCx<'tcx, B: Backend + 'static> {
    tcx: TyCtxt<'tcx>,
    module: Module<B>,
    global_asm: String,
    constants_cx: ConstantCx,
    cached_context: Context,
    vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext<'tcx>,
}

impl<'tcx, B: Backend + 'static> CodegenCx<'tcx, B> {
    fn new(
        tcx: TyCtxt<'tcx>,
        module: Module<B>,
        debug_info: bool,
    ) -> Self {
        let unwind_context = UnwindContext::new(tcx, module.isa());
        let debug_context = if debug_info {
            Some(DebugContext::new(
                tcx,
                module.isa(),
            ))
        } else {
            None
        };
        CodegenCx {
            tcx,
            module,
            global_asm: String::new(),
            constants_cx: ConstantCx::default(),
            cached_context: Context::new(),
            vtables: FxHashMap::default(),
            debug_context,
            unwind_context,
        }
    }

    fn finalize(mut self) -> (Module<B>, String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
        self.constants_cx.finalize(self.tcx, &mut self.module);
        (self.module, self.global_asm, self.debug_context, self.unwind_context)
    }
}

struct CraneliftCodegenBackend;

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode {
            sess.warn("LTO is not supported. You may get a linker error.");
        }
    }

    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
        Box::new(crate::metadata::CraneliftMetadataLoader)
    }

    fn provide(&self, providers: &mut Providers) {
        providers.supported_target_features = |tcx, cnum| {
            assert_eq!(cnum, LOCAL_CRATE);
            if tcx.sess.opts.actually_rustdoc {
                // rustdoc needs to be able to document functions that use all the features, so
                // whitelist them all
                target_features_whitelist::all_known_features()
                    .chain(Some(("cg_clif", None)))
                    .map(|(a, b)| (a.to_string(), b))
                    .collect()
            } else {
                target_features_whitelist::target_feature_whitelist(tcx.sess)
                    .iter()
                    .chain(&Some(("cg_clif", None)))
                    .map(|&(a, b)| (a.to_string(), b))
                    .collect()
            }
        };
    }
    fn provide_extern(&self, _providers: &mut Providers) {}

    fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
        vec![rustc_span::Symbol::intern("cg_clif")]
    }

    fn codegen_crate<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        let res = driver::codegen_crate(tcx, metadata, need_metadata_module);

        rustc_symbol_mangling::test::report_symbol_names(tcx);

        res
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        sess: &Session,
        dep_graph: &DepGraph,
    ) -> Result<Box<dyn Any>, ErrorReported> {
        let (codegen_results, work_products) = *ongoing_codegen.downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>().unwrap();

        sess.time("serialize_work_products", move || {
            rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)
        });

        Ok(Box::new(codegen_results))
    }

    fn link(
        &self,
        sess: &Session,
        res: Box<dyn Any>,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        sess.abort_if_errors();

        let codegen_results = *res
            .downcast::<CodegenResults>()
            .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");

        let _timer = sess.prof.generic_activity("link_crate");

        sess.time("linking", || {
            let target_cpu = crate::target_triple(sess).to_string();
            link_binary::<crate::archive::ArArchiveBuilder<'_>>(
                sess,
                &codegen_results,
                outputs,
                &codegen_results.crate_name.as_str(),
                &target_cpu,
            );
        });

        rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash);

        Ok(())
    }
}

fn target_triple(sess: &Session) -> target_lexicon::Triple {
    sess.target.target.llvm_target.parse().unwrap()
}

fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'static> {
    use target_lexicon::BinaryFormat;

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    if enable_pic {
        flags_builder.enable("is_pic").unwrap();
    } else {
        flags_builder.set("is_pic", "false").unwrap();
    }
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    flags_builder
        .set(
            "enable_verifier",
            if cfg!(debug_assertions) {
                "true"
            } else {
                "false"
            },
        )
        .unwrap();

    let tls_model = match target_triple.binary_format {
        BinaryFormat::Elf => "elf_gd",
        BinaryFormat::Macho => "macho",
        BinaryFormat::Coff => "coff",
        _ => "none",
    };
    flags_builder.set("tls_model", tls_model).unwrap();

    flags_builder.set("enable_simd", "true").unwrap();

    // FIXME(CraneStation/cranelift#732) fix LICM in presence of jump tables
    /*
    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
        OptLevel::Size | OptLevel::SizeMin => {
            sess.warn("Optimizing for size is not supported. Just ignoring the request");
        }
    }*/

    let flags = settings::Flags::new(flags_builder);

    let mut isa_builder = cranelift_codegen::isa::lookup(target_triple).unwrap();
    // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt`
    // is interpreted as `bsr`.
    isa_builder.enable("nehalem").unwrap();
    isa_builder.finish(flags)
}

/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(CraneliftCodegenBackend)
}
<commit_msg>Remove cg_clif fake target feature<commit_after>#![feature(rustc_private, decl_macro, type_alias_impl_trait, associated_type_bounds, never_type, try_blocks)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]

extern crate flate2;
#[cfg(feature = "jit")]
extern crate libc;
extern crate rustc_middle;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_fs_util;
extern crate rustc_hir;
extern crate rustc_incremental;
extern crate rustc_index;
extern crate rustc_mir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_symbol_mangling;
extern crate rustc_target;
extern crate rustc_ast;

// This prevents duplicating functions and statics that are already part of the host rustc process.
#[allow(unused_extern_crates)]
extern crate rustc_driver;

use std::any::Any;

use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{DepGraph, WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_session::Session;
use rustc_session::config::OutputFilenames;
use rustc_middle::ty::query::Providers;
use rustc_codegen_ssa::CodegenResults;
use rustc_codegen_ssa::traits::CodegenBackend;

use cranelift_codegen::settings::{self, Configurable};

use crate::constant::ConstantCx;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod atomic_shim;
mod base;
mod backend;
mod cast;
mod codegen_i128;
mod common;
mod constant;
mod debuginfo;
mod discriminant;
mod driver;
mod inline_asm;
mod intrinsics;
mod linkage;
mod main_shim;
mod metadata;
mod num;
mod optimize;
mod pointer;
mod pretty_clif;
mod target_features_whitelist;
mod toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

mod prelude {
    pub(crate) use std::convert::{TryFrom, TryInto};

    pub(crate) use rustc_ast::ast::{FloatTy, IntTy, UintTy};
    pub(crate) use rustc_span::Span;

    pub(crate) use rustc_middle::bug;
    pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
    pub(crate) use rustc_middle::mir::{self, *};
    pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout};
    pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx};
    pub(crate) use rustc_middle::ty::{
        self, FnSig, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable,
    };

    pub(crate) use rustc_data_structures::fx::FxHashMap;

    pub(crate) use rustc_index::vec::Idx;

    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_codegen::entity::EntitySet;
    pub(crate) use cranelift_codegen::ir::{AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value};
    pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
    pub(crate) use cranelift_codegen::ir::function::Function;
    pub(crate) use cranelift_codegen::ir::types;
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{
        self, Backend, DataContext, DataId, FuncId, Linkage, Module,
    };

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{trans_operand, trans_place};
    pub(crate) use crate::cast::*;
    pub(crate) use crate::common::*;
    pub(crate) use crate::debuginfo::{DebugContext, UnwindContext};
    pub(crate) use crate::pointer::Pointer;
    pub(crate) use crate::trap::*;
    pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
}

struct PrintOnPanic<F: Fn() -> String>(F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
    fn drop(&mut self) {
        if ::std::thread::panicking() {
            println!("{}", (self.0)());
        }
    }
}

struct CodegenCx<'tcx, B: Backend + 'static> {
    tcx: TyCtxt<'tcx>,
    module: Module<B>,
    global_asm: String,
    constants_cx: ConstantCx,
    cached_context: Context,
    vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext<'tcx>,
}

impl<'tcx, B: Backend + 'static> CodegenCx<'tcx, B> {
    fn new(
        tcx: TyCtxt<'tcx>,
        module: Module<B>,
        debug_info: bool,
    ) -> Self {
        let unwind_context = UnwindContext::new(tcx, module.isa());
        let debug_context = if debug_info {
            Some(DebugContext::new(
                tcx,
                module.isa(),
            ))
        } else {
            None
        };
        CodegenCx {
            tcx,
            module,
            global_asm: String::new(),
            constants_cx: ConstantCx::default(),
            cached_context: Context::new(),
            vtables: FxHashMap::default(),
            debug_context,
            unwind_context,
        }
    }

    fn finalize(mut self) -> (Module<B>, String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
        self.constants_cx.finalize(self.tcx, &mut self.module);
        (self.module, self.global_asm, self.debug_context, self.unwind_context)
    }
}

struct CraneliftCodegenBackend;

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode {
            sess.warn("LTO is not supported. You may get a linker error.");
        }
    }

    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
        Box::new(crate::metadata::CraneliftMetadataLoader)
    }

    fn provide(&self, providers: &mut Providers) {
        providers.supported_target_features = |tcx, cnum| {
            assert_eq!(cnum, LOCAL_CRATE);
            if tcx.sess.opts.actually_rustdoc {
                // rustdoc needs to be able to document functions that use all the features, so
                // whitelist them all
                target_features_whitelist::all_known_features()
                    .map(|(a, b)| (a.to_string(), b))
                    .collect()
            } else {
                target_features_whitelist::target_feature_whitelist(tcx.sess)
                    .iter()
                    .map(|&(a, b)| (a.to_string(), b))
                    .collect()
            }
        };
    }
    fn provide_extern(&self, _providers: &mut Providers) {}

    fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
        vec![]
    }

    fn codegen_crate<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        let res = driver::codegen_crate(tcx, metadata, need_metadata_module);

        rustc_symbol_mangling::test::report_symbol_names(tcx);

        res
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        sess: &Session,
        dep_graph: &DepGraph,
    ) -> Result<Box<dyn Any>, ErrorReported> {
        let (codegen_results, work_products) = *ongoing_codegen.downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>().unwrap();

        sess.time("serialize_work_products", move || {
            rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)
        });

        Ok(Box::new(codegen_results))
    }

    fn link(
        &self,
        sess: &Session,
        res: Box<dyn Any>,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        sess.abort_if_errors();

        let codegen_results = *res
            .downcast::<CodegenResults>()
            .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");

        let _timer = sess.prof.generic_activity("link_crate");

        sess.time("linking", || {
            let target_cpu = crate::target_triple(sess).to_string();
            link_binary::<crate::archive::ArArchiveBuilder<'_>>(
                sess,
                &codegen_results,
                outputs,
                &codegen_results.crate_name.as_str(),
                &target_cpu,
            );
        });

        rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash);

        Ok(())
    }
}

fn target_triple(sess: &Session) -> target_lexicon::Triple {
    sess.target.target.llvm_target.parse().unwrap()
}

fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'static> {
    use target_lexicon::BinaryFormat;

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    if enable_pic {
        flags_builder.enable("is_pic").unwrap();
    } else {
        flags_builder.set("is_pic", "false").unwrap();
    }
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    flags_builder
        .set(
            "enable_verifier",
            if cfg!(debug_assertions) {
                "true"
            } else {
                "false"
            },
        )
        .unwrap();

    let tls_model = match target_triple.binary_format {
        BinaryFormat::Elf => "elf_gd",
        BinaryFormat::Macho => "macho",
        BinaryFormat::Coff => "coff",
        _ => "none",
    };
    flags_builder.set("tls_model", tls_model).unwrap();

    flags_builder.set("enable_simd", "true").unwrap();

    // FIXME(CraneStation/cranelift#732) fix LICM in presence of jump tables
    /*
    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
        OptLevel::Size | OptLevel::SizeMin => {
            sess.warn("Optimizing for size is not supported. Just ignoring the request");
        }
    }*/

    let flags = settings::Flags::new(flags_builder);

    let mut isa_builder = cranelift_codegen::isa::lookup(target_triple).unwrap();
    // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt`
    // is interpreted as `bsr`.
    isa_builder.enable("nehalem").unwrap();
    isa_builder.finish(flags)
}

/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(CraneliftCodegenBackend)
}
<|endoftext|>


<commit_before>#![crate_name = "irc"]
#![crate_type = "dylib"]
#![feature(convert, hasher_write, slice_patterns)]

#![allow(stable_features)]
// hasher_write was stabilised in rust 1.4

#![deny(unused_must_use, warnings, unused_variables, unused_mut)]

#[macro_use] extern crate log;

pub use self::event::IrcEvent;

pub use self::watchers::{
    RegisterError,
    RegisterErrorType,

    JoinResult,
    JoinSuccess,
    JoinError,

    WhoResult,
    WhoRecord,
    WhoSuccess,
    WhoError,

    BundlerManager,
    JoinBundlerTrigger,
    WhoBundlerTrigger,
};

pub use self::irccase::{
    IrcAsciiExt,
    OwnedIrcAsciiExt,
};

pub use self::state::{
    User,
    UserId,

    Channel,
    ChannelId,

    State,
    FrozenState,
    MessageEndpoint,
};

#[cfg(test)] pub mod testinfra;
mod numerics;
mod watchers;
mod core_plugins;

/// Experimental message types
pub mod message_types;

/// Experimental utility code
pub mod util;

/// Experimental parsing code
pub mod parse;

pub mod identifier;

pub mod stream;

/// Event types
mod event;

/// IRC case manipulation
mod irccase;

/// IRC state tracker
mod state;

/// Receive buffer
pub mod recv;
<commit_msg>Remove deny(warnings): seems harmful for forwards compat<commit_after>#![crate_name = "irc"]
#![crate_type = "dylib"]
#![feature(convert, hasher_write, slice_patterns)]

#![allow(stable_features)]
// hasher_write was stabilised in rust 1.4

#![deny(unused_must_use, unused_variables, unused_mut)]

#[macro_use] extern crate log;

pub use self::event::IrcEvent;

pub use self::watchers::{
    RegisterError,
    RegisterErrorType,

    JoinResult,
    JoinSuccess,
    JoinError,

    WhoResult,
    WhoRecord,
    WhoSuccess,
    WhoError,

    BundlerManager,
    JoinBundlerTrigger,
    WhoBundlerTrigger,
};

pub use self::irccase::{
    IrcAsciiExt,
    OwnedIrcAsciiExt,
};

pub use self::state::{
    User,
    UserId,

    Channel,
    ChannelId,

    State,
    FrozenState,
    MessageEndpoint,
};

#[cfg(test)] pub mod testinfra;
mod numerics;
mod watchers;
mod core_plugins;

/// Experimental message types
pub mod message_types;

/// Experimental utility code
pub mod util;

/// Experimental parsing code
pub mod parse;

pub mod identifier;

pub mod stream;

/// Event types
mod event;

/// IRC case manipulation
mod irccase;

/// IRC state tracker
mod state;

/// Receive buffer
pub mod recv;
<|endoftext|>


<commit_before>//! # liquery-file
//! A library to make queryable files for the liquery `Queryable`
//! trait.

extern crate liquery;
extern crate mime_guess;

use std::path::Path;
use std::fs::Metadata;

use liquery::Queryable;

pub struct QueryFile<'a> {
    metadata: Metadata,
    path: &'a Path,
}

impl <'a> QueryFile<'a> {
    pub fn new(path: &'a Path) -> std::io::Result<Self> {
        Ok(QueryFile {
            metadata: try!(path.metadata()),
            path: path,
        })
    }
}

impl <'a>  Queryable for QueryFile<'a> {
    fn query(&self, key: &str) -> Option<String> {
        match key {
            "size" => Some(format!("{}", self.metadata.len())),
            "filetype" => {
                let filetype = self.metadata.file_type();
                if filetype.is_symlink() {
                    Some("symlink".to_owned())
                } else if filetype.is_dir() {
                    Some("directory".to_owned())
                } else {
                    Some("file".to_owned())
                }
            },
            "extension" => match self.path.extension() {
                Some(ostr) => match ostr.to_str() {
                    Some(pstr) => Some(pstr.to_owned()),
                    None => None,
                },
                None => None,
            },
            "filename" => match self.path.file_name() {
                Some(ostr) => match ostr.to_str() {
                    Some(pstr) => Some(pstr.to_owned()),
                    None => None,
                },
                None => None,
            },
            "mimetype" => Some(format!("{}", mime_guess::guess_mime_type(self.path))),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate liquery;
    use super::*;
    use liquery::Queryable;
    use std::path::Path;

    macro_rules! query_test {
        ($name: ident, $field: expr, $out: expr) => {
            query_test!($name, $field, $out, "tests/file_1b.txt");
        };
        ($name: ident, $field: expr, $out: expr, $path: expr) => {
            #[test]
            fn $name() {
                let path = Path::new($path);
                let queryable = QueryFile::new(path).unwrap();

                assert_eq!($out, &queryable.query($field).unwrap());
            }
        };
    }

    macro_rules! query_test_no_result {
        ($name: ident, $field: expr) => {
            query_test!($name, $field, "tests/file_1b.txt");
        };
        ($name: ident, $field: expr, $path: expr) => {
            #[test]
            fn $name() {
                let path = Path::new($path);
                let queryable = QueryFile::new(path).unwrap();

                assert_eq!(None, queryable.query($field));
            }
        };
    }

    query_test!(size_of_file, "size", "1");

    query_test!(file_type_file, "filetype", "file");
    query_test!(file_type_dir, "filetype", "directory", "tests");

    query_test!(file_name, "filename", "file_1b.txt");
    query_test!(file_name_dir, "filename", "tests", "tests");

    query_test!(file_extension, "extension", "txt");
    query_test_no_result!(file_extension_dir, "extension", "tests");

    query_test!(file_mime, "mimetype", "text/plain");
    query_test!(file_mime_rust, "mimetype", "text/x-rust", "src/lib.rs");
}
<commit_msg>fix recursive macro<commit_after>//! # liquery-file
//! A library to make queryable files for the liquery `Queryable`
//! trait.

extern crate liquery;
extern crate mime_guess;

use std::path::Path;
use std::fs::Metadata;

use liquery::Queryable;

pub struct QueryFile<'a> {
    metadata: Metadata,
    path: &'a Path,
}

impl <'a> QueryFile<'a> {
    pub fn new(path: &'a Path) -> std::io::Result<Self> {
        Ok(QueryFile {
            metadata: try!(path.metadata()),
            path: path,
        })
    }
}

impl <'a>  Queryable for QueryFile<'a> {
    fn query(&self, key: &str) -> Option<String> {
        match key {
            "size" => Some(format!("{}", self.metadata.len())),
            "filetype" => {
                let filetype = self.metadata.file_type();
                if filetype.is_symlink() {
                    Some("symlink".to_owned())
                } else if filetype.is_dir() {
                    Some("directory".to_owned())
                } else {
                    Some("file".to_owned())
                }
            },
            "extension" => match self.path.extension() {
                Some(ostr) => match ostr.to_str() {
                    Some(pstr) => Some(pstr.to_owned()),
                    None => None,
                },
                None => None,
            },
            "filename" => match self.path.file_name() {
                Some(ostr) => match ostr.to_str() {
                    Some(pstr) => Some(pstr.to_owned()),
                    None => None,
                },
                None => None,
            },
            "mimetype" => Some(format!("{}", mime_guess::guess_mime_type(self.path))),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate liquery;
    use super::*;
    use liquery::Queryable;
    use std::path::Path;

    macro_rules! query_test {
        ($name: ident, $field: expr, $out: expr) => {
            query_test!($name, $field, $out, "tests/file_1b.txt");
        };
        ($name: ident, $field: expr, $out: expr, $path: expr) => {
            #[test]
            fn $name() {
                let path = Path::new($path);
                let queryable = QueryFile::new(path).unwrap();

                assert_eq!($out, &queryable.query($field).unwrap());
            }
        };
    }

    macro_rules! query_test_no_result {
        ($name: ident, $field: expr) => {
            query_test_no_result!($name, $field, "tests/file_1b.txt");
        };
        ($name: ident, $field: expr, $path: expr) => {
            #[test]
            fn $name() {
                let path = Path::new($path);
                let queryable = QueryFile::new(path).unwrap();

                assert_eq!(None, queryable.query($field));
            }
        };
    }

    query_test!(size_of_file, "size", "1");

    query_test!(file_type_file, "filetype", "file");
    query_test!(file_type_dir, "filetype", "directory", "tests");

    query_test!(file_name, "filename", "file_1b.txt");
    query_test!(file_name_dir, "filename", "tests", "tests");

    query_test!(file_extension, "extension", "txt");
    query_test_no_result!(file_extension_dir, "extension", "tests");

    query_test!(file_mime, "mimetype", "text/plain");
    query_test!(file_mime_rust, "mimetype", "text/x-rust", "src/lib.rs");

    query_test_no_result!(unkown_feild, "unkown");
    query_test_no_result!(empty_feild, "");
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::io;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};

struct Message {
    frame: Frame,
    frame_address: FrameAddress,
    protocol_header: ProtocolHeader,
    //payload: Payload,
}

struct Frame {
    size: u16,
    origin: u8,
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: bool,
    addressable: bool,  // Must be true
    protocol: u16,  // Must be 1024
    source: u32,
}

struct FrameAddress {
    target: [u8; 8],  // MAC address, or 0 for all devices
    reserved: [u8; 6],
    reserved_2: u8,
    ack_required: bool,
    res_required: bool,
    sequence: u8,
}

struct ProtocolHeader {
    reserved: u64,
    message_type: u16,
    reserved_2: u16,
}

struct Payload {

}

#[derive(Debug)]
struct Packet(Vec<u8>);

impl Packet {
    fn build(&mut self, msg: Message) {
        self.extend_with_u16(msg.frame.size);
        self.extend_with_u8(msg.frame.origin);
        self.extend_with_bool(msg.frame.tagged);
        self.extend_with_bool(msg.frame.addressable);
        self.extend_with_u16(msg.frame.protocol);
        self.extend_with_u32(msg.frame.source);

        self.extend_with_u8_array_8(msg.frame_address.target);
        self.extend_with_u8_array_6(msg.frame_address.reserved);
        self.extend_with_u8(msg.frame_address.reserved_2);
        self.extend_with_bool(msg.frame_address.ack_required);
        self.extend_with_bool(msg.frame_address.res_required);
        self.extend_with_u8(msg.frame_address.sequence);

        self.extend_with_u64(msg.protocol_header.reserved);
        self.extend_with_u16(msg.protocol_header.message_type);
        self.extend_with_u16(msg.protocol_header.reserved_2);
    }

    fn extend_with_bool(&mut self, field: bool) {
        self.0.extend_from_slice(&Packet::bool_to_u8_array(field));
    }

    fn extend_with_u8(&mut self, field: u8) {
        self.0.extend_from_slice(&[field]);
    }

    fn extend_with_u8_array_8(&mut self, field: [u8; 8]) {
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
    }

    fn extend_with_u8_array_6(&mut self, field: [u8; 6]) {
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
    }

    fn extend_with_u16(&mut self, field: u16) {
        self.0.extend_from_slice(&Packet::u16_to_u8_array(field));
    }

    fn extend_with_u32(&mut self, field: u32) {
        self.0.extend_from_slice(&Packet::u32_to_u8_array(field));
    }

    fn extend_with_u64(&mut self, field: u64) {
        self.0.extend_from_slice(&Packet::u64_to_u8_array(field));
    }

    fn bool_to_u8_array(b: bool) -> [u8; 1] {
        match b {
            true => [1],
            false => [0],
        }
    }

    fn u16_to_u8_array(x: u16) -> [u8; 2] {
        let b1: u8 = ((x >> 8) & 0xff) as u8;
        let b2: u8 = (x & 0xff) as u8;
        [b1, b2]
    }

    fn u32_to_u8_array(x: u32) -> [u8; 4] {
        let b1: u8 = ((x >> 24) & 0xff) as u8;
        let b2: u8 = ((x >> 16) & 0xff) as u8;
        let b3: u8 = ((x >> 8) & 0xff) as u8;
        let b4: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4]
    }

    fn u64_to_u8_array(x: u64) -> [u8; 8] {
        let b1: u8 = ((x >> 56) & 0xff) as u8;
        let b2: u8 = ((x >> 48) & 0xff) as u8;
        let b3: u8 = ((x >> 40) & 0xff) as u8;
        let b4: u8 = ((x >> 32) & 0xff) as u8;
        let b5: u8 = ((x >> 24) & 0xff) as u8;
        let b6: u8 = ((x >> 16) & 0xff) as u8;
        let b7: u8 = ((x >> 8) & 0xff) as u8;
        let b8: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4, b5, b6, b7, b8]
    }
}

fn send(msg: Message) -> Result<(), io::Error> {
    let local_ip = Ipv4Addr::new(127, 0, 0, 1);
    let conn = SocketAddrV4::new(local_ip, 56700);
    let socket = try!(UdpSocket::bind(conn));

    let remote_ip = Ipv4Addr::new(192, 168, 0, 12);
    let remote_conn = SocketAddrV4::new(remote_ip, 56700);

    socket.set_broadcast(true);

    let mut packet: Packet = Packet(vec![0u8; 0]);
    packet.build(msg);
    println!("{:?}", packet);
    //try!(socket.send_to(packet, remote_conn));
    //try!(socket.send_to(msg.as_bytes(), remote_conn));

    Ok(())
}

pub fn get_service() {
    let msg = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: true,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            target: [0; 8],  // TODO: set to light's MAC address
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 2,
            reserved_2: 0,
        },
    };

    send(msg);
}

fn get_device_state() {
    let msg = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: false,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            target: [0; 8],  // TODO: set to light's MAC address
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 101,
            reserved_2: 0,
        },
    };
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Implement get_service().<commit_after>#![allow(dead_code)]

use std::io;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};

//use Endianness::{Big, Little};

enum Endianness {
    Big,
    Little,
}

type Bit = bool;

struct Message {
    frame: Frame,
    frame_address: FrameAddress,
    protocol_header: ProtocolHeader,
    //payload: Payload,
}

// BitFrame is an intermediate representation.
struct BitFrame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: [Bit; 2],
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: Bit,
    addressable: Bit,  // Must be true
    protocol: [Bit; 12],  // Must be 1024

    // Final 4 bytes
    source: u32,
}

impl<'a> From<&'a Frame> for BitFrame {
    fn from(f: &Frame) -> BitFrame {
        BitFrame {
            // First two bytes
            size: f.size,

            // Second two bytes
            origin: {
                // Format as zero padded boolean string.
                let s = format!("{:02b}", f.origin);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 2] = [v[0], v[1]];
                a
            },
            tagged: f.tagged,
            addressable: f.addressable,
            protocol: {
               // Format as zero padded boolean string.
                let s = format!("{:012b}", f.protocol);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 12] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],  v[6],
                    v[7], v[8], v[9], v[10], v[11],
                ];
                a
            },

            // Final four bytes
            source: f.source,
        }
    }
}

impl<'a> From<&'a FrameAddress> for BitFrameAddress {
    fn from(f: &FrameAddress) -> BitFrameAddress {
        BitFrameAddress {
            target: f.target,
            reserved: f.reserved,
            reserved_2: {
                let s = format!("{:06b}", f.reserved_2);
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 6] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],
                ];
                a
            },
            ack_required: f.ack_required,
            res_required: f.res_required,
            sequence: f.sequence,
        }
    }
}

struct Frame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: u8,
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: bool,
    addressable: bool,  // Must be true
    protocol: u16,  // Must be 1024

    // Final 4 bytes
    source: u32,
}

struct FrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: u8,
    ack_required: bool,
    res_required: bool,
    sequence: u8,
}

struct BitFrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: [Bit; 6],
    ack_required: Bit,
    res_required: Bit,
    sequence: u8,
}

struct ProtocolHeader {
    reserved: u64,
    message_type: u16,
    reserved_2: u16,
}

struct Payload {}

#[derive(Debug)]
struct Packet(Vec<u8>);

impl Packet {
    fn build(&mut self, msg: Message) {
        // First 2 bytes of Frame
        self.extend_with_u16(msg.frame.size);

        // Second 2 bytes of Frame
        let bitframe = BitFrame::from(&msg.frame);

        let mut fr_pt2: [Bit; 16] = [false; 16];
        fr_pt2[0] = bitframe.origin[0];
        fr_pt2[1] =    bitframe.origin[1];
        fr_pt2[2] =   bitframe.tagged;
        fr_pt2[3] =  bitframe.addressable;
        for i in 0..bitframe.protocol.len() {
            fr_pt2[i+4] = bitframe.protocol[i];
        }

        let (fr_pt2_a_bits, fr_pt2_b_bits) = fr_pt2.split_at(8);
        let fr_pt2_a = Packet::bits_to_byte(fr_pt2_a_bits);
        let fr_pt2_b = Packet::bits_to_byte(fr_pt2_b_bits);

        // Add these two bytes in little endian order.
        self.extend_with_u8(fr_pt2_b);
        self.extend_with_u8(fr_pt2_a);

        // Final 4 bytes of Frame
        self.extend_with_u32(msg.frame.source);

        // First, 8 bytes of FrameAddress
        self.extend_with_u8_array_8(msg.frame_address.target);

        // Second, 6 bytes of FrameAddress
        self.extend_with_u8_array_6(msg.frame_address.reserved);

        // Third, 1 byte of FrameAddress
        let bitframeaddress = BitFrameAddress::from(&msg.frame_address);

        let mut fa_pt2: [Bit; 8] = [false; 8];
        let rlen = bitframeaddress.reserved_2.len();
        for i in 0..rlen {
            fa_pt2[i] = bitframeaddress.reserved_2[i];
        }
        fa_pt2[rlen + 0] = bitframeaddress.ack_required;
        fa_pt2[rlen + 1] = bitframeaddress.res_required;

        let fa_pt2_byte = Packet::bits_to_byte(&fa_pt2);
        self.extend_with_u8(fa_pt2_byte);

        // Final byte of FrameAddress
        self.extend_with_u8(msg.frame_address.sequence);

        // First 8 bytes of ProtocolHeader
        self.extend_with_u64(msg.protocol_header.reserved);
        // Second, 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.protocol_header.message_type);
        // Final 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.protocol_header.reserved_2);

        // Set packet size in first 2 bytes of packet, Frame.
        let mut p = Packet::u16_to_u8_array(self.0.len() as u16);
        p.reverse();
        self.0[0] = p[0];
        self.0[1] = p[1];
    }

    fn bits_to_byte(bits: &[Bit]) -> u8 {
        bits.iter().fold(0, |acc, b| (acc << 1) + if *b { 1 } else { 0 } )
    }

    fn extend_with_bool(&mut self, field: bool) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&Packet::bool_to_u8_array(field));
        self.pp();
    }

    fn extend_with_u8(&mut self, field: u8) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&[field]);
        self.pp();
    }

    fn extend_with_u8_array_8(&mut self, mut field: [u8; 8]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u8_array_6(&mut self, mut field: [u8; 6]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u16(&mut self, field: u16) {
        let mut p = Packet::u16_to_u8_array(field);
        p.reverse();
        self.pp();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn pp(&self) {
        return;
        // TODO: implement debug switch
        /*
        println!("Packet: ");
        for b in self.0.iter() {
            print!("{:x} ", b);
        }
        println!("");
        */
    }

    fn extend_with_u32(&mut self, field: u32) {
        let mut p = Packet::u32_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn extend_with_u64(&mut self, field: u64) {
        let mut p = Packet::u64_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn bool_to_u8_array(b: bool) -> [u8; 1] {
        match b {
            true => [1],
            false => [0],
        }
    }

    fn u16_to_u8_array(x: u16) -> [u8; 2] {
        let b1: u8 = ((x >> 8) & 0xff) as u8;
        let b2: u8 = (x & 0xff) as u8;
        [b1, b2]
    }

    fn u32_to_u8_array(x: u32) -> [u8; 4] {
        let b1: u8 = ((x >> 24) & 0xff) as u8;
        let b2: u8 = ((x >> 16) & 0xff) as u8;
        let b3: u8 = ((x >> 8) & 0xff) as u8;
        let b4: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4]
    }

    fn u64_to_u8_array(x: u64) -> [u8; 8] {
        let b1: u8 = ((x >> 56) & 0xff) as u8;
        let b2: u8 = ((x >> 48) & 0xff) as u8;
        let b3: u8 = ((x >> 40) & 0xff) as u8;
        let b4: u8 = ((x >> 32) & 0xff) as u8;
        let b5: u8 = ((x >> 24) & 0xff) as u8;
        let b6: u8 = ((x >> 16) & 0xff) as u8;
        let b7: u8 = ((x >> 8) & 0xff) as u8;
        let b8: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4, b5, b6, b7, b8]
    }
}

fn send(msg: Message) -> Result<(), io::Error> {
    let local_ip = Ipv4Addr::new(192, 168, 0, 2);
    //let local_ip = Ipv4Addr::new(127,0,0,1);
    let conn = SocketAddrV4::new(local_ip, 56700);
    let socket = try!(UdpSocket::bind(conn));

    let mut buf = [0; 100]; // for recv

    //let remote_ip = Ipv4Addr::new(127,0,0,1);
    let remote_ip = Ipv4Addr::new(192, 168, 0, 5);
    let remote_conn = SocketAddrV4::new(remote_ip, 56700);

    socket.set_broadcast(true)?;

    let mut packet: Packet = Packet(vec![0u8; 0]);
    packet.build(msg);

    let p = &packet.0;
    println!("Dec: {:?}", p);

    println!("---- Sending packet: ----");
        for b in p.iter() {
            print!("{:x} ", b);
        }
    println!("\n----");

    try!(socket.send_to(&p, remote_conn));

    // Read from the socket
    let (amt, src) = try!(socket.recv_from(&mut buf));

    println!("Received from {} : {:?}", src, &buf[0 .. amt]);

    Ok(())
}

fn all_le(v: Vec<u8>) -> Vec<u8> {
    // TODO: implement
    let mut le_vec: Vec<u8> = vec![];
    for b in v {
        le_vec.push(b.to_le());
    }
    le_vec
}

pub fn get_service() {
    let msg = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: true,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            //target: [0x31, 0x19, 0x95, 0x4c, 0xb9, 0xbc, 0x00, 0x00],
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 2,
            reserved_2: 0,
        },
    };

    match send(msg) {
        Ok(()) => println!("good send"),
        Err(e) => println!("bad send: {}", e),
    };
}

fn get_device_state() {
    let _ = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: false,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 101,
            reserved_2: 0,
        },
    };
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>