<commit_before>extern crate sysfs_gpio;

use sysfs_gpio::{Direction, Pin};

pub struct ShiftRegister {
    pub oe_pin: u64,
    pub ds_pin: u64,
    pub clock_pin: u64,
    pub latch_pin: u64,
    pub data: u64,
}

impl ShiftRegister {
    /// Creates a new instance
    ///
    /// All member variables can set to custom values
    pub fn new(oe_pin: u64, ds_pin: u64, clock_pin: u64, latch_pin: u64) -> ShiftRegister {
        ShiftRegister { oe_pin: oe_pin, ds_pin: ds_pin, clock_pin: clock_pin, latch_pin: latch_pin, data: 0 }
    }

    /// Default constructor for leds
    pub fn new_led() -> ShiftRegister {
        ShiftRegister { oe_pin: 276, ds_pin: 38, clock_pin: 44, latch_pin: 40, data: 0 }
    }

    /// Default constructor for relais
    pub fn new_relais() -> ShiftRegister {
        ShiftRegister { oe_pin: 277, ds_pin: 45, clock_pin: 39, latch_pin: 37, data: 0 }
    }

    /// Export the needed pins, panic if this fails
    fn export_pins(&self, oe_pin: &Pin, ds_pin: &Pin, clock_pin: &Pin, latch_pin: &Pin) {
        match oe_pin.export() {
            Ok(()) => (),
            Err(err) => println!("!OE (output enabled) pin could not be exported: {}", err),
        }
        match ds_pin.export() {
            Ok(()) => (),
            Err(err) => println!("DATA pin could not be exported: {}", err),
        }
        match clock_pin.export() {
            Ok(()) => (),
            Err(err) => println!("CLOCK pin could not be exported: {}", err),
        }
        match latch_pin.export() {
            Ok(()) => (),
            Err(err) => println!("LATCH pin could not be exported: {}", err),
        }
    }

    /// Sets the directions of the given pins.
    fn set_pin_direction(&self, oe_pin: &Pin, ds_pin: &Pin, clock_pin: &Pin, latch_pin: &Pin) {
        match oe_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = oe_pin.set_value(0); }, // !OE pin low == Shift register enabled.
            Err(err) => println!("Could not set direction of DATA pin: {}", err),
        }

        match ds_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = ds_pin.set_value(0); },
            Err(err) => println!("Could not set direction of DATA pin: {}", err),
        }

        match clock_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = clock_pin.set_value(0); },
            Err(err) => println!("Could not set direction of CLOCK pin: {}", err),
        }

        match latch_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = latch_pin.set_value(0); },
            Err(err) => println!("Could not set direction of LATCH pin: {}", err),
        }

    }

    /// # Examples
    ///
    /// Set one given bit:
    ///
    /// ```
    /// extern crate xmz_client_server;
    ///
    /// let mut led = xmz_client_server::shift_register::ShiftRegister::new_led();
    /// assert_eq!(led.data, 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000);
    ///
    /// led.set(1);
    /// assert_eq!(led.data, 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001);
    /// ```
    pub fn set(&mut self, num: u64) {
        self.data |= 1 << num - 1;
    }

    /// Toogles clock pin high->low
    fn clock_in(&self, clock_pin: &Pin) {
        clock_pin.set_value(1).unwrap();
        clock_pin.set_value(0).unwrap();
    }

    /// Latch's the data out, latch pin high->low
    fn latch_out(&self, latch_pin: &Pin) {
        latch_pin.set_value(1).unwrap();
        latch_pin.set_value(0).unwrap();
    }

    /// Shift out the current data
    pub fn shift_out(&self) {
        let oe_pin = Pin::new(self.oe_pin);
        let ds_pin = Pin::new(self.ds_pin);
        let clock_pin = Pin::new(self.clock_pin);
        let latch_pin = Pin::new(self.latch_pin);
        let data = self.data;

        self.export_pins(&oe_pin, &ds_pin, &clock_pin, &latch_pin);

        self.set_pin_direction(&oe_pin, &ds_pin, &clock_pin, &latch_pin);

        // Clock in data
        for i in (0..24).rev() {
            match (data >> i) & 1 {
                1 => { ds_pin.set_value(1).unwrap(); },
                _ => { ds_pin.set_value(0).unwrap(); },
            }
            self.clock_in(&clock_pin);
        }
        self.latch_out(&latch_pin);
    }

    /// Initalises all shift register with zero's and shift this output.
    ///
    /// On startup the shift registers are in a unknown state,
    /// after this function, they are known zero.
    pub fn init(&mut self) {
        self.data = 0;
        self.shift_out();
    }
}

<commit_msg>Fix typo in documentation test<commit_after>extern crate sysfs_gpio;

use sysfs_gpio::{Direction, Pin};

pub struct ShiftRegister {
    pub oe_pin: u64,
    pub ds_pin: u64,
    pub clock_pin: u64,
    pub latch_pin: u64,
    pub data: u64,
}

impl ShiftRegister {
    /// Creates a new instance
    ///
    /// All member variables can set to custom values
    pub fn new(oe_pin: u64, ds_pin: u64, clock_pin: u64, latch_pin: u64) -> ShiftRegister {
        ShiftRegister { oe_pin: oe_pin, ds_pin: ds_pin, clock_pin: clock_pin, latch_pin: latch_pin, data: 0 }
    }

    /// Default constructor for leds
    pub fn new_led() -> ShiftRegister {
        ShiftRegister { oe_pin: 276, ds_pin: 38, clock_pin: 44, latch_pin: 40, data: 0 }
    }

    /// Default constructor for relais
    pub fn new_relais() -> ShiftRegister {
        ShiftRegister { oe_pin: 277, ds_pin: 45, clock_pin: 39, latch_pin: 37, data: 0 }
    }

    /// Export the needed pins, panic if this fails
    fn export_pins(&self, oe_pin: &Pin, ds_pin: &Pin, clock_pin: &Pin, latch_pin: &Pin) {
        match oe_pin.export() {
            Ok(()) => (),
            Err(err) => println!("!OE (output enabled) pin could not be exported: {}", err),
        }
        match ds_pin.export() {
            Ok(()) => (),
            Err(err) => println!("DATA pin could not be exported: {}", err),
        }
        match clock_pin.export() {
            Ok(()) => (),
            Err(err) => println!("CLOCK pin could not be exported: {}", err),
        }
        match latch_pin.export() {
            Ok(()) => (),
            Err(err) => println!("LATCH pin could not be exported: {}", err),
        }
    }

    /// Sets the directions of the given pins.
    fn set_pin_direction(&self, oe_pin: &Pin, ds_pin: &Pin, clock_pin: &Pin, latch_pin: &Pin) {
        match oe_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = oe_pin.set_value(0); }, // !OE pin low == Shift register enabled.
            Err(err) => println!("Could not set direction of DATA pin: {}", err),
        }

        match ds_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = ds_pin.set_value(0); },
            Err(err) => println!("Could not set direction of DATA pin: {}", err),
        }

        match clock_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = clock_pin.set_value(0); },
            Err(err) => println!("Could not set direction of CLOCK pin: {}", err),
        }

        match latch_pin.set_direction(Direction::Out) {
            Ok(()) => { let _ = latch_pin.set_value(0); },
            Err(err) => println!("Could not set direction of LATCH pin: {}", err),
        }

    }

    /// # Examples
    ///
    /// Set one given bit:
    ///
    /// ```
    /// extern crate xmz_shift_register;
    ///
    /// let mut led = xmz_shift_register::ShiftRegister::new_led();
    /// assert_eq!(led.data, 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000);
    ///
    /// led.set(1);
    /// assert_eq!(led.data, 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001);
    /// ```
    pub fn set(&mut self, num: u64) {
        self.data |= 1 << num - 1;
    }

    /// Toogles clock pin high->low
    fn clock_in(&self, clock_pin: &Pin) {
        clock_pin.set_value(1).unwrap();
        clock_pin.set_value(0).unwrap();
    }

    /// Latch's the data out, latch pin high->low
    fn latch_out(&self, latch_pin: &Pin) {
        latch_pin.set_value(1).unwrap();
        latch_pin.set_value(0).unwrap();
    }

    /// Shift out the current data
    pub fn shift_out(&self) {
        let oe_pin = Pin::new(self.oe_pin);
        let ds_pin = Pin::new(self.ds_pin);
        let clock_pin = Pin::new(self.clock_pin);
        let latch_pin = Pin::new(self.latch_pin);
        let data = self.data;

        self.export_pins(&oe_pin, &ds_pin, &clock_pin, &latch_pin);

        self.set_pin_direction(&oe_pin, &ds_pin, &clock_pin, &latch_pin);

        // Clock in data
        for i in (0..24).rev() {
            match (data >> i) & 1 {
                1 => { ds_pin.set_value(1).unwrap(); },
                _ => { ds_pin.set_value(0).unwrap(); },
            }
            self.clock_in(&clock_pin);
        }
        self.latch_out(&latch_pin);
    }

    /// Initalises all shift register with zero's and shift this output.
    ///
    /// On startup the shift registers are in a unknown state,
    /// after this function, they are known zero.
    pub fn init(&mut self) {
        self.data = 0;
        self.shift_out();
    }
}

<|endoftext|>


<commit_before>#![feature(plugin_registrar,quote,rustc_private,slice_patterns)]

extern crate syntax;
extern crate rustc;
extern crate cssparser as css;

use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt,MacEager,MacResult,DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::token as rust_token;
use syntax::print::pprust;
use syntax::fold::Folder;
use rustc::plugin::Registry;

mod token;
mod parse;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry){
	reg.register_macro("css",expand_css);
}

fn expand_css<'context>(context: &'context mut ExtCtxt,span: Span,tts: &[ast::TokenTree]) -> Box<MacResult + 'context>{
	let input = match parse_single_string_literal(context,tts){
		Some(s) => s,
		None => return DummyResult::any(span)
	};

	let mut parser = css::Parser::new(&*input);
	let mut output = String::new();

	for rule in css::RuleListParser::new_for_stylesheet(&mut parser,parse::RuleParser){
		match rule{
			Ok(rule_str) => output.push_str(&*rule_str),
			Err(_) => {}
		}
	}

	/*while let Ok(i) = parser.next(){
		match i{
			//Blocks/brackets
			ref block @ css::Token::ParenthesisBlock |
			ref block @ css::Token::CurlyBracketBlock |
			ref block @ css::Token::SquareBracketBlock => match parser.parse_nested_block(|parser|{
				//Open bracket
				output.push_str(&*i.to_css_string());

				//Bracket contents
				while let Ok(token) = parser.next(){
					output.push_str(&*token::value_token_simplify(token).to_css_string());
				}

				//Close bracket
				output.push_str(&*match block{
					&css::Token::ParenthesisBlock   => css::Token::CloseParenthesis,
					&css::Token::CurlyBracketBlock  => css::Token::CloseCurlyBracket,
					&css::Token::SquareBracketBlock => css::Token::CloseSquareBracket,
					_ => unreachable!()
				}.to_css_string());

				Ok(())
			}){
				Ok(_)  => {},
				Err(_) => {
       				 context.span_err(span,"unexpected token somewhere");
					return DummyResult::any(span);
				}
			},

			//All other tokens
			token => {
				output.push_str(&*token.to_css_string());
			}
		};
	}*/

	MacEager::expr(context.expr_str(span,rust_token::intern_and_get_ident(&*output)))
}

////////////////////////////////////////////////////////////////////
// This code snippet is copied from the `rust-lang/regex` package and slightly modified.
// (Date: 2015-04-10. Version: 0.1.27. Commit: 910aef40aca4f525dd2fecc54a78e9bc183039d1)
// (`https://github.com/rust-lang/regex/blob/910aef40aca4f525dd2fecc54a78e9bc183039d1/regex_macros/src/lib.rs`)
// Credits goes to the developers of the regex package.
////////////////////////////////////////////////////////////////////
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
////////////////////////////////////////////////////////////////////
/// Looks for a single string literal and returns it.
/// Otherwise, logs an error with cx.span_err and returns None.
fn parse_single_string_literal(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
    let mut parser = cx.new_parser_from_tts(tts);
    let entry = cx.expander().fold_expr(parser.parse_expr());
    let regex = match entry.node {
        ast::ExprLit(ref lit) => {
            match lit.node {
                ast::LitStr(ref s, _) => s.to_string(),
                _ => {
                    cx.span_err(entry.span, &format!(
                        "expected string literal but got `{}`",
                        pprust::lit_to_string(&**lit)));
                    return None
                }
            }
        }
        _ => {
            cx.span_err(entry.span, &format!(
                "expected string literal but got `{}`",
                pprust::expr_to_string(&*entry)));
            return None
        }
    };
    if !parser.eat(&rust_token::Eof)/*.ok().unwrap()*/ {
        cx.span_err(parser.span, "only one string literal allowed");
        return None;
    }
    Some(regex)
}
<commit_msg>Removing old code<commit_after>#![feature(plugin_registrar,quote,rustc_private,slice_patterns)]

extern crate syntax;
extern crate rustc;
extern crate cssparser as css;

use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt,MacEager,MacResult,DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::token as rust_token;
use syntax::print::pprust;
use syntax::fold::Folder;
use rustc::plugin::Registry;

mod token;
mod parse;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry){
	reg.register_macro("css",expand_css);
}

fn expand_css<'context>(context: &'context mut ExtCtxt,span: Span,tts: &[ast::TokenTree]) -> Box<MacResult + 'context>{
	let input = match parse_single_string_literal(context,tts){
		Some(s) => s,
		None => return DummyResult::any(span)
	};

	let mut parser = css::Parser::new(&*input);
	let mut output = String::new();

	for rule in css::RuleListParser::new_for_stylesheet(&mut parser,parse::RuleParser){
		match rule{
			Ok(rule_str) => output.push_str(&*rule_str),
			Err(_) => {}
		}
	}

	MacEager::expr(context.expr_str(span,rust_token::intern_and_get_ident(&*output)))
}

////////////////////////////////////////////////////////////////////
// This code snippet is copied from the `rust-lang/regex` package and slightly modified.
// (Date: 2015-04-10. Version: 0.1.27. Commit: 910aef40aca4f525dd2fecc54a78e9bc183039d1)
// (`https://github.com/rust-lang/regex/blob/910aef40aca4f525dd2fecc54a78e9bc183039d1/regex_macros/src/lib.rs`)
// Credits goes to the developers of the regex package.
////////////////////////////////////////////////////////////////////
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
////////////////////////////////////////////////////////////////////
/// Looks for a single string literal and returns it.
/// Otherwise, logs an error with cx.span_err and returns None.
fn parse_single_string_literal(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
    let mut parser = cx.new_parser_from_tts(tts);
    let entry = cx.expander().fold_expr(parser.parse_expr());
    let regex = match entry.node {
        ast::ExprLit(ref lit) => {
            match lit.node {
                ast::LitStr(ref s, _) => s.to_string(),
                _ => {
                    cx.span_err(entry.span, &format!(
                        "expected string literal but got `{}`",
                        pprust::lit_to_string(&**lit)));
                    return None
                }
            }
        }
        _ => {
            cx.span_err(entry.span, &format!(
                "expected string literal but got `{}`",
                pprust::expr_to_string(&*entry)));
            return None
        }
    };
    if !parser.eat(&rust_token::Eof)/*.ok().unwrap()*/ {
        cx.span_err(parser.span, "only one string literal allowed");
        return None;
    }
    Some(regex)
}
<|endoftext|>


<commit_before>#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts, once_cell)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]

extern crate snap;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
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_interface;
extern crate rustc_metadata;
extern crate rustc_mir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

// 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_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::EncodedMetadata;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;

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

pub use crate::config::*;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod backend;
mod base;
mod cast;
mod codegen_i128;
mod common;
mod compiler_builtins;
mod config;
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 toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

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

    pub(crate) use rustc_span::Span;

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

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

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

    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::ir::{
        AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc,
        StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value,
    };
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{self, DataContext, FuncId, Linkage, Module};

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{codegen_operand, codegen_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)());
        }
    }
}

/// The codegen context holds any information shared between the codegen of individual functions
/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module).
struct CodegenCx<'tcx> {
    tcx: TyCtxt<'tcx>,
    global_asm: String,
    cached_context: Context,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext,
}

impl<'tcx> CodegenCx<'tcx> {
    fn new(
        tcx: TyCtxt<'tcx>,
        backend_config: BackendConfig,
        isa: &dyn TargetIsa,
        debug_info: bool,
    ) -> Self {
        assert_eq!(pointer_ty(tcx), isa.pointer_type());

        let unwind_context =
            UnwindContext::new(tcx, isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
        let debug_context = if debug_info { Some(DebugContext::new(tcx, isa)) } else { None };
        CodegenCx {
            tcx,
            global_asm: String::new(),
            cached_context: Context::new(),
            debug_context,
            unwind_context,
        }
    }
}

pub struct CraneliftCodegenBackend {
    pub config: Option<BackendConfig>,
}

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        use rustc_session::config::Lto;
        match sess.lto() {
            Lto::No | Lto::ThinLocal => {}
            Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."),
        }
    }

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

    fn print_version(&self) {
        println!("Cranelift version: {}", cranelift_codegen::VERSION);
    }

    fn codegen_crate(
        &self,
        tcx: TyCtxt<'_>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        tcx.sess.abort_if_errors();
        let config = if let Some(config) = self.config.clone() {
            config
        } else {
            BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
                .unwrap_or_else(|err| tcx.sess.fatal(&err))
        };
        match config.codegen_mode {
            CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
            CodegenMode::Jit | CodegenMode::JitLazy => {
                #[cfg(feature = "jit")]
                let _: ! = driver::jit::run_jit(tcx, config);

                #[cfg(not(feature = "jit"))]
                tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
            }
        }
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
    ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
        Ok(*ongoing_codegen
            .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
            .unwrap())
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: CodegenResults,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        link_binary::<crate::archive::ArArchiveBuilder<'_>>(
            sess,
            &codegen_results,
            outputs,
        );

        Ok(())
    }
}

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

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

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    flags_builder.enable("is_pic").unwrap();
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
    flags_builder.set("enable_verifier", enable_verifier).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();

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

    flags_builder.set("regalloc", &backend_config.regalloc).unwrap();

    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
    }

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

    let variant = cranelift_codegen::isa::BackendVariant::MachInst;

    let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
        Some("native") => {
            let builder = cranelift_native::builder_with_options(variant, true).unwrap();
            builder
        }
        Some(value) => {
            let mut builder =
                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
            if let Err(_) = builder.enable(value) {
                sess.fatal("The specified target cpu isn't currently supported by Cranelift.");
            }
            builder
        }
        None => {
            let mut builder =
                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant).unwrap();
            if target_triple.architecture == target_lexicon::Architecture::X86_64 {
                // Don't use "haswell" as the default, as it implies `has_lzcnt`.
                // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
                builder.enable("nehalem").unwrap();
            }
            builder
        }
    };

    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 { config: None })
}
<commit_msg>Consider all fields when comparing DllImports, to remove nondetermininsm in multiple-definitions test<commit_after>#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts, once_cell)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]

extern crate snap;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
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_interface;
extern crate rustc_metadata;
extern crate rustc_mir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

// 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_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::EncodedMetadata;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;

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

pub use crate::config::*;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod backend;
mod base;
mod cast;
mod codegen_i128;
mod common;
mod compiler_builtins;
mod config;
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 toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

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

    pub(crate) use rustc_span::Span;

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

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

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

    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::ir::{
        AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc,
        StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value,
    };
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{self, DataContext, FuncId, Linkage, Module};

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{codegen_operand, codegen_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)());
        }
    }
}

/// The codegen context holds any information shared between the codegen of individual functions
/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module).
struct CodegenCx<'tcx> {
    tcx: TyCtxt<'tcx>,
    global_asm: String,
    cached_context: Context,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext,
}

impl<'tcx> CodegenCx<'tcx> {
    fn new(
        tcx: TyCtxt<'tcx>,
        backend_config: BackendConfig,
        isa: &dyn TargetIsa,
        debug_info: bool,
    ) -> Self {
        assert_eq!(pointer_ty(tcx), isa.pointer_type());

        let unwind_context =
            UnwindContext::new(tcx, isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
        let debug_context = if debug_info { Some(DebugContext::new(tcx, isa)) } else { None };
        CodegenCx {
            tcx,
            global_asm: String::new(),
            cached_context: Context::new(),
            debug_context,
            unwind_context,
        }
    }
}

pub struct CraneliftCodegenBackend {
    pub config: Option<BackendConfig>,
}

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        use rustc_session::config::Lto;
        match sess.lto() {
            Lto::No | Lto::ThinLocal => {}
            Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."),
        }
    }

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

    fn print_version(&self) {
        println!("Cranelift version: {}", cranelift_codegen::VERSION);
    }

    fn codegen_crate(
        &self,
        tcx: TyCtxt<'_>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        tcx.sess.abort_if_errors();
        let config = if let Some(config) = self.config.clone() {
            config
        } else {
            BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
                .unwrap_or_else(|err| tcx.sess.fatal(&err))
        };
        match config.codegen_mode {
            CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
            CodegenMode::Jit | CodegenMode::JitLazy => {
                #[cfg(feature = "jit")]
                let _: ! = driver::jit::run_jit(tcx, config);

                #[cfg(not(feature = "jit"))]
                tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
            }
        }
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
    ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
        Ok(*ongoing_codegen
            .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
            .unwrap())
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: CodegenResults,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        link_binary::<crate::archive::ArArchiveBuilder<'_>>(
            sess,
            &codegen_results,
            outputs,
        )
    }
}

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

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

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    flags_builder.enable("is_pic").unwrap();
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
    flags_builder.set("enable_verifier", enable_verifier).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();

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

    flags_builder.set("regalloc", &backend_config.regalloc).unwrap();

    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
    }

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

    let variant = cranelift_codegen::isa::BackendVariant::MachInst;

    let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
        Some("native") => {
            let builder = cranelift_native::builder_with_options(variant, true).unwrap();
            builder
        }
        Some(value) => {
            let mut builder =
                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
            if let Err(_) = builder.enable(value) {
                sess.fatal("The specified target cpu isn't currently supported by Cranelift.");
            }
            builder
        }
        None => {
            let mut builder =
                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant).unwrap();
            if target_triple.architecture == target_lexicon::Architecture::X86_64 {
                // Don't use "haswell" as the default, as it implies `has_lzcnt`.
                // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
                builder.enable("nehalem").unwrap();
            }
            builder
        }
    };

    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 { config: None })
}
<|endoftext|>


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

pub mod houselights {
    extern crate sacn;
    use self::sacn::DmxSource;

    const UNIVERSE_SIZE: usize = 510;

    const GAMMA: f32 = 2.2;
    const GC_BOTTOM_THRESHOLD: u16 = 20;

    #[derive(Clone,Debug)]
    pub struct RGB {
        pub red:   u8,
        pub green: u8,
        pub blue:  u8
    }
    impl RGB {
        pub fn null() -> RGB {
            RGB { red: 0, green: 0, blue: 0 }
        }
    }

    pub struct HSV {
        hue:        f32,  // 0-360, degrees
        saturation: f32,  // 0-1
        brightness: f32   // 0-1
    }
    impl HSV {
        pub fn null() -> HSV {
            HSV {
                hue:        0_f32,
                saturation: 0_f32,
                brightness: 0_f32
            }
        }
    }

    #[derive(Clone,Debug)]
    pub struct Zone  {
        pub head: u8,
        pub body: u8,
        pub tail: u8,
        pub name: String
    }

    pub struct Dmx {
        source: DmxSource
    }
    impl Dmx {
        pub fn new() -> Dmx {
            Dmx { source: DmxSource::new("Controller").unwrap() }
        }
    }
    impl Drop for Dmx {
        fn drop(&mut self) {
            let _res = self.source.terminate_stream(1);
        }
    }

    // return RGB for a given color temperature
    pub fn kelvin (mut temp: u16) -> RGB {
        // http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
        temp /= 100;

        let mut rgb: RGB = RGB::null();
        // calculate red
        if temp <= 66 {
            rgb.red = 255;
        } else {
            let red: f32 = (temp - 60) as f32;
            rgb.red = _normalize_value((329.698727446 * red.powf(-0.1332047592)).round());
        }
        // calculate green
        if temp <= 66 {
            let green: f32 = temp as f32;
            rgb.green = _normalize_value((99.4708025861 * green.ln() - 161.1195681661).round());
        } else {
            let green: f32 = (temp - 60) as f32;
            rgb.green = _normalize_value((288.1221695283 * green.powf(-0.0755148492)).round())
        }
        // calculate blue
        if temp >= 66 {
            rgb.blue = 255;
        } else {
            if temp <= 19 {
                rgb.blue = 0;
            } else {
                let blue: f32 = (temp - 10) as f32;
                rgb.blue = _normalize_value((138.5177312231 * blue.ln() - 305.0447927307).round());
            }
        }
        return rgb;
    }

    fn _normalize_value (value: f32) -> u8 {
        if value < 0_f32 {
            return 0_u8;
        }
        if value > 255_f32 {
            return 255_u8;
        }
        return value as u8;
    }

    pub fn hsv2rgb(hsv: HSV) -> RGB {
        let c = hsv.brightness * hsv.saturation;
        let x = c * (1_f32 - (((hsv.hue * 6_f32) % 2_f32).abs() - 1_f32));
        let m = hsv.brightness - c;
        let mut red   = 0_f32;
        let mut green = 0_f32;
        let mut blue  = 0_f32;
        if hsv.hue < 1_f32/6_f32 {
            red   = c;
            green = x;
        } else if hsv.hue < 1_f32/3_f32 {
            red   = x;
            green = c;
        } else if hsv.hue < 1_f32/2_f32 {
            green = c;
            blue  = x;
        } else if hsv.hue < 2_f32/3_f32 {
            green = x;
            blue  = c;
        } else if hsv.hue < 5_f32/6_f32 {
            red   = x;
            blue  = c;
        } else {
            red   = c;
            blue  = x;
        }
        let rgb = RGB {
            red:   ((red   + m) * 255_f32).round() as u8,
            green: ((green + m) * 255_f32).round() as u8,
            blue:  ((blue  + m) * 255_f32).round() as u8
        };
        return rgb;
    }

    pub fn scale_rgb(rgb: RGB, intensity: f32, max_intensity: f32) -> RGB {
        let i: f32 = intensity * max_intensity as f32;
        let scaled: RGB = RGB {
            red:   (rgb.red   as f32 * i).round() as u8,
            green: (rgb.green as f32 * i).round() as u8,
            blue:  (rgb.blue  as f32 * i).round() as u8
        };
        return scaled;
    }

    pub fn gamma_correct(rgb: &RGB) -> RGB {
        let mut c: RGB = RGB {
            red:   (255_f32 * (rgb.red   as f32 / 255_f32).powf(GAMMA)) as u8,
            green: (255_f32 * (rgb.green as f32 / 255_f32).powf(GAMMA)) as u8,
            blue:  (255_f32 * (rgb.blue  as f32 / 255_f32).powf(GAMMA)) as u8
        };
        // drop to dark if sum of all thre falls below threshold
        // trying to avoid bottoming out to dim red or green when I want white
        if (c.red as u16 + c.green as u16 + c.blue as u16) < GC_BOTTOM_THRESHOLD {
            c.red   = 0;
            c.green = 0;
            c.blue  = 0;
        }
        return c;
    }

    pub fn render( lights: &[RGB], zones: &[Zone], dmx: &Dmx ) {
        let spliced = splice_null_pixels(lights, zones);
        let mut out: Vec<u8> = vec![];
        for rgb in spliced.iter() {
            let gc = gamma_correct(rgb);
            out.push(gc.red);
            out.push(gc.green);
            out.push(gc.blue);
        }
        let mut universes = Vec::new();
        while out.len() > UNIVERSE_SIZE {
            let u = out.split_off(UNIVERSE_SIZE);
            universes.push(out);
            out = u;
        }
        universes.push(out);
        let mut universe: u16 = 1;
        for u in universes {
            let _res = dmx.source.send(universe, &u);
            universe += 1;
        }
    }

    fn splice_null_pixels( lights: &[RGB], zones: &[Zone] ) -> Vec<RGB> {
        let mut copy: Vec<RGB> = vec![];
        copy.extend_from_slice(lights);
        let mut idx: usize = 0;
        for zone in zones {
            // null pixels at the head of the zone
            for _i in 0..zone.head {
                copy.insert(idx, RGB::null());
            }
            // and at the tail
            idx += zone.head as usize + zone.body as usize;
            for _i in 0..zone.tail {
                copy.insert(idx, RGB::null());
            }
            idx += zone.tail as usize;
        }
        return copy;
    }
}
<commit_msg>HSV fields are public<commit_after>#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}

pub mod houselights {
    extern crate sacn;
    use self::sacn::DmxSource;

    const UNIVERSE_SIZE: usize = 510;

    const GAMMA: f32 = 2.2;
    const GC_BOTTOM_THRESHOLD: u16 = 20;

    #[derive(Clone,Debug)]
    pub struct RGB {
        pub red:   u8,
        pub green: u8,
        pub blue:  u8
    }
    impl RGB {
        pub fn null() -> RGB {
            RGB { red: 0, green: 0, blue: 0 }
        }
    }

    pub struct HSV {
        pub hue:        f32,  // 0-360, degrees
        pub saturation: f32,  // 0-1
        pub brightness: f32   // 0-1
    }
    impl HSV {
        pub fn null() -> HSV {
            HSV {
                hue:        0_f32,
                saturation: 0_f32,
                brightness: 0_f32
            }
        }
    }

    #[derive(Clone,Debug)]
    pub struct Zone  {
        pub head: u8,
        pub body: u8,
        pub tail: u8,
        pub name: String
    }

    pub struct Dmx {
        source: DmxSource
    }
    impl Dmx {
        pub fn new() -> Dmx {
            Dmx { source: DmxSource::new("Controller").unwrap() }
        }
    }
    impl Drop for Dmx {
        fn drop(&mut self) {
            let _res = self.source.terminate_stream(1);
        }
    }

    // return RGB for a given color temperature
    pub fn kelvin (mut temp: u16) -> RGB {
        // http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
        temp /= 100;

        let mut rgb: RGB = RGB::null();
        // calculate red
        if temp <= 66 {
            rgb.red = 255;
        } else {
            let red: f32 = (temp - 60) as f32;
            rgb.red = _normalize_value((329.698727446 * red.powf(-0.1332047592)).round());
        }
        // calculate green
        if temp <= 66 {
            let green: f32 = temp as f32;
            rgb.green = _normalize_value((99.4708025861 * green.ln() - 161.1195681661).round());
        } else {
            let green: f32 = (temp - 60) as f32;
            rgb.green = _normalize_value((288.1221695283 * green.powf(-0.0755148492)).round())
        }
        // calculate blue
        if temp >= 66 {
            rgb.blue = 255;
        } else {
            if temp <= 19 {
                rgb.blue = 0;
            } else {
                let blue: f32 = (temp - 10) as f32;
                rgb.blue = _normalize_value((138.5177312231 * blue.ln() - 305.0447927307).round());
            }
        }
        return rgb;
    }

    fn _normalize_value (value: f32) -> u8 {
        if value < 0_f32 {
            return 0_u8;
        }
        if value > 255_f32 {
            return 255_u8;
        }
        return value as u8;
    }

    pub fn hsv2rgb(hsv: HSV) -> RGB {
        let c = hsv.brightness * hsv.saturation;
        let x = c * (1_f32 - (((hsv.hue * 6_f32) % 2_f32).abs() - 1_f32));
        let m = hsv.brightness - c;
        let mut red   = 0_f32;
        let mut green = 0_f32;
        let mut blue  = 0_f32;
        if hsv.hue < 1_f32/6_f32 {
            red   = c;
            green = x;
        } else if hsv.hue < 1_f32/3_f32 {
            red   = x;
            green = c;
        } else if hsv.hue < 1_f32/2_f32 {
            green = c;
            blue  = x;
        } else if hsv.hue < 2_f32/3_f32 {
            green = x;
            blue  = c;
        } else if hsv.hue < 5_f32/6_f32 {
            red   = x;
            blue  = c;
        } else {
            red   = c;
            blue  = x;
        }
        let rgb = RGB {
            red:   ((red   + m) * 255_f32).round() as u8,
            green: ((green + m) * 255_f32).round() as u8,
            blue:  ((blue  + m) * 255_f32).round() as u8
        };
        return rgb;
    }

    pub fn scale_rgb(rgb: RGB, intensity: f32, max_intensity: f32) -> RGB {
        let i: f32 = intensity * max_intensity as f32;
        let scaled: RGB = RGB {
            red:   (rgb.red   as f32 * i).round() as u8,
            green: (rgb.green as f32 * i).round() as u8,
            blue:  (rgb.blue  as f32 * i).round() as u8
        };
        return scaled;
    }

    pub fn gamma_correct(rgb: &RGB) -> RGB {
        let mut c: RGB = RGB {
            red:   (255_f32 * (rgb.red   as f32 / 255_f32).powf(GAMMA)) as u8,
            green: (255_f32 * (rgb.green as f32 / 255_f32).powf(GAMMA)) as u8,
            blue:  (255_f32 * (rgb.blue  as f32 / 255_f32).powf(GAMMA)) as u8
        };
        // drop to dark if sum of all thre falls below threshold
        // trying to avoid bottoming out to dim red or green when I want white
        if (c.red as u16 + c.green as u16 + c.blue as u16) < GC_BOTTOM_THRESHOLD {
            c.red   = 0;
            c.green = 0;
            c.blue  = 0;
        }
        return c;
    }

    pub fn render( lights: &[RGB], zones: &[Zone], dmx: &Dmx ) {
        let spliced = splice_null_pixels(lights, zones);
        let mut out: Vec<u8> = vec![];
        for rgb in spliced.iter() {
            let gc = gamma_correct(rgb);
            out.push(gc.red);
            out.push(gc.green);
            out.push(gc.blue);
        }
        let mut universes = Vec::new();
        while out.len() > UNIVERSE_SIZE {
            let u = out.split_off(UNIVERSE_SIZE);
            universes.push(out);
            out = u;
        }
        universes.push(out);
        let mut universe: u16 = 1;
        for u in universes {
            let _res = dmx.source.send(universe, &u);
            universe += 1;
        }
    }

    fn splice_null_pixels( lights: &[RGB], zones: &[Zone] ) -> Vec<RGB> {
        let mut copy: Vec<RGB> = vec![];
        copy.extend_from_slice(lights);
        let mut idx: usize = 0;
        for zone in zones {
            // null pixels at the head of the zone
            for _i in 0..zone.head {
                copy.insert(idx, RGB::null());
            }
            // and at the tail
            idx += zone.head as usize + zone.body as usize;
            for _i in 0..zone.tail {
                copy.insert(idx, RGB::null());
            }
            idx += zone.tail as usize;
        }
        return copy;
    }
}
<|endoftext|>


<commit_before>//! waitgroup provides an interface for awaiting the completion of multiple asynchronous tasks

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

/// A waitgroup waits for a collection of tasks to complete.
/// It keeps track of tasks via shared counter
pub struct WaitGroup {
    cvar: Condvar,
    count: Mutex<usize>,
}

impl Default for WaitGroup {
    fn default() -> WaitGroup {
        WaitGroup::new(0)
    }
}

impl WaitGroup {
    /// creates a new wait group instance
    pub fn new(n: usize) -> WaitGroup {
        WaitGroup {
            cvar: Condvar::new(),
            count: Mutex::new(n),
        }
    }

    /// adds `delta` to internal counter
    pub fn add(&self, delta: usize) {
        let mut count = self.count.lock().unwrap();
        *count += delta;
        self.cvar.notify_all();
    }

    /// subtracts 1 from internal counter
    pub fn done(&self) {
        let mut count = self.count.lock().unwrap();
        *count -= 1;
        self.cvar.notify_all();
    }

    /// blocks the current thread until wait group is complete
    pub fn wait(&self) {
        let mut count = self.count.lock().unwrap();
        while *count > 0 {
            count = self.cvar.wait(count).unwrap();
        }
    }
}

#[test]
fn it_works() {}
<commit_msg>don't bother notifying waiters unless count is <= 0<commit_after>//! waitgroup provides an interface for awaiting the completion of multiple asynchronous tasks

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

/// A waitgroup waits for a collection of tasks to complete.
/// It keeps track of tasks via shared counter
pub struct WaitGroup {
    cvar: Condvar,
    count: Mutex<usize>,
}

impl Default for WaitGroup {
    fn default() -> WaitGroup {
        WaitGroup::new(0)
    }
}

impl WaitGroup {
    /// creates a new wait group instance
    pub fn new(n: usize) -> WaitGroup {
        WaitGroup {
            cvar: Condvar::new(),
            count: Mutex::new(n),
        }
    }

    /// adds `delta` to internal counter
    pub fn add(&self, delta: usize) {
        let mut count = self.count.lock().unwrap();
        *count += delta;
        self.notify_if_empty(*count)
    }

    /// subtracts 1 from internal counter
    pub fn done(&self) {
        let mut count = self.count.lock().unwrap();
        *count -= 1;
        self.notify_if_empty(*count)
    }

    fn notify_if_empty(&self, count: usize) {
        if count <= 0 {
            self.cvar.notify_all();
        }
    }

    /// blocks the current thread until wait group is complete
    pub fn wait(&self) {
        let mut count = self.count.lock().unwrap();
        while *count > 0 {
            count = self.cvar.wait(count).unwrap();
        }
    }
}

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


<commit_before>pub struct HNil;

pub struct HCons<H, T> {
    pub head: H,
    pub tail: T
}

pub trait Contains<A> {
    fn get(&self) -> &A;
    fn get_mut(&mut self) -> &mut A;
}

macro_rules! hlist_type_internal {
    ($hlist_name:ident, $hlist_current:ty, $th:ty, $($tr:ty,)*) => {
       hlist_type_internal!($hlist_name, HCons<$th, $hlist_current>, $($tr,)*);
    };
    ($hlist_name:ident, $hlist_current:ty,) => {
        type $hlist_name = $hlist_current;
    }
}

#[macro_export]
macro_rules! hlist_type {
    ($hlist:ident) => {hlist_type_internal!($hlist, HNil,)};
    ($hlist:ident, $($types:ty),* ) => {hlist_type_internal!($hlist, $crate::HNil, $($types,)*);}
}

macro_rules! generate_hlist_contains {

    ($hlist:ty) => {{}};
    ($hlist:ty,) => {{}};

    ($hlist:ty, $last:ty, $($init:ty,)*) => {{

        impl $crate::Contains<$last> for $hlist {

            #[allow(unused_variables)]
            fn get(&self) -> &$last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head; // Only used to refer to $init
                    let cur_cell = &cur_cell.tail;
                )*
                &cur_cell.head
            }

            #[allow(unused_variables)]
            fn get_mut(&mut self) -> &mut $last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head;
                    let cur_cell = &mut cur_cell.tail;
                )*
                &mut cur_cell.head
            }
        }

        generate_hlist_contains!($hlist, $($init,)*);
    }}
}

/// Test comment
#[macro_export]
macro_rules! generate_contains_impls {
    ($($types:ty),*) => {{
        hlist_type!(TheHList, $($types),*);
        generate_hlist_contains!(TheHList, $($types,)*);
    }}
}

pub trait HList: Sized {
    fn push<A: Sized>(self, a: A) -> HCons<A, Self> {
        HCons { head: a, tail: self }
    }
}

impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}

#[test]
fn empty_hlist_type() {
    hlist_type!(Empty);
    let empty: Empty = HNil;
    drop(empty);
}

#[test]
fn empty_generate_contains_impls() {
    generate_contains_impls!();
}
<commit_msg>More testing. Not sure if these really count as unit tests.<commit_after>pub struct HNil;

pub struct HCons<H, T> {
    pub head: H,
    pub tail: T
}

pub trait Contains<A> {
    fn get(&self) -> &A;
    fn get_mut(&mut self) -> &mut A;
}

macro_rules! hlist_type_internal {
    ($hlist_name:ident, $hlist_current:ty, $th:ty, $($tr:ty,)*) => {
       hlist_type_internal!($hlist_name, HCons<$th, $hlist_current>, $($tr,)*);
    };
    ($hlist_name:ident, $hlist_current:ty,) => {
        type $hlist_name = $hlist_current;
    }
}

#[macro_export]
macro_rules! hlist_type {
    ($hlist:ident) => {hlist_type_internal!($hlist, HNil,)};
    ($hlist:ident, $($types:ty),* ) => {hlist_type_internal!($hlist, $crate::HNil, $($types,)*);}
}

macro_rules! generate_hlist_contains {

    ($hlist:ty) => {{}};
    ($hlist:ty,) => {{}};

    ($hlist:ty, $last:ty, $($init:ty,)*) => {{

        impl $crate::Contains<$last> for $hlist {

            #[allow(unused_variables)]
            fn get(&self) -> &$last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head; // Only used to refer to $init
                    let cur_cell = &cur_cell.tail;
                )*
                &cur_cell.head
            }

            #[allow(unused_variables)]
            fn get_mut(&mut self) -> &mut $last {
                let cur_cell = self;
                $(
                    let head: &$init = &cur_cell.head;
                    let cur_cell = &mut cur_cell.tail;
                )*
                &mut cur_cell.head
            }
        }

        generate_hlist_contains!($hlist, $($init,)*);
    }}
}

/// Test comment
#[macro_export]
macro_rules! generate_contains_impls {
    ($($types:ty),*) => {{
        hlist_type!(TheHList, $($types),*);
        generate_hlist_contains!(TheHList, $($types,)*);
    }}
}

pub trait HList: Sized {
    fn push<A: Sized>(self, a: A) -> HCons<A, Self> {
        HCons { head: a, tail: self }
    }
}

impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}

#[test]
fn hlist_type_tests() {
    hlist_type!(Zero);
    hlist_type!(One, i32);
    hlist_type!(Two, i32, i64);
    let _: Zero = HNil;
    let _: One = HNil.push(0i32);
    let _: Two = HNil.push(0i32).push(0i64);
}

#[test]
fn contains_tests() {
    generate_contains_impls!();
    generate_contains_impls!(i32);
    generate_contains_impls!(i32, i64);
    let _zero: HNil = HNil;
    let one: HCons<i32, HNil> = HNil.push(1i32);
    let two: HCons<i64, HCons<i32, HNil>> = HNil.push(1i32).push(2i64);
    let one_val: &i32 = one.get();
    let two_val_one: &i32 = two.get();
    let two_val_two: &i64 = two.get();
    assert!(one_val == &1i32);
    assert!(two_val_one == &1i32);
    assert!(two_val_two == &2i64);
}

<|endoftext|>


<commit_before>use bitset::BitSet;
use ranges::{GenericRange, Relation};
use search::{search, Character, CHARS_LEN, NAMES};
use std::mem;
use std::ops::{Bound, Range, RangeBounds};
use wasm_bindgen::prelude::*;

mod bitset;
mod search;

mod js {
    use wasm_bindgen::prelude::*;
    #[wasm_bindgen(raw_module = "../../src/index.js")]
    extern "C" {
        pub fn clear();
        #[wasm_bindgen(js_name = "popEnd")]
        pub fn pop_end();
        #[wasm_bindgen(js_name = "popStart")]
        pub fn pop_start();
        #[wasm_bindgen(js_name = "pushEnd")]
        pub fn push_end(index: u32, codepoint: u32, start: usize, end: usize);
        #[wasm_bindgen(js_name = "pushStart")]
        pub fn push_start(index: u32, codepoint: u32, start: usize, end: usize);
    }
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[allow(unused_macros)]
macro_rules! log {
    // Note that this is using the `log` function imported above during
    // `bare_bones`
    ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}

#[wasm_bindgen(start)]
pub fn start() {
    std::panic::set_hook(Box::new(console_error_panic_hook::hook));
}

#[wasm_bindgen]
pub fn names_ptr() -> *const u8 {
    NAMES.as_ptr()
}

#[wasm_bindgen]
pub fn names_len() -> usize {
    NAMES.len()
}

#[wasm_bindgen]
pub struct Searcher {
    chars: Vec<Character>,
    current: GenericRange<u32>,
}

fn to_range(generic: GenericRange<u32>) -> Range<u32> {
    let start = match generic.start_bound() {
        Bound::Included(&s) => s,
        Bound::Excluded(&s) => s + 1,
        Bound::Unbounded => 0,
    };

    let end = match generic.end_bound() {
        Bound::Included(&e) => e + 1,
        Bound::Excluded(&e) => e,
        Bound::Unbounded => u32::MAX,
    };

    start..end
}

#[wasm_bindgen]
impl Searcher {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        Self {
            chars: Vec::with_capacity(CHARS_LEN),
            current: GenericRange::from(0..0),
        }
    }

    pub fn search(&mut self, mut pattern: String) {
        static mut SET: BitSet = BitSet::new();

        pattern.make_ascii_uppercase();

        // SAFETY: wasm will be only single threaded
        search(&pattern, &mut self.chars, unsafe { &mut SET });
        self.current = GenericRange::from(0..0);
    }

    pub fn codepoints(&mut self, codepoints: Vec<u32>) {
        self.chars.clear();
        self.chars
            .extend(codepoints.into_iter().filter_map(Character::from_codepoint));

        self.current = GenericRange::from(0..0);
    }

    pub fn len(&self) -> usize {
        self.chars.len()
    }

    pub fn render(&mut self, start: u32, end: u32) {
        let next = GenericRange::from(start..end);
        let prev = mem::replace(&mut self.current, next);

        // log!("{} -> {}\t{:?}", prev, next, prev.relation(next));

        let pop_start = |generic_range| {
            for _ in to_range(generic_range) {
                js::pop_start();
            }
        };

        let pop_end = |generic_range| {
            for _ in to_range(generic_range) {
                js::pop_end();
            }
        };

        let push_start = |generic_range| {
            for i in to_range(generic_range).rev() {
                let ch = self.chars[i as usize];
                let range = ch.range();
                js::push_start(i, ch.codepoint(), range.start, range.end);
            }
        };

        let push_end = |generic_range| {
            for i in to_range(generic_range) {
                let ch = self.chars[i as usize];
                let range = ch.range();
                js::push_end(i, ch.codepoint(), range.start, range.end);
            }
        };

        match prev.relation(next) {
            Relation::Equal(_) => {}
            Relation::Disjoint { .. } | Relation::Touching { .. } | Relation::Empty { .. } => {
                js::clear();
                push_end(next);
            }
            Relation::Overlapping {
                first_disjoint,
                second_disjoint,
                self_less,
                ..
            } => {
                if self_less {
                    pop_start(first_disjoint);
                    push_end(second_disjoint);
                } else {
                    pop_end(second_disjoint);
                    push_start(first_disjoint);
                }
            }
            Relation::Containing {
                first_disjoint,
                second_disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    pop_start(first_disjoint);
                    pop_end(second_disjoint);
                } else {
                    push_start(first_disjoint);
                    push_end(second_disjoint);
                }
            }
            Relation::Starting {
                disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    push_end(disjoint);
                } else {
                    pop_end(disjoint);
                }
            }
            Relation::Ending {
                disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    push_start(disjoint);
                } else {
                    pop_start(disjoint);
                }
            }
        }
    }
}
<commit_msg>Fix push/pop in Containing diff<commit_after>use bitset::BitSet;
use ranges::{GenericRange, Relation};
use search::{search, Character, CHARS_LEN, NAMES};
use std::mem;
use std::ops::{Bound, Range, RangeBounds};
use wasm_bindgen::prelude::*;

mod bitset;
mod search;

mod js {
    use wasm_bindgen::prelude::*;
    #[wasm_bindgen(raw_module = "../../src/index.js")]
    extern "C" {
        pub fn clear();
        #[wasm_bindgen(js_name = "popEnd")]
        pub fn pop_end();
        #[wasm_bindgen(js_name = "popStart")]
        pub fn pop_start();
        #[wasm_bindgen(js_name = "pushEnd")]
        pub fn push_end(index: u32, codepoint: u32, start: usize, end: usize);
        #[wasm_bindgen(js_name = "pushStart")]
        pub fn push_start(index: u32, codepoint: u32, start: usize, end: usize);
    }
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[allow(unused_macros)]
macro_rules! log {
    // Note that this is using the `log` function imported above during
    // `bare_bones`
    ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}

#[wasm_bindgen(start)]
pub fn start() {
    std::panic::set_hook(Box::new(console_error_panic_hook::hook));
}

#[wasm_bindgen]
pub fn names_ptr() -> *const u8 {
    NAMES.as_ptr()
}

#[wasm_bindgen]
pub fn names_len() -> usize {
    NAMES.len()
}

#[wasm_bindgen]
pub struct Searcher {
    chars: Vec<Character>,
    current: GenericRange<u32>,
}

fn to_range(generic: GenericRange<u32>) -> Range<u32> {
    let start = match generic.start_bound() {
        Bound::Included(&s) => s,
        Bound::Excluded(&s) => s + 1,
        Bound::Unbounded => 0,
    };

    let end = match generic.end_bound() {
        Bound::Included(&e) => e + 1,
        Bound::Excluded(&e) => e,
        Bound::Unbounded => u32::MAX,
    };

    start..end
}

#[wasm_bindgen]
impl Searcher {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        Self {
            chars: Vec::with_capacity(CHARS_LEN),
            current: GenericRange::from(0..0),
        }
    }

    pub fn search(&mut self, mut pattern: String) {
        static mut SET: BitSet = BitSet::new();

        pattern.make_ascii_uppercase();

        // SAFETY: wasm will be only single threaded
        search(&pattern, &mut self.chars, unsafe { &mut SET });
        self.current = GenericRange::from(0..0);
    }

    pub fn codepoints(&mut self, codepoints: Vec<u32>) {
        self.chars.clear();
        self.chars
            .extend(codepoints.into_iter().filter_map(Character::from_codepoint));

        self.current = GenericRange::from(0..0);
    }

    pub fn len(&self) -> usize {
        self.chars.len()
    }

    pub fn render(&mut self, start: u32, end: u32) {
        let next = GenericRange::from(start..end);
        let prev = mem::replace(&mut self.current, next);

        // log!("{} -> {}\t{:?}", prev, next, prev.relation(next));

        let pop_start = |generic_range| {
            for _ in to_range(generic_range) {
                js::pop_start();
            }
        };

        let pop_end = |generic_range| {
            for _ in to_range(generic_range) {
                js::pop_end();
            }
        };

        let push_start = |generic_range| {
            for i in to_range(generic_range).rev() {
                let ch = self.chars[i as usize];
                let range = ch.range();
                js::push_start(i, ch.codepoint(), range.start, range.end);
            }
        };

        let push_end = |generic_range| {
            for i in to_range(generic_range) {
                let ch = self.chars[i as usize];
                let range = ch.range();
                js::push_end(i, ch.codepoint(), range.start, range.end);
            }
        };

        match prev.relation(next) {
            Relation::Equal(_) => {}
            Relation::Disjoint { .. } | Relation::Touching { .. } | Relation::Empty { .. } => {
                js::clear();
                push_end(next);
            }
            Relation::Overlapping {
                first_disjoint,
                second_disjoint,
                self_less,
                ..
            } => {
                if self_less {
                    pop_start(first_disjoint);
                    push_end(second_disjoint);
                } else {
                    pop_end(second_disjoint);
                    push_start(first_disjoint);
                }
            }
            Relation::Containing {
                first_disjoint,
                second_disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    push_start(first_disjoint);
                    push_end(second_disjoint);
                } else {
                    pop_start(first_disjoint);
                    pop_end(second_disjoint);
                }
            }
            Relation::Starting {
                disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    push_end(disjoint);
                } else {
                    pop_end(disjoint);
                }
            }
            Relation::Ending {
                disjoint,
                self_shorter,
                ..
            } => {
                if self_shorter {
                    push_start(disjoint);
                } else {
                    pop_start(disjoint);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>pub trait

pub struct Crc8 {
        table : [u8; 256]
}

pub impl Crc8 {
        pub fn create_msb(polynomial : u8) -> Crc8 {
                let msbit : u8 = 0x80;
                let mut t : u8 = msbit;
                let mut tmp : u8;
                let mut i : u32 = 1;
                let mut idx : u8;
                let mut table : [u8; 256] = [0; 256];

                while i < 256 {
                        if t & msbit != 0 { tmp = polynomial; } else { tmp = 0; }
                        t = (t << 1) ^ tmp;
                        for j in 0..i {
                                idx = (i+j) as u8;
                                table[(idx) as usize] =  table[j as usize] ^ t;
                        }
                        i *= 2;
                }

                return Crc8{ table : table};
        }

        pub fn create_lsb(polynomial :u8) -> Crc8 {
                let mut i :u32 = 0xff;
                let mut j :u32;
                let mut t :u8 = 1;
                let mut tmp :u8;
                let mut idx :u8;
                let mut table : [u8; 256] = [0; 256];

                while i != 0 {
                        if t & 1 != 0 {
                                tmp = polynomial;
                        }
                        else {
                                tmp = 0;
                        }
                        t = (t >> 1) ^ tmp;
                        j = 0;
                        while j < 256 {
                                idx = (i+j) as u8;
                                table[idx as usize] = table[j as usize] ^ t;
                                j += 2 * i;
                        }
                        i >>= 1;
                }

                return Crc8{ table : table };
        }

        pub fn calc(&mut self, buffer : &[u8], length: i32, crc: u8) -> u8 {
                let mut i : i32 = 0;
                let mut crc_tmp = crc;

                while i < length {
                        crc_tmp = self.table[((crc_tmp ^ buffer[i as usize]) as u8) as usize];
                        i+=1;
                }
                return crc_tmp;
        }
}
<commit_msg>Refactoring<commit_after>pub struct Crc8 {
        table : [u8; 256]
}

impl Crc8 {
        pub fn create_msb(polynomial : u8) -> Crc8 {
                let msbit : u8 = 0x80;
                let mut t : u8 = msbit;
                let mut tmp : u8;
                let mut i : u32 = 1;
                let mut idx : u8;
                let mut table : [u8; 256] = [0; 256];

                while i < 256 {
                        if t & msbit != 0 { tmp = polynomial; } else { tmp = 0; }
                        t = (t << 1) ^ tmp;
                        for j in 0..i {
                                idx = (i+j) as u8;
                                table[(idx) as usize] =  table[j as usize] ^ t;
                        }
                        i *= 2;
                }

                return Crc8{ table : table};
        }

        pub fn create_lsb(polynomial :u8) -> Crc8 {
                let mut i :u32 = 0xff;
                let mut j :u32;
                let mut t :u8 = 1;
                let mut tmp :u8;
                let mut idx :u8;
                let mut table : [u8; 256] = [0; 256];

                while i != 0 {
                        if t & 1 != 0 { tmp = polynomial; } else { tmp = 0; }
                        t = (t >> 1) ^ tmp;
                        j = 0;
                        while j < 256 {
                                idx = (i+j) as u8;
                                table[idx as usize] = table[j as usize] ^ t;
                                j += 2 * i;
                        }
                        i >>= 1;
                }

                return Crc8{ table : table };
        }

        pub fn calc(&mut self, buffer : &[u8], length: i32, crc: u8) -> u8 {
                let mut i : i32 = 0;
                let mut crc_tmp = crc;

                while i < length {
                        crc_tmp = self.table[((crc_tmp ^ buffer[i as usize]) as u8) as usize];
                        i+=1;
                }
                return crc_tmp;
        }
}
<|endoftext|>


<commit_before>//! # Convert Sort Expression to SQL
//!
//! Converts 'sort format' to 'SQL format'. E.g.:
//!
//! - `-id` -> `id DESC NULLS LAST`
//! - `id`  -> `id ASC NULLS LAST`
//! - `id-` -> `id ASC NULLS FIRST`
//! - `-aired,id` -> `aired DESC NULLS LAST, id ASC NULLS LAST`
//!
//! # Example
//!
//! ```
//! #![allow(unstable)]
//! # use sort_str_to_sql::{sort_str_to_sql};
//! # use std::borrow::ToOwned;
//! assert!(
//!   sort_str_to_sql("-id") ==
//!   Some("id DESC NULLS LAST".to_owned())
//! );
//! assert!(
//!   sort_str_to_sql("-id,+aired-") ==
//!   Some("id DESC NULLS LAST, aired ASC NULLS FIRST".to_owned())
//! );
//! ```
//!
//! (See tests for more examples.)
#![crate_name = "sort_str_to_sql"]
#![feature(plugin)]

extern crate regex;
#[plugin] #[no_link] extern crate regex_macros;
#[cfg(test)] #[allow(unstable)] extern crate test;

/// Convert One Sort Expression to SQL
fn convert_one_sort_str_field_to_sql(sort_str: &str) -> Option<String> {
    let sort_str_format = regex!(
        r"^(?P<order>[+-]?)(?P<field>[a-zA-Z0-9_\.]+)(?P<nulls>[-]?)$"
    );

    let fields = match sort_str_format.captures(sort_str) {
        Some(captures) => captures,
        None => return None,
    };

    let field = match fields.name("field") {
        Some(f) => f,
        None => return None,
    };

    let order = match fields.name("order") {
        Some("-") => "DESC",
        _   => "ASC",
    };
    let nulls = match fields.name("nulls") {
        Some("-") => "NULLS FIRST",
        _   => "NULLS LAST",
    };

    let sql = format!("{} {} {}", field, order, nulls);
    return Some(sql);
}

/// Convert Sort Expression to SQL
pub fn sort_str_to_sql(sort_str: &str) -> Option<String> {
    let sql_array: Vec<String> = sort_str.split(',')
    .filter_map(convert_one_sort_str_field_to_sql)
    .collect();

    let sql = sql_array.connect(", ");
    return if sql == "" { None } else { Some(sql) };
}

#[cfg(test)]
#[allow(unstable)]
mod tests {
    use test::Bencher;
    use std::borrow::ToOwned;

    use super::{sort_str_to_sql};

    #[test]
    fn it_works() {
        let tests = vec![
            // Correct inputs
            ("id", Some("id ASC NULLS LAST")),
            ("+id", Some("id ASC NULLS LAST")),
            ("-id", Some("id DESC NULLS LAST")),
            ("id-", Some("id ASC NULLS FIRST")),
            ("+id-", Some("id ASC NULLS FIRST")),
            ("-id-", Some("id DESC NULLS FIRST")),
            ("show.id", Some("show.id ASC NULLS LAST")),
            ("-id,aired-", Some("id DESC NULLS LAST, aired ASC NULLS FIRST")),
            ("-id,+aired-", Some("id DESC NULLS LAST, aired ASC NULLS FIRST")),
            ("+id-,show.id", Some("id ASC NULLS FIRST, show.id ASC NULLS LAST")),

            // Incorrect inputs
            ("lol what", None),
            ("+-id-", None),

            // Partially correct inputs
            ("id,++aired+", Some("id ASC NULLS LAST")),
            ("?id,+aired-", Some("aired ASC NULLS FIRST")),
        ];

        for &(input, _sql) in tests.iter() {
            let sql = match _sql { None => None, Some(s) => Some(s.to_owned())};
            assert!(
                sort_str_to_sql(input) == sql,
                "FAILED `{:?}` => `{:?}` NOT `{:?}`", input, sort_str_to_sql(input), sql
            )
        }
    }

    #[bench]
    fn bench_simple(b: &mut Bencher) {
        b.iter(|| sort_str_to_sql("id"));
    }

    #[bench]
    fn bench_complex(b: &mut Bencher) {
        b.iter(|| sort_str_to_sql("-date,+id-,show.id"));
    }

}
<commit_msg>rustup<commit_after>//! # Convert Sort Expression to SQL
//!
//! Converts 'sort format' to 'SQL format'. E.g.:
//!
//! - `-id` -> `id DESC NULLS LAST`
//! - `id`  -> `id ASC NULLS LAST`
//! - `id-` -> `id ASC NULLS FIRST`
//! - `-aired,id` -> `aired DESC NULLS LAST, id ASC NULLS LAST`
//!
//! # Example
//!
//! ```
//! #![allow(unstable)]
//! # use sort_str_to_sql::{sort_str_to_sql};
//! # use std::borrow::ToOwned;
//! assert!(
//!   sort_str_to_sql("-id") ==
//!   Some("id DESC NULLS LAST".to_owned())
//! );
//! assert!(
//!   sort_str_to_sql("-id,+aired-") ==
//!   Some("id DESC NULLS LAST, aired ASC NULLS FIRST".to_owned())
//! );
//! ```
//!
//! (See tests for more examples.)
#![crate_name = "sort_str_to_sql"]
#![feature(plugin, test, core)]

#![plugin(regex_macros)]
extern crate regex;
#[cfg(test)] extern crate test;

/// Convert One Sort Expression to SQL
fn convert_one_sort_str_field_to_sql(sort_str: &str) -> Option<String> {
    let sort_str_format = regex!(
        r"^(?P<order>[+-]?)(?P<field>[a-zA-Z0-9_\.]+)(?P<nulls>[-]?)$"
    );

    let fields = match sort_str_format.captures(sort_str) {
        Some(captures) => captures,
        None => return None,
    };

    let field = match fields.name("field") {
        Some(f) => f,
        None => return None,
    };

    let order = match fields.name("order") {
        Some("-") => "DESC",
        _   => "ASC",
    };
    let nulls = match fields.name("nulls") {
        Some("-") => "NULLS FIRST",
        _   => "NULLS LAST",
    };

    let sql = format!("{} {} {}", field, order, nulls);
    return Some(sql);
}

/// Convert Sort Expression to SQL
pub fn sort_str_to_sql(sort_str: &str) -> Option<String> {
    let sql_array: Vec<String> = sort_str.split(',')
    .filter_map(convert_one_sort_str_field_to_sql)
    .collect();

    let sql = sql_array.connect(", ");
    return if sql == "" { None } else { Some(sql) };
}

#[cfg(test)]
mod tests {
    use test::Bencher;
    use std::borrow::ToOwned;

    use super::{sort_str_to_sql};

    #[test]
    fn it_works() {
        let tests = vec![
            // Correct inputs
            ("id", Some("id ASC NULLS LAST")),
            ("+id", Some("id ASC NULLS LAST")),
            ("-id", Some("id DESC NULLS LAST")),
            ("id-", Some("id ASC NULLS FIRST")),
            ("+id-", Some("id ASC NULLS FIRST")),
            ("-id-", Some("id DESC NULLS FIRST")),
            ("show.id", Some("show.id ASC NULLS LAST")),
            ("-id,aired-", Some("id DESC NULLS LAST, aired ASC NULLS FIRST")),
            ("-id,+aired-", Some("id DESC NULLS LAST, aired ASC NULLS FIRST")),
            ("+id-,show.id", Some("id ASC NULLS FIRST, show.id ASC NULLS LAST")),

            // Incorrect inputs
            ("lol what", None),
            ("+-id-", None),

            // Partially correct inputs
            ("id,++aired+", Some("id ASC NULLS LAST")),
            ("?id,+aired-", Some("aired ASC NULLS FIRST")),
        ];

        for &(input, _sql) in tests.iter() {
            let sql = match _sql { None => None, Some(s) => Some(s.to_owned())};
            assert!(
                sort_str_to_sql(input) == sql,
                "FAILED `{:?}` => `{:?}` NOT `{:?}`", input, sort_str_to_sql(input), sql
            )
        }
    }

    #[bench]
    fn bench_simple(b: &mut Bencher) {
        b.iter(|| sort_str_to_sql("id"));
    }

    #[bench]
    fn bench_complex(b: &mut Bencher) {
        b.iter(|| sort_str_to_sql("-date,+id-,show.id"));
    }

}
<|endoftext|>


<commit_before>#![crate_name = "raft"]
#![crate_type="lib"]

//! Some module level stuff here.
use std::io::net::ip::IpAddr;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
pub trait Raft {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<String>,
                      leader_commit: usize) -> (usize, bool);

    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool);
}

/// A `RaftNode` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
pub struct RaftNode {
    // Raft related.
    state: NodeState,
    persistent_state: PersistentState,
    volatile_state: VolatileState,
    // Auxilary Data.
    // TODO: This should probably be split off.
    // All nodes need to know this otherwise they can't effectively lead or hold elections.
    known_nodes: Vec<IpAddr>, // TODO: Make IP Address structs.
}

/// The implementation of the RaftNode. In most use cases, creating a `RaftNode` should just be
/// done via `::new(node_list)`.
///
/// ```
/// use raft::RaftNode;
/// use std::io::net::ip::IpAddr;
///
/// RaftNode::new(vec![
///     "192.168.0.100".parse::<IpAddr>().unwrap(),
///     "192.168.0.101".parse::<IpAddr>().unwrap()
/// ]);
///
/// ```
impl RaftNode {
    /// Creates a new RaftNode with the neighbors specified.
    pub fn new(node_list: Vec<IpAddr>) -> RaftNode {
        RaftNode {
            state: NodeState::Follower,
            persistent_state: PersistentState {
                current_term: 0, // TODO: Double Check.
                voted_for: 0, // TODO: Better type?
                log: Vec::<String>::new(),
            },
            volatile_state: VolatileState {
                commit_index: 0,
                last_applied: 0,
            },
            known_nodes: node_list
        }
    }
}

/// The RPC calls required by the Raft protocol.
impl Raft for RaftNode {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<String>,
                      leader_commit: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
}

/// Nodes can either be:
///
///   * A `Follower`, which replicates AppendEntries requests and votes for it's leader.
///   * A `Leader`, which leads the cluster by serving incoming requests, ensuring data is
///     replicated, and issuing heartbeats..
///   * A `Candidate`, which campaigns in an election and may become a `Leader` (if it gets enough
///     votes) or a `Follower`, if it hears from a `Leader`.
pub enum NodeState {
    Follower,
    Leader(LeaderState),
    Candidate,
}

/// Persistent state
/// **Must be updated to stable storage before RPC response.**
pub struct PersistentState {
    current_term: usize,
    voted_for: usize, // Better way? Can we use a IpAddr?
    log: Vec<String>,
}

/// Volatile state
pub struct VolatileState {
    commit_index: usize,
    last_applied: usize
}

/// Leader Only
/// **Reinitialized after election.**
pub struct LeaderState {
    next_index: Vec<usize>,
    match_index: Vec<usize>
}

#[cfg(test)]
mod tests {}
<commit_msg>Better types, spinup, and a basic test.<commit_after>#![crate_name = "raft"]
#![crate_type="lib"]

use std::io::net::ip::SocketAddr;
use std::io::net::udp::UdpSocket;
use std::thread::Thread;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::str;

// The maximum size of the read buffer.
const BUFFER_SIZE: usize = 2048;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
pub trait Raft {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<String>,
                      leader_commit: usize) -> (usize, bool);

    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool);
}

/// A `RaftNode` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
pub struct RaftNode {
    // Raft related.
    state: NodeState,
    persistent_state: PersistentState,
    volatile_state: VolatileState,
    // Auxilary Data.
    // TODO: This should probably be split off.
    // All nodes need to know this otherwise they can't effectively lead or hold elections.
    known_nodes: Vec<SocketAddr>,
    own_socket: SocketAddr,
}

/// The implementation of the RaftNode. In most use cases, creating a `RaftNode` should just be
/// done via `::new()`.
///
/// ```
/// use raft::RaftNode;
/// use std::io::net::ip::SocketAddr;
/// use std::io::net::ip::IpAddr::Ipv4Addr;
/// let my_node = RaftNode::new(
///     // This node's address.
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 },
///     // The list of nodes.
///     vec![
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 },
///     SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11113 }
///     ]);
/// ```
impl RaftNode {
    /// Creates a new RaftNode with the neighbors specified.
    pub fn new(own_socket: SocketAddr, node_list: Vec<SocketAddr>) -> RaftNode {
        RaftNode {
            state: NodeState::Follower,
            persistent_state: PersistentState {
                current_term: 0, // TODO: Double Check.
                voted_for: 0,    // TODO: Better type?
                log: Vec::<String>::new(),
            },
            volatile_state: VolatileState {
                commit_index: 0,
                last_applied: 0,
            },
            known_nodes: node_list,
            own_socket: own_socket
        }
    }
    /// Spins up a thread that listens and handles RPCs.
    pub fn spinup(&self) -> Receiver<String> {
        let (sender, reciever) = channel::<String>();
        // Need to clone the SocketAddr for lifetime reasons.
        let mut socket = UdpSocket::bind(self.own_socket)
                .unwrap(); // TODO: Can we do better?
        Thread::spawn(move || {
            let mut read_buffer = [0; BUFFER_SIZE];
            let (num_read, source) = socket.recv_from(&mut read_buffer)
                .unwrap(); // TODO: Can we do better?
            let message = str::from_utf8(&read_buffer)
                .map(|val| String::from_str(val))
                .unwrap_or("FAIL".to_string()); // TODO: Can we do better?
            sender.send(message).unwrap();
        });
        reciever
    }
}

/// The RPC calls required by the Raft protocol.
impl Raft for RaftNode {
    /// Returns (term, success)
    fn append_entries(term: usize, leader_id: usize, prev_log_index: usize,
                      prev_log_term: usize, entries: Vec<String>,
                      leader_commit: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
    /// Returns (term, voteGranted)
    fn request_vote(term: usize, candidate_id: usize, last_log_index: usize,
                    last_log_term: usize) -> (usize, bool) {
        (0, false) // TODO: Implement
    }
}

/// Nodes can either be:
///
///   * A `Follower`, which replicates AppendEntries requests and votes for it's leader.
///   * A `Leader`, which leads the cluster by serving incoming requests, ensuring data is
///     replicated, and issuing heartbeats..
///   * A `Candidate`, which campaigns in an election and may become a `Leader` (if it gets enough
///     votes) or a `Follower`, if it hears from a `Leader`.
pub enum NodeState {
    Follower,
    Leader(LeaderState),
    Candidate,
}

/// Persistent state
/// **Must be updated to stable storage before RPC response.**
pub struct PersistentState {
    current_term: usize,
    voted_for: usize, // Better way? Can we use a IpAddr?
    log: Vec<String>,
}

/// Volatile state
pub struct VolatileState {
    commit_index: usize,
    last_applied: usize
}

/// Leader Only
/// **Reinitialized after election.**
pub struct LeaderState {
    next_index: Vec<usize>,
    match_index: Vec<usize>
}

#[cfg(test)]
mod tests {
    use std::io::net::ip::SocketAddr;
    use std::io::net::udp::UdpSocket;
    use std::io::net::ip::IpAddr::Ipv4Addr;
    use std::thread::Thread;
    use std::sync::mpsc::{channel, Sender, Receiver};
    use std::str;
    use super::*;

    #[test]
    fn basic_functionality() {
        // Create the node.
        let my_node = RaftNode::new(
            // This node's address.
            SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111 },
            // The list of nodes.
            vec![
            SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11112 },
            SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11113 }
            ]);
        // Start up the node.
        let my_channel = my_node.spinup();
        // Make a test send to that port.
        let sender = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 1112 };
        let mut out = UdpSocket::bind(sender).unwrap();
        out.send_to("foo".as_bytes(), SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 11111}).unwrap();
        // Get the result.
        let event = my_channel.recv().unwrap();
        println!("{}", event);
    }

}
<|endoftext|>