<commit_before>//! Setup and control loop devices.
//!
//! Provides rust interface with similar functionalty to the linux utility `losetup`.
//!
//! # Examples
//!
//! ```rust
//! use loopdev::LoopControl;
//! let lc = LoopControl::open().unwrap();
//! let ld = lc.next_free().unwrap();
//!
//! println!("{}", ld.get_path().unwrap().display());
//!
//! ld.attach("test.img", 0).unwrap();
//! // ...
//! ld.detach().unwrap();
//! ```

extern crate libc;

use std::fs::OpenOptions;
use std::fs::File;

use std::os::unix::prelude::*;
use std::io;
use std::path::PathBuf;
use libc::{c_int, ioctl, uint8_t, uint32_t, uint64_t};
use std::default::Default;

static LOOP_SET_FD: u64 = 0x4C00;
static LOOP_CLR_FD: u64 = 0x4C01;
static LOOP_SET_STATUS64: u64 = 0x4C04;
static LOOP_CTL_GET_FREE: u64 = 0x4C82;

const LOOP_CONTROL: &'static str = "/dev/loop-control";
const LOOP_PREFIX: &'static str = "/dev/loop";

/// Interface to the loop control device: `/dev/loop-control`.
#[derive(Debug)]
pub struct LoopControl {
    dev_file: File,
}

impl LoopControl {
    /// Opens the loop control device.
    pub fn open() -> io::Result<LoopControl> {
        Ok(LoopControl {
            dev_file: try!(OpenOptions::new().read(true).write(true).open(LOOP_CONTROL)),
        })
    }

    /// Finds and opens the next available loop device.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use loopdev::LoopControl;
    /// let lc = LoopControl::open().unwrap();
    /// let ld = lc.next_free().unwrap();
    /// println!("{}", ld.get_path().unwrap().display());
    /// ```
    pub fn next_free(&self) -> io::Result<LoopDevice> {
        let result;
        unsafe {
            result = ioctl(self.dev_file.as_raw_fd() as c_int, LOOP_CTL_GET_FREE);
        }
        if result < 0 {
            Err(io::Error::last_os_error())
        } else {
            let dev = LOOP_PREFIX.to_string() + &result.to_string();
            Ok(try!(LoopDevice::open(&dev)))
        }
    }
}

/// Interface to a loop device ie `/dev/loop0`.
#[derive(Debug)]
pub struct LoopDevice {
    device: File,
}

impl LoopDevice {
    /// Opens a loop device.
    pub fn open(dev: &str) -> io::Result<LoopDevice> {
        // TODO create dev if it does not exist and begins with LOOP_PREFIX
        let f = try!(OpenOptions::new().read(true).write(true).open(dev));
        Ok(LoopDevice { device: f })
    }

    /// Attach the loop device to a file starting at offset into the file.
    ///
    /// # Examples
    ///
    /// Attach the device to the start of a file.
    ///
    /// ```rust
    /// use loopdev::LoopDevice;
    /// let ld = LoopDevice::open("/dev/loop4").unwrap();
    /// ld.attach("test.img", 0).unwrap();
    /// # ld.detach().unwrap();
    /// ```
    pub fn attach(&self, backing_file: &str, offset: u64) -> io::Result<()> {
        let bf = try!(OpenOptions::new().read(true).write(true).open(backing_file));

        // Attach the file
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int,
                     LOOP_SET_FD,
                     bf.as_raw_fd() as c_int) < 0 {
                return Err(io::Error::last_os_error());
            }
        }

        // Set offset for backing_file
        let mut info: loop_info64 = Default::default();
        info.lo_offset = offset;
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int,
                     LOOP_SET_STATUS64,
                     &mut info) < 0 {
                try!(self.detach());
                return Err(io::Error::last_os_error());
            }
        }
        Ok(())
    }

    /// Get the path of the loop device.
    pub fn get_path(&self) -> Option<PathBuf> {
        let mut p = PathBuf::from("/proc/self/fd");
        p.push(self.device.as_raw_fd().to_string());
        std::fs::read_link(&p).ok()
    }

    /// Detach a loop device from its backing file.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use loopdev::LoopDevice;
    /// let ld = LoopDevice::open("/dev/loop6").unwrap();
    /// # ld.attach("test.img", 0).unwrap();
    /// ld.detach().unwrap();
    /// ```
    pub fn detach(&self) -> io::Result<()> {
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int, LOOP_CLR_FD, 0) < 0 {
                return Err(io::Error::last_os_error());
            }
        }
        Ok(())
    }
}

#[repr(C)]
struct loop_info64 {
    pub lo_device: uint64_t,
    pub lo_inode: uint64_t,
    pub lo_rdevice: uint64_t,
    pub lo_offset: uint64_t,
    pub lo_sizelimit: uint64_t,
    pub lo_number: uint32_t,
    pub lo_encrypt_type: uint32_t,
    pub lo_encrypt_key_size: uint32_t,
    pub lo_flags: uint32_t,
    pub lo_file_name: [uint8_t; 64],
    pub lo_crypt_name: [uint8_t; 64],
    pub lo_encrypt_key: [uint8_t; 32],
    pub lo_init: [uint64_t; 2],
}

impl Default for loop_info64 {
    fn default() -> loop_info64 {
        loop_info64 {
            lo_device: 0,
            lo_inode: 0,
            lo_rdevice: 0,
            lo_offset: 0,
            lo_sizelimit: 0,
            lo_number: 0,
            lo_encrypt_type: 0,
            lo_encrypt_key_size: 0,
            lo_flags: 0,
            lo_file_name: [0; 64],
            lo_crypt_name: [0; 64],
            lo_encrypt_key: [0; 32],
            lo_init: [0; 2],
        }
    }
}
<commit_msg>Use format! to get device node for loop device<commit_after>//! Setup and control loop devices.
//!
//! Provides rust interface with similar functionalty to the linux utility `losetup`.
//!
//! # Examples
//!
//! ```rust
//! use loopdev::LoopControl;
//! let lc = LoopControl::open().unwrap();
//! let ld = lc.next_free().unwrap();
//!
//! println!("{}", ld.get_path().unwrap().display());
//!
//! ld.attach("test.img", 0).unwrap();
//! // ...
//! ld.detach().unwrap();
//! ```

extern crate libc;

use std::fs::OpenOptions;
use std::fs::File;

use std::os::unix::prelude::*;
use std::io;
use std::path::PathBuf;
use libc::{c_int, ioctl, uint8_t, uint32_t, uint64_t};
use std::default::Default;

static LOOP_SET_FD: u64 = 0x4C00;
static LOOP_CLR_FD: u64 = 0x4C01;
static LOOP_SET_STATUS64: u64 = 0x4C04;
static LOOP_CTL_GET_FREE: u64 = 0x4C82;

const LOOP_CONTROL: &'static str = "/dev/loop-control";
const LOOP_PREFIX: &'static str = "/dev/loop";

/// Interface to the loop control device: `/dev/loop-control`.
#[derive(Debug)]
pub struct LoopControl {
    dev_file: File,
}

impl LoopControl {
    /// Opens the loop control device.
    pub fn open() -> io::Result<LoopControl> {
        Ok(LoopControl {
            dev_file: try!(OpenOptions::new().read(true).write(true).open(LOOP_CONTROL)),
        })
    }

    /// Finds and opens the next available loop device.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use loopdev::LoopControl;
    /// let lc = LoopControl::open().unwrap();
    /// let ld = lc.next_free().unwrap();
    /// println!("{}", ld.get_path().unwrap().display());
    /// ```
    pub fn next_free(&self) -> io::Result<LoopDevice> {
        let result;
        unsafe {
            result = ioctl(self.dev_file.as_raw_fd() as c_int, LOOP_CTL_GET_FREE);
        }
        if result < 0 {
            Err(io::Error::last_os_error())
        } else {
            Ok(try!(LoopDevice::open(&format!("{}{}", LOOP_PREFIX, result))))
        }
    }
}

/// Interface to a loop device ie `/dev/loop0`.
#[derive(Debug)]
pub struct LoopDevice {
    device: File,
}

impl LoopDevice {
    /// Opens a loop device.
    pub fn open(dev: &str) -> io::Result<LoopDevice> {
        // TODO create dev if it does not exist and begins with LOOP_PREFIX
        let f = try!(OpenOptions::new().read(true).write(true).open(dev));
        Ok(LoopDevice { device: f })
    }

    /// Attach the loop device to a file starting at offset into the file.
    ///
    /// # Examples
    ///
    /// Attach the device to the start of a file.
    ///
    /// ```rust
    /// use loopdev::LoopDevice;
    /// let ld = LoopDevice::open("/dev/loop4").unwrap();
    /// ld.attach("test.img", 0).unwrap();
    /// # ld.detach().unwrap();
    /// ```
    pub fn attach(&self, backing_file: &str, offset: u64) -> io::Result<()> {
        let bf = try!(OpenOptions::new().read(true).write(true).open(backing_file));

        // Attach the file
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int,
                     LOOP_SET_FD,
                     bf.as_raw_fd() as c_int) < 0 {
                return Err(io::Error::last_os_error());
            }
        }

        // Set offset for backing_file
        let mut info: loop_info64 = Default::default();
        info.lo_offset = offset;
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int,
                     LOOP_SET_STATUS64,
                     &mut info) < 0 {
                try!(self.detach());
                return Err(io::Error::last_os_error());
            }
        }
        Ok(())
    }

    /// Get the path of the loop device.
    pub fn get_path(&self) -> Option<PathBuf> {
        let mut p = PathBuf::from("/proc/self/fd");
        p.push(self.device.as_raw_fd().to_string());
        std::fs::read_link(&p).ok()
    }

    /// Detach a loop device from its backing file.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use loopdev::LoopDevice;
    /// let ld = LoopDevice::open("/dev/loop6").unwrap();
    /// # ld.attach("test.img", 0).unwrap();
    /// ld.detach().unwrap();
    /// ```
    pub fn detach(&self) -> io::Result<()> {
        unsafe {
            if ioctl(self.device.as_raw_fd() as c_int, LOOP_CLR_FD, 0) < 0 {
                return Err(io::Error::last_os_error());
            }
        }
        Ok(())
    }
}

#[repr(C)]
struct loop_info64 {
    pub lo_device: uint64_t,
    pub lo_inode: uint64_t,
    pub lo_rdevice: uint64_t,
    pub lo_offset: uint64_t,
    pub lo_sizelimit: uint64_t,
    pub lo_number: uint32_t,
    pub lo_encrypt_type: uint32_t,
    pub lo_encrypt_key_size: uint32_t,
    pub lo_flags: uint32_t,
    pub lo_file_name: [uint8_t; 64],
    pub lo_crypt_name: [uint8_t; 64],
    pub lo_encrypt_key: [uint8_t; 32],
    pub lo_init: [uint64_t; 2],
}

impl Default for loop_info64 {
    fn default() -> loop_info64 {
        loop_info64 {
            lo_device: 0,
            lo_inode: 0,
            lo_rdevice: 0,
            lo_offset: 0,
            lo_sizelimit: 0,
            lo_number: 0,
            lo_encrypt_type: 0,
            lo_encrypt_key_size: 0,
            lo_flags: 0,
            lo_file_name: [0; 64],
            lo_crypt_name: [0; 64],
            lo_encrypt_key: [0; 32],
            lo_init: [0; 2],
        }
    }
}
<|endoftext|>


<commit_before>// 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.

//! Syntax extension to generate FourCCs.
//!
//! Once loaded, fourcc!() is called with a single 4-character string,
//! and an optional ident that is either `big`, `little`, or `target`.
//! The ident represents endianness, and specifies in which direction
//! the characters should be read. If the ident is omitted, it is assumed
//! to be `big`, i.e. left-to-right order. It returns a u32.
//!
//! # Examples
//!
//! To load the extension and use it:
//!
//! ```rust,ignore
//! #[phase(plugin)]
//! extern crate fourcc;
//!
//! fn main() {
//!     let val = fourcc!("\xC0\xFF\xEE!");
//!     assert_eq!(val, 0xC0FFEE21u32);
//!     let little_val = fourcc!("foo ", little);
//!     assert_eq!(little_val, 0x21EEFFC0u32);
//! }
//! ```
//!
//! # References
//!
//! * [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico")]

#![feature(plugin_registrar, rustc_private)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacEager};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use rustc::plugin::Registry;
use std::ops::Deref;

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

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult + 'static> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).deref() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.deref().chars().count() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.deref().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacEager::expr(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (P<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::Eof {
        None
    } else {
        p.expect(&token::Comma);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident.unwrap(), span: mk_sp(lo, hi)})
    };
    if p.token != token::Eof {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(&cx.cfg(), &*meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<commit_msg>Update for nightly rust.<commit_after>// 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.

//! Syntax extension to generate FourCCs.
//!
//! Once loaded, fourcc!() is called with a single 4-character string,
//! and an optional ident that is either `big`, `little`, or `target`.
//! The ident represents endianness, and specifies in which direction
//! the characters should be read. If the ident is omitted, it is assumed
//! to be `big`, i.e. left-to-right order. It returns a u32.
//!
//! # Examples
//!
//! To load the extension and use it:
//!
//! ```rust,ignore
//! #[phase(plugin)]
//! extern crate fourcc;
//!
//! fn main() {
//!     let val = fourcc!("\xC0\xFF\xEE!");
//!     assert_eq!(val, 0xC0FFEE21u32);
//!     let little_val = fourcc!("foo ", little);
//!     assert_eq!(little_val, 0x21EEFFC0u32);
//! }
//! ```
//!
//! # References
//!
//! * [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico")]

#![feature(plugin_registrar, rustc_private)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacEager};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use rustc::plugin::Registry;
use std::ops::Deref;

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

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult + 'static> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match &*ident.name.as_str() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.deref().chars().count() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.deref().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacEager::expr(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (P<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::Eof {
        None
    } else {
        p.expect(&token::Comma);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident.unwrap(), span: mk_sp(lo, hi)})
    };
    if p.token != token::Eof {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(&cx.cfg(), &*meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<|endoftext|>


<commit_before>//! A simple `io::stdoud` and `io::stderr` writing `Logger` implementation from the
//! `log` crate, using the `ansi_term` crate for colors and configured at runtime,
//! or at compile time with simple function calls. Designed for simple CLIs.
//!
//! This library only comes with 3 public ways to initialize the global logger.
//! Ensure you call one of these exactly once early in your rust program as shown
//! in one of the examples below.
//!
//! ## Example
//! The standard example with `clap` as the arg parser.
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     logger::init_with_verbosity(args.occurrences_of("v")).unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! But obviously use whatever argument parsing methods you prefer.
//!
//! ## Example
//! For a compile time switch, all you really need is `log` (for the macros)
//! and `loggerv` for how to print what's being sent to the macros.
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//! use log::LogLevel;
//!
//! fn main() {
//!     logger::init_with_level(LogLevel::Info).unwrap();
//!     debug!("this is a debug {}", "message");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! # Example
//! If you don't really care at all you could just use the plain `init` function
//! to only show warnings and errors:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//!
//! fn main() {
//!     logger::init().unwrap();
//!     info!("hidden");
//!     error!("this is printed by default");
//! }
//! ```
//!
//!
//! See the documentation for the log crate for more information about its API.
//!

//#[cfg(test)]
//#[macro_use]
//extern crate log;

extern crate log;

extern crate ansi_term;

use log::{Log, LogLevel, LogMetadata, LogRecord, SetLoggerError};
use std::io::{self, Write};
use ansi_term::Colour;

struct VLogger {
    log_level: LogLevel,
}

fn level_style(l: LogLevel) -> Colour {
    match l {
        LogLevel::Error => Colour::Fixed(9), // bright red
        LogLevel::Warn => Colour::Fixed(11), // bright yellow
        LogLevel::Info => Colour::Fixed(10), // bright green
        LogLevel::Debug => Colour::Fixed(7), // light grey
        LogLevel::Trace => Colour::Fixed(8), // grey
    }
}

impl Log for VLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let msg = format!("{}: {}",
                              level_style(record.level()).paint(record.location().module_path()),
                              record.args());
            if record.level() <= LogLevel::Warn {
                writeln!(&mut io::stderr(), "{}", msg);
            } else {
                println!("{}", msg);
            }
        }
    }
}

/// Initialize loggerv with a maximal log level.
///
/// See the main loggerv documentation page for an example.
pub fn init_with_level(log_level: LogLevel) -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log_level.to_log_level_filter());
        Box::new(VLogger { log_level: log_level })
    })
}

/// Initialize loggerv with a verbosity level.
///
/// Intended to be used with an arg parser counting the amount of -v flags.
/// See the main loggerv documentation page for an example.
pub fn init_with_verbosity(verbosity: u64) -> Result<(), SetLoggerError> {
    init_with_level(match verbosity {
        0 => LogLevel::Warn,  // default
        1 => LogLevel::Info,  // -v
        2 => LogLevel::Debug, // -vv
        _ => LogLevel::Trace, // -vvv and above
    })
}

/// Initializes loggerv with only warnings and errors.
///
/// See the main loggerv documentation page for an example.
pub fn init() -> Result<(), SetLoggerError> {
    init_with_level(LogLevel::Warn)
}

//#[cfg(test)]
//mod tests {
//    use init_with_verbosity;
//
//    #[test]
//    fn init_and_macros() {
//        let l = init_with_verbosity(3);
//        assert_eq!(l.is_ok(), true);
//        error!("error log");
//        warn!("warn log");
//        info!("info log");
//        debug!("debug log");
//        trace!("trace log");
//    }
//}
<commit_msg>give up on conditional compilation of macro_use on extern crate..<commit_after>//! A simple `io::stdoud` and `io::stderr` writing `Logger` implementation from the
//! `log` crate, using the `ansi_term` crate for colors and configured at runtime,
//! or at compile time with simple function calls. Designed for simple CLIs.
//!
//! This library only comes with 3 public ways to initialize the global logger.
//! Ensure you call one of these exactly once early in your rust program as shown
//! in one of the examples below.
//!
//! ## Example
//! The standard example with `clap` as the arg parser.
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     logger::init_with_verbosity(args.occurrences_of("v")).unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! But obviously use whatever argument parsing methods you prefer.
//!
//! ## Example
//! For a compile time switch, all you really need is `log` (for the macros)
//! and `loggerv` for how to print what's being sent to the macros.
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//! use log::LogLevel;
//!
//! fn main() {
//!     logger::init_with_level(LogLevel::Info).unwrap();
//!     debug!("this is a debug {}", "message");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! # Example
//! If you don't really care at all you could just use the plain `init` function
//! to only show warnings and errors:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate loggerv;
//!
//! use loggerv as logger;
//!
//! fn main() {
//!     logger::init().unwrap();
//!     info!("hidden");
//!     error!("this is printed by default");
//! }
//! ```
//!
//!
//! See the documentation for the log crate for more information about its API.
//!

extern crate log;
extern crate ansi_term;

use log::{Log, LogLevel, LogMetadata, LogRecord, SetLoggerError};
use std::io::{self, Write};
use ansi_term::Colour;

struct VLogger {
    log_level: LogLevel,
}

fn level_style(l: LogLevel) -> Colour {
    match l {
        LogLevel::Error => Colour::Fixed(9), // bright red
        LogLevel::Warn => Colour::Fixed(11), // bright yellow
        LogLevel::Info => Colour::Fixed(10), // bright green
        LogLevel::Debug => Colour::Fixed(7), // light grey
        LogLevel::Trace => Colour::Fixed(8), // grey
    }
}

impl Log for VLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let msg = format!("{}: {}",
                              level_style(record.level()).paint(record.location().module_path()),
                              record.args());
            if record.level() <= LogLevel::Warn {
                writeln!(&mut io::stderr(), "{}", msg);
            } else {
                println!("{}", msg);
            }
        }
    }
}

/// Initialize loggerv with a maximal log level.
///
/// See the main loggerv documentation page for an example.
pub fn init_with_level(log_level: LogLevel) -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log_level.to_log_level_filter());
        Box::new(VLogger { log_level: log_level })
    })
}

/// Initialize loggerv with a verbosity level.
///
/// Intended to be used with an arg parser counting the amount of -v flags.
/// See the main loggerv documentation page for an example.
pub fn init_with_verbosity(verbosity: u64) -> Result<(), SetLoggerError> {
    init_with_level(match verbosity {
        0 => LogLevel::Warn,  // default
        1 => LogLevel::Info,  // -v
        2 => LogLevel::Debug, // -vv
        _ => LogLevel::Trace, // -vvv and above
    })
}

/// Initializes loggerv with only warnings and errors.
///
/// See the main loggerv documentation page for an example.
pub fn init() -> Result<(), SetLoggerError> {
    init_with_level(LogLevel::Warn)
}

#[cfg(test)]
mod tests {
    use init_with_verbosity;

    #[test]
    fn init_and_macros() {
        let l = init_with_verbosity(3);
        assert_eq!(l.is_ok(), true);
        //error!("error log");
        //warn!("warn log");
        //info!("info log");
        //debug!("debug log");
        //trace!("trace log");
    }
}
<|endoftext|>


<commit_before>extern crate gurobi_sys as ffi;

use std::ptr::null_mut;
use std::ffi::{CStr, CString};

#[derive(Debug)]
pub enum IntAttr {
  // {{{
  NumConstrs,
  NumVars,
  NumSOS,
  NumQConstrs,
  NumNZs,
  NumQNZs,
  NumQCNZs,
  NumIntVars,
  NumBinVars,
  NumPWLObjVars,
  ModelSense,
  IsMIP,
  IsQP,
  IsQCP,
  Status,
  SolCount,
  BarIterCount,
  VBasis,
  CBasis,
  PWLObjCvx,
  BranchPriority,
  VarPreStat,
  BoundVioIndex,
  BoundSVioIndex,
  ConstrVioIndex,
  ConstrSVioIndex,
  ConstrResidualIndex,
  ConstrSResidualIndex,
  DualVioIndex,
  DualSVioIndex,
  DualResidualIndex,
  DualSResidualIndex,
  ComplVioIndex,
  IntVioIndex,
  IISMinimal,
  IISLB,
  IISUB,
  IISConstr,
  IISSOS,
  IISQConstr,
  TuneResultCount,
  Lazy,
  VarHintPri,
} // }}}

/// represents error information which called the API.
#[derive(Debug)]
pub enum Error {
  /// This function has yet implemented
  NotImplemented,
  /// An exception returned from Gurobi C API
  FromAPI(String, ffi::c_int),
  /// see https://doc.rust-lang.org/std/ffi/struct.NulError.html
  NulError(std::ffi::NulError),
}

pub type Result<T> = std::result::Result<T, Error>;

/// Gurobi environment object
pub struct Env {
  env: *mut ffi::GRBenv,
}

impl Env {
  /// create an empty environment with log file
  pub fn new(logfilename: &str) -> Result<Env> {
    let logfilename = try!(CString::new(logfilename)
      .map_err(|e| Error::NulError(e)));
    let mut env: *mut ffi::GRBenv = null_mut();
    let error = unsafe { ffi::GRBloadenv(&mut env, logfilename.as_ptr()) };
    if error != 0 {
      return Err(Error::FromAPI(get_error_msg_env(env), error));
    }
    Ok(Env { env: env })
  }

  fn get_error_msg(&self) -> String {
    get_error_msg_env(self.env)
  }
}

impl Drop for Env {
  fn drop(&mut self) {
    unsafe { ffi::GRBfreeenv(self.env) };
    self.env = null_mut();
  }
}

fn get_error_msg_env(env: *mut ffi::GRBenv) -> String {
  unsafe {
    CStr::from_ptr(ffi::GRBgeterrormsg(env)).to_string_lossy().into_owned()
  }
}

pub struct Model<'a> {
  model: *mut ffi::GRBmodel,
  env: &'a Env,
}

impl<'a> Model<'a> {
  pub fn new(env: &'a Env) -> Result<Model<'a>> {
    let mut model: *mut ffi::GRBmodel = null_mut();
    let error = unsafe {
      ffi::GRBnewmodel(env.env,
                       &mut model,
                       null_mut(),
                       0,
                       null_mut(),
                       null_mut(),
                       null_mut(),
                       null_mut(),
                       null_mut())
    };
    if error != 0 {
      return Err(Error::FromAPI(env.get_error_msg(), error));
    }
    Ok(Model {
      model: model,
      env: env,
    })
  }

  fn update(&mut self) -> Result<()> {
    Ok(())
  }

  pub fn optimize(&mut self) -> Result<()> {
    try!(self.update());

    let error = unsafe { ffi::GRBoptimize(self.model) };
    if error != 0 {
      return Err(Error::FromAPI(self.get_error_msg(), error));
    }

    Ok(())
  }

  fn get_error_msg(&self) -> String {
    self.env.get_error_msg()
  }

  pub fn get_int(&self, attr: IntAttr) -> Result<i64> {
    let attr = try!(CString::new(format!("{:?}", attr))
      .map_err(|e| Error::NulError(e)));
    let mut value: ffi::c_int = 0;
    let error =
      unsafe { ffi::GRBgetintattr(self.model, attr.as_ptr(), &mut value) };
    if error != 0 {
      return Err(Error::FromAPI(self.get_error_msg(), error));
    }
    Ok(value as i64)
  }
}

impl<'a> Drop for Model<'a> {
  fn drop(&mut self) {
    unsafe { ffi::GRBfreemodel(self.model) };
    self.model = null_mut();
  }
}
<commit_msg>extract conversion function between char const* and String<commit_after>extern crate gurobi_sys as ffi;

use std::ptr::null_mut;
use std::ffi::{CStr, CString};

#[derive(Debug)]
pub enum IntAttr {
  // {{{
  NumConstrs,
  NumVars,
  NumSOS,
  NumQConstrs,
  NumNZs,
  NumQNZs,
  NumQCNZs,
  NumIntVars,
  NumBinVars,
  NumPWLObjVars,
  ModelSense,
  IsMIP,
  IsQP,
  IsQCP,
  Status,
  SolCount,
  BarIterCount,
  VBasis,
  CBasis,
  PWLObjCvx,
  BranchPriority,
  VarPreStat,
  BoundVioIndex,
  BoundSVioIndex,
  ConstrVioIndex,
  ConstrSVioIndex,
  ConstrResidualIndex,
  ConstrSResidualIndex,
  DualVioIndex,
  DualSVioIndex,
  DualResidualIndex,
  DualSResidualIndex,
  ComplVioIndex,
  IntVioIndex,
  IISMinimal,
  IISLB,
  IISUB,
  IISConstr,
  IISSOS,
  IISQConstr,
  TuneResultCount,
  Lazy,
  VarHintPri,
} // }}}

/// represents error information which called the API.
#[derive(Debug)]
pub enum Error {
  /// This function has yet implemented
  NotImplemented,
  /// An exception returned from Gurobi C API
  FromAPI(String, ffi::c_int),
  /// see https://doc.rust-lang.org/std/ffi/struct.NulError.html
  NulError(std::ffi::NulError),
}

pub type Result<T> = std::result::Result<T, Error>;

/// Gurobi environment object
pub struct Env {
  env: *mut ffi::GRBenv,
}

impl Env {
  /// create an empty environment with log file
  pub fn new(logfilename: &str) -> Result<Env> {
    let logfilename = try!(CString::new(logfilename)
      .map_err(|e| Error::NulError(e)));
    let mut env: *mut ffi::GRBenv = null_mut();
    let error = unsafe { ffi::GRBloadenv(&mut env, logfilename.as_ptr()) };
    if error != 0 {
      return Err(Error::FromAPI(get_error_msg_env(env), error));
    }
    Ok(Env { env: env })
  }

  fn get_error_msg(&self) -> String {
    get_error_msg_env(self.env)
  }
}

impl Drop for Env {
  fn drop(&mut self) {
    unsafe { ffi::GRBfreeenv(self.env) };
    self.env = null_mut();
  }
}

fn get_error_msg_env(env: *mut ffi::GRBenv) -> String {
  unsafe { from_c_str(ffi::GRBgeterrormsg(env)) }
}

fn make_c_str(s: &str) -> Result<*const ffi::c_schar> {
  let cstr = try!(CString::new(s).map_err(|e| Error::NulError(e)));
  Ok(cstr.as_ptr())
}

fn from_c_str(s: *const ffi::c_schar) -> String {
  unsafe { CStr::from_ptr(s).to_string_lossy().into_owned() }
}

pub struct Model<'a> {
  model: *mut ffi::GRBmodel,
  env: &'a Env,
}

impl<'a> Model<'a> {
  pub fn new(env: &'a Env) -> Result<Model<'a>> {
    let mut model: *mut ffi::GRBmodel = null_mut();
    let error = unsafe {
      ffi::GRBnewmodel(env.env,
                       &mut model,
                       null_mut(),
                       0,
                       null_mut(),
                       null_mut(),
                       null_mut(),
                       null_mut(),
                       null_mut())
    };
    if error != 0 {
      return Err(Error::FromAPI(env.get_error_msg(), error));
    }
    Ok(Model {
      model: model,
      env: env,
    })
  }

  fn update(&mut self) -> Result<()> {
    Ok(())
  }

  pub fn optimize(&mut self) -> Result<()> {
    try!(self.update());

    let error = unsafe { ffi::GRBoptimize(self.model) };
    if error != 0 {
      return Err(Error::FromAPI(self.get_error_msg(), error));
    }

    Ok(())
  }

  fn get_error_msg(&self) -> String {
    self.env.get_error_msg()
  }

  pub fn get_int(&self, attr: IntAttr) -> Result<i64> {
    let mut value: ffi::c_int = 0;
    let error = unsafe {
      ffi::GRBgetintattr(self.model,
                         try!(make_c_str(format!("{:?}", attr).as_str())),
                         &mut value)
    };
    if error != 0 {
      return Err(Error::FromAPI(self.get_error_msg(), error));
    }
    Ok(value as i64)
  }
}

impl<'a> Drop for Model<'a> {
  fn drop(&mut self) {
    unsafe { ffi::GRBfreemodel(self.model) };
    self.model = null_mut();
  }
}
<|endoftext|>


<commit_before>// 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.

#![feature(simd)]
#![feature(step_by)]
#![feature(convert)]
#![cfg_attr(test, feature(test))]

extern crate rand;
extern crate rustc_serialize as serialize;
extern crate time;
#[cfg(test)] extern crate test;
extern crate libc;

pub mod aead;
pub mod aes;
pub mod aes_gcm;
pub mod aessafe;
pub mod bcrypt;
pub mod bcrypt_pbkdf;
pub mod blake2b;
pub mod blockmodes;
pub mod blowfish;
pub mod buffer;
pub mod chacha20;
pub mod chacha20poly1305;
mod cryptoutil;
pub mod curve25519;
pub mod digest;
pub mod ed25519;
pub mod fortuna;
pub mod ghash;
pub mod hc128;
pub mod hmac;
pub mod hkdf;
pub mod mac;
pub mod md5;
pub mod pbkdf2;
pub mod poly1305;
pub mod rc4;
pub mod ripemd160;
pub mod salsa20;
pub mod scrypt;
pub mod sha1;
pub mod sha2;
mod simd;
pub mod sosemanuk;
pub mod symmetriccipher;
pub mod util;
pub mod whirlpool;

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod aesni;
<commit_msg>Remove unecessary #![feature(convert)]<commit_after>// 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.

#![feature(simd)]
#![feature(step_by)]
#![cfg_attr(test, feature(test))]

extern crate rand;
extern crate rustc_serialize as serialize;
extern crate time;
#[cfg(test)] extern crate test;
extern crate libc;

pub mod aead;
pub mod aes;
pub mod aes_gcm;
pub mod aessafe;
pub mod bcrypt;
pub mod bcrypt_pbkdf;
pub mod blake2b;
pub mod blockmodes;
pub mod blowfish;
pub mod buffer;
pub mod chacha20;
pub mod chacha20poly1305;
mod cryptoutil;
pub mod curve25519;
pub mod digest;
pub mod ed25519;
pub mod fortuna;
pub mod ghash;
pub mod hc128;
pub mod hmac;
pub mod hkdf;
pub mod mac;
pub mod md5;
pub mod pbkdf2;
pub mod poly1305;
pub mod rc4;
pub mod ripemd160;
pub mod salsa20;
pub mod scrypt;
pub mod sha1;
pub mod sha2;
mod simd;
pub mod sosemanuk;
pub mod symmetriccipher;
pub mod util;
pub mod whirlpool;

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod aesni;
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use libimagstore::store::Store;
use libimagerror::trace::trace_error;
use std::error::Error;
use std::ops::Deref;
use std::ops::DerefMut;

use ruru::{Class, Object, AnyObject, Boolean, RString, VM, Hash, NilClass, VerifiedObject};

use ruby_utils::IntoToml;
use toml_utils::IntoRuby;
use util::Wrap;
use util::Unwrap;

use storeid::RStoreId;
use entry::RFileLockEntry;
use cache::StoreHandle;

wrappable_struct!(StoreHandle, StoreWrapper, STORE_WRAPPER);
class!(RStore);
impl_wrap!(StoreHandle, STORE_WRAPPER);
impl_unwrap!(RStore, StoreHandle, STORE_WRAPPER);
impl_verified_object!(RStore);

macro_rules! call_on_store_by_handle {
    {
        $store_handle:ident named $name:ident inside $operation:block
    }=> {{
        call_on_store_by_handle! {
            $store_handle
            named $name
            inside $operation
            on fail return NilClass::new().to_any_object()
        }
    }};

    {
        $store_handle:ident named $name:ident inside $operation:block on fail return $ex:expr
    } => {{
        use cache::RUBY_STORE_CACHE;

        let arc = RUBY_STORE_CACHE.clone();
        {
            let lock = arc.lock();
            match lock {
                Ok(mut hm) => {
                    match hm.get($store_handle) {
                        Some($name) => { $operation },
                        None => {
                            VM::raise(Class::from_existing("RuntimeError"),
                                    "Tried to operate on non-existing object");
                            $ex
                        }
                    }
                },
                Err(e) => {
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                    $ex
                }
            }
        }
    }};
}

macro_rules! call_on_store {
    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        $fle_name:ident <- fetch $fle_handle_name:ident
        operation $operation:block
    } => {
        call_on_store! {
            $store_name <- $itself wrapped inside $wrapper,
            $fle_name <- fetch $fle_handle_name,
            operation $operation,
            on fail return NilClass::new()
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        $fle_name:ident <- fetch $fle_handle_name:ident,
        operation $operation:block,
        on fail return $fail_expr:expr
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! {
            handle named $store_name inside {
                let $fle_name = match $store_name.get($fle_handle_name) {
                    Ok(Some(fle)) => fle,
                    Ok(None) => {
                        VM::raise(Class::from_existing("RuntimeError"), "Obj does not exist");
                        return $fail_expr
                    },
                    Err(e) => {
                        VM::raise(Class::from_existing("RuntimeError"), e.description());
                        return $fail_expr
                    },
                };
                $operation
            }
            on fail return $fail_expr
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        operation $operation:block,
        on fail return $fail_expr:expr
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! {
            handle named $store_name inside $operation on fail return $fail_expr
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        operation $block
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! { handle named $name inside $operation }
    };
}

methods!(
    RStore,
    itself,

    // Create an FileLockEntry in the store
    //
    // # Returns:
    //
    // On success: A RFileLockEntry
    // On failure: Nil
    // On error: Nil + Exception
    //
    fn create(id: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Retrieve an FileLockEntry from the store
    //
    // # Returns:
    //
    // On success: A RFileLockEntry
    // On error: Nil + Exception
    //
    fn retrieve(id: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Get an FileLockEntry from the store
    //
    // # Returns:
    //
    // On success, if there is some: A RFileLockEntry
    // On success, if there is none: Nil
    // On error: Nil + Exception
    //
    fn get(sid: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Get all FileLockEntry of a module from the store
    //
    // # Returns:
    //
    // On success: A Array[RFileLockEntry]
    // On error: Nil + Exception
    //
    fn retrieve_for_module(name: RString) -> AnyObject {
        unimplemented!()
    }

    // Update a FileLockEntry in the store
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn update(fle: RFileLockEntry) -> NilClass {
        unimplemented!()
    }

    // Delete a FileLockEntry from the store
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn delete(sid: RStoreId) -> NilClass {
        unimplemented!()
    }

    // Save a FileLockEntry in a new path inside the store, keep the RFileLockEntry
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn save_to(fle: RFileLockEntry, sid: RStoreId) -> NilClass {
        let fle = typecheck!(fle).unwrap().clone();
        let sid = typecheck!(sid).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            real_fle <- fetch fle,
            operation {
                if let Err(e) = store.save_to(&real_fle, sid) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Save a FileLockEntry in a new path inside the store, move the RFileLockEntry
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn save_as(fle: RFileLockEntry, sid: RStoreId) -> NilClass {
        let fle = typecheck!(fle).unwrap().clone();
        let sid = typecheck!(sid).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            real_fle <- fetch fle,
            operation {
                if let Err(e) = store.save_as(real_fle, sid) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Move one entry in the store to another place, by its ID
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn move_by_id(old: RStoreId, nw: RStoreId) -> NilClass {
        let old = typecheck!(old).unwrap().clone();
        let nw  = typecheck!(nw).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            operation {
                if let Err(e) = store.move_by_id(old, nw) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Get the path of the store object
    //
    // # Returns:
    //
    // A RString
    //
    fn path() -> RString {
        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            operation {
                store.path()
                    .clone()
                    .to_str()
                    .map(RString::new)
                    .unwrap_or(RString::new(""))
            },
            on fail return RString::new("")
        }
    }

);

pub fn setup() {
    unimplemented!()
}
<commit_msg>impl Store::delete() interface function<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use libimagstore::store::Store;
use libimagerror::trace::trace_error;
use std::error::Error;
use std::ops::Deref;
use std::ops::DerefMut;

use ruru::{Class, Object, AnyObject, Boolean, RString, VM, Hash, NilClass, VerifiedObject};

use ruby_utils::IntoToml;
use toml_utils::IntoRuby;
use util::Wrap;
use util::Unwrap;

use storeid::RStoreId;
use entry::RFileLockEntry;
use cache::StoreHandle;

wrappable_struct!(StoreHandle, StoreWrapper, STORE_WRAPPER);
class!(RStore);
impl_wrap!(StoreHandle, STORE_WRAPPER);
impl_unwrap!(RStore, StoreHandle, STORE_WRAPPER);
impl_verified_object!(RStore);

macro_rules! call_on_store_by_handle {
    {
        $store_handle:ident named $name:ident inside $operation:block
    }=> {{
        call_on_store_by_handle! {
            $store_handle
            named $name
            inside $operation
            on fail return NilClass::new().to_any_object()
        }
    }};

    {
        $store_handle:ident named $name:ident inside $operation:block on fail return $ex:expr
    } => {{
        use cache::RUBY_STORE_CACHE;

        let arc = RUBY_STORE_CACHE.clone();
        {
            let lock = arc.lock();
            match lock {
                Ok(mut hm) => {
                    match hm.get($store_handle) {
                        Some($name) => { $operation },
                        None => {
                            VM::raise(Class::from_existing("RuntimeError"),
                                    "Tried to operate on non-existing object");
                            $ex
                        }
                    }
                },
                Err(e) => {
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                    $ex
                }
            }
        }
    }};
}

macro_rules! call_on_store {
    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        $fle_name:ident <- fetch $fle_handle_name:ident
        operation $operation:block
    } => {
        call_on_store! {
            $store_name <- $itself wrapped inside $wrapper,
            $fle_name <- fetch $fle_handle_name,
            operation $operation,
            on fail return NilClass::new()
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        $fle_name:ident <- fetch $fle_handle_name:ident,
        operation $operation:block,
        on fail return $fail_expr:expr
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! {
            handle named $store_name inside {
                let $fle_name = match $store_name.get($fle_handle_name) {
                    Ok(Some(fle)) => fle,
                    Ok(None) => {
                        VM::raise(Class::from_existing("RuntimeError"), "Obj does not exist");
                        return $fail_expr
                    },
                    Err(e) => {
                        VM::raise(Class::from_existing("RuntimeError"), e.description());
                        return $fail_expr
                    },
                };
                $operation
            }
            on fail return $fail_expr
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        operation $operation:block,
        on fail return $fail_expr:expr
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! {
            handle named $store_name inside $operation on fail return $fail_expr
        }
    };

    {
        $store_name:ident <- $itself:ident wrapped inside $wrapper:ident,
        operation $block
    } => {
        let handle = $itself.get_data(&*$wrapper);
        call_on_store_by_handle! { handle named $name inside $operation }
    };
}

methods!(
    RStore,
    itself,

    // Create an FileLockEntry in the store
    //
    // # Returns:
    //
    // On success: A RFileLockEntry
    // On failure: Nil
    // On error: Nil + Exception
    //
    fn create(id: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Retrieve an FileLockEntry from the store
    //
    // # Returns:
    //
    // On success: A RFileLockEntry
    // On error: Nil + Exception
    //
    fn retrieve(id: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Get an FileLockEntry from the store
    //
    // # Returns:
    //
    // On success, if there is some: A RFileLockEntry
    // On success, if there is none: Nil
    // On error: Nil + Exception
    //
    fn get(sid: RStoreId) -> AnyObject {
        unimplemented!()
    }

    // Get all FileLockEntry of a module from the store
    //
    // # Returns:
    //
    // On success: A Array[RFileLockEntry]
    // On error: Nil + Exception
    //
    fn retrieve_for_module(name: RString) -> AnyObject {
        unimplemented!()
    }

    // Update a FileLockEntry in the store
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn update(fle: RFileLockEntry) -> NilClass {
        unimplemented!()
    }

    // Delete a FileLockEntry from the store
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn delete(sid: RStoreId) -> NilClass {
        let sid = typecheck!(sid).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            operation {
                if let Err(e) = store.delete(sid) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Save a FileLockEntry in a new path inside the store, keep the RFileLockEntry
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn save_to(fle: RFileLockEntry, sid: RStoreId) -> NilClass {
        let fle = typecheck!(fle).unwrap().clone();
        let sid = typecheck!(sid).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            real_fle <- fetch fle,
            operation {
                if let Err(e) = store.save_to(&real_fle, sid) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Save a FileLockEntry in a new path inside the store, move the RFileLockEntry
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn save_as(fle: RFileLockEntry, sid: RStoreId) -> NilClass {
        let fle = typecheck!(fle).unwrap().clone();
        let sid = typecheck!(sid).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            real_fle <- fetch fle,
            operation {
                if let Err(e) = store.save_as(real_fle, sid) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Move one entry in the store to another place, by its ID
    //
    // # Returns:
    //
    // On success: Nil
    // On error: Nil + Exception
    //
    fn move_by_id(old: RStoreId, nw: RStoreId) -> NilClass {
        let old = typecheck!(old).unwrap().clone();
        let nw  = typecheck!(nw).unwrap().clone();

        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            operation {
                if let Err(e) = store.move_by_id(old, nw) {
                    trace_error(&e);
                    VM::raise(Class::from_existing("RuntimeError"), e.description());
                }
                NilClass::new()
            },
            on fail return NilClass::new()
        }
    }

    // Get the path of the store object
    //
    // # Returns:
    //
    // A RString
    //
    fn path() -> RString {
        call_on_store! {
            store <- itself wrapped inside STORE_WRAPPER,
            operation {
                store.path()
                    .clone()
                    .to_str()
                    .map(RString::new)
                    .unwrap_or(RString::new(""))
            },
            on fail return RString::new("")
        }
    }

);

pub fn setup() {
    unimplemented!()
}
<|endoftext|>


<commit_before>#![feature(no_std)]
#![no_std]

pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter};

use core::mem::size_of;

mod elf_sections;

pub unsafe fn load(address: usize) -> &'static Multiboot {
    let multiboot = &*(address as *const Multiboot);
    assert!(multiboot.has_valid_end_tag());
    multiboot
}

#[repr(C)]
pub struct Multiboot {
    pub total_size: u32,
    _reserved: u32,
    // tags
}

impl Multiboot {
    pub fn elf_sections_tag(&self) -> Option<&'static ElfSectionsTag> {
        self.get_tag(9).map(|tag| unsafe{&*(tag as *const Tag as *const ElfSectionsTag)})
    }

    fn has_valid_end_tag(&self) -> bool {
        const END_TAG: Tag = Tag{typ:0, size:8};

        let self_ptr = self as *const _;
        let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
        let end_tag = unsafe{&*(end_tag_addr as *const Tag)};

        end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
    }

    fn get_tag(&self, typ: u32) -> Option<&'static Tag> {
        self.tags().find(|tag| tag.typ == typ)
    }

    fn tags(&self) -> TagIter {
        let self_addr = self as *const _ as usize;
        let first_tag = (self_addr + size_of::<Multiboot>()) as *const Tag;
        TagIter{current: first_tag}
    }
}

#[repr(C)]
struct Tag {
    typ: u32,
    size: u32,
    // tag specific fields
}

struct TagIter {
    current: *const Tag,
}

impl Iterator for TagIter {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<&'static Tag> {
        match unsafe{&*self.current} {
            &Tag{typ:0, size:8} => None, // end tag
            tag => {
                // go to next tag
                let mut tag_addr = self.current as usize;
                tag_addr += tag.size as usize;
                tag_addr = ((tag_addr-1) & !0x7) + 0x8; //align at 8 byte
                self.current = tag_addr as *const _;

                Some(tag)
            },
        }
    }
}
<commit_msg>Use `first_tag` field to avoid size_of<commit_after>#![feature(no_std)]
#![no_std]

pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter};

mod elf_sections;

pub unsafe fn load(address: usize) -> &'static Multiboot {
    let multiboot = &*(address as *const Multiboot);
    assert!(multiboot.has_valid_end_tag());
    multiboot
}

#[repr(C)]
pub struct Multiboot {
    pub total_size: u32,
    _reserved: u32,
    first_tag: Tag,
}

impl Multiboot {
    pub fn elf_sections_tag(&self) -> Option<&'static ElfSectionsTag> {
        self.get_tag(9).map(|tag| unsafe{&*(tag as *const Tag as *const ElfSectionsTag)})
    }

    fn has_valid_end_tag(&self) -> bool {
        const END_TAG: Tag = Tag{typ:0, size:8};

        let self_ptr = self as *const _;
        let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
        let end_tag = unsafe{&*(end_tag_addr as *const Tag)};

        end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
    }

    fn get_tag(&self, typ: u32) -> Option<&'static Tag> {
        self.tags().find(|tag| tag.typ == typ)
    }

    fn tags(&self) -> TagIter {
        TagIter{current: &self.first_tag as *const _}
    }
}

#[repr(C)]
struct Tag {
    typ: u32,
    size: u32,
    // tag specific fields
}

struct TagIter {
    current: *const Tag,
}

impl Iterator for TagIter {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<&'static Tag> {
        match unsafe{&*self.current} {
            &Tag{typ:0, size:8} => None, // end tag
            tag => {
                // go to next tag
                let mut tag_addr = self.current as usize;
                tag_addr += tag.size as usize;
                tag_addr = ((tag_addr-1) & !0x7) + 0x8; //align at 8 byte
                self.current = tag_addr as *const _;

                Some(tag)
            },
        }
    }
}
<|endoftext|>


<commit_before>//! call rank and take command of slack with rust at your helm

#[macro_use]
extern crate log;
extern crate hyper;
extern crate url;
extern crate regex;
extern crate serde;
extern crate serde_json;

mod rep;

pub use rep::{Response, ResponseBuilder};
use regex::{Captures as RegexCaptures, Regex};

use hyper::Client;
use hyper::server::{Handler as HyperHandler, Request, Response as HyperResponse};
use std::collections::HashMap;
use std::io::Read;

const DEFAULT_RESPONSE: &'static [u8] =  b"ok";

fn params<R: Read>(read: &mut R) -> HashMap<String, String> {
    let mut buffer = String::new();
    read.read_to_string(&mut buffer).unwrap();
    let mut params = HashMap::new();
    for (k, v) in url::form_urlencoded::parse(buffer.as_bytes()) {
        params.insert(k, v);
    }
    params
}

pub type Captures<'a> = RegexCaptures<'a>;

/// Responds to commands after some deferred time
/// This allows command handlers to asyncronously
/// response to commands
pub trait Responder: Sync + Send {
    fn respond(&self, response: Response) -> ();
}

pub struct DefaultResponder {
    response_url: String,
}

impl Responder for DefaultResponder {
    fn respond(&self, response: Response) {
        let client = Client::new();
        let _ = client.post(&self.response_url[..])
                      .body(serde_json::to_string(&response).unwrap().as_bytes())
                      .send();
    }
}

pub struct DiscardResponder;

impl Responder for DiscardResponder {
    fn respond(&self, _: Response) {}
}

/// Handles matched commands
pub trait Handler: Sync + Send {
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response>;
}

impl<F> Handler for F
    where F: Fn(&Command, &Option<Captures>, Box<Responder>) -> Option<Response>,
          F: Send + Sync
{
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response> {
        self(cmd, caps, responder)
    }
}

pub struct TokenValidator<H: Handler + 'static> {
    handler: H,
    token: String,
}

impl<H: Handler + 'static> Handler for TokenValidator<H> {
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response> {
        if cmd.token == self.token {
            self.handler.handle(cmd, caps, responder)
        } else {
            None
        }
    }
}

/// A matcher matches commands
pub trait Matcher: Send + Sync {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool);
}

impl<F> Matcher for F
    where F: Fn(&Command) -> (Option<Captures>, bool),
          F: Send + Sync
{
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        self(cmd)
    }
}

/// A direct command matcher
///
pub struct MatchCommand(String);

impl Matcher for MatchCommand {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        (None, cmd.command == self.0)
    }
}

/// A regex pattern matcher
///
pub struct MatchRegex(Regex);

impl Matcher for MatchRegex {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        if self.0.is_match(cmd.command.as_ref()) {
            (self.0.captures(cmd.command.as_ref()), true)
        } else {
            (None, false)
        }
    }
}

/// A binding between a command handler and which commands its handles
pub struct Route {
    handler: Box<Handler>,
    matcher: Box<Matcher>,
}

///
/// A command de-multiplexor
///
#[derive(Default)]
pub struct Mux {
    routes: Vec<Box<Route>>,
}

impl Mux {
    pub fn new() -> Mux {
        Mux { ..Default::default() }
    }

    pub fn command<C, T, H>(&mut self, cmd: C, token: T, handler: H)
        where C: Into<String>,
              T: Into<String>,
              H: Handler + 'static
    {
        self.matching(MatchCommand(cmd.into()),
                      TokenValidator {
                          handler: handler,
                          token: token.into(),
                      })
    }

    pub fn matching<M, H>(&mut self, matcher: M, handler: H)
        where M: Matcher + 'static,
              H: Handler + 'static
    {
        let route = Route {
            handler: Box::new(handler),
            matcher: Box::new(matcher),
        };
        self.route(route)
    }

    ///
    pub fn route(&mut self, route: Route) {
        self.routes.push(Box::new(route));
    }

    pub fn handler<'a>(&self, cmd: &'a Command) -> Option<(Option<Captures<'a>>, &Box<Handler>)> {
        for r in self.routes.iter() {
            if let (captures, true) = r.matcher.matches(cmd) {
                return Some((captures, &r.handler));
            }
        }
        None
    }

    pub fn handle(&self, cmd: &Command) -> Option<Response> {
        // set up responder
        let responder = DefaultResponder { response_url: cmd.response_url.clone() };
        // handle cmd
        if let &Some((ref captures, handler)) = &self.handler(&cmd) {
            info!("attempting to handle cmd ${:?}", cmd);
            handler.handle(&cmd, &captures, Box::new(responder))
        } else {
            None
        }
    }
}

#[derive(Default, Debug)]
pub struct Command {
    pub token: String,
    pub team_id: String,
    pub team_domain: String,
    pub channel_id: String,
    pub channel_name: String,
    pub user_id: String,
    pub user_name: String,
    pub command: String,
    pub text: String,
    pub response_url: String,
}

impl Command {
    pub fn from_params(params: HashMap<String, String>) -> Option<Command> {
        if let (Some(token),
                Some(team_id),
                Some(team_domain),
                Some(channel_id),
                Some(channel_name),
                Some(user_id),
                Some(user_name),
                Some(command),
                Some(text),
                Some(response_url)) = (params.get("token"),
                                       params.get("team_id"),
                                       params.get("team_domain"),
                                       params.get("channel_id"),
                                       params.get("channel_name"),
                                       params.get("user_id"),
                                       params.get("user_name"),
                                       params.get("command"),
                                       params.get("text"),
                                       params.get("response_url")) {
            Some(Command {
                token: token.clone(),
                team_id: team_id.clone(),
                team_domain: team_domain.clone(),
                channel_id: channel_id.clone(),
                channel_name: channel_name.clone(),
                user_id: user_id.clone(),
                user_name: user_name.clone(),
                command: command.clone(),
                text: text.clone(),
                response_url: response_url.clone(),
            })
        } else {
            None
        }
    }
}

impl HyperHandler for Mux {
    // https://api.slack.com/slash-commands
    fn handle(&self, req: Request, res: HyperResponse) {
        let (_, _, _, _, _, mut body) = req.deconstruct();
        // parse params
        let params = params(&mut body);
        // parse cmd
        if let Some(cmd) = Command::from_params(params) {
            info!("rec cmd {:?}", cmd);
            let write = |bytes: &[u8]| {
                let _ = res.send(bytes);
            };
            if let Some(resp) = self.handle(&cmd) {
                match serde_json::to_string(&resp) {
                    Ok(payload) => write(payload.as_bytes()),
                    _ => write(DEFAULT_RESPONSE),
                };
            } else {
                write(DEFAULT_RESPONSE)
            };
        } else {
            error!("rec invalid cmd");
            let _ = res.send(DEFAULT_RESPONSE);
        }
        ()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::regex::Regex;
    use std::collections::HashMap;

    #[test]
    fn matches_commands() {
        let cmd = Command { command: "/test".to_owned(), ..Default::default() };
        let (_, matched) = MatchCommand("/test".to_owned()).matches(&cmd);
        assert!(matched)
    }

    #[test]
    fn matches_regexes() {
        let cmd = Command { command: "/test".to_owned(), ..Default::default() };
        let (_, matched) = MatchRegex(Regex::new("(test)").unwrap()).matches(&cmd);
        assert!(matched)
    }

    #[test]
    fn extracts_commands() {
        let mut params = HashMap::new();
        params.insert("token".to_owned(), "test_token".to_owned());
        params.insert("team_id".to_owned(), "test_team".to_owned());
        params.insert("team_domain".to_owned(), "test_team_domain".to_owned());
        params.insert("channel_id".to_owned(), "test_channel_id".to_owned());
        params.insert("channel_name".to_owned(), "test_channel_name".to_owned());
        params.insert("user_id".to_owned(), "test_user_id".to_owned());
        params.insert("user_name".to_owned(), "test_user_name".to_owned());
        params.insert("command".to_owned(), "test_command".to_owned());
        params.insert("text".to_owned(), "test_text".to_owned());
        params.insert("response_url".to_owned(), "test_response_url".to_owned());
        assert!(Command::from_params(params).is_some())
    }
}
<commit_msg>better test<commit_after>//! call rank and take command of slack with rust at your helm

#[macro_use]
extern crate log;
extern crate hyper;
extern crate url;
extern crate regex;
extern crate serde;
extern crate serde_json;

mod rep;

pub use rep::{Response, ResponseBuilder};
use regex::{Captures as RegexCaptures, Regex};

use hyper::Client;
use hyper::server::{Handler as HyperHandler, Request, Response as HyperResponse};
use std::collections::HashMap;
use std::io::Read;

const DEFAULT_RESPONSE: &'static [u8] =  b"ok";

fn params<R: Read>(read: &mut R) -> HashMap<String, String> {
    let mut buffer = String::new();
    read.read_to_string(&mut buffer).unwrap();
    let mut params = HashMap::new();
    for (k, v) in url::form_urlencoded::parse(buffer.as_bytes()) {
        params.insert(k, v);
    }
    params
}

pub type Captures<'a> = RegexCaptures<'a>;

/// Responds to commands after some deferred time
/// This allows command handlers to asyncronously
/// response to commands
pub trait Responder: Sync + Send {
    fn respond(&self, response: Response) -> ();
}

pub struct DefaultResponder {
    response_url: String,
}

impl Responder for DefaultResponder {
    fn respond(&self, response: Response) {
        let client = Client::new();
        let _ = client.post(&self.response_url[..])
                      .body(serde_json::to_string(&response).unwrap().as_bytes())
                      .send();
    }
}

pub struct DiscardResponder;

impl Responder for DiscardResponder {
    fn respond(&self, _: Response) {}
}

/// Handles matched commands
pub trait Handler: Sync + Send {
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response>;
}

impl<F> Handler for F
    where F: Fn(&Command, &Option<Captures>, Box<Responder>) -> Option<Response>,
          F: Send + Sync
{
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response> {
        self(cmd, caps, responder)
    }
}

pub struct TokenValidator<H: Handler + 'static> {
    handler: H,
    token: String,
}

impl<H: Handler + 'static> Handler for TokenValidator<H> {
    fn handle(&self,
              cmd: &Command,
              caps: &Option<Captures>,
              responder: Box<Responder>)
              -> Option<Response> {
        if cmd.token == self.token {
            self.handler.handle(cmd, caps, responder)
        } else {
            None
        }
    }
}

/// A matcher matches commands
pub trait Matcher: Send + Sync {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool);
}

impl<F> Matcher for F
    where F: Fn(&Command) -> (Option<Captures>, bool),
          F: Send + Sync
{
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        self(cmd)
    }
}

/// A direct command matcher
///
pub struct MatchCommand(String);

impl Matcher for MatchCommand {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        (None, cmd.command == self.0)
    }
}

/// A regex pattern matcher
///
pub struct MatchRegex(Regex);

impl Matcher for MatchRegex {
    fn matches<'a>(&self, cmd: &'a Command) -> (Option<Captures<'a>>, bool) {
        if self.0.is_match(cmd.command.as_ref()) {
            (self.0.captures(cmd.command.as_ref()), true)
        } else {
            (None, false)
        }
    }
}

/// A binding between a command handler and which commands its handles
pub struct Route {
    handler: Box<Handler>,
    matcher: Box<Matcher>,
}

///
/// A command de-multiplexor
///
#[derive(Default)]
pub struct Mux {
    routes: Vec<Box<Route>>,
}

impl Mux {
    pub fn new() -> Mux {
        Mux { ..Default::default() }
    }

    pub fn command<C, T, H>(&mut self, cmd: C, token: T, handler: H)
        where C: Into<String>,
              T: Into<String>,
              H: Handler + 'static
    {
        self.matching(MatchCommand(cmd.into()),
                      TokenValidator {
                          handler: handler,
                          token: token.into(),
                      })
    }

    pub fn matching<M, H>(&mut self, matcher: M, handler: H)
        where M: Matcher + 'static,
              H: Handler + 'static
    {
        let route = Route {
            handler: Box::new(handler),
            matcher: Box::new(matcher),
        };
        self.route(route)
    }

    ///
    pub fn route(&mut self, route: Route) {
        self.routes.push(Box::new(route));
    }

    pub fn handler<'a>(&self, cmd: &'a Command) -> Option<(Option<Captures<'a>>, &Box<Handler>)> {
        for r in self.routes.iter() {
            if let (captures, true) = r.matcher.matches(cmd) {
                return Some((captures, &r.handler));
            }
        }
        None
    }

    pub fn handle(&self, cmd: &Command) -> Option<Response> {
        // set up responder
        let responder = DefaultResponder { response_url: cmd.response_url.clone() };
        // handle cmd
        if let &Some((ref captures, handler)) = &self.handler(&cmd) {
            info!("attempting to handle cmd ${:?}", cmd);
            handler.handle(&cmd, &captures, Box::new(responder))
        } else {
            None
        }
    }
}

#[derive(Default, Debug, PartialEq)]
pub struct Command {
    pub token: String,
    pub team_id: String,
    pub team_domain: String,
    pub channel_id: String,
    pub channel_name: String,
    pub user_id: String,
    pub user_name: String,
    pub command: String,
    pub text: String,
    pub response_url: String,
}

impl Command {
    pub fn from_params(params: HashMap<String, String>) -> Option<Command> {
        if let (Some(token),
                Some(team_id),
                Some(team_domain),
                Some(channel_id),
                Some(channel_name),
                Some(user_id),
                Some(user_name),
                Some(command),
                Some(text),
                Some(response_url)) = (params.get("token"),
                                       params.get("team_id"),
                                       params.get("team_domain"),
                                       params.get("channel_id"),
                                       params.get("channel_name"),
                                       params.get("user_id"),
                                       params.get("user_name"),
                                       params.get("command"),
                                       params.get("text"),
                                       params.get("response_url")) {
            Some(Command {
                token: token.clone(),
                team_id: team_id.clone(),
                team_domain: team_domain.clone(),
                channel_id: channel_id.clone(),
                channel_name: channel_name.clone(),
                user_id: user_id.clone(),
                user_name: user_name.clone(),
                command: command.clone(),
                text: text.clone(),
                response_url: response_url.clone(),
            })
        } else {
            None
        }
    }
}

impl HyperHandler for Mux {
    // https://api.slack.com/slash-commands
    fn handle(&self, req: Request, res: HyperResponse) {
        let (_, _, _, _, _, mut body) = req.deconstruct();
        // parse params
        let params = params(&mut body);
        // parse cmd
        if let Some(cmd) = Command::from_params(params) {
            info!("rec cmd {:?}", cmd);
            let write = |bytes: &[u8]| {
                let _ = res.send(bytes);
            };
            if let Some(resp) = self.handle(&cmd) {
                match serde_json::to_string(&resp) {
                    Ok(payload) => write(payload.as_bytes()),
                    _ => write(DEFAULT_RESPONSE),
                };
            } else {
                write(DEFAULT_RESPONSE)
            };
        } else {
            error!("rec invalid cmd");
            let _ = res.send(DEFAULT_RESPONSE);
        }
        ()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::regex::Regex;
    use std::collections::HashMap;

    #[test]
    fn matches_commands() {
        let cmd = Command { command: "/test".to_owned(), ..Default::default() };
        let (_, matched) = MatchCommand("/test".to_owned()).matches(&cmd);
        assert!(matched)
    }

    #[test]
    fn matches_regexes() {
        let cmd = Command { command: "/test".to_owned(), ..Default::default() };
        let (_, matched) = MatchRegex(Regex::new("(test)").unwrap()).matches(&cmd);
        assert!(matched)
    }

    #[test]
    fn extracts_commands() {
        let mut params = HashMap::new();
        params.insert("token".to_owned(), "test_token".to_owned());
        params.insert("team_id".to_owned(), "test_team".to_owned());
        params.insert("team_domain".to_owned(), "test_team_domain".to_owned());
        params.insert("channel_id".to_owned(), "test_channel_id".to_owned());
        params.insert("channel_name".to_owned(), "test_channel_name".to_owned());
        params.insert("user_id".to_owned(), "test_user_id".to_owned());
        params.insert("user_name".to_owned(), "test_user_name".to_owned());
        params.insert("command".to_owned(), "test_command".to_owned());
        params.insert("text".to_owned(), "test_text".to_owned());
        params.insert("response_url".to_owned(), "test_response_url".to_owned());
        match Command::from_params(params) {
            Some(cmd) => assert_eq!(cmd, Command {
                token: "test_token".to_owned(),
                team_id: "test_team".to_owned(),
                team_domain: "test_team_domain".to_owned(),
                channel_id: "test_channel_id".to_owned(),
                channel_name: "test_channel_name".to_owned(),
                user_id: "test_user_id".to_owned(),
                user_name: "test_user_name".to_owned(),
                command: "test_command".to_owned(),
                text: "test_text".to_owned(),
                response_url: "test_response_url".to_owned()
            }),
            _ => assert!(false)
        }
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]

extern crate libc;

#[cfg(target_os = "android")]
#[phase(plugin, link)]
extern crate android_glue;

#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;

mod gl {
    generate_gl_bindings! {
        api: "gles2",
        profile: "core",
        version: "2.0",
        generator: "static", // TODO: global? struct?
    }
}

static mut COLOR_COUNTER: i32 = 0;

pub fn main() {
    let window = glutin::Window::new().unwrap();
    unsafe {
        window.make_current();
    };
    while !window.is_closed() {
        unsafe {
            match COLOR_COUNTER {
                0 => gl::ClearColor(0.3, 0.0, 0.0, 1.0),
                30 => gl::ClearColor(0.0, 0.3, 0.0, 1.0),
                60 => gl::ClearColor(0.0, 0.0, 0.3, 1.0),
                _ => if COLOR_COUNTER > 90 { COLOR_COUNTER = -1; }
            }
            COLOR_COUNTER += 1;
        }
        unsafe {
            assert!(gl::GetError() == 0);
        }
        unsafe {
            gl::Clear(gl::COLOR_BUFFER_BIT);
        }
        window.swap_buffers();
        let events = window.wait_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
    }
}

#[cfg(target_os = "android")]
#[no_mangle]
pub fn rust_android_main(app: *mut()) {
    android_glue::android_main2(app, proc() main());
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>gl_generator: static -> static_struct<commit_after>#![feature(phase)]

extern crate libc;

#[cfg(target_os = "android")]
#[phase(plugin, link)]
extern crate android_glue;

#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;

mod gl {
    generate_gl_bindings! {
        api: "gles2",
        profile: "core",
        version: "2.0",
        generator: "static_struct",
    }
}

static mut COLOR_COUNTER: i32 = 0;

pub fn main() {
    let window = glutin::Window::new().unwrap();
    unsafe {
        window.make_current();
    };
    let gl = gl::Gles2::load_with(|s| window.get_proc_address(s));
    while !window.is_closed() {
        unsafe {
            match COLOR_COUNTER {
                0 => gl.ClearColor(0.3, 0.0, 0.0, 1.0),
                30 => gl.ClearColor(0.0, 0.3, 0.0, 1.0),
                60 => gl.ClearColor(0.0, 0.0, 0.3, 1.0),
                _ => if COLOR_COUNTER > 90 { COLOR_COUNTER = -1; }
            }
            COLOR_COUNTER += 1;
        }
        unsafe {
            assert!(gl.GetError() == 0);
        }
        unsafe {
            gl.Clear(gl::COLOR_BUFFER_BIT);
        }
        window.swap_buffers();
        let events = window.wait_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
    }
}

#[cfg(target_os = "android")]
#[no_mangle]
pub fn rust_android_main(app: *mut()) {
    android_glue::android_main2(app, proc() main());
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>//! Units of measurement is a crate that does automatic type-safe zero-cost
//! [dimensional analysis][analysis]. You can create your own systems or use the pre-built
//! [International System of Units][si] (SI) which is based on the
//! [International System of Quantities][isq] (ISQ) and includes numerous [quantities][quantity]
//! (length, mass, time, ...) with conversion factors for even more numerous
//! [measurement units][measurement] (meter, kilometer, foot, mile, ...). No more crashing your
//! [climate orbiter][orbiter]!
//!
//! [analysis]: https://en.wikipedia.org/wiki/Dimensional_analysis
//! [si]: http://jcgm.bipm.org/vim/en/1.16.html
//! [isq]: http://jcgm.bipm.org/vim/en/1.6.html
//! [quantity]: http://jcgm.bipm.org/vim/en/1.1.html
//! [measurement]: http://jcgm.bipm.org/vim/en/1.9.html
//! [orbiter]: https://en.wikipedia.org/wiki/Mars_Climate_Orbiter

#![no_std]
#![warn(missing_docs,
    missing_debug_implementations,
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unused_import_braces,
    unused_qualifications)]

// Clippy.
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#[doc(hidden)]
pub extern crate typenum;

#[doc(hidden)]
pub mod stdlib {
    pub use core::*;
}

#[macro_use]
mod system;

#[cfg(feature = "si")]
#[macro_use]
pub mod si;
<commit_msg>Add simple example to crate documentation.<commit_after>//! Units of measurement is a crate that does automatic type-safe zero-cost
//! [dimensional analysis][analysis]. You can create your own systems or use the pre-built
//! [International System of Units][si] (SI) which is based on the
//! [International System of Quantities][isq] (ISQ) and includes numerous [quantities][quantity]
//! (length, mass, time, ...) with conversion factors for even more numerous
//! [measurement units][measurement] (meter, kilometer, foot, mile, ...). No more crashing your
//! [climate orbiter][orbiter]!
//!
//! The simple example below shows how to use quantities and units as well as how `uom` stops
//! invalid operations
//!
//! ```
//! extern crate uom;
//!
//! use uom::si::f32::*;
//! use uom::si::length::kilometer;
//! use uom::si::time::second;
//!
//! fn main() {
//! 	let length = Length::new(5.0, kilometer);
//! 	let time = Time::new(15.0, second);
//! 	let velocity = length / time;
//! 	//let error = length + time; // error[E0308]: mismatched types
//! }
//! ```
//!
//! See examples provided with the crate for more advanced usage including how to create `Quantity`
//! type aliases for a different set of base units and how to create an entirely new system.
//!
//! [analysis]: https://en.wikipedia.org/wiki/Dimensional_analysis
//! [si]: http://jcgm.bipm.org/vim/en/1.16.html
//! [isq]: http://jcgm.bipm.org/vim/en/1.6.html
//! [quantity]: http://jcgm.bipm.org/vim/en/1.1.html
//! [measurement]: http://jcgm.bipm.org/vim/en/1.9.html
//! [orbiter]: https://en.wikipedia.org/wiki/Mars_Climate_Orbiter

#![no_std]
#![warn(missing_docs,
    missing_debug_implementations,
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unused_import_braces,
    unused_qualifications)]

// Clippy.
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#[doc(hidden)]
pub extern crate typenum;

#[doc(hidden)]
pub mod stdlib {
    pub use core::*;
}

#[macro_use]
mod system;

#[cfg(feature = "si")]
#[macro_use]
pub mod si;
<|endoftext|>


<commit_before>use mul_reader;
use byte_helpers;

pub type Map = ~[Block];

pub type Block = ~[Cell];

pub struct Cell {
    graphic: u16,
    altitude: i8,
}

pub type Statics = ~[StaticLocation];

pub struct StaticLocation {
    object_id: u16,
    x: u8,
    y: u8,
    altitude: i8,
    remainder: u16
}

const BLOCK_SIZE: uint = 196;
const OFFSET: uint = 4;

pub struct MapReader {
    data_reader: io::Reader
}

impl MapReader {

    /**
     * Read a specific block from a map
     */
    fn read_block(&self, id: uint) -> Block {
        //Cycle to id * 196 + Offset
        self.data_reader.seek(((id * BLOCK_SIZE) + OFFSET) as int, io::SeekSet);
        let map_reader = self.data_reader as io::ReaderUtil;
        //Read the 64 cells
        let mut block: Block = ~[];
        //Read 64 cells
        for uint::range(0, 64) |_index| {
            block.push(Cell{
                graphic: map_reader.read_le_u16(),
                altitude: map_reader.read_i8()
            });
        }
        block
    }

    /**
     * Read the whole map!
     */
    fn read_map(&self, max_blocks: uint) -> Map {
        let mut map: Map = ~[];
        let mut index = 0;
        while index < max_blocks {
            map.push(self.read_block(index));
            index += 1;
        }
        map
    }
}

/**
 * Create a handle to a mapreader, and read out given blocks as needed
 */
pub fn MapReader(path: ~str) -> result::Result<MapReader, ~str> {
    let mul_path: path::Path = path::Path(path);
    match io::file_reader(&mul_path) {
        result::Ok(data_reader) => {
            result::Ok(MapReader {
                data_reader: data_reader
            })
        },
        result::Err(error_message) => {
            result::Err(error_message)
        }
    }
}

pub struct StaticReader {
    mul_reader: mul_reader::MulReader
}

impl StaticReader {
    fn read_block(&self, id: uint) -> option::Option<Statics> {
        match self.mul_reader.read(id) {
            option::Some(record) => {
                assert record.data.len() % 7 == 0;
                let mut statics:Statics = ~[];
                for uint::range_step(0, record.data.len(), 7) |_i| {
                    let data_source = byte_helpers::Buffer(copy record.data);
                    let object_id: u16 = byte_helpers::bytes_to_le_uint(data_source.read(2)) as u16;
                    let x: u8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as u8;
                    let y: u8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as u8;
                    let altitude: i8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as i8;
                    let remainder: u16 = byte_helpers::bytes_to_le_uint(data_source.read(2)) as u16;
                    statics.push(StaticLocation{
                        object_id: object_id,
                        x: x,
                        y: y,
                        altitude: altitude,
                        remainder: remainder
                    });
                }
                option::Some(statics)
            }
            option::None => {
                option::None
            }
        }
    }
}

pub fn StaticReader(index_path: &path::Path, mul_path: &path::Path) -> result::Result<StaticReader, ~str> {
    match mul_reader::MulReader(index_path, mul_path) {
        result::Err(message) => result::Err(message),
        result::Ok(mul_reader) => {
            result::Ok(StaticReader{
                mul_reader: mul_reader
            })
        }
    }
}
<commit_msg>Corrected Static reader to read more than just the first static!<commit_after>use mul_reader;
use byte_helpers;

pub type Map = ~[Block];

pub type Block = ~[Cell];

pub struct Cell {
    graphic: u16,
    altitude: i8,
}

pub type Statics = ~[StaticLocation];

pub struct StaticLocation {
    object_id: u16,
    x: u8,
    y: u8,
    altitude: i8,
    remainder: u16
}

const BLOCK_SIZE: uint = 196;
const OFFSET: uint = 4;

pub struct MapReader {
    data_reader: io::Reader
}

impl MapReader {

    /**
     * Read a specific block from a map
     */
    fn read_block(&self, id: uint) -> Block {
        //Cycle to id * 196 + Offset
        self.data_reader.seek(((id * BLOCK_SIZE) + OFFSET) as int, io::SeekSet);
        let map_reader = self.data_reader as io::ReaderUtil;
        //Read the 64 cells
        let mut block: Block = ~[];
        //Read 64 cells
        for uint::range(0, 64) |_index| {
            block.push(Cell{
                graphic: map_reader.read_le_u16(),
                altitude: map_reader.read_i8()
            });
        }
        block
    }

    /**
     * Read the whole map!
     */
    fn read_map(&self, max_blocks: uint) -> Map {
        let mut map: Map = ~[];
        let mut index = 0;
        while index < max_blocks {
            map.push(self.read_block(index));
            index += 1;
        }
        map
    }
}

/**
 * Create a handle to a mapreader, and read out given blocks as needed
 */
pub fn MapReader(mul_path: &path::Path) -> result::Result<MapReader, ~str> {
    match io::file_reader(mul_path) {
        result::Ok(data_reader) => {
            result::Ok(MapReader {
                data_reader: data_reader
            })
        },
        result::Err(error_message) => {
            result::Err(error_message)
        }
    }
}

pub struct StaticReader {
    mul_reader: mul_reader::MulReader
}

impl StaticReader {
    fn read_block(&self, id: uint) -> option::Option<Statics> {
        match self.mul_reader.read(id) {
            option::Some(record) => {
                assert record.data.len() % 7 == 0;
                let mut statics:Statics = ~[];
                let data_source = byte_helpers::Buffer(copy record.data);
                for uint::range_step(0, record.data.len(), 7) |_i| {
                    let object_id: u16 = byte_helpers::bytes_to_le_uint(data_source.read(2)) as u16;
                    let x: u8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as u8;
                    let y: u8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as u8;
                    let altitude: i8 = byte_helpers::bytes_to_le_uint(data_source.read(1)) as i8;
                    let remainder: u16 = byte_helpers::bytes_to_le_uint(data_source.read(2)) as u16;
                    statics.push(StaticLocation{
                        object_id: object_id,
                        x: x,
                        y: y,
                        altitude: altitude,
                        remainder: remainder
                    });
                }
                option::Some(statics)
            }
            option::None => {
                option::None
            }
        }
    }
}

pub fn StaticReader(index_path: &path::Path, mul_path: &path::Path) -> result::Result<StaticReader, ~str> {
    match mul_reader::MulReader(index_path, mul_path) {
        result::Err(message) => result::Err(message),
        result::Ok(mul_reader) => {
            result::Ok(StaticReader{
                mul_reader: mul_reader
            })
        }
    }
}
<|endoftext|>