<commit_before><commit_msg>Rust: initial<commit_after>extern crate debug;

use std::rand;
use std::rand::Rng;
use std::collections::hashmap::{HashMap, HashSet};
use std::collections::TrieMap;
use std::cmp;
use std::mem::size_of;
use std::uint;
use std::fmt::Show;

struct WeightedTrie<T> {
_d:()
}

// struct FenwickTree

// struct SegmentTree {
//     root: Option<Box<TreeNode<K, V>>>,
//     length: uint
// }

// struct TreeNode<K, V> {
//     key: K,
//     value: V,
//     left: Option<Box<TreeNode<K, V>>>,
//     right: Option<Box<TreeNode<K, V>>>,
//     level: uint
// }

/// A trait which allows numbers to act as fixed-size bit arrays
pub trait BitArray {
  /// Is bit set?
  fn bit(&self, idx: uint) -> bool;

  /// Returns an array which is just the bits from start to end
  fn bit_slice(&self, start: uint, end: uint) -> uint;
}

impl BitArray for uint {
    /// Is bit set?
    fn bit(&self, idx: uint) -> bool {
        (*self >> (idx % uint::BITS)) & 1 == 1
    }

    /// Returns an array which is just the bits from start to end
    fn bit_slice(&self, start: uint, end: uint) -> uint {
        (*self & (1 << end) - 1) >> start
    }
}

impl<'a> BitArray for &'a [uint] {
    /// Is bit set?
    fn bit(&self, idx: uint) -> bool {
        (self[idx / uint::BITS] >> (idx % uint::BITS)) & 1 == 1
    }

    /// Returns an array which is just the bits from start to end
    fn bit_slice(&self, start: uint, end: uint) -> uint {
        if (start / uint::BITS) == (end / uint::BITS) {
            self[start / uint::BITS].bit_slice(start % uint::BITS, end % uint::BITS)
        } else if end % uint::BITS == 0 && end - start <= 64 {
            self[start / uint::BITS] >> (start % uint::BITS)
        } else if end - start <= 64 {
            ((self[start / uint::BITS] >> (start % uint::BITS))
             | (
                (self[end / uint::BITS] & (end % uint::BITS))
                    <<
                (uint::BITS - (start % uint::BITS))))
        } else {
            fail!("invalid range from {} to {}", start, end);
        }
    }
}

#[test]
fn test_bit() {
    // assert!(3u);
    assert!(3u.bit(0));
}

// impl uint {
//     /// Bitwise and with `n` ones
//     fn mask(self, n: uint) -> uint {
//         self & ((1 << n) - 1)
//     }

//     // /// Returns an array which is just the bits from start to end
//     // fn bit_slice_from(&self, start: uint, end: uint) -> &[uint] {
//     //     (*self & (1 << end) - 1) >> start
//     // }
// }

struct PatriciaTrie<V> {
    data: Option<V>,
    child_l: Option<Box<PatriciaTrie<V>>>,
    child_r: Option<Box<PatriciaTrie<V>>>,
    prefix: uint,
    skip_len: u8
}

impl<V> PatriciaTrie<V> {
  pub fn new() -> PatriciaTrie<V> {
    PatriciaTrie {
      data: None,
      child_l: None,
      child_r: None,
      prefix: 0,
      skip_len: 0
    }
  }

  fn insert(&mut self, key: &[uint], value: V) -> bool {
    let mut node = self;
    let mut idx = 0;
    let key_len = key.len() * uint::BITS;
    loop {
        // Mask in case search key is shorter than node key
        let slice_len = cmp::min(node.skip_len as uint,
                        cmp::min(key_len - idx,
                                 uint::BITS));
        let mut masked_prefix = node.prefix;
        if slice_len < 64 {
            masked_prefix &= ((1 << slice_len) - 1);
        }
        let key_slice = key.bit_slice(idx, idx + slice_len);

        // println!("{masked_prefix} == {key_slice}", masked_prefix = masked_prefix, key_slice = key_slice);
        if masked_prefix == key_slice {
            // Prefixes match
            let slice_len = key_len - idx;
            // Search key is shorter than skip prefix: truncate the prefix and attach
            // the old data as a child
            if node.skip_len as uint > slice_len {
                // Remove the old node's children
                let child_l = node.child_l.take();
                let child_r = node.child_r.take();
                let value_neighbor = node.data.take();
                // Put the old data in a new child, with the remainder of the prefix
                let new_child = if node.prefix.bit(slice_len)
                                  { &mut node.child_r } else { &mut node.child_l };
                *new_child = Some(box PatriciaTrie {
                  data: value_neighbor,
                  child_l: child_l,
                  child_r: child_r,
                  prefix: node.prefix >> (slice_len + 1),
                  skip_len: node.skip_len - slice_len as u8 - 1
                });
                // Chop the prefix down and put the new data in place
                node.skip_len = slice_len as u8;
                node.prefix = key_slice;
                node.data = Some(value);
                return true;
            }
            else if node.skip_len as uint == slice_len {
                // If we have an exact match, great, insert it
                // println!("exact");
                if node.data.is_none() {
                  node.data = Some(value);
                  return true;
                }
                // if overwrite {
                //   node.data = Some(value);
                // }
                return false;
            }
            else {
                // Search key longer than node key, recurse
                idx += node.skip_len as uint + 1;
                let tmp = node;  // hack to appease borrowck
                let subtree = if key.bit(idx - 1)
                                { &mut tmp.child_r } else { &mut tmp.child_l };
                let slice_len = cmp::min(key_len, idx + uint::BITS);
                // Recurse, adding a new node if necessary
                if subtree.is_none() {
                  // println!("skip_len: {slice_len} as u8 - {idx} as u8, prefix = {:x}", key.bit_slice(idx, slice_len), slice_len = slice_len, idx = idx)
                  *subtree = Some(box PatriciaTrie {
                    data: None,
                    child_l: None,
                    child_r: None,
                    prefix: key.bit_slice(idx, slice_len),
                    skip_len: slice_len as u8 - idx as u8
                  });
                }
                // subtree.get_mut_ref is a &mut Box<U> here, so &mut ** gets a &mut U
                node = &mut **subtree.get_mut_ref();
            } // end search_len vs prefix len
        }
        else {
            // Prefixes do not match: split key
            let diff = (masked_prefix ^ key_slice).trailing_zeros();
            // println!("{:x} ^ {:x}  diff={}", masked_prefix, key_slice, diff);

            // Remove the old node's children
            let child_l = node.child_l.take();
            let child_r = node.child_r.take();
            let value_neighbor = node.data.take();
            let tmp = node;  // borrowck hack
            let (insert, neighbor) = if key_slice.bit(diff)
                                          { (&mut tmp.child_r, &mut tmp.child_l) }
                                     else { (&mut tmp.child_l, &mut tmp.child_r) };
            *insert = Some(box PatriciaTrie {
              data: None,
              child_l: None,
              child_r: None,
              prefix: key.bit_slice(idx + diff + 1, key_len),
              skip_len: (key_len - idx - diff - 1) as u8
            });
            *neighbor = Some(box PatriciaTrie {
              data: value_neighbor,
              child_l: child_l,
              child_r: child_r,
              prefix: tmp.prefix >> (diff + 1),
              skip_len: tmp.skip_len - diff as u8 - 1
            });
            // Chop the prefix down
            tmp.skip_len = diff as u8;
            tmp.prefix = tmp.prefix & ((1 << diff) - 1);
            // Recurse
            idx += 1 + diff;
            node = &mut **insert.get_mut_ref();
        } // end if prefixes match
    } // end loop
  }

  pub fn lookup<'a>(&'a self, key: &[uint]) -> Option<&'a V> {
    let mut node = self;
    let mut key_idx = 0;
    let key_len = key.len() * uint::BITS;

    // println!("lookup({})", key);
    loop {
        // If the search key is shorter than the node prefix, there is no
        // way we can match, so fail.
        if key_len - key_idx < node.skip_len as uint {
          return None;
        }

        // Key fails to match prefix --- no match
        if node.prefix != key.bit_slice(key_idx, key_idx + node.skip_len as uint) {
          return None;
        }

        // Key matches prefix: if they are an exact match, return the data
        if node.skip_len as uint == key_len - key_idx {
          return node.data.as_ref();
        } else {
          // Key matches prefix: search key longer than node key, recurse
          key_idx += 1 + node.skip_len as uint;
          let subtree = if key.bit(key_idx - 1) { &node.child_r } else { &node.child_l };
          // println!("bit {} => {}", key_idx - 1, key.bit(key_idx - 1));
          match subtree {
            &Some(ref bx) => {
              node = &**bx;  // bx is a &Box<U> here, so &**bx gets &U
            }
            &None => { return None; }
          }
        }
    } // end loop
  }

  /// Lookup a value by exactly matching `key` and return a referenc
  pub fn lookup_mut<'a>(&'a mut self, key: &[uint]) -> Option<&'a mut V> {
    // Caution: `lookup_mut` never modifies its self parameter (in fact its
    // internal recursion uses a non-mutable self, so we are OK to just
    // transmute our self pointer into a mutable self before passing it in.
    use std::mem::transmute;
    unsafe { transmute(self.lookup(key)) }
  }
}

impl<V:Show> PatriciaTrie<V> {
  /// Print the entire tree
  pub fn print<'a>(&'a self) {
    fn recurse<'a, V:Show>(tree: &'a PatriciaTrie<V>, depth: uint) {
      for i in range(0, tree.skip_len as uint) {
        print!("{:}", if tree.prefix.bit(i) { 1u } else { 0 });
      }
      println!(": {:}", tree.data);
      // left gets no indentation
      match tree.child_l {
        Some(ref t) => {
          for _ in range(0, depth + tree.skip_len as uint) {
            print!("-");
          }
          print!("0");
          recurse(&**t, depth + tree.skip_len as uint + 1);
        }
        None => { }
      }
      // right one gets indentation
      match tree.child_r {
        Some(ref t) => {
          for _ in range(0, depth + tree.skip_len as uint) {
            print!("_");
          }
          print!("1");
          recurse(&**t, depth + tree.skip_len as uint + 1);
        }
        None => { }
      }
    }
    recurse(self, 0);
  }
}

fn main() {
    let mut intern_syl: HashMap<String, uint> = HashMap::new();
    let mut intern_syl_vec: Vec<String> = Vec::new();
    let mut syllable_multiset: HashMap<uint, uint> = HashMap::new();
    let mut syl_trie: PatriciaTrie<HashMap<uint, uint>> = PatriciaTrie::new();
    // let mut syl_trie = TrieMap::new();

    let s = "Ala ma ko ta lu bi mle ko ten ko tek ży";
    // Ala ma ko ta lu bi mle ten

    let mut syls = Vec::new();

    for syl in s.split(' ') {
        let i = intern_syl.len();
        let interned_syl = *intern_syl.find_with_or_insert_with(syl.to_string(),
                                                                i,
                                                                |_k, _v, _a| (),
                                                                |_k, a| {
                                                                    intern_syl_vec.push(syl.to_string());
                                                                    a
                                                                });

        syllable_multiset.find_with_or_insert_with(interned_syl, (), |_k, v_ref, _u| *v_ref += 1, |_k, _u| 1);

        match syls.last() {
            Some(&last) => {
                // println!("{} => {}", *syls.last().unwrap(), interned_syl);
                let found = match syl_trie.lookup_mut(&[last]) {
                    Some(set_ref) => {
                        set_ref.find_with_or_insert_with(interned_syl, (), |_k, v_ref, _u| *v_ref += 1, |_k, _u| 1);
                        true
                    }
                    None => {
                        // println!("trie for {}", syl);
                        false
                    }
                };

                if !found {
                    let mut syllable_multiset: HashMap<uint, uint> = HashMap::new();

                    // println!("{:?}", syl_trie);
                    // syl_trie.print();
                    // println!("inserting key:{}!", &[*syls.last().unwrap()]);
                    // println!("");
                    syllable_multiset.insert(interned_syl, 1);

                    syl_trie.insert(&[last], syllable_multiset);
                }
            }
            None => ()
        }

        syls.push(interned_syl);
    }

    // for i in range(0u, intern_syl_vec.len()) {
    //     match syl_trie.lookup(&[i]) {
    //         Some(set_ref) => {
    //             println!("{} => {}!!", i, set_ref);
    //         }
    //         None => {
    //             println!("None: {}", i);
    //         }
    //     }
    // }

    // intern_syl.insert("Ala".to_string(), 0);
    // intern_syl.insert(" ".to_string(), 1);
    // intern_syl.insert("ma".to_string(), 2);
    // intern_syl.insert("ko".to_string(), 3);
    // intern_syl.insert("ta".to_string(), 4);

    // syllable_multiset.insert(4, 1);

    // let path = [3u, 2];

    // println!("{:?}", syl_trie);
    // syl_trie.print();
    // println!("{}", syllable_multiset);

    // // syl_trie.insert(path.as_slice(), 12345);
    // // syl_trie.insert(path.as_slice().slice_to(1), 6789u);

    // // println!("{:?}", syl_trie);
    // // println!("{:?}", path.as_slice().bit_slice(1, 65));

    // println!("{:?}", syl_trie.lookup(path.as_slice()));

    let mut rng = rand::task_rng();

    // let i: uint = rng.gen_range();
    let mut last_i = rng.gen_range(0, intern_syl_vec.len());
    let last = rng.choose(intern_syl_vec.as_slice());//intern_syl_vec.get(last_i);
    // println!("{}", last);

    for _ in range(0u, 50) {
        match syl_trie.lookup(&[last_i]) {
            Some(set_ref) => {
                let len = set_ref.len();
                let i = rng.gen_range(0, len);
                let (&i, _) = set_ref.iter().skip(i).next().unwrap();
                // println!("{} => {}!", last_i, i);
                last_i = i;
                // println!("{}!", intern_syl_vec.get(last_i));
            }
            None => {
                last_i = rng.gen_range(0, intern_syl_vec.len());
                // println!("{}", intern_syl_vec.get(last_i));
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementations of things like `Eq` for fixed-length arrays
//! up to a certain length. Eventually we should able to generalize
//! to all lengths.
//!
//! *[See also the array primitive type](../primitive.array.html).*

#![unstable(feature = "fixed_size_array",
            reason = "traits and impls are better expressed through generic \
                      integer constants",
            issue = "27778")]

use borrow::{Borrow, BorrowMut};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use convert::{AsRef, AsMut};
use default::Default;
use fmt;
use hash::{Hash, self};
use iter::IntoIterator;
use marker::{Copy, Sized, Unsize};
use option::Option;
use slice::{Iter, IterMut, SliceExt};

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
///
/// The trait is marked unsafe in order to restrict implementors to fixed-size
/// arrays. User of this trait can assume that implementors have the exact
/// layout in memory of a fixed size array (for example, for unsafe
/// initialization).
///
/// Note that the traits AsRef and AsMut provide similar methods for types that
/// may not be fixed-size arrays. Implementors should prefer those traits
/// instead.
pub unsafe trait FixedSizeArray<T> {
    /// Converts the array to immutable slice
    fn as_slice(&self) -> &[T];
    /// Converts the array to mutable slice
    fn as_mut_slice(&mut self) -> &mut [T];
}

unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
    #[inline]
    fn as_slice(&self) -> &[T] {
        self
    }
    #[inline]
    fn as_mut_slice(&mut self) -> &mut [T] {
        self
    }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            impl<T> AsRef<[T]> for [T; $N] {
                #[inline]
                fn as_ref(&self) -> &[T] {
                    &self[..]
                }
            }

            impl<T> AsMut<[T]> for [T; $N] {
                #[inline]
                fn as_mut(&mut self) -> &mut [T] {
                    &mut self[..]
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> Borrow<[T]> for [T; $N] {
                fn borrow(&self) -> &[T] {
                    self
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> BorrowMut<[T]> for [T; $N] {
                fn borrow_mut(&mut self) -> &mut [T] {
                    self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Copy> Clone for [T; $N] {
                fn clone(&self) -> [T; $N] {
                    *self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: Hash> Hash for [T; $N] {
                fn hash<H: hash::Hasher>(&self, state: &mut H) {
                    Hash::hash(&self[..], state)
                }
            }

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

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a [T; $N] {
                type Item = &'a T;
                type IntoIter = Iter<'a, T>;

                fn into_iter(self) -> Iter<'a, T> {
                    self.iter()
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a mut [T; $N] {
                type Item = &'a mut T;
                type IntoIter = IterMut<'a, T>;

                fn into_iter(self) -> IterMut<'a, T> {
                    self.iter_mut()
                }
            }

            // NOTE: some less important impls are omitted to reduce code bloat
            __impl_slice_eq1! { [A; $N], [B; $N] }
            __impl_slice_eq2! { [A; $N], [B] }
            __impl_slice_eq2! { [A; $N], &'b [B] }
            __impl_slice_eq2! { [A; $N], &'b mut [B] }
            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Eq> Eq for [T; $N] { }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:PartialOrd> PartialOrd for [T; $N] {
                #[inline]
                fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                }
                #[inline]
                fn lt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::lt(&&self[..], &&other[..])
                }
                #[inline]
                fn le(&self, other: &[T; $N]) -> bool {
                    PartialOrd::le(&&self[..], &&other[..])
                }
                #[inline]
                fn ge(&self, other: &[T; $N]) -> bool {
                    PartialOrd::ge(&&self[..], &&other[..])
                }
                #[inline]
                fn gt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::gt(&&self[..], &&other[..])
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Ord> Ord for [T; $N] {
                #[inline]
                fn cmp(&self, other: &[T; $N]) -> Ordering {
                    Ord::cmp(&&self[..], &&other[..])
                }
            }
        )+
    }
}

array_impls! {
     0  1  2  3  4  5  6  7  8  9
    10 11 12 13 14 15 16 17 18 19
    20 21 22 23 24 25 26 27 28 29
    30 31 32
}

// The Default impls cannot be generated using the array_impls! macro because
// they require array literals.

macro_rules! array_impl_default {
    {$n:expr, $t:ident $($ts:ident)*} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] where T: Default {
            fn default() -> [T; $n] {
                [$t::default(), $($ts::default()),*]
            }
        }
        array_impl_default!{($n - 1), $($ts)*}
    };
    {$n:expr,} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] {
            fn default() -> [T; $n] { [] }
        }
    };
}

array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
<commit_msg>Auto merge of #30130 - tbu-:pr_array_clone, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementations of things like `Eq` for fixed-length arrays
//! up to a certain length. Eventually we should able to generalize
//! to all lengths.
//!
//! *[See also the array primitive type](../primitive.array.html).*

#![unstable(feature = "fixed_size_array",
            reason = "traits and impls are better expressed through generic \
                      integer constants",
            issue = "27778")]

use borrow::{Borrow, BorrowMut};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use convert::{AsRef, AsMut};
use default::Default;
use fmt;
use hash::{Hash, self};
use iter::IntoIterator;
use marker::{Sized, Unsize};
use option::Option;
use slice::{Iter, IterMut, SliceExt};

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
///
/// The trait is marked unsafe in order to restrict implementors to fixed-size
/// arrays. User of this trait can assume that implementors have the exact
/// layout in memory of a fixed size array (for example, for unsafe
/// initialization).
///
/// Note that the traits AsRef and AsMut provide similar methods for types that
/// may not be fixed-size arrays. Implementors should prefer those traits
/// instead.
pub unsafe trait FixedSizeArray<T> {
    /// Converts the array to immutable slice
    fn as_slice(&self) -> &[T];
    /// Converts the array to mutable slice
    fn as_mut_slice(&mut self) -> &mut [T];
}

unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
    #[inline]
    fn as_slice(&self) -> &[T] {
        self
    }
    #[inline]
    fn as_mut_slice(&mut self) -> &mut [T] {
        self
    }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            impl<T> AsRef<[T]> for [T; $N] {
                #[inline]
                fn as_ref(&self) -> &[T] {
                    &self[..]
                }
            }

            impl<T> AsMut<[T]> for [T; $N] {
                #[inline]
                fn as_mut(&mut self) -> &mut [T] {
                    &mut self[..]
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> Borrow<[T]> for [T; $N] {
                fn borrow(&self) -> &[T] {
                    self
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> BorrowMut<[T]> for [T; $N] {
                fn borrow_mut(&mut self) -> &mut [T] {
                    self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: Hash> Hash for [T; $N] {
                fn hash<H: hash::Hasher>(&self, state: &mut H) {
                    Hash::hash(&self[..], state)
                }
            }

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

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a [T; $N] {
                type Item = &'a T;
                type IntoIter = Iter<'a, T>;

                fn into_iter(self) -> Iter<'a, T> {
                    self.iter()
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a mut [T; $N] {
                type Item = &'a mut T;
                type IntoIter = IterMut<'a, T>;

                fn into_iter(self) -> IterMut<'a, T> {
                    self.iter_mut()
                }
            }

            // NOTE: some less important impls are omitted to reduce code bloat
            __impl_slice_eq1! { [A; $N], [B; $N] }
            __impl_slice_eq2! { [A; $N], [B] }
            __impl_slice_eq2! { [A; $N], &'b [B] }
            __impl_slice_eq2! { [A; $N], &'b mut [B] }
            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Eq> Eq for [T; $N] { }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:PartialOrd> PartialOrd for [T; $N] {
                #[inline]
                fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                }
                #[inline]
                fn lt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::lt(&&self[..], &&other[..])
                }
                #[inline]
                fn le(&self, other: &[T; $N]) -> bool {
                    PartialOrd::le(&&self[..], &&other[..])
                }
                #[inline]
                fn ge(&self, other: &[T; $N]) -> bool {
                    PartialOrd::ge(&&self[..], &&other[..])
                }
                #[inline]
                fn gt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::gt(&&self[..], &&other[..])
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Ord> Ord for [T; $N] {
                #[inline]
                fn cmp(&self, other: &[T; $N]) -> Ordering {
                    Ord::cmp(&&self[..], &&other[..])
                }
            }
        )+
    }
}

array_impls! {
     0  1  2  3  4  5  6  7  8  9
    10 11 12 13 14 15 16 17 18 19
    20 21 22 23 24 25 26 27 28 29
    30 31 32
}

// The Default impls cannot be generated using the array_impls! macro because
// they require array literals.

macro_rules! array_impl_default {
    {$n:expr, $t:ident $($ts:ident)*} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] where T: Default {
            fn default() -> [T; $n] {
                [$t::default(), $($ts::default()),*]
            }
        }
        array_impl_default!{($n - 1), $($ts)*}
    };
    {$n:expr,} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] {
            fn default() -> [T; $n] { [] }
        }
    };
}

array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}

macro_rules! array_impl_clone {
    {$n:expr, $i:expr, $($idx:expr,)*} => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl<T: Clone> Clone for [T; $n] {
            fn clone(&self) -> [T; $n] {
                [self[$i-$i].clone(), $(self[$i-$idx].clone()),*]
            }
        }
        array_impl_clone!{$i, $($idx,)*}
    };
    {$n:expr,} => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl<T: Clone> Clone for [T; 0] {
            fn clone(&self) -> [T; 0] {
                []
            }
        }
    };
}

array_impl_clone! {
                                32, 31, 30,
    29, 28, 27, 26, 25, 24, 23, 22, 21, 20,
    19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
     9,  8,  7,  6,  5,  4,  3,  2,  1,  0,
}
<|endoftext|>


<commit_before>import ptr::extensions;

export handle;
export reader_methods;
export writer_methods;
export scope;

type scope_data<T:send,A> = {
    mut layout_active: bool,
    mut free_list: [handle<T,A>],
    mut first_dirty: handle<T,A>
};

resource scope_rsrc<T:send,A>(d: scope_data<T,A>) {
    unsafe {
        for d.free_list.each { |h| free_handle(h); }
    }
}

type scope<T:send,A> = @scope_rsrc<T,A>;

type handle_data<T:send,A> = {mut rd_ptr: *T,
                              mut wr_ptr: *T,
                              mut rd_aux: *A,
                              mut next_dirty: handle<T,A>};
enum handle<T:send,A> {
    _handle(*handle_data<T,A>)
}

impl private_methods<T:send,A> for handle<T,A> {
    fn rd_ptr() -> *T unsafe { (**self).rd_ptr }
    fn wr_ptr() -> *T unsafe { (**self).wr_ptr }
    fn rd_aux() -> *A unsafe { (**self).rd_aux }
    fn next_dirty() -> handle<T,A> unsafe { (**self).next_dirty }

    fn set_rd_ptr(t: *T) unsafe { (**self).rd_ptr = t; }
    fn set_wr_ptr(t: *T) unsafe { (**self).wr_ptr = t; }
    fn set_rd_aux(t: *A) unsafe { (**self).rd_aux = t; }
    fn set_next_dirty(+h: handle<T,A>) unsafe { (**self).next_dirty = h; }

    fn is_null() -> bool { (*self).is_null() }
    fn is_not_null() -> bool { (*self).is_not_null() }
}

impl reader_methods<T:send,A> for handle<T,A> {
    fn rd<U>(f: fn(T) -> U) -> U unsafe {
        f(*self.rd_ptr())
    }

    fn has_aux() -> bool unsafe {
        self.rd_aux().is_not_null()
    }

    fn set_aux(p: @A) unsafe {
        (**self).rd_aux = ptr::addr_of(*p);
    }

    fn aux<U>(f: fn(A) -> U) -> U unsafe {
        // warning: do not use if has_aux() is false!
        f(*self.rd_aux())
    }
}

impl private_methods<T:send,A> for scope<T,A> {
    fn clone(v: *T) -> *T unsafe {
        let n: *mut T =
            unsafe::reinterpret_cast(
                libc::calloc(sys::size_of::<T>(), 1u));

        // n.b.: this assignment will run the drop glue for <T,A>.
        // *Hopefully* the fact that everything is initialized to NULL
        // by calloc will make this ok.  We may have to make the take
        // glue be tolerant.
        *n = unsafe{*v};

        ret unsafe::reinterpret_cast(n);
    }
}

unsafe fn free<T:send>(t: *T) {
    let _x <- *unsafe::reinterpret_cast::<*T,*mut T>(t);
    libc::free(unsafe::reinterpret_cast(t));
}

unsafe fn free_handle<T:send,A>(h: handle<T,A>) {
    free(h.rd_ptr());
    if h.wr_ptr() != h.rd_ptr() { free(h.wr_ptr()); }
}

fn null_handle<T:send,A>() -> handle<T,A> {
    _handle(ptr::null())
}

fn scope<T:send,A>() -> scope<T,A> {
    @scope_rsrc({mut layout_active: false,
                 mut free_list: [],
                 mut first_dirty: null_handle()})
}

impl writer_methods<T:send,A> for scope<T,A> {
    fn is_reader_forked() -> bool {
        self.layout_active
    }

    fn reader_forked() {
        assert !self.layout_active;
        assert self.first_dirty.is_null();
        self.layout_active = true;
    }

    fn reader_joined() unsafe {
        assert self.layout_active;

        if self.first_dirty.is_not_null() {
            let mut handle = self.first_dirty;
            while (*handle).is_not_null() {
                free(handle.rd_ptr());

                handle.set_rd_ptr(handle.wr_ptr());
                let next_handle = handle.next_dirty();
                handle.set_next_dirty(null_handle());
                handle = next_handle;
            }
            self.first_dirty = null_handle();
        }

        assert self.first_dirty.is_null();
        self.layout_active = false;
    }

    fn rd<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
        // Use the wr_ptr, which may be more up to date than the
        // rd_ptr or may not
        f(*h.wr_ptr())
    }

    fn wr<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
        if self.layout_active && h.rd_ptr() == h.wr_ptr() {
            #debug["marking handle %? as dirty", h];
            h.set_wr_ptr(self.clone(h.rd_ptr()));
            h.set_next_dirty(self.first_dirty);
            self.first_dirty = h;
        }
        f(*h.wr_ptr())
    }

    fn handle(v: T) -> handle<T,A> unsafe {
        let d: *handle_data<T,A> =
            unsafe::reinterpret_cast(
                libc::malloc(sys::size_of::<handle_data<T,A>>()));
        (*d).rd_ptr = self.clone(ptr::addr_of(v));
        (*d).wr_ptr = (*d).rd_ptr;
        (*d).rd_aux = ptr::null();
        (*d).next_dirty = null_handle();
        let h = _handle(d);
        self.free_list += [h];
        ret h;
    }
}

#[cfg(test)]
mod test {

    type animal = {name: str, species: species};
    enum species {
        chicken(~chicken),
        bull(~bull)
    }
    type chicken = {mut eggs_per_day:uint};
    type bull = {mut horns:uint};

    type processed = {flag: bool};

    type animal_scope = scope<animal, processed>;

    #[test]
    fn handles_get_freed() {
        let s: animal_scope = scope();
        s.handle({name:"henrietta", species:chicken(~{mut eggs_per_day:22u})});
        s.handle({name:"ferdinand", species:bull(~{mut horns:3u})});
    }

    fn mutate(a: animal) {
        alt a.species {
          chicken(c) { c.eggs_per_day += 1u; }
          bull(c) { c.horns += 1u; }
        }
    }

    fn read_characteristic(a: animal) -> uint {
        alt a.species {
          chicken(c) { c.eggs_per_day }
          bull(c) { c.horns }
        }
    }

    #[test]
    fn interspersed_execution() {
        let s: animal_scope = scope();
        let henrietta =
            s.handle({name:"henrietta",
                      species:chicken(~{mut eggs_per_day:0u})});
        let ferdinand =
            s.handle({name:"ferdinand",
                      species:bull(~{mut horns:0u})});

        let iter1 = 3u;
        let iter2 = 22u;
        let read_port = comm::port();
        let read_chan = comm::chan(read_port);

        // fire up a reader task
        uint::range(0u, iter1) { |i|
            s.reader_forked();
            let wait_chan = task::spawn_listener {|wait_port|
                uint::range(0u, iter2) { |_i|
                    comm::send(read_chan, henrietta.rd(read_characteristic));
                    comm::send(read_chan, ferdinand.rd(read_characteristic));
                    comm::recv(wait_port);
                }
            };

            let hrc = henrietta.rd(read_characteristic);
            assert hrc == (i * iter2);

            let frc = ferdinand.rd(read_characteristic);
            assert frc == i * iter2;

            uint::range(0u, iter2) { |_i|
                assert hrc == comm::recv(read_port);
                s.wr(henrietta, mutate);
                assert frc == comm::recv(read_port);
                s.wr(ferdinand, mutate);
                comm::send(wait_chan, ());
            }
            s.reader_joined();
        }

        assert henrietta.rd(read_characteristic) == iter1 * iter2;
        assert ferdinand.rd(read_characteristic) == iter1 * iter2;
    }

}<commit_msg>Assert that self.has_aux() in rcu before returning aux<commit_after>import ptr::extensions;

export handle;
export reader_methods;
export writer_methods;
export scope;

type scope_data<T:send,A> = {
    mut layout_active: bool,
    mut free_list: [handle<T,A>],
    mut first_dirty: handle<T,A>
};

resource scope_rsrc<T:send,A>(d: scope_data<T,A>) {
    unsafe {
        for d.free_list.each { |h| free_handle(h); }
    }
}

type scope<T:send,A> = @scope_rsrc<T,A>;

type handle_data<T:send,A> = {mut rd_ptr: *T,
                              mut wr_ptr: *T,
                              mut rd_aux: *A,
                              mut next_dirty: handle<T,A>};
enum handle<T:send,A> {
    _handle(*handle_data<T,A>)
}

impl private_methods<T:send,A> for handle<T,A> {
    fn rd_ptr() -> *T unsafe { (**self).rd_ptr }
    fn wr_ptr() -> *T unsafe { (**self).wr_ptr }
    fn rd_aux() -> *A unsafe { (**self).rd_aux }
    fn next_dirty() -> handle<T,A> unsafe { (**self).next_dirty }

    fn set_rd_ptr(t: *T) unsafe { (**self).rd_ptr = t; }
    fn set_wr_ptr(t: *T) unsafe { (**self).wr_ptr = t; }
    fn set_rd_aux(t: *A) unsafe { (**self).rd_aux = t; }
    fn set_next_dirty(+h: handle<T,A>) unsafe { (**self).next_dirty = h; }

    fn is_null() -> bool { (*self).is_null() }
    fn is_not_null() -> bool { (*self).is_not_null() }
}

impl reader_methods<T:send,A> for handle<T,A> {
    fn rd<U>(f: fn(T) -> U) -> U unsafe {
        f(*self.rd_ptr())
    }

    fn has_aux() -> bool unsafe {
        self.rd_aux().is_not_null()
    }

    fn set_aux(p: @A) unsafe {
        (**self).rd_aux = ptr::addr_of(*p);
    }

    fn aux<U>(f: fn(A) -> U) -> U unsafe {
        assert self.has_aux();
        f(*self.rd_aux())
    }
}

impl private_methods<T:send,A> for scope<T,A> {
    fn clone(v: *T) -> *T unsafe {
        let n: *mut T =
            unsafe::reinterpret_cast(
                libc::calloc(sys::size_of::<T>(), 1u));

        // n.b.: this assignment will run the drop glue for <T,A>.
        // *Hopefully* the fact that everything is initialized to NULL
        // by calloc will make this ok.  We may have to make the take
        // glue be tolerant.
        *n = unsafe{*v};

        ret unsafe::reinterpret_cast(n);
    }
}

unsafe fn free<T:send>(t: *T) {
    let _x <- *unsafe::reinterpret_cast::<*T,*mut T>(t);
    libc::free(unsafe::reinterpret_cast(t));
}

unsafe fn free_handle<T:send,A>(h: handle<T,A>) {
    free(h.rd_ptr());
    if h.wr_ptr() != h.rd_ptr() { free(h.wr_ptr()); }
}

fn null_handle<T:send,A>() -> handle<T,A> {
    _handle(ptr::null())
}

fn scope<T:send,A>() -> scope<T,A> {
    @scope_rsrc({mut layout_active: false,
                 mut free_list: [],
                 mut first_dirty: null_handle()})
}

impl writer_methods<T:send,A> for scope<T,A> {
    fn is_reader_forked() -> bool {
        self.layout_active
    }

    fn reader_forked() {
        assert !self.layout_active;
        assert self.first_dirty.is_null();
        self.layout_active = true;
    }

    fn reader_joined() unsafe {
        assert self.layout_active;

        if self.first_dirty.is_not_null() {
            let mut handle = self.first_dirty;
            while (*handle).is_not_null() {
                free(handle.rd_ptr());

                handle.set_rd_ptr(handle.wr_ptr());
                let next_handle = handle.next_dirty();
                handle.set_next_dirty(null_handle());
                handle = next_handle;
            }
            self.first_dirty = null_handle();
        }

        assert self.first_dirty.is_null();
        self.layout_active = false;
    }

    fn rd<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
        // Use the wr_ptr, which may be more up to date than the
        // rd_ptr or may not
        f(*h.wr_ptr())
    }

    fn wr<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
        if self.layout_active && h.rd_ptr() == h.wr_ptr() {
            #debug["marking handle %? as dirty", h];
            h.set_wr_ptr(self.clone(h.rd_ptr()));
            h.set_next_dirty(self.first_dirty);
            self.first_dirty = h;
        }
        f(*h.wr_ptr())
    }

    fn handle(v: T) -> handle<T,A> unsafe {
        let d: *handle_data<T,A> =
            unsafe::reinterpret_cast(
                libc::malloc(sys::size_of::<handle_data<T,A>>()));
        (*d).rd_ptr = self.clone(ptr::addr_of(v));
        (*d).wr_ptr = (*d).rd_ptr;
        (*d).rd_aux = ptr::null();
        (*d).next_dirty = null_handle();
        let h = _handle(d);
        self.free_list += [h];
        ret h;
    }
}

#[cfg(test)]
mod test {

    type animal = {name: str, species: species};
    enum species {
        chicken(~chicken),
        bull(~bull)
    }
    type chicken = {mut eggs_per_day:uint};
    type bull = {mut horns:uint};

    type processed = {flag: bool};

    type animal_scope = scope<animal, processed>;

    #[test]
    fn handles_get_freed() {
        let s: animal_scope = scope();
        s.handle({name:"henrietta", species:chicken(~{mut eggs_per_day:22u})});
        s.handle({name:"ferdinand", species:bull(~{mut horns:3u})});
    }

    fn mutate(a: animal) {
        alt a.species {
          chicken(c) { c.eggs_per_day += 1u; }
          bull(c) { c.horns += 1u; }
        }
    }

    fn read_characteristic(a: animal) -> uint {
        alt a.species {
          chicken(c) { c.eggs_per_day }
          bull(c) { c.horns }
        }
    }

    #[test]
    fn interspersed_execution() {
        let s: animal_scope = scope();
        let henrietta =
            s.handle({name:"henrietta",
                      species:chicken(~{mut eggs_per_day:0u})});
        let ferdinand =
            s.handle({name:"ferdinand",
                      species:bull(~{mut horns:0u})});

        let iter1 = 3u;
        let iter2 = 22u;
        let read_port = comm::port();
        let read_chan = comm::chan(read_port);

        // fire up a reader task
        uint::range(0u, iter1) { |i|
            s.reader_forked();
            let wait_chan = task::spawn_listener {|wait_port|
                uint::range(0u, iter2) { |_i|
                    comm::send(read_chan, henrietta.rd(read_characteristic));
                    comm::send(read_chan, ferdinand.rd(read_characteristic));
                    comm::recv(wait_port);
                }
            };

            let hrc = henrietta.rd(read_characteristic);
            assert hrc == (i * iter2);

            let frc = ferdinand.rd(read_characteristic);
            assert frc == i * iter2;

            uint::range(0u, iter2) { |_i|
                assert hrc == comm::recv(read_port);
                s.wr(henrietta, mutate);
                assert frc == comm::recv(read_port);
                s.wr(ferdinand, mutate);
                comm::send(wait_chan, ());
            }
            s.reader_joined();
        }

        assert henrietta.rd(read_characteristic) == iter1 * iter2;
        assert ferdinand.rd(read_characteristic) == iter1 * iter2;
    }

}
<|endoftext|>


<commit_before><commit_msg>Add I2C/MPU-9250 example<commit_after>#![no_std]

extern crate cortex_m;
extern crate embedded_hal;
extern crate stm32f0_hal;
extern crate stm32f0x2;

use embedded_hal::prelude::*;
use stm32f0x2::{I2C1, GPIOB, RCC};
use stm32f0_hal::gpio;
use stm32f0_hal::i2c::I2C;

fn main() {
    // This example was developed and tested with the STM32F072B Discovery board
    // and an TDK-InvenSense Motion Sensor Universal Evaluation Board (UEVB)
    // with an MPU-9250. It assumes that the UEVB is connected to the discovery
    // board in the following way:
    // - GND to GND, VIN to 3V.
    // - AD0 to GND (sets the LSB of the 7-bit address to 0)
    // - SCL to PB6, SDA to PB7

    cortex_m::interrupt::free(|cs| {
        let rcc = RCC.borrow(cs);
        let gpiob = GPIOB.borrow(cs);
        let i2c = I2C1.borrow(cs);

        let mut i2c = I2C::init(rcc, gpiob, i2c);

        // Set up LEDs that we can later use to signal error or success
        //
        // These LEDs are marked as LD3, LD4, and LD5 on the STM32F0 Discovery
        // board. Please note that the board's documentation that matches those
        // names to PC6, PC8, and PC9 is not correct. It also mixes up the
        // colors of the LEDs. At least that's the case with the board I have in
        // front of me.
        let mut led_init = gpio::Output::setup(gpio::Pin::PC8); // orange
        let mut led_success = gpio::Output::setup(gpio::Pin::PC9); // green
        let mut led_error = gpio::Output::setup(gpio::Pin::PC6); // red

        led_init.high();
        led_success.low();
        led_error.low();

        // This is the address of the MPU-9250, is AD0 is connected to GND, as
        // specified above. If it is connected to VIN instead, the LSB must be
        // 1.
        let mpu9250_address = 0b1101000 << 1;

        // WHOAMI register
        if let Err(_) = i2c.write(mpu9250_address, &[117]) {
            led_error.high();
            loop {}
        }
        let mut buffer = [0u8; 1];
        if let Err(_) = i2c.read(mpu9250_address, &mut buffer) {
            led_error.high();
            loop {}
        }

        // Check received data
        // The WHOAMI register should always return 0x71.
        if buffer[0] == 0x71 {
            led_success.high();
        } else {
            led_error.high();
        }
    });
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary debug message<commit_after><|endoftext|>


<commit_before><commit_msg>initial commit<commit_after>use std::io;

#[deriving(Eq)]
enum Value {
	List(~[Value]),
	Atom(~str),
	Str(~str),
	Num(float)
}

fn read_number(input: &str, start: uint) -> Option<(~Value, uint)> {
	for (i,c) in input.iter().enumerate().skip(start) {
		if c == ' ' || i == input.len()-1 {
			let acc = input.slice(start, i+1);
			match std::float::from_str(acc) {
				Some(f) => return Some((~Num(f), i)),
				None => return None
			}
		}
	}

	None
}

fn read_list(input: &str, start: uint) -> Option<(~Value, uint)> {
	let mut list = ~[];
	let mut i = start;
	loop {
		match read_value(input, i) {
			Some((v,new_i)) => {
				list.push(*v);
				i = new_i;
			}
			None if input[start] as char == ')' => return Some((~List(list), i)),
			None => return None
		}
	}
}

fn read_atom(input: &str, start: uint) -> Option<(~Value, uint)> {
	let atom = std::str::from_chars(input.iter().skip(start).take_while(|&c| c != ' ' && c != ')').to_owned_vec());
	let len = atom.len();
	printfln!("atom: %s | %u", atom, len);
	Some((~Atom(atom), start + len))
}

fn read_value(input: &str, start: uint) -> Option<(~Value, uint)> {
	if(start >= input.len() || input.is_whitespace() || input.slice(start, input.len()).is_whitespace()) {
		return None
	}

	match input[start] as char {
		' ' => read_value(input, start+1),
		'(' => read_list(input, start+1),
		')' => None,
		c if c.is_digit() || c == '.' => read_number(input, start),
		c => read_atom(input, start)
	}
}

fn parse(input: &str) -> Option<Value> {
	/*do io::with_str_reader(input) |r| {
		//let c =
		println("blah: " + input + " -> " + read_token(r));
		List(~[])
	}*/
	match read_value(input, 0) {
		Some((v,_)) => {
			println(fmt!("v: %?", *v));
			Some(*v)
		}
		None => None
	}
}

#[test]
fn test_sexp() {
	assert_eq!(parse(""), None);
	assert_eq!(parse("123"), Some(Num(123.0)));
	assert_eq!(parse("()"), Some(List(~[])));
	assert_eq!(parse("3.14159265358"), Some(Num(3.14159265358)));
	assert_eq!(parse("(hi)"), Some(List(~[Atom(~"hi")])));
	assert_eq!(parse("(hi there)"), Some(List(~[Atom(~"hi"), Atom(~"there")])));
	assert_eq!(parse("(hi (there))"), Some(List(~[Atom(~"hi"), List(~[Atom(~"there")])])));
}<|endoftext|>


<commit_before><commit_msg>[No-auto] bin/domain/log: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before>use std::{mem, ptr, int};
use std::num::Int;
use std::ops::{Index, IndexMut};
use alloc::heap;
use os::token::Token;

/// A preallocated chunk of memory for storing objects of the same type.
pub struct Slab<T> {
    // Chunk of memory
    mem: *mut Entry<T>,
    // Number of elements currently in the slab
    len: int,
    // The total number of elements that the slab can hold
    cap: int,
    // THe token offset
    off: uint,
    // Offset of the next available slot in the slab. Set to the slab's
    // capacity when the slab is full.
    nxt: int,
    // The total number of slots that were initialized
    init: int,
}

const MAX: uint = int::MAX as uint;

// When Entry.nxt is set to this, the entry is in use
const IN_USE: int = -1;

impl<T> Slab<T> {
    pub fn new(cap: uint) -> Slab<T> {
        Slab::new_starting_at(Token(0), cap)
    }

    pub fn new_starting_at(offset: Token, cap: uint) -> Slab<T> {
        assert!(cap <= MAX, "capacity too large");
        // TODO:
        // - Rename to with_capacity
        // - Use a power of 2 capacity
        // - Ensure that mem size is less than uint::MAX

        let size = cap.checked_mul(mem::size_of::<Entry<T>>())
            .expect("capacity overflow");

        let ptr = unsafe { heap::allocate(size, mem::min_align_of::<Entry<T>>()) };

        Slab {
            mem: ptr as *mut Entry<T>,
            cap: cap as int,
            len: 0,
            off: offset.as_uint(),
            nxt: 0,
            init: 0,
        }
    }

    #[inline]
    pub fn count(&self) -> uint {
        self.len as uint
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    #[inline]
    pub fn remaining(&self) -> uint {
        (self.cap - self.len) as uint
    }

    #[inline]
    pub fn has_remaining(&self) -> bool {
        self.remaining() > 0
    }

    #[inline]
    pub fn contains(&self, idx: Token) -> bool {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                return self.entry(idx).in_use();
            }
        }

        false
    }

    pub fn get(&self, idx: Token) -> Option<&T> {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                let entry = self.entry(idx);

                if entry.in_use() {
                    return Some(&entry.val);
                }
            }
        }

        None
    }

    pub fn get_mut(&mut self, idx: Token) -> Option<&mut T> {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                let mut entry = self.mut_entry(idx);

                if entry.in_use() {
                    return Some(&mut entry.val);
                }
            }
        }

        None
    }

    pub fn insert(&mut self, val: T) -> Result<Token, T> {
        let idx = self.nxt;

        if idx == self.init {
            // Using an uninitialized entry
            if idx == self.cap {
                // No more capacity
                debug!("slab out of capacity; cap={}", self.cap);
                return Err(val);
            }

            self.mut_entry(idx).put(val, true);

            self.init += 1;
            self.len = self.init;
            self.nxt = self.init;

            debug!("inserting into new slot; idx={}", idx);
        }
        else {
            self.len += 1;
            self.nxt = self.mut_entry(idx).put(val, false);

            debug!("inserting into reused slot; idx={}", idx);
        }

        Ok(self.idx_to_token(idx))
    }

    /// Releases the given slot
    pub fn remove(&mut self, idx: Token) -> Option<T> {
        debug!("removing value; idx={:?}", idx);

        // Cast to uint
        let idx = self.token_to_idx(idx);

        if idx > MAX {
            return None;
        }

        let idx = idx as int;

        // Ensure index is within capacity of slab
        if idx >= self.init {
            return None;
        }

        let nxt = self.nxt;

        match self.mut_entry(idx).remove(nxt) {
            Some(v) => {
                self.nxt = idx;
                self.len -= 1;
                Some(v)
            }
            None => None
        }
    }

    #[inline]
    fn entry(&self, idx: int) -> &Entry<T> {
        unsafe { &*self.mem.offset(idx) }
    }

    #[inline]
    fn mut_entry(&mut self, idx: int) -> &mut Entry<T> {
        unsafe { &mut *self.mem.offset(idx) }
    }

    #[inline]
    fn validate_idx(&self, idx: uint) -> int {
        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                return idx;
            }
        }

        panic!("invalid index {} -- greater than capacity {}", idx, self.cap);
    }

    fn token_to_idx(&self, token: Token) -> uint {
        token.as_uint() - self.off
    }

    fn idx_to_token(&self, idx: int) -> Token {
        Token(idx as uint + self.off)
    }
}

impl<T> Index<Token> for Slab<T> {
    type Output = T;

    fn index<'a>(&'a self, idx: &Token) -> &'a T {
        let idx = self.token_to_idx(*idx);
        let idx = self.validate_idx(idx);

        let e = self.entry(idx);

        if !e.in_use() {
            panic!("invalid index; idx={}", idx);
        }

        &e.val
    }
}

impl<T> IndexMut<Token> for Slab<T> {
    type Output = T;

    fn index_mut<'a>(&'a mut self, idx: &Token) -> &'a mut T {
        let idx = self.token_to_idx(*idx);
        let idx = self.validate_idx(idx);

        let e = self.mut_entry(idx);

        if !e.in_use() {
            panic!("invalid index; idx={}", idx);
        }

        &mut e.val
    }
}

#[unsafe_destructor]
impl<T> Drop for Slab<T> {
    fn drop(&mut self) {
        // TODO: check whether or not this is needed with intrinsics::needs_drop
        let mut i = 0;

        while i < self.init {
            self.mut_entry(i).release();
            i += 1;
        }

        let cap = self.cap as uint;
        let size = cap.checked_mul(mem::size_of::<Entry<T>>()).unwrap();
        unsafe { heap::deallocate(self.mem as *mut u8, size, mem::min_align_of::<Entry<T>>()) };
    }
}

// Holds the values in the slab.
struct Entry<T> {
    nxt: int,
    val: T
}

impl<T> Entry<T> {
    #[inline]
    fn put(&mut self, val: T, init: bool) -> int {
        assert!(init || self.nxt != IN_USE);

        let ret = self.nxt;

        unsafe { ptr::write(&mut self.val as *mut T, val); }
        self.nxt = IN_USE;

        // Could be uninitialized memory, but the caller (Slab) should guard
        // not use the return value in those cases.
        ret
    }

    fn remove(&mut self, nxt: int) -> Option<T> {
        if self.in_use() {
            self.nxt = nxt;
            Some(unsafe { ptr::read(&self.val as *const T) })
        } else {
            None
        }
    }

    fn release(&mut self) {
        if self.in_use() {
            let _ = Some(unsafe { ptr::read(&self.val as *const T) });
        }
    }

    #[inline]
    fn in_use(&self) -> bool {
        self.nxt == IN_USE
    }
}

#[cfg(test)]
mod tests {
    use super::Slab;
    use {Token};

    #[test]
    fn test_insertion() {
        let mut slab = Slab::new(1);
        let token = slab.insert(10u).ok().expect("Failed to insert");
        assert_eq!(slab[token], 10u);
    }

    #[test]
    fn test_repeated_insertion() {
        let mut slab = Slab::new(10);

        for i in range(0u, 10u) {
            let token = slab.insert(i + 10u).ok().expect("Failed to insert");
            assert_eq!(slab[token], i + 10u);
        }

        slab.insert(20).err().expect("Inserted when full");
    }

    #[test]
    fn test_repeated_insertion_and_removal() {
        let mut slab = Slab::new(10);
        let mut tokens = vec![];

        for i in range(0u, 10u) {
            let token = slab.insert(i + 10u).ok().expect("Failed to insert");
            tokens.push(token);
            assert_eq!(slab[token], i + 10u);
        }

        for &i in tokens.iter() {
            slab.remove(i);
        }

        slab.insert(20).ok().expect("Failed to insert in newly empty slab");
    }

    #[test]
    fn test_insertion_when_full() {
        let mut slab = Slab::new(1);
        slab.insert(10u).ok().expect("Failed to insert");
        slab.insert(10u).err().expect("Inserted into a full slab");
    }

    #[test]
    fn test_removal_is_successful() {
        let mut slab = Slab::new(1);
        let t1 = slab.insert(10u).ok().expect("Failed to insert");
        slab.remove(t1);
        let t2 = slab.insert(20u).ok().expect("Failed to insert");
        assert_eq!(slab[t2], 20u);
    }

    #[test]
    fn test_mut_retrieval() {
        let mut slab = Slab::new(1);
        let t1 = slab.insert("foo".to_string()).ok().expect("Failed to insert");

        slab[t1].push_str("bar");

        assert_eq!(slab[t1].as_slice(), "foobar");
    }

    #[test]
    #[should_fail]
    fn test_reusing_slots_1() {
        let mut slab = Slab::new(16);

        let t0 = slab.insert(123u).unwrap();
        let t1 = slab.insert(456u).unwrap();

        assert!(slab.count() == 2);
        assert!(slab.remaining() == 14);

        slab.remove(t0);

        assert!(slab.count() == 1, "actual={}", slab.count());
        assert!(slab.remaining() == 15);

        slab.remove(t1);

        assert!(slab.count() == 0);
        assert!(slab.remaining() == 16);

        let _ = slab[t1];
    }

    #[test]
    fn test_reusing_slots_2() {
        let mut slab = Slab::new(16);

        let t0 = slab.insert(123u).unwrap();

        assert!(slab[t0] == 123u);
        assert!(slab.remove(t0) == Some(123u));

        let t0 = slab.insert(456u).unwrap();

        assert!(slab[t0] == 456u);

        let t1 = slab.insert(789u).unwrap();

        assert!(slab[t0] == 456u);
        assert!(slab[t1] == 789u);

        assert!(slab.remove(t0).unwrap() == 456u);
        assert!(slab.remove(t1).unwrap() == 789u);

        assert!(slab.count() == 0);
    }

    #[test]
    #[should_fail]
    fn test_accessing_out_of_bounds() {
        let slab = Slab::<uint>::new(16);
        slab[Token(0)];
    }

    #[test]
    fn test_contains() {
        let mut slab = Slab::new_starting_at(Token(5),16);
        assert!(!slab.contains(Token(0)));

        let tok = slab.insert(111u).unwrap();
        assert!(slab.contains(tok));
    }
}
<commit_msg>Make Slab<T> Send if T is.<commit_after>use std::{mem, ptr, int};
use std::num::Int;
use std::ops::{Index, IndexMut};
use alloc::heap;
use os::token::Token;

/// A preallocated chunk of memory for storing objects of the same type.
pub struct Slab<T> {
    // Chunk of memory
    mem: *mut Entry<T>,
    // Number of elements currently in the slab
    len: int,
    // The total number of elements that the slab can hold
    cap: int,
    // THe token offset
    off: uint,
    // Offset of the next available slot in the slab. Set to the slab's
    // capacity when the slab is full.
    nxt: int,
    // The total number of slots that were initialized
    init: int,
}

const MAX: uint = int::MAX as uint;

// When Entry.nxt is set to this, the entry is in use
const IN_USE: int = -1;

unsafe impl<T> Send for Slab<T> where T: Send {}

impl<T> Slab<T> {
    pub fn new(cap: uint) -> Slab<T> {
        Slab::new_starting_at(Token(0), cap)
    }

    pub fn new_starting_at(offset: Token, cap: uint) -> Slab<T> {
        assert!(cap <= MAX, "capacity too large");
        // TODO:
        // - Rename to with_capacity
        // - Use a power of 2 capacity
        // - Ensure that mem size is less than uint::MAX

        let size = cap.checked_mul(mem::size_of::<Entry<T>>())
            .expect("capacity overflow");

        let ptr = unsafe { heap::allocate(size, mem::min_align_of::<Entry<T>>()) };

        Slab {
            mem: ptr as *mut Entry<T>,
            cap: cap as int,
            len: 0,
            off: offset.as_uint(),
            nxt: 0,
            init: 0,
        }
    }

    #[inline]
    pub fn count(&self) -> uint {
        self.len as uint
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    #[inline]
    pub fn remaining(&self) -> uint {
        (self.cap - self.len) as uint
    }

    #[inline]
    pub fn has_remaining(&self) -> bool {
        self.remaining() > 0
    }

    #[inline]
    pub fn contains(&self, idx: Token) -> bool {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                return self.entry(idx).in_use();
            }
        }

        false
    }

    pub fn get(&self, idx: Token) -> Option<&T> {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                let entry = self.entry(idx);

                if entry.in_use() {
                    return Some(&entry.val);
                }
            }
        }

        None
    }

    pub fn get_mut(&mut self, idx: Token) -> Option<&mut T> {
        let idx = self.token_to_idx(idx);

        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                let mut entry = self.mut_entry(idx);

                if entry.in_use() {
                    return Some(&mut entry.val);
                }
            }
        }

        None
    }

    pub fn insert(&mut self, val: T) -> Result<Token, T> {
        let idx = self.nxt;

        if idx == self.init {
            // Using an uninitialized entry
            if idx == self.cap {
                // No more capacity
                debug!("slab out of capacity; cap={}", self.cap);
                return Err(val);
            }

            self.mut_entry(idx).put(val, true);

            self.init += 1;
            self.len = self.init;
            self.nxt = self.init;

            debug!("inserting into new slot; idx={}", idx);
        }
        else {
            self.len += 1;
            self.nxt = self.mut_entry(idx).put(val, false);

            debug!("inserting into reused slot; idx={}", idx);
        }

        Ok(self.idx_to_token(idx))
    }

    /// Releases the given slot
    pub fn remove(&mut self, idx: Token) -> Option<T> {
        debug!("removing value; idx={:?}", idx);

        // Cast to uint
        let idx = self.token_to_idx(idx);

        if idx > MAX {
            return None;
        }

        let idx = idx as int;

        // Ensure index is within capacity of slab
        if idx >= self.init {
            return None;
        }

        let nxt = self.nxt;

        match self.mut_entry(idx).remove(nxt) {
            Some(v) => {
                self.nxt = idx;
                self.len -= 1;
                Some(v)
            }
            None => None
        }
    }

    #[inline]
    fn entry(&self, idx: int) -> &Entry<T> {
        unsafe { &*self.mem.offset(idx) }
    }

    #[inline]
    fn mut_entry(&mut self, idx: int) -> &mut Entry<T> {
        unsafe { &mut *self.mem.offset(idx) }
    }

    #[inline]
    fn validate_idx(&self, idx: uint) -> int {
        if idx <= MAX {
            let idx = idx as int;

            if idx < self.init {
                return idx;
            }
        }

        panic!("invalid index {} -- greater than capacity {}", idx, self.cap);
    }

    fn token_to_idx(&self, token: Token) -> uint {
        token.as_uint() - self.off
    }

    fn idx_to_token(&self, idx: int) -> Token {
        Token(idx as uint + self.off)
    }
}

impl<T> Index<Token> for Slab<T> {
    type Output = T;

    fn index<'a>(&'a self, idx: &Token) -> &'a T {
        let idx = self.token_to_idx(*idx);
        let idx = self.validate_idx(idx);

        let e = self.entry(idx);

        if !e.in_use() {
            panic!("invalid index; idx={}", idx);
        }

        &e.val
    }
}

impl<T> IndexMut<Token> for Slab<T> {
    type Output = T;

    fn index_mut<'a>(&'a mut self, idx: &Token) -> &'a mut T {
        let idx = self.token_to_idx(*idx);
        let idx = self.validate_idx(idx);

        let e = self.mut_entry(idx);

        if !e.in_use() {
            panic!("invalid index; idx={}", idx);
        }

        &mut e.val
    }
}

#[unsafe_destructor]
impl<T> Drop for Slab<T> {
    fn drop(&mut self) {
        // TODO: check whether or not this is needed with intrinsics::needs_drop
        let mut i = 0;

        while i < self.init {
            self.mut_entry(i).release();
            i += 1;
        }

        let cap = self.cap as uint;
        let size = cap.checked_mul(mem::size_of::<Entry<T>>()).unwrap();
        unsafe { heap::deallocate(self.mem as *mut u8, size, mem::min_align_of::<Entry<T>>()) };
    }
}

// Holds the values in the slab.
struct Entry<T> {
    nxt: int,
    val: T
}

impl<T> Entry<T> {
    #[inline]
    fn put(&mut self, val: T, init: bool) -> int {
        assert!(init || self.nxt != IN_USE);

        let ret = self.nxt;

        unsafe { ptr::write(&mut self.val as *mut T, val); }
        self.nxt = IN_USE;

        // Could be uninitialized memory, but the caller (Slab) should guard
        // not use the return value in those cases.
        ret
    }

    fn remove(&mut self, nxt: int) -> Option<T> {
        if self.in_use() {
            self.nxt = nxt;
            Some(unsafe { ptr::read(&self.val as *const T) })
        } else {
            None
        }
    }

    fn release(&mut self) {
        if self.in_use() {
            let _ = Some(unsafe { ptr::read(&self.val as *const T) });
        }
    }

    #[inline]
    fn in_use(&self) -> bool {
        self.nxt == IN_USE
    }
}

#[cfg(test)]
mod tests {
    use super::Slab;
    use {Token};

    #[test]
    fn test_insertion() {
        let mut slab = Slab::new(1);
        let token = slab.insert(10u).ok().expect("Failed to insert");
        assert_eq!(slab[token], 10u);
    }

    #[test]
    fn test_repeated_insertion() {
        let mut slab = Slab::new(10);

        for i in range(0u, 10u) {
            let token = slab.insert(i + 10u).ok().expect("Failed to insert");
            assert_eq!(slab[token], i + 10u);
        }

        slab.insert(20).err().expect("Inserted when full");
    }

    #[test]
    fn test_repeated_insertion_and_removal() {
        let mut slab = Slab::new(10);
        let mut tokens = vec![];

        for i in range(0u, 10u) {
            let token = slab.insert(i + 10u).ok().expect("Failed to insert");
            tokens.push(token);
            assert_eq!(slab[token], i + 10u);
        }

        for &i in tokens.iter() {
            slab.remove(i);
        }

        slab.insert(20).ok().expect("Failed to insert in newly empty slab");
    }

    #[test]
    fn test_insertion_when_full() {
        let mut slab = Slab::new(1);
        slab.insert(10u).ok().expect("Failed to insert");
        slab.insert(10u).err().expect("Inserted into a full slab");
    }

    #[test]
    fn test_removal_is_successful() {
        let mut slab = Slab::new(1);
        let t1 = slab.insert(10u).ok().expect("Failed to insert");
        slab.remove(t1);
        let t2 = slab.insert(20u).ok().expect("Failed to insert");
        assert_eq!(slab[t2], 20u);
    }

    #[test]
    fn test_mut_retrieval() {
        let mut slab = Slab::new(1);
        let t1 = slab.insert("foo".to_string()).ok().expect("Failed to insert");

        slab[t1].push_str("bar");

        assert_eq!(slab[t1].as_slice(), "foobar");
    }

    #[test]
    #[should_fail]
    fn test_reusing_slots_1() {
        let mut slab = Slab::new(16);

        let t0 = slab.insert(123u).unwrap();
        let t1 = slab.insert(456u).unwrap();

        assert!(slab.count() == 2);
        assert!(slab.remaining() == 14);

        slab.remove(t0);

        assert!(slab.count() == 1, "actual={}", slab.count());
        assert!(slab.remaining() == 15);

        slab.remove(t1);

        assert!(slab.count() == 0);
        assert!(slab.remaining() == 16);

        let _ = slab[t1];
    }

    #[test]
    fn test_reusing_slots_2() {
        let mut slab = Slab::new(16);

        let t0 = slab.insert(123u).unwrap();

        assert!(slab[t0] == 123u);
        assert!(slab.remove(t0) == Some(123u));

        let t0 = slab.insert(456u).unwrap();

        assert!(slab[t0] == 456u);

        let t1 = slab.insert(789u).unwrap();

        assert!(slab[t0] == 456u);
        assert!(slab[t1] == 789u);

        assert!(slab.remove(t0).unwrap() == 456u);
        assert!(slab.remove(t1).unwrap() == 789u);

        assert!(slab.count() == 0);
    }

    #[test]
    #[should_fail]
    fn test_accessing_out_of_bounds() {
        let slab = Slab::<uint>::new(16);
        slab[Token(0)];
    }

    #[test]
    fn test_contains() {
        let mut slab = Slab::new_starting_at(Token(5),16);
        assert!(!slab.contains(Token(0)));

        let tok = slab.insert(111u).unwrap();
        assert!(slab.contains(tok));
    }
}
<|endoftext|>


<commit_before><commit_msg>start work on first real example<commit_after>extern crate tini;
use std::collections::HashMap;
use tini::Ini;

fn main() {
    let config = Ini::from_file("converter.ini").unwrap();

    // iterate over config
    let currencies: HashMap<String, f64> =
        config.section_iter("currencies").map(|(k, v)| (k.to_string(), v.parse().unwrap())).collect();

    // cli code here
}
<|endoftext|>


<commit_before><commit_msg>add test for #37765<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Parser test for #37765

fn with_parens<T: ToString>(arg: T) -> String { //~WARN dead_code
  return (<T as ToString>::to_string(&arg)); //~WARN unused_parens
}

fn no_parens<T: ToString>(arg: T) -> String { //~WARN dead_code
  return <T as ToString>::to_string(&arg);
}

fn main() {

}
<|endoftext|>


<commit_before><commit_msg>woops - add liblrustc<commit_after>// Copyright 2012-2014 The Literate Rust Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![experimental]
#![crate_id = "lrustc"]
#![desc = "lrustc, Literate Rust"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(globs)]
#![feature(phase)]

extern crate regex;
extern crate debug;
#[phase(plugin, link)] extern crate log;

use std::io::{File, fs, Open, Read};
use std::path::posix::Path;

/// Convert a lrs path to a rs path.
fn lrs_path_to_rs(path: Path) -> Option<Path> {
    path.extension_str().and_then(
        |ext| match ext {
            "lrs" => {
                let mut newpath = path.clone();
                newpath.set_extension("rs");
                Some(newpath)
            }
            _ => { None }
        }
    )
}

fn dump(path: Path) {
    let file = match File::open_mode(&path, Open, Read) {
        Ok(f) => f,
        Err(e) => fail!("file error: {}", e),
    };

}

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

    fn expect_path(path: &str, expect: &str) {
        let path = Path::new(path.clone());
        let ps = lrs_path_to_rs(path).unwrap();
        assert!(ps.as_str().unwrap() == expect);
    }

    #[test]
    fn test_lrs_path_to_rs() {
        expect_path("/tmp/lrustc.lrs", "/tmp/lrustc.rs");
        expect_path("~/tmp/afs.lrs", "~/tmp/afs.rs");
        assert!(lrs_path_to_rs(Path::new("/tmp/lr.rs")).is_none());
        assert!(lrs_path_to_rs(Path::new("lr.rs")).is_none());
    }

}
<|endoftext|>


<commit_before><commit_msg>Update invalid parameter use in rm.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Fix wc on new nightly<commit_after><|endoftext|>


<commit_before><commit_msg>Fix duration parsing for sub-second units.<commit_after><|endoftext|>


<commit_before><commit_msg>Document Database.clear<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Pierre Marijon.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! GFF3 format reading and writing.
//!
//! GFF2 definition : http://gmod.org/wiki/GFF2#The_GFF2_File_Format (not yet support)
//! GTF2 definition : http://mblab.wustl.edu/GTF2.html (not yet support)
//! GFF3 definition : http://gmod.org/wiki/GFF3#GFF3_Format
//!
//! # Example
//!
//! ```
//! use std::io;
//! use bio::io::gff;
//! let reader = gff::Reader::new(io::stdin());
//! ```

use std::io;
use std::fs;
use std::path::Path;
use std::convert::AsRef;
use std::collections::HashMap;

use csv;

use io::Strand;

/// A GFF reader.
pub struct Reader<R: io::Read> {
    inner: csv::Reader<R>,
}

impl Reader<fs::File> {
    /// Read GFF from given file path.
    pub fn from_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::open(path).map(Reader::new)
    }
}

impl<R: io::Read> Reader<R> {
    /// Create a new GFF reader given an instance of `io::Read`.
    pub fn new(reader: R) -> Self {
        Reader {
            inner: csv::Reader::from_reader(reader).delimiter(b'\t').has_headers(false)
        }
    }

    /// Iterate over all records.
    pub fn records(&mut self) -> Records<R> {
        Records { inner: self.inner.decode() }
    }
}

/// A GFF record.
pub struct Records<'a, R: 'a + io::Read> {
    inner: csv::DecodedRecords<'a, R, (String, String, String, u64, u64, String, String, String, String)>,
}

impl<'a, R: io::Read> Iterator for Records<'a, R> {
    type Item = csv::Result<Record>;

    fn next(&mut self) -> Option<csv::Result<Record>> {
        self.inner.next().map(|res| {
            res.map(|(seqname, source, feature_type, start, end, score, strand, frame, attributes)| {
                Record {
                    seqname: seqname,
                    source: source,
                    feature_type: feature_type,
                    start: start,
                    end: end,
                    score: score,
                    strand: strand,
                    frame: frame,
                    attributes: csv::Reader::from_string(attributes)
                        .delimiter(b'=')
                        .record_terminator(csv::RecordTerminator::Any(b';'))
                        .has_headers(false)
                        .decode().collect::<csv::Result<HashMap<String, String>>>().unwrap(),
                }
            })
        })
    }
}

/// A GFF writer.
pub struct Writer<W: io::Write> {
    inner: csv::Writer<W>,
}

impl Writer<fs::File> {
    /// Write to a given file path.
    pub fn to_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::create(path).map(Writer::new)
    }
}

impl<W: io::Write> Writer<W> {
    /// Write to a given writer.
    pub fn new(writer: W) -> Self {
        Writer { inner: csv::Writer::from_writer(writer).delimiter(b'\t').flexible(true) }
    }

    /// Write a given GFF record.
    pub fn write(&mut self, record: Record) -> csv::Result<()> {
        let attributes;
        if !record.attributes.is_empty() {
            attributes = record.attributes.iter().map(|(a, b)| format!("{}={}", a, b)).collect::<Vec<_>>().join(";");
        } else {
            attributes = "".to_owned();
        }
        self.inner.encode((record.seqname, record.source, record.feature_type, record.start, record.end, record.score, record.strand, record.frame, attributes))
    }
}

/// A GFF record
#[derive(RustcEncodable)]
pub struct Record {
    seqname: String,
    source: String,
    feature_type: String,
    start: u64,
    end: u64,
    score: String,
    strand: String,
    frame: String,
    attributes: HashMap<String, String>,
}

impl Record {
    /// Create a new GFF record.
    pub fn new() -> Self {
        Record {
            seqname: "".to_owned(),
            source: "".to_owned(),
            feature_type: "".to_owned(),
            start: 0,
            end: 0,
            score: ".".to_owned(),
            strand: ".".to_owned(),
            frame: "".to_owned(),
            attributes: HashMap::<String, String>::new(),
        }
    }

    /// Sequence name of the feature.
    pub fn seqname(&self) -> &str {
        &self.seqname
    }

    /// Source of the feature.
    pub fn source(&self) -> &str {
        &self.source
    }

    /// Type of the feature.
    pub fn feature_type(&self) -> &str {
        &self.feature_type
    }

    /// Start position of feature (1-based).
    pub fn start(&self) -> &u64 {
        &self.start
    }

    /// End position of feature (1-based, not included).
    pub fn end(&self) -> &u64 {
        &self.end
    }

    /// Score of feature
    pub fn score(&self) -> Option<u64> {
        match self.score.as_ref() {
            "." => None,
            _ => self.score.parse::<u64>().ok(),
        }
    }

    /// Strand of the feature.
    pub fn strand(&self) -> Option<Strand> {
        match self.strand.as_ref() {
            "+" => Some(Strand::Forward),
            "-" => Some(Strand::Reverse),
            _ => None,
        }
    }

    /// Frame of the feature.
    pub fn frame(&self) -> &str {
        &self.frame
    }

    /// Attribute of feature
    pub fn attributes(&self) -> &HashMap<String, String> {
        &self.attributes
    }

    /// Get mutable reference on seqname of feature.
    pub fn seqname_mut(&mut self) -> &mut String {
        return &mut self.seqname;
    }

    /// Get mutable reference on source of feature.
    pub fn source_mut(&mut self) -> &mut String {
        return &mut self.source;
    }

    /// Get mutable reference on type of feature.
    pub fn feature_type_mut(&mut self) -> &mut String {
        return &mut self.feature_type;
    }

    /// Get mutable reference on start of feature.
    pub fn start_mut(&mut self) -> &mut u64 {
        return &mut self.start;
    }

    /// Get mutable reference on end of feature.
    pub fn end_mut(&mut self) -> &mut u64 {
        return &mut self.end;
    }

    /// Get mutable reference on score of feature.
    pub fn score_mut(&mut self) -> &mut String {
        return &mut self.score;
    }

    /// Get mutable reference on strand of feature.
    pub fn strand_mut(&mut self) -> &mut String {
        return &mut self.strand;
    }

    /// Get mutable reference on attributes of feature.
    pub fn attributes_mut(&mut self) -> &mut HashMap<String, String> {
        return &mut self.attributes;
    }
}

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

    const GFF_FILE: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\tNote=Removed;ID=test
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\tNote=ATP-dependent protease subunit HslV;ID=PRO_0000148105
";
    //required because HashMap iter on element randomly
    const GFF_FILE_NO_ATTRIB: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\t
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\t
";

    #[test]
    fn test_reader() {
        let seqname = ["P0A7B8", "P0A7B8"];
        let source = ["UniProtKB", "UniProtKB"];
        let feature_type = ["Initiator methionine", "Chain"];
        let starts = [1, 2];
        let ends = [1, 176];
        let scores = [None, Some(50)];
        let strand = [None, Some(Strand::Forward)];
        let frame = [".", "."];
        let mut attributes = [HashMap::new(), HashMap::new()];
        attributes[0].insert("ID".to_owned(), "test".to_owned());
        attributes[0].insert("Note".to_owned(), "Removed".to_owned());
        attributes[1].insert("ID".to_owned(), "PRO_0000148105".to_owned());
        attributes[1].insert("Note".to_owned(), "ATP-dependent protease subunit HslV".to_owned());

        let mut reader = Reader::new(GFF_FILE);
        for (i, r) in reader.records().enumerate() {
            let record = r.ok().expect("Error reading record");
            assert_eq!(record.seqname(), seqname[i]);
            assert_eq!(record.source(), source[i]);
            assert_eq!(record.feature_type(), feature_type[i]);
            assert_eq!(*record.start(), starts[i]);
            assert_eq!(*record.end(), ends[i]);
            assert_eq!(record.score(), scores[i]);
            assert_eq!(record.strand(), strand[i]);
            assert_eq!(record.frame(), frame[i]);
            assert_eq!(record.attributes(), &attributes[i]);
        }
    }

    #[test]
    fn test_writer() {
        let mut reader = Reader::new(GFF_FILE_NO_ATTRIB);
        let mut writer = Writer::new(vec![]);
        for r in reader.records() {
            writer.write(r.ok().expect("Error reading record")).ok().expect("Error writing record");
        }
        assert_eq!(writer.inner.as_string(), String::from_utf8_lossy(GFF_FILE_NO_ATTRIB))
    }
}
<commit_msg>Add support of GFF2, GTF2 and Any other attributes field format<commit_after>// Copyright 2016 Pierre Marijon.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! GFF3 format reading and writing.
//!
//! GFF2 definition : http://gmod.org/wiki/GFF2#The_GFF2_File_Format (not yet support)
//! GTF2 definition : http://mblab.wustl.edu/GTF2.html (not yet support)
//! GFF3 definition : http://gmod.org/wiki/GFF3#GFF3_Format
//!
//! # Example
//!
//! ```
//! use std::io;
//! use bio::io::gff;
//! let reader = gff::Reader::new(io::stdin(), gff::GffType::GFF3);
//! ```

use std::str;
use std::io;
use std::fs;
use std::path::Path;
use std::convert::AsRef;
use std::collections::HashMap;

use csv;

use io::Strand;

/// GffType
///
/// We have three format in the GFF family.
/// The change is in the last field of GFF.
/// For each type we have key value separator and field separator
#[derive(Clone, Copy)]
pub enum GffType {
    /// Attribute format is key1=value, key2=value
    GFF3,
    /// Attribute format is key1 value; key2 value
    GFF2,
    /// Same as GFF2 just possible keyword and possible value change
    GTF2,
    /// Any first field of tuple is key value separator, second is field separator
    Any(u8, u8),
}

impl GffType {
    #[inline]
    fn get_separator(&self) -> (u8, u8) {
        match *self {
            GffType::GFF3 => (b'=', b','),
            GffType::GFF2 => (b' ', b';'),
            GffType::GTF2 => (b' ', b';'),
            GffType::Any(x, y) => (x, y),
        }
    }
}

impl PartialEq<(u8, u8)> for GffType {
    #[inline]
    fn eq(&self, &other: &(u8, u8)) -> bool {
        match *self {
            GffType::GFF3 => other.0 == b'=' && other.1 == b',',
            GffType::GFF2 => other.0 == b' ' && other.1 == b';',
            GffType::GTF2 => other.0 == b' ' && other.1 == b';',
            GffType::Any(x, y) => other.0 == x && other.1 == y,
        }
    }
}

/// A GFF reader.
pub struct Reader<R: io::Read> {
    inner: csv::Reader<R>,
    gff_type: GffType,
}

impl Reader<fs::File> {
    /// Read GFF from given file path.
    pub fn from_file<P: AsRef<Path>>(path: P, fileformat: GffType) -> io::Result<Self> {
        fs::File::open(path).map(|f| Reader::new(f, fileformat))
    }
}

impl<R: io::Read> Reader<R> {
    /// Create a new GFF reader given an instance of `io::Read`.
    pub fn new(reader: R, fileformat: GffType) -> Self {
        Reader {
            inner: csv::Reader::from_reader(reader).delimiter(b'\t').has_headers(false),
            gff_type: fileformat,
        }
    }

    /// Iterate over all records.
    pub fn records(&mut self) -> Records<R> {
        Records {
            inner: self.inner.decode(),
            gff_type: self.gff_type
        }
    }
}

/// A GFF record.
pub struct Records<'a, R: 'a + io::Read> {
    inner: csv::DecodedRecords<'a, R, (String, String, String, u64, u64, String, String, String, String)>,
    gff_type: GffType,
}

impl<'a, R: io::Read> Iterator for Records<'a, R> {
    type Item = csv::Result<Record>;

    fn next(&mut self) -> Option<csv::Result<Record>> {
        let (delim, termi) = self.gff_type.get_separator();

        self.inner.next().map(|res| {
            res.map(|(seqname, source, feature_type, start, end, score, strand, frame, attributes)| {
                Record {
                    seqname: seqname,
                    source: source,
                    feature_type: feature_type,
                    start: start,
                    end: end,
                    score: score,
                    strand: strand,
                    frame: frame,
                    attributes: csv::Reader::from_string(attributes)
                        .delimiter(delim)
                        .record_terminator(csv::RecordTerminator::Any(termi))
                        .has_headers(false)
                        .decode()
                        .collect::<csv::Result<HashMap<String, String>>>()
                        .unwrap(),
                }
            })
        })
    }
}

/// A GFF writer.
pub struct Writer<W: io::Write> {
    inner: csv::Writer<W>,
    gff_type: GffType,
}

impl Writer<fs::File> {
    /// Write to a given file path.
    pub fn to_file<P: AsRef<Path>>(path: P, fileformat: GffType) -> io::Result<Self> {
        fs::File::open(path).map(|f| Writer::new(f, fileformat))
    }
}

impl<W: io::Write> Writer<W> {
    /// Write to a given writer.
    pub fn new(writer: W, fileformat: GffType) -> Self {
        Writer {
            inner: csv::Writer::from_writer(writer).delimiter(b'\t').flexible(true),
            gff_type: fileformat,
        }
    }

    /// Write a given GFF record.
    pub fn write(&mut self, record: Record) -> csv::Result<()> {
        let (delim, termi) = self.gff_type.get_separator();

        // If you can remove this ugly code please do it
        let termi = [termi];
        let termi = str::from_utf8(&termi).unwrap_or(";");

        let attributes;

        if !record.attributes.is_empty() {
            attributes = record.attributes.iter().map(|(a, b)| format!("{}{}{}", a, delim as char, b)).collect::<Vec<_>>().join(&termi);
        } else {
            attributes = "".to_owned();
        }
        self.inner.encode((record.seqname, record.source, record.feature_type, record.start, record.end, record.score, record.strand, record.frame, attributes))
    }
}

/// A GFF record
#[derive(RustcEncodable)]
pub struct Record {
    seqname: String,
    source: String,
    feature_type: String,
    start: u64,
    end: u64,
    score: String,
    strand: String,
    frame: String,
    attributes: HashMap<String, String>,
}

impl Record {
    /// Create a new GFF record.
    pub fn new() -> Self {
        Record {
            seqname: "".to_owned(),
            source: "".to_owned(),
            feature_type: "".to_owned(),
            start: 0,
            end: 0,
            score: ".".to_owned(),
            strand: ".".to_owned(),
            frame: "".to_owned(),
            attributes: HashMap::<String, String>::new(),
        }
    }

    /// Sequence name of the feature.
    pub fn seqname(&self) -> &str {
        &self.seqname
    }

    /// Source of the feature.
    pub fn source(&self) -> &str {
        &self.source
    }

    /// Type of the feature.
    pub fn feature_type(&self) -> &str {
        &self.feature_type
    }

    /// Start position of feature (1-based).
    pub fn start(&self) -> &u64 {
        &self.start
    }

    /// End position of feature (1-based, not included).
    pub fn end(&self) -> &u64 {
        &self.end
    }

    /// Score of feature
    pub fn score(&self) -> Option<u64> {
        match self.score.as_ref() {
            "." => None,
            _ => self.score.parse::<u64>().ok(),
        }
    }

    /// Strand of the feature.
    pub fn strand(&self) -> Option<Strand> {
        match self.strand.as_ref() {
            "+" => Some(Strand::Forward),
            "-" => Some(Strand::Reverse),
            _ => None,
        }
    }

    /// Frame of the feature.
    pub fn frame(&self) -> &str {
        &self.frame
    }

    /// Attribute of feature
    pub fn attributes(&self) -> &HashMap<String, String> {
        &self.attributes
    }

    /// Get mutable reference on seqname of feature.
    pub fn seqname_mut(&mut self) -> &mut String {
        return &mut self.seqname;
    }

    /// Get mutable reference on source of feature.
    pub fn source_mut(&mut self) -> &mut String {
        return &mut self.source;
    }

    /// Get mutable reference on type of feature.
    pub fn feature_type_mut(&mut self) -> &mut String {
        return &mut self.feature_type;
    }

    /// Get mutable reference on start of feature.
    pub fn start_mut(&mut self) -> &mut u64 {
        return &mut self.start;
    }

    /// Get mutable reference on end of feature.
    pub fn end_mut(&mut self) -> &mut u64 {
        return &mut self.end;
    }

    /// Get mutable reference on score of feature.
    pub fn score_mut(&mut self) -> &mut String {
        return &mut self.score;
    }

    /// Get mutable reference on strand of feature.
    pub fn strand_mut(&mut self) -> &mut String {
        return &mut self.strand;
    }

    /// Get mutable reference on attributes of feature.
    pub fn attributes_mut(&mut self) -> &mut HashMap<String, String> {
        return &mut self.attributes;
    }
}

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

    const GFF_FILE: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\tNote=Removed,ID=test
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\tNote=ATP-dependent protease subunit HslV,ID=PRO_0000148105
";
    //required because HashMap iter on element randomly
    const GFF_FILE_ONE_ATTRIB: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\tNote=Removed
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\tID=PRO_0000148105
";

    const GTF_FILE: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\tNote Removed;ID test
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\tNote ATP-dependent;ID PRO_0000148105
";

    //required because HashMap iter on element randomly
    const GTF_FILE_ONE_ATTRIB: &'static [u8] = b"P0A7B8\tUniProtKB\tInitiator methionine\t1\t1\t.\t.\t.\tNote Removed
P0A7B8\tUniProtKB\tChain\t2\t176\t50\t+\t.\tID PRO_0000148105
";

    #[test]
    fn test_reader_gff3() {
        let seqname = ["P0A7B8", "P0A7B8"];
        let source = ["UniProtKB", "UniProtKB"];
        let feature_type = ["Initiator methionine", "Chain"];
        let starts = [1, 2];
        let ends = [1, 176];
        let scores = [None, Some(50)];
        let strand = [None, Some(Strand::Forward)];
        let frame = [".", "."];
        let mut attributes = [HashMap::new(), HashMap::new()];
        attributes[0].insert("ID".to_owned(), "test".to_owned());
        attributes[0].insert("Note".to_owned(), "Removed".to_owned());
        attributes[1].insert("ID".to_owned(), "PRO_0000148105".to_owned());
        attributes[1].insert("Note".to_owned(), "ATP-dependent protease subunit HslV".to_owned());

        let mut reader = Reader::new(GFF_FILE, GffType::GFF3);
        for (i, r) in reader.records().enumerate() {
            let record = r.ok().expect("Error reading record");
            assert_eq!(record.seqname(), seqname[i]);
            assert_eq!(record.source(), source[i]);
            assert_eq!(record.feature_type(), feature_type[i]);
            assert_eq!(*record.start(), starts[i]);
            assert_eq!(*record.end(), ends[i]);
            assert_eq!(record.score(), scores[i]);
            assert_eq!(record.strand(), strand[i]);
            assert_eq!(record.frame(), frame[i]);
            assert_eq!(record.attributes(), &attributes[i]);
        }
    }

    #[test]
    fn test_reader_gtf2() {
        let seqname = ["P0A7B8", "P0A7B8"];
        let source = ["UniProtKB", "UniProtKB"];
        let feature_type = ["Initiator methionine", "Chain"];
        let starts = [1, 2];
        let ends = [1, 176];
        let scores = [None, Some(50)];
        let strand = [None, Some(Strand::Forward)];
        let frame = [".", "."];
        let mut attributes = [HashMap::new(), HashMap::new()];
        attributes[0].insert("ID".to_owned(), "test".to_owned());
        attributes[0].insert("Note".to_owned(), "Removed".to_owned());
        attributes[1].insert("ID".to_owned(), "PRO_0000148105".to_owned());
        attributes[1].insert("Note".to_owned(), "ATP-dependent".to_owned());

        let mut reader = Reader::new(GTF_FILE, GffType::GTF2);
        for (i, r) in reader.records().enumerate() {
            let record = r.ok().expect("Error reading record");
            assert_eq!(record.seqname(), seqname[i]);
            assert_eq!(record.source(), source[i]);
            assert_eq!(record.feature_type(), feature_type[i]);
            assert_eq!(*record.start(), starts[i]);
            assert_eq!(*record.end(), ends[i]);
            assert_eq!(record.score(), scores[i]);
            assert_eq!(record.strand(), strand[i]);
            assert_eq!(record.frame(), frame[i]);
            assert_eq!(record.attributes(), &attributes[i]);
        }
    }

    #[test]
    fn test_writer_gff3() {
        let mut reader = Reader::new(GFF_FILE_ONE_ATTRIB, GffType::GFF3);
        let mut writer = Writer::new(vec![], GffType::GFF3);
        for r in reader.records() {
            writer.write(r.ok().expect("Error reading record")).ok().expect("Error writing record");
        }
        assert_eq!(writer.inner.as_string(), String::from_utf8_lossy(GFF_FILE_ONE_ATTRIB))
    }

    #[test]
    fn test_writer_gtf2() {
        let mut reader = Reader::new(GTF_FILE_ONE_ATTRIB, GffType::GTF2);
        let mut writer = Writer::new(vec![], GffType::GTF2);
        for r in reader.records() {
            writer.write(r.ok().expect("Error reading record")).ok().expect("Error writing record");
        }
        assert_eq!(writer.inner.as_string(), String::from_utf8_lossy(GTF_FILE_ONE_ATTRIB))
    }

    #[test]
    fn test_convert_gtf2_to_gff3() {
        let mut reader = Reader::new(GTF_FILE_ONE_ATTRIB, GffType::GTF2);
        let mut writer = Writer::new(vec![], GffType::GFF3);
        for r in reader.records() {
            writer.write(r.ok().expect("Error reading record")).ok().expect("Error writing record");
        }
        assert_eq!(writer.inner.as_string(), String::from_utf8_lossy(GFF_FILE_ONE_ATTRIB))
    }
}
<|endoftext|>