<commit_before>use std::result::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder<'a> {
    root: &'a mut MutableTreeNode
}

impl<'a> TreeNodeEncoder<'a> {
    fn new(root: &'a mut MutableTreeNode) -> TreeNodeEncoder<'a> {
        TreeNodeEncoder { root: root }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl<'a> Encoder for TreeNodeEncoder<'a> {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Nothing);
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v));
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Bool(v));
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v));
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v as f64));
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(v.to_string()));
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}
<commit_msg>Version of emit_struct_field with the thing that rust is too pedantic to do commented out (it'd work if f() used a better lifetime specifier)<commit_after>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder<'a> {
    root: &'a mut MutableTreeNode
}

impl<'a> TreeNodeEncoder<'a> {
    fn new(root: &'a mut MutableTreeNode) -> TreeNodeEncoder<'a> {
        TreeNodeEncoder { root: root }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl<'a> Encoder for TreeNodeEncoder<'a> {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Nothing);
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v));
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Bool(v));
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v));
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v as f64));
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(v.to_string()));
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(name.to_string()));

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        // Insert a new node into the tree
        let new_node = BasicTree::new(f_name, ());

        self.root.get_child_ref().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Encode the field into the new node (would be super-elegant if this works but Rust is all 'nooope, you need to write a
        // billion more lines of code'). I know *why* but this is stupid, if the encoder function had a better lifetime specifier
        // it'd be unnecessary.
        // Rust thinks that f() needs stuff with a lifetime the same as this struct rather than stuff with a lifetime as long
        // as the function call (it's not obvious from a casual reading of the definition, rust likes to be inscrutable).
        // This means we need to do dumb stuff to make it work.
        /*
        let node_encoder = TreeNodeEncoder::new(&mut new_node);
        f(&mut node_encoder);
        */

        // Save the node we just created and update the tree
        self.root.set_child_ref(Rc::new(new_node));

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use backend::Backend;
use query_builder::{AsQuery, QueryFragment, QueryId};
use query_source::Queryable;
use result::*;
use types::HasSqlType;

pub trait SimpleConnection {
    #[doc(hidden)]
    fn batch_execute(&self, query: &str) -> QueryResult<()>;
}

pub trait Connection: SimpleConnection + Sized {
    type Backend: Backend;

    /// Establishes a new connection to the database at the given URL. The URL
    /// should be a valid connection string for a given backend. See the
    /// documentation for the specific backend for specifics.
    fn establish(database_url: &str) -> ConnectionResult<Self>;

    /// Executes the given function inside of a database transaction. When
    /// a transaction is already occurring, savepoints will be used to emulate a nested
    /// transaction.
    ///
    /// If the function returns an `Ok`, that value will be returned.  If the
    /// function returns an `Err`,
    /// [`TransactionError::UserReturnedError`](result/enum.TransactionError.html#variant.UserReturnedError)
    /// will be returned wrapping that value.
    fn transaction<T, E, F>(&self, f: F) -> TransactionResult<T, E> where
        F: FnOnce() -> Result<T, E>,
    {
        try!(self.begin_transaction());
        match f() {
            Ok(value) => {
                try!(self.commit_transaction());
                Ok(value)
            },
            Err(e) => {
                try!(self.rollback_transaction());
                Err(TransactionError::UserReturnedError(e))
            },
        }
    }

    /// Creates a transaction that will never be committed. This is useful for
    /// tests. Panics if called while inside of a transaction.
    fn begin_test_transaction(&self) -> QueryResult<()> {
        assert_eq!(self.get_transaction_depth(), 0);
        self.begin_transaction()
    }

    /// Executes the given function inside a transaction, but does not commit
    /// it. Panics if the given function returns an `Err`.
    fn test_transaction<T, E, F>(&self, f: F) -> T where
        F: FnOnce() -> Result<T, E>,
    {
        let mut user_result = None;
        let _ = self.transaction::<(), _, _>(|| {
            user_result = f().ok();
            Err(())
        });
        user_result.expect("Transaction did not succeed")
    }

    #[doc(hidden)]
    fn execute(&self, query: &str) -> QueryResult<usize>;

    #[doc(hidden)]
    fn query_one<T, U>(&self, source: T) -> QueryResult<U> where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        Self::Backend: HasSqlType<T::SqlType>,
        U: Queryable<T::SqlType, Self::Backend>,
    {
        self.query_all(source)
            .and_then(|e: Vec<U>| e.into_iter().next().ok_or(Error::NotFound))
    }

    #[doc(hidden)]
    fn query_all<T, U>(&self, source: T) -> QueryResult<Vec<U>> where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        Self::Backend: HasSqlType<T::SqlType>,
        U: Queryable<T::SqlType, Self::Backend>;

    #[doc(hidden)]
    fn execute_returning_count<T>(&self, source: &T) -> QueryResult<usize> where
        T: QueryFragment<Self::Backend> + QueryId;

    #[doc(hidden)] fn silence_notices<F: FnOnce() -> T, T>(&self, f: F) -> T;
    #[doc(hidden)] fn begin_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn rollback_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn commit_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn get_transaction_depth(&self) -> i32;

    #[doc(hidden)] fn setup_helper_functions(&self);
}
<commit_msg>Unused import<commit_after>use backend::Backend;
use query_builder::{AsQuery, QueryFragment, QueryId};
use query_source::Queryable;
use result::*;
use types::HasSqlType;

pub trait SimpleConnection {
    #[doc(hidden)]
    fn batch_execute(&self, query: &str) -> QueryResult<()>;
}

pub trait Connection: SimpleConnection + Sized {
    type Backend: Backend;

    /// Establishes a new connection to the database at the given URL. The URL
    /// should be a valid connection string for a given backend. See the
    /// documentation for the specific backend for specifics.
    fn establish(database_url: &str) -> ConnectionResult<Self>;

    /// Executes the given function inside of a database transaction. When
    /// a transaction is already occurring, savepoints will be used to emulate a nested
    /// transaction.
    ///
    /// If the function returns an `Ok`, that value will be returned.  If the
    /// function returns an `Err`,
    /// [`TransactionError::UserReturnedError`](result/enum.TransactionError.html#variant.UserReturnedError)
    /// will be returned wrapping that value.
    fn transaction<T, E, F>(&self, f: F) -> TransactionResult<T, E> where
        F: FnOnce() -> Result<T, E>,
    {
        try!(self.begin_transaction());
        match f() {
            Ok(value) => {
                try!(self.commit_transaction());
                Ok(value)
            },
            Err(e) => {
                try!(self.rollback_transaction());
                Err(TransactionError::UserReturnedError(e))
            },
        }
    }

    /// Creates a transaction that will never be committed. This is useful for
    /// tests. Panics if called while inside of a transaction.
    fn begin_test_transaction(&self) -> QueryResult<()> {
        assert_eq!(self.get_transaction_depth(), 0);
        self.begin_transaction()
    }

    /// Executes the given function inside a transaction, but does not commit
    /// it. Panics if the given function returns an `Err`.
    fn test_transaction<T, E, F>(&self, f: F) -> T where
        F: FnOnce() -> Result<T, E>,
    {
        let mut user_result = None;
        let _ = self.transaction::<(), _, _>(|| {
            user_result = f().ok();
            Err(())
        });
        user_result.expect("Transaction did not succeed")
    }

    #[doc(hidden)]
    fn execute(&self, query: &str) -> QueryResult<usize>;

    #[doc(hidden)]
    fn query_one<T, U>(&self, source: T) -> QueryResult<U> where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        Self::Backend: HasSqlType<T::SqlType>,
        U: Queryable<T::SqlType, Self::Backend>,
    {
        self.query_all(source)
            .and_then(|e: Vec<U>| e.into_iter().next().ok_or(Error::NotFound))
    }

    #[doc(hidden)]
    fn query_all<T, U>(&self, source: T) -> QueryResult<Vec<U>> where
        T: AsQuery,
        T::Query: QueryFragment<Self::Backend> + QueryId,
        Self::Backend: HasSqlType<T::SqlType>,
        U: Queryable<T::SqlType, Self::Backend>;

    #[doc(hidden)]
    fn execute_returning_count<T>(&self, source: &T) -> QueryResult<usize> where
        T: QueryFragment<Self::Backend> + QueryId;

    #[doc(hidden)] fn silence_notices<F: FnOnce() -> T, T>(&self, f: F) -> T;
    #[doc(hidden)] fn begin_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn rollback_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn commit_transaction(&self) -> QueryResult<()>;
    #[doc(hidden)] fn get_transaction_depth(&self) -> i32;

    #[doc(hidden)] fn setup_helper_functions(&self);
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Jordi Boggiano <j.boggiano@seld.be>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/* last synced with: env (GNU coreutils) 8.13 */

// spell-checker:ignore (ToDO) chdir execvp progname subcommand subcommands unsets

#[macro_use]
extern crate clap;

use clap::{App, AppSettings, Arg};
use ini::Ini;
use std::borrow::Cow;
use std::env;
use std::io::{self, Write};
use std::iter::Iterator;
use std::process::Command;

const USAGE: &str = "env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
const AFTER_HELP: &str = "\
A mere - implies -i. If no COMMAND, print the resulting environment.
";

struct Options<'a> {
    ignore_env: bool,
    null: bool,
    running_directory: Option<&'a str>,
    files: Vec<&'a str>,
    unsets: Vec<&'a str>,
    sets: Vec<(&'a str, &'a str)>,
    program: Vec<&'a str>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    let stdout_raw = io::stdout();
    let mut stdout = stdout_raw.lock();
    for (n, v) in env::vars() {
        write!(stdout, "{}={}{}", n, v, if null { '\0' } else { '\n' }).unwrap();
    }
}

fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<bool, i32> {
    // is it a NAME=VALUE like opt ?
    if let Some(idx) = opt.find('=') {
        // yes, so push name, value pair
        let (name, value) = opt.split_at(idx);
        opts.sets.push((name, &value['='.len_utf8()..]));

        Ok(false)
    } else {
        // no, it's a program-like opt
        parse_program_opt(opts, opt).map(|_| true)
    }
}

fn parse_program_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<(), i32> {
    if opts.null {
        eprintln!("{}: cannot specify --null (-0) with command", crate_name!());
        eprintln!("Type \"{} --help\" for detailed information", crate_name!());
        Err(1)
    } else {
        opts.program.push(opt);
        Ok(())
    }
}

fn load_config_file(opts: &mut Options) -> Result<(), i32> {
    // NOTE: config files are parsed using an INI parser b/c it's available and compatible with ".env"-style files
    //   ... * but support for actual INI files, although working, is not intended, nor claimed
    for &file in &opts.files {
        let conf = if file == "-" {
            let stdin = io::stdin();
            let mut stdin_locked = stdin.lock();
            Ini::read_from(&mut stdin_locked)
        } else {
            Ini::load_from_file(file)
        };

        let conf = conf.map_err(|error| {
            eprintln!("env: error: \"{}\": {}", file, error);
            1
        })?;

        for (_, prop) in &conf {
            // ignore all INI section lines (treat them as comments)
            for (key, value) in prop.iter() {
                env::set_var(key, value);
            }
        }
    }

    Ok(())
}

#[cfg(not(windows))]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    let progname = Cow::from(args[0]);
    (progname, &args[1..])
}

#[cfg(windows)]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    args.insert(0, "/d/c");
    let progname = env::var("ComSpec")
        .map(Cow::from)
        .unwrap_or_else(|_| Cow::from("cmd"));

    (progname, &args[..])
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .usage(USAGE)
        .after_help(AFTER_HELP)
        .setting(AppSettings::AllowExternalSubcommands)
        .arg(Arg::with_name("ignore-environment")
            .short("i")
            .long("ignore-environment")
            .help("start with an empty environment"))
        .arg(Arg::with_name("chdir")
            .short("c")
            .long("chdir")
            .takes_value(true)
            .number_of_values(1)
            .value_name("DIR")
            .help("change working directory to DIR"))
        .arg(Arg::with_name("null")
            .short("0")
            .long("null")
            .help("end each output line with a 0 byte rather than a newline (only valid when \
                    printing the environment)"))
        .arg(Arg::with_name("file")
            .short("f")
            .long("file")
            .takes_value(true)
            .number_of_values(1)
            .value_name("PATH")
            .multiple(true)
            .help("read and set variables from a \".env\"-style configuration file (prior to any \
                    unset and/or set)"))
        .arg(Arg::with_name("unset")
            .short("u")
            .long("unset")
            .takes_value(true)
            .number_of_values(1)
            .value_name("NAME")
            .multiple(true)
            .help("remove variable from the environment"))
}

fn run_env(args: impl uucore::Args) -> Result<(), i32> {
    let app = uu_app();
    let matches = app.get_matches_from(args);

    let ignore_env = matches.is_present("ignore-environment");
    let null = matches.is_present("null");
    let running_directory = matches.value_of("chdir");
    let files = matches
        .values_of("file")
        .map(Iterator::collect)
        .unwrap_or_else(|| Vec::with_capacity(0));
    let unsets = matches
        .values_of("unset")
        .map(Iterator::collect)
        .unwrap_or_else(|| Vec::with_capacity(0));

    let mut opts = Options {
        ignore_env,
        null,
        running_directory,
        files,
        unsets,
        sets: vec![],
        program: vec![],
    };

    // change directory
    if let Some(d) = opts.running_directory {
        match env::set_current_dir(d) {
            Ok(()) => d,
            Err(error) => {
                eprintln!("env: cannot change directory to \"{}\": {}", d, error);
                return Err(125);
            }
        };
    }

    // we handle the name, value pairs and the program to be executed by treating them as external
    // subcommands in clap
    if let (external, Some(matches)) = matches.subcommand() {
        let mut begin_prog_opts = false;

        if external == "-" {
            // "-" implies -i and stop parsing opts
            opts.ignore_env = true;
        } else {
            begin_prog_opts = parse_name_value_opt(&mut opts, external)?;
        }

        if let Some(mut iter) = matches.values_of("") {
            // read NAME=VALUE arguments (and up to a single program argument)
            while !begin_prog_opts {
                if let Some(opt) = iter.next() {
                    begin_prog_opts = parse_name_value_opt(&mut opts, opt)?;
                } else {
                    break;
                }
            }

            // read any leftover program arguments
            for opt in iter {
                parse_program_opt(&mut opts, opt)?;
            }
        }
    }

    // NOTE: we manually set and unset the env vars below rather than using Command::env() to more
    //       easily handle the case where no command is given

    // remove all env vars if told to ignore presets
    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    // load .env-style config file prior to those given on the command-line
    load_config_file(&mut opts)?;

    // unset specified env vars
    for name in &opts.unsets {
        env::remove_var(name);
    }

    // set specified env vars
    for &(name, val) in &opts.sets {
        // FIXME: set_var() panics if name is an empty string
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        // we need to execute a command
        let (prog, args) = build_command(&mut opts.program);

        // FIXME: this should just use execvp() (no fork()) on Unix-like systems
        match Command::new(&*prog).args(args).status() {
            Ok(exit) if !exit.success() => return Err(exit.code().unwrap()),
            Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(127),
            Err(_) => return Err(126),
            Ok(_) => (),
        }
    } else {
        // no program provided, so just dump all env vars to stdout
        print_env(opts.null);
    }

    Ok(())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    match run_env(args) {
        Ok(()) => 0,
        Err(code) => code,
    }
}
<commit_msg>env: added UResult<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Jordi Boggiano <j.boggiano@seld.be>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/* last synced with: env (GNU coreutils) 8.13 */

// spell-checker:ignore (ToDO) chdir execvp progname subcommand subcommands unsets

#[macro_use]
extern crate clap;

#[macro_use]
extern crate uucore;

use clap::{App, AppSettings, Arg};
use ini::Ini;
use std::borrow::Cow;
use std::env;
use std::io::{self, Write};
use std::iter::Iterator;
use std::process::Command;
use uucore::error::{UResult, USimpleError};

const USAGE: &str = "env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
const AFTER_HELP: &str = "\
A mere - implies -i. If no COMMAND, print the resulting environment.
";

struct Options<'a> {
    ignore_env: bool,
    null: bool,
    running_directory: Option<&'a str>,
    files: Vec<&'a str>,
    unsets: Vec<&'a str>,
    sets: Vec<(&'a str, &'a str)>,
    program: Vec<&'a str>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    let stdout_raw = io::stdout();
    let mut stdout = stdout_raw.lock();
    for (n, v) in env::vars() {
        write!(stdout, "{}={}{}", n, v, if null { '\0' } else { '\n' }).unwrap();
    }
}

fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<bool, i32> {
    // is it a NAME=VALUE like opt ?
    if let Some(idx) = opt.find('=') {
        // yes, so push name, value pair
        let (name, value) = opt.split_at(idx);
        opts.sets.push((name, &value['='.len_utf8()..]));

        Ok(false)
    } else {
        // no, it's a program-like opt
        parse_program_opt(opts, opt).map(|_| true)
    }
}

fn parse_program_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<(), i32> {
    if opts.null {
        eprintln!("{}: cannot specify --null (-0) with command", crate_name!());
        eprintln!("Type \"{} --help\" for detailed information", crate_name!());
        Err(1)
    } else {
        opts.program.push(opt);
        Ok(())
    }
}

fn load_config_file(opts: &mut Options) -> UResult<()> {
    // NOTE: config files are parsed using an INI parser b/c it's available and compatible with ".env"-style files
    //   ... * but support for actual INI files, although working, is not intended, nor claimed
    for &file in &opts.files {
        let conf = if file == "-" {
            let stdin = io::stdin();
            let mut stdin_locked = stdin.lock();
            Ini::read_from(&mut stdin_locked)
        } else {
            Ini::load_from_file(file)
        };

        let conf = conf.map_err(|error| {
            eprintln!("env: error: \"{}\": {}", file, error);
            1
        })?;

        for (_, prop) in &conf {
            // ignore all INI section lines (treat them as comments)
            for (key, value) in prop.iter() {
                env::set_var(key, value);
            }
        }
    }

    Ok(())
}

#[cfg(not(windows))]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    let progname = Cow::from(args[0]);
    (progname, &args[1..])
}

#[cfg(windows)]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    args.insert(0, "/d/c");
    let progname = env::var("ComSpec")
        .map(Cow::from)
        .unwrap_or_else(|_| Cow::from("cmd"));

    (progname, &args[..])
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .usage(USAGE)
        .after_help(AFTER_HELP)
        .setting(AppSettings::AllowExternalSubcommands)
        .arg(Arg::with_name("ignore-environment")
            .short("i")
            .long("ignore-environment")
            .help("start with an empty environment"))
        .arg(Arg::with_name("chdir")
            .short("c")
            .long("chdir")
            .takes_value(true)
            .number_of_values(1)
            .value_name("DIR")
            .help("change working directory to DIR"))
        .arg(Arg::with_name("null")
            .short("0")
            .long("null")
            .help("end each output line with a 0 byte rather than a newline (only valid when \
                    printing the environment)"))
        .arg(Arg::with_name("file")
            .short("f")
            .long("file")
            .takes_value(true)
            .number_of_values(1)
            .value_name("PATH")
            .multiple(true)
            .help("read and set variables from a \".env\"-style configuration file (prior to any \
                    unset and/or set)"))
        .arg(Arg::with_name("unset")
            .short("u")
            .long("unset")
            .takes_value(true)
            .number_of_values(1)
            .value_name("NAME")
            .multiple(true)
            .help("remove variable from the environment"))
}

fn run_env(args: impl uucore::Args) -> UResult<()> {
    let app = uu_app();
    let matches = app.get_matches_from(args);

    let ignore_env = matches.is_present("ignore-environment");
    let null = matches.is_present("null");
    let running_directory = matches.value_of("chdir");
    let files = matches
        .values_of("file")
        .map(Iterator::collect)
        .unwrap_or_else(|| Vec::with_capacity(0));
    let unsets = matches
        .values_of("unset")
        .map(Iterator::collect)
        .unwrap_or_else(|| Vec::with_capacity(0));

    let mut opts = Options {
        ignore_env,
        null,
        running_directory,
        files,
        unsets,
        sets: vec![],
        program: vec![],
    };

    // change directory
    if let Some(d) = opts.running_directory {
        match env::set_current_dir(d) {
            Ok(()) => d,
            Err(error) => {
                return Err(USimpleError::new(
                    125,
                    format!("env: cannot change directory to \"{}\": {}", d, error),
                ));
            }
        };
    }

    // we handle the name, value pairs and the program to be executed by treating them as external
    // subcommands in clap
    if let (external, Some(matches)) = matches.subcommand() {
        let mut begin_prog_opts = false;

        if external == "-" {
            // "-" implies -i and stop parsing opts
            opts.ignore_env = true;
        } else {
            begin_prog_opts = parse_name_value_opt(&mut opts, external)?;
        }

        if let Some(mut iter) = matches.values_of("") {
            // read NAME=VALUE arguments (and up to a single program argument)
            while !begin_prog_opts {
                if let Some(opt) = iter.next() {
                    begin_prog_opts = parse_name_value_opt(&mut opts, opt)?;
                } else {
                    break;
                }
            }

            // read any leftover program arguments
            for opt in iter {
                parse_program_opt(&mut opts, opt)?;
            }
        }
    }

    // NOTE: we manually set and unset the env vars below rather than using Command::env() to more
    //       easily handle the case where no command is given

    // remove all env vars if told to ignore presets
    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    // load .env-style config file prior to those given on the command-line
    load_config_file(&mut opts)?;

    // unset specified env vars
    for name in &opts.unsets {
        env::remove_var(name);
    }

    // set specified env vars
    for &(name, val) in &opts.sets {
        // FIXME: set_var() panics if name is an empty string
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        // we need to execute a command
        let (prog, args) = build_command(&mut opts.program);

        // FIXME: this should just use execvp() (no fork()) on Unix-like systems
        match Command::new(&*prog).args(args).status() {
            Ok(exit) if !exit.success() => return Err(exit.code().unwrap().into()),
            Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(127.into()),
            Err(_) => return Err(126.into()),
            Ok(_) => (),
        }
    } else {
        // no program provided, so just dump all env vars to stdout
        print_env(opts.null);
    }

    Ok(())
}

#[uucore_procs::gen_uumain]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    run_env(args)
}
<|endoftext|>


<commit_before>//! Linear algebra utils module.
//!
//! Contains support methods for linear algebra structs.

use std::cmp;
use libnum::{Zero};
use std::ops::{Add, Mul, Sub};

/// Compute dot product of two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::dot(&a,&b);
/// ```
pub fn dot<T: Copy + Zero + Add<T, Output=T> + Mul<T, Output=T>>(u: &[T], v: &[T]) -> T {
    let len = cmp::min(u.len(), v.len());
    let mut xs = &u[..len];
    let mut ys = &v[..len];

    let mut s = T::zero();
    let (mut p0, mut p1, mut p2, mut p3, mut p4, mut p5, mut p6, mut p7) =
        (T::zero(), T::zero(), T::zero(), T::zero(),
            T::zero(), T::zero(), T::zero(), T::zero());

    while xs.len() >= 8 {
        p0 = p0 + xs[0] * ys[0];
        p1 = p1 + xs[1] * ys[1];
        p2 = p2 + xs[2] * ys[2];
        p3 = p3 + xs[3] * ys[3];
        p4 = p4 + xs[4] * ys[4];
        p5 = p5 + xs[5] * ys[5];
        p6 = p6 + xs[6] * ys[6];
        p7 = p7 + xs[7] * ys[7];

        xs = &xs[8..];
        ys = &ys[8..];
    }
    s = s + p0 + p4;
    s = s + p1 + p5;
    s = s + p2 + p6;
    s = s + p3 + p7;

    for i in 0..xs.len() {
        s = s + xs[i] * ys[i];
    }
    s
 }

/// Compute vector sum of two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::vec_sum(&a,&b);
///
/// assert_eq!(c, vec![2.0,4.0, 6.0, 8.0]);
/// ```
pub fn vec_sum<T: Copy + Zero + Add<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] + ys[i];
    }
    sum_data
}

/// Compute vector difference two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::vec_sub(&a,&b);
///
/// assert_eq!(c, vec![0.0; 4]);
/// ```
pub fn vec_sub<T: Copy + Zero + Sub<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] - ys[i];
    }
    sum_data
}

/// Find argmax of slice.
///
/// Returns index of first occuring maximum.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::argmax(&a);
/// assert_eq!(c, 3);
/// ```
pub fn argmax<T: Copy + PartialOrd>(u: &[T]) -> usize {
    assert!(u.len() != 0);

    let mut max_index = 0;
    let mut max = u[max_index];

    for (i, v) in (u.iter()).enumerate() {
        if max < *v {
            max_index = i;
            max = *v;
        }
    }

    max_index
}

/// Find index of value in slice.
///
/// Returns index of first occuring value.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::find(&a, 3.0);
/// assert_eq!(c, 2);
/// ```
pub fn find<T: PartialEq>(p: &[T], u: T) -> usize {
        for (i, v) in p.iter().enumerate() {
            if *v == u {
                return i;
            }
        }

        panic!("Value not found.")
    }<commit_msg>Adding elementwise arithmetic.<commit_after>//! Linear algebra utils module.
//!
//! Contains support methods for linear algebra structs.

use std::cmp;
use libnum::{Zero};
use std::ops::{Add, Mul, Sub, Div};

/// Compute dot product of two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::dot(&a,&b);
/// ```
pub fn dot<T: Copy + Zero + Add<T, Output=T> + Mul<T, Output=T>>(u: &[T], v: &[T]) -> T {
    let len = cmp::min(u.len(), v.len());
    let mut xs = &u[..len];
    let mut ys = &v[..len];

    let mut s = T::zero();
    let (mut p0, mut p1, mut p2, mut p3, mut p4, mut p5, mut p6, mut p7) =
        (T::zero(), T::zero(), T::zero(), T::zero(),
            T::zero(), T::zero(), T::zero(), T::zero());

    while xs.len() >= 8 {
        p0 = p0 + xs[0] * ys[0];
        p1 = p1 + xs[1] * ys[1];
        p2 = p2 + xs[2] * ys[2];
        p3 = p3 + xs[3] * ys[3];
        p4 = p4 + xs[4] * ys[4];
        p5 = p5 + xs[5] * ys[5];
        p6 = p6 + xs[6] * ys[6];
        p7 = p7 + xs[7] * ys[7];

        xs = &xs[8..];
        ys = &ys[8..];
    }
    s = s + p0 + p4;
    s = s + p1 + p5;
    s = s + p2 + p6;
    s = s + p3 + p7;

    for i in 0..xs.len() {
        s = s + xs[i] * ys[i];
    }
    s
 }

/// Compute vector sum of two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::vec_sum(&a,&b);
///
/// assert_eq!(c, vec![2.0,4.0, 6.0, 8.0]);
/// ```
pub fn vec_sum<T: Copy + Zero + Add<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] + ys[i];
    }
    sum_data
}

/// Compute vector difference two slices.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::vec_sub(&a,&b);
///
/// assert_eq!(c, vec![0.0; 4]);
/// ```
pub fn vec_sub<T: Copy + Zero + Sub<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] - ys[i];
    }
    sum_data
}

/// Computes elementwise multiplication.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::ele_mul(&a,&b);
///
/// assert_eq!(c, vec![1.0,4.0,9.0,16.0]);
/// ```
pub fn ele_mul<T: Copy + Zero + Mul<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] * ys[i];
    }
    sum_data
}

/// Computes elementwise division.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
/// let b = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::ele_div(&a,&b);
///
/// assert_eq!(c, vec![1.0,4.0,9.0,16.0]);
/// ```
pub fn ele_div<T: Copy + Zero + Div<T, Output=T>> (u: &[T], v: &[T]) -> Vec<T> {
    let len = cmp::min(u.len(), v.len());
    let xs = &u[..len];
    let ys = &v[..len];

    let mut sum_data = vec![T::zero(); len];

    for i in 0..len {
        sum_data[i] = xs[i] / ys[i];
    }
    sum_data
}

/// Find argmax of slice.
///
/// Returns index of first occuring maximum.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::argmax(&a);
/// assert_eq!(c, 3);
/// ```
pub fn argmax<T: Copy + PartialOrd>(u: &[T]) -> usize {
    assert!(u.len() != 0);

    let mut max_index = 0;
    let mut max = u[max_index];

    for (i, v) in (u.iter()).enumerate() {
        if max < *v {
            max_index = i;
            max = *v;
        }
    }

    max_index
}

/// Find index of value in slice.
///
/// Returns index of first occuring value.
///
/// # Examples
///
/// ```
/// use rusty_machine::linalg::utils;
/// let a = vec![1.0,2.0,3.0,4.0];
///
/// let c = utils::find(&a, 3.0);
/// assert_eq!(c, 2);
/// ```
pub fn find<T: PartialEq>(p: &[T], u: T) -> usize {
        for (i, v) in p.iter().enumerate() {
            if *v == u {
                return i;
            }
        }

        panic!("Value not found.")
    }<|endoftext|>


<commit_before>extern crate nalgebra as na;
extern crate ncollide;
extern crate nphysics2d;
extern crate nphysics_testbed2d;
extern crate rand;

use na::{Vector1, Vector2, Translation2};
use ncollide::shape::{Plane, Cuboid};
use nphysics2d::world::World;
use nphysics2d::object::RigidBody;
use nphysics_testbed2d::Testbed;
use rand::distributions::{IndependentSample, Range, Weighted, WeightedChoice};
use nphysics_testbed2d::{CallBackMode, CallBackId};

fn main() {
    /*
     * World
     */
    let mut world = World::new();
    world.set_gravity(Vector2::new(0.0, 9.81));

    /*
     * First plane
     */
    let mut rb = RigidBody::new_static(Plane::new(Vector2::new(-1.0, -1.0)), 0.3, 0.6);

    rb.append_translation(&Translation2::new(0.0, 10.0));

    world.add_rigid_body(rb);

    /*
     * Second plane
     */
    let mut rb = RigidBody::new_static(Plane::new(Vector2::new(1.0, -1.0)), 0.3, 0.6);

    rb.append_translation(&Translation2::new(0.0, 10.0));

    world.add_rigid_body(rb);

    /*
     * Create the convex shapes
     */
    let num = (1000.0f32.sqrt()) as usize;
    let rad = 0.5;
    let shift   = 2.5 * rad;
    let centerx = shift * (num as f32) / 2.0;
    let centery = shift * (num as f32) / 2.0;
    //let g = 9.81;

    let mut handles = Vec::new();
    let mut forces = Vec::new();
    let mut ang_forces = Vec::new();
    let mut impulses = Vec::new();
    let mut torques = Vec::new();
    let mut rng = rand::thread_rng();
    let posneg = Range::new(-1f32, 1f32);
    let pos = Range::new(0.1f32, 1f32);
    let mut items = vec!(Weighted { weight: 1, item: -1.0 },
                         Weighted { weight: 1, item:  1.0 });
    let wc = WeightedChoice::new(&mut items);

    for i in 0usize .. num {
        for j in 0usize .. num {
            let x = i as f32 * shift - centerx;
            let y = j as f32 * shift - centery * 2.0 - 10.0;

            let geom = Cuboid::new(Vector2::new(0.5, 0.5));
            let mut rb = RigidBody::new_dynamic(geom, 0.1, 0.3, 0.6);
            rb.append_translation(&Translation2::new(x, y));
            let rb_handle = world.add_rigid_body(rb);

            handles.push(rb_handle);
            forces.push(Vector2::new(posneg.ind_sample(&mut rng) * 0.00008, pos.ind_sample(&mut rng) * -0.0008));
            ang_forces.push(Vector1::new(pos.ind_sample(&mut rng) * 0.001 * wc.ind_sample(&mut rng)));
            impulses.push(Vector2::new(posneg.ind_sample(&mut rng) * 0.1, pos.ind_sample(&mut rng) * -1.0));
            torques.push(Vector1::new(posneg.ind_sample(&mut rng) * 0.1));
        }
    }

    println!("Press 1 to toggle linear upward forces buildup.");
    println!("Press 2 to toggle angular forces buildup.");
    println!("Press 3 to apply an upward central impulse to the pieces.");
    println!("Press 4 to apply a torque impulse to the pieces.");

    /*
     * Run the simulation.
     */
    let mut testbed = Testbed::new(world);

    let ang_handles = handles.clone();
    let imp_handles = handles.clone();
    let torque_handles = handles.clone();

    testbed.add_callback(CallBackId::Cb1, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated => {
                    println!("Linear Forces accumulation activated.");
                },
                CallBackMode::StateDeactivated => {
                    handles.iter().map(|object| object.borrow_mut().clear_linear_force()).last();
                    println!("Linear Forces deactivated.");
                },
                CallBackMode::LoopActive => {
                    handles.iter().zip(forces.iter()).map(
                        |(object, force)| {
                            let mut obj = object.borrow_mut();
                            let thr = obj.deactivation_threshold().unwrap_or(0.0);
                            obj.activate(thr*4.0);
                            obj.append_lin_force(force.clone());
                        }
                        ).last();
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb2, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated => {
                    println!("Angular Forces accumulation activated.");
                },
                CallBackMode::StateDeactivated => {
                    ang_handles.iter().map(|object| object.borrow_mut().clear_angular_force()).last();
                    println!("Angular Forces deactivated.");
                },
                CallBackMode::LoopActive => {
                    ang_handles.iter().zip(ang_forces.iter()).map(
                        |(object, force)| {
                            let mut obj = object.borrow_mut();
                            let thr = obj.deactivation_threshold().unwrap_or(0.0);
                            obj.activate(thr * 4.0);
                            obj.append_ang_force(force.clone());
                        }
                        ).last();
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb3, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated | CallBackMode::StateDeactivated => {
                    imp_handles.iter().zip(impulses.iter()).map(
                        |(object, impulse)| {
                            let mut obj = object.borrow_mut();
                            obj.apply_central_impulse(impulse.clone());
                        }
                        ).last();
                    println!("Nudge applied.");
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb4, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated | CallBackMode::StateDeactivated => {
                    torque_handles.iter().zip(torques.iter()).map(
                        |(object, torque)| {
                            let mut obj = object.borrow_mut();
                            obj.apply_angular_momentum(torque.clone());
                        }
                        ).last();
                    println!("Angular momentum applied.");
                },
                _ => {}
            }));

    testbed.run();
}
<commit_msg>2D force demo: don't wake up objects manually.<commit_after>extern crate nalgebra as na;
extern crate ncollide;
extern crate nphysics2d;
extern crate nphysics_testbed2d;
extern crate rand;

use na::{Vector1, Vector2, Translation2};
use ncollide::shape::{Plane, Cuboid};
use nphysics2d::world::World;
use nphysics2d::object::RigidBody;
use nphysics_testbed2d::Testbed;
use rand::distributions::{IndependentSample, Range, Weighted, WeightedChoice};
use nphysics_testbed2d::{CallBackMode, CallBackId};

fn main() {
    /*
     * World
     */
    let mut world = World::new();
    world.set_gravity(Vector2::new(0.0, 9.81));

    /*
     * First plane
     */
    let mut rb = RigidBody::new_static(Plane::new(Vector2::new(-1.0, -1.0)), 0.3, 0.6);

    rb.append_translation(&Translation2::new(0.0, 10.0));

    world.add_rigid_body(rb);

    /*
     * Second plane
     */
    let mut rb = RigidBody::new_static(Plane::new(Vector2::new(1.0, -1.0)), 0.3, 0.6);

    rb.append_translation(&Translation2::new(0.0, 10.0));

    world.add_rigid_body(rb);

    /*
     * Create the convex shapes
     */
    let num = (1000.0f32.sqrt()) as usize;
    let rad = 0.5;
    let shift   = 2.5 * rad;
    let centerx = shift * (num as f32) / 2.0;
    let centery = shift * (num as f32) / 2.0;
    //let g = 9.81;

    let mut handles = Vec::new();
    let mut forces = Vec::new();
    let mut ang_forces = Vec::new();
    let mut impulses = Vec::new();
    let mut torques = Vec::new();
    let mut rng = rand::thread_rng();
    let posneg = Range::new(-1f32, 1f32);
    let pos = Range::new(0.1f32, 1f32);
    let mut items = vec!(Weighted { weight: 1, item: -1.0 },
                         Weighted { weight: 1, item:  1.0 });
    let wc = WeightedChoice::new(&mut items);

    for i in 0usize .. num {
        for j in 0usize .. num {
            let x = i as f32 * shift - centerx;
            let y = j as f32 * shift - centery * 2.0 - 10.0;

            let geom = Cuboid::new(Vector2::new(0.5, 0.5));
            let mut rb = RigidBody::new_dynamic(geom, 0.1, 0.3, 0.6);
            rb.append_translation(&Translation2::new(x, y));
            let rb_handle = world.add_rigid_body(rb);

            handles.push(rb_handle);
            forces.push(Vector2::new(posneg.ind_sample(&mut rng) * 0.00008, pos.ind_sample(&mut rng) * -0.0008));
            ang_forces.push(Vector1::new(pos.ind_sample(&mut rng) * 0.001 * wc.ind_sample(&mut rng)));
            impulses.push(Vector2::new(posneg.ind_sample(&mut rng) * 0.1, pos.ind_sample(&mut rng) * -1.0));
            torques.push(Vector1::new(posneg.ind_sample(&mut rng) * 0.1));
        }
    }

    println!("Press 1 to toggle linear upward forces buildup.");
    println!("Press 2 to toggle angular forces buildup.");
    println!("Press 3 to apply an upward central impulse to the pieces.");
    println!("Press 4 to apply a torque impulse to the pieces.");

    /*
     * Run the simulation.
     */
    let mut testbed = Testbed::new(world);

    let ang_handles = handles.clone();
    let imp_handles = handles.clone();
    let torque_handles = handles.clone();

    testbed.add_callback(CallBackId::Cb1, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated => {
                    println!("Linear Forces accumulation activated.");
                },
                CallBackMode::StateDeactivated => {
                    handles.iter().map(|object| object.borrow_mut().clear_linear_force()).last();
                    println!("Linear Forces deactivated.");
                },
                CallBackMode::LoopActive => {
                    handles.iter().zip(forces.iter()).map(
                        |(object, force)| {
                            let mut obj = object.borrow_mut();
                            obj.append_lin_force(force.clone());
                        }
                        ).last();
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb2, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated => {
                    println!("Angular Forces accumulation activated.");
                },
                CallBackMode::StateDeactivated => {
                    ang_handles.iter().map(|object| object.borrow_mut().clear_angular_force()).last();
                    println!("Angular Forces deactivated.");
                },
                CallBackMode::LoopActive => {
                    ang_handles.iter().zip(ang_forces.iter()).map(
                        |(object, force)| {
                            let mut obj = object.borrow_mut();
                            obj.append_ang_force(force.clone());
                        }
                        ).last();
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb3, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated | CallBackMode::StateDeactivated => {
                    imp_handles.iter().zip(impulses.iter()).map(
                        |(object, impulse)| {
                            let mut obj = object.borrow_mut();
                            obj.apply_central_impulse(impulse.clone());
                        }
                        ).last();
                    println!("Nudge applied.");
                },
                _ => {}
            }));

    testbed.add_callback(CallBackId::Cb4, Box::new(
            move | mode: CallBackMode |
            match mode {
                CallBackMode::StateActivated | CallBackMode::StateDeactivated => {
                    torque_handles.iter().zip(torques.iter()).map(
                        |(object, torque)| {
                            let mut obj = object.borrow_mut();
                            obj.apply_angular_momentum(torque.clone());
                        }
                        ).last();
                    println!("Angular momentum applied.");
                },
                _ => {}
            }));

    testbed.run();
}
<|endoftext|>


<commit_before>use super::primitives::*;
use crate::{
    chunk::{Chunk, Param, TupleMode},
    codegen::{translate_from_glib::TranslateFromGlib, translate_to_glib::TranslateToGlib},
    env::Env,
};

pub trait ToCode {
    fn to_code(&self, env: &Env) -> Vec<String>;
}

impl ToCode for Chunk {
    fn to_code(&self, env: &Env) -> Vec<String> {
        use crate::chunk::Chunk::*;
        match *self {
            Comment(ref chs) => comment_block(&chs.to_code(env)),
            Chunks(ref chs) => chs.to_code(env),
            BlockHalf(ref chs) => format_block("", "}", &chs.to_code(env)),
            UnsafeSmart(ref chs) => {
                format_block_smart("unsafe {", "}", &chs.to_code(env), " ", " ")
            }
            Unsafe(ref chs) => format_block("unsafe {", "}", &chs.to_code(env)),
            FfiCallTODO(ref name) => vec![format!("TODO: call {}()", name)],
            FfiCall {
                ref name,
                ref params,
            } => {
                let prefix = format!("{}(", name);
                //TODO: change to format_block or format_block_smart
                let s = format_block_one_line(&prefix, ")", &params.to_code(env), "", ", ");
                vec![s]
            }
            FfiCallParameter {
                ref transformation_type,
            } => {
                let s = transformation_type.translate_to_glib();
                vec![s]
            }
            FfiCallOutParameter { ref par } => {
                let s = if par.caller_allocates {
                    format!("{}.to_glib_none_mut().0", par.name)
                } else if par.is_uninitialized && !par.is_error {
                    format!("{}.as_mut_ptr()", par.name)
                } else {
                    format!("&mut {}", par.name)
                };
                vec![s]
            }
            FfiCallConversion {
                ref ret,
                ref array_length_name,
                ref call,
            } => {
                let call_strings = call.to_code(env);
                let (prefix, suffix) =
                    ret.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &call_strings, "", "");
                vec![s]
            }
            Let {
                ref name,
                is_mut,
                ref value,
                ref type_,
            } => {
                let modif = if is_mut { "mut " } else { "" };
                let type_string = if let Some(ref type_) = *type_ {
                    let type_strings = type_.to_code(env);
                    format_block_one_line(": ", "", &type_strings, "", "")
                } else {
                    "".to_owned()
                };
                let value_strings = value.to_code(env);
                let prefix = format!("let {}{}{} = ", modif, name, type_string);
                let s = format_block_one_line(&prefix, ";", &value_strings, "", "");
                vec![s]
            }
            Uninitialized => vec!["mem::MaybeUninit::uninit()".into()],
            UninitializedNamed { ref name } => {
                let s = format!("{}::uninitialized()", name);
                vec![s]
            }
            NullPtr => vec!["ptr::null()".into()],
            NullMutPtr => vec!["ptr::null_mut()".into()],
            Custom(ref string) => vec![string.clone()],
            Tuple(ref chs, mode) => {
                #[allow(deprecated)]
                let with_bracket = match mode {
                    TupleMode::Auto => chs.len() > 1,
                    TupleMode::WithUnit => chs.len() != 1,
                    TupleMode::Simple => true,
                };
                let (prefix, suffix) = if with_bracket { ("(", ")") } else { ("", "") };
                let s = format_block_one_line(prefix, suffix, &chs.to_code(env), "", ", ");
                vec![s]
            }
            FromGlibConversion {
                ref mode,
                ref array_length_name,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let (prefix, suffix) =
                    mode.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &value_strings, "", "");
                vec![s]
            }
            OptionalReturn {
                ref condition,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let prefix = format!("if {} {{ Some(", condition);
                let suffix = ") } else { None }";
                let s = format_block_one_line(&prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            ErrorResultReturn { ref value } => {
                let value_strings = value.to_code(env);
                let prefix = "if error.is_null() { Ok(";
                let suffix = ") } else { Err(from_glib_full(error)) }";
                let s = format_block_one_line(prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            AssertInitializedAndInMainThread => {
                vec!["assert_initialized_main_thread!();".to_string()]
            }
            AssertSkipInitialized => vec!["skip_assert_initialized!();".to_string()],
            Connect {
                ref signal,
                ref trampoline,
                in_trait,
            } => {
                let s1 = format!(
                    "connect_raw(self.as_ptr() as *mut _, b\"{}\\0\".as_ptr() as *const _,",
                    signal
                );
                let self_str = if in_trait { "Self, " } else { "" };
                let s2 = format!(
                    "\tSome(transmute({}::<{}F> as usize)), Box_::into_raw(f))",
                    trampoline, self_str
                );
                vec![s1, s2]
            }
            Name(ref name) => vec![name.clone()],
            ExternCFunc {
                ref name,
                ref parameters,
                ref body,
                ref return_value,
                ref bounds,
            } => {
                let prefix = format!(r#"unsafe extern "C" fn {}{}("#, name, bounds);
                let suffix = ")".to_string();
                let params: Vec<_> = parameters
                    .iter()
                    .flat_map(|param| param.to_code(env))
                    .collect();
                let mut s = format_block_one_line(&prefix, &suffix, &params, "", ", ");
                if let Some(ref return_value) = return_value {
                    s.push_str(&format!(" -> {}", return_value));
                }
                s.push_str(" {");
                let mut code = format_block("", "}", &body.to_code(env));
                code.insert(0, s);
                code
            }
            Cast {
                ref name,
                ref type_,
            } => vec![format!("{} as {}", name, type_)],
            Call {
                ref func_name,
                ref arguments,
            } => {
                let args: Vec<_> = arguments.iter().flat_map(|arg| arg.to_code(env)).collect();
                let s = format_block_one_line("(", ")", &args, "", ",");
                vec![format!("{}{};", func_name, s)]
            }
        }
    }
}

impl ToCode for Param {
    fn to_code(&self, _env: &Env) -> Vec<String> {
        vec![format!("{}: {}", self.name, self.typ)]
    }
}

impl ToCode for [Chunk] {
    fn to_code(&self, env: &Env) -> Vec<String> {
        let mut v = Vec::new();
        for ch in self {
            let strs = ch.to_code(env);
            v.extend_from_slice(&strs);
        }
        v
    }
}
<commit_msg>Change transmute to be closer to the unsafe code guidelines.<commit_after>use super::primitives::*;
use crate::{
    chunk::{Chunk, Param, TupleMode},
    codegen::{translate_from_glib::TranslateFromGlib, translate_to_glib::TranslateToGlib},
    env::Env,
};

pub trait ToCode {
    fn to_code(&self, env: &Env) -> Vec<String>;
}

impl ToCode for Chunk {
    fn to_code(&self, env: &Env) -> Vec<String> {
        use crate::chunk::Chunk::*;
        match *self {
            Comment(ref chs) => comment_block(&chs.to_code(env)),
            Chunks(ref chs) => chs.to_code(env),
            BlockHalf(ref chs) => format_block("", "}", &chs.to_code(env)),
            UnsafeSmart(ref chs) => {
                format_block_smart("unsafe {", "}", &chs.to_code(env), " ", " ")
            }
            Unsafe(ref chs) => format_block("unsafe {", "}", &chs.to_code(env)),
            FfiCallTODO(ref name) => vec![format!("TODO: call {}()", name)],
            FfiCall {
                ref name,
                ref params,
            } => {
                let prefix = format!("{}(", name);
                //TODO: change to format_block or format_block_smart
                let s = format_block_one_line(&prefix, ")", &params.to_code(env), "", ", ");
                vec![s]
            }
            FfiCallParameter {
                ref transformation_type,
            } => {
                let s = transformation_type.translate_to_glib();
                vec![s]
            }
            FfiCallOutParameter { ref par } => {
                let s = if par.caller_allocates {
                    format!("{}.to_glib_none_mut().0", par.name)
                } else if par.is_uninitialized && !par.is_error {
                    format!("{}.as_mut_ptr()", par.name)
                } else {
                    format!("&mut {}", par.name)
                };
                vec![s]
            }
            FfiCallConversion {
                ref ret,
                ref array_length_name,
                ref call,
            } => {
                let call_strings = call.to_code(env);
                let (prefix, suffix) =
                    ret.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &call_strings, "", "");
                vec![s]
            }
            Let {
                ref name,
                is_mut,
                ref value,
                ref type_,
            } => {
                let modif = if is_mut { "mut " } else { "" };
                let type_string = if let Some(ref type_) = *type_ {
                    let type_strings = type_.to_code(env);
                    format_block_one_line(": ", "", &type_strings, "", "")
                } else {
                    "".to_owned()
                };
                let value_strings = value.to_code(env);
                let prefix = format!("let {}{}{} = ", modif, name, type_string);
                let s = format_block_one_line(&prefix, ";", &value_strings, "", "");
                vec![s]
            }
            Uninitialized => vec!["mem::MaybeUninit::uninit()".into()],
            UninitializedNamed { ref name } => {
                let s = format!("{}::uninitialized()", name);
                vec![s]
            }
            NullPtr => vec!["ptr::null()".into()],
            NullMutPtr => vec!["ptr::null_mut()".into()],
            Custom(ref string) => vec![string.clone()],
            Tuple(ref chs, mode) => {
                #[allow(deprecated)]
                let with_bracket = match mode {
                    TupleMode::Auto => chs.len() > 1,
                    TupleMode::WithUnit => chs.len() != 1,
                    TupleMode::Simple => true,
                };
                let (prefix, suffix) = if with_bracket { ("(", ")") } else { ("", "") };
                let s = format_block_one_line(prefix, suffix, &chs.to_code(env), "", ", ");
                vec![s]
            }
            FromGlibConversion {
                ref mode,
                ref array_length_name,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let (prefix, suffix) =
                    mode.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &value_strings, "", "");
                vec![s]
            }
            OptionalReturn {
                ref condition,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let prefix = format!("if {} {{ Some(", condition);
                let suffix = ") } else { None }";
                let s = format_block_one_line(&prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            ErrorResultReturn { ref value } => {
                let value_strings = value.to_code(env);
                let prefix = "if error.is_null() { Ok(";
                let suffix = ") } else { Err(from_glib_full(error)) }";
                let s = format_block_one_line(prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            AssertInitializedAndInMainThread => {
                vec!["assert_initialized_main_thread!();".to_string()]
            }
            AssertSkipInitialized => vec!["skip_assert_initialized!();".to_string()],
            Connect {
                ref signal,
                ref trampoline,
                in_trait,
            } => {
                let s1 = format!(
                    "connect_raw(self.as_ptr() as *mut _, b\"{}\\0\".as_ptr() as *const _,",
                    signal
                );
                let self_str = if in_trait { "Self, " } else { "" };
                let s2 = format!(
                    "\tSome(transmute::<_, unsafe extern \"C\" fn()>({}::<{}F> as *const ())), Box_::into_raw(f))",
                    trampoline, self_str
                );
                vec![s1, s2]
            }
            Name(ref name) => vec![name.clone()],
            ExternCFunc {
                ref name,
                ref parameters,
                ref body,
                ref return_value,
                ref bounds,
            } => {
                let prefix = format!(r#"unsafe extern "C" fn {}{}("#, name, bounds);
                let suffix = ")".to_string();
                let params: Vec<_> = parameters
                    .iter()
                    .flat_map(|param| param.to_code(env))
                    .collect();
                let mut s = format_block_one_line(&prefix, &suffix, &params, "", ", ");
                if let Some(ref return_value) = return_value {
                    s.push_str(&format!(" -> {}", return_value));
                }
                s.push_str(" {");
                let mut code = format_block("", "}", &body.to_code(env));
                code.insert(0, s);
                code
            }
            Cast {
                ref name,
                ref type_,
            } => vec![format!("{} as {}", name, type_)],
            Call {
                ref func_name,
                ref arguments,
            } => {
                let args: Vec<_> = arguments.iter().flat_map(|arg| arg.to_code(env)).collect();
                let s = format_block_one_line("(", ")", &args, "", ",");
                vec![format!("{}{};", func_name, s)]
            }
        }
    }
}

impl ToCode for Param {
    fn to_code(&self, _env: &Env) -> Vec<String> {
        vec![format!("{}: {}", self.name, self.typ)]
    }
}

impl ToCode for [Chunk] {
    fn to_code(&self, env: &Env) -> Vec<String> {
        let mut v = Vec::new();
        for ch in self {
            let strs = ch.to_code(env);
            v.extend_from_slice(&strs);
        }
        v
    }
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::fmt::{self, Formatter};
use std::hash;
use std::hash::Hash;
use std::path::Path;
use std::ptr;
use std::sync::Mutex;

use semver;
use serde::de;
use serde::ser;

use crate::core::interning::InternedString;
use crate::core::source::SourceId;
use crate::util::{CargoResult, ToSemver};

lazy_static::lazy_static! {
    static ref PACKAGE_ID_CACHE: Mutex<HashSet<&'static PackageIdInner>> =
        Mutex::new(HashSet::new());
}

/// Identifier for a specific version of a package in a specific source.
#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
pub struct PackageId {
    inner: &'static PackageIdInner,
}

#[derive(PartialOrd, Eq, Ord)]
struct PackageIdInner {
    name: InternedString,
    version: semver::Version,
    source_id: SourceId,
}

// Custom equality that uses full equality of SourceId, rather than its custom equality.
impl PartialEq for PackageIdInner {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
            && self.version == other.version
            && self.source_id.full_eq(other.source_id)
    }
}

// Custom hash that is coherent with the custom equality above.
impl Hash for PackageIdInner {
    fn hash<S: hash::Hasher>(&self, into: &mut S) {
        self.name.hash(into);
        self.version.hash(into);
        self.source_id.full_hash(into);
    }
}

impl ser::Serialize for PackageId {
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        s.collect_str(&format_args!(
            "{} {} ({})",
            self.inner.name,
            self.inner.version,
            self.inner.source_id.to_url()
        ))
    }
}

impl<'de> de::Deserialize<'de> for PackageId {
    fn deserialize<D>(d: D) -> Result<PackageId, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        let string = String::deserialize(d)?;
        let mut s = string.splitn(3, ' ');
        let name = s.next().unwrap();
        let version = match s.next() {
            Some(s) => s,
            None => return Err(de::Error::custom("invalid serialized PackageId")),
        };
        let version = version.to_semver().map_err(de::Error::custom)?;
        let url = match s.next() {
            Some(s) => s,
            None => return Err(de::Error::custom("invalid serialized PackageId")),
        };
        let url = if url.starts_with('(') && url.ends_with(')') {
            &url[1..url.len() - 1]
        } else {
            return Err(de::Error::custom("invalid serialized PackageId"));
        };
        let source_id = SourceId::from_url(url).map_err(de::Error::custom)?;

        Ok(PackageId::wrap(PackageIdInner {
            name: InternedString::new(name),
            version,
            source_id,
        }))
    }
}

impl PartialEq for PackageId {
    fn eq(&self, other: &PackageId) -> bool {
        if ptr::eq(self.inner, other.inner) {
            return true;
        }
        self.inner.name == other.inner.name
            && self.inner.version == other.inner.version
            && self.inner.source_id == other.inner.source_id
    }
}

impl<'a> Hash for PackageId {
    fn hash<S: hash::Hasher>(&self, state: &mut S) {
        self.inner.name.hash(state);
        self.inner.version.hash(state);
        self.inner.source_id.hash(state);
    }
}

impl PackageId {
    pub fn new<T: ToSemver>(name: &str, version: T, sid: SourceId) -> CargoResult<PackageId> {
        let v = version.to_semver()?;

        Ok(PackageId::wrap(PackageIdInner {
            name: InternedString::new(name),
            version: v,
            source_id: sid,
        }))
    }

    fn wrap(inner: PackageIdInner) -> PackageId {
        let mut cache = PACKAGE_ID_CACHE.lock().unwrap();
        let inner = cache.get(&inner).cloned().unwrap_or_else(|| {
            let inner = Box::leak(Box::new(inner));
            cache.insert(inner);
            inner
        });
        PackageId { inner }
    }

    pub fn name(self) -> InternedString {
        self.inner.name
    }
    pub fn version(self) -> &'static semver::Version {
        &self.inner.version
    }
    pub fn source_id(self) -> SourceId {
        self.inner.source_id
    }

    pub fn with_precise(self, precise: Option<String>) -> PackageId {
        PackageId::wrap(PackageIdInner {
            name: self.inner.name,
            version: self.inner.version.clone(),
            source_id: self.inner.source_id.with_precise(precise),
        })
    }

    pub fn with_source_id(self, source: SourceId) -> PackageId {
        PackageId::wrap(PackageIdInner {
            name: self.inner.name,
            version: self.inner.version.clone(),
            source_id: source,
        })
    }

    pub fn stable_hash(self, workspace: &Path) -> PackageIdStableHash<'_> {
        PackageIdStableHash(self, workspace)
    }
}

pub struct PackageIdStableHash<'a>(PackageId, &'a Path);

impl<'a> Hash for PackageIdStableHash<'a> {
    fn hash<S: hash::Hasher>(&self, state: &mut S) {
        self.0.inner.name.hash(state);
        self.0.inner.version.hash(state);
        self.0.inner.source_id.stable_hash(self.1, state);
    }
}

impl fmt::Display for PackageId {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{} v{}", self.inner.name, self.inner.version)?;

        if !self.inner.source_id.is_default_registry() {
            write!(f, " ({})", self.inner.source_id)?;
        }

        Ok(())
    }
}

impl fmt::Debug for PackageId {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.debug_struct("PackageId")
            .field("name", &self.inner.name)
            .field("version", &self.inner.version.to_string())
            .field("source", &self.inner.source_id.to_string())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::PackageId;
    use crate::core::source::SourceId;
    use crate::sources::CRATES_IO_INDEX;
    use crate::util::ToUrl;

    #[test]
    fn invalid_version_handled_nicely() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let repo = SourceId::for_registry(&loc).unwrap();

        assert!(PackageId::new("foo", "1.0", repo).is_err());
        assert!(PackageId::new("foo", "1", repo).is_err());
        assert!(PackageId::new("foo", "bar", repo).is_err());
        assert!(PackageId::new("foo", "", repo).is_err());
    }

    #[test]
    fn debug() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
        assert_eq!(r#"PackageId { name: "foo", version: "1.0.0", source: "registry `https://github.com/rust-lang/crates.io-index`" }"#, format!("{:?}", pkg_id));

        let pretty = r#"
PackageId {
    name: "foo",
    version: "1.0.0",
    source: "registry `https://github.com/rust-lang/crates.io-index`"
}
"#
        .trim();
        assert_eq!(pretty, format!("{:#?}", pkg_id));
    }

    #[test]
    fn display() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
        assert_eq!("foo v1.0.0", pkg_id.to_string());
    }
}
<commit_msg>Replace PackageId::wrap with PackageId::pure<commit_after>use std::collections::HashSet;
use std::fmt::{self, Formatter};
use std::hash;
use std::hash::Hash;
use std::path::Path;
use std::ptr;
use std::sync::Mutex;

use semver;
use serde::de;
use serde::ser;

use crate::core::interning::InternedString;
use crate::core::source::SourceId;
use crate::util::{CargoResult, ToSemver};

lazy_static::lazy_static! {
    static ref PACKAGE_ID_CACHE: Mutex<HashSet<&'static PackageIdInner>> =
        Mutex::new(HashSet::new());
}

/// Identifier for a specific version of a package in a specific source.
#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
pub struct PackageId {
    inner: &'static PackageIdInner,
}

#[derive(PartialOrd, Eq, Ord)]
struct PackageIdInner {
    name: InternedString,
    version: semver::Version,
    source_id: SourceId,
}

// Custom equality that uses full equality of SourceId, rather than its custom equality.
impl PartialEq for PackageIdInner {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
            && self.version == other.version
            && self.source_id.full_eq(other.source_id)
    }
}

// Custom hash that is coherent with the custom equality above.
impl Hash for PackageIdInner {
    fn hash<S: hash::Hasher>(&self, into: &mut S) {
        self.name.hash(into);
        self.version.hash(into);
        self.source_id.full_hash(into);
    }
}

impl ser::Serialize for PackageId {
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        s.collect_str(&format_args!(
            "{} {} ({})",
            self.inner.name,
            self.inner.version,
            self.inner.source_id.to_url()
        ))
    }
}

impl<'de> de::Deserialize<'de> for PackageId {
    fn deserialize<D>(d: D) -> Result<PackageId, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        let string = String::deserialize(d)?;
        let mut s = string.splitn(3, ' ');
        let name = s.next().unwrap();
        let name = InternedString::new(name);
        let version = match s.next() {
            Some(s) => s,
            None => return Err(de::Error::custom("invalid serialized PackageId")),
        };
        let version = version.to_semver().map_err(de::Error::custom)?;
        let url = match s.next() {
            Some(s) => s,
            None => return Err(de::Error::custom("invalid serialized PackageId")),
        };
        let url = if url.starts_with('(') && url.ends_with(')') {
            &url[1..url.len() - 1]
        } else {
            return Err(de::Error::custom("invalid serialized PackageId"));
        };
        let source_id = SourceId::from_url(url).map_err(de::Error::custom)?;

        Ok(PackageId::pure(name, version, source_id))
    }
}

impl PartialEq for PackageId {
    fn eq(&self, other: &PackageId) -> bool {
        if ptr::eq(self.inner, other.inner) {
            return true;
        }
        self.inner.name == other.inner.name
            && self.inner.version == other.inner.version
            && self.inner.source_id == other.inner.source_id
    }
}

impl<'a> Hash for PackageId {
    fn hash<S: hash::Hasher>(&self, state: &mut S) {
        self.inner.name.hash(state);
        self.inner.version.hash(state);
        self.inner.source_id.hash(state);
    }
}

impl PackageId {
    pub fn new<T: ToSemver>(name: &str, version: T, sid: SourceId) -> CargoResult<PackageId> {
        let v = version.to_semver()?;
        Ok(PackageId::pure(InternedString::new(name), v, sid))
    }

    pub fn pure(name: InternedString, version: semver::Version, source_id: SourceId) -> PackageId {
        let inner = PackageIdInner {
            name,
            version,
            source_id,
        };
        let mut cache = PACKAGE_ID_CACHE.lock().unwrap();
        let inner = cache.get(&inner).cloned().unwrap_or_else(|| {
            let inner = Box::leak(Box::new(inner));
            cache.insert(inner);
            inner
        });
        PackageId { inner }
    }

    pub fn name(self) -> InternedString {
        self.inner.name
    }
    pub fn version(self) -> &'static semver::Version {
        &self.inner.version
    }
    pub fn source_id(self) -> SourceId {
        self.inner.source_id
    }

    pub fn with_precise(self, precise: Option<String>) -> PackageId {
        PackageId::pure(
            self.inner.name,
            self.inner.version.clone(),
            self.inner.source_id.with_precise(precise),
        )
    }

    pub fn with_source_id(self, source: SourceId) -> PackageId {
        PackageId::pure(self.inner.name, self.inner.version.clone(), source)
    }

    pub fn stable_hash(self, workspace: &Path) -> PackageIdStableHash<'_> {
        PackageIdStableHash(self, workspace)
    }
}

pub struct PackageIdStableHash<'a>(PackageId, &'a Path);

impl<'a> Hash for PackageIdStableHash<'a> {
    fn hash<S: hash::Hasher>(&self, state: &mut S) {
        self.0.inner.name.hash(state);
        self.0.inner.version.hash(state);
        self.0.inner.source_id.stable_hash(self.1, state);
    }
}

impl fmt::Display for PackageId {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{} v{}", self.inner.name, self.inner.version)?;

        if !self.inner.source_id.is_default_registry() {
            write!(f, " ({})", self.inner.source_id)?;
        }

        Ok(())
    }
}

impl fmt::Debug for PackageId {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.debug_struct("PackageId")
            .field("name", &self.inner.name)
            .field("version", &self.inner.version.to_string())
            .field("source", &self.inner.source_id.to_string())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::PackageId;
    use crate::core::source::SourceId;
    use crate::sources::CRATES_IO_INDEX;
    use crate::util::ToUrl;

    #[test]
    fn invalid_version_handled_nicely() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let repo = SourceId::for_registry(&loc).unwrap();

        assert!(PackageId::new("foo", "1.0", repo).is_err());
        assert!(PackageId::new("foo", "1", repo).is_err());
        assert!(PackageId::new("foo", "bar", repo).is_err());
        assert!(PackageId::new("foo", "", repo).is_err());
    }

    #[test]
    fn debug() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
        assert_eq!(r#"PackageId { name: "foo", version: "1.0.0", source: "registry `https://github.com/rust-lang/crates.io-index`" }"#, format!("{:?}", pkg_id));

        let pretty = r#"
PackageId {
    name: "foo",
    version: "1.0.0",
    source: "registry `https://github.com/rust-lang/crates.io-index`"
}
"#
        .trim();
        assert_eq!(pretty, format!("{:#?}", pkg_id));
    }

    #[test]
    fn display() {
        let loc = CRATES_IO_INDEX.to_url().unwrap();
        let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
        assert_eq!("foo v1.0.0", pkg_id.to_string());
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_name = "gio_2_0_sys"]
#![crate_type = "lib"]

#![allow(missing_copy_implementations)]

extern crate glib_2_0_sys as glib;
extern crate gobject_2_0_sys as gobject;

use glib::types::{gchar, gint, gpointer};
use glib::GError;
use gobject::GType;

#[repr(C)]
pub struct GAsyncResult;

#[repr(C)]
pub struct GFile;

#[repr(C)]
pub struct GCancellable {
    pub parent_instance: gobject::GObject,
    _priv: gpointer
}

#[repr(C)]
pub struct GInputStream {
    pub parent_instance: gobject::GObject,
    _priv: gpointer
}

#[repr(C)]
pub struct GFileInputStream {
    pub parent_instance: GInputStream,
    _priv: gpointer
}

pub type GAsyncReadyCallback = extern "C" fn(source_object: *mut gobject::GObject,
                                             res: *mut GAsyncResult,
                                             user_data: gpointer);

extern {
    pub fn g_async_result_get_type() -> GType;
    pub fn g_file_get_path(file: *mut GFile) -> *mut gchar;
    pub fn g_file_get_type() -> GType;
    pub fn g_file_new_for_path(path: *const gchar) -> *mut GFile;
    pub fn g_file_read_async(file: *mut GFile,
                             io_priority: gint,
                             cancellable: *mut GCancellable,
                             callback: GAsyncReadyCallback,
                             user_data: gpointer);
    pub fn g_file_read_finish(file: *mut GFile,
                              res: *mut GAsyncResult,
                              error: *mut *mut GError)
                              -> *mut GFileInputStream;
    pub fn g_file_attribute_info_flags_get_type() -> GType;
    pub fn g_file_input_stream_get_type() -> GType;
    pub fn g_input_stream_get_type() -> GType;
    pub fn g_io_error_enum_get_type() -> GType;
}
<commit_msg>Updated to Rust 1.3<commit_after>// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_name = "gio_2_0_sys"]
#![crate_type = "lib"]

#![allow(missing_copy_implementations)]

extern crate glib_2_0_sys as glib;
extern crate gobject_2_0_sys as gobject;

use glib::types::{gchar, gint, gpointer};
use glib::GError;
use gobject::GType;

pub enum GAsyncResult { }

pub enum GFile { }

#[repr(C)]
pub struct GCancellable {
    pub parent_instance: gobject::GObject,
    _priv: gpointer
}

#[repr(C)]
pub struct GInputStream {
    pub parent_instance: gobject::GObject,
    _priv: gpointer
}

#[repr(C)]
pub struct GFileInputStream {
    pub parent_instance: GInputStream,
    _priv: gpointer
}

pub type GAsyncReadyCallback = extern "C" fn(source_object: *mut gobject::GObject,
                                             res: *mut GAsyncResult,
                                             user_data: gpointer);

extern {
    pub fn g_async_result_get_type() -> GType;
    pub fn g_file_get_path(file: *mut GFile) -> *mut gchar;
    pub fn g_file_get_type() -> GType;
    pub fn g_file_new_for_path(path: *const gchar) -> *mut GFile;
    pub fn g_file_read_async(file: *mut GFile,
                             io_priority: gint,
                             cancellable: *mut GCancellable,
                             callback: GAsyncReadyCallback,
                             user_data: gpointer);
    pub fn g_file_read_finish(file: *mut GFile,
                              res: *mut GAsyncResult,
                              error: *mut *mut GError)
                              -> *mut GFileInputStream;
    pub fn g_file_attribute_info_flags_get_type() -> GType;
    pub fn g_file_input_stream_get_type() -> GType;
    pub fn g_input_stream_get_type() -> GType;
    pub fn g_io_error_enum_get_type() -> GType;
}
<|endoftext|>