<commit_before>//! Assorted functions shared by several assists.
pub(crate) mod import_assets;

use std::ops;

use hir::HasSource;
use ide_db::RootDatabase;
use itertools::Itertools;
use syntax::{
    ast::edit::AstNodeEdit,
    ast::AttrsOwner,
    ast::NameOwner,
    ast::{self, edit, make, ArgListOwner},
    AstNode, Direction,
    SyntaxKind::*,
    SyntaxNode, TextSize, T,
};

use crate::{
    assist_config::SnippetCap,
    ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
};

pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
    extract_trivial_expression(&block)
        .filter(|expr| !expr.syntax().text().contains_char('\n'))
        .unwrap_or_else(|| block.into())
}

pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
    let has_anything_else = |thing: &SyntaxNode| -> bool {
        let mut non_trivial_children =
            block.syntax().children_with_tokens().filter(|it| match it.kind() {
                WHITESPACE | T!['{'] | T!['}'] => false,
                _ => it.as_node() != Some(thing),
            });
        non_trivial_children.next().is_some()
    };

    if let Some(expr) = block.expr() {
        if has_anything_else(expr.syntax()) {
            return None;
        }
        return Some(expr);
    }
    // Unwrap `{ continue; }`
    let (stmt,) = block.statements().next_tuple()?;
    if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
        if has_anything_else(expr_stmt.syntax()) {
            return None;
        }
        let expr = expr_stmt.expr()?;
        match expr.syntax().kind() {
            CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
            _ => (),
        }
    }
    None
}

/// This is a method with a heuristics to support test methods annotated with custom test annotations, such as
/// `#[test_case(...)]`, `#[tokio::test]` and similar.
/// Also a regular `#[test]` annotation is supported.
///
/// It may produce false positives, for example, `#[wasm_bindgen_test]` requires a different command to run the test,
/// but it's better than not to have the runnables for the tests at all.
pub fn test_related_attribute(fn_def: &ast::Fn) -> Option<ast::Attr> {
    fn_def.attrs().find_map(|attr| {
        let path = attr.path()?;
        if path.syntax().text().to_string().contains("test") {
            Some(attr)
        } else {
            None
        }
    })
}

#[derive(Copy, Clone, PartialEq)]
pub enum DefaultMethods {
    Only,
    No,
}

pub fn filter_assoc_items(
    db: &RootDatabase,
    items: &[hir::AssocItem],
    default_methods: DefaultMethods,
) -> Vec<ast::AssocItem> {
    fn has_def_name(item: &ast::AssocItem) -> bool {
        match item {
            ast::AssocItem::Fn(def) => def.name(),
            ast::AssocItem::TypeAlias(def) => def.name(),
            ast::AssocItem::Const(def) => def.name(),
            ast::AssocItem::MacroCall(_) => None,
        }
        .is_some()
    };

    items
        .iter()
        .map(|i| {
            #[allow(deprecated)]
            match i {
                hir::AssocItem::Function(i) => ast::AssocItem::Fn(i.source_old(db).value),
                hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAlias(i.source_old(db).value),
                hir::AssocItem::Const(i) => ast::AssocItem::Const(i.source_old(db).value),
            }
        })
        .filter(has_def_name)
        .filter(|it| match it {
            ast::AssocItem::Fn(def) => matches!(
                (default_methods, def.body()),
                (DefaultMethods::Only, Some(_)) | (DefaultMethods::No, None)
            ),
            _ => default_methods == DefaultMethods::No,
        })
        .collect::<Vec<_>>()
}

pub fn add_trait_assoc_items_to_impl(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    items: Vec<ast::AssocItem>,
    trait_: hir::Trait,
    impl_def: ast::Impl,
    target_scope: hir::SemanticsScope,
) -> (ast::Impl, ast::AssocItem) {
    let impl_item_list = impl_def.assoc_item_list().unwrap_or_else(make::assoc_item_list);

    let n_existing_items = impl_item_list.assoc_items().count();
    let source_scope = sema.scope_for_def(trait_);
    let ast_transform = QualifyPaths::new(&target_scope, &source_scope)
        .or(SubstituteTypeParams::for_trait_impl(&source_scope, trait_, impl_def.clone()));

    let items = items
        .into_iter()
        .map(|it| ast_transform::apply(&*ast_transform, it))
        .map(|it| match it {
            ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
            ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),
            _ => it,
        })
        .map(|it| edit::remove_attrs_and_docs(&it));

    let new_impl_item_list = impl_item_list.append_items(items);
    let new_impl_def = impl_def.with_assoc_item_list(new_impl_item_list);
    let first_new_item =
        new_impl_def.assoc_item_list().unwrap().assoc_items().nth(n_existing_items).unwrap();
    return (new_impl_def, first_new_item);

    fn add_body(fn_def: ast::Fn) -> ast::Fn {
        match fn_def.body() {
            Some(_) => fn_def,
            None => {
                let body =
                    make::block_expr(None, Some(make::expr_todo())).indent(edit::IndentLevel(1));
                fn_def.with_body(body)
            }
        }
    }
}

#[derive(Clone, Copy, Debug)]
pub(crate) enum Cursor<'a> {
    Replace(&'a SyntaxNode),
    Before(&'a SyntaxNode),
}

impl<'a> Cursor<'a> {
    fn node(self) -> &'a SyntaxNode {
        match self {
            Cursor::Replace(node) | Cursor::Before(node) => node,
        }
    }
}

pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor) -> String {
    assert!(cursor.node().ancestors().any(|it| it == *node));
    let range = cursor.node().text_range() - node.text_range().start();
    let range: ops::Range<usize> = range.into();

    let mut placeholder = cursor.node().to_string();
    escape(&mut placeholder);
    let tab_stop = match cursor {
        Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
        Cursor::Before(placeholder) => format!("$0{}", placeholder),
    };

    let mut buf = node.to_string();
    buf.replace_range(range, &tab_stop);
    return buf;

    fn escape(buf: &mut String) {
        stdx::replace(buf, '{', r"\{");
        stdx::replace(buf, '}', r"\}");
        stdx::replace(buf, '$', r"\$");
    }
}

pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
    node.children_with_tokens()
        .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
        .map(|it| it.text_range().start())
        .unwrap_or_else(|| node.text_range().start())
}

pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
    if let Some(expr) = invert_special_case(&expr) {
        return expr;
    }
    make::expr_prefix(T![!], expr)
}

fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
    match expr {
        ast::Expr::BinExpr(bin) => match bin.op_kind()? {
            ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()),
            ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
            // Parenthesize composite boolean expressions before prefixing `!`
            ast::BinOp::BooleanAnd | ast::BinOp::BooleanOr => {
                Some(make::expr_prefix(T![!], make::expr_paren(expr.clone())))
            }
            _ => None,
        },
        ast::Expr::MethodCallExpr(mce) => {
            let receiver = mce.receiver()?;
            let method = mce.name_ref()?;
            let arg_list = mce.arg_list()?;

            let method = match method.text().as_str() {
                "is_some" => "is_none",
                "is_none" => "is_some",
                "is_ok" => "is_err",
                "is_err" => "is_ok",
                _ => return None,
            };
            Some(make::expr_method_call(receiver, method, arg_list))
        }
        ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => {
            if let ast::Expr::ParenExpr(parexpr) = pe.expr()? {
                parexpr.expr()
            } else {
                pe.expr()
            }
        }
        // FIXME:
        // ast::Expr::Literal(true | false )
        _ => None,
    }
}

pub(crate) fn next_prev() -> impl Iterator<Item = Direction> {
    [Direction::Next, Direction::Prev].iter().copied()
}
<commit_msg>Handle missing source in filter_assoc_items<commit_after>//! Assorted functions shared by several assists.
pub(crate) mod import_assets;

use std::ops;

use hir::HasSource;
use ide_db::RootDatabase;
use itertools::Itertools;
use syntax::{
    ast::edit::AstNodeEdit,
    ast::AttrsOwner,
    ast::NameOwner,
    ast::{self, edit, make, ArgListOwner},
    AstNode, Direction,
    SyntaxKind::*,
    SyntaxNode, TextSize, T,
};

use crate::{
    assist_config::SnippetCap,
    ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
};

pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
    extract_trivial_expression(&block)
        .filter(|expr| !expr.syntax().text().contains_char('\n'))
        .unwrap_or_else(|| block.into())
}

pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
    let has_anything_else = |thing: &SyntaxNode| -> bool {
        let mut non_trivial_children =
            block.syntax().children_with_tokens().filter(|it| match it.kind() {
                WHITESPACE | T!['{'] | T!['}'] => false,
                _ => it.as_node() != Some(thing),
            });
        non_trivial_children.next().is_some()
    };

    if let Some(expr) = block.expr() {
        if has_anything_else(expr.syntax()) {
            return None;
        }
        return Some(expr);
    }
    // Unwrap `{ continue; }`
    let (stmt,) = block.statements().next_tuple()?;
    if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
        if has_anything_else(expr_stmt.syntax()) {
            return None;
        }
        let expr = expr_stmt.expr()?;
        match expr.syntax().kind() {
            CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
            _ => (),
        }
    }
    None
}

/// This is a method with a heuristics to support test methods annotated with custom test annotations, such as
/// `#[test_case(...)]`, `#[tokio::test]` and similar.
/// Also a regular `#[test]` annotation is supported.
///
/// It may produce false positives, for example, `#[wasm_bindgen_test]` requires a different command to run the test,
/// but it's better than not to have the runnables for the tests at all.
pub fn test_related_attribute(fn_def: &ast::Fn) -> Option<ast::Attr> {
    fn_def.attrs().find_map(|attr| {
        let path = attr.path()?;
        if path.syntax().text().to_string().contains("test") {
            Some(attr)
        } else {
            None
        }
    })
}

#[derive(Copy, Clone, PartialEq)]
pub enum DefaultMethods {
    Only,
    No,
}

pub fn filter_assoc_items(
    db: &RootDatabase,
    items: &[hir::AssocItem],
    default_methods: DefaultMethods,
) -> Vec<ast::AssocItem> {
    fn has_def_name(item: &ast::AssocItem) -> bool {
        match item {
            ast::AssocItem::Fn(def) => def.name(),
            ast::AssocItem::TypeAlias(def) => def.name(),
            ast::AssocItem::Const(def) => def.name(),
            ast::AssocItem::MacroCall(_) => None,
        }
        .is_some()
    };

    items
        .iter()
        // Note: This throws away items with no source.
        .filter_map(|i| {
            let item = match i {
                hir::AssocItem::Function(i) => ast::AssocItem::Fn(i.source(db)?.value),
                hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAlias(i.source(db)?.value),
                hir::AssocItem::Const(i) => ast::AssocItem::Const(i.source(db)?.value),
            };
            Some(item)
        })
        .filter(has_def_name)
        .filter(|it| match it {
            ast::AssocItem::Fn(def) => matches!(
                (default_methods, def.body()),
                (DefaultMethods::Only, Some(_)) | (DefaultMethods::No, None)
            ),
            _ => default_methods == DefaultMethods::No,
        })
        .collect::<Vec<_>>()
}

pub fn add_trait_assoc_items_to_impl(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    items: Vec<ast::AssocItem>,
    trait_: hir::Trait,
    impl_def: ast::Impl,
    target_scope: hir::SemanticsScope,
) -> (ast::Impl, ast::AssocItem) {
    let impl_item_list = impl_def.assoc_item_list().unwrap_or_else(make::assoc_item_list);

    let n_existing_items = impl_item_list.assoc_items().count();
    let source_scope = sema.scope_for_def(trait_);
    let ast_transform = QualifyPaths::new(&target_scope, &source_scope)
        .or(SubstituteTypeParams::for_trait_impl(&source_scope, trait_, impl_def.clone()));

    let items = items
        .into_iter()
        .map(|it| ast_transform::apply(&*ast_transform, it))
        .map(|it| match it {
            ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
            ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),
            _ => it,
        })
        .map(|it| edit::remove_attrs_and_docs(&it));

    let new_impl_item_list = impl_item_list.append_items(items);
    let new_impl_def = impl_def.with_assoc_item_list(new_impl_item_list);
    let first_new_item =
        new_impl_def.assoc_item_list().unwrap().assoc_items().nth(n_existing_items).unwrap();
    return (new_impl_def, first_new_item);

    fn add_body(fn_def: ast::Fn) -> ast::Fn {
        match fn_def.body() {
            Some(_) => fn_def,
            None => {
                let body =
                    make::block_expr(None, Some(make::expr_todo())).indent(edit::IndentLevel(1));
                fn_def.with_body(body)
            }
        }
    }
}

#[derive(Clone, Copy, Debug)]
pub(crate) enum Cursor<'a> {
    Replace(&'a SyntaxNode),
    Before(&'a SyntaxNode),
}

impl<'a> Cursor<'a> {
    fn node(self) -> &'a SyntaxNode {
        match self {
            Cursor::Replace(node) | Cursor::Before(node) => node,
        }
    }
}

pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor) -> String {
    assert!(cursor.node().ancestors().any(|it| it == *node));
    let range = cursor.node().text_range() - node.text_range().start();
    let range: ops::Range<usize> = range.into();

    let mut placeholder = cursor.node().to_string();
    escape(&mut placeholder);
    let tab_stop = match cursor {
        Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
        Cursor::Before(placeholder) => format!("$0{}", placeholder),
    };

    let mut buf = node.to_string();
    buf.replace_range(range, &tab_stop);
    return buf;

    fn escape(buf: &mut String) {
        stdx::replace(buf, '{', r"\{");
        stdx::replace(buf, '}', r"\}");
        stdx::replace(buf, '$', r"\$");
    }
}

pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
    node.children_with_tokens()
        .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
        .map(|it| it.text_range().start())
        .unwrap_or_else(|| node.text_range().start())
}

pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
    if let Some(expr) = invert_special_case(&expr) {
        return expr;
    }
    make::expr_prefix(T![!], expr)
}

fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
    match expr {
        ast::Expr::BinExpr(bin) => match bin.op_kind()? {
            ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()),
            ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
            // Parenthesize composite boolean expressions before prefixing `!`
            ast::BinOp::BooleanAnd | ast::BinOp::BooleanOr => {
                Some(make::expr_prefix(T![!], make::expr_paren(expr.clone())))
            }
            _ => None,
        },
        ast::Expr::MethodCallExpr(mce) => {
            let receiver = mce.receiver()?;
            let method = mce.name_ref()?;
            let arg_list = mce.arg_list()?;

            let method = match method.text().as_str() {
                "is_some" => "is_none",
                "is_none" => "is_some",
                "is_ok" => "is_err",
                "is_err" => "is_ok",
                _ => return None,
            };
            Some(make::expr_method_call(receiver, method, arg_list))
        }
        ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => {
            if let ast::Expr::ParenExpr(parexpr) = pe.expr()? {
                parexpr.expr()
            } else {
                pe.expr()
            }
        }
        // FIXME:
        // ast::Expr::Literal(true | false )
        _ => None,
    }
}

pub(crate) fn next_prev() -> impl Iterator<Item = Direction> {
    [Direction::Next, Direction::Prev].iter().copied()
}
<|endoftext|>


<commit_before>use clap::ArgMatches;
use std::env;
use std::process::Command;

pub fn open_shell_at_repo(args: &ArgMatches) -> Result<(), (String, i32)> {
    info!("CD to: {}", args.value_of("repository").unwrap());

    let shell = match env::var("SHELL") {
        Ok(val) => val,
        Err(e) => return Err((format!("Could not determine shell to use: {}", e), 1)),
    };

    info!("Using shell: {}", shell);
    match Command::new(shell).status() {
        Ok(exit_status) => {
            if exit_status.success() {
                Ok(())
            } else {
                Err(("Shell failed".to_string(), exit_status.code().unwrap_or(1)))
            }
        },
        Err(e) => {
            Err((format!("{}", e), 1))
        }
    }
}
<commit_msg>Give more context in the error message if the shell fails to execute<commit_after>use clap::ArgMatches;
use std::env;
use std::process::Command;

pub fn open_shell_at_repo(args: &ArgMatches) -> Result<(), (String, i32)> {
    info!("CD to: {}", args.value_of("repository").unwrap());

    let shell = match env::var("SHELL") {
        Ok(val) => val,
        Err(e) => return Err((format!("Could not determine shell to use: {}", e), 1)),
    };

    info!("Using shell: {}", shell);
    match Command::new(shell).status() {
        Ok(exit_status) => {
            if exit_status.success() {
                Ok(())
            } else {
                Err(("Shell failed".to_string(), exit_status.code().unwrap_or(1)))
            }
        },
        Err(e) => {
            Err((format!("Unable to execute shell: {}", e), 1))
        }
    }
}
<|endoftext|>


<commit_before>use ffi;
use std::os::raw::c_int;
use std::ptr;
use types::*;
use ffi::MaybeError;
use device::DeviceInfo;

/// Represents the input port of a PortMidi device.
pub struct InputPort {
    stream: *const ffi::PortMidiStream,
    device: ffi::PmDeviceId,
    buffer_size: usize,
}
impl InputPort {
    /// Construct a new `InputPort` for the given device and buffer size.
    ///
    /// If the `device` is not an input device an `Error::NotAnInputDevice` is returned.
    pub fn new(device: DeviceInfo, buffer_size: usize) -> Result<InputPort> {
        if device.is_output() {
            return Err(Error::NotAnInputDevice);
        }
        let raw_stream: *const ffi::PortMidiStream = ptr::null();
        try!(Result::from(unsafe {
            ffi::Pm_OpenInput(&raw_stream as *const *const _,
                              device.id(),
                              ptr::null(), // *inputDriverInfo, not needed for normal operation
                              buffer_size as c_int,
                              ptr::null(), // PmTimeProcPtr, a procedure that returns time in ms,
                              ptr::null()) // time_info, a pointer passed to the time procedure
        }));

        Ok(InputPort {
            stream: raw_stream,
            device: device.id(),
            buffer_size: buffer_size,
        })
    }

    /// Returns a `Vec<MidiEvent>` with at most `cnt` elements.
    /// If there was no Midi event available, `None` is returned.
    /// If PortMidi fails to read from the device an `Error::PortMidi(_)` is returned.
    pub fn read_n(&self, cnt: usize) -> Result<Option<Vec<MidiEvent>>> {
        let read_cnt = if cnt > self.buffer_size {
            self.buffer_size as c_int
        } else {
            cnt as c_int
        };
        let mut event_buffer = vec![ffi::PmEvent::default(); self.buffer_size];
        let res = unsafe { ffi::Pm_Read(self.stream, event_buffer.as_mut_ptr(), read_cnt) };
        ::std::thread::sleep_ms(20);
        match ffi::PmError::try_from(res) {
            Ok(event_cnt) => {
                let events = (0..event_cnt as usize)
                                 .map(|i| MidiEvent::from(event_buffer[i].clone()))
                                 .collect::<Vec<MidiEvent>>();
                Ok(Some(events))
            }
            err @ Err(ffi::PmError::PmNoError) => Ok(None),
            Err(err) => return Err(Error::PortMidi(err)),
        }
    }

    /// Reads a single `MidiEvent` if one is avaible.
    ///
    /// A `Result` of `None` means no event was available.
    pub fn read(&mut self) -> Result<Option<MidiEvent>> {
        match self.read_n(1) {
            Ok(Some(mut vec)) => Ok(vec.pop()),
            Ok(_) => Ok(None),
            Err(e) => Err(e),
        }
    }

    /// Polls for available Midi events.
    /// Returns `true` if there are events available, otherwise `false` is returned.
    /// If the polling fails an `Error::PortMidi(_)` is returned.
    pub fn poll(&self) -> Result<bool> {
        let pm_error = unsafe { ffi::Pm_Poll(self.stream) };
        match pm_error {
            ffi::PmError::PmNoError => Ok(false),
            ffi::PmError::PmGotData => Ok(true),
            err @ _ => Err(Error::PortMidi(err)),
        }
    }
}
impl Drop for InputPort {
    fn drop(&mut self) {
        if let Err(err) = Result::from(unsafe { ffi::Pm_Close(self.stream) }) {
            println!("{}", err);
        }
    }
}

/// Representation the output port of a PortMidi device.
pub struct OutputPort {
    stream: *const ffi::PortMidiStream,
    device: ffi::PmDeviceId,
    buffer_size: usize,
}
impl OutputPort {
    /// Construct a new `OutputPort` for the given device and buffer size.
    ///
    /// If the `device` is not an output device an `Error::NotAnOutputDevice` is returned.
    pub fn new(device: DeviceInfo, buffer_size: usize) -> Result<OutputPort> {
        if device.is_input() {
            return Err(Error::NotAnOutputDevice);
        }
        let raw_stream: *const ffi::PortMidiStream = ptr::null();
        try!(Result::from(unsafe {
            ffi::Pm_OpenOutput(&raw_stream as *const *const _,
                               device.id(),
                               ptr::null(), // *inputDriverInfo, not needed for normal operation
                               buffer_size as c_int,
                               ptr::null(), // PmTimeProcPtr, a procedure that returns time in ms,
                               ptr::null(), // time_info, a pointer passed to the time procedure
                               0) //latency
        }));

        Ok(OutputPort {
            stream: raw_stream,
            device: device.id(),
            buffer_size: buffer_size,
        })
    }

    /// Terminates outgoing messages immediately.
    ///
    /// The caller should immediately close the output port, this may
    /// result in transmission of a partial midi message. Note, not all platforms
    /// support abort.
    pub fn abort(&mut self) -> Result<()> {
        Result::from(unsafe { ffi::Pm_Abort(self.stream) })
    }

    /// Write a single `MidiEvent`
    pub fn write_event(&mut self, midi_event: MidiEvent) -> Result<()> {
        let event = midi_event.into();
        Result::from(unsafe { ffi::Pm_Write(self.stream, &event, 1) })
    }

    /// Write a single `MidiMessage`.
    /// Returns an `Error::PortMidi(_)` if something went wrong.
    pub fn write_message(&mut self, midi_message: MidiMessage) -> Result<()> {
        let message = midi_message.into();
        Result::from(unsafe { ffi::Pm_WriteShort(self.stream, 0, message) })
    }
}
impl Drop for OutputPort {
    fn drop(&mut self) {
        if let Err(err) = Result::from(unsafe { ffi::Pm_Close(self.stream) }) {
            println!("{}", err);
        }
    }
}
<commit_msg>Make `abort` private and add a note about posssible unsafety.<commit_after>use ffi;
use std::os::raw::c_int;
use std::ptr;
use types::*;
use ffi::MaybeError;
use device::DeviceInfo;

/// Represents the input port of a PortMidi device.
pub struct InputPort {
    stream: *const ffi::PortMidiStream,
    device: ffi::PmDeviceId,
    buffer_size: usize,
}
impl InputPort {
    /// Construct a new `InputPort` for the given device and buffer size.
    ///
    /// If the `device` is not an input device an `Error::NotAnInputDevice` is returned.
    pub fn new(device: DeviceInfo, buffer_size: usize) -> Result<InputPort> {
        if device.is_output() {
            return Err(Error::NotAnInputDevice);
        }
        let raw_stream: *const ffi::PortMidiStream = ptr::null();
        try!(Result::from(unsafe {
            ffi::Pm_OpenInput(&raw_stream as *const *const _,
                              device.id(),
                              ptr::null(), // *inputDriverInfo, not needed for normal operation
                              buffer_size as c_int,
                              ptr::null(), // PmTimeProcPtr, a procedure that returns time in ms,
                              ptr::null()) // time_info, a pointer passed to the time procedure
        }));

        Ok(InputPort {
            stream: raw_stream,
            device: device.id(),
            buffer_size: buffer_size,
        })
    }

    /// Returns a `Vec<MidiEvent>` with at most `cnt` elements.
    /// If there was no Midi event available, `None` is returned.
    /// If PortMidi fails to read from the device an `Error::PortMidi(_)` is returned.
    pub fn read_n(&self, cnt: usize) -> Result<Option<Vec<MidiEvent>>> {
        let read_cnt = if cnt > self.buffer_size {
            self.buffer_size as c_int
        } else {
            cnt as c_int
        };
        let mut event_buffer = vec![ffi::PmEvent::default(); self.buffer_size];
        let res = unsafe { ffi::Pm_Read(self.stream, event_buffer.as_mut_ptr(), read_cnt) };
        ::std::thread::sleep_ms(20);
        match ffi::PmError::try_from(res) {
            Ok(event_cnt) => {
                let events = (0..event_cnt as usize)
                                 .map(|i| MidiEvent::from(event_buffer[i].clone()))
                                 .collect::<Vec<MidiEvent>>();
                Ok(Some(events))
            }
            err @ Err(ffi::PmError::PmNoError) => Ok(None),
            Err(err) => return Err(Error::PortMidi(err)),
        }
    }

    /// Reads a single `MidiEvent` if one is avaible.
    ///
    /// A `Result` of `None` means no event was available.
    pub fn read(&mut self) -> Result<Option<MidiEvent>> {
        match self.read_n(1) {
            Ok(Some(mut vec)) => Ok(vec.pop()),
            Ok(_) => Ok(None),
            Err(e) => Err(e),
        }
    }

    /// Polls for available Midi events.
    /// Returns `true` if there are events available, otherwise `false` is returned.
    /// If the polling fails an `Error::PortMidi(_)` is returned.
    pub fn poll(&self) -> Result<bool> {
        let pm_error = unsafe { ffi::Pm_Poll(self.stream) };
        match pm_error {
            ffi::PmError::PmNoError => Ok(false),
            ffi::PmError::PmGotData => Ok(true),
            err @ _ => Err(Error::PortMidi(err)),
        }
    }
}
impl Drop for InputPort {
    fn drop(&mut self) {
        if let Err(err) = Result::from(unsafe { ffi::Pm_Close(self.stream) }) {
            println!("{}", err);
        }
    }
}

/// Representation the output port of a PortMidi device.
pub struct OutputPort {
    stream: *const ffi::PortMidiStream,
    device: ffi::PmDeviceId,
    buffer_size: usize,
}
impl OutputPort {
    /// Construct a new `OutputPort` for the given device and buffer size.
    ///
    /// If the `device` is not an output device an `Error::NotAnOutputDevice` is returned.
    pub fn new(device: DeviceInfo, buffer_size: usize) -> Result<OutputPort> {
        if device.is_input() {
            return Err(Error::NotAnOutputDevice);
        }
        let raw_stream: *const ffi::PortMidiStream = ptr::null();
        try!(Result::from(unsafe {
            ffi::Pm_OpenOutput(&raw_stream as *const *const _,
                               device.id(),
                               ptr::null(), // *inputDriverInfo, not needed for normal operation
                               buffer_size as c_int,
                               ptr::null(), // PmTimeProcPtr, a procedure that returns time in ms,
                               ptr::null(), // time_info, a pointer passed to the time procedure
                               0) //latency
        }));

        Ok(OutputPort {
            stream: raw_stream,
            device: device.id(),
            buffer_size: buffer_size,
        })
    }

    /// Terminates outgoing messages immediately.
    ///
    /// The caller should immediately close the output port, this may
    /// result in transmission of a partial midi message. Note, not all platforms
    /// support abort.
    ///
    /// NOTE: This is unsafe, either mark the device as invalid or try to reopen it afterwards.
    fn abort(&mut self) -> Result<()> {
        Result::from(unsafe { ffi::Pm_Abort(self.stream) })
    }

    /// Write a single `MidiEvent`
    pub fn write_event(&mut self, midi_event: MidiEvent) -> Result<()> {
        let event = midi_event.into();
        Result::from(unsafe { ffi::Pm_Write(self.stream, &event, 1) })
    }

    /// Write a single `MidiMessage`.
    /// Returns an `Error::PortMidi(_)` if something went wrong.
    pub fn write_message(&mut self, midi_message: MidiMessage) -> Result<()> {
        let message = midi_message.into();
        Result::from(unsafe { ffi::Pm_WriteShort(self.stream, 0, message) })
    }
}
impl Drop for OutputPort {
    fn drop(&mut self) {
        if let Err(err) = Result::from(unsafe { ffi::Pm_Close(self.stream) }) {
            println!("{}", err);
        }
    }
}
<|endoftext|>


<commit_before>use std;
use std::path::Path;
use std::fmt::{
  Display,
  Formatter,
};

use ::{
  KVStore,
  ValueType,
};

use ::cmd::Command;

pub enum UiError {
  KvStoreNotExisting(String),
  NoValueForKey(String),
  AlreadyValuePresent(String),
  KvError(::KVError),
  CmdError(::cmd::Error),
  UnknownError(String),
}

impl Display for UiError {
  fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
    match *self {
      UiError::KvStoreNotExisting(ref path) => write!(f, "kv store at {} not existing. Consider creating with the 'init' command", path),
      UiError::NoValueForKey(ref key) => write!(f, "no value for key {}", key),
      UiError::AlreadyValuePresent(ref key) => write!(f, "there is already a value at {}", key),
      UiError::KvError(ref e) => e.fmt(f),
      UiError::CmdError(ref e) => e.fmt(f),
      UiError::UnknownError(ref msg) => write!(f, "unknown error: {}", msg),
    }
  }
}

impl From<::cmd::Error> for UiError {
  fn from(e: ::cmd::Error) -> Self {
    UiError::CmdError(e)
  }
}

impl From<::KVError> for UiError {
  fn from(e: ::KVError) -> Self {
    UiError::KvError(e)
  }
}

pub enum UiResult {
  StringValueResult(String),
  StringListResult(Vec<String>),
  Ok,
}

impl Display for UiResult {
  fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
    match *self {
      UiResult::StringValueResult(ref value) => write!(f, "{}", value),
      UiResult::StringListResult(ref strings) => {
        if strings.len() == 0 {
          write!(f, "(empty list)")
        } else {
          write!(f, "{}", strings.join("\n"))
        }
      },
      UiResult::Ok => write!(f, "ok"),
    }
  }
}

impl UiResult {
  pub fn ok(_: ()) -> Result<UiResult> {
    Ok(UiResult::Ok)
  }
}

type Result<T> = std::result::Result<T, UiError>;

#[derive(Debug)]
pub struct Ui {
  program: String,
  store_file: String,
  enumerate_list: bool,
}

impl Ui {
  pub fn new(program: String, store_file: String, enumerate_list: bool) -> Ui {
    Ui {
      program: program,
      store_file: store_file,
      enumerate_list: enumerate_list,
    }
  }

  fn load_or_create_kvstore(&self, store_path: &Path, is_init: bool) -> Result<KVStore> {
    if !store_path.exists() {
      if !is_init {
        return Err(UiError::KvStoreNotExisting(store_path.to_str().unwrap_or("<invalid path>").to_string()));
      }

      return Ok(KVStore::new());
    }

    return Ok(::KVStore::read_from_file(store_path)?);
  }

  pub fn run(&self, args: Vec<String>) -> Result<UiResult> {
    let store_path = Path::new(&self.store_file);

    let command = Command::from_strings(args)?;

    let mut kvs = self.load_or_create_kvstore(store_path, command == Command::Init)?;

    let result = self.interpret(&mut kvs, &command)?;

    kvs.write_to_file(store_path)?;

    Ok(result)
  }

  fn interpret(&self, kvs: &mut KVStore, command: &Command) -> Result<UiResult> {
    match *command {
      Command::Init => Ok(UiResult::Ok),
      Command::PutString(ref key, ref value) => self.put_string(key, value, kvs),
      Command::Get(ref key) => self.get(key, kvs),
      Command::ListKeys => self.list_keys(kvs),
      Command::CreateEmptyList(ref key) => self.create_empty_list(key, kvs),
      Command::PushListValue(ref key, ref value) => UiResult::ok(kvs.push_value(key, value)?),
      Command::PopListValue(ref key) => Ok(UiResult::StringValueResult(kvs.pop_value(key)?)),
      Command::Drop(ref key) => self.drop(key, kvs),
      Command::ClearList(ref key) => self.clear_list(key, kvs),
    }
  }

  fn put_string(&self, key: &String, value: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.get_value_type(key) {
      Some(ValueType::String) => UiResult::ok(kvs.put(key, value)),
      _ => Err(UiError::AlreadyValuePresent(key.to_string()))
    }
  }

  fn create_empty_list(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    if kvs.has_key(key) {
      Err(UiError::AlreadyValuePresent(key.to_string()))
    } else {
      self.clear_list(key, kvs)?;
      Ok(UiResult::Ok)
    }
  }

  fn clear_list(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.put_empty_list(key) {
      Some(v) => Ok(self.to_result(&v)),
      None => Ok(UiResult::Ok),
    }
  }

  fn drop(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.drop(key) {
      Some(v) => Ok(self.to_result(&v)),
      None => Ok(UiResult::Ok),
    }
  }

  fn list_keys(&self, kvs: &KVStore) -> Result<UiResult> {
    Ok(UiResult::StringListResult(kvs.get_keys().iter().map(|x| x.to_string()).collect()))
  }

  fn get(&self, key: &String, kvs: &KVStore) -> Result<UiResult> {
    let value = kvs.get(key).ok_or(UiError::NoValueForKey(key.clone()))?;

    Ok(self.to_result(value))
  }

  fn to_result(&self, value: &::Value) -> UiResult {
    match *value {
      ::Value::StringValue(ref val) => UiResult::StringValueResult(val.clone()),
      ::Value::ListValue(ref list) => UiResult::StringListResult(self.prepare_list_result(list)),
    }
  }

  fn prepare_list_result(&self, list: &Vec<String>) -> Vec<String> {
    if self.enumerate_list {
      let mut i = 0;
      list.iter().map(|x| {
        i += 1;
        format!("{}: {}", i, x)
      }).collect()
    } else {
      list.clone()
    }
  }
}

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

  #[test]
  fn test_construct() {
    let ui = Ui::new("program".to_string(), "test".to_string(), false);
  }
}
<commit_msg>added program to non existing kvs<commit_after>use std;
use std::path::Path;
use std::fmt::{
  Display,
  Formatter,
};

use ::{
  KVStore,
  ValueType,
};

use ::cmd::Command;

pub enum UiError {
  KvStoreNotExisting(String, String),
  NoValueForKey(String),
  AlreadyValuePresent(String),
  KvError(::KVError),
  CmdError(::cmd::Error),
  UnknownError(String),
}

impl Display for UiError {
  fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
    match *self {
      UiError::KvStoreNotExisting(ref path, ref program) => write!(f, "kv store at {} not existing. Create with '{} init' command", path, program),
      UiError::NoValueForKey(ref key) => write!(f, "no value for key {}", key),
      UiError::AlreadyValuePresent(ref key) => write!(f, "there is already a value at {}", key),
      UiError::KvError(ref e) => e.fmt(f),
      UiError::CmdError(ref e) => e.fmt(f),
      UiError::UnknownError(ref msg) => write!(f, "unknown error: {}", msg),
    }
  }
}

impl From<::cmd::Error> for UiError {
  fn from(e: ::cmd::Error) -> Self {
    UiError::CmdError(e)
  }
}

impl From<::KVError> for UiError {
  fn from(e: ::KVError) -> Self {
    UiError::KvError(e)
  }
}

pub enum UiResult {
  StringValueResult(String),
  StringListResult(Vec<String>),
  Ok,
}

impl Display for UiResult {
  fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
    match *self {
      UiResult::StringValueResult(ref value) => write!(f, "{}", value),
      UiResult::StringListResult(ref strings) => {
        if strings.len() == 0 {
          write!(f, "(empty list)")
        } else {
          write!(f, "{}", strings.join("\n"))
        }
      },
      UiResult::Ok => write!(f, "ok"),
    }
  }
}

impl UiResult {
  pub fn ok(_: ()) -> Result<UiResult> {
    Ok(UiResult::Ok)
  }
}

type Result<T> = std::result::Result<T, UiError>;

#[derive(Debug)]
pub struct Ui {
  program: String,
  store_file: String,
  enumerate_list: bool,
}

impl Ui {
  pub fn new(program: String, store_file: String, enumerate_list: bool) -> Ui {
    Ui {
      program: program,
      store_file: store_file,
      enumerate_list: enumerate_list,
    }
  }

  fn load_or_create_kvstore(&self, store_path: &Path, is_init: bool) -> Result<KVStore> {
    if !store_path.exists() {
      if !is_init {
        return Err(UiError::KvStoreNotExisting(store_path.to_str().unwrap_or("<invalid path>").to_string(), self.program.clone()));
      }

      return Ok(KVStore::new());
    }

    return Ok(::KVStore::read_from_file(store_path)?);
  }

  pub fn run(&self, args: Vec<String>) -> Result<UiResult> {
    let store_path = Path::new(&self.store_file);

    let command = Command::from_strings(args)?;

    let mut kvs = self.load_or_create_kvstore(store_path, command == Command::Init)?;

    let result = self.interpret(&mut kvs, &command)?;

    kvs.write_to_file(store_path)?;

    Ok(result)
  }

  fn interpret(&self, kvs: &mut KVStore, command: &Command) -> Result<UiResult> {
    match *command {
      Command::Init => Ok(UiResult::Ok),
      Command::PutString(ref key, ref value) => self.put_string(key, value, kvs),
      Command::Get(ref key) => self.get(key, kvs),
      Command::ListKeys => self.list_keys(kvs),
      Command::CreateEmptyList(ref key) => self.create_empty_list(key, kvs),
      Command::PushListValue(ref key, ref value) => UiResult::ok(kvs.push_value(key, value)?),
      Command::PopListValue(ref key) => Ok(UiResult::StringValueResult(kvs.pop_value(key)?)),
      Command::Drop(ref key) => self.drop(key, kvs),
      Command::ClearList(ref key) => self.clear_list(key, kvs),
    }
  }

  fn put_string(&self, key: &String, value: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.get_value_type(key) {
      Some(ValueType::String) => UiResult::ok(kvs.put(key, value)),
      _ => Err(UiError::AlreadyValuePresent(key.to_string()))
    }
  }

  fn create_empty_list(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    if kvs.has_key(key) {
      Err(UiError::AlreadyValuePresent(key.to_string()))
    } else {
      self.clear_list(key, kvs)?;
      Ok(UiResult::Ok)
    }
  }

  fn clear_list(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.put_empty_list(key) {
      Some(v) => Ok(self.to_result(&v)),
      None => Ok(UiResult::Ok),
    }
  }

  fn drop(&self, key: &String, kvs: &mut KVStore) -> Result<UiResult> {
    match kvs.drop(key) {
      Some(v) => Ok(self.to_result(&v)),
      None => Ok(UiResult::Ok),
    }
  }

  fn list_keys(&self, kvs: &KVStore) -> Result<UiResult> {
    Ok(UiResult::StringListResult(kvs.get_keys().iter().map(|x| x.to_string()).collect()))
  }

  fn get(&self, key: &String, kvs: &KVStore) -> Result<UiResult> {
    let value = kvs.get(key).ok_or(UiError::NoValueForKey(key.clone()))?;

    Ok(self.to_result(value))
  }

  fn to_result(&self, value: &::Value) -> UiResult {
    match *value {
      ::Value::StringValue(ref val) => UiResult::StringValueResult(val.clone()),
      ::Value::ListValue(ref list) => UiResult::StringListResult(self.prepare_list_result(list)),
    }
  }

  fn prepare_list_result(&self, list: &Vec<String>) -> Vec<String> {
    if self.enumerate_list {
      let mut i = 0;
      list.iter().map(|x| {
        i += 1;
        format!("{}: {}", i, x)
      }).collect()
    } else {
      list.clone()
    }
  }
}

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

  #[test]
  fn test_construct() {
    Ui::new("program".to_string(), "test".to_string(), false);
  }
}
<|endoftext|>


<commit_before>use proc_macro2::{Span, TokenStream};

use syn::{self, Field, Ident};

use super::context::Context;

pub fn transcoder_decorator(ast: &syn::DeriveInput) -> TokenStream {
    let ctx = Context::from_ast(ast);

    let struct_fields = ctx
        .struct_fields
        .as_ref()
        .expect("NifMap can only be used with structs");

    // Unwrap is ok here, as we already determined that struct_fields is not None
    let field_atoms = ctx.field_atoms().unwrap();

    let atom_defs = quote! {
        rustler::atoms! {
            #(#field_atoms)*
        }
    };

    let atoms_module_name = ctx.atoms_module_name(Span::call_site());

    let decoder = if ctx.decode() {
        gen_decoder(&ctx, &struct_fields, &atoms_module_name)
    } else {
        quote! {}
    };

    let encoder = if ctx.encode() {
        gen_encoder(&ctx, &struct_fields, &atoms_module_name)
    } else {
        quote! {}
    };

    let gen = quote! {
        mod #atoms_module_name {
            #atom_defs
        }

        #decoder
        #encoder
    };

    gen
}

fn gen_decoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> TokenStream {
    let struct_type = &ctx.ident_with_lifetime;
    let struct_name = ctx.ident;

    let field_defs: Vec<TokenStream> = fields
        .iter()
        .map(|field| {
            let ident = field.ident.as_ref().unwrap();
            let ident_str = ident.to_string();

            let atom_fun = Ident::new(&format!("atom_{}", ident_str), Span::call_site());
            let error_message = format!("Could not decode field :{} on %{{}}", ident.to_string());
            quote! {
                #ident: match ::rustler::Decoder::decode(term.map_get(#atom_fun().encode(env))?) {
                    Err(_) => return Err(::rustler::Error::RaiseTerm(Box::new(#error_message))),
                    Ok(value) => value
                }

            }
        })
        .collect();

    let gen = quote! {
        impl<'a> ::rustler::Decoder<'a> for #struct_type {
            fn decode(term: ::rustler::Term<'a>) -> Result<Self, ::rustler::Error> {
                use #atoms_module_name::*;

                let env = term.get_env();
                Ok(#struct_name { #(#field_defs),* })
            }
        }
    };

    gen
}

fn gen_encoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> TokenStream {
    let struct_type = &ctx.ident_with_lifetime;

    let field_defs: Vec<TokenStream> = fields
        .iter()
        .map(|field| {
            let field_ident = field.ident.as_ref().unwrap();
            let field_ident_str = field_ident.to_string();

            let atom_fun = Ident::new(&format!("atom_{}", field_ident_str), Span::call_site());

            quote! {
                map = map.map_put(#atom_fun().encode(env), self.#field_ident.encode(env)).unwrap();
            }
        })
        .collect();

    let gen = quote! {
        impl<'b> ::rustler::Encoder for #struct_type {
            fn encode<'a>(&self, env: ::rustler::Env<'a>) -> ::rustler::Term<'a> {
                use #atoms_module_name::*;

                let mut map = ::rustler::types::map::map_new(env);
                #(#field_defs)*
                map
            }
        }
    };

    gen
}
<commit_msg>Speed-up compilation of NifMap<commit_after>use proc_macro2::{Span, TokenStream};

use syn::{self, Field, Ident};

use super::context::Context;

pub fn transcoder_decorator(ast: &syn::DeriveInput) -> TokenStream {
    let ctx = Context::from_ast(ast);

    let struct_fields = ctx
        .struct_fields
        .as_ref()
        .expect("NifMap can only be used with structs");

    // Unwrap is ok here, as we already determined that struct_fields is not None
    let field_atoms = ctx.field_atoms().unwrap();

    let atom_defs = quote! {
        rustler::atoms! {
            #(#field_atoms)*
        }
    };

    let atoms_module_name = ctx.atoms_module_name(Span::call_site());

    let decoder = if ctx.decode() {
        gen_decoder(&ctx, &struct_fields, &atoms_module_name)
    } else {
        quote! {}
    };

    let encoder = if ctx.encode() {
        gen_encoder(&ctx, &struct_fields, &atoms_module_name)
    } else {
        quote! {}
    };

    let gen = quote! {
        mod #atoms_module_name {
            #atom_defs
        }

        #decoder
        #encoder
    };

    gen
}

fn gen_decoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> TokenStream {
    let struct_type = &ctx.ident_with_lifetime;
    let struct_name = ctx.ident;

    let idents: Vec<_> = fields
        .iter()
        .map(|field| field.ident.as_ref().unwrap())
        .collect();

    let field_defs: Vec<TokenStream> = idents
        .iter()
        .map(|ident| {
            let ident_str = ident.to_string();

            let atom_fun = Ident::new(&format!("atom_{}", ident_str), Span::call_site());
            quote! {
                let #ident = try_decode_field(env, term, #atom_fun())?;

            }
        })
        .collect();

    let gen = quote! {
        impl<'a> ::rustler::Decoder<'a> for #struct_type {
            fn decode(term: ::rustler::Term<'a>) -> Result<Self, ::rustler::Error> {
                use #atoms_module_name::*;

                let env = term.get_env();

                fn try_decode_field<'a, T>(
                    env: rustler::Env<'a>,
                    term: rustler::Term<'a>,
                    field: rustler::Atom,
                    ) -> Result<T, rustler::Error>
                    where
                        T: rustler::Decoder<'a>,
                    {
                        use rustler::Encoder;
                        match ::rustler::Decoder::decode(term.map_get(field.encode(env))?) {
                            Err(_) => Err(::rustler::Error::RaiseTerm(Box::new(format!(
                                            "Could not decode field :{:?} on %{{}}",
                                            field
                            )))),
                            Ok(value) => Ok(value),
                        }
                    };

                #(#field_defs);*

                Ok(#struct_name { #(#idents),* })
            }
        }
    };

    gen
}

fn gen_encoder(ctx: &Context, fields: &[&Field], atoms_module_name: &Ident) -> TokenStream {
    let struct_type = &ctx.ident_with_lifetime;

    let field_defs: Vec<TokenStream> = fields
        .iter()
        .map(|field| {
            let field_ident = field.ident.as_ref().unwrap();
            let field_ident_str = field_ident.to_string();

            let atom_fun = Ident::new(&format!("atom_{}", field_ident_str), Span::call_site());

            quote! {
                map = map.map_put(#atom_fun().encode(env), self.#field_ident.encode(env)).unwrap();
            }
        })
        .collect();

    let gen = quote! {
        impl<'b> ::rustler::Encoder for #struct_type {
            fn encode<'a>(&self, env: ::rustler::Env<'a>) -> ::rustler::Term<'a> {
                use #atoms_module_name::*;

                let mut map = ::rustler::types::map::map_new(env);
                #(#field_defs)*
                map
            }
        }
    };

    gen
}
<|endoftext|>


<commit_before>//! This module is used to store stuff from Rust's AST in a more convenient
//! manner (and with prettier names) before cleaning.
pub use self::StructType::*;

use syntax::ast;
use syntax::ast::Name;
use syntax::ext::base::MacroKind;
use syntax_pos::{self, Span};

use rustc::hir;
use rustc::hir::def_id::CrateNum;
use rustc::hir::ptr::P;

pub struct Module<'hir> {
    pub name: Option<Name>,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub where_outer: Span,
    pub where_inner: Span,
    pub extern_crates: Vec<ExternCrate<'hir>>,
    pub imports: Vec<Import<'hir>>,
    pub structs: Vec<Struct<'hir>>,
    pub unions: Vec<Union<'hir>>,
    pub enums: Vec<Enum<'hir>>,
    pub fns: Vec<Function<'hir>>,
    pub mods: Vec<Module<'hir>>,
    pub id: hir::HirId,
    pub typedefs: Vec<Typedef<'hir>>,
    pub opaque_tys: Vec<OpaqueTy<'hir>>,
    pub statics: Vec<Static<'hir>>,
    pub constants: Vec<Constant<'hir>>,
    pub traits: Vec<Trait<'hir>>,
    pub vis: &'hir hir::Visibility,
    pub impls: Vec<Impl<'hir>>,
    pub foreigns: Vec<ForeignItem<'hir>>,
    pub macros: Vec<Macro<'hir>>,
    pub proc_macros: Vec<ProcMacro<'hir>>,
    pub trait_aliases: Vec<TraitAlias<'hir>>,
    pub is_crate: bool,
}

impl Module<'hir> {
    pub fn new(
        name: Option<Name>,
        attrs: &'hir hir::HirVec<ast::Attribute>,
        vis: &'hir hir::Visibility,
    ) -> Module<'hir> {
        Module {
            name       : name,
            id: hir::CRATE_HIR_ID,
            vis,
            where_outer: syntax_pos::DUMMY_SP,
            where_inner: syntax_pos::DUMMY_SP,
            attrs,
            extern_crates: Vec::new(),
            imports    :   Vec::new(),
            structs    :   Vec::new(),
            unions     :   Vec::new(),
            enums      :   Vec::new(),
            fns        :   Vec::new(),
            mods       :   Vec::new(),
            typedefs   :   Vec::new(),
            opaque_tys :  Vec::new(),
            statics    :   Vec::new(),
            constants  :   Vec::new(),
            traits     :   Vec::new(),
            impls      :   Vec::new(),
            foreigns   :   Vec::new(),
            macros     :   Vec::new(),
            proc_macros:   Vec::new(),
            trait_aliases: Vec::new(),
            is_crate   : false,
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub enum StructType {
    /// A braced struct
    Plain,
    /// A tuple struct
    Tuple,
    /// A unit struct
    Unit,
}

pub struct Struct<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub struct_type: StructType,
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub fields: &'hir [hir::StructField],
    pub whence: Span,
}

pub struct Union<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub struct_type: StructType,
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub fields: &'hir [hir::StructField],
    pub whence: Span,
}

pub struct Enum<'hir> {
    pub vis: &'hir hir::Visibility,
    pub variants: Vec<Variant<'hir>>,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub id: hir::HirId,
    pub whence: Span,
    pub name: Name,
}

pub struct Variant<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub def: &'hir hir::VariantData,
    pub whence: Span,
}

pub struct Function<'hir> {
    pub decl: &'hir hir::FnDecl,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub id: hir::HirId,
    pub name: Name,
    pub vis: &'hir hir::Visibility,
    pub header: hir::FnHeader,
    pub whence: Span,
    pub generics: &'hir hir::Generics,
    pub body: hir::BodyId,
}

pub struct Typedef<'hir> {
    pub ty: &'hir P<hir::Ty>,
    pub gen: &'hir hir::Generics,
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

pub struct OpaqueTy<'hir> {
    pub opaque_ty: &'hir hir::OpaqueTy,
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

#[derive(Debug)]
pub struct Static<'hir> {
    pub type_: &'hir P<hir::Ty>,
    pub mutability: hir::Mutability,
    pub expr: hir::BodyId,
    pub name: Name,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub whence: Span,
}

pub struct Constant<'hir> {
    pub type_: &'hir P<hir::Ty>,
    pub expr: hir::BodyId,
    pub name: Name,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub whence: Span,
}

pub struct Trait<'hir> {
    pub is_auto: hir::IsAuto,
    pub unsafety: hir::Unsafety,
    pub name: Name,
    pub items: Vec<&'hir hir::TraitItem>,
    pub generics: &'hir hir::Generics,
    pub bounds: &'hir hir::HirVec<hir::GenericBound>,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub id: hir::HirId,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

pub struct TraitAlias<'hir> {
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub bounds: &'hir hir::HirVec<hir::GenericBound>,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub id: hir::HirId,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

#[derive(Debug)]
pub struct Impl<'hir> {
    pub unsafety: hir::Unsafety,
    pub polarity: hir::ImplPolarity,
    pub defaultness: hir::Defaultness,
    pub generics: &'hir hir::Generics,
    pub trait_: &'hir Option<hir::TraitRef>,
    pub for_: &'hir P<hir::Ty>,
    pub items: Vec<&'hir hir::ImplItem>,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
}

pub struct ForeignItem<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub name: Name,
    pub kind: &'hir hir::ForeignItemKind,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
}

// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
pub struct Macro<'hir> {
    pub name: Name,
    pub hid: hir::HirId,
    pub def_id: hir::def_id::DefId,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
    pub matchers: hir::HirVec<Span>,
    pub imported_from: Option<Name>,
}

pub struct ExternCrate<'hir> {
    pub name: Name,
    pub cnum: CrateNum,
    pub path: Option<String>,
    pub vis: &'hir hir::Visibility,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
}

pub struct Import<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub vis: &'hir hir::Visibility,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub path: &'hir hir::Path,
    pub glob: bool,
    pub whence: Span,
}

pub struct ProcMacro<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub kind: MacroKind,
    pub helpers: Vec<Name>,
    pub attrs: &'hir hir::HirVec<ast::Attribute>,
    pub whence: Span,
}

pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType {
    match *vdata {
        hir::VariantData::Struct(..) => Plain,
        hir::VariantData::Tuple(..) => Tuple,
        hir::VariantData::Unit(..) => Unit,
    }
}
<commit_msg>rustdoc: Replace HirVec with slices in doctree<commit_after>//! This module is used to store stuff from Rust's AST in a more convenient
//! manner (and with prettier names) before cleaning.
pub use self::StructType::*;

use syntax::ast;
use syntax::ast::Name;
use syntax::ext::base::MacroKind;
use syntax_pos::{self, Span};

use rustc::hir;
use rustc::hir::def_id::CrateNum;
use rustc::hir::ptr::P;

pub struct Module<'hir> {
    pub name: Option<Name>,
    pub attrs: &'hir [ast::Attribute],
    pub where_outer: Span,
    pub where_inner: Span,
    pub extern_crates: Vec<ExternCrate<'hir>>,
    pub imports: Vec<Import<'hir>>,
    pub structs: Vec<Struct<'hir>>,
    pub unions: Vec<Union<'hir>>,
    pub enums: Vec<Enum<'hir>>,
    pub fns: Vec<Function<'hir>>,
    pub mods: Vec<Module<'hir>>,
    pub id: hir::HirId,
    pub typedefs: Vec<Typedef<'hir>>,
    pub opaque_tys: Vec<OpaqueTy<'hir>>,
    pub statics: Vec<Static<'hir>>,
    pub constants: Vec<Constant<'hir>>,
    pub traits: Vec<Trait<'hir>>,
    pub vis: &'hir hir::Visibility,
    pub impls: Vec<Impl<'hir>>,
    pub foreigns: Vec<ForeignItem<'hir>>,
    pub macros: Vec<Macro<'hir>>,
    pub proc_macros: Vec<ProcMacro<'hir>>,
    pub trait_aliases: Vec<TraitAlias<'hir>>,
    pub is_crate: bool,
}

impl Module<'hir> {
    pub fn new(
        name: Option<Name>,
        attrs: &'hir [ast::Attribute],
        vis: &'hir hir::Visibility,
    ) -> Module<'hir> {
        Module {
            name       : name,
            id: hir::CRATE_HIR_ID,
            vis,
            where_outer: syntax_pos::DUMMY_SP,
            where_inner: syntax_pos::DUMMY_SP,
            attrs,
            extern_crates: Vec::new(),
            imports    :   Vec::new(),
            structs    :   Vec::new(),
            unions     :   Vec::new(),
            enums      :   Vec::new(),
            fns        :   Vec::new(),
            mods       :   Vec::new(),
            typedefs   :   Vec::new(),
            opaque_tys :  Vec::new(),
            statics    :   Vec::new(),
            constants  :   Vec::new(),
            traits     :   Vec::new(),
            impls      :   Vec::new(),
            foreigns   :   Vec::new(),
            macros     :   Vec::new(),
            proc_macros:   Vec::new(),
            trait_aliases: Vec::new(),
            is_crate   : false,
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub enum StructType {
    /// A braced struct
    Plain,
    /// A tuple struct
    Tuple,
    /// A unit struct
    Unit,
}

pub struct Struct<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub struct_type: StructType,
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir [ast::Attribute],
    pub fields: &'hir [hir::StructField],
    pub whence: Span,
}

pub struct Union<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub struct_type: StructType,
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir [ast::Attribute],
    pub fields: &'hir [hir::StructField],
    pub whence: Span,
}

pub struct Enum<'hir> {
    pub vis: &'hir hir::Visibility,
    pub variants: Vec<Variant<'hir>>,
    pub generics: &'hir hir::Generics,
    pub attrs: &'hir [ast::Attribute],
    pub id: hir::HirId,
    pub whence: Span,
    pub name: Name,
}

pub struct Variant<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir [ast::Attribute],
    pub def: &'hir hir::VariantData,
    pub whence: Span,
}

pub struct Function<'hir> {
    pub decl: &'hir hir::FnDecl,
    pub attrs: &'hir [ast::Attribute],
    pub id: hir::HirId,
    pub name: Name,
    pub vis: &'hir hir::Visibility,
    pub header: hir::FnHeader,
    pub whence: Span,
    pub generics: &'hir hir::Generics,
    pub body: hir::BodyId,
}

pub struct Typedef<'hir> {
    pub ty: &'hir P<hir::Ty>,
    pub gen: &'hir hir::Generics,
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

pub struct OpaqueTy<'hir> {
    pub opaque_ty: &'hir hir::OpaqueTy,
    pub name: Name,
    pub id: hir::HirId,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

#[derive(Debug)]
pub struct Static<'hir> {
    pub type_: &'hir P<hir::Ty>,
    pub mutability: hir::Mutability,
    pub expr: hir::BodyId,
    pub name: Name,
    pub attrs: &'hir [ast::Attribute],
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub whence: Span,
}

pub struct Constant<'hir> {
    pub type_: &'hir P<hir::Ty>,
    pub expr: hir::BodyId,
    pub name: Name,
    pub attrs: &'hir [ast::Attribute],
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub whence: Span,
}

pub struct Trait<'hir> {
    pub is_auto: hir::IsAuto,
    pub unsafety: hir::Unsafety,
    pub name: Name,
    pub items: Vec<&'hir hir::TraitItem>,
    pub generics: &'hir hir::Generics,
    pub bounds: &'hir [hir::GenericBound],
    pub attrs: &'hir [ast::Attribute],
    pub id: hir::HirId,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

pub struct TraitAlias<'hir> {
    pub name: Name,
    pub generics: &'hir hir::Generics,
    pub bounds: &'hir [hir::GenericBound],
    pub attrs: &'hir [ast::Attribute],
    pub id: hir::HirId,
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
}

#[derive(Debug)]
pub struct Impl<'hir> {
    pub unsafety: hir::Unsafety,
    pub polarity: hir::ImplPolarity,
    pub defaultness: hir::Defaultness,
    pub generics: &'hir hir::Generics,
    pub trait_: &'hir Option<hir::TraitRef>,
    pub for_: &'hir P<hir::Ty>,
    pub items: Vec<&'hir hir::ImplItem>,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
}

pub struct ForeignItem<'hir> {
    pub vis: &'hir hir::Visibility,
    pub id: hir::HirId,
    pub name: Name,
    pub kind: &'hir hir::ForeignItemKind,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
}

// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
pub struct Macro<'hir> {
    pub name: Name,
    pub hid: hir::HirId,
    pub def_id: hir::def_id::DefId,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
    pub matchers: hir::HirVec<Span>,
    pub imported_from: Option<Name>,
}

pub struct ExternCrate<'hir> {
    pub name: Name,
    pub cnum: CrateNum,
    pub path: Option<String>,
    pub vis: &'hir hir::Visibility,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
}

pub struct Import<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub vis: &'hir hir::Visibility,
    pub attrs: &'hir [ast::Attribute],
    pub path: &'hir hir::Path,
    pub glob: bool,
    pub whence: Span,
}

pub struct ProcMacro<'hir> {
    pub name: Name,
    pub id: hir::HirId,
    pub kind: MacroKind,
    pub helpers: Vec<Name>,
    pub attrs: &'hir [ast::Attribute],
    pub whence: Span,
}

pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType {
    match *vdata {
        hir::VariantData::Struct(..) => Plain,
        hir::VariantData::Tuple(..) => Tuple,
        hir::VariantData::Unit(..) => Unit,
    }
}
<|endoftext|>


<commit_before>/// A thread pool abstraction. Useful for achieving predictable CPU
/// parallelism.

use pipes::{Chan, Port};
use task::{SchedMode, SingleThreaded};

enum Msg<T> {
    Execute(~fn(&T)),
    Quit
}

pub struct ThreadPool<T> {
    channels: ~[Chan<Msg<T>>],
    mut next_index: uint,

}

impl<T> ThreadPool<T> {
    fn finalize() {
        for self.channels.each |channel| {
            channel.send(Quit);
        }
    }
}

pub impl<T> ThreadPool<T> {
    /// Spawns a new thread pool with `n_tasks` tasks. If the `sched_mode`
    /// is None, the tasks run on this scheduler; otherwise, they run on a
    /// new scheduler with the given mode. The provided `init_fn_factory`
    /// returns a function which, given the index of the task, should return
    /// local data to be kept around in that task.
    static fn new(n_tasks: uint,
                  opt_sched_mode: Option<SchedMode>,
                  init_fn_factory: ~fn() -> ~fn(uint) -> T) -> ThreadPool<T> {
        assert n_tasks >= 1;

        let channels = do vec::from_fn(n_tasks) |i| {
            let (chan, port) = pipes::stream::<Msg<T>>();
            let init_fn = init_fn_factory();

            let task_body: ~fn() = |move port, move init_fn| {
                let local_data = init_fn(i);
                loop {
                    match port.recv() {
                        Execute(move f) => f(&local_data),
                        Quit => break
                    }
                }
            };

            // Start the task.
            match opt_sched_mode {
                None => {
                    // Run on this scheduler.
                    task::spawn(move task_body);
                }
                Some(sched_mode) => {
                    task::task().sched_mode(sched_mode).spawn(move task_body);
                }
            }

            move chan
        };

        return ThreadPool { channels: move channels, next_index: 0 };
    }

    /// Executes the function `f` on a thread in the pool. The function
    /// receives a reference to the local data returned by the `init_fn`.
    fn execute(&self, f: ~fn(&T)) {
        self.channels[self.next_index].send(Execute(move f));
        self.next_index += 1;
        if self.next_index == self.channels.len() { self.next_index = 0; }
    }
}

#[test]
fn test_thread_pool() {
    let f: ~fn() -> ~fn(uint) -> uint = || {
        let g: ~fn(uint) -> uint = |i| i;
        move g
    };
    let pool = ThreadPool::new(4, Some(SingleThreaded), move f);
    for 8.times {
        pool.execute(|i| io::println(fmt!("Hello from thread %u!", *i)));
    }
}

<commit_msg>std: Don't use Drop trait in thread_pool<commit_after>/// A thread pool abstraction. Useful for achieving predictable CPU
/// parallelism.

use pipes::{Chan, Port};
use task::{SchedMode, SingleThreaded};

enum Msg<T> {
    Execute(~fn(&T)),
    Quit
}

pub struct ThreadPool<T> {
    channels: ~[Chan<Msg<T>>],
    mut next_index: uint,

    drop {
        for self.channels.each |channel| {
            channel.send(Quit);
        }
    }
}

pub impl<T> ThreadPool<T> {
    /// Spawns a new thread pool with `n_tasks` tasks. If the `sched_mode`
    /// is None, the tasks run on this scheduler; otherwise, they run on a
    /// new scheduler with the given mode. The provided `init_fn_factory`
    /// returns a function which, given the index of the task, should return
    /// local data to be kept around in that task.
    static fn new(n_tasks: uint,
                  opt_sched_mode: Option<SchedMode>,
                  init_fn_factory: ~fn() -> ~fn(uint) -> T) -> ThreadPool<T> {
        assert n_tasks >= 1;

        let channels = do vec::from_fn(n_tasks) |i| {
            let (chan, port) = pipes::stream::<Msg<T>>();
            let init_fn = init_fn_factory();

            let task_body: ~fn() = |move port, move init_fn| {
                let local_data = init_fn(i);
                loop {
                    match port.recv() {
                        Execute(move f) => f(&local_data),
                        Quit => break
                    }
                }
            };

            // Start the task.
            match opt_sched_mode {
                None => {
                    // Run on this scheduler.
                    task::spawn(move task_body);
                }
                Some(sched_mode) => {
                    task::task().sched_mode(sched_mode).spawn(move task_body);
                }
            }

            move chan
        };

        return ThreadPool { channels: move channels, next_index: 0 };
    }

    /// Executes the function `f` on a thread in the pool. The function
    /// receives a reference to the local data returned by the `init_fn`.
    fn execute(&self, f: ~fn(&T)) {
        self.channels[self.next_index].send(Execute(move f));
        self.next_index += 1;
        if self.next_index == self.channels.len() { self.next_index = 0; }
    }
}

#[test]
fn test_thread_pool() {
    let f: ~fn() -> ~fn(uint) -> uint = || {
        let g: ~fn(uint) -> uint = |i| i;
        move g
    };
    let pool = ThreadPool::new(4, Some(SingleThreaded), move f);
    for 8.times {
        pool.execute(|i| io::println(fmt!("Hello from thread %u!", *i)));
    }
}

<|endoftext|>


<commit_before>extern crate ktensor as k;
use k::{Arc, Vec2, Tensor, Context, Graph, State, Variable};
use std::path::{Path};
use std::fs::{File};
use std::io::{BufReader, Read};
use std::error::{Error};
use std::cmp;

fn read_u8(reader: &mut Read) -> u8 {
    use std::mem;

    let mut buf: [u8; 1] = [0];
    match reader.read_exact(&mut buf).map(|_| {
        let data: u8 = unsafe { mem::transmute(buf) };
        data
    }) {
        Err(reason) => panic!("failed to read u8: {}", Error::description(&reason)),
        Ok(byte)    => byte,
    }
}

fn read_u32(reader: &mut Read) -> u32 {
    use std::mem;

    let mut buf: [u8; 4] = [0, 0, 0, 0];
    match reader.read_exact(&mut buf).map(|_| {
        let data: u32 = unsafe { mem::transmute(buf) };
        data
    }) {
        Err(reason) => panic!("failed to read u32: {}", Error::description(&reason)),
        Ok(byte)    => byte,
    }
}

fn read_mnist(labels_path: &Path, labels_checknum: u32, data_path: &Path, data_checknum: u32, batch_size: usize, samples: Option<usize>) {
    let labels_file = match File::open(&labels_path) {
        Err(reason) => panic!("failed to open {}: {}", labels_path.display(), Error::description(&reason)),
        Ok(file)    => file,
    };
    let data_file = match File::open(&data_path) {
        Err(reason) => panic!("failed to open {}: {}", data_path.display(), Error::description(&reason)),
        Ok(file)    => file,
    };
    let ref mut labels_reader = BufReader::new(labels_file);
    let ref mut data_reader = BufReader::new(data_file);

    let labels_magic = u32::from_be(read_u32(labels_reader));
    let data_magic = u32::from_be(read_u32(data_reader));

    assert_eq!(labels_magic, labels_checknum);
    assert_eq!(data_magic, data_checknum);

    let labels_count = u32::from_be(read_u32(labels_reader)) as usize;
    let data_count = u32::from_be(read_u32(data_reader)) as usize;
    let sample_count = cmp::min(labels_count, data_count);
    let sample_count = cmp::min(sample_count, samples.unwrap_or(sample_count));

    let rows = u32::from_be(read_u32(data_reader)) as usize;
    let columns = u32::from_be(read_u32(data_reader)) as usize;

    let mut sample_vec: Vec<(Vec<u8>, Vec<u8>)> = Vec::with_capacity(sample_count/batch_size);
    for _ in 0..sample_count/batch_size {
        let mut sample_data = vec![0u8; batch_size*rows*columns];
        match data_reader.read_exact(sample_data.as_mut()) {
            Err(reason) => panic!("failed to read data byte array: {}", Error::description(&reason)),
            Ok(_)       => (),
        }
        let mut sample_labels = vec![0u8; batch_size];
        match labels_reader.read_exact(sample_labels.as_mut()) {
            Err(reason) => panic!("failed to read labels byte array: {}", Error::description(&reason)),
            Ok(_)       => (),
        }
        sample_vec.push((sample_data, sample_labels));
    }
}

#[test]
#[ignore]
fn mnist(){
    ///////////////
    // Variables //
    ///////////////

    let input_x = Arc::new(Variable::new("input_x".to_string(), Vec2(0, 28 * 28)));
    let target_y = Arc::new(Variable::new("target_y".to_string(), Vec2(0, 10)));

    // Initialize
    let mut variable_context = Context::<f32>::with_capacity(2);
    Variable::init_f32(vec![input_x.clone(), target_y.clone()], &mut variable_context);

    ///////////
    // Graph //
    ///////////

    let layers: usize = 2;
    let mut states = Vec::<Arc<State>>::with_capacity(2 * layers);
    let mut graph_head: Arc<Graph<f32>> = input_x.clone();

    {
        let w = Arc::new(State::new(format!("weight_w_{}", 1), Vec2(28 * 28, 16)));
        let b = Arc::new(State::new(format!("weight_b_{}", 1), Vec2(1, 16)));

        let dot = Arc::new(k::op::dot::<f32>(format!("layer_{}_dot", 1), graph_head.clone(), w.clone()));
        let add = Arc::new(k::op::add::<f32>(format!("layer_{}_add", 1), dot, b.clone()));

        let relu = Arc::new(k::op::relu_f32(format!("layer_{}_relu", 1), add));

        graph_head = relu;

        states.push(w);
        states.push(b);
    }

    {
        let w = Arc::new(State::new(format!("weight_w_{}", 2), Vec2(16, 10)));
        let b = Arc::new(State::new(format!("weight_b_{}", 2), Vec2(1, 10)));

        let dot = Arc::new(k::op::dot::<f32>(format!("layer_{}_dot", 2), graph_head.clone(), w.clone()));
        let add = Arc::new(k::op::add::<f32>(format!("layer_{}_add", 2), dot, b.clone()));

        let relu = Arc::new(k::op::relu_f32(format!("layer_{}_relu", 2), add));

        graph_head = relu;

        states.push(w);
        states.push(b);
    }

    let softmax = Arc::new(k::op::softmax_f32(format!("layer_{}_softmax", 3), graph_head.clone()));
    let xentropy = Arc::new(k::cost::softmax_cross_entropy_f32(format!("layer_{}_xentropy", 3), softmax.clone(), target_y.clone()));

    // initialize states
    let mut state_context = Context::<f32>::with_capacity(2 * layers);
    State::init_f32(states, &mut state_context);

    //////////////
    // Training //
    //////////////

    let iterations = 16384;
    let learning_rate = -0.1;
    let print_rate = 4096;

    let train_labels_path = Path::new("data/train-labels-idx1-ubyte");
    let train_data_path = Path::new("data/train-images-idx3-ubyte");
    read_mnist(&train_labels_path, 2049, &train_data_path, 2051, 16, Some(4096));

    let training_vec = vec![(
        Tensor::from_vec(Vec2(4, 2), vec![
        0.0, 0.0,
        0.0, 1.0,
        1.0, 0.0,
        1.0, 1.0,
        ]),
        Tensor::from_vec(Vec2(4, 2), vec![
        0.0, 1.0,
        1.0, 0.0,
        1.0, 0.0,
        0.0, 1.0,
        ]),
    )];

    let mut history = Context::<f32>::with_capacity(5 * layers + 4);

    for i in 0..iterations {
        let (ref a, ref b) = training_vec[i % training_vec.len()];
        variable_context.set(input_x.get_id(), a.clone());
        variable_context.set(target_y.get_id(), b.clone());

        k::train(xentropy.clone(), &mut state_context, &variable_context, &mut history, learning_rate);

        // test print
        if i % print_rate == 0 {
            println!("\niteration: {} | cross entropy cost: {}", i, k::execute(xentropy.clone(), &state_context, &variable_context).get(Vec2(0, 0)));
        }
    }

    ////////////////
    // Final test //
    ////////////////

}
<commit_msg>mnist todo final check<commit_after>extern crate ktensor as k;
use k::{Arc, Vec2, Tensor, Context, Graph, State, Variable};
use std::path::{Path};
use std::fs::{File};
use std::io::{BufReader, Read};
use std::error::{Error};
use std::cmp;

fn read_u8(reader: &mut Read) -> u8 {
    use std::mem;

    let mut buf: [u8; 1] = [0];
    match reader.read_exact(&mut buf).map(|_| {
        let data: u8 = unsafe { mem::transmute(buf) };
        data
    }) {
        Err(reason) => panic!("failed to read u8: {}", Error::description(&reason)),
        Ok(byte)    => byte,
    }
}

fn read_u32(reader: &mut Read) -> u32 {
    use std::mem;

    let mut buf: [u8; 4] = [0, 0, 0, 0];
    match reader.read_exact(&mut buf).map(|_| {
        let data: u32 = unsafe { mem::transmute(buf) };
        data
    }) {
        Err(reason) => panic!("failed to read u32: {}", Error::description(&reason)),
        Ok(byte)    => byte,
    }
}

fn read_mnist(labels_path: &Path, labels_checknum: u32, data_path: &Path, data_checknum: u32, batch_size: usize, sample_size: Option<usize>) -> Vec<(Tensor<f32>, Tensor<f32>)> {
    let labels_file = match File::open(&labels_path) {
        Err(reason) => panic!("failed to open {}: {}", labels_path.display(), Error::description(&reason)),
        Ok(file)    => file,
    };
    let data_file = match File::open(&data_path) {
        Err(reason) => panic!("failed to open {}: {}", data_path.display(), Error::description(&reason)),
        Ok(file)    => file,
    };
    let ref mut labels_reader = BufReader::new(labels_file);
    let ref mut data_reader = BufReader::new(data_file);

    let labels_magic = u32::from_be(read_u32(labels_reader));
    let data_magic = u32::from_be(read_u32(data_reader));

    assert_eq!(labels_magic, labels_checknum);
    assert_eq!(data_magic, data_checknum);

    let labels_count = u32::from_be(read_u32(labels_reader)) as usize;
    let data_count = u32::from_be(read_u32(data_reader)) as usize;
    let sample_count = cmp::min(labels_count, data_count);
    let sample_count = cmp::min(sample_count, sample_size.unwrap_or(sample_count));

    let rows = u32::from_be(read_u32(data_reader)) as usize;
    let columns = u32::from_be(read_u32(data_reader)) as usize;

    let mut sample_vec: Vec<(Tensor<f32>, Tensor<f32>)> = Vec::with_capacity(sample_count/batch_size);
    for _ in 0..sample_count/batch_size {
        let mut sample_data = vec![0u8; batch_size*rows*columns];
        match data_reader.read_exact(sample_data.as_mut()) {
            Err(reason) => panic!("failed to read data byte array: {}", Error::description(&reason)),
            Ok(_)       => (),
        }
        let mut sample_labels_byte = vec![0u8; batch_size];
        match labels_reader.read_exact(sample_labels.as_mut()) {
            Err(reason) => panic!("failed to read labels byte array: {}", Error::description(&reason)),
            Ok(_)       => (),
        }

        let sample_data = sample_data.map(|x| x as f32);
        let sample_labels = Vec<f32>::with_capacity(batch_size * 10);
        for i in sample_labels_byte {
            match i {
                0 => sample_labels.extend([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                1 => sample_labels.extend([0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                2 => sample_labels.extend([0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                3 => sample_labels.extend([0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                4 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                5 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0].iter().cloned()),
                6 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0].iter().cloned()),
                7 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0].iter().cloned()),
                8 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0].iter().cloned()),
                9 => sample_labels.extend([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0].iter().cloned()),
                _ => (),
            }
        }

        sample_vec.push((Tensor::from_vec(Vec2(batch_size, rows*columns), sample_data), Tensor::from_vec(Vec2(batch_size, 10), sample_labels)));
    }

    sample_vec
}

#[test]
#[ignore]
fn mnist(){
    ///////////////
    // Variables //
    ///////////////

    let input_x = Arc::new(Variable::new("input_x".to_string(), Vec2(0, 28 * 28)));
    let target_y = Arc::new(Variable::new("target_y".to_string(), Vec2(0, 10)));

    // Initialize
    let mut variable_context = Context::<f32>::with_capacity(2);
    Variable::init_f32(vec![input_x.clone(), target_y.clone()], &mut variable_context);

    ///////////
    // Graph //
    ///////////

    let layers: usize = 2;
    let mut states = Vec::<Arc<State>>::with_capacity(2 * layers);
    let mut graph_head: Arc<Graph<f32>> = input_x.clone();

    {
        let w = Arc::new(State::new(format!("weight_w_{}", 1), Vec2(28 * 28, 16)));
        let b = Arc::new(State::new(format!("weight_b_{}", 1), Vec2(1, 16)));

        let dot = Arc::new(k::op::dot::<f32>(format!("layer_{}_dot", 1), graph_head.clone(), w.clone()));
        let add = Arc::new(k::op::add::<f32>(format!("layer_{}_add", 1), dot, b.clone()));

        let relu = Arc::new(k::op::relu_f32(format!("layer_{}_relu", 1), add));

        graph_head = relu;

        states.push(w);
        states.push(b);
    }

    {
        let w = Arc::new(State::new(format!("weight_w_{}", 2), Vec2(16, 10)));
        let b = Arc::new(State::new(format!("weight_b_{}", 2), Vec2(1, 10)));

        let dot = Arc::new(k::op::dot::<f32>(format!("layer_{}_dot", 2), graph_head.clone(), w.clone()));
        let add = Arc::new(k::op::add::<f32>(format!("layer_{}_add", 2), dot, b.clone()));

        let relu = Arc::new(k::op::relu_f32(format!("layer_{}_relu", 2), add));

        graph_head = relu;

        states.push(w);
        states.push(b);
    }

    let softmax = Arc::new(k::op::softmax_f32(format!("layer_{}_softmax", 3), graph_head.clone()));
    let xentropy = Arc::new(k::cost::softmax_cross_entropy_f32(format!("layer_{}_xentropy", 3), softmax.clone(), target_y.clone()));

    // initialize states
    let mut state_context = Context::<f32>::with_capacity(2 * layers);
    State::init_f32(states, &mut state_context);

    //////////////
    // Training //
    //////////////
    {
        // Parameters
        let batch_size = 16;
        let sample_size = Some(4096);
        let learning_rate = -0.1;
        let iterations = 16384;
        let print_rate = 4096;

        let train_labels_path = Path::new("data/train-labels-idx1-ubyte");
        let train_data_path = Path::new("data/train-images-idx3-ubyte");
        let training_vec = read_mnist(&train_labels_path, 2049, &train_data_path, 2051, batch_size, sample_size);

        let mut history = Context::<f32>::with_capacity(5 * layers + 4);

        let training_vec_length = training_vec.len();
        for i in 0..iterations {
            let (ref a, ref b) = training_vec[i % training_vec_length];
            variable_context.set(input_x.get_id(), a.clone());
            variable_context.set(target_y.get_id(), b.clone());

            k::train(xentropy.clone(), &mut state_context, &variable_context, &mut history, learning_rate);

            // test print
            if i % print_rate == 0 {
                println!("\niteration: {} | cross entropy cost: {}", i,
                k::execute(xentropy.clone(), &state_context, &variable_context).get(Vec2(0, 0)));
            }
        }
    }

    ////////////////
    // Final test //
    ////////////////
    {
        // Parameters
        let batch_size = 1;
        let sample_size = None;
        let iterations = 16384;
        let print_rate = 4096;

        let test_labels_path = Path::new("data/t10k-labels-idx1-ubyte");
        let test_data_path = Path::new("data/t10k-images-idx3-ubyte");
        let test_vec = read_mnist(&test_labels_path, 2049, &test_data_path, 2051, batch_size, sample_size);

        let mut history = Context::<f32>::with_capacity(5 * layers + 4);

        let score = 0.0;
        let test_vec_length = test_vec.len();
        for i in 0..iterations {
            let (ref a, ref b) = test_vec[i % test_vec_length];
            variable_context.set(input_x.get_id(), a.clone());
            variable_context.set(target_y.get_id(), b.clone());

        }
    }
}
<|endoftext|>


<commit_before>// Rx -- Reactive programming for Rust
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate rx;

use rx::Observable;

#[test]
fn subscribe_next_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    values.subscribe_next(|&x| received.push(x));
    assert_eq!(&values[..], &received[..]);
}

#[test]
fn subscribe_completed_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    let mut completed = false;
    values.subscribe_completed(|&x| received.push(x), || completed = true);
    assert_eq!(&values[..], &received[..]);
    assert!(completed);
}

#[test]
fn subscribe_error_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    let mut completed = false;
    let mut failed = false;
    values.subscribe_error(|&x| received.push(x), || completed = true, |_err| failed = true);
    assert_eq!(&values[..], &received[..]);
    assert!(completed);
    assert!(!failed);
}

#[test]
fn subscribe_option_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let expected = &[Some(2u8), Some(3), Some(5), Some(7), Some(11), Some(13), None];
    let mut received = Vec::new();
    values.subscribe_option(|x| received.push(x.cloned()));
    assert_eq!(&received[..], &expected[..]);
}

#[test]
fn subscribe_result_slice() {
    let mut values = &[2u8, 3, 5, 7];
    let expected = &[Ok(Some(2u8)), Ok(Some(3)), Ok(Some(5)), Ok(Some(7)), Ok(None)];
    let mut received: Vec<Result<Option<u8>, ()>> = Vec::new();
    values.subscribe_result(|x| received.push(x.map(|y| y.cloned())));
    assert_eq!(&received[..], &expected[..]);
}
<commit_msg>Remove redundant type annotation<commit_after>// Rx -- Reactive programming for Rust
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate rx;

use rx::Observable;

#[test]
fn subscribe_next_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    values.subscribe_next(|&x| received.push(x));
    assert_eq!(&values[..], &received[..]);
}

#[test]
fn subscribe_completed_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    let mut completed = false;
    values.subscribe_completed(|&x| received.push(x), || completed = true);
    assert_eq!(&values[..], &received[..]);
    assert!(completed);
}

#[test]
fn subscribe_error_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let mut received = Vec::new();
    let mut completed = false;
    let mut failed = false;
    values.subscribe_error(|&x| received.push(x), || completed = true, |_err| failed = true);
    assert_eq!(&values[..], &received[..]);
    assert!(completed);
    assert!(!failed);
}

#[test]
fn subscribe_option_slice() {
    let mut values = &[2u8, 3, 5, 7, 11, 13];
    let expected = &[Some(2u8), Some(3), Some(5), Some(7), Some(11), Some(13), None];
    let mut received = Vec::new();
    values.subscribe_option(|x| received.push(x.cloned()));
    assert_eq!(&received[..], &expected[..]);
}

#[test]
fn subscribe_result_slice() {
    let mut values = &[2u8, 3, 5, 7];
    let expected = &[Ok(Some(2u8)), Ok(Some(3)), Ok(Some(5)), Ok(Some(7)), Ok(None)];
    let mut received = Vec::new();
    values.subscribe_result(|x| received.push(x.map(|y| y.cloned())));
    assert_eq!(&received[..], &expected[..]);
}
<|endoftext|>