<commit_before>// Copyright 2013 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.
//
// btree.rs
//
// starting implementation of a btree for rust
// inspired by github user davidhalperin's gist

use std::util::replace;

///A B-tree contains a root node (which contains a vector of elements),
///a length (the height of the tree), and lower and upper bounds on the
///number of elements that a given node can contain.
#[allow(missing_doc)]
pub struct BTree<K, V>{
    root: Node<K, V>,
    len: uint,
    lower_bound: uint,
    upper_bound: uint
}

//We would probably want to remove the dependence on the Clone trait in the future.
//It is here as a crutch to ensure values can be passed around through the tree's nodes
//especially during insertions and deletions.
//Using the swap or replace methods is one option for replacing dependence on Clone, or
//changing the way in which the BTree is stored could also potentially work.
impl<K: Clone + TotalOrd, V: Clone> BTree<K, V>{

    ///Returns new BTree with root node (leaf) and user-supplied lower bound
    fn new(k: K, v: V, lb: uint) -> BTree<K, V>{
        BTree{
            root: Node::new_leaf(~[LeafElt::new(k, v)]),
            len: 1,
            lower_bound: lb,
            upper_bound: 2 * lb
        }
    }

    ///Helper function for clone: returns new BTree with supplied root node,
    ///length, and lower bound.  For use when the length is known already.
    fn new_with_node_len(n: Node<K, V>, length: uint, lb: uint) -> BTree<K, V>{
        BTree{
            root: n,
            len: length,
            lower_bound: lb,
            upper_bound: 2 * lb
        }
    }

    ///Implements the Clone trait for the BTree.
    ///Uses a helper function/constructor to produce a new BTree.
    fn clone(&self) -> BTree<K, V>{
        return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound);
    }

    ///Returns the value of a given key, which may not exist in the tree.
    ///Calls the root node's get method.
    fn get(self, k: K) -> Option<V>{
        return self.root.get(k);
    }

    ///Checks to see if the key already exists in the tree, and if it is not,
    ///the key-value pair is added to the tree by calling add on the root node.
    fn add(self, k: K, v: V) -> bool{
        let is_get = &self.clone().get(k.clone());
        if is_get.is_some(){ return false; }
        else{
            replace(&mut self.root.clone(),self.root.add(k.clone(), v));
            return true;
        }

    }

}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for BTree<K, V>{
    ///Returns a string representation of the BTree
    fn to_str(&self) -> ~str{
        let ret = self.root.to_str();
        ret
    }
}

//Node types
//A node is either a LeafNode or a BranchNode, which contain either a Leaf or a Branch.
//Branches contain BranchElts, which contain a left child (another node) and a key-value
//pair.  Branches also contain the rightmost child of the elements in the array.
//Leaves contain LeafElts, which do not have children.
enum Node<K, V>{
    LeafNode(Leaf<K, V>),
    BranchNode(Branch<K, V>)
}

//Node functions/methods
impl<K: Clone + TotalOrd, V: Clone> Node<K, V>{

    ///Differentiates between leaf and branch nodes.
    fn is_leaf(&self) -> bool{
        match self{
            &LeafNode(*) => true,
            &BranchNode(*) => false
        }
    }

    ///Creates a new leaf node given a vector of elements.
    fn new_leaf(vec: ~[LeafElt<K, V>]) -> Node<K,V>{
        LeafNode(Leaf::new(vec))
    }

    ///Creates a new branch node given a vector of an elements and a pointer to a rightmost child.
    fn new_branch(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Node<K, V>{
        BranchNode(Branch::new(vec, right))
    }

    ///Returns the corresponding value to the provided key.
    ///get() is called in different ways on a branch or a leaf.
    fn get(&self, k: K) -> Option<V>{
        match *self{
            LeafNode(ref leaf) => return leaf.get(k),
            BranchNode(ref branch) => return branch.get(k)
        }
    }

    ///A placeholder for add
    ///Currently returns a leaf node with a single value (the added one)
    fn add(self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }
}

//Again, this might not be necessary in the future.
impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V>{

    ///Returns a new node based on whether or not it is a branch or a leaf.
    fn clone(&self) -> Node<K, V>{
        match *self{
            LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()),
            BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(),
                                                              branch.rightmost_child.clone())
        }
    }
}

//The following impl is unfinished.  Old iterations of code are left in for
//future reference when implementing this trait (commented-out).
impl<K: Clone + TotalOrd, V: Clone> TotalOrd for Node<K, V>{

    ///Placeholder for an implementation of TotalOrd for Nodes.
    #[allow(unused_variable)]
    fn cmp(&self, other: &Node<K, V>) -> Ordering{
        //Requires a match statement--defer these procs to branch and leaf.
        /* if self.elts[0].less_than(other.elts[0]) { return Less}
        if self.elts[0].greater_than(other.elts[0]) {return Greater}
            else {return Equal}
         */
        return Equal;
    }
}

//The following impl is unfinished.  Old iterations of code are left in for
//future reference when implementing this trait (commented-out).
impl<K: Clone + TotalOrd, V: Clone> TotalEq for Node<K, V>{

    ///Placeholder for an implementation of TotalEq for Nodes.
    #[allow(unused_variable)]
    fn equals(&self, other: &Node<K, V>) -> bool{
        /* put in a match and defer this stuff to branch and leaf

        let mut shorter = 0;
        if self.elts.len() <= other.elts.len(){
        shorter = self.elts.len();
    }
            else{
        shorter = other.elts.len();
    }
        let mut i = 0;
        while i < shorter{
        if !self.elts[i].has_key(other.elts[i].key){
        return false;
    }
        i +=1;
    }
        return true;
         */
        return true;
    }
}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Node<K, V>{
    ///Returns a string representation of a Node.
    ///The Branch's to_str() is not implemented yet.
    fn to_str(&self) -> ~str{
        match *self{
            LeafNode(ref leaf) => leaf.to_str(),
            BranchNode(*) => ~""
        }
    }
}

//A leaf is a vector with elements that contain no children.  A leaf also
//does not contain a rightmost child.
struct Leaf<K, V>{
    elts: ~[LeafElt<K, V>]
}

//Vector of values with children, plus a rightmost child (greater than all)
struct Branch<K, V>{
    elts: ~[BranchElt<K,V>],
    rightmost_child: ~Node<K, V>
}

impl<K: Clone + TotalOrd, V: Clone> Leaf<K, V>{

    ///Creates a new Leaf from a vector of LeafElts.
    fn new(vec: ~[LeafElt<K, V>]) -> Leaf<K, V>{
        Leaf{
            elts: vec
        }
    }

    ///Returns the corresponding value to the supplied key.
    fn get(&self, k: K) -> Option<V>{
        for s in self.elts.iter(){
            let order = s.key.cmp(&k);
            match order{
                Equal => return Some(s.value.clone()),
                _ => {}
            }
        }
        return None;
    }

    ///Placeholder for add method in progress.
    ///Currently returns a new Leaf containing a single LeafElt.
    fn add(&self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }

}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Leaf<K, V>{

    ///Returns a string representation of a Leaf.
    fn to_str(&self) -> ~str{
        let mut ret = ~"";
        for s in self.elts.iter(){
            ret = ret + " // " + s.to_str();
        }
        ret
    }

}

impl<K: Clone + TotalOrd, V: Clone> Branch<K, V>{

    ///Creates a new Branch from a vector of BranchElts and a rightmost child (a node).
    fn new(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Branch<K, V>{
        Branch{
            elts: vec,
            rightmost_child: right
        }
    }

    ///Returns the corresponding value to the supplied key.
    ///If the key is not there, find the child that might hold it.
    fn get(&self, k: K) -> Option<V>{
        for s in self.elts.iter(){
            let order = s.key.cmp(&k);
            match order{
                Less => return s.left.get(k),
                Equal => return Some(s.value.clone()),
                _ => {}
            }
        }
        return self.rightmost_child.get(k);
    }

    ///Placeholder for add method in progress
    fn add(&self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }
}

//A LeafElt containts no left child, but a key-value pair.
struct LeafElt<K, V>{
    key: K,
    value: V
}

//A BranchElt has a left child in addition to a key-value pair.
struct BranchElt<K, V>{
    left: Node<K, V>,
    key: K,
    value: V
}

impl<K: Clone + TotalOrd, V> LeafElt<K, V>{

    ///Creates a new LeafElt from a supplied key-value pair.
    fn new(k: K, v: V) -> LeafElt<K, V>{
        LeafElt{
            key: k,
            value: v
        }
    }

    ///Compares another LeafElt against itself and determines whether
    ///the original LeafElt's key is less than the other one's key.
    fn less_than(&self, other: LeafElt<K, V>) -> bool{
        let order = self.key.cmp(&other.key);
        match order{
            Less => true,
            _ => false
        }
    }

    ///Compares another LeafElt against itself and determines whether
    ///the original LeafElt's key is greater than the other one's key.
    fn greater_than(&self, other: LeafElt<K, V>) -> bool{
        let order = self.key.cmp(&other.key);
        match order{
            Greater => true,
            _ => false
        }
    }

    ///Takes a key and determines whether its own key and the supplied key
    ///are the same.
    fn has_key(&self, other: K) -> bool{
        let order = self.key.cmp(&other);
        match order{
            Equal => true,
            _ => false
        }
    }

}

//This may be eliminated in the future to perserve efficiency by adjusting the way
//the BTree as a whole is stored in memory.
impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V>{

    ///Returns a new LeafElt by cloning the key and value.
    fn clone(&self) -> LeafElt<K, V>{
        return LeafElt::new(self.key.clone(), self.value.clone());
    }
}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for LeafElt<K, V>{

    ///Returns a string representation of a LeafElt.
    fn to_str(&self) -> ~str{
        return "Key: " + self.key.to_str() + ", value: "+ self.value.to_str() + "; ";
    }

}

impl<K: Clone + TotalOrd, V: Clone> BranchElt<K, V>{

    ///Creates a new BranchElt from a supplied key, value, and left child.
    fn new(k: K, v: V, n: Node<K, V>) -> BranchElt<K, V>{
        BranchElt{
            left: n,
            key: k,
            value: v
        }
    }

    ///Placeholder for add method in progress.
    ///Overall implementation will determine the actual return value of this method.
    fn add(&self, k: K, v: V) -> LeafElt<K, V>{
        return LeafElt::new(k, v);
    }
}

impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V>{

    ///Returns a new BranchElt by cloning the key, value, and left child.
    fn clone(&self) -> BranchElt<K, V>{
        return BranchElt::new(self.key.clone(), self.value.clone(), self.left.clone());
    }
}

#[cfg(test)]
mod test_btree{

    use super::*;

    ///Tests the functionality of the add methods (which are unfinished).
    #[test]
    fn add_test(){
        let b = BTree::new(1, ~"abc", 2);
        let is_add = b.add(2, ~"xyz");
        assert!(is_add);
    }

    ///Tests the functionality of the get method.
    #[test]
    fn get_test(){
        let b = BTree::new(1, ~"abc", 2);
        let val = b.get(1);
        assert_eq!(val, Some(~"abc"));
    }

    ///Tests the LeafElt's less_than() method.
    #[test]
    fn leaf_lt(){
        let l1 = LeafElt::new(1, ~"abc");
        let l2 = LeafElt::new(2, ~"xyz");
        assert!(l1.less_than(l2));
    }

    ///Tests the LeafElt's greater_than() method.
    #[test]
    fn leaf_gt(){
        let l1 = LeafElt::new(1, ~"abc");
        let l2 = LeafElt::new(2, ~"xyz");
        assert!(l2.greater_than(l1));
    }

    ///Tests the LeafElt's has_key() method.
    #[test]
    fn leaf_hk(){
        let l1 = LeafElt::new(1, ~"abc");
        assert!(l1.has_key(1));
    }
}

<commit_msg>Added proper //! documentation to the beginning of btree.rs.<commit_after>// Copyright 2013 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.
//
// btree.rs
//

//! Starting implementation of a btree for rust.
//! Structure inspired by github user davidhalperin's gist.

use std::util::replace;

///A B-tree contains a root node (which contains a vector of elements),
///a length (the height of the tree), and lower and upper bounds on the
///number of elements that a given node can contain.
#[allow(missing_doc)]
pub struct BTree<K, V>{
    root: Node<K, V>,
    len: uint,
    lower_bound: uint,
    upper_bound: uint
}

//We would probably want to remove the dependence on the Clone trait in the future.
//It is here as a crutch to ensure values can be passed around through the tree's nodes
//especially during insertions and deletions.
//Using the swap or replace methods is one option for replacing dependence on Clone, or
//changing the way in which the BTree is stored could also potentially work.
impl<K: Clone + TotalOrd, V: Clone> BTree<K, V>{

    ///Returns new BTree with root node (leaf) and user-supplied lower bound
    fn new(k: K, v: V, lb: uint) -> BTree<K, V>{
        BTree{
            root: Node::new_leaf(~[LeafElt::new(k, v)]),
            len: 1,
            lower_bound: lb,
            upper_bound: 2 * lb
        }
    }

    ///Helper function for clone: returns new BTree with supplied root node,
    ///length, and lower bound.  For use when the length is known already.
    fn new_with_node_len(n: Node<K, V>, length: uint, lb: uint) -> BTree<K, V>{
        BTree{
            root: n,
            len: length,
            lower_bound: lb,
            upper_bound: 2 * lb
        }
    }

    ///Implements the Clone trait for the BTree.
    ///Uses a helper function/constructor to produce a new BTree.
    fn clone(&self) -> BTree<K, V>{
        return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound);
    }

    ///Returns the value of a given key, which may not exist in the tree.
    ///Calls the root node's get method.
    fn get(self, k: K) -> Option<V>{
        return self.root.get(k);
    }

    ///Checks to see if the key already exists in the tree, and if it is not,
    ///the key-value pair is added to the tree by calling add on the root node.
    fn add(self, k: K, v: V) -> bool{
        let is_get = &self.clone().get(k.clone());
        if is_get.is_some(){ return false; }
        else{
            replace(&mut self.root.clone(),self.root.add(k.clone(), v));
            return true;
        }

    }

}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for BTree<K, V>{
    ///Returns a string representation of the BTree
    fn to_str(&self) -> ~str{
        let ret = self.root.to_str();
        ret
    }
}

//Node types
//A node is either a LeafNode or a BranchNode, which contain either a Leaf or a Branch.
//Branches contain BranchElts, which contain a left child (another node) and a key-value
//pair.  Branches also contain the rightmost child of the elements in the array.
//Leaves contain LeafElts, which do not have children.
enum Node<K, V>{
    LeafNode(Leaf<K, V>),
    BranchNode(Branch<K, V>)
}

//Node functions/methods
impl<K: Clone + TotalOrd, V: Clone> Node<K, V>{

    ///Differentiates between leaf and branch nodes.
    fn is_leaf(&self) -> bool{
        match self{
            &LeafNode(*) => true,
            &BranchNode(*) => false
        }
    }

    ///Creates a new leaf node given a vector of elements.
    fn new_leaf(vec: ~[LeafElt<K, V>]) -> Node<K,V>{
        LeafNode(Leaf::new(vec))
    }

    ///Creates a new branch node given a vector of an elements and a pointer to a rightmost child.
    fn new_branch(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Node<K, V>{
        BranchNode(Branch::new(vec, right))
    }

    ///Returns the corresponding value to the provided key.
    ///get() is called in different ways on a branch or a leaf.
    fn get(&self, k: K) -> Option<V>{
        match *self{
            LeafNode(ref leaf) => return leaf.get(k),
            BranchNode(ref branch) => return branch.get(k)
        }
    }

    ///A placeholder for add
    ///Currently returns a leaf node with a single value (the added one)
    fn add(self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }
}

//Again, this might not be necessary in the future.
impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V>{

    ///Returns a new node based on whether or not it is a branch or a leaf.
    fn clone(&self) -> Node<K, V>{
        match *self{
            LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()),
            BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(),
                                                              branch.rightmost_child.clone())
        }
    }
}

//The following impl is unfinished.  Old iterations of code are left in for
//future reference when implementing this trait (commented-out).
impl<K: Clone + TotalOrd, V: Clone> TotalOrd for Node<K, V>{

    ///Placeholder for an implementation of TotalOrd for Nodes.
    #[allow(unused_variable)]
    fn cmp(&self, other: &Node<K, V>) -> Ordering{
        //Requires a match statement--defer these procs to branch and leaf.
        /* if self.elts[0].less_than(other.elts[0]) { return Less}
        if self.elts[0].greater_than(other.elts[0]) {return Greater}
            else {return Equal}
         */
        return Equal;
    }
}

//The following impl is unfinished.  Old iterations of code are left in for
//future reference when implementing this trait (commented-out).
impl<K: Clone + TotalOrd, V: Clone> TotalEq for Node<K, V>{

    ///Placeholder for an implementation of TotalEq for Nodes.
    #[allow(unused_variable)]
    fn equals(&self, other: &Node<K, V>) -> bool{
        /* put in a match and defer this stuff to branch and leaf

        let mut shorter = 0;
        if self.elts.len() <= other.elts.len(){
        shorter = self.elts.len();
    }
            else{
        shorter = other.elts.len();
    }
        let mut i = 0;
        while i < shorter{
        if !self.elts[i].has_key(other.elts[i].key){
        return false;
    }
        i +=1;
    }
        return true;
         */
        return true;
    }
}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Node<K, V>{
    ///Returns a string representation of a Node.
    ///The Branch's to_str() is not implemented yet.
    fn to_str(&self) -> ~str{
        match *self{
            LeafNode(ref leaf) => leaf.to_str(),
            BranchNode(*) => ~""
        }
    }
}

//A leaf is a vector with elements that contain no children.  A leaf also
//does not contain a rightmost child.
struct Leaf<K, V>{
    elts: ~[LeafElt<K, V>]
}

//Vector of values with children, plus a rightmost child (greater than all)
struct Branch<K, V>{
    elts: ~[BranchElt<K,V>],
    rightmost_child: ~Node<K, V>
}

impl<K: Clone + TotalOrd, V: Clone> Leaf<K, V>{

    ///Creates a new Leaf from a vector of LeafElts.
    fn new(vec: ~[LeafElt<K, V>]) -> Leaf<K, V>{
        Leaf{
            elts: vec
        }
    }

    ///Returns the corresponding value to the supplied key.
    fn get(&self, k: K) -> Option<V>{
        for s in self.elts.iter(){
            let order = s.key.cmp(&k);
            match order{
                Equal => return Some(s.value.clone()),
                _ => {}
            }
        }
        return None;
    }

    ///Placeholder for add method in progress.
    ///Currently returns a new Leaf containing a single LeafElt.
    fn add(&self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }

}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Leaf<K, V>{

    ///Returns a string representation of a Leaf.
    fn to_str(&self) -> ~str{
        let mut ret = ~"";
        for s in self.elts.iter(){
            ret = ret + " // " + s.to_str();
        }
        ret
    }

}

impl<K: Clone + TotalOrd, V: Clone> Branch<K, V>{

    ///Creates a new Branch from a vector of BranchElts and a rightmost child (a node).
    fn new(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Branch<K, V>{
        Branch{
            elts: vec,
            rightmost_child: right
        }
    }

    ///Returns the corresponding value to the supplied key.
    ///If the key is not there, find the child that might hold it.
    fn get(&self, k: K) -> Option<V>{
        for s in self.elts.iter(){
            let order = s.key.cmp(&k);
            match order{
                Less => return s.left.get(k),
                Equal => return Some(s.value.clone()),
                _ => {}
            }
        }
        return self.rightmost_child.get(k);
    }

    ///Placeholder for add method in progress
    fn add(&self, k: K, v: V) -> Node<K, V>{
        return Node::new_leaf(~[LeafElt::new(k, v)]);
    }
}

//A LeafElt containts no left child, but a key-value pair.
struct LeafElt<K, V>{
    key: K,
    value: V
}

//A BranchElt has a left child in addition to a key-value pair.
struct BranchElt<K, V>{
    left: Node<K, V>,
    key: K,
    value: V
}

impl<K: Clone + TotalOrd, V> LeafElt<K, V>{

    ///Creates a new LeafElt from a supplied key-value pair.
    fn new(k: K, v: V) -> LeafElt<K, V>{
        LeafElt{
            key: k,
            value: v
        }
    }

    ///Compares another LeafElt against itself and determines whether
    ///the original LeafElt's key is less than the other one's key.
    fn less_than(&self, other: LeafElt<K, V>) -> bool{
        let order = self.key.cmp(&other.key);
        match order{
            Less => true,
            _ => false
        }
    }

    ///Compares another LeafElt against itself and determines whether
    ///the original LeafElt's key is greater than the other one's key.
    fn greater_than(&self, other: LeafElt<K, V>) -> bool{
        let order = self.key.cmp(&other.key);
        match order{
            Greater => true,
            _ => false
        }
    }

    ///Takes a key and determines whether its own key and the supplied key
    ///are the same.
    fn has_key(&self, other: K) -> bool{
        let order = self.key.cmp(&other);
        match order{
            Equal => true,
            _ => false
        }
    }

}

//This may be eliminated in the future to perserve efficiency by adjusting the way
//the BTree as a whole is stored in memory.
impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V>{

    ///Returns a new LeafElt by cloning the key and value.
    fn clone(&self) -> LeafElt<K, V>{
        return LeafElt::new(self.key.clone(), self.value.clone());
    }
}

impl<K: ToStr + TotalOrd, V: ToStr> ToStr for LeafElt<K, V>{

    ///Returns a string representation of a LeafElt.
    fn to_str(&self) -> ~str{
        return "Key: " + self.key.to_str() + ", value: "+ self.value.to_str() + "; ";
    }

}

impl<K: Clone + TotalOrd, V: Clone> BranchElt<K, V>{

    ///Creates a new BranchElt from a supplied key, value, and left child.
    fn new(k: K, v: V, n: Node<K, V>) -> BranchElt<K, V>{
        BranchElt{
            left: n,
            key: k,
            value: v
        }
    }

    ///Placeholder for add method in progress.
    ///Overall implementation will determine the actual return value of this method.
    fn add(&self, k: K, v: V) -> LeafElt<K, V>{
        return LeafElt::new(k, v);
    }
}

impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V>{

    ///Returns a new BranchElt by cloning the key, value, and left child.
    fn clone(&self) -> BranchElt<K, V>{
        return BranchElt::new(self.key.clone(), self.value.clone(), self.left.clone());
    }
}

#[cfg(test)]
mod test_btree{

    use super::*;

    ///Tests the functionality of the add methods (which are unfinished).
    #[test]
    fn add_test(){
        let b = BTree::new(1, ~"abc", 2);
        let is_add = b.add(2, ~"xyz");
        assert!(is_add);
    }

    ///Tests the functionality of the get method.
    #[test]
    fn get_test(){
        let b = BTree::new(1, ~"abc", 2);
        let val = b.get(1);
        assert_eq!(val, Some(~"abc"));
    }

    ///Tests the LeafElt's less_than() method.
    #[test]
    fn leaf_lt(){
        let l1 = LeafElt::new(1, ~"abc");
        let l2 = LeafElt::new(2, ~"xyz");
        assert!(l1.less_than(l2));
    }

    ///Tests the LeafElt's greater_than() method.
    #[test]
    fn leaf_gt(){
        let l1 = LeafElt::new(1, ~"abc");
        let l2 = LeafElt::new(2, ~"xyz");
        assert!(l2.greater_than(l1));
    }

    ///Tests the LeafElt's has_key() method.
    #[test]
    fn leaf_hk(){
        let l1 = LeafElt::new(1, ~"abc");
        assert!(l1.has_key(1));
    }
}

<|endoftext|>


<commit_before>use bindings::{
    jit_type_void_ptr,
    jit_type_ubyte,
    jit_type_sbyte,
    jit_type_ushort,
    jit_type_short,
    jit_type_uint,
    jit_type_int,
    jit_type_nuint,
    jit_type_nint,
    jit_type_float32,
    jit_type_float64,
    jit_type_long,
    jit_type_ulong,
    jit_type_sys_bool,
    jit_type_sys_char,

    jit_value_create_long_constant,
    jit_value_create_nint_constant,
    jit_value_create_float64_constant,
    jit_value_create_float32_constant
};
use function::{
    CDECL,
    Function
};
use get_type = types::get;
use libc::c_long;
use value::Value;
use std::c_str::CString;
use std::mem::transmute;
use types::Type;
use util::NativeRef;
/// A type that can be compiled into a LibJIT representation
pub trait Compile {
    /// Get a JIT representation of this value
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a>;
    /// Get the JIT type repr of the value
    fn jit_type(_:Option<Self>) -> Type;
}
impl Compile for () {
    fn compile(&self, func:&Function) -> Value {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit_type_void_ptr,
                0
            ))
        }
    }
    #[inline]
    fn jit_type(_:Option<()>) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_void_ptr)
        }
    }
}
compile_prim!(f64, jit_type_float64, jit_value_create_float64_constant)
compile_prim!(f32, jit_type_float32, jit_value_create_float32_constant)
compile_prim!(int, jit_type_nint, jit_value_create_nint_constant, c_long)
compile_prim!(uint,jit_type_nuint, jit_value_create_nint_constant, c_long)
compile_prim!(i64, jit_type_long, jit_value_create_long_constant, c_long)
compile_prim!(u64, jit_type_ulong, jit_value_create_long_constant, c_long)
compile_prim!(i32, jit_type_int, jit_value_create_nint_constant, c_long)
compile_prim!(u32, jit_type_uint, jit_value_create_nint_constant, c_long)
compile_prim!(i16, jit_type_short, jit_value_create_nint_constant, c_long)
compile_prim!(u16, jit_type_ushort, jit_value_create_nint_constant, c_long)
compile_prim!(i8, jit_type_sbyte, jit_value_create_nint_constant, c_long)
compile_prim!(u8, jit_type_ubyte, jit_value_create_nint_constant, c_long)
compile_prim!(bool, jit_type_sys_bool, jit_value_create_nint_constant, c_long)
compile_prim!(char, jit_type_sys_char, jit_value_create_nint_constant, c_long)
impl Compile for *const u8 {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let c_str = unsafe { CString::new(transmute(*self), false) };
        let ty = jit!(&u8);
        let ptr = Value::new(func, ty);
        let length = c_str.len() + 1u;
        func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&length)));
        for enum_char in c_str.iter().enumerate() {
            let (pos, ch) = enum_char;
            let char_v = ch.compile(func);
            func.insn_store_relative(&ptr, pos as int, &char_v);
        }
        func.insn_store_relative(&ptr, c_str.len() as int, &func.insn_of(&'\0'));
        ptr
    }
    #[inline(always)]
    fn jit_type(_:Option<*const u8>) -> Type {
        ::get::<&u8>()
    }
}
impl<T:Compile> Compile for *mut T {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit!(&T).as_ptr(),
                self.to_uint() as c_long
            ))
        }
    }
    #[inline(always)]
    fn jit_type(_:Option<*mut T>) -> Type {
        jit!(&T)
    }
}
impl<'s> Compile for CString {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ty = jit!(CString);
        let val = Value::new(func, ty.clone());
        let string:*const u8 = unsafe { transmute(self.as_ptr()) };
        func.insn_store_relative(&val, 0, &string.compile(func));
        func.insn_store_relative(&val, ty.find_name("is_owned").get_offset() as int, &true.compile(func));
        val
    }
    #[inline]
    fn jit_type(_:Option<CString>) -> Type {
        jit!(struct {
            "ptr": *const u8,
            "is_owned": bool
        })
    }
}
impl<'a> Compile for &'a str {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let str_ptr = {
            let ty = ::get::<*const u8>();
            let ptr = Value::new(func, ty);
            func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&self.len())));
            for enum_char in self.bytes().enumerate() {
                let (pos, ch) = enum_char;
                let char_v = ch.compile(func);
                func.insn_store_relative(&ptr, pos as int, &char_v);
            }
            ptr
        };
        let ty = ::get::<&'a str>();
        let val = Value::new(func, ty.clone());
        func.insn_store_relative(&val, 0, &str_ptr);
        func.insn_store_relative(&val, ty.find_name("len").get_offset() as int, &self.len().compile(func));
        val
    }
    #[inline]
    fn jit_type(_:Option<&'a str>) -> Type {
        jit!(struct {
            "ptr": *const u8,
            "len": uint
        })
    }
}
impl<'a> Compile for String {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let str_ptr = {
            let ty = ::get::<*const u8>();
            let ptr = Value::new(func, ty);
            func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&self.len())));
            for (pos, ch) in self.as_slice().bytes().enumerate() {
                let char_v = ch.compile(func);
                func.insn_store_relative(&ptr, pos as int, &char_v);
            }
            ptr
        };
        let ty = ::get::<String>();
        let val = Value::new(func, ty.clone());
        let length = self.len().compile(func);
        func.insn_store_relative(&val, 0, &length);
        func.insn_store_relative(&val, ty.clone().find_name("cap").get_offset() as int, &length);
        func.insn_store_relative(&val, ty.find_name("ptr").get_offset() as int, &str_ptr);
        val
    }
    #[inline]
    fn jit_type(_:Option<String>) -> Type {
        jit!(struct {
            "len": uint,
            "cap": uint,
            "ptr": &u8
        })
    }
}
impl<'a, T:Compile> Compile for Vec<T> {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let vec_ptr = {
            let ty = ::get::<&T>();
            let inner_ty = jit!(T);
            let ptr = Value::new(func, ty);
            let ptr_size = self.len() * inner_ty.get_size();
            let ptr_size = func.insn_of(&ptr_size);
            func.insn_store(&ptr, &func.insn_alloca(&ptr_size));
            for (pos, val) in self.iter().enumerate() {
                let val_v = val.compile(func);
                func.insn_store_relative(&ptr, pos as int, &val_v);
            }
            ptr
        };
        let ty = ::get::<String>();
        let val = Value::new(func, ty.clone());
        let length = func.insn_of(&self.len());
        func.insn_store_relative(&val, 0, &length);
        func.insn_store_relative(&val, ty.clone().find_name("cap").get_offset() as int, &length);
        func.insn_store_relative(&val, ty.find_name("ptr").get_offset() as int, &vec_ptr);
        val
    }
    #[inline]
    fn jit_type(_:Option<Vec<T>>) -> Type {
        jit!(struct {
            "len": uint,
            "cap": uint,
            "ptr": &T
        })
    }
}
impl<'a, T:Compile> Compile for &'a T {
    #[inline]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit!(T).as_ptr(),
                (*self as *const T).to_uint() as c_long
            ))
        }
    }
    #[inline]
    fn jit_type(_:Option<&'a T>) -> Type {
        Type::create_pointer(jit!(T))
    }
}
impl<R:Compile> Compile for fn() -> R {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn() -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn() -> R>(), false)
    }
    #[inline]
    fn jit_type(_:Option<fn() -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [])
    }
}
impl<A:Compile, R:Compile> Compile for fn(A) -> R {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A) -> R>(), false)
    }
    #[inline]
    fn jit_type(_:Option<fn(A) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A)])
    }
}
impl<A:Compile, B:Compile, R:Compile> Compile for fn(A, B) -> R {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A, B) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A, B) -> R>(), false)
    }
    #[inline]
    fn jit_type(_:Option<fn(A, B) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A), jit!(B)])
    }
}
impl<A:Compile, B:Compile, C:Compile, R:Compile> Compile for fn(A, B, C) -> R {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A, B, C) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A, B, C) -> R>(), false)
    }
    #[inline]
    fn jit_type(_:Option<fn(A, B, C) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A), jit!(B), jit!(C)])
    }
}<commit_msg>Always inline most Compile implementations<commit_after>use bindings::{
    jit_type_void_ptr,
    jit_type_ubyte,
    jit_type_sbyte,
    jit_type_ushort,
    jit_type_short,
    jit_type_uint,
    jit_type_int,
    jit_type_nuint,
    jit_type_nint,
    jit_type_float32,
    jit_type_float64,
    jit_type_long,
    jit_type_ulong,
    jit_type_sys_bool,
    jit_type_sys_char,

    jit_value_create_long_constant,
    jit_value_create_nint_constant,
    jit_value_create_float64_constant,
    jit_value_create_float32_constant
};
use function::{
    CDECL,
    Function
};
use get_type = types::get;
use libc::c_long;
use value::Value;
use std::c_str::CString;
use std::mem::transmute;
use types::Type;
use util::NativeRef;
/// A type that can be compiled into a LibJIT representation
pub trait Compile {
    /// Get a JIT representation of this value
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a>;
    /// Get the JIT type repr of the value
    fn jit_type(_:Option<Self>) -> Type;
}
impl Compile for () {
    #[inline(always)]
    fn compile(&self, func:&Function) -> Value {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit_type_void_ptr,
                0
            ))
        }
    }
    #[inline(always)]
    fn jit_type(_:Option<()>) -> Type {
        unsafe {
            NativeRef::from_ptr(jit_type_void_ptr)
        }
    }
}
compile_prim!(f64, jit_type_float64, jit_value_create_float64_constant)
compile_prim!(f32, jit_type_float32, jit_value_create_float32_constant)
compile_prim!(int, jit_type_nint, jit_value_create_nint_constant, c_long)
compile_prim!(uint,jit_type_nuint, jit_value_create_nint_constant, c_long)
compile_prim!(i64, jit_type_long, jit_value_create_long_constant, c_long)
compile_prim!(u64, jit_type_ulong, jit_value_create_long_constant, c_long)
compile_prim!(i32, jit_type_int, jit_value_create_nint_constant, c_long)
compile_prim!(u32, jit_type_uint, jit_value_create_nint_constant, c_long)
compile_prim!(i16, jit_type_short, jit_value_create_nint_constant, c_long)
compile_prim!(u16, jit_type_ushort, jit_value_create_nint_constant, c_long)
compile_prim!(i8, jit_type_sbyte, jit_value_create_nint_constant, c_long)
compile_prim!(u8, jit_type_ubyte, jit_value_create_nint_constant, c_long)
compile_prim!(bool, jit_type_sys_bool, jit_value_create_nint_constant, c_long)
compile_prim!(char, jit_type_sys_char, jit_value_create_nint_constant, c_long)
impl Compile for *const u8 {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let c_str = unsafe { CString::new(transmute(*self), false) };
        let ty = jit!(&u8);
        let ptr = Value::new(func, ty);
        let length = c_str.len() + 1u;
        func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&length)));
        for enum_char in c_str.iter().enumerate() {
            let (pos, ch) = enum_char;
            let char_v = ch.compile(func);
            func.insn_store_relative(&ptr, pos as int, &char_v);
        }
        func.insn_store_relative(&ptr, c_str.len() as int, &func.insn_of(&'\0'));
        ptr
    }
    #[inline(always)]
    fn jit_type(_:Option<*const u8>) -> Type {
        ::get::<&u8>()
    }
}
impl<T:Compile> Compile for *mut T {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit!(&T).as_ptr(),
                self.to_uint() as c_long
            ))
        }
    }
    #[inline(always)]
    fn jit_type(_:Option<*mut T>) -> Type {
        jit!(&T)
    }
}
impl<'s> Compile for CString {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ty = jit!(CString);
        let val = Value::new(func, ty.clone());
        let string:*const u8 = unsafe { transmute(self.as_ptr()) };
        func.insn_store_relative(&val, 0, &string.compile(func));
        func.insn_store_relative(&val, ty.find_name("is_owned").get_offset() as int, &true.compile(func));
        val
    }
    #[inline]
    fn jit_type(_:Option<CString>) -> Type {
        jit!(struct {
            "ptr": *const u8,
            "is_owned": bool
        })
    }
}
impl<'a> Compile for &'a str {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let str_ptr = {
            let ty = ::get::<*const u8>();
            let ptr = Value::new(func, ty);
            func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&self.len())));
            for enum_char in self.bytes().enumerate() {
                let (pos, ch) = enum_char;
                let char_v = ch.compile(func);
                func.insn_store_relative(&ptr, pos as int, &char_v);
            }
            ptr
        };
        let ty = ::get::<&'a str>();
        let val = Value::new(func, ty.clone());
        func.insn_store_relative(&val, 0, &str_ptr);
        func.insn_store_relative(&val, ty.find_name("len").get_offset() as int, &self.len().compile(func));
        val
    }
    #[inline]
    fn jit_type(_:Option<&'a str>) -> Type {
        jit!(struct {
            "ptr": *const u8,
            "len": uint
        })
    }
}
impl<'a> Compile for String {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let str_ptr = {
            let ty = ::get::<*const u8>();
            let ptr = Value::new(func, ty);
            func.insn_store(&ptr, &func.insn_alloca(&func.insn_of(&self.len())));
            for (pos, ch) in self.as_slice().bytes().enumerate() {
                let char_v = ch.compile(func);
                func.insn_store_relative(&ptr, pos as int, &char_v);
            }
            ptr
        };
        let ty = ::get::<String>();
        let val = Value::new(func, ty.clone());
        let length = self.len().compile(func);
        func.insn_store_relative(&val, 0, &length);
        func.insn_store_relative(&val, ty.clone().find_name("cap").get_offset() as int, &length);
        func.insn_store_relative(&val, ty.find_name("ptr").get_offset() as int, &str_ptr);
        val
    }
    #[inline]
    fn jit_type(_:Option<String>) -> Type {
        jit!(struct {
            "len": uint,
            "cap": uint,
            "ptr": &u8
        })
    }
}
impl<'a, T:Compile> Compile for Vec<T> {
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let vec_ptr = {
            let ty = ::get::<&T>();
            let inner_ty = jit!(T);
            let ptr = Value::new(func, ty);
            let ptr_size = self.len() * inner_ty.get_size();
            let ptr_size = func.insn_of(&ptr_size);
            func.insn_store(&ptr, &func.insn_alloca(&ptr_size));
            for (pos, val) in self.iter().enumerate() {
                let val_v = val.compile(func);
                func.insn_store_relative(&ptr, pos as int, &val_v);
            }
            ptr
        };
        let ty = ::get::<String>();
        let val = Value::new(func, ty.clone());
        let length = func.insn_of(&self.len());
        func.insn_store_relative(&val, 0, &length);
        func.insn_store_relative(&val, ty.clone().find_name("cap").get_offset() as int, &length);
        func.insn_store_relative(&val, ty.find_name("ptr").get_offset() as int, &vec_ptr);
        val
    }
    #[inline]
    fn jit_type(_:Option<Vec<T>>) -> Type {
        jit!(struct {
            "len": uint,
            "cap": uint,
            "ptr": &T
        })
    }
}
impl<'a, T:Compile> Compile for &'a T {
    #[inline(always)]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_create_nint_constant(
                func.as_ptr(),
                jit!(T).as_ptr(),
                (*self as *const T).to_uint() as c_long
            ))
        }
    }
    #[inline(always)]
    fn jit_type(_:Option<&'a T>) -> Type {
        Type::create_pointer(jit!(T))
    }
}
impl<R:Compile> Compile for fn() -> R {
    #[inline(always)]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn() -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn() -> R>(), false)
    }
    #[inline(always)]
    fn jit_type(_:Option<fn() -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [])
    }
}
impl<A:Compile, R:Compile> Compile for fn(A) -> R {
    #[inline(always)]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A) -> R>(), false)
    }
    #[inline(always)]
    fn jit_type(_:Option<fn(A) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A)])
    }
}
impl<A:Compile, B:Compile, R:Compile> Compile for fn(A, B) -> R {
    #[inline(always)]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A, B) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A, B) -> R>(), false)
    }
    #[inline(always)]
    fn jit_type(_:Option<fn(A, B) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A), jit!(B)])
    }
}
impl<A:Compile, B:Compile, C:Compile, R:Compile> Compile for fn(A, B, C) -> R {
    #[inline(always)]
    fn compile<'a>(&self, func:&'a Function<'a>) -> Value<'a> {
        let ptr = (self as *const fn(A, B, C) -> R).to_uint().compile(func);
        func.insn_convert(&ptr, get_type::<fn(A, B, C) -> R>(), false)
    }
    #[inline(always)]
    fn jit_type(_:Option<fn(A, B, C) -> R>) -> Type {
        Type::create_signature(CDECL, jit!(R), &mut [jit!(A), jit!(B), jit!(C)])
    }
}<|endoftext|>


<commit_before>use std::f32::consts::{PI, FRAC_1_PI};
use std::path::Path;
use std::cmp::max;

use na::{Norm, Inverse, origin};
use uuid::Uuid;

use ::{Vector3f, Point2i, Point2f, Point3f, Transform};
use geometry::{spherical_phi, spherical_theta};
use interaction::{Interaction, SurfaceInteraction};
use light::{Light, LightFlags, VisibilityTester, INFINITE};
use mipmap::{MIPMap, WrapMode};
use ray::Ray;
use sampling::Distribution2D;
use spectrum::Spectrum;

pub struct InfiniteAreaLight {
    id: Uuid,
    light_to_world: Transform,
    world_to_light: Transform,
    n_samples: u32,
    l_map: Box<MIPMap<Spectrum>>,
    world_center: Point3f,
    world_radius: f32,
    distribution: Box<Distribution2D>,
}

impl InfiniteAreaLight {
    pub fn new(l2w: Transform,
               n_samples: u32,
               power: Spectrum,
               texmap: &Path)
               -> InfiniteAreaLight {
        // Read texel data from texmap and initialise Lmap TODO
        let resolution = Point2i::new(1, 1);
        let l_map = Box::new(MIPMap::new(&resolution, &[power; 1], false, 0.0, WrapMode::Repeat));
        // initialize sampling PDFs for infinite area light TODO
        // - compute scalar-valued image img from environment map
        let (width, height) = (2 * l_map.width(), 2 * l_map.height());
        let filter = 0.5 / max(width, height) as f32;
        let mut img = Vec::with_capacity(width * height);
        for v in 0..height {
            let vp = (v as f32 + 0.5) / height as f32;
            let sin_theta = (PI * (v as f32 + 0.5) / height as f32).sin();
            for u in 0..width {
                let up = (u as f32 + 0.5) / width as f32;
                img.push(l_map.lookup(&Point2f::new(up, vp), filter).y() * sin_theta);
            }
        }
        // - compute sampling distributions for rows and columns of image
        let distribution = Box::new(Distribution2D::new(&img[..], width, height));

        InfiniteAreaLight {
            id: Uuid::new_v4(),
            light_to_world: l2w,
            world_to_light: l2w.inverse().unwrap(),
            n_samples: n_samples,
            l_map: l_map,
            world_center: origin(),
            world_radius: 100.0, // TODO
            distribution: distribution,
        }
    }
}

impl Light for InfiniteAreaLight {
    fn id(&self) -> Uuid {
        self.id
    }

    fn sample_li(&self,
                 isect: &SurfaceInteraction,
                 u: &Point2f)
                 -> (Spectrum, Vector3f, f32, VisibilityTester) {
        // Find (u, v) sample coordinates in infinite light texture
        let (uv, map_pdf) = self.distribution.sample_continuous(u);
        if map_pdf == 0.0 {
            return (Spectrum::black(),
                    Vector3f::new(0.0, 0.0, 0.0),
                    0.0,
                    VisibilityTester::new(Interaction::from_point(&origin()),
                                          Interaction::from_point(&origin())));
        }
        // Convert infinite light sample point to direction
        let theta = uv[1] * PI;
        let phi = uv[0] * 2.0 * PI;
        let cos_theta = theta.cos();
        let sin_theta = theta.sin();
        let cos_phi = phi.cos();
        let sin_phi = phi.sin();
        let wi = self.light_to_world *
                 Vector3f::new(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
        // Compute PDF for sampled infinite light direction
        let pdf = if sin_theta == 0.0 {
            0.0
        } else {
            map_pdf / (2.0 * PI * PI * sin_theta)
        };
        // Return radiance value for infinite light direction
        let target = isect.p + wi * (2.0 * self.world_radius);
        let vis = VisibilityTester::new(isect.into(), Interaction::from_point(&target));
        (self.l_map.lookup(&uv, 0.0), wi, pdf, vis)
    }

    fn pdf_li(&self, si: &SurfaceInteraction, w: &Vector3f) -> f32 {
        let wi = self.world_to_light * *w;
        let theta = spherical_theta(&wi);
        let phi = spherical_phi(&wi);
        let sin_theta = theta.sin();

        if sin_theta == 0.0 {
            0.0
        } else {
            self.distribution.pdf(&Point2f::new(phi * FRAC_1_PI * 0.5, theta * FRAC_1_PI)) /
            (2.0 * PI * PI * sin_theta)
        }
    }

    fn n_samples(&self) -> u32 {
        self.n_samples
    }

    fn flags(&self) -> LightFlags {
        INFINITE
    }

    fn power(&self) -> Spectrum {
        PI * self.world_radius * self.world_radius * self.l_map.lookup(&Point2f::new(0.5, 0.5), 0.5)
    }

    fn le(&self, ray: &Ray) -> Spectrum {
        let w = (self.world_to_light * ray.d).normalize();
        let st = Point2f::new(spherical_phi(&w) * FRAC_1_PI * 0.5,
                              spherical_theta(&w) * FRAC_1_PI);

        self.l_map.lookup(&st, 0.0)
    }
}
<commit_msg>Add support for environment maps in infinite lights<commit_after>use std::f32::consts::{PI, FRAC_1_PI};
use std::path::Path;
use std::cmp::min;

use img;
use na::{Norm, Inverse, origin};
use uuid::Uuid;

use ::{Vector3f, Point2i, Point2f, Point3f, Transform};
use geometry::{spherical_phi, spherical_theta};
use interaction::{Interaction, SurfaceInteraction};
use light::{Light, LightFlags, VisibilityTester, INFINITE};
use mipmap::{MIPMap, WrapMode};
use ray::Ray;
use sampling::Distribution2D;
use spectrum::Spectrum;

pub struct InfiniteAreaLight {
    id: Uuid,
    light_to_world: Transform,
    world_to_light: Transform,
    n_samples: u32,
    l_map: Box<MIPMap<Spectrum>>,
    world_center: Point3f,
    world_radius: f32,
    distribution: Box<Distribution2D>,
}

impl InfiniteAreaLight {
    pub fn new(l2w: Transform,
               n_samples: u32,
               power: Spectrum,
               texmap: &Path)
               -> InfiniteAreaLight {
        // Read texel data from texmap and initialise Lmap
        let (resolution, mut texels) = if let Ok(buf) = img::open(texmap) {
            info!("Loading environment map {} for infinite light",
                  texmap.display());
            let rgb = buf.to_rgb();
            let resolution = Point2i::new(rgb.width(), rgb.height());
            let mut pixels: Vec<Spectrum> = rgb.pixels()
                .map(|p| Spectrum::from_srgb(&p.data) * power)
                .collect();
            (resolution, pixels)
        } else {
            warn!("Environment map {} for infinite light not found! Using constant texture \
                   instead.",
                  texmap.display());
            (Point2i::new(1, 1), vec![power])
        };
        //
        let l_map = Box::new(MIPMap::new(&resolution, &texels[..], false, 0.0, WrapMode::Repeat));
        // initialize sampling PDFs for infinite area light
        // - compute scalar-valued image img from environment map
        let (width, height) = (2 * l_map.width(), 2 * l_map.height());
        let filter = 0.5 / min(width, height) as f32;
        let mut img = Vec::with_capacity(width * height);
        for v in 0..height {
            let vp = (v as f32 + 0.5) / height as f32;
            let sin_theta = (PI * (v as f32 + 0.5) / height as f32).sin();
            for u in 0..width {
                let up = (u as f32 + 0.5) / width as f32;
                img.push(l_map.lookup(&Point2f::new(up, vp), filter).y() * sin_theta);
            }
        }
        // - compute sampling distributions for rows and columns of image
        let distribution = Box::new(Distribution2D::new(&img[..], width, height));

        InfiniteAreaLight {
            id: Uuid::new_v4(),
            light_to_world: l2w,
            world_to_light: l2w.inverse().unwrap(),
            n_samples: n_samples,
            l_map: l_map,
            world_center: origin(),
            world_radius: 100.0, // TODO
            distribution: distribution,
        }
    }
}

impl Light for InfiniteAreaLight {
    fn id(&self) -> Uuid {
        self.id
    }

    fn sample_li(&self,
                 isect: &SurfaceInteraction,
                 u: &Point2f)
                 -> (Spectrum, Vector3f, f32, VisibilityTester) {
        // Find (u, v) sample coordinates in infinite light texture
        let (uv, map_pdf) = self.distribution.sample_continuous(u);
        if map_pdf == 0.0 {
            return (Spectrum::black(),
                    Vector3f::new(0.0, 0.0, 0.0),
                    0.0,
                    VisibilityTester::new(Interaction::from_point(&origin()),
                                          Interaction::from_point(&origin())));
        }
        // Convert infinite light sample point to direction
        let theta = uv[1] * PI;
        let phi = uv[0] * 2.0 * PI;
        let cos_theta = theta.cos();
        let sin_theta = theta.sin();
        let cos_phi = phi.cos();
        let sin_phi = phi.sin();
        let wi = self.light_to_world *
                 Vector3f::new(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
        // Compute PDF for sampled infinite light direction
        let pdf = if sin_theta == 0.0 {
            0.0
        } else {
            map_pdf / (2.0 * PI * PI * sin_theta)
        };
        // Return radiance value for infinite light direction
        let target = isect.p + wi * (2.0 * self.world_radius);
        let vis = VisibilityTester::new(isect.into(), Interaction::from_point(&target));
        (self.l_map.lookup(&uv, 0.0), wi, pdf, vis)
    }

    fn pdf_li(&self, si: &SurfaceInteraction, w: &Vector3f) -> f32 {
        let wi = self.world_to_light * *w;
        let theta = spherical_theta(&wi);
        let phi = spherical_phi(&wi);
        let sin_theta = theta.sin();

        if sin_theta == 0.0 {
            0.0
        } else {
            self.distribution.pdf(&Point2f::new(phi * FRAC_1_PI * 0.5, theta * FRAC_1_PI)) /
            (2.0 * PI * PI * sin_theta)
        }
    }

    fn n_samples(&self) -> u32 {
        self.n_samples
    }

    fn flags(&self) -> LightFlags {
        INFINITE
    }

    fn power(&self) -> Spectrum {
        PI * self.world_radius * self.world_radius * self.l_map.lookup(&Point2f::new(0.5, 0.5), 0.5)
    }

    fn le(&self, ray: &Ray) -> Spectrum {
        let w = (self.world_to_light * ray.d).normalize();
        let st = Point2f::new(spherical_phi(&w) * FRAC_1_PI * 0.5,
                              spherical_theta(&w) * FRAC_1_PI);

        self.l_map.lookup(&st, 0.0)
    }
}
<|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.

//! Overlap: No two impls for the same trait are implemented for the
//! same type.

use middle::traits;
use middle::ty;
use middle::infer::{self, new_infer_ctxt};
use syntax::ast::{DefId};
use syntax::ast::{LOCAL_CRATE};
use syntax::ast;
use syntax::codemap::{Span};
use util::ppaux::Repr;

pub fn check(tcx: &ty::ctxt) {
    let overlap = OverlapChecker { tcx: tcx };
    overlap.check_for_overlapping_impls();
}

struct OverlapChecker<'cx, 'tcx:'cx> {
    tcx: &'cx ty::ctxt<'tcx>
}

impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
    fn check_for_overlapping_impls(&self) {
        debug!("check_for_overlapping_impls");

        // Collect this into a vector to avoid holding the
        // refcell-lock during the
        // check_for_overlapping_impls_of_trait() check, since that
        // check can populate this table further with impls from other
        // crates.
        let trait_def_ids: Vec<ast::DefId> =
            self.tcx.trait_impls.borrow().keys().map(|&d| d).collect();

        for trait_def_id in trait_def_ids.iter() {
            self.check_for_overlapping_impls_of_trait(*trait_def_id);
        }
    }

    fn check_for_overlapping_impls_of_trait(&self,
                                            trait_def_id: ast::DefId)
    {
        debug!("check_for_overlapping_impls_of_trait(trait_def_id={})",
               trait_def_id.repr(self.tcx));

        // FIXME -- it seems like this method actually pushes
        // duplicate impls onto the list
        ty::populate_implementations_for_trait_if_necessary(self.tcx,
                                                            trait_def_id);

        let mut impls = Vec::new();
        self.push_impls_of_trait(trait_def_id, &mut impls);

        for (i, &impl1_def_id) in impls.iter().enumerate() {
            if impl1_def_id.krate != ast::LOCAL_CRATE {
                // we don't need to check impls if both are external;
                // that's the other crate's job.
                continue;
            }

            for &impl2_def_id in impls.slice_from(i+1).iter() {
                self.check_if_impls_overlap(trait_def_id,
                                            impl1_def_id,
                                            impl2_def_id);
            }
        }
    }

    fn check_if_impls_overlap(&self,
                              trait_def_id: ast::DefId,
                              impl1_def_id: ast::DefId,
                              impl2_def_id: ast::DefId)
    {
        assert_eq!(impl1_def_id.krate, ast::LOCAL_CRATE);

        debug!("check_if_impls_overlap({}, {}, {})",
               trait_def_id.repr(self.tcx),
               impl1_def_id.repr(self.tcx),
               impl2_def_id.repr(self.tcx));

        let infcx = infer::new_infer_ctxt(self.tcx);
        if !traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
            return;
        }

        span_err!(self.tcx.sess, self.span_of_impl(impl1_def_id), E0119,
                  "conflicting implementations for trait `{}`",
                  ty::item_path_str(self.tcx, trait_def_id));

        if impl2_def_id.krate == ast::LOCAL_CRATE {
            span_note!(self.tcx.sess, self.span_of_impl(impl2_def_id),
                       "note conflicting implementation here");
        } else {
            let crate_store = &self.tcx.sess.cstore;
            let cdata = crate_store.get_crate_data(impl2_def_id.krate);
            span_note!(self.tcx.sess, self.span_of_impl(impl1_def_id),
                       "conflicting implementation in crate `{}`",
                       cdata.name);
        }
    }

    fn push_impls_of_trait(&self,
                           trait_def_id: ast::DefId,
                           out: &mut Vec<ast::DefId>) {
        match self.tcx.trait_impls.borrow().get(&trait_def_id) {
            Some(impls) => { out.push_all(impls.borrow().as_slice()); }
            None => { /* no impls */ }
        }
    }

    fn span_of_impl(&self, impl_did: ast::DefId) -> Span {
        assert_eq!(impl_did.krate, ast::LOCAL_CRATE);
        self.tcx.map.span(impl_did.node)
    }
}
<commit_msg>push_impls_of_trait is not needed, use map<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.

//! Overlap: No two impls for the same trait are implemented for the
//! same type.

use middle::traits;
use middle::ty;
use middle::infer::{self, new_infer_ctxt};
use syntax::ast::{DefId};
use syntax::ast::{LOCAL_CRATE};
use syntax::ast;
use syntax::codemap::{Span};
use util::ppaux::Repr;

pub fn check(tcx: &ty::ctxt) {
    let overlap = OverlapChecker { tcx: tcx };
    overlap.check_for_overlapping_impls();
}

struct OverlapChecker<'cx, 'tcx:'cx> {
    tcx: &'cx ty::ctxt<'tcx>
}

impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
    fn check_for_overlapping_impls(&self) {
        debug!("check_for_overlapping_impls");

        // Collect this into a vector to avoid holding the
        // refcell-lock during the
        // check_for_overlapping_impls_of_trait() check, since that
        // check can populate this table further with impls from other
        // crates.
        let trait_def_ids: Vec<(ast::DefId, Vec<ast::DefId>)> =
            self.tcx.trait_impls.borrow().iter().map(|(&k, v)|
                                                     (k, v.borrow().clone())).collect();

        for &(trait_def_id, ref impls) in trait_def_ids.iter() {
            self.check_for_overlapping_impls_of_trait(trait_def_id, impls);
        }
    }

    fn check_for_overlapping_impls_of_trait(&self,
                                            trait_def_id: ast::DefId,
                                            trait_impls: &Vec<ast::DefId>)
    {
        debug!("check_for_overlapping_impls_of_trait(trait_def_id={})",
               trait_def_id.repr(self.tcx));

        // FIXME -- it seems like this method actually pushes
        // duplicate impls onto the list
        ty::populate_implementations_for_trait_if_necessary(self.tcx,
                                                            trait_def_id);

        for (i, &impl1_def_id) in trait_impls.iter().enumerate() {
            if impl1_def_id.krate != ast::LOCAL_CRATE {
                // we don't need to check impls if both are external;
                // that's the other crate's job.
                continue;
            }

            for &impl2_def_id in trait_impls.slice_from(i+1).iter() {
                self.check_if_impls_overlap(trait_def_id,
                                            impl1_def_id,
                                            impl2_def_id);
            }
        }
    }

    fn check_if_impls_overlap(&self,
                              trait_def_id: ast::DefId,
                              impl1_def_id: ast::DefId,
                              impl2_def_id: ast::DefId)
    {
        assert_eq!(impl1_def_id.krate, ast::LOCAL_CRATE);

        debug!("check_if_impls_overlap({}, {}, {})",
               trait_def_id.repr(self.tcx),
               impl1_def_id.repr(self.tcx),
               impl2_def_id.repr(self.tcx));

        let infcx = infer::new_infer_ctxt(self.tcx);
        if !traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
            return;
        }

        span_err!(self.tcx.sess, self.span_of_impl(impl1_def_id), E0119,
                  "conflicting implementations for trait `{}`",
                  ty::item_path_str(self.tcx, trait_def_id));

        if impl2_def_id.krate == ast::LOCAL_CRATE {
            span_note!(self.tcx.sess, self.span_of_impl(impl2_def_id),
                       "note conflicting implementation here");
        } else {
            let crate_store = &self.tcx.sess.cstore;
            let cdata = crate_store.get_crate_data(impl2_def_id.krate);
            span_note!(self.tcx.sess, self.span_of_impl(impl1_def_id),
                       "conflicting implementation in crate `{}`",
                       cdata.name);
        }
    }

    fn span_of_impl(&self, impl_did: ast::DefId) -> Span {
        assert_eq!(impl_did.krate, ast::LOCAL_CRATE);
        self.tcx.map.span(impl_did.node)
    }
}
<|endoftext|>


<commit_before>use std::io::Read;

use rustc_serialize::json::Json;
use oauthcli::SignatureMethod::HmacSha1;
use oauthcli::OAuthAuthorizationHeaderBuilder;
use url::Url;
use url::form_urlencoded::Serializer;
use hyper::{Client, Error};
use hyper::client::Response;
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::header::{Headers, Authorization, ContentType};

pub struct TwitterClient {
	consumer_key: String,
	consumer_secret: String,
	access_key: String,
	access_secret: String,
	client: Client
}

#[derive(Debug)]
pub enum StatusUpdateError {
	Duplicated,
	RateLimitExceeded,
	Invalid,
	Network,
	Unauthorized,
	Unknown
}

impl TwitterClient {

	pub fn new(consumer_key: String, consumer_secret: String, access_key: String, access_secret: String) -> TwitterClient
	{
		TwitterClient {
			consumer_key: consumer_key,
			consumer_secret: consumer_secret,
			access_key: access_key,
			access_secret: access_secret,
			client: Client::new()
		}
	}

	pub fn is_valid(&self) -> bool
	{
		// TODO: implement token validation
		return true;
	}

	pub fn update_status(&self, message: &str, in_reply_to: Option<u64>)
	 -> Result<u64, StatusUpdateError>
	{
		let api_url = "https://api.twitter.com/1.1/statuses/update.json";
		let prev_str_opt = in_reply_to.map(|i| i.to_string());
		let mut args = vec![("status", message)];
		if prev_str_opt.is_some() {
			args.push(("in_reply_to_status_id", prev_str_opt.as_ref().unwrap()));
		}
		let result = self.request(Method::Post, api_url, args);

		let mut res = try!(result.map_err(|_| StatusUpdateError::Network));

		match res.status {

			StatusCode::Forbidden => {

				let mut body = String::new();

				try!(res.read_to_string(&mut body).map_err(|_| StatusUpdateError::Unknown));

				if body.contains("140") {
					return Err(StatusUpdateError::Invalid);
				} else if body.contains("duplicate") {
					return Err(StatusUpdateError::Duplicated);
				}

				return Err(StatusUpdateError::Unknown);
			},

			StatusCode::Ok => {

				let mut body = String::new();

				try!(res.read_to_string(&mut body).map_err(|_| StatusUpdateError::Unknown));

				let json = try!(Json::from_str(&body).map_err(|_| StatusUpdateError::Unknown));
				let id_obj = try!(json.find("id").ok_or(StatusUpdateError::Unknown));
				let id = try!(id_obj.as_u64().ok_or(StatusUpdateError::Unknown));

				return Ok(id);
			},

			StatusCode::TooManyRequests => return Err(StatusUpdateError::RateLimitExceeded),
			StatusCode::Unauthorized => return Err(StatusUpdateError::Unauthorized),
			_ => return Err(StatusUpdateError::Unknown)
		};
	}

	fn request(&self, method: Method, api_url: &str, args: Vec<(&str, &str)>)
	 -> Result<Response, Error>
	{
		match method {

			Method::Get => {

				let mut headers = Headers::new();
				let oauth_header = self.construct_oauth_header("GET", api_url, args);
				headers.set(Authorization(oauth_header));

				let result = self.client.get(api_url).headers(headers).send();

				return result;

			},

			Method::Post => {

				let content_type = ContentType("application/x-www-form-urlencoded".parse().unwrap());

				let mut args_serializer = Serializer::new(String::new());
				for &(ref k, ref v) in &args {
					args_serializer.append_pair(k, v);
				}
				let args_serialized = args_serializer.finish();

				let mut headers = Headers::new();
				let oauth_header = self.construct_oauth_header("POST", api_url, args);
				headers.set(Authorization(oauth_header));
				headers.set(content_type);

				let result = self.client.post(api_url).body(&args_serialized).headers(headers).send();

				return result;

			},

			_ => {
				panic!();
			}
		}
	}

	fn construct_oauth_header(&self, method: &str, api_url: &str, args: Vec<(&str, &str)>)
	 -> String
	{
		let oauth_header = OAuthAuthorizationHeaderBuilder::new(
			method,
			&Url::parse(api_url).unwrap(),
			self.consumer_key.as_ref(),
			self.consumer_secret.as_ref(),
			HmacSha1)
			.token(self.access_key.as_ref(), self.access_secret.as_ref())
			.request_parameters(args.into_iter())
			.finish_for_twitter();

		return oauth_header.to_string();
	}
}
<commit_msg>TwitterClient: Return more detailed error when failing to tweet<commit_after>use std::io::Read;

use rustc_serialize::json::Json;
use oauthcli::SignatureMethod::HmacSha1;
use oauthcli::OAuthAuthorizationHeaderBuilder;
use url::Url;
use url::form_urlencoded::Serializer;
use hyper::{Client, Error};
use hyper::client::Response;
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::header::{Headers, Authorization, ContentType};

pub struct TwitterClient {
	consumer_key: String,
	consumer_secret: String,
	access_key: String,
	access_secret: String,
	client: Client
}

#[derive(Debug)]
pub enum StatusUpdateError {
	Duplicated,
	RateLimitExceeded,
	InvalidTweet,
	InvalidResponse,
	Network,
	Unauthorized,
	Unknown(String)
}

impl TwitterClient {

	pub fn new(consumer_key: String, consumer_secret: String, access_key: String, access_secret: String) -> TwitterClient
	{
		TwitterClient {
			consumer_key: consumer_key,
			consumer_secret: consumer_secret,
			access_key: access_key,
			access_secret: access_secret,
			client: Client::new()
		}
	}

	pub fn is_valid(&self) -> bool
	{
		// TODO: implement token validation
		return true;
	}

	pub fn update_status(&self, message: &str, in_reply_to: Option<u64>)
	 -> Result<u64, StatusUpdateError>
	{
		let api_url = "https://api.twitter.com/1.1/statuses/update.json";
		let prev_str_opt = in_reply_to.map(|i| i.to_string());
		let mut args = vec![("status", message)];
		if prev_str_opt.is_some() {
			args.push(("in_reply_to_status_id", prev_str_opt.as_ref().unwrap()));
		}
		let result = self.request(Method::Post, api_url, args);

		let mut res = try!(result.map_err(|_| StatusUpdateError::Network));

		match res.status {

			StatusCode::Forbidden => {

				let mut body = String::new();

				try!(res.read_to_string(&mut body).map_err(|_| StatusUpdateError::Network));

				if body.contains("140") {
					return Err(StatusUpdateError::InvalidTweet);
				} else if body.contains("duplicate") {
					return Err(StatusUpdateError::Duplicated);
				}

				return Err(StatusUpdateError::Unknown(body));
			},

			StatusCode::Ok => {

				let mut body = String::new();

				try!(res.read_to_string(&mut body).map_err(|_| StatusUpdateError::Network));

				let json = try!(Json::from_str(&body).map_err(|_| StatusUpdateError::InvalidResponse));
				let id_obj = try!(json.find("id").ok_or(StatusUpdateError::InvalidResponse));
				let id = try!(id_obj.as_u64().ok_or(StatusUpdateError::InvalidResponse));

				return Ok(id);
			},

			StatusCode::TooManyRequests => return Err(StatusUpdateError::RateLimitExceeded),
			StatusCode::Unauthorized => return Err(StatusUpdateError::Unauthorized),
			_ => return Err(StatusUpdateError::Unknown(format!("Unknown status: {}", res.status)))
		};
	}

	fn request(&self, method: Method, api_url: &str, args: Vec<(&str, &str)>)
	 -> Result<Response, Error>
	{
		match method {

			Method::Get => {

				let mut headers = Headers::new();
				let oauth_header = self.construct_oauth_header("GET", api_url, args);
				headers.set(Authorization(oauth_header));

				let result = self.client.get(api_url).headers(headers).send();

				return result;

			},

			Method::Post => {

				let content_type = ContentType("application/x-www-form-urlencoded".parse().unwrap());

				let mut args_serializer = Serializer::new(String::new());
				for &(ref k, ref v) in &args {
					args_serializer.append_pair(k, v);
				}
				let args_serialized = args_serializer.finish();

				let mut headers = Headers::new();
				let oauth_header = self.construct_oauth_header("POST", api_url, args);
				headers.set(Authorization(oauth_header));
				headers.set(content_type);

				let result = self.client.post(api_url).body(&args_serialized).headers(headers).send();

				return result;

			},

			_ => {
				panic!();
			}
		}
	}

	fn construct_oauth_header(&self, method: &str, api_url: &str, args: Vec<(&str, &str)>)
	 -> String
	{
		let oauth_header = OAuthAuthorizationHeaderBuilder::new(
			method,
			&Url::parse(api_url).unwrap(),
			self.consumer_key.as_ref(),
			self.consumer_secret.as_ref(),
			HmacSha1)
			.token(self.access_key.as_ref(), self.access_secret.as_ref())
			.request_parameters(args.into_iter())
			.finish_for_twitter();

		return oauth_header.to_string();
	}
}
<|endoftext|>


<commit_before>pub fn score_on_word_length(string: &Vec<u8>) -> u8 {
	// Ensure a minimum of one space
	let mut string_with_space = string.clone();
	string_with_space.push(' ' as u8);

	// We'll simply score on how much whitespace there is
	let mut whitespace_count = 0;
	for c in &string_with_space {
		match *c as char {
			' ' | '\t' => whitespace_count += 1,
			_ => {},
		}
	}

	assert!(whitespace_count > 0);
	let average_word_length = string_with_space.len() / whitespace_count;

	let mut closeness_to_avg: f32 = average_word_length as f32 / 5.0;
	closeness_to_avg -= 1.0;
	if closeness_to_avg < 0.0 {
		closeness_to_avg = -closeness_to_avg;
	}

	let score_modifier: u8 = (closeness_to_avg * 40.0) as u8;
	let score: u8 = 255 - score_modifier;

	if score > 0 {
		score
	} else {
		0
	}
}

pub fn score_on_letter_frequency(string: &Vec<u8>) -> u8 {
	let mut frequency_table: Vec<u32> = vec![0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
	let example_frequency_table: Vec<f32> = vec![8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074, 0.0];
	assert_eq!(frequency_table.len(), example_frequency_table.len());

    for byte in string {
    	match *byte as char {
    		'A'...'Z' => frequency_table[(byte - 65) as usize] += 1,
    		'a'...'z' => frequency_table[(byte - 97) as usize] += 1,
    		e @ _ => {
    			if (e as u8) < 128 {
    				frequency_table[26] += 1
    			} else {
    				return 0
    			}
    		}
    	}
    }

    let max_value: u32 = *frequency_table.iter().max().unwrap();

    // Score tables out of 0 - 1
    let normalised_frequency_table: Vec<f32> = frequency_table.iter().map(|x| (*x) as f32 / max_value as f32).collect();
    let normalised_example_frequency_table: Vec<f32> = example_frequency_table.iter().map(|x| (*x) as f32 / 12.702).collect();

    // Create a similarity vector
    let mut similarity_vector: Vec<f32> = vec![];
	for pair in normalised_frequency_table.iter().zip(normalised_example_frequency_table.iter()) {
    	let (a, b) = pair;
    	similarity_vector.push(a - b);
    }

    let difference: f32 = similarity_vector.iter().fold(0.0, |acc, &item| acc + item).abs();
    (255.0 - difference * 5.0) as u8
}

pub fn score_combined(string: &Vec<u8>) -> u16 {
	score_on_word_length(&string) as u16 + score_on_letter_frequency(&string) as u16
}

//-----------------------------------------------------------------------------

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

	#[test]
	fn score_on_word_length_i_longer() {
		let score_real = score_on_word_length(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_word_length(&"ejGD%5545 j48494$%i43i3fdg3AE22".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_word_length_i_shorter() {
		let score_real = score_on_word_length(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_word_length(&"ej n 45 j 48 494 $% i4 3AE 22".bytes().collect());

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_letter_frequency_i_longer() {
		let score_real = score_on_letter_frequency(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_letter_frequency(&"ejGD*%%%%5545 j48494$%i43i3fdg3AE22".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}
}<commit_msg>Up test coverage<commit_after>pub fn score_on_word_length(string: &Vec<u8>) -> u8 {
	// Ensure a minimum of one space
	let mut string_with_space = string.clone();
	string_with_space.push(' ' as u8);

	// We'll simply score on how much whitespace there is
	let mut whitespace_count = 0;
	for c in &string_with_space {
		match *c as char {
			' ' | '\t' => whitespace_count += 1,
			_ => {},
		}
	}

	assert!(whitespace_count > 0);
	let average_word_length = string_with_space.len() / whitespace_count;

	let mut closeness_to_avg: f32 = average_word_length as f32 / 5.0;
	closeness_to_avg -= 1.0;
	if closeness_to_avg < 0.0 {
		closeness_to_avg = -closeness_to_avg;
	}

	let score_modifier: u8 = (closeness_to_avg * 40.0) as u8;
	let score: u8 = 255 - score_modifier;

	if score > 0 {
		score
	} else {
		0
	}
}

pub fn score_on_letter_frequency(string: &Vec<u8>) -> u8 {
	let mut frequency_table: Vec<u32> = vec![0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
	let example_frequency_table: Vec<f32> = vec![8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074, 0.0];
	assert_eq!(frequency_table.len(), example_frequency_table.len());

    for byte in string {
    	match *byte as char {
    		'A'...'Z' => frequency_table[(byte - 65) as usize] += 1,
    		'a'...'z' => frequency_table[(byte - 97) as usize] += 1,
    		e @ _ => {
    			if (e as u8) < 128 {
    				frequency_table[26] += 1
    			} else {
    				return 0
    			}
    		}
    	}
    }

    let max_value: u32 = *frequency_table.iter().max().unwrap();

    // Score tables out of 0 - 1
    let normalised_frequency_table: Vec<f32> = frequency_table.iter().map(|x| (*x) as f32 / max_value as f32).collect();
    let normalised_example_frequency_table: Vec<f32> = example_frequency_table.iter().map(|x| (*x) as f32 / 12.702).collect();

    // Create a similarity vector
    let mut similarity_vector: Vec<f32> = vec![];
	for pair in normalised_frequency_table.iter().zip(normalised_example_frequency_table.iter()) {
    	let (a, b) = pair;
    	similarity_vector.push(a - b);
    }

    let difference: f32 = similarity_vector.iter().fold(0.0, |acc, &item| acc + item).abs();
    (255.0 - difference * 5.0) as u8
}

pub fn score_combined(string: &Vec<u8>) -> u16 {
	score_on_word_length(&string) as u16 + score_on_letter_frequency(&string) as u16
}

//-----------------------------------------------------------------------------

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

	#[test]
	fn score_on_word_length_i_longer() {
		let score_real = score_on_word_length(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_word_length(&"ejGD%5545 j48494$%i43i3fdg3AE22".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_word_length_i_really_long() {
		let score_real = score_on_word_length(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_word_length(&"ejGD%5545j48494$%i43i3ffg5dg3AE22".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_word_length_i_shorter() {
		let score_real = score_on_word_length(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_word_length(&"ej n 45 j 48 494 $% i4 3AE 22".bytes().collect());

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_letter_frequency_i_longer() {
		let score_real = score_on_letter_frequency(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_letter_frequency(&"ejGD*%%%%5545 j48494$%i43i3fdg3AE22".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}

	#[test]
	fn score_on_letter_frequency_i_longer() {
		let score_real = score_on_letter_frequency(&"This is a realistic looking piece of text.".bytes().collect());
		let score_fake = score_on_letter_frequency(&"This is a realistic looking piece of text with a weird character in it: ☃".bytes().collect());

		println!("{} {} ", score_real, score_fake);

		assert!(score_real > score_fake);
	}
}<|endoftext|>


<commit_before>//! System operations instructions

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

#[cfg(not(feature = "std"))] use alloc::rc::Rc;
#[cfg(feature = "std")] use std::rc::Rc;

use bigint::{U256, M256, H256, Address, Gas};
use ::{Memory, Log, ValidTransaction, Patch};
use eval::util::{l64, copy_from_memory};
use block_core::TransactionAction;
use super::{Control, State};

#[cfg(feature = "std")] use std::cmp::min;
#[cfg(not(feature = "std"))] use core::cmp::min;

use sha3::{Digest, Keccak256};

pub fn suicide<M: Memory + Default, P: Patch>(state: &mut State<M, P>) {
    pop!(state, address: Address);
    let balance = state.account_state.balance(state.context.address).unwrap();
    if !state.removed.contains(&state.context.address) {
        state.removed.push(state.context.address);
    }
    state.account_state.increase_balance(address, balance);

    let balance = state.account_state.balance(state.context.address).unwrap();
    state.account_state.decrease_balance(state.context.address, balance);
}

pub fn log<M: Memory + Default, P: Patch>(state: &mut State<M, P>, topic_len: usize) {
    pop!(state, index: U256, len: U256);
    let data = copy_from_memory(&state.memory, index, len);
    let mut topics = Vec::new();
    for _ in 0..topic_len {
        topics.push(H256::from(state.stack.pop().unwrap()));
    }

    state.logs.push(Log {
        address: state.context.address,
        data,
        topics,
    });
}

pub fn sha3<M: Memory + Default, P: Patch>(state: &mut State<M, P>) {
    pop!(state, from: U256, len: U256);
    let data = copy_from_memory(&state.memory, from, len);
    let ret = Keccak256::digest(data.as_slice());
    push!(state, M256::from(ret.as_slice()));
}

macro_rules! try_callstack_limit {
    ( $state:expr, $patch:tt ) => {
        if $state.depth > $patch::callstack_limit() {
            push!($state, M256::zero());
            return None;
        }
    }
}

macro_rules! try_balance {
    ( $state:expr, $value:expr, $gas:expr ) => {
        if $state.account_state.balance($state.context.address).unwrap() < $value {
            push!($state, M256::zero());
            return None;
        }
    }
}

pub fn create<M: Memory + Default, P: Patch>(state: &mut State<M, P>, after_gas: Gas, is_create2: bool) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, value: U256);
    pop!(state, init_start: U256, init_len: U256);

    try_callstack_limit!(state, P);
    try_balance!(state, value, Gas::zero());

    let init = Rc::new(copy_from_memory(&state.memory, init_start, init_len));
    let transaction = if !is_create2 {
        ValidTransaction {
            caller: Some(state.context.address),
            gas_price: state.context.gas_price,
            gas_limit: l64_after_gas,
            value,
            input: init,
            action: TransactionAction::Create,
            nonce: state.account_state.nonce(state.context.address).unwrap(),
        }
    } else {
        pop!(state, salt: H256);
        let init_hash = Keccak256::digest(&init);
        let init_hash = M256::from(&init_hash[..]);
        ValidTransaction {
            caller: Some(state.context.address),
            gas_price: state.context.gas_price,
            gas_limit: l64_after_gas,
            value,
            input: init.clone(),
            action: TransactionAction::Create2(salt, init_hash),
            nonce: state.account_state.nonce(state.context.address).unwrap(),
        }
    };

    let context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();

    push!(state, context.address.into());
    Some(Control::InvokeCreate(context))
}

pub fn call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, stipend_gas: Gas, after_gas: Gas, as_self: bool) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address, value: U256);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas) + stipend_gas;

    try_callstack_limit!(state, P);
    try_balance!(state, value, gas_limit);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.address),
        gas_price: state.context.gas_price,
        gas_limit,
        value,
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let mut context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();
    if as_self {
        context.address = state.context.address;
    }

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}

pub fn static_call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, stipend_gas: Gas, after_gas: Gas) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas) + stipend_gas;

    try_callstack_limit!(state, P);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.address),
        gas_price: state.context.gas_price,
        gas_limit,
        value: U256::zero(),
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        true,
    ).unwrap();

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}

pub fn delegate_call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, after_gas: Gas) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas);

    try_callstack_limit!(state, P);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.caller),
        gas_price: state.context.gas_price,
        gas_limit,
        value: state.context.value,
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let mut context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();
    context.value = U256::zero();
    context.address = state.context.address;

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}
<commit_msg>remove redundant clone<commit_after>//! System operations instructions

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

#[cfg(not(feature = "std"))] use alloc::rc::Rc;
#[cfg(feature = "std")] use std::rc::Rc;

use bigint::{U256, M256, H256, Address, Gas};
use ::{Memory, Log, ValidTransaction, Patch};
use eval::util::{l64, copy_from_memory};
use block_core::TransactionAction;
use super::{Control, State};

#[cfg(feature = "std")] use std::cmp::min;
#[cfg(not(feature = "std"))] use core::cmp::min;

use sha3::{Digest, Keccak256};

pub fn suicide<M: Memory + Default, P: Patch>(state: &mut State<M, P>) {
    pop!(state, address: Address);
    let balance = state.account_state.balance(state.context.address).unwrap();
    if !state.removed.contains(&state.context.address) {
        state.removed.push(state.context.address);
    }
    state.account_state.increase_balance(address, balance);

    let balance = state.account_state.balance(state.context.address).unwrap();
    state.account_state.decrease_balance(state.context.address, balance);
}

pub fn log<M: Memory + Default, P: Patch>(state: &mut State<M, P>, topic_len: usize) {
    pop!(state, index: U256, len: U256);
    let data = copy_from_memory(&state.memory, index, len);
    let mut topics = Vec::new();
    for _ in 0..topic_len {
        topics.push(H256::from(state.stack.pop().unwrap()));
    }

    state.logs.push(Log {
        address: state.context.address,
        data,
        topics,
    });
}

pub fn sha3<M: Memory + Default, P: Patch>(state: &mut State<M, P>) {
    pop!(state, from: U256, len: U256);
    let data = copy_from_memory(&state.memory, from, len);
    let ret = Keccak256::digest(data.as_slice());
    push!(state, M256::from(ret.as_slice()));
}

macro_rules! try_callstack_limit {
    ( $state:expr, $patch:tt ) => {
        if $state.depth > $patch::callstack_limit() {
            push!($state, M256::zero());
            return None;
        }
    }
}

macro_rules! try_balance {
    ( $state:expr, $value:expr, $gas:expr ) => {
        if $state.account_state.balance($state.context.address).unwrap() < $value {
            push!($state, M256::zero());
            return None;
        }
    }
}

pub fn create<M: Memory + Default, P: Patch>(state: &mut State<M, P>, after_gas: Gas, is_create2: bool) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, value: U256);
    pop!(state, init_start: U256, init_len: U256);

    try_callstack_limit!(state, P);
    try_balance!(state, value, Gas::zero());

    let init = Rc::new(copy_from_memory(&state.memory, init_start, init_len));
    let transaction = if !is_create2 {
        ValidTransaction {
            caller: Some(state.context.address),
            gas_price: state.context.gas_price,
            gas_limit: l64_after_gas,
            value,
            input: init,
            action: TransactionAction::Create,
            nonce: state.account_state.nonce(state.context.address).unwrap(),
        }
    } else {
        pop!(state, salt: H256);
        let init_hash = Keccak256::digest(&init);
        let init_hash = M256::from(&init_hash[..]);
        ValidTransaction {
            caller: Some(state.context.address),
            gas_price: state.context.gas_price,
            gas_limit: l64_after_gas,
            value,
            input: init,
            action: TransactionAction::Create2(salt, init_hash),
            nonce: state.account_state.nonce(state.context.address).unwrap(),
        }
    };

    let context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();

    push!(state, context.address.into());
    Some(Control::InvokeCreate(context))
}

pub fn call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, stipend_gas: Gas, after_gas: Gas, as_self: bool) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address, value: U256);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas) + stipend_gas;

    try_callstack_limit!(state, P);
    try_balance!(state, value, gas_limit);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.address),
        gas_price: state.context.gas_price,
        gas_limit,
        value,
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let mut context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();
    if as_self {
        context.address = state.context.address;
    }

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}

pub fn static_call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, stipend_gas: Gas, after_gas: Gas) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas) + stipend_gas;

    try_callstack_limit!(state, P);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.address),
        gas_price: state.context.gas_price,
        gas_limit,
        value: U256::zero(),
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        true,
    ).unwrap();

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}

pub fn delegate_call<M: Memory + Default, P: Patch>(state: &mut State<M, P>, after_gas: Gas) -> Option<Control> {
    let l64_after_gas = if P::call_create_l64_after_gas() { l64(after_gas) } else { after_gas };

    pop!(state, gas: Gas, to: Address);
    pop!(state, in_start: U256, in_len: U256, out_start: U256, out_len: U256);
    let gas_limit = min(gas, l64_after_gas);

    try_callstack_limit!(state, P);

    let input = Rc::new(copy_from_memory(&state.memory, in_start, in_len));
    let transaction = ValidTransaction {
        caller: Some(state.context.caller),
        gas_price: state.context.gas_price,
        gas_limit,
        value: state.context.value,
        input,
        action: TransactionAction::Call(to),
        nonce: state.account_state.nonce(state.context.address).unwrap(),
    };

    let mut context = transaction.into_context::<P>(
        Gas::zero(), Some(state.context.origin), &mut state.account_state, true,
        state.context.is_static,
    ).unwrap();
    context.value = U256::zero();
    context.address = state.context.address;

    push!(state, M256::from(1u64));
    Some(Control::InvokeCall(context, (out_start, out_len)))
}
<|endoftext|>