<commit_before>//! An immutable map constructed at compile time.
use core::fmt;
use core::iter::FusedIterator;
use core::iter::IntoIterator;
use core::ops::Index;
use core::slice;
use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
#[cfg(feature = "serde")]
use serde::ser::{Serialize, SerializeMap, Serializer};

/// An immutable map constructed at compile time.
///
/// ## Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_map!` macro and code generation. They are subject to change at any
/// time and should never be accessed directly.
pub struct Map<K: 'static, V: 'static> {
    #[doc(hidden)]
    pub key: HashKey,
    #[doc(hidden)]
    pub disps: &'static [(u32, u32)],
    #[doc(hidden)]
    pub entries: &'static [(K, V)],
}

impl<K, V> fmt::Debug for Map<K, V>
where
    K: fmt::Debug,
    V: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.debug_map().entries(self.entries()).finish()
    }
}

impl<'a, K, V, T: ?Sized> Index<&'a T> for Map<K, V>
where
    T: Eq + PhfHash,
    K: PhfBorrow<T>,
{
    type Output = V;

    fn index(&self, k: &'a T) -> &V {
        self.get(k).expect("invalid key")
    }
}

impl<K, V> Map<K, V> {
    /// Returns the number of entries in the `Map`.
    #[inline]
    pub const fn len(&self) -> usize {
        self.entries.len()
    }

    /// Returns true if the `Map` is empty.
    #[inline]
    pub const fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Determines if `key` is in the `Map`.
    pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get(key).is_some()
    }

    /// Returns a reference to the value that `key` maps to.
    pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get_entry(key).map(|e| e.1)
    }

    /// Returns a reference to the map's internal static instance of the given
    /// key.
    ///
    /// This can be useful for interning schemes.
    pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get_entry(key).map(|e| e.0)
    }

    /// Like `get`, but returns both the key and the value.
    pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        if self.disps.is_empty() {
            return None;
        } //Prevent panic on empty map
        let hashes = phf_shared::hash(key, &self.key);
        let index = phf_shared::get_index(&hashes, &*self.disps, self.entries.len());
        let entry = &self.entries[index as usize];
        let b: &T = entry.0.borrow();
        if b == key {
            Some((&entry.0, &entry.1))
        } else {
            None
        }
    }

    /// Returns an iterator over the key/value pairs in the map.
    ///
    /// Entries are returned in an arbitrary but fixed order.
    pub fn entries(&self) -> Entries<'_, K, V> {
        Entries {
            iter: self.entries.iter(),
        }
    }

    /// Returns an iterator over the keys in the map.
    ///
    /// Keys are returned in an arbitrary but fixed order.
    pub fn keys(&self) -> Keys<'_, K, V> {
        Keys {
            iter: self.entries(),
        }
    }

    /// Returns an iterator over the values in the map.
    ///
    /// Values are returned in an arbitrary but fixed order.
    pub fn values(&self) -> Values<'_, K, V> {
        Values {
            iter: self.entries(),
        }
    }
}

impl<'a, K, V> IntoIterator for &'a Map<K, V> {
    type Item = (&'a K, &'a V);
    type IntoIter = Entries<'a, K, V>;

    fn into_iter(self) -> Entries<'a, K, V> {
        self.entries()
    }
}

/// An iterator over the key/value pairs in a `Map`.
pub struct Entries<'a, K, V> {
    iter: slice::Iter<'a, (K, V)>,
}

impl<'a, K, V> Clone for Entries<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Entries<'a, K, V>
where
    K: fmt::Debug,
    V: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Entries<'a, K, V> {
    type Item = (&'a K, &'a V);

    fn next(&mut self) -> Option<(&'a K, &'a V)> {
        self.iter.next().map(|&(ref k, ref v)| (k, v))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
        self.iter.next_back().map(|e| (&e.0, &e.1))
    }
}

impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}

impl<'a, K, V> FusedIterator for Entries<'a, K, V> {}

/// An iterator over the keys in a `Map`.
pub struct Keys<'a, K, V> {
    iter: Entries<'a, K, V>,
}

impl<'a, K, V> Clone for Keys<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Keys<'a, K, V>
where
    K: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Keys<'a, K, V> {
    type Item = &'a K;

    fn next(&mut self) -> Option<&'a K> {
        self.iter.next().map(|e| e.0)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
    fn next_back(&mut self) -> Option<&'a K> {
        self.iter.next_back().map(|e| e.0)
    }
}

impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}

impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}

/// An iterator over the values in a `Map`.
pub struct Values<'a, K, V> {
    iter: Entries<'a, K, V>,
}

impl<'a, K, V> Clone for Values<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Values<'a, K, V>
where
    V: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Values<'a, K, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<&'a V> {
        self.iter.next().map(|e| e.1)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
    fn next_back(&mut self) -> Option<&'a V> {
        self.iter.next_back().map(|e| e.1)
    }
}

impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}

impl<'a, K, V> FusedIterator for Values<'a, K, V> {}

#[cfg(feature = "serde")]
impl<K, V> Serialize for Map<K, V>
where
    K: Serialize,
    V: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(self.len()))?;
        for (k, v) in self.entries() {
            map.serialize_entry(k, v)?;
        }
        map.end()
    }
}
<commit_msg>Add `Map::new()` function and `Default` implementation to create new, empty map (#249)<commit_after>//! An immutable map constructed at compile time.
use core::fmt;
use core::iter::FusedIterator;
use core::iter::IntoIterator;
use core::ops::Index;
use core::slice;
use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
#[cfg(feature = "serde")]
use serde::ser::{Serialize, SerializeMap, Serializer};

/// An immutable map constructed at compile time.
///
/// ## Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_map!` macro and code generation. They are subject to change at any
/// time and should never be accessed directly.
pub struct Map<K: 'static, V: 'static> {
    #[doc(hidden)]
    pub key: HashKey,
    #[doc(hidden)]
    pub disps: &'static [(u32, u32)],
    #[doc(hidden)]
    pub entries: &'static [(K, V)],
}

impl<K, V> fmt::Debug for Map<K, V>
where
    K: fmt::Debug,
    V: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.debug_map().entries(self.entries()).finish()
    }
}

impl<'a, K, V, T: ?Sized> Index<&'a T> for Map<K, V>
where
    T: Eq + PhfHash,
    K: PhfBorrow<T>,
{
    type Output = V;

    fn index(&self, k: &'a T) -> &V {
        self.get(k).expect("invalid key")
    }
}

impl<K, V> Default for Map<K, V> {
    fn default() -> Self {
        Self::new()
    }
}

impl<K, V> Map<K, V> {
    /// Create a new, empty, immutable map.
    #[inline]
    pub const fn new() -> Self {
        Self {
            key: 0,
            disps: &[],
            entries: &[],
        }
    }

    /// Returns the number of entries in the `Map`.
    #[inline]
    pub const fn len(&self) -> usize {
        self.entries.len()
    }

    /// Returns true if the `Map` is empty.
    #[inline]
    pub const fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Determines if `key` is in the `Map`.
    pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get(key).is_some()
    }

    /// Returns a reference to the value that `key` maps to.
    pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get_entry(key).map(|e| e.1)
    }

    /// Returns a reference to the map's internal static instance of the given
    /// key.
    ///
    /// This can be useful for interning schemes.
    pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        self.get_entry(key).map(|e| e.0)
    }

    /// Like `get`, but returns both the key and the value.
    pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
    where
        T: Eq + PhfHash,
        K: PhfBorrow<T>,
    {
        if self.disps.is_empty() {
            return None;
        } //Prevent panic on empty map
        let hashes = phf_shared::hash(key, &self.key);
        let index = phf_shared::get_index(&hashes, &*self.disps, self.entries.len());
        let entry = &self.entries[index as usize];
        let b: &T = entry.0.borrow();
        if b == key {
            Some((&entry.0, &entry.1))
        } else {
            None
        }
    }

    /// Returns an iterator over the key/value pairs in the map.
    ///
    /// Entries are returned in an arbitrary but fixed order.
    pub fn entries(&self) -> Entries<'_, K, V> {
        Entries {
            iter: self.entries.iter(),
        }
    }

    /// Returns an iterator over the keys in the map.
    ///
    /// Keys are returned in an arbitrary but fixed order.
    pub fn keys(&self) -> Keys<'_, K, V> {
        Keys {
            iter: self.entries(),
        }
    }

    /// Returns an iterator over the values in the map.
    ///
    /// Values are returned in an arbitrary but fixed order.
    pub fn values(&self) -> Values<'_, K, V> {
        Values {
            iter: self.entries(),
        }
    }
}

impl<'a, K, V> IntoIterator for &'a Map<K, V> {
    type Item = (&'a K, &'a V);
    type IntoIter = Entries<'a, K, V>;

    fn into_iter(self) -> Entries<'a, K, V> {
        self.entries()
    }
}

/// An iterator over the key/value pairs in a `Map`.
pub struct Entries<'a, K, V> {
    iter: slice::Iter<'a, (K, V)>,
}

impl<'a, K, V> Clone for Entries<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Entries<'a, K, V>
where
    K: fmt::Debug,
    V: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Entries<'a, K, V> {
    type Item = (&'a K, &'a V);

    fn next(&mut self) -> Option<(&'a K, &'a V)> {
        self.iter.next().map(|&(ref k, ref v)| (k, v))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
        self.iter.next_back().map(|e| (&e.0, &e.1))
    }
}

impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}

impl<'a, K, V> FusedIterator for Entries<'a, K, V> {}

/// An iterator over the keys in a `Map`.
pub struct Keys<'a, K, V> {
    iter: Entries<'a, K, V>,
}

impl<'a, K, V> Clone for Keys<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Keys<'a, K, V>
where
    K: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Keys<'a, K, V> {
    type Item = &'a K;

    fn next(&mut self) -> Option<&'a K> {
        self.iter.next().map(|e| e.0)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
    fn next_back(&mut self) -> Option<&'a K> {
        self.iter.next_back().map(|e| e.0)
    }
}

impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}

impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}

/// An iterator over the values in a `Map`.
pub struct Values<'a, K, V> {
    iter: Entries<'a, K, V>,
}

impl<'a, K, V> Clone for Values<'a, K, V> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            iter: self.iter.clone(),
        }
    }
}

impl<'a, K, V> fmt::Debug for Values<'a, K, V>
where
    V: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'a, K, V> Iterator for Values<'a, K, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<&'a V> {
        self.iter.next().map(|e| e.1)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
    fn next_back(&mut self) -> Option<&'a V> {
        self.iter.next_back().map(|e| e.1)
    }
}

impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}

impl<'a, K, V> FusedIterator for Values<'a, K, V> {}

#[cfg(feature = "serde")]
impl<K, V> Serialize for Map<K, V>
where
    K: Serialize,
    V: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(self.len()))?;
        for (k, v) in self.entries() {
            map.serialize_entry(k, v)?;
        }
        map.end()
    }
}
<|endoftext|>


<commit_before>//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories.

use std::fs;
use std::path::Path;

pub fn check(path: &Path, bad: &mut bool) {
    for path in &[&path.join("test/ui"), &path.join("test/ui-fulldeps")] {
        super::walk_no_read(path, &mut |_| false, &mut |entry| {
            let file_path = entry.path();
            if let Some(ext) = file_path.extension() {
                if ext == "stderr" || ext == "stdout" {
                    // Test output filenames have one of the formats:
                    // ```
                    // $testname.stderr
                    // $testname.$mode.stderr
                    // $testname.$revision.stderr
                    // $testname.$revision.$mode.stderr
                    // ```
                    //
                    // For now, just make sure that there is a corresponding
                    // `$testname.rs` file.
                    //
                    // NB: We do not use file_stem() as some file names have multiple `.`s and we
                    // must strip all of them.
                    let testname =
                        file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
                    if !file_path.with_file_name(testname).with_extension("rs").exists() {
                        println!("Stray file with UI testing output: {:?}", file_path);
                        *bad = true;
                    }

                    if let Ok(metadata) = fs::metadata(file_path) {
                        if metadata.len() == 0 {
                            println!("Empty file with UI testing output: {:?}", file_path);
                            *bad = true;
                        }
                    }
                }
            }
        });
    }
}
<commit_msg>Check the number of entries in UI test<commit_after>//! Tidy check to ensure below in UI test directories:
//! - the number of entries in each directory must be less than `ENTRY_LIMIT`
//! - there are no stray `.stderr` files

use std::fs;
use std::path::Path;

const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
const ROOT_ENTRY_LIMIT: usize = 1580;
const ISSUES_ENTRY_LIMIT: usize = 2830;

fn check_entries(path: &Path, bad: &mut bool) {
    let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
        .into_iter()
        .filter_entry(|e| e.file_type().is_dir());
    for dir in dirs {
        if let Ok(dir) = dir {
            let dir_path = dir.path();

            // Use special values for these dirs.
            let is_root = path.join("test/ui") == dir_path;
            let is_issues_dir = path.join("test/ui/issues") == dir_path;
            let limit = if is_root {
                ROOT_ENTRY_LIMIT
            } else if is_issues_dir {
                ISSUES_ENTRY_LIMIT
            } else {
                ENTRY_LIMIT
            };

            let count = std::fs::read_dir(dir_path).unwrap().count();
            if count >= limit {
                tidy_error!(
                    bad,
                    "following path contains more than {} entries, \
                    you should move the test to some relevant subdirectory (current: {}): {}",
                    limit,
                    count,
                    dir_path.display()
                );
            }
        }
    }
}

pub fn check(path: &Path, bad: &mut bool) {
    check_entries(&path, bad);
    for path in &[&path.join("test/ui"), &path.join("test/ui-fulldeps")] {
        super::walk_no_read(path, &mut |_| false, &mut |entry| {
            let file_path = entry.path();
            if let Some(ext) = file_path.extension() {
                if ext == "stderr" || ext == "stdout" {
                    // Test output filenames have one of the formats:
                    // ```
                    // $testname.stderr
                    // $testname.$mode.stderr
                    // $testname.$revision.stderr
                    // $testname.$revision.$mode.stderr
                    // ```
                    //
                    // For now, just make sure that there is a corresponding
                    // `$testname.rs` file.
                    //
                    // NB: We do not use file_stem() as some file names have multiple `.`s and we
                    // must strip all of them.
                    let testname =
                        file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
                    if !file_path.with_file_name(testname).with_extension("rs").exists() {
                        println!("Stray file with UI testing output: {:?}", file_path);
                        *bad = true;
                    }

                    if let Ok(metadata) = fs::metadata(file_path) {
                        if metadata.len() == 0 {
                            println!("Empty file with UI testing output: {:?}", file_path);
                            *bad = true;
                        }
                    }
                }
            }
        });
    }
}
<|endoftext|>


<commit_before>pub use super::zfile::ArgType;

/// addition
/// variable2 = variable1 + sub_const
pub fn op_add( variable1: u8, add_const: u16, variable2: u8) -> Vec<u8> {
    let args: Vec<ArgType> = vec![ArgType::Variable, ArgType::LargeConst];
    let mut bytes = op_2(0x14, args);
    let b1 = (add_const >> 8) as u8;
 	let b2 = (add_const & 0xff) as u8;
    bytes.push(variable1);
    write_u16(add_const, bytes);
    bytes.push(variable2);
    bytes
}

/// decrements the value of the variable
pub fn op_dec(variable: u8) -> Vec<u8> {
    let mut bytes = op_1(0x06, ArgType::Reference);
    bytes.push(variable);
    bytes
}

/// increments the value of the variable
pub fn op_inc( variable: u8) -> Vec<u8> {
    let mut bytes = op_1(0x05, ArgType::Reference);
    bytes.push(variable);
    bytes
}

pub fn op_newline() -> Vec<u8> {
    op_0(0x0b)
}

pub fn quit() -> Vec<u8> {
    op_0(0x0a)
}

/// op-codes with 0 operators
fn op_0(value: u8) -> Vec<u8> {
    let byte = value | 0xb0;
    vec![byte]
}

/// op-codes with 1 operator
fn op_1( value: u8, arg_type: ArgType) -> Vec<u8> {
    let mut byte: u8 = 0x80 | value;

     match arg_type {
        ArgType::Reference  => byte |= 0x01 << 4,
        ArgType::Variable   => byte |= 0x02 << 4,
        ArgType::SmallConst => byte |= 0x00 << 4,
        _                   => panic!("no possible 1OP")
    }

    vec![byte]
}

fn op_2( value: u8, arg_types: Vec<ArgType>) -> Vec<u8> {
    let mut byte: u8 = 0x00;
    let mut is_variable: bool = false;
    let mut ret = Vec::new();
    for (i, arg_type) in arg_types.iter().enumerate() {
        let shift: u8 = 6 - i as u8;
        match arg_type {
            &ArgType::SmallConst => byte |= 0x00 << shift,
            &ArgType::Variable   => byte |= 0x01 << shift,
            &ArgType::Reference  => byte |= 0x00 << shift,
            &ArgType::LargeConst => is_variable = true,
            _                    => panic!("no possible 2OP")
        }
    }

    if is_variable {
        let mut byte: u8 = 0xc0 | value;
        byte = byte | value;
        ret.push(byte);

        let mut byte2 = encode_variable_arguments(arg_types);
        byte2 = byte2 | 0xf;
        ret.push(byte2)
    } else {
        byte = byte | value;
        ret.push(byte)
    }
    ret
}

fn encode_variable_arguments( arg_types: Vec<ArgType>) -> u8 {
        let mut byte: u8 = 0x00;
        for (i, arg_type) in arg_types.iter().enumerate() {
            let shift: u8 = 6 - 2 * i as u8;
            match arg_type {
                &ArgType::LargeConst => byte |= 0x00 << shift,
                &ArgType::SmallConst => byte |= 0x01 << shift,
                &ArgType::Variable   => byte |= 0x02 << shift,
                &ArgType::Nothing    => byte |= 0x03 << shift,
                &ArgType::Reference  => byte |= 0x01 << shift,
                //_                    => panic!("no possible varOP")
            }
        }

        byte

    }

///writes u16 to a vec<u8>
pub fn write_u16(value: u16, &mut v: Vec<u8>) {
        v.push((value >> 8) as u8);
        v.push((value & 0xff) as u8);
}
<commit_msg>write_u16 fixed<commit_after>pub use super::zfile::ArgType;

/// addition
/// variable2 = variable1 + sub_const
pub fn op_add( variable1: u8, add_const: u16, variable2: u8) -> Vec<u8> {
    let args: Vec<ArgType> = vec![ArgType::Variable, ArgType::LargeConst];
    let mut bytes = op_2(0x14, args);
    bytes.push(variable1);
	write_u16(add_const, &mut bytes);
    bytes.push(variable2);
    bytes
}

/// decrements the value of the variable
pub fn op_dec(variable: u8) -> Vec<u8> {
    let mut bytes = op_1(0x06, ArgType::Reference);
    bytes.push(variable);
    bytes
}

/// increments the value of the variable
pub fn op_inc( variable: u8) -> Vec<u8> {
    let mut bytes = op_1(0x05, ArgType::Reference);
    bytes.push(variable);
    bytes
}

pub fn op_newline() -> Vec<u8> {
    op_0(0x0b)
}

pub fn quit() -> Vec<u8> {
    op_0(0x0a)
}

/// op-codes with 0 operators
fn op_0(value: u8) -> Vec<u8> {
    let byte = value | 0xb0;
    vec![byte]
}

/// op-codes with 1 operator
fn op_1( value: u8, arg_type: ArgType) -> Vec<u8> {
    let mut byte: u8 = 0x80 | value;

     match arg_type {
        ArgType::Reference  => byte |= 0x01 << 4,
        ArgType::Variable   => byte |= 0x02 << 4,
        ArgType::SmallConst => byte |= 0x00 << 4,
        _                   => panic!("no possible 1OP")
    }

    vec![byte]
}

fn op_2( value: u8, arg_types: Vec<ArgType>) -> Vec<u8> {
    let mut byte: u8 = 0x00;
    let mut is_variable: bool = false;
    let mut ret = Vec::new();
    for (i, arg_type) in arg_types.iter().enumerate() {
        let shift: u8 = 6 - i as u8;
        match arg_type {
            &ArgType::SmallConst => byte |= 0x00 << shift,
            &ArgType::Variable   => byte |= 0x01 << shift,
            &ArgType::Reference  => byte |= 0x00 << shift,
            &ArgType::LargeConst => is_variable = true,
            _                    => panic!("no possible 2OP")
        }
    }

    if is_variable {
        let mut byte: u8 = 0xc0 | value;
        byte = byte | value;
        ret.push(byte);

        let mut byte2 = encode_variable_arguments(arg_types);
        byte2 = byte2 | 0xf;
        ret.push(byte2)
    } else {
        byte = byte | value;
        ret.push(byte)
    }
    ret
}

fn encode_variable_arguments( arg_types: Vec<ArgType>) -> u8 {
        let mut byte: u8 = 0x00;
        for (i, arg_type) in arg_types.iter().enumerate() {
            let shift: u8 = 6 - 2 * i as u8;
            match arg_type {
                &ArgType::LargeConst => byte |= 0x00 << shift,
                &ArgType::SmallConst => byte |= 0x01 << shift,
                &ArgType::Variable   => byte |= 0x02 << shift,
                &ArgType::Nothing    => byte |= 0x03 << shift,
                &ArgType::Reference  => byte |= 0x01 << shift,
                //_                    => panic!("no possible varOP")
            }
        }

        byte

    }

///writes u16 to a vec<u8>
pub fn write_u16(value: u16, v: &mut Vec<u8>) {
        v.push((value >> 8) as u8);
        v.push((value & 0xff) as u8);
}
<|endoftext|>


<commit_before><commit_msg>Add tests where both filter types are used<commit_after><|endoftext|>


<commit_before>//! The datatable module.
//!
//! Contains the DataTable struct and provides methods
//! for converting the tables to various formats.

use std;
use std::collections::HashMap;
use std::str::FromStr;
use std::ops::Index;
use std::vec::IntoIter;

use num::traits::{One, Zero};

use error::DataError;

/// A data table consisting of varying column types and headers.
pub struct DataTable {
    /// Vector of DataColumns.
    pub data_cols: Vec<DataColumn>,
}

impl DataTable {
    /// Constructs an empty DataTable
    pub fn empty() -> DataTable {
        DataTable { data_cols: Vec::new() }
    }

    /// The number of columns in the DataTable.
    pub fn cols(&self) -> usize {
        self.data_cols.len()
    }

    /// The number of rows in the DataTable.
    pub fn rows(&self) -> usize {
        if self.data_cols.len() > 0 {
            return self.data_cols[0].len();
        }

        0usize
    }

    /// Shrinks the table and it's underlying columns.
    pub fn shrink_to_fit(&mut self) {
        for col in self.data_cols.iter_mut() {
            col.shrink_to_fit();
        }

        self.data_cols.shrink_to_fit();
    }

    /// Consumes self and attempts to convert the DataTable into a single Vec.
    ///
    /// Uses column major ordering.
    ///
    /// # Failures
    ///
    /// - DataCastError : Returned when the data cannot be cast into the requested type.
    pub fn into_consistent_data<T: FromStr>(self) -> Result<Vec<T>, DataError> {
        let mut table_data = Vec::with_capacity(self.cols() * self.rows());
        for d in self.data_cols.into_iter() {
            match d.into_vec() {
                Ok(x) => table_data.extend(x),
                Err(e) => return Err(e),
            }
        }

        Ok(table_data)
    }

    /// Attempts to convert the DataTable into a single Vec.
    ///
    /// Uses column major ordering. Returns an Option.
    pub fn consistent_data<T: FromStr>(&self) -> Option<Vec<T>> {
        let mut table_data = Vec::with_capacity(self.cols() * self.rows());
        for d in self.data_cols.iter() {
            match d.cast() {
                Some(x) => table_data.extend(x),
                None => return None,
            }
        }

        Some(table_data)
    }
}

impl Index<usize> for DataTable {
    type Output = DataColumn;

    fn index(&self, idx: usize) -> &DataColumn {
        &self.data_cols[idx]
    }
}

/// A data column consisting of Strings.
pub struct DataColumn {
    /// The name associated with the DataColumn.
    pub name: Option<String>,
    categories: Option<HashMap<String, usize>>,
    data: Vec<String>,
}

impl DataColumn {
    /// Constructs an empty data column.
    pub fn empty() -> DataColumn {
        DataColumn {
            name: None,
            categories: None,
            data: Vec::new(),
        }
    }

    /// Gets the length of the data column.
    pub fn len(&self) -> usize {
        self.data.len()
    }

    /// Gets an immutable reference to the underlying data.
    pub fn data(&self) -> &Vec<String> {
        &self.data
    }

    /// Gets an immutable reference to the categories Option.
    pub fn categories(&self) -> Option<HashMap<String, usize>> {
        match self.categories {
            None => None,
            Some(ref x) => Some(x.clone()),
        }
    }

    /// Update the categories set using the current data.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_data::datatable::DataColumn;
    ///
    /// let mut dc = DataColumn::empty();
    ///
    /// dc.push("Class1".to_string());
    /// dc.push("Class2".to_string());
    /// dc.push("Class2".to_string());
    ///
    /// dc.update_categories();
    /// let categories = dc.categories().unwrap();
    ///
    /// // Note that contains requires a reference so we pass an &str.
    /// assert!(categories.contains_key("Class2"));
    /// assert_eq!(categories.len(), 2);
    /// ```
    pub fn update_categories(&mut self) {
        let mut categories = HashMap::new();
        let mut count = 0usize;

        for s in self.data.iter() {
            if !categories.contains_key(s) {
                categories.insert(s.clone(), count);
                count += 1usize;
            }

        }
        categories.shrink_to_fit();
        self.categories = Some(categories);
    }

    /// Produce a numerical vector representation of the category data.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_data::datatable::DataColumn;
    ///
    /// let mut dc = DataColumn::empty();
    ///
    /// dc.push("Class1".to_string());
    /// dc.push("Class2".to_string());
    /// dc.push("Class2".to_string());
    ///
    /// dc.update_categories();
    ///
    /// let data = dc.numeric_category_data::<f64>().unwrap();
    ///
    /// println!("The data is: {:?}", data);
    /// ```
    pub fn numeric_category_data<T: Zero + One>(&self) -> Result<Vec<Vec<T>>, DataError> {
        if let Some(ref categories) = self.categories {
            let mut outer_vec = Vec::new();

            for _ in 0..categories.len() {
                outer_vec.push(Vec::<T>::new())
            }

            for d in self.data.iter() {
                match categories.get(d) {
                    Some(x) => {
                        for i in 0..categories.len() {
                            if *x == i {
                                outer_vec[i].push(T::one());
                            } else {
                                outer_vec[i].push(T::zero());
                            }
                        }
                    }
                    None => {
                        return Err(DataError::InvalidStateError);
                    }
                }
            }
            return Ok(outer_vec);
        }

        Err(DataError::InvalidStateError)
    }

    /// Pushes a new &str to the column.
    pub fn push(&mut self, val: String) {
        self.data.push(val);
    }

    /// Try to get the element at the index as the requested type.
    ///
    /// # Failures
    ///
    /// - DataCastError : The element at the given index could not be parsed to this type.
    pub fn get_as<T: FromStr>(&self, idx: usize) -> Result<T, DataError> {
        match T::from_str(self.data[idx].as_ref()) {
            Ok(x) => Ok(x),
            Err(_) => Err(DataError::DataCastError),
        }
    }

    /// Shrink the column to fit the data.
    pub fn shrink_to_fit(&mut self) {
        self.data.shrink_to_fit();
    }

    /// Consumes self and returns a Vec of the requested type.
    ///
    /// # Failures
    ///
    /// - DataCastError : Returned when the data cannot be parsed to the requested type.
    pub fn into_vec<T: FromStr>(self) -> Result<Vec<T>, DataError> {
        let mut casted_data = Vec::<T>::with_capacity(self.data.len());

        for d in self.data.into_iter() {
            match T::from_str(d.as_ref()) {
                Ok(x) => casted_data.push(x),
                Err(_) => return Err(DataError::DataCastError),
            }
        }

        Ok(casted_data)
    }

    /// Cast the data to the requested type.
    ///
    /// Returns a Vec of the requested type wrapped in an option.
    pub fn cast<T: FromStr>(&self) -> Option<Vec<T>> {
        let mut casted_data = Vec::<T>::with_capacity(self.data.len());

        for d in self.data.iter() {
            match T::from_str(&d[..]) {
                Ok(x) => casted_data.push(x),
                Err(_) => return None,
            }
        }

        Some(casted_data)
    }

    /// Consumes self and returns an iterator which parses
    /// the data to the specified type returning results.
    ///
    /// The iterator will return a result on `next()` detailing
    /// the outcome of the parse.
    pub fn into_iter_cast<U: FromStr>
        (self)
         -> std::iter::Map<IntoIter<String>, fn(String) -> Result<U, <U as FromStr>::Err>>
        where U: FromStr
    {
        from_str_iter::<_, U>(self.data.into_iter())
    }
}

/// Converts the iterator to a FromStr iterator.
fn from_str_iter<I, U>
    (iter: I)
     -> std::iter::Map<I, fn(<I as Iterator>::Item) -> Result<U, <U as FromStr>::Err>>
    where I: Iterator,
          <I as Iterator>::Item: AsRef<str>,
          U: FromStr
{
    fn from_str_fn<T, U>(item: T) -> Result<U, <U as FromStr>::Err>
        where T: AsRef<str>,
              U: FromStr
    {
        FromStr::from_str(item.as_ref())
    }
    iter.map(from_str_fn)
}

impl Index<usize> for DataColumn {
    type Output = String;
    fn index(&self, idx: usize) -> &String {
        &self.data[idx]
    }
}
<commit_msg>Implementing basic row-major/col-major data pulling.<commit_after>//! The datatable module.
//!
//! Contains the DataTable struct and provides methods
//! for converting the tables to various formats.

use std;
use std::collections::HashMap;
use std::str::FromStr;
use std::ops::Index;
use std::vec::IntoIter;

use num::traits::{One, Zero};

use error::DataError;

/// A data table consisting of varying column types and headers.
pub struct DataTable {
    /// Vector of DataColumns.
    pub data_cols: Vec<DataColumn>,
}

impl DataTable {
    /// Constructs an empty DataTable
    pub fn empty() -> DataTable {
        DataTable { data_cols: Vec::new() }
    }

    /// The number of columns in the DataTable.
    pub fn cols(&self) -> usize {
        self.data_cols.len()
    }

    /// The number of rows in the DataTable.
    pub fn rows(&self) -> usize {
        if self.data_cols.len() > 0 {
            return self.data_cols[0].len();
        }

        0usize
    }

    /// Shrinks the table and it's underlying columns.
    pub fn shrink_to_fit(&mut self) {
        for col in self.data_cols.iter_mut() {
            col.shrink_to_fit();
        }

        self.data_cols.shrink_to_fit();
    }

    /// Consumes self and attempts to convert the DataTable into a single Vec.
    ///
    /// Uses column major ordering.
    ///
    /// # Failures
    ///
    /// - DataCastError : Returned when the data cannot be cast into the requested type.
    pub fn into_consistent_data<T: FromStr>(self, row_major: bool) -> Result<Vec<T>, DataError> {
        let cols = self.cols();
        let rows = self.rows();

        let mut table_data = Vec::with_capacity(cols * rows);
        if row_major {
            let mut column_iters = Vec::new();

            for d in self.data_cols.into_iter() {
                column_iters.push(d.into_iter_cast::<T>());
            }

            for _ in 0..rows {
                for i in 0..cols {
                    match column_iters[i].next() {
                        Some(Ok(x)) => table_data.push(x),
                        Some(Err(_)) => return Err(DataError::DataCastError),
                        None =>{},
                    }
                }
            }
        }
        else {
            for d in self.data_cols.into_iter() {
                match d.into_vec() {
                    Ok(x) => table_data.extend(x),
                    Err(e) => return Err(e),
                }
            }
        }

        if table_data.len() != cols*rows {
            return Err(DataError::InvalidStateError);
        }

        Ok(table_data)
    }
}

impl Index<usize> for DataTable {
    type Output = DataColumn;

    fn index(&self, idx: usize) -> &DataColumn {
        &self.data_cols[idx]
    }
}

/// A data column consisting of Strings.
pub struct DataColumn {
    /// The name associated with the DataColumn.
    pub name: Option<String>,
    categories: Option<HashMap<String, usize>>,
    data: Vec<String>,
}

impl DataColumn {
    /// Constructs an empty data column.
    pub fn empty() -> DataColumn {
        DataColumn {
            name: None,
            categories: None,
            data: Vec::new(),
        }
    }

    /// Gets the length of the data column.
    pub fn len(&self) -> usize {
        self.data.len()
    }

    /// Gets an immutable reference to the underlying data.
    pub fn data(&self) -> &Vec<String> {
        &self.data
    }

    /// Gets an immutable reference to the categories Option.
    pub fn categories(&self) -> Option<HashMap<String, usize>> {
        match self.categories {
            None => None,
            Some(ref x) => Some(x.clone()),
        }
    }

    /// Update the categories set using the current data.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_data::datatable::DataColumn;
    ///
    /// let mut dc = DataColumn::empty();
    ///
    /// dc.push("Class1".to_string());
    /// dc.push("Class2".to_string());
    /// dc.push("Class2".to_string());
    ///
    /// dc.update_categories();
    /// let categories = dc.categories().unwrap();
    ///
    /// // Note that contains requires a reference so we pass an &str.
    /// assert!(categories.contains_key("Class2"));
    /// assert_eq!(categories.len(), 2);
    /// ```
    pub fn update_categories(&mut self) {
        let mut categories = HashMap::new();
        let mut count = 0usize;

        for s in self.data.iter() {
            if !categories.contains_key(s) {
                categories.insert(s.clone(), count);
                count += 1usize;
            }

        }
        categories.shrink_to_fit();
        self.categories = Some(categories);
    }

    /// Produce a numerical vector representation of the category data.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_data::datatable::DataColumn;
    ///
    /// let mut dc = DataColumn::empty();
    ///
    /// dc.push("Class1".to_string());
    /// dc.push("Class2".to_string());
    /// dc.push("Class2".to_string());
    ///
    /// dc.update_categories();
    ///
    /// let data = dc.numeric_category_data::<f64>().unwrap();
    ///
    /// println!("The data is: {:?}", data);
    /// ```
    pub fn numeric_category_data<T: Zero + One>(&self) -> Result<Vec<Vec<T>>, DataError> {
        if let Some(ref categories) = self.categories {
            let mut outer_vec = Vec::new();

            for _ in 0..categories.len() {
                outer_vec.push(Vec::<T>::new())
            }

            for d in self.data.iter() {
                match categories.get(d) {
                    Some(x) => {
                        for i in 0..categories.len() {
                            if *x == i {
                                outer_vec[i].push(T::one());
                            } else {
                                outer_vec[i].push(T::zero());
                            }
                        }
                    }
                    None => {
                        return Err(DataError::InvalidStateError);
                    }
                }
            }
            return Ok(outer_vec);
        }

        Err(DataError::InvalidStateError)
    }

    /// Pushes a new &str to the column.
    pub fn push(&mut self, val: String) {
        self.data.push(val);
    }

    /// Try to get the element at the index as the requested type.
    ///
    /// # Failures
    ///
    /// - DataCastError : The element at the given index could not be parsed to this type.
    pub fn get_as<T: FromStr>(&self, idx: usize) -> Result<T, DataError> {
        match T::from_str(self.data[idx].as_ref()) {
            Ok(x) => Ok(x),
            Err(_) => Err(DataError::DataCastError),
        }
    }

    /// Shrink the column to fit the data.
    pub fn shrink_to_fit(&mut self) {
        self.data.shrink_to_fit();
    }

    /// Consumes self and returns a Vec of the requested type.
    ///
    /// # Failures
    ///
    /// - DataCastError : Returned when the data cannot be parsed to the requested type.
    pub fn into_vec<T: FromStr>(self) -> Result<Vec<T>, DataError> {
        let mut casted_data = Vec::<T>::with_capacity(self.data.len());

        for d in self.data.into_iter() {
            match T::from_str(d.as_ref()) {
                Ok(x) => casted_data.push(x),
                Err(_) => return Err(DataError::DataCastError),
            }
        }

        Ok(casted_data)
    }

    /// Cast the data to the requested type.
    ///
    /// Returns a Vec of the requested type wrapped in an option.
    pub fn cast<T: FromStr>(&self) -> Option<Vec<T>> {
        let mut casted_data = Vec::<T>::with_capacity(self.data.len());

        for d in self.data.iter() {
            match T::from_str(&d[..]) {
                Ok(x) => casted_data.push(x),
                Err(_) => return None,
            }
        }

        Some(casted_data)
    }

    /// Consumes self and returns an iterator which parses
    /// the data to the specified type returning results.
    ///
    /// The iterator will return a result on `next()` detailing
    /// the outcome of the parse.
    pub fn into_iter_cast<U: FromStr>
        (self)
         -> std::iter::Map<IntoIter<String>, fn(String) -> Result<U, <U as FromStr>::Err>>
        where U: FromStr
    {
        from_str_iter::<_, U>(self.data.into_iter())
    }
}

/// Converts the iterator to a FromStr iterator.
fn from_str_iter<I, U>
    (iter: I)
     -> std::iter::Map<I, fn(<I as Iterator>::Item) -> Result<U, <U as FromStr>::Err>>
    where I: Iterator,
          <I as Iterator>::Item: AsRef<str>,
          U: FromStr
{
    fn from_str_fn<T, U>(item: T) -> Result<U, <U as FromStr>::Err>
        where T: AsRef<str>,
              U: FromStr
    {
        FromStr::from_str(item.as_ref())
    }
    iter.map(from_str_fn)
}

impl Index<usize> for DataColumn {
    type Output = String;
    fn index(&self, idx: usize) -> &String {
        &self.data[idx]
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove newline from TestLogger time output<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(missing_docs, missing_copy_implementations)]

//! Memory mapping

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::{Mutex, MutexGuard};
use {Resources, Factory};
use {memory, handle};

/// Unsafe, backend-provided operations for a buffer mapping
#[doc(hidden)]
pub trait Gate<R: Resources> {
    /// Set the element at `index` to `val`. Not bounds-checked.
    unsafe fn set<T>(&self, index: usize, val: T);
    /// Returns a slice of the specified length.
    unsafe fn slice<'a, 'b, T>(&'a self, len: usize) -> &'b [T];
    /// Returns a mutable slice of the specified length.
    unsafe fn mut_slice<'a, 'b, T>(&'a self, len: usize) -> &'b mut [T];

    /// Hook before user read access
    fn before_read(&mut RawInner<R>) {}
    /// Hook before user write access
    fn before_write(&mut RawInner<R>) {}
}

fn valid_access(access: memory::Access, usage: memory::Usage) -> Result<(), Error> {
    use memory::Usage::*;
    match usage {
        Persistent(a) if a.contains(access) => Ok(()),
        _ => Err(Error::InvalidAccess(access, usage)),
    }
}

/// Would mapping this buffer with this memory access be an error ?
fn is_ok<R: Resources>(access: memory::Access, buffer: &handle::RawBuffer<R>) -> Result<(), Error> {
    try!(valid_access(access, buffer.get_info().usage));
    if buffer.mapping().is_some() { Err(Error::AlreadyMapped) }
    else { Ok(()) }
}

#[derive(Debug)]
#[doc(hidden)]
pub struct Status<R: Resources> {
    pub cpu_write: bool,
    pub gpu_access: Option<handle::Fence<R>>,
}

impl<R: Resources> Status<R> {
    fn clean() -> Self {
        Status {
            cpu_write: false,
            gpu_access: None,
        }
    }

    fn access(&mut self) {
        self.gpu_access.take().map(|fence| fence.wait());
    }

    fn write_access(&mut self) {
        self.access();
        self.cpu_write = true;
    }
}

/// Error mapping a buffer.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// The requested mapping access did not match the expected usage.
    InvalidAccess(memory::Access, memory::Usage),
    /// The memory was already mapped
    AlreadyMapped,
}

#[derive(Debug)]
#[doc(hidden)]
pub struct RawInner<R: Resources> {
    pub resource: R::Mapping,
    pub buffer: handle::RawBuffer<R>,
    pub access: memory::Access,
    pub status: Status<R>,
}

impl<R: Resources> Drop for RawInner<R> {
    fn drop(&mut self) {
        self.buffer.was_unmapped();
    }
}

/// Raw mapping providing status tracking
#[derive(Debug)]
pub struct Raw<R: Resources>(Mutex<RawInner<R>>);

impl<R: Resources> Raw<R> {
    #[doc(hidden)]
    pub fn new<F>(access: memory::Access, buffer: &handle::RawBuffer<R>, f: F) -> Result<Self, Error>
        where F: FnOnce() -> R::Mapping
    {
        try!(is_ok(access, buffer));
        Ok(Raw(Mutex::new(RawInner {
            resource: f(),
            buffer: buffer.clone(),
            access: access,
            status: Status::clean(),
        })))
    }

    #[doc(hidden)]
    pub fn access(&self) -> Option<MutexGuard<RawInner<R>>> {
        self.0.try_lock().ok()
    }

    unsafe fn read<T: Copy>(&self, len: usize) -> Reader<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        inner.status.access();

        Reader {
            slice: inner.resource.slice(len),
            inner: inner,
        }
    }

    unsafe fn write<T: Copy>(&self, len: usize) -> Writer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        Writer {
            len: len,
            inner: inner,
            phantom: PhantomData,
        }
    }

    unsafe fn read_write<T: Copy>(&self, len: usize) -> RWer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        RWer {
            slice: inner.resource.mut_slice(len),
            inner: inner,
        }
    }
}

/// Mapping reader
pub struct Reader<'a, R: Resources, T: 'a + Copy> {
    slice: &'a [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for Reader<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { self.slice }
}

/// Mapping writer
pub struct Writer<'a, R: Resources, T: 'a + Copy> {
    len: usize,
    inner: MutexGuard<'a, RawInner<R>>,
    phantom: PhantomData<T>,
}

impl<'a, R: Resources, T: 'a + Copy> Writer<'a, R, T> {
    /// Set a value in the buffer
    pub fn set(&mut self, index: usize, value: T) {
        if index >= self.len {
            panic!("tried to write out of bounds of a mapped buffer");
        }
        unsafe { self.inner.resource.set(index, value); }
    }
}

/// Mapping reader & writer
pub struct RWer<'a, R: Resources, T: 'a + Copy> {
    slice: &'a mut [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for RWer<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { &*self.slice }
}

impl<'a, R: Resources, T: Copy> DerefMut for RWer<'a, R, T> {
    fn deref_mut(&mut self) -> &mut [T] { self.slice }
}

/// Readable mapping.
pub struct Readable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Readable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }
}

/// Writable mapping.
pub struct Writable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Writable<R, T> {
    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }
}

/// Readable & writable mapping.
pub struct RWable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>
}

impl<R: Resources, T: Copy> RWable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }

    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }

    /// Acquire a mapping reader & writer
    pub fn read_write(&mut self) -> RWer<R, T> {
        unsafe { self.raw.read_write::<T>(self.len) }
    }
}

/// A service trait with methods for mapping already implemented.
/// To be used by device back ends.
#[doc(hidden)]
pub trait Builder<R: Resources>: Factory<R> {
    fn map_readable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Readable<R, T>;
    fn map_writable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Writable<R, T>;
    fn map_read_write<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> RWable<R, T>;
}

impl<R: Resources, F: Factory<R>> Builder<R> for F {
    fn map_readable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Readable<R, T> {
        Readable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_writable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Writable<R, T> {
        Writable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_read_write<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> RWable<R, T> {
        RWable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }
}
<commit_msg>Add missing lifetime bound in DerefMut impl for RWer<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(missing_docs, missing_copy_implementations)]

//! Memory mapping

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::{Mutex, MutexGuard};
use {Resources, Factory};
use {memory, handle};

/// Unsafe, backend-provided operations for a buffer mapping
#[doc(hidden)]
pub trait Gate<R: Resources> {
    /// Set the element at `index` to `val`. Not bounds-checked.
    unsafe fn set<T>(&self, index: usize, val: T);
    /// Returns a slice of the specified length.
    unsafe fn slice<'a, 'b, T>(&'a self, len: usize) -> &'b [T];
    /// Returns a mutable slice of the specified length.
    unsafe fn mut_slice<'a, 'b, T>(&'a self, len: usize) -> &'b mut [T];

    /// Hook before user read access
    fn before_read(&mut RawInner<R>) {}
    /// Hook before user write access
    fn before_write(&mut RawInner<R>) {}
}

fn valid_access(access: memory::Access, usage: memory::Usage) -> Result<(), Error> {
    use memory::Usage::*;
    match usage {
        Persistent(a) if a.contains(access) => Ok(()),
        _ => Err(Error::InvalidAccess(access, usage)),
    }
}

/// Would mapping this buffer with this memory access be an error ?
fn is_ok<R: Resources>(access: memory::Access, buffer: &handle::RawBuffer<R>) -> Result<(), Error> {
    try!(valid_access(access, buffer.get_info().usage));
    if buffer.mapping().is_some() { Err(Error::AlreadyMapped) }
    else { Ok(()) }
}

#[derive(Debug)]
#[doc(hidden)]
pub struct Status<R: Resources> {
    pub cpu_write: bool,
    pub gpu_access: Option<handle::Fence<R>>,
}

impl<R: Resources> Status<R> {
    fn clean() -> Self {
        Status {
            cpu_write: false,
            gpu_access: None,
        }
    }

    fn access(&mut self) {
        self.gpu_access.take().map(|fence| fence.wait());
    }

    fn write_access(&mut self) {
        self.access();
        self.cpu_write = true;
    }
}

/// Error mapping a buffer.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// The requested mapping access did not match the expected usage.
    InvalidAccess(memory::Access, memory::Usage),
    /// The memory was already mapped
    AlreadyMapped,
}

#[derive(Debug)]
#[doc(hidden)]
pub struct RawInner<R: Resources> {
    pub resource: R::Mapping,
    pub buffer: handle::RawBuffer<R>,
    pub access: memory::Access,
    pub status: Status<R>,
}

impl<R: Resources> Drop for RawInner<R> {
    fn drop(&mut self) {
        self.buffer.was_unmapped();
    }
}

/// Raw mapping providing status tracking
#[derive(Debug)]
pub struct Raw<R: Resources>(Mutex<RawInner<R>>);

impl<R: Resources> Raw<R> {
    #[doc(hidden)]
    pub fn new<F>(access: memory::Access, buffer: &handle::RawBuffer<R>, f: F) -> Result<Self, Error>
        where F: FnOnce() -> R::Mapping
    {
        try!(is_ok(access, buffer));
        Ok(Raw(Mutex::new(RawInner {
            resource: f(),
            buffer: buffer.clone(),
            access: access,
            status: Status::clean(),
        })))
    }

    #[doc(hidden)]
    pub fn access(&self) -> Option<MutexGuard<RawInner<R>>> {
        self.0.try_lock().ok()
    }

    unsafe fn read<T: Copy>(&self, len: usize) -> Reader<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        inner.status.access();

        Reader {
            slice: inner.resource.slice(len),
            inner: inner,
        }
    }

    unsafe fn write<T: Copy>(&self, len: usize) -> Writer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        Writer {
            len: len,
            inner: inner,
            phantom: PhantomData,
        }
    }

    unsafe fn read_write<T: Copy>(&self, len: usize) -> RWer<R, T> {
        let mut inner = self.access().unwrap();
        R::Mapping::before_read(&mut inner);
        R::Mapping::before_write(&mut inner);
        inner.status.write_access();

        RWer {
            slice: inner.resource.mut_slice(len),
            inner: inner,
        }
    }
}

/// Mapping reader
pub struct Reader<'a, R: Resources, T: 'a + Copy> {
    slice: &'a [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for Reader<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { self.slice }
}

/// Mapping writer
pub struct Writer<'a, R: Resources, T: 'a + Copy> {
    len: usize,
    inner: MutexGuard<'a, RawInner<R>>,
    phantom: PhantomData<T>,
}

impl<'a, R: Resources, T: 'a + Copy> Writer<'a, R, T> {
    /// Set a value in the buffer
    pub fn set(&mut self, index: usize, value: T) {
        if index >= self.len {
            panic!("tried to write out of bounds of a mapped buffer");
        }
        unsafe { self.inner.resource.set(index, value); }
    }
}

/// Mapping reader & writer
pub struct RWer<'a, R: Resources, T: 'a + Copy> {
    slice: &'a mut [T],
    #[allow(dead_code)] inner: MutexGuard<'a, RawInner<R>>,
}

impl<'a, R: Resources, T: 'a + Copy> Deref for RWer<'a, R, T> {
    type Target = [T];

    fn deref(&self) -> &[T] { &*self.slice }
}

impl<'a, R: Resources, T: 'a + Copy> DerefMut for RWer<'a, R, T> {
    fn deref_mut(&mut self) -> &mut [T] { self.slice }
}

/// Readable mapping.
pub struct Readable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Readable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }
}

/// Writable mapping.
pub struct Writable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>,
}

impl<R: Resources, T: Copy> Writable<R, T> {
    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }
}

/// Readable & writable mapping.
pub struct RWable<R: Resources, T: Copy> {
    raw: handle::RawMapping<R>,
    len: usize,
    phantom: PhantomData<T>
}

impl<R: Resources, T: Copy> RWable<R, T> {
    /// Acquire a mapping Reader
    pub fn read(&mut self) -> Reader<R, T> {
        unsafe { self.raw.read::<T>(self.len) }
    }

    /// Acquire a mapping Writer
    pub fn write(&mut self) -> Writer<R, T> {
        unsafe { self.raw.write::<T>(self.len) }
    }

    /// Acquire a mapping reader & writer
    pub fn read_write(&mut self) -> RWer<R, T> {
        unsafe { self.raw.read_write::<T>(self.len) }
    }
}

/// A service trait with methods for mapping already implemented.
/// To be used by device back ends.
#[doc(hidden)]
pub trait Builder<R: Resources>: Factory<R> {
    fn map_readable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Readable<R, T>;
    fn map_writable<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> Writable<R, T>;
    fn map_read_write<T: Copy>(&mut self, handle::RawMapping<R>, usize) -> RWable<R, T>;
}

impl<R: Resources, F: Factory<R>> Builder<R> for F {
    fn map_readable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Readable<R, T> {
        Readable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_writable<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> Writable<R, T> {
        Writable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }

    fn map_read_write<T: Copy>(&mut self, raw: handle::RawMapping<R>, len: usize) -> RWable<R, T> {
        RWable {
            raw: raw,
            len: len,
            phantom: PhantomData,
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "uu_echo"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Derek Chiang <derekchiang93@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#[macro_use]
extern crate uucore;

use std::io::{Write, stdout};
use std::str::from_utf8;

#[allow(dead_code)]
static SYNTAX: &'static str = "[OPTIONS]... [STRING]...";
static SUMMARY: &'static str = "display a line of text";
static LONG_HELP: &'static str = r#"
 Echo the STRING(s) to standard output.
 If -e is in effect, the following sequences are recognized:

 \\\\      backslash
 \\a      alert (BEL)
 \\b      backspace
 \\c      produce no further output
 \\e      escape
 \\f      form feed
 \\n      new line
 \\r      carriage return
 \\t      horizontal tab
 \\v      vertical tab
 \\0NNN   byte with octal value NNN (1 to 3 digits)
 \\xHH    byte with hexadecimal value HH (1 to 2 digits)
"#;

#[derive(Clone)]
struct EchoOptions {
    newline: bool,
    escape: bool
}

#[inline(always)]
fn to_char(bytes: &[u8], base: u32) -> char {
    usize::from_str_radix(from_utf8(bytes.as_ref()).unwrap(), base).unwrap() as u8 as char
}

fn convert_str(string: &[u8], index: usize, base: u32) -> (char, usize) {
    let (max_digits, is_legal_digit) : (usize, fn(u8) -> bool) = match base {
        8 => (3, |c| { (c as char).is_digit(8) }),
        16 => (2, |c| { (c as char).is_digit(16) }),
        _ => panic!(),
    };

    let mut bytes = vec!();
    for offset in 0usize .. max_digits {
        if string.len() <= index + offset as usize {
            break;
        }
        let c = string[index + offset as usize];
        if is_legal_digit(c) {
            bytes.push(c as u8);
        } else {
            break;
        }
    }

    if bytes.is_empty() {
        (' ', 0)
    } else {
        (to_char(&bytes, base), bytes.len())
    }
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut options = EchoOptions {
        newline: false,
        escape: false
    };

    let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
        .optflag("n", "", "do not output the trailing newline")
        .optflag("e", "", "enable interpretation of backslash escapes")
        .optflag("E", "", "disable interpretation of backslash escapes (default)")
        .parse(args);

    options.newline = matches.opt_present("n");
    options.escape = matches.opt_present("e");
    let free = matches.free;
    if !free.is_empty() {
        let string = free.join(" ");
        if options.escape {
            let mut prev_was_slash = false;
            let mut iter = string.chars().enumerate();
            while let Some((index, c)) = iter.next() {
                if !prev_was_slash {
                    if c != '\\' {
                        print!("{}", c);
                    } else {
                        prev_was_slash = true;
                    }
                } else {
                    prev_was_slash = false;
                    match c {
                        '\\' => print!("\\"),
                        'n' => print!("\n"),
                        'r' => print!("\r"),
                        't' => print!("\t"),
                        'v' => print!("\x0B"),
                        'a' => print!("\x07"),
                        'b' => print!("\x08"),
                        'c' => break,
                        'e' => print!("\x1B"),
                        'f' => print!("\x0C"),
                        'x' => {
                            let (c, num_char_used) = convert_str(string.as_bytes(), index + 1, 16);
                            if num_char_used == 0 {
                                print!("\\x");
                            } else {
                                print!("{}", c);
                                for _ in 0 .. num_char_used {
                                    iter.next(); // consume used characters
                                }
                            }
                        },
                        '0' => {
                            let (c, num_char_used) = convert_str(string.as_bytes(), index + 1, 8);
                            if num_char_used == 0 {
                                print!("\0");
                            } else {
                                print!("{}", c);
                                for _ in 0 .. num_char_used {
                                    iter.next(); // consume used characters
                                }
                            }
                        }
                        _ => {
                            let (esc_c, num_char_used) = convert_str(string.as_bytes(), index, 8);
                            if num_char_used == 0 {
                                print!("\\{}", c);
                            } else {
                                print!("{}", esc_c);
                                for _ in 1 .. num_char_used {
                                    iter.next(); // consume used characters
                                }
                            }
                        }
                    }
                }
            }
        } else {
            print!("{}", string);
        }
    }

    if options.newline {
        return_if_err!(1, stdout().flush())
    } else {
        println!()
    }

    0
}
<commit_msg>echo: refactor slightly<commit_after>#![crate_name = "uu_echo"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Derek Chiang <derekchiang93@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#[macro_use]
extern crate uucore;

use std::io::{Write, stdout};
use std::str::from_utf8;

#[allow(dead_code)]
static SYNTAX: &str = "[OPTIONS]... [STRING]...";
static SUMMARY: &str = "display a line of text";
static HELP: &str = r#"
 Echo the STRING(s) to standard output.
 If -e is in effect, the following sequences are recognized:

 \\\\      backslash
 \\a      alert (BEL)
 \\b      backspace
 \\c      produce no further output
 \\e      escape
 \\f      form feed
 \\n      new line
 \\r      carriage return
 \\t      horizontal tab
 \\v      vertical tab
 \\0NNN   byte with octal value NNN (1 to 3 digits)
 \\xHH    byte with hexadecimal value HH (1 to 2 digits)
"#;

enum Base {
    B8 = 8,
    B16 = 16,
}

struct Opts {
    newline: bool,
    escape: bool
}

fn convert_str(string: &[u8], index: usize, base: Base) -> (char, usize) {
    let (max_digits, is_legal_digit): (usize, fn(u8) -> bool) = match base {
        Base::B8 => (3, |c| { (c as char).is_digit(8) }),
        Base::B16 => (2, |c| { (c as char).is_digit(16) }),
    };

    let mut bytes = vec![];
    for offset in 0..max_digits {
        if string.len() <= index + offset as usize {
            break;
        }
        let c = string[index + offset as usize];
        if is_legal_digit(c) {
            bytes.push(c as u8);
        } else {
            break;
        }
    }

    if bytes.is_empty() {
        (' ', 0)
    } else {
        (usize::from_str_radix(
            from_utf8(bytes.as_ref()).unwrap(),
            base as u32
        ).unwrap() as u8 as char, bytes.len())
    }
}

pub fn uumain(args: Vec<String>) -> i32 {
    let matches = new_coreopts!(SYNTAX, SUMMARY, HELP)
        .optflag("n", "", "do not output the trailing newline")
        .optflag("e", "", "enable interpretation of backslash escapes")
        .optflag("E", "", "disable interpretation of backslash escapes (default)")
        .parse(args);

    let options = Opts {
        newline: matches.opt_present("n"),
        escape: matches.opt_present("e"),
    };
    let free = matches.free;
    if !free.is_empty() {
        let string = free.join(" ");
        if options.escape {
            let mut prev_was_slash = false;
            let mut iter = string.chars().enumerate();
            while let Some((mut idx, c)) = iter.next() {
                prev_was_slash = if !prev_was_slash {
                    if c != '\\' {
                        print!("{}", c);
                        false
                    } else {
                        true
                    }
                } else {
                    match c {
                        '\\' => print!("\\"),
                        'n' => print!("\n"),
                        'r' => print!("\r"),
                        't' => print!("\t"),
                        'v' => print!("\x0B"),
                        'a' => print!("\x07"),
                        'b' => print!("\x08"),
                        'c' => break,
                        'e' => print!("\x1B"),
                        'f' => print!("\x0C"),
                        ch => { // 'x' or '0' or _
                            idx = if ch == 'x' || ch == '0' {
                                idx + 1
                            } else {
                                idx
                            };
                            let base = if ch == 'x' { Base::B16 } else { Base::B8 };
                            match convert_str(string.as_bytes(), idx, base) {
                                (_, 0) => {
                                    match ch {
                                        'x' => print!("\\x"),
                                        '0' => print!("\0"),
                                        _ => print!("\\{}", c),
                                    }
                                },
                                (c, num_char_used) => {
                                    print!("{}", c);
                                    let beg = if ch == 'x' || ch == '0' { 0 } else { 1 };
                                    for _ in beg..num_char_used {
                                        iter.next(); // consume used characters
                                    }
                                }
                            }
                        }
                    }
                    false
                }
            }
        } else {
            print!("{}", string);
        }
    }

    if options.newline {
        return_if_err!(1, stdout().flush())
    } else {
        println!()
    }

    0
}
<|endoftext|>


<commit_before>use std::io::println;
use rf_common::*;
use syntax::ast;
use syntax::codemap::Pos;
use find_ast_node::FNodeInfoMap;
use jumptodefmap::{JumpToDefMap};
use codemaput::ToZTextFilePos;
use ioutil;
use rfindctx::{RFindCtx, str_of_opt_ident};

/*new file*/

pub type ZeroBasedIndex=uint;

/// cross crate map, extra info written out when compiling links of a crate
/// allows sunsequent crates to jump to definitions in that crate
/// TODO - check if this already exists in the 'cstore/create metadata'
/// specificially we need node->span info
#[deriving(Clone)]
pub struct CrossCrateMapItem {
	fname:~str,
	line:ZeroBasedIndex,
	col:uint,
	len:uint
}

pub type CrossCrateMap = HashMap<ast::DefId,CrossCrateMapItem>;

pub fn read_cross_crate_map(_:&RFindCtx, crate_num:int, crate_name:&str,lib_path:&str)->~CrossCrateMap {
	let mut raw_bytes=ioutil::fileLoad(crate_name);
	if raw_bytes.len()==0 {
		println("loading lib crosscratemap "+lib_path+"/"+crate_name);
		raw_bytes=ioutil::fileLoad(lib_path+"/"+crate_name);
	}
	let rfx=str::from_utf8(raw_bytes);
	println("loaded cratemap "+rfx.get_ref().len().to_str()+" bytes"+" as crate "+crate_num.to_str());
//	for &x in raw_bytes.iter() { rfx.push_char(x as char); }

	let mut xcm=~HashMap::new();
	for s in rfx.get_ref().lines() {
//		println(s.to_str());
		let toks=s.split('\t').to_owned_vec();
		if toks.len()>=6 {
			match toks[0] {
				"jdef"=> {
					// jimp- to def info, we dont need this here as we already generated it
					// for the current crate. TODO , genarlized rfx would use it..
				}
				"node"=> {
                    // node cratename nodeid parentid sourcefile line col len type [ident]
					//cratename is ignoredd, because we already know it.
					// parent id ignored, we use span information to reconstruct AST

					let node_id: int= from_str::<int>(toks[2]).unwrap_or(0);
					xcm.insert(ast::DefId{krate:crate_num as u32, node:node_id as u32,},
						CrossCrateMapItem{
							fname:	toks[4].to_owned(),
							line:   from_str(toks[5]).unwrap_or(0)-1,
							col:	from_str(toks[6]).unwrap_or(0),
							len:	from_str(toks[7]).unwrap_or(0)
						}
					);
				}
				// legacy noode definitons,no keyword
				_=>{

					let node_id:int=from_str(toks[1]).unwrap_or(0);
					xcm.insert(ast::DefId{krate:crate_num as u32, node:node_id as u32,},
						CrossCrateMapItem{
							fname:	toks[2].to_owned(),
							line:   from_str(toks[3]).unwrap_or(0)-1,
							col:	from_str(toks[4]).unwrap_or(0),
							len:	from_str(toks[5]).unwrap_or(0)
						}
					);
				}
			}
		}
	}
	//dump!(xcm);
	println("from cratemap "+rfx.get_ref().len().to_str()+" bytes");
	xcm
}

pub fn write_cross_crate_map(dc:&RFindCtx, _:&str,nim:&FNodeInfoMap, _:&HashMap<ast::NodeId, ast::DefId>, jdm:&JumpToDefMap) {
	// write inter-crate node map
	let crate_rel_path_name= dc.sess.codemap.files.borrow();
    let crate_rel_path_name = Path::new(crate_rel_path_name.get()[0].name.as_slice());
	let new_format:bool=true;

	let curr_crate_name_only = crate_rel_path_name.filestem_str().unwrap_or("");
	println!("Writing rustfind cross-crate link info for {}", curr_crate_name_only);
    let out_path = crate_rel_path_name.with_extension("rfx");
	let out = ioutil::file_create_with_dirs(&out_path).map(|out| {
        let mut out_file = out;
        // todo - idents to a seperate block, they're rare.
        for (k,ni) in nim.iter() {
            match ni.span.lo.to_text_file_pos(dc.tycx) {
                Some(tfp)=>{
                    // new format, a little more verbose,
                    // and includes parent id for easier reconstruction of full AST
                    // "node" cratename id parent_id filename line col len type [ident]
                    if new_format {
                        try!(writeln!(&mut out_file, "node\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
                            curr_crate_name_only, k, ni.parent_id, tfp.name, (tfp.line + 1), tfp.col,
                            (ni.span.hi - ni.span.lo).to_uint(), ni.kind, str_of_opt_ident(ni.ident)));
                    } else 	{
                        // old format, relies on spans to reconstruct AST.
                        // cratename id filename line col len type [ident]
                        try!(writeln!(&mut out_file, "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
                            curr_crate_name_only, k, tfp.name, (tfp.line+1), tfp.col,
                            (ni.span.hi-ni.span.lo).to_uint(), ni.kind, str_of_opt_ident(ni.ident)));
                    }
                },
                None=>{}
            }
        }

        for (k,v) in jdm.iter()  {
            let cname: ~str = if v.krate > 0 {
                dc.tycx.cstore.get_crate_data(v.krate).name.to_str()
            } else {
                curr_crate_name_only.to_str()
            };
            //println(cdata.name);
            try!(writeln!(&mut out_file, "jdef\t{}\t{}\t{}", k, cname, v.node));
        }

        Ok(())
    });

    match out {
        Err(e) => println!("Error while writing to {}: {}", out_path.display(), e),
        _ => ()
    };

//	for (k,v) in ndm.iter()  {
//		outp.push_str("def\t"+k.to_str()+"\t"+dc.tycx.cstore.crate() +v.node.to_str()+"\n");
//	}
}
<commit_msg>Cleanup whitespace<commit_after>use std::io::println;
use rf_common::*;
use syntax::ast;
use syntax::codemap::Pos;
use find_ast_node::FNodeInfoMap;
use jumptodefmap::{JumpToDefMap};
use codemaput::ToZTextFilePos;
use ioutil;
use rfindctx::{RFindCtx, str_of_opt_ident};

/*new file*/

pub type ZeroBasedIndex=uint;

/// cross crate map, extra info written out when compiling links of a crate
/// allows sunsequent crates to jump to definitions in that crate
/// TODO - check if this already exists in the 'cstore/create metadata'
/// specificially we need node->span info
#[deriving(Clone)]
pub struct CrossCrateMapItem {
    fname:~str,
    line:ZeroBasedIndex,
    col:uint,
    len:uint
}

pub type CrossCrateMap = HashMap<ast::DefId,CrossCrateMapItem>;

pub fn read_cross_crate_map(_:&RFindCtx, crate_num:int, crate_name:&str,lib_path:&str)->~CrossCrateMap {
    let mut raw_bytes=ioutil::fileLoad(crate_name);
    if raw_bytes.len()==0 {
        println("loading lib crosscratemap "+lib_path+"/"+crate_name);
        raw_bytes=ioutil::fileLoad(lib_path+"/"+crate_name);
    }
    let rfx=str::from_utf8(raw_bytes);
    println("loaded cratemap "+rfx.get_ref().len().to_str()+" bytes"+" as crate "+crate_num.to_str());
//  for &x in raw_bytes.iter() { rfx.push_char(x as char); }

    let mut xcm=~HashMap::new();
    for s in rfx.get_ref().lines() {
//      println(s.to_str());
        let toks=s.split('\t').to_owned_vec();
        if toks.len()>=6 {
            match toks[0] {
                "jdef"=> {
                    // jimp- to def info, we dont need this here as we already generated it
                    // for the current crate. TODO , genarlized rfx would use it..
                }
                "node"=> {
                    // node cratename nodeid parentid sourcefile line col len type [ident]
                    //cratename is ignoredd, because we already know it.
                    // parent id ignored, we use span information to reconstruct AST

                    let node_id: int= from_str::<int>(toks[2]).unwrap_or(0);
                    xcm.insert(ast::DefId{krate:crate_num as u32, node:node_id as u32,},
                        CrossCrateMapItem{
                            fname:  toks[4].to_owned(),
                            line:   from_str(toks[5]).unwrap_or(0)-1,
                            col:    from_str(toks[6]).unwrap_or(0),
                            len:    from_str(toks[7]).unwrap_or(0)
                        }
                    );
                }
                // legacy noode definitons,no keyword
                _=>{

                    let node_id:int=from_str(toks[1]).unwrap_or(0);
                    xcm.insert(ast::DefId{krate:crate_num as u32, node:node_id as u32,},
                        CrossCrateMapItem{
                            fname:  toks[2].to_owned(),
                            line:   from_str(toks[3]).unwrap_or(0)-1,
                            col:    from_str(toks[4]).unwrap_or(0),
                            len:    from_str(toks[5]).unwrap_or(0)
                        }
                    );
                }
            }
        }
    }
    //dump!(xcm);
    println("from cratemap "+rfx.get_ref().len().to_str()+" bytes");
    xcm
}

pub fn write_cross_crate_map(dc:&RFindCtx, _:&str,nim:&FNodeInfoMap, _:&HashMap<ast::NodeId, ast::DefId>, jdm:&JumpToDefMap) {
    // write inter-crate node map
    let crate_rel_path_name= dc.sess.codemap.files.borrow();
    let crate_rel_path_name = Path::new(crate_rel_path_name.get()[0].name.as_slice());
    let new_format:bool=true;

    let curr_crate_name_only = crate_rel_path_name.filestem_str().unwrap_or("");
    println!("Writing rustfind cross-crate link info for {}", curr_crate_name_only);
    let out_path = crate_rel_path_name.with_extension("rfx");
    let out = ioutil::file_create_with_dirs(&out_path).map(|out| {
        let mut out_file = out;
        // todo - idents to a seperate block, they're rare.
        for (k,ni) in nim.iter() {
            match ni.span.lo.to_text_file_pos(dc.tycx) {
                Some(tfp)=>{
                    // new format, a little more verbose,
                    // and includes parent id for easier reconstruction of full AST
                    // "node" cratename id parent_id filename line col len type [ident]
                    if new_format {
                        try!(writeln!(&mut out_file, "node\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
                            curr_crate_name_only, k, ni.parent_id, tfp.name, (tfp.line + 1), tfp.col,
                            (ni.span.hi - ni.span.lo).to_uint(), ni.kind, str_of_opt_ident(ni.ident)));
                    } else  {
                        // old format, relies on spans to reconstruct AST.
                        // cratename id filename line col len type [ident]
                        try!(writeln!(&mut out_file, "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
                            curr_crate_name_only, k, tfp.name, (tfp.line+1), tfp.col,
                            (ni.span.hi-ni.span.lo).to_uint(), ni.kind, str_of_opt_ident(ni.ident)));
                    }
                },
                None=>{}
            }
        }

        for (k,v) in jdm.iter()  {
            let cname: ~str = if v.krate > 0 {
                dc.tycx.cstore.get_crate_data(v.krate).name.to_str()
            } else {
                curr_crate_name_only.to_str()
            };
            //println(cdata.name);
            try!(writeln!(&mut out_file, "jdef\t{}\t{}\t{}", k, cname, v.node));
        }

        Ok(())
    });

    match out {
        Err(e) => println!("Error while writing to {}: {}", out_path.display(), e),
        _ => ()
    };

//  for (k,v) in ndm.iter()  {
//      outp.push_str("def\t"+k.to_str()+"\t"+dc.tycx.cstore.crate() +v.node.to_str()+"\n");
//  }
}
<|endoftext|>


<commit_before>//! Binary lambda calculus execution

use binary_encoding::{from_binary};
use lambda_encoding::{encode, decode};
use lambda_calculus::reduction::beta_full;
use self::Error::*;

/// An error that can occur during blc execution.
#[derive(Debug, PartialEq)]
pub enum Error {
    InvalidProgram
}

/// Executes a binary lambda calculus program, feeding it the given argument.
///
/// # Example
/// ```
/// use blc::execution::run;
///
/// let reverse = b"0001011001000110100000000001011100111110111100001011011110110000010";
///
/// assert_eq!(run(&*reverse, b"herp derp"), Ok("pred preh".into()));
/// ```
pub fn run(blc_program: &[u8], blc_argument: &[u8]) -> Result<String, Error> {
    let program = from_binary(blc_program);
    if program.is_err() { return Err(InvalidProgram) }
    let calculation = beta_full(program.unwrap().app(encode(blc_argument))); // safe

    Ok(decode(calculation))
}

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

    #[test]
    fn inflating() {
        // program code from http://www.ioccc.org/2012/tromp/inflate.Blc
        let inflate_compressed =
            [0x44, 0x44, 0x68, 0x16, 0x01, 0x79, 0x1a, 0x00, 0x16, 0x7f, 0xfb, 0xcb, 0xcf, 0xdf,
             0x65, 0xfb, 0xed, 0x0f, 0x3c, 0xe7, 0x3c, 0xf3, 0xc2, 0xd8, 0x20, 0x58, 0x2c, 0x0b,
             0x06, 0xc0];

        let inflate_blc = decompress(&inflate_compressed);
        let s_compressed = [0x1, 0x7a, 0x74];

        assert_eq!(run(&*inflate_blc, &s_compressed[..]).unwrap(), "000000010111101001110100".to_owned());
    }

    #[test]
    fn deflating() {
        // program code from http://www.ioccc.org/2012/tromp/deflate.Blc
        let deflate_compressed =
            [0x44, 0x68, 0x16, 0x05, 0x7e, 0x01, 0x17, 0x00, 0xbe, 0x55, 0xff, 0xf0, 0x0d, 0xc1,
             0x8b, 0xb2, 0xc1, 0xb0, 0xf8, 0x7c, 0x2d, 0xd8, 0x05, 0x9e, 0x09, 0x7f, 0xbf, 0xb1,
             0x48, 0x39, 0xce, 0x81, 0xce, 0x80];

        let deflate_blc = decompress(&deflate_compressed);
        let s_blc = b"00000001011110100111010";

        assert_eq!(run(&*deflate_blc, &s_blc[..]).unwrap().as_bytes(), [0x1, 0x7a, 0x74]);
    }

    #[test]
    fn brainfuck() {
        // program code from
        let bf_interpreter_compressed =
            [0x01, 0xa1, 0x51, 0x44, 0x02, 0xd5, 0x55, 0x84, 0x22, 0x30, 0x70, 0xb7, 0x00, 0xf0,
             0x32, 0xff, 0x7f, 0x85, 0xf9, 0xbf, 0x95, 0x6f, 0xe1, 0x5e, 0xc0, 0xee, 0x7d, 0x7f,
             0x00, 0x68, 0x54, 0xe5, 0xfb, 0xfd, 0x55, 0x58, 0xfd, 0x57, 0x45, 0xe0, 0xb6, 0xf0,
             0xfb, 0xeb, 0x07, 0xd6, 0x2f, 0xf0, 0xd7, 0x73, 0x6f, 0xe1, 0xc0, 0xbc, 0x14, 0xf1,
             0x1f, 0x2e, 0xff, 0x0b, 0x17, 0x66, 0x6f, 0xa1, 0x2f, 0xef, 0x5b, 0xe8, 0xff, 0x13,
             0xff, 0xcf, 0x20, 0x34, 0xca, 0xe1, 0x0b, 0xd0, 0xc8, 0x0a, 0xe5, 0x1f, 0xee, 0x99,
             0x6a, 0x5a, 0x7f, 0xff, 0xff, 0x0f, 0xff, 0x1f, 0xd0, 0x04, 0x9d, 0x87, 0xdb, 0x05,
             0x00, 0xab, 0x3b, 0xb7, 0x40, 0x23, 0xb0, 0xc0, 0xcc, 0x28, 0x10, 0x74, 0x0e, 0x6c];

        let bf_interpreter_blc = decompress(&bf_interpreter_compressed);
        let bf_hello = b"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..\
                         +++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]";

        assert_eq!(run(&bf_interpreter_blc, &bf_hello[..]), Ok("Hello World!".into()));
    }
}
<commit_msg>some more tweaking in blc exec tests<commit_after>//! Binary lambda calculus execution

use binary_encoding::{from_binary};
use lambda_encoding::{encode, decode};
use lambda_calculus::reduction::beta_full;
use self::Error::*;

/// An error that can occur during blc execution.
#[derive(Debug, PartialEq)]
pub enum Error {
    InvalidProgram
}

/// Executes a binary lambda calculus program, feeding it the given argument.
///
/// # Example
/// ```
/// use blc::execution::run;
///
/// let reverse = b"0001011001000110100000000001011100111110111100001011011110110000010";
///
/// assert_eq!(run(&*reverse, b"herp derp"), Ok("pred preh".into()));
/// ```
pub fn run(blc_program: &[u8], blc_argument: &[u8]) -> Result<String, Error> {
    let program = from_binary(blc_program);
    if program.is_err() { return Err(InvalidProgram) }
    let calculation = beta_full(program.unwrap().app(encode(blc_argument))); // safe

    Ok(decode(calculation))
}

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

    #[test]
    fn inflating() {
        // program code from http://www.ioccc.org/2012/tromp/inflate.Blc
        let inflate_compressed =
            [0x44, 0x44, 0x68, 0x16, 0x01, 0x79, 0x1a, 0x00, 0x16, 0x7f, 0xfb, 0xcb, 0xcf, 0xdf,
             0x65, 0xfb, 0xed, 0x0f, 0x3c, 0xe7, 0x3c, 0xf3, 0xc2, 0xd8, 0x20, 0x58, 0x2c, 0x0b,
             0x06, 0xc0];

        let inflate_blc = decompress(&inflate_compressed);
        let s_compressed = [0x1, 0x7a, 0x74];

        assert_eq!(run(&*inflate_blc, &s_compressed[..]).unwrap(), "000000010111101001110100".to_owned());
    }

    #[test]
    fn deflating() {
        // program code from http://www.ioccc.org/2012/tromp/deflate.Blc
        let deflate_compressed =
            [0x44, 0x68, 0x16, 0x05, 0x7e, 0x01, 0x17, 0x00, 0xbe, 0x55, 0xff, 0xf0, 0x0d, 0xc1,
             0x8b, 0xb2, 0xc1, 0xb0, 0xf8, 0x7c, 0x2d, 0xd8, 0x05, 0x9e, 0x09, 0x7f, 0xbf, 0xb1,
             0x48, 0x39, 0xce, 0x81, 0xce, 0x80];

        let deflate_blc = decompress(&deflate_compressed);
        let s_blc = b"00000001011110100111010";

        assert_eq!(run(&*deflate_blc, &s_blc[..]).unwrap().as_bytes(), [0x1, 0x7a, 0x74]);
    }

    #[test] /* WIP */
    fn hilbert() {
        // program code from http://www.ioccc.org/2012/tromp/hilbert.Blc
        let hilbert_compressed =
            [0x18, 0x18, 0x18, 0x18, 0x11, 0x11, 0x54, 0x68, 0x06, 0x04, 0x15, 0x5f, 0xf0, 0x41,
             0x9d, 0xf9, 0xde, 0x16, 0xff, 0xfe, 0x5f, 0x3f, 0xef, 0xf6, 0x15, 0xff, 0x94, 0x68,
             0x40, 0x58, 0x11, 0x7e, 0x05, 0xcb, 0xfe, 0xbc, 0xbf, 0xee, 0x86, 0xcb, 0x94, 0x68,
             0x16, 0x00, 0x5c, 0x0b, 0xfa, 0xcb, 0xfb, 0xf7, 0x1a, 0x85, 0xe0, 0x5c, 0xf4, 0x14,
             0xd5, 0xfe, 0x08, 0x18, 0x0b, 0x04, 0x8d, 0x08, 0x00, 0xe0, 0x78, 0x01, 0x64, 0x45,
             0xff, 0xe5, 0xff, 0x7f, 0xff, 0xfe, 0x5f, 0xff, 0x2f, 0xc0, 0x2f, 0x7a, 0xd9, 0x7f,
             0x5b, 0xff, 0xff, 0xfb, 0xff, 0xfc, 0xaa, 0xff, 0xf7, 0x81, 0x7f, 0xfa, 0xdf, 0x76,
             0x69, 0x54, 0x68, 0x06, 0x01, 0x57, 0xf7, 0xe1, 0x60, 0x5c, 0x13, 0xfe, 0x80, 0xb2,
             0x2c, 0x18, 0x58, 0x1b, 0xfe, 0x5c, 0x10, 0x42, 0xff, 0x80, 0x5d, 0xee, 0xc0, 0x6c,
             0x2c, 0x0c, 0x06, 0x08, 0x19, 0x1a, 0x00, 0x16, 0x7f, 0xbc, 0xbc, 0xfd, 0xf6, 0x5f,
             0x7c, 0x0a, 0x20];

        let hilbert_blc = decompress(&hilbert_compressed);
        let arg = b"1234";

        assert_eq!(run(&hilbert_blc[..], &arg[..]), Ok("WIP".into()));
    }

    #[test] /* WIP */
    fn brainfuck() {
        // program code from http://www.ioccc.org/2012/tromp/bf.Blc
        let bf_interpreter_compressed =
            [0x01, 0xa1, 0x51, 0x44, 0x02, 0xd5, 0x55, 0x84, 0x22, 0x30, 0x70, 0xb7, 0x00, 0xf0,
             0x32, 0xff, 0x7f, 0x85, 0xf9, 0xbf, 0x95, 0x6f, 0xe1, 0x5e, 0xc0, 0xee, 0x7d, 0x7f,
             0x00, 0x68, 0x54, 0xe5, 0xfb, 0xfd, 0x55, 0x58, 0xfd, 0x57, 0x45, 0xe0, 0xb6, 0xf0,
             0xfb, 0xeb, 0x07, 0xd6, 0x2f, 0xf0, 0xd7, 0x73, 0x6f, 0xe1, 0xc0, 0xbc, 0x14, 0xf1,
             0x1f, 0x2e, 0xff, 0x0b, 0x17, 0x66, 0x6f, 0xa1, 0x2f, 0xef, 0x5b, 0xe8, 0xff, 0x13,
             0xff, 0xcf, 0x20, 0x34, 0xca, 0xe1, 0x0b, 0xd0, 0xc8, 0x0a, 0xe5, 0x1f, 0xee, 0x99,
             0x6a, 0x5a, 0x7f, 0xff, 0xff, 0x0f, 0xff, 0x1f, 0xd0, 0x04, 0x9d, 0x87, 0xdb, 0x05,
             0x00, 0xab, 0x3b, 0xb7, 0x40, 0x23, 0xb0, 0xc0, 0xcc, 0x28, 0x10, 0x74, 0x0e, 0x6c];

        let bf_interpreter_blc = decompress(&bf_interpreter_compressed);
        let bf_hello =
            b"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]";

        assert_eq!(run(&bf_interpreter_blc, &bf_hello[..]), Ok("Hello World!".into()));
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate rand;

pub const DEFAULT_ENGLISH_DICTIONARY_PATH: &'static str = "/usr/share/dict/words";

#[derive(Debug)]
pub struct EnglishPasswordOptions {
    pub num_words: u8,
    pub dictionary_path: String,
}

#[derive(Debug)]
pub struct KanaPasswordOptions {
    pub syllable_counts: Vec<u8>,
}

pub enum PasswordOptions {
    English(EnglishPasswordOptions),
    Japanese(KanaPasswordOptions),
}

mod args {
    use crate::{EnglishPasswordOptions, KanaPasswordOptions, PasswordOptions};
    use clap::{value_t, values_t};

    // Aborts this process on error.
    pub fn parse_args() -> PasswordOptions {
        let matches = clap::App::new("xkpw")
            .version("0.1.0")
            .author("j39m")
            .about("Generates passwords")
            .subcommand(
                clap::SubCommand::with_name("en")
                    .about("generates dictionary passwords in English")
                    .arg(clap::Arg::with_name("num-words").required(true)),
            )
            .subcommand(
                clap::SubCommand::with_name("jp")
                    .about("generates random strings of Japanese syllables")
                    .arg(
                        clap::Arg::with_name("syllable-counts")
                            .required(true)
                            .multiple(true),
                    ),
            )
            .get_matches();

        match matches.subcommand() {
            ("en", Some(en_matches)) => {
                return crate::PasswordOptions::English(crate::EnglishPasswordOptions {
                    num_words: clap::value_t!(en_matches, "num-words", u8)
                        .unwrap_or_else(|e| e.exit()),
                    dictionary_path: crate::DEFAULT_ENGLISH_DICTIONARY_PATH.to_owned(),
                })
            }
            ("jp", Some(jp_matches)) => {
                return crate::PasswordOptions::Japanese(crate::KanaPasswordOptions {
                    syllable_counts: clap::values_t!(jp_matches, "syllable-counts", u8)
                        .unwrap_or_else(|e| e.exit()),
                })
            }
            _ => ()
        }
        crate::PasswordOptions::Japanese(crate::KanaPasswordOptions {
            syllable_counts: vec![4, 3, 3, 3],
        })
    }
} // mod args

mod helpers {
    use rand::seq::SliceRandom;
    use std::io::Read;
    use std::convert::TryInto;

    // Reads the dictionary at |path| and returns a linewise vector of
    // its contents.
    fn ingest_english_dictionary(path: &std::path::Path) -> std::io::Result<Vec<String>> {
        let mut file = std::fs::File::open(path)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(contents
            .lines()
            .map(|word| word.trim().to_lowercase())
            .collect())
    }

    // Returns 1 if we fail to read the word dictionary.
    fn print_english_password(options: crate::EnglishPasswordOptions) -> i32 {
        let words = match ingest_english_dictionary(std::path::Path::new(&options.dictionary_path))
        {
            Ok(result) => result,
            Err(error) => {
                eprintln!("Error reading dictionary: {}", error);
                return 1;
            }
        };
        let mut rng = &mut rand::thread_rng();
        let selection: Vec<&String> = words
            .choose_multiple(&mut rng, options.num_words.try_into().unwrap())
            .collect();

        let mut iter = selection.iter();
        if let Some(word) = iter.next() {
            print!("{}", word);
            for word in iter {
                print!(" {}", word);
            }
            print!("\n");
        }
        0
    }

    fn print_kana_password(options: crate::KanaPasswordOptions) {
        eprintln!("XXX(j39m): FIX ME");
    }

    pub fn main() -> i32 {
        let options = crate::args::parse_args();
        match options {
            crate::PasswordOptions::English(options) => return print_english_password(options),
            crate::PasswordOptions::Japanese(options) => print_kana_password(options),
        }
        0
    }
} // mod helpers

fn main() {
    std::process::exit(crate::helpers::main());
}
<commit_msg>xkpw: pass under rustfmt<commit_after>extern crate clap;
extern crate rand;

pub const DEFAULT_ENGLISH_DICTIONARY_PATH: &'static str = "/usr/share/dict/words";

#[derive(Debug)]
pub struct EnglishPasswordOptions {
    pub num_words: u8,
    pub dictionary_path: String,
}

#[derive(Debug)]
pub struct KanaPasswordOptions {
    pub syllable_counts: Vec<u8>,
}

pub enum PasswordOptions {
    English(EnglishPasswordOptions),
    Japanese(KanaPasswordOptions),
}

mod args {
    use crate::{EnglishPasswordOptions, KanaPasswordOptions, PasswordOptions};
    use clap::{value_t, values_t};

    // Aborts this process on error.
    pub fn parse_args() -> PasswordOptions {
        let matches = clap::App::new("xkpw")
            .version("0.1.0")
            .author("j39m")
            .about("Generates passwords")
            .subcommand(
                clap::SubCommand::with_name("en")
                    .about("generates dictionary passwords in English")
                    .arg(clap::Arg::with_name("num-words").required(true)),
            )
            .subcommand(
                clap::SubCommand::with_name("jp")
                    .about("generates random strings of Japanese syllables")
                    .arg(
                        clap::Arg::with_name("syllable-counts")
                            .required(true)
                            .multiple(true),
                    ),
            )
            .get_matches();

        match matches.subcommand() {
            ("en", Some(en_matches)) => {
                return crate::PasswordOptions::English(crate::EnglishPasswordOptions {
                    num_words: clap::value_t!(en_matches, "num-words", u8)
                        .unwrap_or_else(|e| e.exit()),
                    dictionary_path: crate::DEFAULT_ENGLISH_DICTIONARY_PATH.to_owned(),
                })
            }
            ("jp", Some(jp_matches)) => {
                return crate::PasswordOptions::Japanese(crate::KanaPasswordOptions {
                    syllable_counts: clap::values_t!(jp_matches, "syllable-counts", u8)
                        .unwrap_or_else(|e| e.exit()),
                })
            }
            _ => (),
        }
        crate::PasswordOptions::Japanese(crate::KanaPasswordOptions {
            syllable_counts: vec![4, 3, 3, 3],
        })
    }
} // mod args

mod helpers {
    use rand::seq::SliceRandom;
    use std::convert::TryInto;
    use std::io::Read;

    // Reads the dictionary at |path| and returns a linewise vector of
    // its contents.
    fn ingest_english_dictionary(path: &std::path::Path) -> std::io::Result<Vec<String>> {
        let mut file = std::fs::File::open(path)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(contents
            .lines()
            .map(|word| word.trim().to_lowercase())
            .collect())
    }

    // Returns 1 if we fail to read the word dictionary.
    fn print_english_password(options: crate::EnglishPasswordOptions) -> i32 {
        let words = match ingest_english_dictionary(std::path::Path::new(&options.dictionary_path))
        {
            Ok(result) => result,
            Err(error) => {
                eprintln!("Error reading dictionary: {}", error);
                return 1;
            }
        };
        let mut rng = &mut rand::thread_rng();
        let selection: Vec<&String> = words
            .choose_multiple(&mut rng, options.num_words.try_into().unwrap())
            .collect();

        let mut iter = selection.iter();
        if let Some(word) = iter.next() {
            print!("{}", word);
            for word in iter {
                print!(" {}", word);
            }
            print!("\n");
        }
        0
    }

    fn print_kana_password(options: crate::KanaPasswordOptions) {
        eprintln!("XXX(j39m): FIX ME");
    }

    pub fn main() -> i32 {
        let options = crate::args::parse_args();
        match options {
            crate::PasswordOptions::English(options) => return print_english_password(options),
            crate::PasswordOptions::Japanese(options) => print_kana_password(options),
        }
        0
    }
} // mod helpers

fn main() {
    std::process::exit(crate::helpers::main());
}
<|endoftext|>


<commit_before><commit_msg>more progress on lsm storage<commit_after><|endoftext|>