<commit_before>extern crate android_glue;

use libc;
use std::ffi::{CString};
use std::sync::mpsc::{Receiver, channel};
use {CreationError, Event, MouseCursor};
use CreationError::OsError;
use events::ElementState::{Pressed, Released};
use events::Event::{MouseInput, MouseMoved};
use events::MouseButton::LeftMouseButton;

use std::collections::RingBuf;

use BuilderAttribs;

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
    event_rx: Receiver<android_glue::Event>,
}

pub struct MonitorID;

mod ffi;

pub fn get_available_monitors() -> RingBuf <MonitorID> {
    let mut rb = RingBuf::new();
    rb.push_back(MonitorID);
    rb
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (u32, u32) {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
pub struct HeadlessContext(i32);

#[cfg(feature = "headless")]
impl HeadlessContext {
    /// See the docs in the crate root file.
    pub fn new(_builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub unsafe fn make_current(&self) {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub fn get_proc_address(&self, _addr: &str) -> *const () {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
unsafe impl Send for HeadlessContext {}
#[cfg(feature = "headless")]
unsafe impl Sync for HeadlessContext {}

impl Window {
    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        if builder.sharing.is_some() {
            unimplemented!()
        }

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let use_gles2 = match builder.gl_version {
            Some((2, 0)) => true,
            _ => false,
        };

        let config = unsafe {
            let mut attribute_list = vec!();
            if use_gles2 {
                attribute_list.push_all(&[ffi::egl::RENDERABLE_TYPE as i32,
                                         ffi::egl::OPENGL_ES2_BIT as i32]);
            }
            attribute_list.push_all(&[ffi::egl::RED_SIZE as i32, 1]);
            attribute_list.push_all(&[ffi::egl::GREEN_SIZE as i32, 1]);
            attribute_list.push_all(&[ffi::egl::BLUE_SIZE as i32, 1]);
            attribute_list.push(ffi::egl::NONE as i32);

            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let mut context_attributes = vec!();
            if use_gles2 {
                context_attributes.push_all(&[ffi::egl::CONTEXT_CLIENT_VERSION as i32, 2]);
            }
            context_attributes.push(ffi::egl::NONE as i32);

            let context = ffi::egl::CreateContext(display, config, ptr::null(),
                                                  context_attributes.as_ptr());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        let (tx, rx) = channel();
        android_glue::add_sender(tx);

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
            event_rx: rx,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        None
    }

    pub fn set_position(&self, _x: i32, _y: i32) {
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as u32,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as u32
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: u32, _y: u32) {
    }

    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy
    }

    pub fn poll_events(&self) -> RingBuf<Event> {
        let mut events = RingBuf::new();
        loop {
            match self.event_rx.try_recv() {
                Ok(event) => match event {
                    android_glue::Event::EventDown => {
                        events.push_back(MouseInput(Pressed, LeftMouseButton));
                    },
                    android_glue::Event::EventUp => {
                        events.push_back(MouseInput(Released, LeftMouseButton));
                    },
                    android_glue::Event::EventMove(x, y) => {
                        events.push_back(MouseMoved((x as i32, y as i32)));
                    },
                },
                Err(_) => {
                    break;
                },
            }
        }
        events
    }

    pub fn wait_events(&self) -> RingBuf<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        self.poll_events()
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        let addr = CString::from_slice(addr.as_bytes()).as_slice_with_nul().as_ptr();
        unsafe {
            ffi::egl::GetProcAddress(addr) as *const ()
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }

    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    pub fn set_cursor(&self, _: MouseCursor) {
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

#[cfg(feature = "window")]
#[derive(Clone)]
pub struct WindowProxy;

impl WindowProxy {
    pub fn wakeup_event_loop(&self) {
        unimplemented!()
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::MakeCurrent(self.display, ptr::null(), ptr::null(), ptr::null());
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<commit_msg>android: Fixed depth buffer<commit_after>extern crate android_glue;

use libc;
use std::ffi::{CString};
use std::sync::mpsc::{Receiver, channel};
use {CreationError, Event, MouseCursor};
use CreationError::OsError;
use events::ElementState::{Pressed, Released};
use events::Event::{MouseInput, MouseMoved};
use events::MouseButton::LeftMouseButton;

use std::collections::RingBuf;

use BuilderAttribs;

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
    event_rx: Receiver<android_glue::Event>,
}

pub struct MonitorID;

mod ffi;

pub fn get_available_monitors() -> RingBuf <MonitorID> {
    let mut rb = RingBuf::new();
    rb.push_back(MonitorID);
    rb
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (u32, u32) {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
pub struct HeadlessContext(i32);

#[cfg(feature = "headless")]
impl HeadlessContext {
    /// See the docs in the crate root file.
    pub fn new(_builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub unsafe fn make_current(&self) {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub fn get_proc_address(&self, _addr: &str) -> *const () {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
unsafe impl Send for HeadlessContext {}
#[cfg(feature = "headless")]
unsafe impl Sync for HeadlessContext {}

impl Window {
    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        if builder.sharing.is_some() {
            unimplemented!()
        }

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let use_gles2 = match builder.gl_version {
            Some((2, 0)) => true,
            _ => false,
        };

        let config = unsafe {
            let mut attribute_list = vec!();
            if use_gles2 {
                attribute_list.push_all(&[ffi::egl::RENDERABLE_TYPE as i32,
                                         ffi::egl::OPENGL_ES2_BIT as i32]);
            }
            attribute_list.push_all(&[ffi::egl::RED_SIZE as i32, 1]);
            attribute_list.push_all(&[ffi::egl::GREEN_SIZE as i32, 1]);
            attribute_list.push_all(&[ffi::egl::BLUE_SIZE as i32, 1]);
            attribute_list.push_all(&[ffi::egl::DEPTH_SIZE as i32, 1]);
            attribute_list.push(ffi::egl::NONE as i32);

            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let mut context_attributes = vec!();
            if use_gles2 {
                context_attributes.push_all(&[ffi::egl::CONTEXT_CLIENT_VERSION as i32, 2]);
            }
            context_attributes.push(ffi::egl::NONE as i32);

            let context = ffi::egl::CreateContext(display, config, ptr::null(),
                                                  context_attributes.as_ptr());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        let (tx, rx) = channel();
        android_glue::add_sender(tx);

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
            event_rx: rx,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        None
    }

    pub fn set_position(&self, _x: i32, _y: i32) {
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as u32,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as u32
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: u32, _y: u32) {
    }

    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy
    }

    pub fn poll_events(&self) -> RingBuf<Event> {
        let mut events = RingBuf::new();
        loop {
            match self.event_rx.try_recv() {
                Ok(event) => match event {
                    android_glue::Event::EventDown => {
                        events.push_back(MouseInput(Pressed, LeftMouseButton));
                    },
                    android_glue::Event::EventUp => {
                        events.push_back(MouseInput(Released, LeftMouseButton));
                    },
                    android_glue::Event::EventMove(x, y) => {
                        events.push_back(MouseMoved((x as i32, y as i32)));
                    },
                },
                Err(_) => {
                    break;
                },
            }
        }
        events
    }

    pub fn wait_events(&self) -> RingBuf<Event> {
        use std::time::Duration;
        use std::io::timer;
        timer::sleep(Duration::milliseconds(16));
        self.poll_events()
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        let addr = CString::from_slice(addr.as_bytes()).as_slice_with_nul().as_ptr();
        unsafe {
            ffi::egl::GetProcAddress(addr) as *const ()
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }

    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    pub fn set_cursor(&self, _: MouseCursor) {
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

#[cfg(feature = "window")]
#[derive(Clone)]
pub struct WindowProxy;

impl WindowProxy {
    pub fn wakeup_event_loop(&self) {
        unimplemented!()
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::MakeCurrent(self.display, ptr::null(), ptr::null(), ptr::null());
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<|endoftext|>


<commit_before>// advent7.rs
// circuit

#[macro_use] extern crate scan_fmt;

use std::io;
use std::collections::HashMap;

fn main() {
    let mut circuit = Circuit::new();
    loop {
        let mut input = String::new();
        let result = io::stdin().read_line(&mut input);
        match result {
            Ok(byte_count) => if byte_count == 0 { break; },
            Err(_) => {
                println!("error reading from stdin");
                break;
            }
        }
        circuit.add(&input.trim());

    }

    let result = circuit.eval("a");
    println!("Part 1 a = {}", result);

    // Part 2
    circuit.cache.clear();
    circuit.add(&format!("{} -> b", result));
    println!("Part 2 a = {}", circuit.eval("a"));
}

#[derive(Debug)]
struct Circuit {
    sym_table: HashMap<String, String>,
    cache: HashMap<String, u16>,
}

impl Circuit {
    fn new() -> Circuit {
        Circuit {sym_table: HashMap::new(), cache: HashMap::new()}
    }

    fn add(&mut self, s: &str) {
        let mut iter = s.splitn(2, " -> ");
        let val = String::from(iter.next().unwrap());
        let symbol = String::from(iter.next().unwrap());
        self.sym_table.insert(symbol, val);
    }

    fn eval(&mut self, expr: &str) -> u16 {
        // If the expression is in the cache, we're done
        if self.cache.contains_key(expr) {
            return *self.cache.get(expr).unwrap();
        }

        // Otherwise further parse the expression
        let result = if let Ok(val) = expr.parse::<u16>() {
            // expression is a u16
            return val;
        } else if self.sym_table.contains_key(expr) {
            // expression is a symbol in our table
            let symbol_val = self.sym_table.get(expr).unwrap().clone();
            self.eval(&symbol_val)
        } else if expr.contains("AND") {
            let v: Vec<&str> = expr.splitn(2, " AND ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) & self.eval(&right)
        } else if expr.contains("OR") {
            let v: Vec<&str> = expr.splitn(2, " OR ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) | self.eval(&right)
        } else if expr.contains("LSHIFT") {
            let v: Vec<&str> = expr.splitn(2, " LSHIFT ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) << self.eval(&right)
        } else if expr.contains("RSHIFT") {
            let v: Vec<&str> = expr.splitn(2, " RSHIFT ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) >> self.eval(&right)
        } else if expr.contains("NOT") {
            let right = expr.trim_left_matches("NOT ");
            !self.eval(&right)
        } else {
            panic!(format!("couldn't parse expr {}", expr))
        };

        self.cache.insert(String::from(expr), result);
        result
    }
}

#[test]
#[should_panic]
fn test_eval_fail() {
    let mut circuit = Circuit::new();
    circuit.add("123 -> x");
    circuit.add("456 -> y");
    circuit.add("x AND y -> d");
    circuit.add("x OR y -> e");
    circuit.add("x LSHIFT 2 -> f");
    circuit.add("y RSHIFT 2 -> g");
    circuit.add("NOT x -> h");
    circuit.add("NOT y -> i");

    circuit.eval("xyzzy");
}

#[test]
fn test_eval() {
    let mut circuit = Circuit::new();
    circuit.add("123 -> x");
    circuit.add("456 -> y");
    circuit.add("x AND y -> d");
    circuit.add("x OR y -> e");
    circuit.add("x LSHIFT 2 -> f");
    circuit.add("y RSHIFT 2 -> g");
    circuit.add("NOT x -> h");
    circuit.add("NOT y -> i");

    assert_eq!(123, circuit.eval("x"));
    assert_eq!(456, circuit.eval("y"));
    assert_eq!(72, circuit.eval("d"));
    assert_eq!(507, circuit.eval("e"));
    assert_eq!(492, circuit.eval("f"));
    assert_eq!(114, circuit.eval("g"));
    assert_eq!(65412, circuit.eval("h"));
    assert_eq!(65079, circuit.eval("i"));
}

<commit_msg>remove unneeded extern<commit_after>// advent7.rs
// circuit

use std::io;
use std::collections::HashMap;

fn main() {
    let mut circuit = Circuit::new();
    loop {
        let mut input = String::new();
        let result = io::stdin().read_line(&mut input);
        match result {
            Ok(byte_count) => if byte_count == 0 { break; },
            Err(_) => {
                println!("error reading from stdin");
                break;
            }
        }
        circuit.add(&input.trim());
    }

    let result = circuit.eval("a");
    println!("Part 1 a = {}", result);

    // Part 2
    circuit.cache.clear();
    circuit.add(&format!("{} -> b", result));
    println!("Part 2 a = {}", circuit.eval("a"));
}

#[derive(Debug)]
struct Circuit {
    sym_table: HashMap<String, String>,
    cache: HashMap<String, u16>,
}

impl Circuit {
    fn new() -> Circuit {
        Circuit {sym_table: HashMap::new(), cache: HashMap::new()}
    }

    fn add(&mut self, s: &str) {
        let mut iter = s.splitn(2, " -> ");
        let val = String::from(iter.next().unwrap());
        let symbol = String::from(iter.next().unwrap());
        self.sym_table.insert(symbol, val);
    }

    fn eval(&mut self, expr: &str) -> u16 {
        // If the expression is in the cache, we're done
        if self.cache.contains_key(expr) {
            return *self.cache.get(expr).unwrap();
        }

        // Otherwise further parse the expression
        let result = if let Ok(val) = expr.parse::<u16>() {
            // expression is a u16
            return val;
        } else if self.sym_table.contains_key(expr) {
            // expression is a symbol in our table
            let symbol_val = self.sym_table.get(expr).unwrap().clone();
            self.eval(&symbol_val)
        } else if expr.contains("AND") {
            let v: Vec<&str> = expr.splitn(2, " AND ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) & self.eval(&right)
        } else if expr.contains("OR") {
            let v: Vec<&str> = expr.splitn(2, " OR ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) | self.eval(&right)
        } else if expr.contains("LSHIFT") {
            let v: Vec<&str> = expr.splitn(2, " LSHIFT ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) << self.eval(&right)
        } else if expr.contains("RSHIFT") {
            let v: Vec<&str> = expr.splitn(2, " RSHIFT ").collect();
            let (left, right) = (v[0], v[1]);
            self.eval(&left) >> self.eval(&right)
        } else if expr.contains("NOT") {
            let right = expr.trim_left_matches("NOT ");
            !self.eval(&right)
        } else {
            panic!(format!("couldn't parse expr {}", expr))
        };

        self.cache.insert(String::from(expr), result);
        result
    }
}

#[test]
#[should_panic]
fn test_eval_fail() {
    let mut circuit = Circuit::new();
    circuit.add("123 -> x");
    circuit.add("456 -> y");
    circuit.add("x AND y -> d");
    circuit.add("x OR y -> e");
    circuit.add("x LSHIFT 2 -> f");
    circuit.add("y RSHIFT 2 -> g");
    circuit.add("NOT x -> h");
    circuit.add("NOT y -> i");

    circuit.eval("xyzzy");
}

#[test]
fn test_eval() {
    let mut circuit = Circuit::new();
    circuit.add("123 -> x");
    circuit.add("456 -> y");
    circuit.add("x AND y -> d");
    circuit.add("x OR y -> e");
    circuit.add("x LSHIFT 2 -> f");
    circuit.add("y RSHIFT 2 -> g");
    circuit.add("NOT x -> h");
    circuit.add("NOT y -> i");

    assert_eq!(123, circuit.eval("x"));
    assert_eq!(456, circuit.eval("y"));
    assert_eq!(72, circuit.eval("d"));
    assert_eq!(507, circuit.eval("e"));
    assert_eq!(492, circuit.eval("f"));
    assert_eq!(114, circuit.eval("g"));
    assert_eq!(65412, circuit.eval("h"));
    assert_eq!(65079, circuit.eval("i"));
}

<|endoftext|>


<commit_before>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
    static ref COUNT: usize = HASHMAP.len();
    static ref NUMBER: u32 = times_two(21);
}

fn times_two(n: u32) -> u32 { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        impl ::std::ops::Deref for $N {
            type Target = $T;
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut __static: *const $T = 0 as *const $T;
                    static mut __ONCE: Once = ONCE_INIT;
                    __ONCE.call_once(|| {
                        __static = transmute::<Box<$T>, *const $T>(Box::new(($e)));
                    });
                    let static_ref = &*__static;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<commit_msg>We need an additional dead_code disable, since Rust has gotten better about warnings recently<commit_after>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
    static ref COUNT: usize = HASHMAP.len();
    static ref NUMBER: u32 = times_two(21);
}

fn times_two(n: u32) -> u32 { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        impl ::std::ops::Deref for $N {
            type Target = $T;
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut __static: *const $T = 0 as *const $T;
                    static mut __ONCE: Once = ONCE_INIT;
                    __ONCE.call_once(|| {
                        __static = transmute::<Box<$T>, *const $T>(Box::new(($e)));
                    });
                    let static_ref = &*__static;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        #[allow(dead_code)]
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        #[allow(dead_code)]
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<|endoftext|>


<commit_before>use std::cmp;

pub fn levenshtein(a: &str, b: &str) -> i32 {
    // get length of unicode chars
    let len_a = a.chars().count();
    let len_b = b.chars().count();

    // initialize matrix
    let mut mat: Vec<Vec<i32>> = vec![vec![0; len_b + 1]; len_a + 1];
    for i in 1..(len_a + 1) {
        mat[i][0] = i as i32;
    }
    for i in 1..(len_b + 1) {
        mat[0][i] = i as i32;
    }

    // apply edit operations
    for (i, a_char) in a.chars().enumerate() {
        for (j, b_char) in b.chars().enumerate() {
            let substitution = if a_char == b_char {0} else {1};
            mat[i+1][j+1] = cmp::min(
                cmp::min(
                    mat[i][j+1] + 1,        // deletion
                    mat[i+1][j] + 1         // insertion
                ),
                mat[i][j] + substitution    // substitution
            );
        }
    }

    return mat[len_a][len_b];
}

#[cfg(test)]
mod tests {
    use super::levenshtein;

    #[test]
    fn basic() {
        assert_eq!(levenshtein("kitten", "sitting"), 3);
        assert_eq!(levenshtein("book", "back"), 2);
        assert_eq!(levenshtein("table", "dinner"), 5);
        assert_eq!(levenshtein("person", "pardon"), 2);
        assert_eq!(levenshtein("person", "persons"), 1);
    }

    #[test]
    fn equal() {
        assert_eq!(levenshtein("kitten", "kitten"), 0);
        assert_eq!(levenshtein("a", "a"), 0);
    }

    #[test]
    fn empty() {
        assert_eq!(levenshtein("book", ""), 4);
        assert_eq!(levenshtein("", "book"), 4);
        assert_eq!(levenshtein("", ""), 0);
    }

}<commit_msg>Added unicode tests<commit_after>use std::cmp;

pub fn levenshtein(a: &str, b: &str) -> i32 {
    // get length of unicode chars
    let len_a = a.chars().count();
    let len_b = b.chars().count();

    // initialize matrix
    let mut mat: Vec<Vec<i32>> = vec![vec![0; len_b + 1]; len_a + 1];
    for i in 1..(len_a + 1) {
        mat[i][0] = i as i32;
    }
    for i in 1..(len_b + 1) {
        mat[0][i] = i as i32;
    }

    // apply edit operations
    for (i, a_char) in a.chars().enumerate() {
        for (j, b_char) in b.chars().enumerate() {
            let substitution = if a_char == b_char {0} else {1};
            mat[i+1][j+1] = cmp::min(
                cmp::min(
                    mat[i][j+1] + 1,        // deletion
                    mat[i+1][j] + 1         // insertion
                ),
                mat[i][j] + substitution    // substitution
            );
        }
    }

    return mat[len_a][len_b];
}

#[cfg(test)]
mod tests {
    use super::levenshtein;

    #[test]
    fn basic() {
        assert_eq!(levenshtein("kitten", "sitting"), 3);
        assert_eq!(levenshtein("book", "back"), 2);
        assert_eq!(levenshtein("table", "dinner"), 5);
        assert_eq!(levenshtein("person", "pardon"), 2);
        assert_eq!(levenshtein("person", "persons"), 1);
    }

    #[test]
    fn equal() {
        assert_eq!(levenshtein("kitten", "kitten"), 0);
        assert_eq!(levenshtein("a", "a"), 0);
    }

    #[test]
    fn cases() {
        assert_eq!(levenshtein("Hello", "hello"), 1);
        assert_eq!(levenshtein("World", "world"), 1);
    }

    #[test]
    fn empty() {
        assert_eq!(levenshtein("book", ""), 4);
        assert_eq!(levenshtein("", "book"), 4);
        assert_eq!(levenshtein("", ""), 0);
    }

    #[test]
    fn unicode() {
        assert_eq!(levenshtein("Späße", "Spaß"), 2);
        assert_eq!(levenshtein("さようなら", "こんにちは"), 5);
        assert_eq!(levenshtein("さようなら", "さようなう"), 1);
        assert_eq!(levenshtein("こんにちは", "こんにちは abc"), 4);
        assert_eq!(levenshtein("༆༃ʘ", "༆˥ʘ"), 1);
    }

}<|endoftext|>


<commit_before>use super::color::{Color,White,Black};

pub use self::Side::{Kingside,Queenside};

#[deriving(PartialEq,Eq,Copy,Clone)]
pub enum Side {
    Kingside,
    Queenside,
}

#[deriving(PartialEq,Eq,Copy,Clone)]
pub struct CastlingData {
    w_kingside: bool,
    w_queenside: bool,
    b_kingside: bool,
    b_queenside: bool,
}
impl CastlingData {
    pub fn new() -> CastlingData {
        CastlingData {
            w_kingside: false,
            w_queenside: false,
            b_kingside: false,
            b_queenside: false,
        }
    }
    pub fn get(&self, side: Side, c: Color) -> bool {
        match (c, side) {
            (White, Kingside)  => self.w_kingside,
            (White, Queenside) => self.w_queenside,
            (Black, Kingside)  => self.b_kingside,
            (Black, Queenside) => self.b_queenside,
        }
    }
    pub fn set(self, side: Side, c: Color, val: bool) -> CastlingData {
        match (c, side) {
            (White, Kingside)  => CastlingData { w_kingside:  val, ..self },
            (White, Queenside) => CastlingData { w_queenside: val, ..self },
            (Black, Kingside)  => CastlingData { b_kingside:  val, ..self },
            (Black, Queenside) => CastlingData { b_queenside: val, ..self },
        }
    }
    pub fn set_mut(&mut self, side: Side, c: Color, val: bool) {
        match (c, side) {
            (White, Kingside)  => self.w_kingside  = val,
            (White, Queenside) => self.w_queenside = val,
            (Black, Kingside)  => self.b_kingside  = val,
            (Black, Queenside) => self.b_queenside = val,
        }
    }
}
<commit_msg>Add "require_*()" functions for castling.<commit_after>use super::color::{Color,White,Black};
use super::square::{Square,File,Rank};

pub use self::Side::{Kingside,Queenside};

#[deriving(PartialEq,Eq,Copy,Clone)]
pub enum Side {
    Kingside,
    Queenside,
}

pub fn require_empty_squares(side: Side, c: Color) -> Vec<Square> {
    match (c, side) {
        (White, Kingside)  => vec![Square::new(File(5),Rank(0)),
                                   Square::new(File(6),Rank(0))],
        (White, Queenside) => vec![Square::new(File(3),Rank(0)),
                                   Square::new(File(2),Rank(0)),
                                   Square::new(File(1),Rank(0))],
        (Black, Kingside)  => vec![Square::new(File(5),Rank(7)),
                                   Square::new(File(6),Rank(7))],
        (Black, Queenside) => vec![Square::new(File(3),Rank(7)),
                                   Square::new(File(2),Rank(7)),
                                   Square::new(File(1),Rank(7))],
    }
}

pub fn require_no_attack(side: Side, c: Color) -> Vec<Square> {
    match (c, side) {
        (White, Kingside)  => vec![Square::new(File(4),Rank(0)),
                                   Square::new(File(5),Rank(0)),
                                   Square::new(File(6),Rank(0))],
        (White, Queenside) => vec![Square::new(File(4),Rank(0)),
                                   Square::new(File(3),Rank(0)),
                                   Square::new(File(2),Rank(0))],
        (Black, Kingside)  => vec![Square::new(File(4),Rank(7)),
                                   Square::new(File(5),Rank(7)),
                                   Square::new(File(6),Rank(7))],
        (Black, Queenside) => vec![Square::new(File(4),Rank(7)),
                                   Square::new(File(3),Rank(7)),
                                   Square::new(File(2),Rank(7))],
    }
}

#[deriving(PartialEq,Eq,Copy,Clone)]
pub struct CastlingData {
    w_kingside: bool,
    w_queenside: bool,
    b_kingside: bool,
    b_queenside: bool,
}
impl CastlingData {
    pub fn new() -> CastlingData {
        CastlingData {
            w_kingside: false,
            w_queenside: false,
            b_kingside: false,
            b_queenside: false,
        }
    }
    pub fn get(&self, side: Side, c: Color) -> bool {
        match (c, side) {
            (White, Kingside)  => self.w_kingside,
            (White, Queenside) => self.w_queenside,
            (Black, Kingside)  => self.b_kingside,
            (Black, Queenside) => self.b_queenside,
        }
    }
    pub fn set(self, side: Side, c: Color, val: bool) -> CastlingData {
        match (c, side) {
            (White, Kingside)  => CastlingData { w_kingside:  val, ..self },
            (White, Queenside) => CastlingData { w_queenside: val, ..self },
            (Black, Kingside)  => CastlingData { b_kingside:  val, ..self },
            (Black, Queenside) => CastlingData { b_queenside: val, ..self },
        }
    }
    pub fn set_mut(&mut self, side: Side, c: Color, val: bool) {
        match (c, side) {
            (White, Kingside)  => self.w_kingside  = val,
            (White, Queenside) => self.w_queenside = val,
            (Black, Kingside)  => self.b_kingside  = val,
            (Black, Queenside) => self.b_queenside = val,
        }
    }
}
<|endoftext|>


<commit_before>use constant::*;
use lib::fs::*;
use std::collections::BTreeSet;
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::PathBuf;

pub fn working_dir() -> PathBuf {
    path_buf![WORKING_DIR_NAME]
}

pub fn storage_dir() -> PathBuf {
    path_buf![working_dir(), STORAGE_DIR_NAME]
}

pub fn config_file() -> PathBuf {
    path_buf![working_dir(), CONFIG_FILE_NAME]
}

pub fn ignore_file() -> PathBuf {
    path_buf![working_dir(), IGNORE_FILE_NAME]
}

pub fn working_dir_exists() -> bool {
    working_dir().is_dir()
}

pub fn storage_dir_exists() -> bool {
    storage_dir().is_dir()
}

pub fn config_file_exists() -> bool {
    config_file().is_file()
}

pub fn ignore_file_exists() -> bool {
    ignore_file().is_file()
}

pub fn create_working_dir() {
    create_essential_dir(&working_dir());
}

pub fn create_storage_dir() {
    create_essential_dir(&storage_dir());
}

pub fn create_essential_dir(path_to_dir: &PathBuf) {
    let dir_name = extract_file_name(path_to_dir);

    if path_to_dir.is_dir() {
        println!(r#"NOTICE: "{}" directory has already exist."#, dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!(r#"OK: Created "{}" directory."#, dir_name),
            Err(why) => panic!("ERROR: {}", why),
        }
    }
}

pub fn create_config_file<S: AsRef<str>>(contents: S) {
    create_setting_file(config_file(), contents);
}

pub fn create_ignore_file<S: AsRef<str>>(contents: S) {
    create_setting_file(ignore_file(), contents);
}

fn create_setting_file<S: AsRef<str>>(path_to_file: PathBuf, contents: S) {
    let file_name = extract_file_name(&path_to_file);

    if path_to_file.is_file() {
        println!(r#"NOTICE: "{}" file has already exist."#, file_name);
    } else {
        match File::create(&path_to_file) {
            Ok(mut f) => {
                println!(r#"OK: Created "{}" file."#, file_name);
                if let Err(why) = f.write(contents.as_ref().as_bytes()) {
                    panic!("ERROR: {}", why);
                }
            },
            Err(why) => panic!("ERROR: {}", why),
        }
    }
}

pub fn read_ignore_file() -> BTreeSet<String> {
    let mut f = match File::open(ignore_file()) {
        Ok(f)    => f,
        Err(why) => panic!("ERROR: {}", why),
    };
    let mut contents = String::new();
    if let Err(why) = f.read_to_string(&mut contents) {
        panic!("ERROR: {}", why);
    }
    contents
        .lines()
        .map(|l| l.trim().to_string())
        .collect::<BTreeSet<String>>()
}

pub fn delete_all_setting_files() {
    match fs::remove_dir_all(WORKING_DIR_NAME) {
        Ok(_)    => println!(r#"OK: Removed "{}" directory."#, WORKING_DIR_NAME),
        Err(why) => panic!("ERROR: {}", why),
    }
}
<commit_msg>Unpublicated create_essential_dir()<commit_after>use constant::*;
use lib::fs::*;
use std::collections::BTreeSet;
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::PathBuf;

pub fn working_dir() -> PathBuf {
    path_buf![WORKING_DIR_NAME]
}

pub fn storage_dir() -> PathBuf {
    path_buf![working_dir(), STORAGE_DIR_NAME]
}

pub fn config_file() -> PathBuf {
    path_buf![working_dir(), CONFIG_FILE_NAME]
}

pub fn ignore_file() -> PathBuf {
    path_buf![working_dir(), IGNORE_FILE_NAME]
}

pub fn working_dir_exists() -> bool {
    working_dir().is_dir()
}

pub fn storage_dir_exists() -> bool {
    storage_dir().is_dir()
}

pub fn config_file_exists() -> bool {
    config_file().is_file()
}

pub fn ignore_file_exists() -> bool {
    ignore_file().is_file()
}

pub fn create_working_dir() {
    create_essential_dir(working_dir());
}

pub fn create_storage_dir() {
    create_essential_dir(storage_dir());
}

fn create_essential_dir(path_to_dir: PathBuf) {
    let dir_name = extract_file_name(&path_to_dir);

    if path_to_dir.is_dir() {
        println!(r#"NOTICE: "{}" directory has already exist."#, dir_name);
    } else {
        match fs::create_dir(&path_to_dir) {
            Ok(_)    => println!(r#"OK: Created "{}" directory."#, dir_name),
            Err(why) => panic!("ERROR: {}", why),
        }
    }
}

pub fn create_config_file<S: AsRef<str>>(contents: S) {
    create_setting_file(config_file(), contents);
}

pub fn create_ignore_file<S: AsRef<str>>(contents: S) {
    create_setting_file(ignore_file(), contents);
}

fn create_setting_file<S: AsRef<str>>(path_to_file: PathBuf, contents: S) {
    let file_name = extract_file_name(&path_to_file);

    if path_to_file.is_file() {
        println!(r#"NOTICE: "{}" file has already exist."#, file_name);
    } else {
        match File::create(&path_to_file) {
            Ok(mut f) => {
                println!(r#"OK: Created "{}" file."#, file_name);
                if let Err(why) = f.write(contents.as_ref().as_bytes()) {
                    panic!("ERROR: {}", why);
                }
            },
            Err(why) => panic!("ERROR: {}", why),
        }
    }
}

pub fn read_ignore_file() -> BTreeSet<String> {
    let mut f = match File::open(ignore_file()) {
        Ok(f)    => f,
        Err(why) => panic!("ERROR: {}", why),
    };
    let mut contents = String::new();
    if let Err(why) = f.read_to_string(&mut contents) {
        panic!("ERROR: {}", why);
    }
    contents
        .lines()
        .map(|l| l.trim().to_string())
        .collect::<BTreeSet<String>>()
}

pub fn delete_all_setting_files() {
    match fs::remove_dir_all(WORKING_DIR_NAME) {
        Ok(_)    => println!(r#"OK: Removed "{}" directory."#, WORKING_DIR_NAME),
        Err(why) => panic!("ERROR: {}", why),
    }
}
<|endoftext|>


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

//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `downcast_ref` methods, to test if the contained value is of a given type,
//! and to get a reference to the inner value as a type. As `&mut Any`, there
//! is also the `downcast_mut` method, for getting a mutable reference to the
//! inner value. `Box<Any>` adds the `move` method, which will unwrap a
//! `Box<T>` from the object. See the extension traits (`*Ext`) for the full
//! details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Debug, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Debug;
//! use std::any::Any;
//!
//! // Logger function for any type that implements Debug.
//! fn log<T: Any + Debug>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{:?}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Any + Debug>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable(feature = "rust1", since = "1.0.0")]

use fmt;
use marker::Send;
use mem::transmute;
use option::Option::{self, Some, None};
use raw::TraitObject;
use intrinsics;
use marker::{Reflect, Sized};

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static {
    /// Gets the `TypeId` of `self`.
    #[unstable(feature = "get_type_id",
               reason = "this method will likely be replaced by an associated static",
               issue = "27745")]
    fn get_type_id(&self) -> TypeId;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect + 'static> Any for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
///////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

// Ensure that the result of e.g. joining a thread can be printed and
// hence used with `unwrap`. May eventually no longer be needed if
// dispatch works with upcasting.
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any + Send {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

impl Any {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Any+Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        Any::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        Any::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        Any::downcast_mut::<T>(self)
    }
}

///////////////////////////////////////////////////////////////////////////////
// TypeID and its methods
///////////////////////////////////////////////////////////////////////////////

/// A `TypeId` represents a globally unique identifier for a type.
///
/// Each `TypeId` is an opaque object which does not allow inspection of what's
/// inside but does allow basic operations such as cloning, comparison,
/// printing, and showing.
///
/// A `TypeId` is currently only available for types which ascribe to `'static`,
/// but this limitation may be removed in the future.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TypeId {
    t: u64,
}

impl TypeId {
    /// Returns the `TypeId` of the type this generic function has been
    /// instantiated with
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId {
        TypeId {
            t: unsafe { intrinsics::type_id::<T>() },
        }
    }
}
<commit_msg>Auto merge of #30348 - shepmaster:box-any-docs, r=steveklabnik<commit_after>// Copyright 2013-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.

//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `downcast_ref` methods, to test if the contained value is of a given type,
//! and to get a reference to the inner value as a type. As `&mut Any`, there
//! is also the `downcast_mut` method, for getting a mutable reference to the
//! inner value. `Box<Any>` adds the `downcast` method, which attempts to
//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! [`Box`]: ../boxed/struct.Box.html
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Debug, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Debug;
//! use std::any::Any;
//!
//! // Logger function for any type that implements Debug.
//! fn log<T: Any + Debug>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{:?}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Any + Debug>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable(feature = "rust1", since = "1.0.0")]

use fmt;
use marker::Send;
use mem::transmute;
use option::Option::{self, Some, None};
use raw::TraitObject;
use intrinsics;
use marker::{Reflect, Sized};

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static {
    /// Gets the `TypeId` of `self`.
    #[unstable(feature = "get_type_id",
               reason = "this method will likely be replaced by an associated static",
               issue = "27745")]
    fn get_type_id(&self) -> TypeId;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect + 'static> Any for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
///////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

// Ensure that the result of e.g. joining a thread can be printed and
// hence used with `unwrap`. May eventually no longer be needed if
// dispatch works with upcasting.
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any + Send {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

impl Any {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Any+Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        Any::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        Any::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        Any::downcast_mut::<T>(self)
    }
}

///////////////////////////////////////////////////////////////////////////////
// TypeID and its methods
///////////////////////////////////////////////////////////////////////////////

/// A `TypeId` represents a globally unique identifier for a type.
///
/// Each `TypeId` is an opaque object which does not allow inspection of what's
/// inside but does allow basic operations such as cloning, comparison,
/// printing, and showing.
///
/// A `TypeId` is currently only available for types which ascribe to `'static`,
/// but this limitation may be removed in the future.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TypeId {
    t: u64,
}

impl TypeId {
    /// Returns the `TypeId` of the type this generic function has been
    /// instantiated with
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId {
        TypeId {
            t: unsafe { intrinsics::type_id::<T>() },
        }
    }
}
<|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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! *It is not recommended to use the core library*. The stable
//! functionality of libcore is reexported from the
//! [standard library](../std/index.html). The composition of this library is
//! subject to change over time; only the interface exposed through libstd is
//! intended to be stable.
//!
//! # How to use the core library
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `fmt::Arguments`, a `&str`, and a `u32`. These three arguments dictate
//!   the panic message, the file at which panic was invoked, and the line.
//!   It is up to consumers of this core library to define this panic
//!   function; it is only required to never return.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "core"]
#![stable(feature = "core", since = "1.6.0")]
#![cfg_attr(stage0, staged_api)]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![no_core]
#![deny(missing_docs)]

#![cfg_attr(stage0, feature(rustc_attrs))]
#![cfg_attr(stage0, allow(unused_attributes))]
#![feature(allow_internal_unstable)]
#![feature(associated_type_defaults)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(custom_attribute)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(reflect)]
#![feature(unwind_attributes)]
#![cfg_attr(stage0, feature(simd))]
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
#![feature(staged_api)]
#![feature(unboxed_closures)]

#[macro_use]
mod macros;

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod nonzero;
pub mod ptr;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panicking;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;

// note: does not need to be public
mod tuple;
<commit_msg>Remove incorrect words about libcore's stability<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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! # How to use the core library
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `fmt::Arguments`, a `&str`, and a `u32`. These three arguments dictate
//!   the panic message, the file at which panic was invoked, and the line.
//!   It is up to consumers of this core library to define this panic
//!   function; it is only required to never return.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "core"]
#![stable(feature = "core", since = "1.6.0")]
#![cfg_attr(stage0, staged_api)]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![no_core]
#![deny(missing_docs)]

#![cfg_attr(stage0, feature(rustc_attrs))]
#![cfg_attr(stage0, allow(unused_attributes))]
#![feature(allow_internal_unstable)]
#![feature(associated_type_defaults)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(custom_attribute)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(reflect)]
#![feature(unwind_attributes)]
#![cfg_attr(stage0, feature(simd))]
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
#![feature(staged_api)]
#![feature(unboxed_closures)]

#[macro_use]
mod macros;

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod nonzero;
pub mod ptr;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panicking;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;

// note: does not need to be public
mod tuple;
<|endoftext|>


<commit_before>//! Checks for any invariants we expect to be true, and pages whoever is on call
//! if they are not.
//!
//! Usage:
//!     cargo run --bin monitor

#![deny(warnings)]

#[macro_use]
extern crate serde_derive;

mod on_call;

use cargo_registry::{db, schema::*, util::CargoResult};
use diesel::prelude::*;

fn main() -> CargoResult<()> {
    let conn = db::connect_now()?;

    check_stalled_background_jobs(&conn)?;
    check_spam_attack(&conn)?;
    Ok(())
}

fn check_stalled_background_jobs(conn: &PgConnection) -> CargoResult<()> {
    use cargo_registry::schema::background_jobs::dsl::*;
    use diesel::dsl::*;

    const EVENT_KEY: &str = "background_jobs";

    println!("Checking for stalled background jobs");

    let max_job_time = dotenv::var("MAX_JOB_TIME")
        .map(|s| s.parse::<i32>().unwrap())
        .unwrap_or(15);

    let stalled_job_count = background_jobs
        .filter(created_at.lt(now - max_job_time.minutes()))
        .count()
        .get_result::<i64>(conn)?;

    let event = if stalled_job_count > 0 {
        on_call::Event::Trigger {
            incident_key: Some(EVENT_KEY.into()),
            description: format!(
                "{} jobs have been in the queue for more than {} minutes",
                stalled_job_count, max_job_time
            ),
        }
    } else {
        on_call::Event::Resolve {
            incident_key: EVENT_KEY.into(),
            description: Some("No stalled background jobs".into()),
        }
    };

    log_and_trigger_event(event)?;
    Ok(())
}

fn check_spam_attack(conn: &PgConnection) -> CargoResult<()> {
    use cargo_registry::models::krate::canon_crate_name;
    use diesel::dsl::*;
    use diesel::sql_types::Bool;

    const EVENT_KEY: &str = "spam_attack";

    println!("Checking for crates indicating someone is spamming us");

    let bad_crate_names = dotenv::var("SPAM_CRATE_NAMES");
    let bad_crate_names = bad_crate_names
        .as_ref()
        .map(|s| s.split(",").collect())
        .unwrap_or(Vec::new());
    let bad_author_patterns = dotenv::var("SPAM_AUTHOR_PATTERNS");
    let bad_author_patterns = bad_author_patterns
        .as_ref()
        .map(|s| s.split(",").collect())
        .unwrap_or(Vec::new());

    let mut event_description = None;

    let bad_crate = crates::table
        .filter(canon_crate_name(crates::name).eq(any(bad_crate_names)))
        .select(crates::name)
        .first::<String>(conn)
        .optional()?;

    if let Some(bad_crate) = bad_crate {
        event_description = Some(format!("Crate named {} published", bad_crate));
    }

    let mut query = version_authors::table
        .select(version_authors::name)
        .filter(false.into_sql::<Bool>()) // Never return anything if we have no patterns
        .into_boxed();
    for author_pattern in bad_author_patterns {
        query = query.or_filter(version_authors::name.like(author_pattern));
    }
    let bad_author = query.first::<String>(conn).optional()?;

    if let Some(bad_author) = bad_author {
        event_description = Some(format!("Crate with author {} published", bad_author));
    }

    let event = if let Some(event_description) = event_description {
        on_call::Event::Trigger {
            incident_key: Some(EVENT_KEY.into()),
            description: format!("{}, possible spam attack underway", event_description,),
        }
    } else {
        on_call::Event::Resolve {
            incident_key: EVENT_KEY.into(),
            description: Some("No spam crates detected".into()),
        }
    };

    log_and_trigger_event(event)?;
    Ok(())
}

fn log_and_trigger_event(event: on_call::Event) -> CargoResult<()> {
    match event {
        on_call::Event::Trigger {
            ref description, ..
        } => println!("Paging on-call: {}", description),
        on_call::Event::Resolve {
            description: Some(ref description),
            ..
        } => println!("{}", description),
        _ => {} // noop
    }
    event.send()
}
<commit_msg>Make clippy happy<commit_after>//! Checks for any invariants we expect to be true, and pages whoever is on call
//! if they are not.
//!
//! Usage:
//!     cargo run --bin monitor

#![deny(warnings)]

#[macro_use]
extern crate serde_derive;

mod on_call;

use cargo_registry::{db, schema::*, util::CargoResult};
use diesel::prelude::*;

fn main() -> CargoResult<()> {
    let conn = db::connect_now()?;

    check_stalled_background_jobs(&conn)?;
    check_spam_attack(&conn)?;
    Ok(())
}

fn check_stalled_background_jobs(conn: &PgConnection) -> CargoResult<()> {
    use cargo_registry::schema::background_jobs::dsl::*;
    use diesel::dsl::*;

    const EVENT_KEY: &str = "background_jobs";

    println!("Checking for stalled background jobs");

    let max_job_time = dotenv::var("MAX_JOB_TIME")
        .map(|s| s.parse::<i32>().unwrap())
        .unwrap_or(15);

    let stalled_job_count = background_jobs
        .filter(created_at.lt(now - max_job_time.minutes()))
        .count()
        .get_result::<i64>(conn)?;

    let event = if stalled_job_count > 0 {
        on_call::Event::Trigger {
            incident_key: Some(EVENT_KEY.into()),
            description: format!(
                "{} jobs have been in the queue for more than {} minutes",
                stalled_job_count, max_job_time
            ),
        }
    } else {
        on_call::Event::Resolve {
            incident_key: EVENT_KEY.into(),
            description: Some("No stalled background jobs".into()),
        }
    };

    log_and_trigger_event(event)?;
    Ok(())
}

fn check_spam_attack(conn: &PgConnection) -> CargoResult<()> {
    use cargo_registry::models::krate::canon_crate_name;
    use diesel::dsl::*;
    use diesel::sql_types::Bool;

    const EVENT_KEY: &str = "spam_attack";

    println!("Checking for crates indicating someone is spamming us");

    let bad_crate_names = dotenv::var("SPAM_CRATE_NAMES");
    let bad_crate_names: Vec<_> = bad_crate_names
        .as_ref()
        .map(|s| s.split(',').collect())
        .unwrap_or_default();
    let bad_author_patterns = dotenv::var("SPAM_AUTHOR_PATTERNS");
    let bad_author_patterns: Vec<_> = bad_author_patterns
        .as_ref()
        .map(|s| s.split(',').collect())
        .unwrap_or_default();

    let mut event_description = None;

    let bad_crate = crates::table
        .filter(canon_crate_name(crates::name).eq(any(bad_crate_names)))
        .select(crates::name)
        .first::<String>(conn)
        .optional()?;

    if let Some(bad_crate) = bad_crate {
        event_description = Some(format!("Crate named {} published", bad_crate));
    }

    let mut query = version_authors::table
        .select(version_authors::name)
        .filter(false.into_sql::<Bool>()) // Never return anything if we have no patterns
        .into_boxed();
    for author_pattern in bad_author_patterns {
        query = query.or_filter(version_authors::name.like(author_pattern));
    }
    let bad_author = query.first::<String>(conn).optional()?;

    if let Some(bad_author) = bad_author {
        event_description = Some(format!("Crate with author {} published", bad_author));
    }

    let event = if let Some(event_description) = event_description {
        on_call::Event::Trigger {
            incident_key: Some(EVENT_KEY.into()),
            description: format!("{}, possible spam attack underway", event_description,),
        }
    } else {
        on_call::Event::Resolve {
            incident_key: EVENT_KEY.into(),
            description: Some("No spam crates detected".into()),
        }
    };

    log_and_trigger_event(event)?;
    Ok(())
}

fn log_and_trigger_event(event: on_call::Event) -> CargoResult<()> {
    match event {
        on_call::Event::Trigger {
            ref description, ..
        } => println!("Paging on-call: {}", description),
        on_call::Event::Resolve {
            description: Some(ref description),
            ..
        } => println!("{}", description),
        _ => {} // noop
    }
    event.send()
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for FreeBSD and NetBSD
use crate::{util_libc::sys_fill_exact, Error};
use core::ptr;

fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
    static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
    let mut len = buf.len();
    let ret = unsafe {
        libc::sysctl(
            MIB.as_ptr(),
            MIB.len() as libc::c_uint,
            buf.as_mut_ptr() as *mut _,
            &mut len,
            ptr::null(),
            0,
        )
    };
    if ret == -1 {
        -1
    } else {
        len as libc::ssize_t
    }
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    // getrandom(2) was introduces in FreeBSD 12.0 and NetBsd 10.0
    #[cfg(target_os = "freebsd")]
    {
        use crate::util_libc::Weak;
        static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
        type GetRandomFn =
            unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;

        if let Some(fptr) = GETRANDOM.ptr() {
            let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
            return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
        }
    }
    // Both FreeBSD and NetBSD will only return up to 256 bytes at a time, and
    // older NetBSD kernels will fail on longer buffers.
    for chunk in dest.chunks_mut(256) {
        sys_fill_exact(chunk, kern_arnd)?
    }
    Ok(())
}
<commit_msg>bsd_arandom: fix typo in comment (#260)<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for FreeBSD and NetBSD
use crate::{util_libc::sys_fill_exact, Error};
use core::ptr;

fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
    static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
    let mut len = buf.len();
    let ret = unsafe {
        libc::sysctl(
            MIB.as_ptr(),
            MIB.len() as libc::c_uint,
            buf.as_mut_ptr() as *mut _,
            &mut len,
            ptr::null(),
            0,
        )
    };
    if ret == -1 {
        -1
    } else {
        len as libc::ssize_t
    }
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    // getrandom(2) was introduced in FreeBSD 12.0 and NetBSD 10.0
    #[cfg(target_os = "freebsd")]
    {
        use crate::util_libc::Weak;
        static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
        type GetRandomFn =
            unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;

        if let Some(fptr) = GETRANDOM.ptr() {
            let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
            return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
        }
    }
    // Both FreeBSD and NetBSD will only return up to 256 bytes at a time, and
    // older NetBSD kernels will fail on longer buffers.
    for chunk in dest.chunks_mut(256) {
        sys_fill_exact(chunk, kern_arnd)?
    }
    Ok(())
}
<|endoftext|>


<commit_before>use std::old_io;
use std::old_io::fs::PathExtensions;
use std::collections::HashSet;

use vobject::{Component,Property,parse_component,write_component};
use email::rfc5322::Rfc5322Parser;
use uuid::Uuid;
use atomicwrites::{GenericAtomicFile,AtomicFile,DisallowOverwrite};

use cli::Configuration;

struct IndexIterator {
    linebuffer: Vec<String>
}

impl IndexIterator {
    fn new(output: &String) -> IndexIterator {
        let rv = output.split('\n').map(|x| x.to_string()).collect();
        IndexIterator {
            linebuffer: rv
        }
    }
}

impl Iterator for IndexIterator {
    type Item = IndexItem;

    fn next(&mut self) -> Option<IndexItem> {
        match self.linebuffer.pop() {
            Some(x) => Some(IndexItem::new(x)),
            None => None
        }
    }
}

struct IndexItem {
    pub email: String,
    pub name: String,
    pub filepath: Option<Path>
}

impl IndexItem {
    fn new(line: String) -> IndexItem {
        let mut parts = line.split('\t');

        IndexItem {
            email: parts.next().unwrap_or("").to_string(),
            name: parts.next().unwrap_or("").to_string(),
            filepath: match parts.next() {
                Some(x) => Some(Path::new(x)),
                None => None
            }
        }
    }
}

pub struct Contact {
    pub component: Component,
    pub path: Path
}

impl Contact {
    pub fn from_file(path: Path) -> old_io::IoResult<Contact> {
        let mut contact_file = try!(old_io::File::open(&path));
        let contact_string = try!(contact_file.read_to_string());
        let item = match parse_component(contact_string.as_slice()) {
            Ok(x) => x,
            Err(e) => return Err(old_io::IoError {
                kind: old_io::OtherIoError,
                desc: "Error while parsing contact",
                detail: Some(e)
            })
        };
        Ok(Contact { component: item, path: path })
    }

    pub fn generate(fullname: Option<&str>, email: Option<&str>, dir: &Path) -> Contact {
        let (uid, contact_path) = {
            let mut uid;
            let mut contact_path;
            loop {
                uid = Uuid::new_v4().to_simple_string();
                contact_path = dir.join(format!("{}.vcf", uid));
                if !contact_path.exists() {
                    break
                }
            };
            (uid, contact_path)
        };
        Contact { path: contact_path, component: generate_component(uid, fullname, email) }
    }

    pub fn write_create(&self) -> old_io::IoResult<()> {
        let string = write_component(&self.component);
        let af: AtomicFile = GenericAtomicFile::new(&self.path, DisallowOverwrite);

        af.write(|&: f| {
            f.write_str(string.as_slice())
        })
    }
}

fn generate_component(uid: String, fullname: Option<&str>, email: Option<&str>) -> Component {
    let mut comp = Component::new("VCARD");

    match fullname {
        Some(x) => comp.all_props_mut("FN").push(Property::new(x)),
        None => ()
    };

    match email {
        Some(x) => comp.all_props_mut("EMAIL").push(Property::new(x)),
        None => ()
    };
    comp.all_props_mut("UID").push(Property::new(uid.as_slice()));
    comp
}

pub fn index_query<'a>(config: &Configuration, query: &str) -> old_io::IoResult<IndexIterator> {
    let mut process = try!(command_from_config(config.grep_cmd.as_slice())
        .arg(query.as_slice())
        .stderr(old_io::process::InheritFd(2))
        .spawn());

    {
        let mut index_fp = try!(old_io::File::open(&config.index_path));
        let mut stdin = process.stdin.take().unwrap();
        try!(stdin.write_str(try!(index_fp.read_to_string()).as_slice()));
    }

    let exitcode = try!(process.wait());
    if !exitcode.success() {
        return Err(old_io::IoError {
            kind: old_io::OtherIoError,
            desc: "non-zero exit code",
            detail: Some(format!("grep process failed with errorcode {}", exitcode))
        });
    };

    let stream = match process.stdout.as_mut() {
        Some(x) => x,
        None => return Err(old_io::IoError {
            kind: old_io::IoUnavailable,
            desc: "Failed to get stdout from grep process.",
            detail: None
        })
    };

    let output = try!(stream.read_to_string());
    Ok(IndexIterator::new(&output))
}

/// Better than index_query if you're only interested in the filepath, as duplicate entries will be
/// removed.
pub fn file_query(config: &Configuration, query: &str) -> old_io::IoResult<HashSet<Path>> {
    let mut rv: HashSet<Path> = HashSet::new();
    rv.extend(
        try!(index_query(config, query)).filter_map(|x| x.filepath)
    );
    Ok(rv)
}

pub fn index_item_from_contact(contact: &Contact) -> old_io::IoResult<String> {
    let name = match contact.component.single_prop("FN") {
        Some(name) => name.value_as_string(),
        None => return Err(old_io::IoError {
            kind: old_io::OtherIoError,
            desc: "No name found.",
            detail: None
        })
    };

    let emails = contact.component.all_props("EMAIL");
    let mut rv = String::new();
    for email in emails.iter() {
        rv.push_str(format!("{}\t{}\t{}\n", email.value_as_string(), name, contact.path.display()).as_slice());
    };
    Ok(rv)
}

/// Return a tuple (fullname, email)
pub fn parse_from_header<'a>(s: &'a String) -> (Option<&'a str>, Option<&'a str>) {
    let mut split = s.rsplitn(1, ' ');
    let email = match split.next() {
        Some(x) => Some(x.trim_left_matches('<').trim_right_matches('>')),
        None => Some(s.as_slice())
    };
    let name = split.next();
    (name, email)
}

/// Given an email, return value of From header.
pub fn read_sender_from_email(email: &str) -> Option<String> {
    let mut parser = Rfc5322Parser::new(email);
    while !parser.eof() {
        match parser.consume_header() {
            Some(header) => {
                if header.name == "From" {
                    return header.get_value().ok()
                };
            },
            None => return None
        };
    };
    None
}

/// Write sender from given email as .vcf file to given directory.
pub fn add_contact_from_email(contact_dir: &Path, email_input: &str) -> old_io::IoResult<Contact> {
    let from_header = match read_sender_from_email(email_input) {
        Some(x) => x,
        None => return Err(old_io::IoError {
            kind: old_io::InvalidInput,
            desc: "Couldn't find From-header in email.",
            detail: None
        })
    };
    let (fullname, email) = parse_from_header(&from_header);
    let contact = Contact::generate(fullname, email, contact_dir);
    try!(contact.write_create());
    Ok(contact)
}

fn command_from_config(config_val: &str) -> old_io::process::Command {
    let mut parts = config_val.split(' ');
    let main = parts.next().unwrap();
    let rest: Vec<_> = parts.map(|x| x.to_string()).collect();
    old_io::process::Command::new(main)
        .args(rest.as_slice())
        .clone()
}
<commit_msg>Shorten error message<commit_after>use std::old_io;
use std::old_io::fs::PathExtensions;
use std::collections::HashSet;

use vobject::{Component,Property,parse_component,write_component};
use email::rfc5322::Rfc5322Parser;
use uuid::Uuid;
use atomicwrites::{GenericAtomicFile,AtomicFile,DisallowOverwrite};

use cli::Configuration;

struct IndexIterator {
    linebuffer: Vec<String>
}

impl IndexIterator {
    fn new(output: &String) -> IndexIterator {
        let rv = output.split('\n').map(|x| x.to_string()).collect();
        IndexIterator {
            linebuffer: rv
        }
    }
}

impl Iterator for IndexIterator {
    type Item = IndexItem;

    fn next(&mut self) -> Option<IndexItem> {
        match self.linebuffer.pop() {
            Some(x) => Some(IndexItem::new(x)),
            None => None
        }
    }
}

struct IndexItem {
    pub email: String,
    pub name: String,
    pub filepath: Option<Path>
}

impl IndexItem {
    fn new(line: String) -> IndexItem {
        let mut parts = line.split('\t');

        IndexItem {
            email: parts.next().unwrap_or("").to_string(),
            name: parts.next().unwrap_or("").to_string(),
            filepath: match parts.next() {
                Some(x) => Some(Path::new(x)),
                None => None
            }
        }
    }
}

pub struct Contact {
    pub component: Component,
    pub path: Path
}

impl Contact {
    pub fn from_file(path: Path) -> old_io::IoResult<Contact> {
        let mut contact_file = try!(old_io::File::open(&path));
        let contact_string = try!(contact_file.read_to_string());
        let item = match parse_component(contact_string.as_slice()) {
            Ok(x) => x,
            Err(e) => return Err(old_io::IoError {
                kind: old_io::OtherIoError,
                desc: "Error while parsing contact",
                detail: Some(e)
            })
        };
        Ok(Contact { component: item, path: path })
    }

    pub fn generate(fullname: Option<&str>, email: Option<&str>, dir: &Path) -> Contact {
        let (uid, contact_path) = {
            let mut uid;
            let mut contact_path;
            loop {
                uid = Uuid::new_v4().to_simple_string();
                contact_path = dir.join(format!("{}.vcf", uid));
                if !contact_path.exists() {
                    break
                }
            };
            (uid, contact_path)
        };
        Contact { path: contact_path, component: generate_component(uid, fullname, email) }
    }

    pub fn write_create(&self) -> old_io::IoResult<()> {
        let string = write_component(&self.component);
        let af: AtomicFile = GenericAtomicFile::new(&self.path, DisallowOverwrite);

        af.write(|&: f| {
            f.write_str(string.as_slice())
        })
    }
}

fn generate_component(uid: String, fullname: Option<&str>, email: Option<&str>) -> Component {
    let mut comp = Component::new("VCARD");

    match fullname {
        Some(x) => comp.all_props_mut("FN").push(Property::new(x)),
        None => ()
    };

    match email {
        Some(x) => comp.all_props_mut("EMAIL").push(Property::new(x)),
        None => ()
    };
    comp.all_props_mut("UID").push(Property::new(uid.as_slice()));
    comp
}

pub fn index_query<'a>(config: &Configuration, query: &str) -> old_io::IoResult<IndexIterator> {
    let mut process = try!(command_from_config(config.grep_cmd.as_slice())
        .arg(query.as_slice())
        .stderr(old_io::process::InheritFd(2))
        .spawn());

    {
        let mut index_fp = try!(old_io::File::open(&config.index_path));
        let mut stdin = process.stdin.take().unwrap();
        try!(stdin.write_str(try!(index_fp.read_to_string()).as_slice()));
    }

    let exitcode = try!(process.wait());
    if !exitcode.success() {
        return Err(old_io::IoError {
            kind: old_io::OtherIoError,
            desc: "non-zero exit code",
            detail: Some(format!("{}", exitcode))
        });
    };

    let stream = match process.stdout.as_mut() {
        Some(x) => x,
        None => return Err(old_io::IoError {
            kind: old_io::IoUnavailable,
            desc: "Failed to get stdout from grep process.",
            detail: None
        })
    };

    let output = try!(stream.read_to_string());
    Ok(IndexIterator::new(&output))
}

/// Better than index_query if you're only interested in the filepath, as duplicate entries will be
/// removed.
pub fn file_query(config: &Configuration, query: &str) -> old_io::IoResult<HashSet<Path>> {
    let mut rv: HashSet<Path> = HashSet::new();
    rv.extend(
        try!(index_query(config, query)).filter_map(|x| x.filepath)
    );
    Ok(rv)
}

pub fn index_item_from_contact(contact: &Contact) -> old_io::IoResult<String> {
    let name = match contact.component.single_prop("FN") {
        Some(name) => name.value_as_string(),
        None => return Err(old_io::IoError {
            kind: old_io::OtherIoError,
            desc: "No name found.",
            detail: None
        })
    };

    let emails = contact.component.all_props("EMAIL");
    let mut rv = String::new();
    for email in emails.iter() {
        rv.push_str(format!("{}\t{}\t{}\n", email.value_as_string(), name, contact.path.display()).as_slice());
    };
    Ok(rv)
}

/// Return a tuple (fullname, email)
pub fn parse_from_header<'a>(s: &'a String) -> (Option<&'a str>, Option<&'a str>) {
    let mut split = s.rsplitn(1, ' ');
    let email = match split.next() {
        Some(x) => Some(x.trim_left_matches('<').trim_right_matches('>')),
        None => Some(s.as_slice())
    };
    let name = split.next();
    (name, email)
}

/// Given an email, return value of From header.
pub fn read_sender_from_email(email: &str) -> Option<String> {
    let mut parser = Rfc5322Parser::new(email);
    while !parser.eof() {
        match parser.consume_header() {
            Some(header) => {
                if header.name == "From" {
                    return header.get_value().ok()
                };
            },
            None => return None
        };
    };
    None
}

/// Write sender from given email as .vcf file to given directory.
pub fn add_contact_from_email(contact_dir: &Path, email_input: &str) -> old_io::IoResult<Contact> {
    let from_header = match read_sender_from_email(email_input) {
        Some(x) => x,
        None => return Err(old_io::IoError {
            kind: old_io::InvalidInput,
            desc: "Couldn't find From-header in email.",
            detail: None
        })
    };
    let (fullname, email) = parse_from_header(&from_header);
    let contact = Contact::generate(fullname, email, contact_dir);
    try!(contact.write_create());
    Ok(contact)
}

fn command_from_config(config_val: &str) -> old_io::process::Command {
    let mut parts = config_val.split(' ');
    let main = parts.next().unwrap();
    let rest: Vec<_> = parts.map(|x| x.to_string()).collect();
    old_io::process::Command::new(main)
        .args(rest.as_slice())
        .clone()
}
<|endoftext|>