<commit_before>// Copyright 2015 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.

//! An immutable singly-linked list, as seen in basically every functional language.

#![feature(iter_order, rc_unique)]

#![cfg_attr(test, feature(test, hash_default))]
#[cfg(test)] extern crate test;

use std::cmp::Ordering;
use std::iter;
use std::rc::Rc;
use std::hash::{Hash, Hasher};

struct Node<T> {
    elem: T,
    next: Option<Rc<Node<T>>>,
}

impl<T> Node<T> {
    fn new(elem: T) -> Node<T> {
        Node { elem: elem, next: None }
    }
}

/// An iterator over the items of an ConsList
#[derive(Clone)]
pub struct Iter<'a, T: 'a> {
    head: Option<&'a Node<T>>,
    nelem: usize,
}

/// An immutable singly-linked list, as seen in basically every functional language
pub struct ConsList<T> {
    front: Option<Rc<Node<T>>>,
    length: usize,
}

impl<T> ConsList<T> {
    /// Constructs a new, empty `ConsList`
    pub fn new () -> ConsList<T> {
        ConsList{ front: None, length: 0 }
    }

    /// Returns a copy of the list, with `elem` appended to the front
    pub fn append (&self, elem: T) -> ConsList<T>{
        let mut new_node = Node::new(elem);
        new_node.next = self.front.clone();

        ConsList{
            front: Some(Rc::new(new_node)),
            length: self.len() + 1,
        }
    }

    /// Returns a reference to the first element in the list
    pub fn head (&self) -> Option<&T> {
        self.front.as_ref().map(|node| &node.elem)
    }

    /// Returns a copy of the list, with the first element removed
    pub fn tail (&self) -> ConsList<T> {
        self.tailn(1)
    }

    /// Returns a copy of the list, with the first `n` elements removed
    pub fn tailn (&self, n: usize) -> ConsList<T> {
        if self.len() <= n {
            ConsList::new()
        } else {
            let len = self.len() - n;
            let mut head = self.front.as_ref();
            for _ in 0..n {
                head = head.unwrap().next.as_ref();
            }
            ConsList {
                front: Some(head.unwrap().clone()),
                length: len,
            }
        }
    }

    /// Returns the last element in the list
    pub fn last (&self) -> Option<&T> {
        self.iter().last()
    }

    /// Returns a copy of the list, with only the last `n` elements remaining
    pub fn lastn (&self, n: usize) -> ConsList<T> {
        if n >= self.length {
            self.clone()
        } else {
            self.tailn(self.length - n)
        }

    }

    /// Returns an iterator over references to the elements of the list in order
    pub fn iter <'a> (&'a self) -> Iter<'a, T> {
        Iter{ head: self.front.as_ref().map(|x| &**x), nelem: self.len() }
    }

    pub fn len (&self) -> usize {
        self.length
    }

    pub fn is_empty(&self) -> bool {
        return self.len() == 0
    }
}

impl<T> Drop for ConsList<T> {
    fn drop (&mut self) {
        // don't want to blow the stack with destructors,
        // but also don't want to walk the whole list.
        // So walk the list until we find a non-uniquely owned item
        let mut head = self.front.take();
        loop {
            let temp = head;
            match temp {
                Some(node) => match Rc::try_unwrap(node) {
                    Ok(mut node) => {
                        head = node.next.take();
                    }
                    _ => return,
                },
                _ => return,
            }
        }
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        match self.head.take() {
            None => None,
            Some(head) => {
                self.nelem -= 1;
                self.head = head.next.as_ref().map(|next| &**next);
                Some(&head.elem)
            }
        }
    }

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

impl<T> iter::FromIterator<T> for ConsList<T> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> ConsList<T> {
        let mut list = ConsList::new();
        for elem in iter {
            list = list.append(elem);
        }
        list
    }
}

impl<T: PartialEq> PartialEq for ConsList<T> {
    fn eq(&self, other: &ConsList<T>) -> bool {
        self.len() == other.len() &&
            std::iter::order::eq(self.iter(), other.iter())
    }

    fn ne(&self, other: &ConsList<T>) -> bool {
        self.len() != other.len() ||
            std::iter::order::ne(self.iter(), other.iter())
    }
}

impl<T: PartialOrd> PartialOrd for ConsList<T> {
    fn partial_cmp(&self, other: &ConsList<T>) -> Option<Ordering> {
        std::iter::order::partial_cmp(self.iter(), other.iter())
    }
}

impl <T> Clone for ConsList<T> {
    fn clone(&self) -> ConsList<T> {
        ConsList {
            front: self.front.clone(),
            length: self.length,
        }
    }
}

impl<T: std::fmt::Debug> std::fmt::Debug for ConsList<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "["));

        for (i, e) in self.iter().enumerate() {
            if i != 0 { try!(write!(f, ", ")); }
            try!(write!(f, "{:?}", *e));
        }

        write!(f, "]")
    }
}

impl<A: Hash> Hash for ConsList<A> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.len().hash(state);
        for elt in self.iter() {
            elt.hash(state);
        }
    }
}

impl<'a, T> IntoIterator for &'a ConsList<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;
    fn into_iter(self) -> Iter<'a, T> { self.iter() }
}

#[cfg(test)]
mod tests {
    use std::hash;

    use super::ConsList;

    #[test]
    fn test_basic() {
        let mut m = ConsList::new();
        assert_eq!(m.head(), None);
        assert_eq!(m.tail().head(), None);
        m = m.append(Box::new(1));
        assert_eq!(**m.head().unwrap(), 1);
        m = m.tail().append(Box::new(2)).append(Box::new(3));
        assert_eq!(m.len(), 2);
        assert_eq!(**m.head().unwrap(), 3);
        m = m.tail();
        assert_eq!(**m.head().unwrap(), 2);
        m = m.tail();
        assert_eq!(m.len(), 0);
        assert_eq!(m.head(), None);
        m = m.append(Box::new(7)).append(Box::new(5)).append(Box::new(3)).append(Box::new(1));
        assert_eq!(**m.head().unwrap(), 1);
    }

    #[test]
    fn test_tailn() {
        let m = list_from(&[0,1,2,3,4,5]);
        assert_eq!(m.tailn(0), m);
        assert_eq!(m.tailn(3), m.tail().tail().tail());
    }

    #[test]
    fn test_last() {
        let mut m = list_from(&[0,1,2,3,4,5]);
        assert_eq!(m.last().unwrap(), &5);

        m = ConsList::new();
        assert_eq!(m.last(), None);
    }

    #[test]
    fn test_lastn() {
        let m = list_from(&[0,1,2,3,4,5]);
        assert_eq!(m.lastn(0).head(), None);
        assert_eq!(m.lastn(8), m);
        assert_eq!(m.lastn(4), m.tail().tail());
    }

    #[cfg(test)]
    fn generate_test() -> ConsList<i32> {
        list_from(&[0,1,2,3,4,5,6])
    }

    #[cfg(test)]
    fn list_from<T: Clone>(v: &[T]) -> ConsList<T> {
        v.iter().rev().map(|x| (*x).clone()).collect()
    }

    #[test]
    fn test_iterator() {
        let m = generate_test();
        for (i, elt) in m.iter().enumerate() {
            assert_eq!(i as i32, *elt);
        }
        let mut n = ConsList::new();
        assert_eq!(n.iter().next(), None);
        n = n.append(4);
        let mut it = n.iter();
        assert_eq!(it.size_hint(), (1, Some(1)));
        assert_eq!(it.next().unwrap(), &4);
        assert_eq!(it.size_hint(), (0, Some(0)));
        assert_eq!(it.next(), None);
    }

    #[test]
    fn test_iterator_clone() {
        let mut n = ConsList::new();
        n = n.append(1).append(2).append(3);
        let mut it = n.iter();
        it.next();
        let mut jt = it.clone();
        assert_eq!(it.next(), jt.next());
        assert_eq!(it.next(), jt.next());
    }

    #[test]
    fn test_eq() {
        let mut n: ConsList<u8> = list_from(&[]);
        let mut m = list_from(&[]);
        assert!(n == m);
        n = n.append(1);
        assert!(n != m);
        m = m.append(1);
        assert!(n == m);

        let n = list_from(&[2,3,4]);
        let m = list_from(&[1,2,3]);
        assert!(n != m);
    }

    #[test]
    fn test_hash() {
      let mut x = ConsList::new();
      let mut y = ConsList::new();

      assert!(hash::hash::<_, hash::SipHasher>(&x) == hash::hash::<_, hash::SipHasher>(&y));

      x = x.append(1).append(2).append(3);
      y = y.append(1).append(4).tail().append(2).append(3);

      assert!(hash::hash::<_, hash::SipHasher>(&x) == hash::hash::<_, hash::SipHasher>(&y));
    }

    #[test]
    fn test_ord() {
        let n = list_from(&[]);
        let m = list_from(&[1,2,3]);
        assert!(n < m);
        assert!(m > n);
        assert!(n <= n);
        assert!(n >= n);
    }

    #[test]
    fn test_ord_nan() {
        let nan = 0.0f64/0.0;
        let n = list_from(&[nan]);
        let m = list_from(&[nan]);
        assert!(!(n < m));
        assert!(!(n > m));
        assert!(!(n <= m));
        assert!(!(n >= m));

        let n = list_from(&[nan]);
        let one = list_from(&[1.0f64]);
        assert!(!(n < one));
        assert!(!(n > one));
        assert!(!(n <= one));
        assert!(!(n >= one));

        let u = list_from(&[1.0f64,2.0,nan]);
        let v = list_from(&[1.0f64,2.0,3.0]);
        assert!(!(u < v));
        assert!(!(u > v));
        assert!(!(u <= v));
        assert!(!(u >= v));

        let s = list_from(&[1.0f64,2.0,4.0,2.0]);
        let t = list_from(&[1.0f64,2.0,3.0,2.0]);
        assert!(!(s < t));
        assert!(s > one);
        assert!(!(s <= one));
        assert!(s >= one);
    }

    #[test]
    fn test_debug() {
        let list: ConsList<i32> = (0..10).rev().collect();
        assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");

        let list: ConsList<&str> = vec!["just", "one", "test", "more"].iter()
                                                                   .rev()
                                                                   .map(|&s| s)
                                                                   .collect();
        assert_eq!(format!("{:?}", list), r#"["just", "one", "test", "more"]"#);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;
    use test;

    use super::ConsList;

    #[bench]
    fn bench_collect_into(b: &mut test::Bencher) {
        let v = &[0i32; 64];
        b.iter(|| {
            let _: ConsList<i32> = v.iter().map(|x| *x).collect();
        })
    }

    #[bench]
    fn bench_append(b: &mut test::Bencher) {
        let mut m: ConsList<i32> = ConsList::new();
        b.iter(|| {
            m = m.append(0);
        })
    }

    #[bench]
    fn bench_append_tail(b: &mut test::Bencher) {
        let mut m: ConsList<i32> = ConsList::new();
        b.iter(|| {
            m = m.append(0).tail();
        })
    }

    #[bench]
    fn bench_iter(b: &mut test::Bencher) {
        let v = &[0; 128];
        let m: ConsList<i32> = v.iter().map(|&x|x).collect();
        b.iter(|| {
            assert!(m.iter().count() == 128);
        })
    }
}
<commit_msg>Work with stable Rust, rustfmt<commit_after>// Copyright 2015 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.

//! An immutable singly-linked list, as seen in basically every functional language.

#![cfg_attr(test, feature(test))]
#[cfg(test)]
extern crate test;

use std::cmp::Ordering;
use std::iter;
use std::rc::Rc;
use std::hash::{Hash, Hasher};

struct Node<T> {
    elem: T,
    next: Option<Rc<Node<T>>>,
}

impl<T> Node<T> {
    fn new(elem: T) -> Node<T> {
        Node {
            elem: elem,
            next: None,
        }
    }
}

/// An iterator over the items of an ConsList
#[derive(Clone)]
pub struct Iter<'a, T: 'a> {
    head: Option<&'a Node<T>>,
    nelem: usize,
}

/// An immutable singly-linked list, as seen in basically every functional language
pub struct ConsList<T> {
    front: Option<Rc<Node<T>>>,
    length: usize,
}

impl<T> ConsList<T> {
    /// Constructs a new, empty `ConsList`
    pub fn new() -> ConsList<T> {
        ConsList {
            front: None,
            length: 0,
        }
    }

    /// Returns a copy of the list, with `elem` appended to the front
    pub fn append(&self, elem: T) -> ConsList<T> {
        let mut new_node = Node::new(elem);
        new_node.next = self.front.clone();

        ConsList {
            front: Some(Rc::new(new_node)),
            length: self.len() + 1,
        }
    }

    /// Returns a reference to the first element in the list
    pub fn head(&self) -> Option<&T> {
        self.front.as_ref().map(|node| &node.elem)
    }

    /// Returns a copy of the list, with the first element removed
    pub fn tail(&self) -> ConsList<T> {
        self.tailn(1)
    }

    /// Returns a copy of the list, with the first `n` elements removed
    pub fn tailn(&self, n: usize) -> ConsList<T> {
        if self.len() <= n {
            ConsList::new()
        } else {
            let len = self.len() - n;
            let mut head = self.front.as_ref();
            for _ in 0..n {
                head = head.unwrap().next.as_ref();
            }
            ConsList {
                front: Some(head.unwrap().clone()),
                length: len,
            }
        }
    }

    /// Returns the last element in the list
    pub fn last(&self) -> Option<&T> {
        self.iter().last()
    }

    /// Returns a copy of the list, with only the last `n` elements remaining
    pub fn lastn(&self, n: usize) -> ConsList<T> {
        if n >= self.length {
            self.clone()
        } else {
            self.tailn(self.length - n)
        }

    }

    /// Returns an iterator over references to the elements of the list in order
    pub fn iter<'a>(&'a self) -> Iter<'a, T> {
        Iter {
            head: self.front.as_ref().map(|x| &**x),
            nelem: self.len(),
        }
    }

    pub fn len(&self) -> usize {
        self.length
    }

    pub fn is_empty(&self) -> bool {
        return self.len() == 0;
    }
}

impl<T> Drop for ConsList<T> {
    fn drop(&mut self) {
        // don't want to blow the stack with destructors,
        // but also don't want to walk the whole list.
        // So walk the list until we find a non-uniquely owned item
        let mut head = self.front.take();
        loop {
            let temp = head;
            match temp {
                Some(node) => {
                    match Rc::try_unwrap(node) {
                        Ok(mut node) => {
                            head = node.next.take();
                        }
                        _ => return,
                    }
                }
                _ => return,
            }
        }
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        match self.head.take() {
            None => None,
            Some(head) => {
                self.nelem -= 1;
                self.head = head.next.as_ref().map(|next| &**next);
                Some(&head.elem)
            }
        }
    }

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

impl<T> iter::FromIterator<T> for ConsList<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> ConsList<T> {
        let mut list = ConsList::new();
        for elem in iter {
            list = list.append(elem);
        }
        list
    }
}

impl<T: PartialEq> PartialEq for ConsList<T> {
    fn eq(&self, other: &ConsList<T>) -> bool {
        self.len() == other.len() && self.iter().zip(other.iter()).all(|(x, y)| x == y)
    }

    fn ne(&self, other: &ConsList<T>) -> bool {
        self.len() != other.len() || self.iter().zip(other.iter()).all(|(x, y)| x != y)
    }
}

impl<T: PartialOrd> PartialOrd for ConsList<T> {
    fn partial_cmp(&self, other: &ConsList<T>) -> Option<Ordering> {
        let mut a = self.iter();
        let mut b = other.iter();
        loop {
            match (a.next(), b.next()) {
                (None, None) => return Some(std::cmp::Ordering::Equal),
                (None, _) => return Some(std::cmp::Ordering::Less),
                (_, None) => return Some(std::cmp::Ordering::Greater),
                (Some(x), Some(y)) => {
                    match x.partial_cmp(&y) {
                        Some(std::cmp::Ordering::Equal) => (),
                        non_eq => return non_eq,
                    }
                }
            }
        }
    }
}

impl<T> Clone for ConsList<T> {
    fn clone(&self) -> ConsList<T> {
        ConsList {
            front: self.front.clone(),
            length: self.length,
        }
    }
}

impl<T: std::fmt::Debug> std::fmt::Debug for ConsList<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "["));

        for (i, e) in self.iter().enumerate() {
            if i != 0 {
                try!(write!(f, ", "));
            }
            try!(write!(f, "{:?}", *e));
        }

        write!(f, "]")
    }
}

impl<A: Hash> Hash for ConsList<A> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.len().hash(state);
        for elt in self.iter() {
            elt.hash(state);
        }
    }
}

impl<'a, T> IntoIterator for &'a ConsList<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;
    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

#[cfg(test)]
mod tests {
    use std::hash;

    use super::ConsList;

    #[test]
    fn test_basic() {
        let mut m = ConsList::new();
        assert_eq!(m.head(), None);
        assert_eq!(m.tail().head(), None);
        m = m.append(Box::new(1));
        assert_eq!(**m.head().unwrap(), 1);
        m = m.tail().append(Box::new(2)).append(Box::new(3));
        assert_eq!(m.len(), 2);
        assert_eq!(**m.head().unwrap(), 3);
        m = m.tail();
        assert_eq!(**m.head().unwrap(), 2);
        m = m.tail();
        assert_eq!(m.len(), 0);
        assert_eq!(m.head(), None);
        m = m.append(Box::new(7)).append(Box::new(5)).append(Box::new(3)).append(Box::new(1));
        assert_eq!(**m.head().unwrap(), 1);
    }

    #[test]
    fn test_tailn() {
        let m = list_from(&[0, 1, 2, 3, 4, 5]);
        assert_eq!(m.tailn(0), m);
        assert_eq!(m.tailn(3), m.tail().tail().tail());
    }

    #[test]
    fn test_last() {
        let mut m = list_from(&[0, 1, 2, 3, 4, 5]);
        assert_eq!(m.last().unwrap(), &5);

        m = ConsList::new();
        assert_eq!(m.last(), None);
    }

    #[test]
    fn test_lastn() {
        let m = list_from(&[0, 1, 2, 3, 4, 5]);
        assert_eq!(m.lastn(0).head(), None);
        assert_eq!(m.lastn(8), m);
        assert_eq!(m.lastn(4), m.tail().tail());
    }

    #[cfg(test)]
    fn generate_test() -> ConsList<i32> {
        list_from(&[0, 1, 2, 3, 4, 5, 6])
    }

    #[cfg(test)]
    fn list_from<T: Clone>(v: &[T]) -> ConsList<T> {
        v.iter().rev().map(|x| (*x).clone()).collect()
    }

    #[test]
    fn test_iterator() {
        let m = generate_test();
        for (i, elt) in m.iter().enumerate() {
            assert_eq!(i as i32, *elt);
        }
        let mut n = ConsList::new();
        assert_eq!(n.iter().next(), None);
        n = n.append(4);
        let mut it = n.iter();
        assert_eq!(it.size_hint(), (1, Some(1)));
        assert_eq!(it.next().unwrap(), &4);
        assert_eq!(it.size_hint(), (0, Some(0)));
        assert_eq!(it.next(), None);
    }

    #[test]
    fn test_iterator_clone() {
        let mut n = ConsList::new();
        n = n.append(1).append(2).append(3);
        let mut it = n.iter();
        it.next();
        let mut jt = it.clone();
        assert_eq!(it.next(), jt.next());
        assert_eq!(it.next(), jt.next());
    }

    #[test]
    fn test_eq() {
        let mut n: ConsList<u8> = list_from(&[]);
        let mut m = list_from(&[]);
        assert!(n == m);
        n = n.append(1);
        assert!(n != m);
        m = m.append(1);
        assert!(n == m);

        let n = list_from(&[2, 3, 4]);
        let m = list_from(&[1, 2, 3]);
        assert!(n != m);
    }

    #[test]
    fn test_hash() {
        let mut x = ConsList::new();
        let mut y = ConsList::new();

        let mut h = hash::SipHasher::new();

        assert!(hash::Hash::hash(&x, &mut h) == hash::Hash::hash(&y, &mut h));

        x = x.append(1).append(2).append(3);
        y = y.append(1).append(4).tail().append(2).append(3);

        assert!(hash::Hash::hash(&x, &mut h) == hash::Hash::hash(&y, &mut h));
    }

    #[test]
    fn test_ord() {
        let n = list_from(&[]);
        let m = list_from(&[1, 2, 3]);
        assert!(n < m);
        assert!(m > n);
        assert!(n <= n);
        assert!(n >= n);
    }

    #[test]
    fn test_ord_nan() {
        let nan = 0.0f64 / 0.0;
        let n = list_from(&[nan]);
        let m = list_from(&[nan]);
        assert!(!(n < m));
        assert!(!(n > m));
        assert!(!(n <= m));
        assert!(!(n >= m));

        let n = list_from(&[nan]);
        let one = list_from(&[1.0f64]);
        assert!(!(n < one));
        assert!(!(n > one));
        assert!(!(n <= one));
        assert!(!(n >= one));

        let u = list_from(&[1.0f64, 2.0, nan]);
        let v = list_from(&[1.0f64, 2.0, 3.0]);
        assert!(!(u < v));
        assert!(!(u > v));
        assert!(!(u <= v));
        assert!(!(u >= v));

        let s = list_from(&[1.0f64, 2.0, 4.0, 2.0]);
        let t = list_from(&[1.0f64, 2.0, 3.0, 2.0]);
        assert!(!(s < t));
        assert!(s > one);
        assert!(!(s <= one));
        assert!(s >= one);
    }

    #[test]
    fn test_debug() {
        let list: ConsList<i32> = (0..10).rev().collect();
        assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");

        let list: ConsList<&str> = vec!["just", "one", "test", "more"]
            .iter()
            .rev()
            .map(|&s| s)
            .collect();
        assert_eq!(format!("{:?}", list), r#"["just", "one", "test", "more"]"#);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;
    use test;

    use super::ConsList;

    #[bench]
    fn bench_collect_into(b: &mut test::Bencher) {
        let v = &[0i32; 64];
        b.iter(|| { let _: ConsList<i32> = v.iter().map(|x| *x).collect(); })
    }

    #[bench]
    fn bench_append(b: &mut test::Bencher) {
        let mut m: ConsList<i32> = ConsList::new();
        b.iter(|| { m = m.append(0); })
    }

    #[bench]
    fn bench_append_tail(b: &mut test::Bencher) {
        let mut m: ConsList<i32> = ConsList::new();
        b.iter(|| { m = m.append(0).tail(); })
    }

    #[bench]
    fn bench_iter(b: &mut test::Bencher) {
        let v = &[0; 128];
        let m: ConsList<i32> = v.iter().map(|&x| x).collect();
        b.iter(|| {
                   assert!(m.iter().count() == 128);
               })
    }
}

<|endoftext|>


<commit_before>#![feature(collections)]

#[macro_use] mod macros;
mod std_impls;

pub trait Collection {
    /// Removes all items from the collection.
    fn clear(&mut self);

    /// Checks if the collection is empty.
    fn is_empty(&self) -> bool { self.len() == 0 }

    /// Returns the number of items in the collection.
    fn len(&self) -> usize;
}

pub trait Map: Collection + MapLookup<<Self as Map>::Key, MapValue=<Self as Map>::Value> {
    /// The map's key type.
    type Key;
    /// The map's value type.
    type Value;

    /// Inserts the given key and value into the map, returning the previous value associated with
    /// the key, or `None` if the map did not already contain the key.
    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
}

pub trait MapLookup<Q: ?Sized> {
    type MapValue;

    /// Checks if the map contains the given key.
    fn contains_key(&self, key: &Q) -> bool { self.get(key).is_some() }

    /// Returns a reference to the value associated with the given key in the map, or `None` if
    /// the map does not contain the key.
    fn get(&self, key: &Q) -> Option<&Self::MapValue>;

    /// Returns a mutable reference to the value associated with the given key in the map, or
    /// `None` if the map does not contain the key.
    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::MapValue>;

    /// Removes the given key from the map, returning the value associated with it, or `None` if
    /// the map did not contain the key.
    fn remove(&mut self, key: &Q) -> Option<Self::MapValue>;
}

pub trait EntryMap<'a>: Map {
    type Occupied: OccupiedEntry<'a, Value=Self::Value>;
    type Vacant: VacantEntry<'a, Value=Self::Value>;

    /// Returns the given key's corresponding entry in the map for in-place manipulation.
    fn entry(&'a mut self, key: Self::Key) -> Entry<Self::Occupied, Self::Vacant>;
}

pub enum Entry<O, V> {
    Occupied(O),
    Vacant(V),
}

impl<'a, O, V> Entry<O, V> where O: OccupiedEntry<'a>, V: VacantEntry<'a, Value=O::Value> {
    /// Returns a mutable reference to the entry's value if it is occupied, or the vacant entry if
    /// it is vacant.
    pub fn get(self) -> Result<&'a mut O::Value, V> {
        match self {
            Entry::Occupied(e) => Ok(e.into_mut()),
            Entry::Vacant(e) => Err(e),
        }
    }

    /// Ensures that a value is in the entry by inserting the default if it is empty, and returns a
    /// mutable reference to the value.
    pub fn or_insert(self, default: O::Value) -> &'a mut O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default),
        }
    }

    /// Ensures that a value is in the entry by inserting the result of the default function if it
    /// is empty, and returns a mutable reference to the value.
    pub fn or_insert_with<F>(self, default: F) -> &'a mut O::Value where F: FnOnce() -> O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default()),
        }
    }
}

pub trait OccupiedEntry<'a> {
    type Value: 'a;

    /// Returns a reference to the entry's value.
    fn get(&self) -> &Self::Value;

    /// Returns a mutable reference to the entry's value.
    fn get_mut(&mut self) -> &mut Self::Value;

    /// Sets the entry's value to the given one, returning the old value.
    fn insert(&mut self, value: Self::Value) -> Self::Value;

    /// Returns a mutable reference to the entry's value with the lifetime of the map.
    fn into_mut(self) -> &'a mut Self::Value;

    /// Removes the entry, returning its value.
    fn remove(self) -> Self::Value;
}

pub trait VacantEntry<'a> {
    type Value: 'a;

    /// Sets the entry's value to the given one, returning a mutable reference to the value with
    /// the lifetime of the map.
    fn insert(self, value: Self::Value) -> &'a mut Self::Value;
}

pub trait Set: Collection + SetLookup<<Self as Set>::Item> {
    type Item;

    /// Inserts the given item into the set, returning `true` if the set did not already contain
    /// the item.
    fn insert(&mut self, item: Self::Item) -> bool;
}

pub trait SetLookup<Q: ?Sized> {
    /// Checks if the set contains the given item.
    fn contains(&self, item: &Q) -> bool;

    /// Removes the given item from the set, returning `true` if the set contained the item.
    fn remove(&mut self, item: &Q) -> bool;
}
<commit_msg>document remaining items<commit_after>#![feature(collections)]

#[macro_use] mod macros;
mod std_impls;

/// A collection.
pub trait Collection {
    /// Removes all items from the collection.
    fn clear(&mut self);

    /// Checks if the collection is empty.
    fn is_empty(&self) -> bool { self.len() == 0 }

    /// Returns the number of items in the collection.
    fn len(&self) -> usize;
}

/// A map.
pub trait Map: Collection + MapLookup<<Self as Map>::Key, MapValue=<Self as Map>::Value> {
    /// The map's key type.
    type Key;
    /// The map's value type.
    type Value;

    /// Inserts the given key and value into the map, returning the previous value associated with
    /// the key, or `None` if the map did not already contain the key.
    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
}

/// A map that supports alternate key lookups.
pub trait MapLookup<Q: ?Sized> {
    type MapValue;

    /// Checks if the map contains the given key.
    fn contains_key(&self, key: &Q) -> bool { self.get(key).is_some() }

    /// Returns a reference to the value associated with the given key in the map, or `None` if
    /// the map does not contain the key.
    fn get(&self, key: &Q) -> Option<&Self::MapValue>;

    /// Returns a mutable reference to the value associated with the given key in the map, or
    /// `None` if the map does not contain the key.
    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::MapValue>;

    /// Removes the given key from the map, returning the value associated with it, or `None` if
    /// the map did not contain the key.
    fn remove(&mut self, key: &Q) -> Option<Self::MapValue>;
}

/// A map that supports the entry API.
pub trait EntryMap<'a>: Map {
    /// The occupied entry type.
    type Occupied: OccupiedEntry<'a, Value=Self::Value>;

    /// The vacant entry type.
    type Vacant: VacantEntry<'a, Value=Self::Value>;

    /// Returns the given key's corresponding entry in the map for in-place manipulation.
    fn entry(&'a mut self, key: Self::Key) -> Entry<Self::Occupied, Self::Vacant>;
}

/// A map entry.
pub enum Entry<O, V> {
    /// An occupied entry.
    Occupied(O),
    /// A vacant entry.
    Vacant(V),
}

impl<'a, O, V> Entry<O, V> where O: OccupiedEntry<'a>, V: VacantEntry<'a, Value=O::Value> {
    /// Returns a mutable reference to the entry's value if it is occupied, or the vacant entry if
    /// it is vacant.
    pub fn get(self) -> Result<&'a mut O::Value, V> {
        match self {
            Entry::Occupied(e) => Ok(e.into_mut()),
            Entry::Vacant(e) => Err(e),
        }
    }

    /// Ensures that a value is in the entry by inserting the default if it is empty, and returns a
    /// mutable reference to the value.
    pub fn or_insert(self, default: O::Value) -> &'a mut O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default),
        }
    }

    /// Ensures that a value is in the entry by inserting the result of the default function if it
    /// is empty, and returns a mutable reference to the value.
    pub fn or_insert_with<F>(self, default: F) -> &'a mut O::Value where F: FnOnce() -> O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default()),
        }
    }
}

/// An occupied map entry.
pub trait OccupiedEntry<'a> {
    /// The entry's value type.
    type Value: 'a;

    /// Returns a reference to the entry's value.
    fn get(&self) -> &Self::Value;

    /// Returns a mutable reference to the entry's value.
    fn get_mut(&mut self) -> &mut Self::Value;

    /// Sets the entry's value to the given one, returning the old value.
    fn insert(&mut self, value: Self::Value) -> Self::Value;

    /// Returns a mutable reference to the entry's value with the lifetime of the map.
    fn into_mut(self) -> &'a mut Self::Value;

    /// Removes the entry, returning its value.
    fn remove(self) -> Self::Value;
}

/// A vacant map entry.
pub trait VacantEntry<'a> {
    /// The entry's value type.
    type Value: 'a;

    /// Sets the entry's value to the given one, returning a mutable reference to the value with
    /// the lifetime of the map.
    fn insert(self, value: Self::Value) -> &'a mut Self::Value;
}

/// A set.
pub trait Set: Collection + SetLookup<<Self as Set>::Item> {
    /// The set's item type.
    type Item;

    /// Inserts the given item into the set, returning `true` if the set did not already contain
    /// the item.
    fn insert(&mut self, item: Self::Item) -> bool;
}

/// A set that supports alternate item lookups.
pub trait SetLookup<Q: ?Sized> {
    /// Checks if the set contains the given item.
    fn contains(&self, item: &Q) -> bool;

    /// Removes the given item from the set, returning `true` if the set contained the item.
    fn remove(&mut self, item: &Q) -> bool;
}
<|endoftext|>


<commit_before>extern crate exempi_sys as c;
extern crate libc;
#[macro_use]
extern crate bitflags;

mod xmp;
mod xmpfile;
mod xmpiterator;
mod xmpstring;

use std::cmp::Ordering;
use std::ffi::CString;
use std::mem::transmute;
use std::result;
use std::sync::{Once, ONCE_INIT};

pub use c::consts::*;
pub use c::FileType;
pub use c::TzSign as XmpTzSign;
pub use c::XmpError as Error;
pub use xmp::Xmp;
pub use xmpfile::XmpFile;
pub use xmpiterator::XmpIterator;
pub use xmpstring::XmpString;
// all the flags.
pub use xmp::flags::*;
pub use xmpfile::flags::*;
pub use xmpiterator::flags::*;

/// Result type
pub type Result<T> = result::Result<T, Error>;

static START: Once = ONCE_INIT;

/// Initialize the library.
///
/// This will ensure xmp_init() is called only once so that
/// concurrent calls are exclusive.
pub fn init() -> bool {
    let mut inited = true;
    START.call_once(|| {
        // run initialization here
        inited = unsafe { c::xmp_init() };
    });
    inited
}

/// Force initialize the library.
///
/// Can be safely called more than once or after `init()`
/// but can't be called concurrently from different threads.
pub fn force_init() -> bool {
    unsafe { c::xmp_init() }
}

/// Terminate the library. (use is discouraged)
///
/// As a side effect, you can't counter balance it with a `init()`
/// hence its use is discouraged.
pub fn terminate() {
    unsafe { c::xmp_terminate() }
}

/// Get the last error code on the thread
/// Set when a function return false or None.
pub fn get_error() -> Error {
    let err = unsafe { c::xmp_get_error() };
    match err {
        -15...0 | -110...-101 | -211...-201 => unsafe { transmute(err) },
        _ => Error::TBD,
    }
}

/// Register namespace with uri and suggested prefix
/// Returns the actual registered prefix.
pub fn register_namespace(uri: &str, prefix: &str) -> Option<XmpString> {
    let s_uri = CString::new(uri).unwrap();
    let s_prefix = CString::new(prefix).unwrap();
    let mut reg_prefix = XmpString::new();
    if unsafe {
        c::xmp_register_namespace(s_uri.as_ptr(), s_prefix.as_ptr(), reg_prefix.as_mut_ptr())
    } {
        Some(reg_prefix)
    } else {
        None
    }
}

/// Return the prefix for the namespace uri.
pub fn namespace_prefix(uri: &str) -> Option<XmpString> {
    let s = CString::new(uri).unwrap();
    let mut prefix = XmpString::new();
    if unsafe { c::xmp_namespace_prefix(s.as_ptr(), prefix.as_mut_ptr()) } {
        Some(prefix)
    } else {
        None
    }
}

/// Return the namespace uri for the prefix.
pub fn prefix_namespace(prefix: &str) -> Option<XmpString> {
    let s = CString::new(prefix).unwrap();
    let mut uri = XmpString::new();
    if unsafe { c::xmp_prefix_namespace_uri(s.as_ptr(), uri.as_mut_ptr()) } {
        Some(uri)
    } else {
        None
    }
}

/// A wrapper around the C type DateTime
#[derive(Clone, Debug, Default)]
pub struct DateTime(c::XmpDateTime);

impl DateTime {
    pub fn new() -> Self {
        DateTime::default()
    }
    /// Construct from the native C type
    pub fn from(d: c::XmpDateTime) -> DateTime {
        DateTime(d)
    }
    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpDateTime {
        &self.0 as *const c::XmpDateTime
    }
    /// Return the native mutable pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpDateTime {
        &mut self.0 as *mut c::XmpDateTime
    }
    /// Set date
    pub fn set_date(&mut self, year: i32, month: i32, day: i32) {
        self.0.year = year;
        self.0.month = month;
        self.0.day = day;
        self.0.has_date = 1;
    }
    /// Set time
    pub fn set_time(&mut self, hour: i32, min: i32, sec: i32) {
        self.0.hour = hour;
        self.0.minute = min;
        self.0.second = sec;
        self.0.has_time = 1;
    }
    /// Set nano_second
    pub fn set_nano_second(&mut self, nano_second: i32) {
        self.0.nano_second = nano_second;
    }
    /// Set Timezone
    pub fn set_timezone(&mut self, sign: XmpTzSign, hour: i32, min: i32) {
        self.0.tz_sign = sign;
        self.0.tz_hour = hour;
        self.0.tz_minute = min;
        self.0.has_tz = 1;
    }
    pub fn year(&self) -> i32 {
        self.0.year
    }
    pub fn month(&self) -> i32 {
        self.0.month
    }
    pub fn day(&self) -> i32 {
        self.0.day
    }
    pub fn hour(&self) -> i32 {
        self.0.hour
    }
    pub fn minute(&self) -> i32 {
        self.0.minute
    }
    pub fn second(&self) -> i32 {
        self.0.second
    }
    pub fn nano_second(&self) -> i32 {
        self.0.nano_second
    }
}

impl PartialEq for DateTime {
    fn eq(&self, other: &DateTime) -> bool {
        unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            ) == 0
        }
    }
}
impl PartialOrd for DateTime {
    fn partial_cmp(&self, other: &DateTime) -> Option<Ordering> {
        match unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            )
        } {
            0 => Some(Ordering::Equal),
            n if n < 0 => Some(Ordering::Less),
            n if n > 0 => Some(Ordering::Greater),
            _ => None,
        }
    }
}
impl Eq for DateTime {}
impl Ord for DateTime {
    fn cmp(&self, other: &DateTime) -> Ordering {
        match unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            )
        } {
            n if n < 0 => Ordering::Less,
            n if n > 0 => Ordering::Greater,
            _ => Ordering::Equal,
        }
    }
}
<commit_msg>Fix Rust deprecations<commit_after>extern crate exempi_sys as c;
extern crate libc;
#[macro_use]
extern crate bitflags;

mod xmp;
mod xmpfile;
mod xmpiterator;
mod xmpstring;

use std::cmp::Ordering;
use std::ffi::CString;
use std::mem::transmute;
use std::result;
use std::sync::Once;

pub use c::consts::*;
pub use c::FileType;
pub use c::TzSign as XmpTzSign;
pub use c::XmpError as Error;
pub use xmp::Xmp;
pub use xmpfile::XmpFile;
pub use xmpiterator::XmpIterator;
pub use xmpstring::XmpString;
// all the flags.
pub use xmp::flags::*;
pub use xmpfile::flags::*;
pub use xmpiterator::flags::*;

/// Result type
pub type Result<T> = result::Result<T, Error>;

static START: Once = Once::new();

/// Initialize the library.
///
/// This will ensure xmp_init() is called only once so that
/// concurrent calls are exclusive.
pub fn init() -> bool {
    let mut inited = true;
    START.call_once(|| {
        // run initialization here
        inited = unsafe { c::xmp_init() };
    });
    inited
}

/// Force initialize the library.
///
/// Can be safely called more than once or after `init()`
/// but can't be called concurrently from different threads.
pub fn force_init() -> bool {
    unsafe { c::xmp_init() }
}

/// Terminate the library. (use is discouraged)
///
/// As a side effect, you can't counter balance it with a `init()`
/// hence its use is discouraged.
pub fn terminate() {
    unsafe { c::xmp_terminate() }
}

/// Get the last error code on the thread
/// Set when a function return false or None.
pub fn get_error() -> Error {
    let err = unsafe { c::xmp_get_error() };
    match err {
        -15..=0 | -110..=-101 | -211..=-201 => unsafe { transmute(err) },
        _ => Error::TBD,
    }
}

/// Register namespace with uri and suggested prefix
/// Returns the actual registered prefix.
pub fn register_namespace(uri: &str, prefix: &str) -> Option<XmpString> {
    let s_uri = CString::new(uri).unwrap();
    let s_prefix = CString::new(prefix).unwrap();
    let mut reg_prefix = XmpString::new();
    if unsafe {
        c::xmp_register_namespace(s_uri.as_ptr(), s_prefix.as_ptr(), reg_prefix.as_mut_ptr())
    } {
        Some(reg_prefix)
    } else {
        None
    }
}

/// Return the prefix for the namespace uri.
pub fn namespace_prefix(uri: &str) -> Option<XmpString> {
    let s = CString::new(uri).unwrap();
    let mut prefix = XmpString::new();
    if unsafe { c::xmp_namespace_prefix(s.as_ptr(), prefix.as_mut_ptr()) } {
        Some(prefix)
    } else {
        None
    }
}

/// Return the namespace uri for the prefix.
pub fn prefix_namespace(prefix: &str) -> Option<XmpString> {
    let s = CString::new(prefix).unwrap();
    let mut uri = XmpString::new();
    if unsafe { c::xmp_prefix_namespace_uri(s.as_ptr(), uri.as_mut_ptr()) } {
        Some(uri)
    } else {
        None
    }
}

/// A wrapper around the C type DateTime
#[derive(Clone, Debug, Default)]
pub struct DateTime(c::XmpDateTime);

impl DateTime {
    pub fn new() -> Self {
        DateTime::default()
    }
    /// Construct from the native C type
    pub fn from(d: c::XmpDateTime) -> DateTime {
        DateTime(d)
    }
    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpDateTime {
        &self.0 as *const c::XmpDateTime
    }
    /// Return the native mutable pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpDateTime {
        &mut self.0 as *mut c::XmpDateTime
    }
    /// Set date
    pub fn set_date(&mut self, year: i32, month: i32, day: i32) {
        self.0.year = year;
        self.0.month = month;
        self.0.day = day;
        self.0.has_date = 1;
    }
    /// Set time
    pub fn set_time(&mut self, hour: i32, min: i32, sec: i32) {
        self.0.hour = hour;
        self.0.minute = min;
        self.0.second = sec;
        self.0.has_time = 1;
    }
    /// Set nano_second
    pub fn set_nano_second(&mut self, nano_second: i32) {
        self.0.nano_second = nano_second;
    }
    /// Set Timezone
    pub fn set_timezone(&mut self, sign: XmpTzSign, hour: i32, min: i32) {
        self.0.tz_sign = sign;
        self.0.tz_hour = hour;
        self.0.tz_minute = min;
        self.0.has_tz = 1;
    }
    pub fn year(&self) -> i32 {
        self.0.year
    }
    pub fn month(&self) -> i32 {
        self.0.month
    }
    pub fn day(&self) -> i32 {
        self.0.day
    }
    pub fn hour(&self) -> i32 {
        self.0.hour
    }
    pub fn minute(&self) -> i32 {
        self.0.minute
    }
    pub fn second(&self) -> i32 {
        self.0.second
    }
    pub fn nano_second(&self) -> i32 {
        self.0.nano_second
    }
}

impl PartialEq for DateTime {
    fn eq(&self, other: &DateTime) -> bool {
        unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            ) == 0
        }
    }
}
impl PartialOrd for DateTime {
    fn partial_cmp(&self, other: &DateTime) -> Option<Ordering> {
        match unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            )
        } {
            0 => Some(Ordering::Equal),
            n if n < 0 => Some(Ordering::Less),
            n if n > 0 => Some(Ordering::Greater),
            _ => None,
        }
    }
}
impl Eq for DateTime {}
impl Ord for DateTime {
    fn cmp(&self, other: &DateTime) -> Ordering {
        match unsafe {
            c::xmp_datetime_compare(
                &self.0 as *const c::XmpDateTime,
                &other.0 as *const c::XmpDateTime,
            )
        } {
            n if n < 0 => Ordering::Less,
            n if n > 0 => Ordering::Greater,
            _ => Ordering::Equal,
        }
    }
}
<|endoftext|>


<commit_before>use std::ptr;

pub type TssFlag = u32;
pub type TssHObject = u32;
pub type TssHContext = TssHObject;
pub type TssHTPM = TssHObject;
pub type TssHPCRS = TssHObject;
pub type TssResult = u32;
pub type TssUnicode = u16;

pub const TSS_SUCCESS: TssResult = 0;

const TSS_OBJECT_TYPE_PCRS: TssFlag = 4;

const TSS_PCRS_STRUCT_DEFAULT: TssFlag = 0;
const TSS_PCRS_STRUCT_INFO: TssFlag = 1;
const TSS_PCRS_STRUCT_INFO_LONG: TssFlag = 2;
const TSS_PCRS_STRUCT_INFO_SHORT: TssFlag = 3;

pub enum TssPcrsStructType {
    Default, Info, InfoLong, InfoShort
}

pub struct TssContext {
    pub handle: u32
}
pub struct TssTPM<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}
pub struct TssPCRComposite<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Close(hContext: TssHContext) -> TssResult;
    fn Tspi_Context_Connect(hContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_FreeMemory(hContext: TssHContext, rgbMemory: *mut u8) -> TssResult;
    fn Tspi_Context_CreateObject(hContext: TssHContext, objectType: TssFlag, initFlags: TssFlag, phObject: *mut TssHObject) -> TssResult;
    fn Tspi_Context_GetTpmObject(hContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_TPM_PcrRead(hTPM: TssHTPM, ulPcrIndex: u32, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
    fn Tspi_TPM_PcrExtend(hTPM: TssHTPM, ulPcrIndex: u32, ulPcrDataLength: u32, pbPcrData: *const u8, pPcrEvent: *mut u8, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
    fn Tspi_TPM_PcrReset(hTPM: TssHTPM, hPcrComposite: TssHPCRS) -> TssResult;
}

impl TssContext {
    pub fn new() -> Result<TssContext, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_Create(&mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssContext { handle: handle })
    }

    // TODO: support destination
    pub fn connect(&self) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_Context_Connect(self.handle, ptr::null())
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }

    pub fn get_tpm_object(&self) -> Result<TssTPM, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_GetTpmObject(self.handle, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssTPM { context: self, handle: handle })
    }

    // TODO: Should selecting an index be tied into actually creating the PCRS object?
    pub fn create_pcr_composite(&self, pcrs_type: TssPcrsStructType) -> Result<TssPCRComposite, TssResult> {
        let mut handle = 0;
        // Do it as a <> instead? Would mean we can actually make functions taking *only* PCR
        // composite objects that are supported by the function!
        // e.g. Tspi_PcrComposite_SelectPcrIndex only supports TCPA_PCR_INFO structures
        // Maybe do 1.2 structures as an enum...
        let init_flags = match pcrs_type {
            TssPcrsStructType::Default => TSS_PCRS_STRUCT_DEFAULT,
            TssPcrsStructType::Info => TSS_PCRS_STRUCT_INFO,
            TssPcrsStructType::InfoLong => TSS_PCRS_STRUCT_INFO_LONG,
            TssPcrsStructType::InfoShort => TSS_PCRS_STRUCT_INFO_SHORT
        };
        let result = unsafe {
            Tspi_Context_CreateObject(self.handle, TSS_OBJECT_TYPE_PCRS, init_flags, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssPCRComposite { context: self, handle: handle })
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_FreeMemory(self.handle, 0 as *mut u8);
            Tspi_Context_Close(self.handle);
        }
    }
}

impl<'context> TssTPM<'context> {
    pub fn pcr_read(&self, pcr_index: u32) -> Result<Vec<u8>, TssResult> {
        let mut pcr_value_length = 0;
        let mut pcr_value_ptr = 0 as *mut u8;
        let result = unsafe {
            Tspi_TPM_PcrRead(self.handle, pcr_index, &mut pcr_value_length, &mut pcr_value_ptr)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        let mut vec = Vec::new();
        unsafe {
            for i in 0..pcr_value_length {
                // TODO: Is this isize cast safe?
                vec.push(*pcr_value_ptr.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pcr_value_ptr);
        }
        Ok(vec)
    }

    // TODO: events
    pub fn pcr_extend(&self, pcr_index: u32, data: &[u8]) -> Result<Vec<u8>, TssResult> {
        let mut pcr_value_length = 0;
        let mut pcr_value_ptr = 0 as *mut u8;
        let result = unsafe {
            // TODO: Is this u32 cast safe?
            Tspi_TPM_PcrExtend(self.handle, pcr_index, data.len() as u32, data.as_ptr(), 0 as *mut u8, &mut pcr_value_length, &mut pcr_value_ptr)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        // TODO: DRY with above
        let mut vec = Vec::new();
        unsafe {
            for i in 0..pcr_value_length {
                // TODO: Is this isize cast safe?
                vec.push(*pcr_value_ptr.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pcr_value_ptr);
        }
        Ok(vec)
    }

    pub fn pcr_reset(&self, pcr_composite: TssPCRComposite) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_TPM_PcrReset(self.handle, pcr_composite.handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }
}

impl<'context> TssPCRComposite<'context> {
}
<commit_msg>Use traits for PCRS so we can restrict with function signatures<commit_after>use std::ptr;

pub type TssFlag = u32;
pub type TssHObject = u32;
pub type TssHContext = TssHObject;
pub type TssHTPM = TssHObject;
pub type TssHPCRS = TssHObject;
pub type TssResult = u32;
pub type TssUnicode = u16;

pub const TSS_SUCCESS: TssResult = 0;

const TSS_OBJECT_TYPE_PCRS: TssFlag = 4;

const TSS_PCRS_STRUCT_DEFAULT: TssFlag = 0;
const TSS_PCRS_STRUCT_INFO: TssFlag = 1;
const TSS_PCRS_STRUCT_INFO_LONG: TssFlag = 2;
const TSS_PCRS_STRUCT_INFO_SHORT: TssFlag = 3;

pub struct TssContext {
    pub handle: u32
}
pub struct TssTPM<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}

pub enum TssPcrsStructType {
    Default, Info, InfoLong, InfoShort
}

pub struct TssPCRCompositeInfo<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}
pub struct TssPCRCompositeInfoLong<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}
pub struct TssPCRCompositeInfoShort<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}
pub trait TcpaPcrInfoAny {
    fn get_handle(&self) -> u32;
}
pub trait TcpaPcrInfo1_1 : TcpaPcrInfoAny {
    fn get_handle(&self) -> u32;
}
pub trait TcpaPcrInfo1_2 : TcpaPcrInfoAny {
    fn get_handle(&self) -> u32;
}
impl<'c> TcpaPcrInfoAny for TssPCRCompositeInfo<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}
impl<'c> TcpaPcrInfo1_1 for TssPCRCompositeInfo<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}
impl<'c> TcpaPcrInfoAny for TssPCRCompositeInfoLong<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}
impl<'c> TcpaPcrInfo1_2 for TssPCRCompositeInfoLong<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}
impl<'c> TcpaPcrInfoAny for TssPCRCompositeInfoShort<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}
impl<'c> TcpaPcrInfo1_2 for TssPCRCompositeInfoShort<'c> {
    fn get_handle(&self) -> u32 { self.handle }
}

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Close(hContext: TssHContext) -> TssResult;
    fn Tspi_Context_Connect(hContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_FreeMemory(hContext: TssHContext, rgbMemory: *mut u8) -> TssResult;
    fn Tspi_Context_CreateObject(hContext: TssHContext, objectType: TssFlag, initFlags: TssFlag, phObject: *mut TssHObject) -> TssResult;
    fn Tspi_Context_GetTpmObject(hContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_TPM_PcrRead(hTPM: TssHTPM, ulPcrIndex: u32, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
    fn Tspi_TPM_PcrExtend(hTPM: TssHTPM, ulPcrIndex: u32, ulPcrDataLength: u32, pbPcrData: *const u8, pPcrEvent: *mut u8, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
    fn Tspi_TPM_PcrReset(hTPM: TssHTPM, hPcrComposite: TssHPCRS) -> TssResult;
}

impl TssContext {
    pub fn new() -> Result<TssContext, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_Create(&mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssContext { handle: handle })
    }

    // TODO: support destination
    pub fn connect(&self) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_Context_Connect(self.handle, ptr::null())
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }

    pub fn get_tpm_object(&self) -> Result<TssTPM, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_GetTpmObject(self.handle, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssTPM { context: self, handle: handle })
    }

    pub fn create_pcr_composite_info(&self) -> Result<TssPCRCompositeInfo, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_CreateObject(self.handle, TSS_OBJECT_TYPE_PCRS, TSS_PCRS_STRUCT_INFO, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssPCRCompositeInfo { context: self, handle: handle })
    }
    pub fn create_pcr_composite_info_long(&self) -> Result<TssPCRCompositeInfoLong, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_CreateObject(self.handle, TSS_OBJECT_TYPE_PCRS, TSS_PCRS_STRUCT_INFO_LONG, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssPCRCompositeInfoLong { context: self, handle: handle })
    }
    pub fn create_pcr_composite_info_short(&self) -> Result<TssPCRCompositeInfoShort, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_CreateObject(self.handle, TSS_OBJECT_TYPE_PCRS, TSS_PCRS_STRUCT_INFO_SHORT, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssPCRCompositeInfoShort { context: self, handle: handle })
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_FreeMemory(self.handle, 0 as *mut u8);
            Tspi_Context_Close(self.handle);
        }
    }
}

impl<'context> TssTPM<'context> {
    pub fn pcr_read(&self, pcr_index: u32) -> Result<Vec<u8>, TssResult> {
        let mut pcr_value_length = 0;
        let mut pcr_value_ptr = 0 as *mut u8;
        let result = unsafe {
            Tspi_TPM_PcrRead(self.handle, pcr_index, &mut pcr_value_length, &mut pcr_value_ptr)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        let mut vec = Vec::new();
        unsafe {
            for i in 0..pcr_value_length {
                // TODO: Is this isize cast safe?
                vec.push(*pcr_value_ptr.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pcr_value_ptr);
        }
        Ok(vec)
    }

    // TODO: events
    pub fn pcr_extend(&self, pcr_index: u32, data: &[u8]) -> Result<Vec<u8>, TssResult> {
        let mut pcr_value_length = 0;
        let mut pcr_value_ptr = 0 as *mut u8;
        let result = unsafe {
            // TODO: Is this u32 cast safe?
            Tspi_TPM_PcrExtend(self.handle, pcr_index, data.len() as u32, data.as_ptr(), 0 as *mut u8, &mut pcr_value_length, &mut pcr_value_ptr)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        // TODO: DRY with above
        let mut vec = Vec::new();
        unsafe {
            for i in 0..pcr_value_length {
                // TODO: Is this isize cast safe?
                vec.push(*pcr_value_ptr.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pcr_value_ptr);
        }
        Ok(vec)
    }

    pub fn pcr_reset(&self, pcr_composite: &TcpaPcrInfoAny) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_TPM_PcrReset(self.handle, pcr_composite.get_handle())
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>mod key;
mod rangeset;

use key::Key;
use rangeset::{Range, RangeSet};
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct VKeyMarker;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct EKeyMarker;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct FKeyMarker;
pub type VKey = Key<VKeyMarker>;
pub type EKey = Key<EKeyMarker>;
pub type FKey = Key<FKeyMarker>;
pub type FaceLen = u32;

/// Editable mesh with persistent adjacency data. Modeled loosely
/// after Blender's BMesh:
///
/// http://wiki.blender.org/index.php/Dev:2.6/Source/Modeling/BMesh/Design
pub struct Mesh<VData, EData, FData> {
    verts: HashMap<VKey, Vert<VData>>,
    edges: HashMap<EKey, Edge<EData>>,
    faces: HashMap<FKey, Face<FData>>,

    vert_range_set: RangeSet,
    edge_range_set: RangeSet,
    face_range_set: RangeSet
}

// TODO
fn new_key_range_set() -> RangeSet {
    RangeSet::new(Range::new(0, 0xffffffff - 1))
}

impl<VData: Clone, EData: Clone, FData: Clone> Mesh<VData, EData, FData> {
    pub fn new() -> Mesh<VData, EData, FData> {
        Mesh {
            verts: HashMap::new(),
            edges: HashMap::new(),
            faces: HashMap::new(),

            vert_range_set: new_key_range_set(),
            edge_range_set: new_key_range_set(),
            face_range_set: new_key_range_set()
        }
    }

    pub fn get_vert(&self, vk: VKey) -> Option<&Vert<VData>> {
        self.verts.get(&vk)
    }

    pub fn get_edge(&self, ek: EKey) -> Option<&Edge<EData>> {
        self.edges.get(&ek)
    }

    pub fn get_face(&self, fk: FKey) -> Option<&Face<FData>> {
        self.faces.get(&fk)
    }

    pub fn get_vert_data(&mut self, vk: VKey) -> Option<&mut Vert<VData>> {
        self.verts.get_mut(&vk)
    }

    pub fn get_edge_data(&mut self, ek: EKey) -> Option<&mut Edge<EData>> {
        self.edges.get_mut(&ek)
    }

    pub fn get_face_data(&mut self, fk: FKey) -> Option<&mut Face<FData>> {
        self.faces.get_mut(&fk)
    }

    /// Return the edge between two verts, or None if no such edge
    /// exists.
    pub fn find_edge(&self, vk0: VKey, vk1: VKey) -> Option<EKey> {
        for ek in self.verts[&vk0].edges.iter() {
            if self.edges[ek].is_vert_adjacent(vk1) {
                return Some(*ek)
            }
        }
        None
    }

    /// Get all faces adjacent to the specified vertex. The order is
    /// arbitrary.
    pub fn vert_adjacent_faces(&self, vk: VKey) -> Vec<FKey> {
        let mut adj = Vec::new();
        for ek in self.verts[&vk].edges.iter() {
            for fk in self.edges[ek].faces.iter() {
                if !adj.contains(fk) {
                    adj.push(*fk);
                }
            }
        }
        adj
    }

    /// Add a new isolated vertex and return its key. Fail and return
    /// None if there are no more vertex keys available.
    pub fn add_vert(&mut self, vdata: VData) -> Option<VKey> {
        if let Some(val) = self.vert_range_set.take_any_one() {
            let vkey = VKey::new(val);
            self.verts.insert(vkey, Vert::new(vdata));
            Some(vkey)
        } else {
            None
        }
    }

    pub fn add_edge(&mut self, vk0: VKey, vk1: VKey, edata: EData) -> Option<EKey> {
        // TODO(nicholasbishop): check that the verts are in the mesh,
        if vk0 == vk1 {
            None
        } else if let Some(ek) = self.find_edge(vk0, vk1) {
            Some(ek)
        } else {
            if let Some(val) = self.edge_range_set.take_any_one() {
                let ekey = EKey::new(val);
                self.verts.get_mut(&vk0).unwrap().push_edge(ekey);
                self.verts.get_mut(&vk1).unwrap().push_edge(ekey);
                self.edges.insert(ekey, Edge::new(vk0, vk1, edata));
                Some(ekey)
            } else {
                None
            }
        }
    }

    pub fn add_face(&mut self, vk: &[VKey], edata: EData, fdata: FData) -> Option<FKey> {
        let mut loops = Vec::with_capacity(vk.len());
        for i in 0..vk.len() {
            let vk0 = vk[i];
            let vk1 = vk[if i < (vk.len() - 1) { i + 1 } else { 0 }];
            // TODO(nicholasbishop): do more checking up front so that
            // edges don't get created on failure, or delete them after.
            if let Some(ek) = self.add_edge(vk0, vk1, edata.clone()) {
                loops.push(Loop { vert: vk0, edge: ek });
            } else {
                // Error: failed to create edge
                return None;
            }
        }
        if let Some(val) = self.face_range_set.take_any_one() {
            let fk = FKey::new(val);
            for lp in loops.iter() {
                self.edges.get_mut(&lp.edge).unwrap().push_face(fk);
            }
            self.faces.insert(fk, Face::new(loops, fdata));
            Some(fk)
        } else {
            None
        }
    }
}

pub struct Vert<VData> {
    pub vdata: VData,
    edges: Vec<EKey>
}

impl<VData> Vert<VData> {
    fn new(vdata: VData) -> Vert<VData> {
        Vert { vdata: vdata, edges: Vec::new() }
    }

    /// Check if the edge is in the set of edges adjacent to this vert.
    pub fn is_edge_adjacent(&self, ek: EKey) -> bool {
        self.edges.contains(&ek)
    }

    /// Add edge to set of edges adjacent to the vert. Does nothing if
    /// the edge is already in the set.
    fn push_edge(&mut self, ek: EKey) {
        if !self.is_edge_adjacent(ek) {
            self.edges.push(ek);
        }
    }
}

pub struct Edge<EData> {
    pub edata: EData,
    verts: [VKey; 2],
    faces: Vec<FKey>
}

impl<EData> Edge<EData> {
    fn new(vk0: VKey, vk1: VKey, edata: EData) -> Edge<EData> {
        Edge { edata: edata, verts: [vk0, vk1], faces: Vec::new() }
    }

    /// Check if the vert is one of the two verts adjacent to this edge.
    fn is_vert_adjacent(&self, vk: VKey) -> bool {
        self.verts.contains(&vk)
    }

    /// Check if the face is in the set of edges adjacent to this edge.
    pub fn is_face_adjacent(&self, fk: FKey) -> bool {
        self.faces.contains(&fk)
    }

    /// Add face to set of faces adjacent to the edge. Does nothing if
    /// the face is already in the set.
    fn push_face(&mut self, fk: FKey) {
        if !self.is_face_adjacent(fk) {
            self.faces.push(fk);
        }
    }
}

pub struct Loop {
    pub vert: VKey,
    pub edge: EKey
}

pub struct Face<FData> {
    pub fdata: FData,
    loops: Vec<Loop>
}

impl<FData> Face<FData> {
    fn new(loops: Vec<Loop>, fdata: FData) -> Face<FData> {
        Face { fdata: fdata, loops: loops }
    }

    pub fn get_loops(&self) -> &Vec<Loop> {
        &self.loops
    }
}

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

    // Placeholder for vert/edge/face data
    const DAT: () = ();

    #[test]
    fn test_add_vert() {
        let mut mesh = Mesh::<_, (), ()>::new();
        assert!(mesh.add_vert(DAT).is_some());
        assert!(!mesh.verts.is_empty());
    }

    #[test]
    fn test_add_edge() {
        let mut mesh = Mesh::<_, _, ()>::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();

        // Add a valid edge
        let e = mesh.add_edge(a, b, DAT).unwrap();
        assert!(mesh.verts[&a].edges.contains(&e));
        assert!(mesh.verts[&b].edges.contains(&e));

        // Edge from a vertex to the same vertex is not allowed
        assert!(mesh.add_edge(a, a, DAT).is_none());

        // Duplicate edge should return the existing edge
        assert_eq!(mesh.add_edge(a, b, DAT).unwrap(), e);
        assert_eq!(mesh.add_edge(b, a, DAT).unwrap(), e);
    }

    #[test]
    fn test_add_face() {
        let mut mesh = Mesh::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();
        let c = mesh.add_vert(DAT).unwrap();

        // Add a valid triangle
        let fk = mesh.add_face(&[a, b, c], DAT, DAT).unwrap();
        assert_eq!(mesh.edges.len(), 3);
        for lp in mesh.faces[&fk].loops.iter() {
            assert!(mesh.edges[&lp.edge].is_face_adjacent(fk));
        }

        // Add an invalid triangle with invalid edge
        assert!(mesh.add_face(&[a, b, b], DAT, DAT).is_none());
    }

    #[test]
    fn test_vert_adjacent_faces() {
        // Create a bow-tie mesh
        let mut mesh = Mesh::new();
        let middle = mesh.add_vert(DAT).unwrap();
        let l0 = mesh.add_vert(DAT).unwrap();
        let l1 = mesh.add_vert(DAT).unwrap();
        let r0 = mesh.add_vert(DAT).unwrap();
        let r1 = mesh.add_vert(DAT).unwrap();
        let fk0 = mesh.add_face(&[middle, l0, l1], DAT, DAT).unwrap();
        let fk1 = mesh.add_face(&[middle, r0, r1], DAT, DAT).unwrap();

        let adj = mesh.vert_adjacent_faces(middle);
        assert_eq!(adj.len(), 2);
        assert!(adj.contains(&fk0));
        assert!(adj.contains(&fk1));
    }

    #[test]
    fn test_ngon() {
        let mut mesh = Mesh::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();
        let c = mesh.add_vert(DAT).unwrap();
        let d = mesh.add_vert(DAT).unwrap();
        let e = mesh.add_vert(DAT).unwrap();

        let fk = mesh.add_face(&[a, b, c, d, e], DAT, DAT).unwrap();
        let face = &mesh.faces[&fk];

        assert_eq!(face.loops.len(), 5);
    }
}
<commit_msg>Add more accessors<commit_after>mod key;
mod rangeset;

use key::Key;
use rangeset::{Range, RangeSet};
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct VKeyMarker;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct EKeyMarker;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct FKeyMarker;
pub type VKey = Key<VKeyMarker>;
pub type EKey = Key<EKeyMarker>;
pub type FKey = Key<FKeyMarker>;
pub type FaceLen = u32;

/// Editable mesh with persistent adjacency data. Modeled loosely
/// after Blender's BMesh:
///
/// http://wiki.blender.org/index.php/Dev:2.6/Source/Modeling/BMesh/Design
pub struct Mesh<VData, EData, FData> {
    verts: HashMap<VKey, Vert<VData>>,
    edges: HashMap<EKey, Edge<EData>>,
    faces: HashMap<FKey, Face<FData>>,

    vert_range_set: RangeSet,
    edge_range_set: RangeSet,
    face_range_set: RangeSet
}

// TODO
fn new_key_range_set() -> RangeSet {
    RangeSet::new(Range::new(0, 0xffffffff - 1))
}

impl<VData: Clone, EData: Clone, FData: Clone> Mesh<VData, EData, FData> {
    pub fn new() -> Mesh<VData, EData, FData> {
        Mesh {
            verts: HashMap::new(),
            edges: HashMap::new(),
            faces: HashMap::new(),

            vert_range_set: new_key_range_set(),
            edge_range_set: new_key_range_set(),
            face_range_set: new_key_range_set()
        }
    }

    pub fn get_vert(&self, vk: VKey) -> Option<&Vert<VData>> {
        self.verts.get(&vk)
    }

    pub fn get_edge(&self, ek: EKey) -> Option<&Edge<EData>> {
        self.edges.get(&ek)
    }

    pub fn get_face(&self, fk: FKey) -> Option<&Face<FData>> {
        self.faces.get(&fk)
    }

    pub fn get_vert_data(&mut self, vk: VKey) -> Option<&mut Vert<VData>> {
        self.verts.get_mut(&vk)
    }

    pub fn get_edge_data(&mut self, ek: EKey) -> Option<&mut Edge<EData>> {
        self.edges.get_mut(&ek)
    }

    pub fn get_face_data(&mut self, fk: FKey) -> Option<&mut Face<FData>> {
        self.faces.get_mut(&fk)
    }

    /// Return the edge between two verts, or None if no such edge
    /// exists.
    pub fn find_edge(&self, vk0: VKey, vk1: VKey) -> Option<EKey> {
        for ek in self.verts[&vk0].edges.iter() {
            if self.edges[ek].is_vert_adjacent(vk1) {
                return Some(*ek)
            }
        }
        None
    }

    /// Get all faces adjacent to the specified vertex. The order is
    /// arbitrary.
    pub fn vert_adjacent_faces(&self, vk: VKey) -> Vec<FKey> {
        let mut adj = Vec::new();
        for ek in self.verts[&vk].edges.iter() {
            for fk in self.edges[ek].faces.iter() {
                if !adj.contains(fk) {
                    adj.push(*fk);
                }
            }
        }
        adj
    }

    /// Add a new isolated vertex and return its key. Fail and return
    /// None if there are no more vertex keys available.
    pub fn add_vert(&mut self, vdata: VData) -> Option<VKey> {
        if let Some(val) = self.vert_range_set.take_any_one() {
            let vkey = VKey::new(val);
            self.verts.insert(vkey, Vert::new(vdata));
            Some(vkey)
        } else {
            None
        }
    }

    pub fn add_edge(&mut self, vk0: VKey, vk1: VKey, edata: EData) -> Option<EKey> {
        // TODO(nicholasbishop): check that the verts are in the mesh,
        if vk0 == vk1 {
            None
        } else if let Some(ek) = self.find_edge(vk0, vk1) {
            Some(ek)
        } else {
            if let Some(val) = self.edge_range_set.take_any_one() {
                let ekey = EKey::new(val);
                self.verts.get_mut(&vk0).unwrap().push_edge(ekey);
                self.verts.get_mut(&vk1).unwrap().push_edge(ekey);
                self.edges.insert(ekey, Edge::new(vk0, vk1, edata));
                Some(ekey)
            } else {
                None
            }
        }
    }

    pub fn add_face(&mut self, vk: &[VKey], edata: EData, fdata: FData) -> Option<FKey> {
        let mut loops = Vec::with_capacity(vk.len());
        for i in 0..vk.len() {
            let vk0 = vk[i];
            let vk1 = vk[if i < (vk.len() - 1) { i + 1 } else { 0 }];
            // TODO(nicholasbishop): do more checking up front so that
            // edges don't get created on failure, or delete them after.
            if let Some(ek) = self.add_edge(vk0, vk1, edata.clone()) {
                loops.push(Loop { vert: vk0, edge: ek });
            } else {
                // Error: failed to create edge
                return None;
            }
        }
        if let Some(val) = self.face_range_set.take_any_one() {
            let fk = FKey::new(val);
            for lp in loops.iter() {
                self.edges.get_mut(&lp.edge).unwrap().push_face(fk);
            }
            self.faces.insert(fk, Face::new(loops, fdata));
            Some(fk)
        } else {
            None
        }
    }
}

pub struct Vert<VData> {
    pub vdata: VData,
    edges: Vec<EKey>
}

impl<VData> Vert<VData> {
    fn new(vdata: VData) -> Vert<VData> {
        Vert { vdata: vdata, edges: Vec::new() }
    }

    /// Check if the edge is in the set of edges adjacent to this vert.
    pub fn is_edge_adjacent(&self, ek: EKey) -> bool {
        self.edges.contains(&ek)
    }

    pub fn get_edges(&self) -> &Vec<EKey> {
        &self.edges
    }

    /// Add edge to set of edges adjacent to the vert. Does nothing if
    /// the edge is already in the set.
    fn push_edge(&mut self, ek: EKey) {
        if !self.is_edge_adjacent(ek) {
            self.edges.push(ek);
        }
    }
}

pub struct Edge<EData> {
    pub edata: EData,
    verts: [VKey; 2],
    faces: Vec<FKey>
}

impl<EData> Edge<EData> {
    fn new(vk0: VKey, vk1: VKey, edata: EData) -> Edge<EData> {
        Edge { edata: edata, verts: [vk0, vk1], faces: Vec::new() }
    }

    /// Check if the vert is one of the two verts adjacent to this edge.
    fn is_vert_adjacent(&self, vk: VKey) -> bool {
        self.verts.contains(&vk)
    }

    /// Check if the face is in the set of edges adjacent to this edge.
    pub fn is_face_adjacent(&self, fk: FKey) -> bool {
        self.faces.contains(&fk)
    }

    pub fn get_verts(&self) -> &[VKey; 2] {
        &self.verts
    }

    pub fn get_faces(&self) -> &Vec<FKey> {
        &self.faces
    }

    /// Add face to set of faces adjacent to the edge. Does nothing if
    /// the face is already in the set.
    fn push_face(&mut self, fk: FKey) {
        if !self.is_face_adjacent(fk) {
            self.faces.push(fk);
        }
    }
}

pub struct Loop {
    pub vert: VKey,
    pub edge: EKey
}

pub struct Face<FData> {
    pub fdata: FData,
    loops: Vec<Loop>
}

impl<FData> Face<FData> {
    fn new(loops: Vec<Loop>, fdata: FData) -> Face<FData> {
        Face { fdata: fdata, loops: loops }
    }

    pub fn get_loops(&self) -> &Vec<Loop> {
        &self.loops
    }
}

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

    // Placeholder for vert/edge/face data
    const DAT: () = ();

    #[test]
    fn test_add_vert() {
        let mut mesh = Mesh::<_, (), ()>::new();
        assert!(mesh.add_vert(DAT).is_some());
        assert!(!mesh.verts.is_empty());
    }

    #[test]
    fn test_add_edge() {
        let mut mesh = Mesh::<_, _, ()>::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();

        // Add a valid edge
        let e = mesh.add_edge(a, b, DAT).unwrap();
        assert!(mesh.verts[&a].edges.contains(&e));
        assert!(mesh.verts[&b].edges.contains(&e));

        // Edge from a vertex to the same vertex is not allowed
        assert!(mesh.add_edge(a, a, DAT).is_none());

        // Duplicate edge should return the existing edge
        assert_eq!(mesh.add_edge(a, b, DAT).unwrap(), e);
        assert_eq!(mesh.add_edge(b, a, DAT).unwrap(), e);
    }

    #[test]
    fn test_add_face() {
        let mut mesh = Mesh::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();
        let c = mesh.add_vert(DAT).unwrap();

        // Add a valid triangle
        let fk = mesh.add_face(&[a, b, c], DAT, DAT).unwrap();
        assert_eq!(mesh.edges.len(), 3);
        for lp in mesh.faces[&fk].loops.iter() {
            assert!(mesh.edges[&lp.edge].is_face_adjacent(fk));
        }

        // Add an invalid triangle with invalid edge
        assert!(mesh.add_face(&[a, b, b], DAT, DAT).is_none());
    }

    #[test]
    fn test_vert_adjacent_faces() {
        // Create a bow-tie mesh
        let mut mesh = Mesh::new();
        let middle = mesh.add_vert(DAT).unwrap();
        let l0 = mesh.add_vert(DAT).unwrap();
        let l1 = mesh.add_vert(DAT).unwrap();
        let r0 = mesh.add_vert(DAT).unwrap();
        let r1 = mesh.add_vert(DAT).unwrap();
        let fk0 = mesh.add_face(&[middle, l0, l1], DAT, DAT).unwrap();
        let fk1 = mesh.add_face(&[middle, r0, r1], DAT, DAT).unwrap();

        let adj = mesh.vert_adjacent_faces(middle);
        assert_eq!(adj.len(), 2);
        assert!(adj.contains(&fk0));
        assert!(adj.contains(&fk1));
    }

    #[test]
    fn test_ngon() {
        let mut mesh = Mesh::new();
        let a = mesh.add_vert(DAT).unwrap();
        let b = mesh.add_vert(DAT).unwrap();
        let c = mesh.add_vert(DAT).unwrap();
        let d = mesh.add_vert(DAT).unwrap();
        let e = mesh.add_vert(DAT).unwrap();

        let fk = mesh.add_face(&[a, b, c, d, e], DAT, DAT).unwrap();
        let face = &mesh.faces[&fk];

        assert_eq!(face.loops.len(), 5);
    }
}
<|endoftext|>


<commit_before>#![crate_name = "persistent"]
#![license = "MIT"]
#![deny(missing_docs)]
#![deny(warnings)]
#![feature(default_type_params)]

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use iron::typemap::Assoc;
use std::sync::{Arc, RWLock, Mutex};
use plugin::{PluginFor, Phantom};

/// Middleware for data that persists between requests with read and write capabilities.
///
/// The data is stored behind a `RWLock`, so multiple read locks
/// can be taken out concurrently.
///
/// If most threads need to take out a write lock, you may want to
/// consider `Write`, which stores the data behind a `Mutex`, which
/// has a faster locking speed.
///
/// `State` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `State` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<State<P, D>>()` as an `Arc<RWLock<D>>`.
pub struct State<P, D> {
    data: Arc<RWLock<D>>
}

/// Middleware for data that persists between Requests with read-only capabilities.
///
/// The data is stored behind an Arc, so multiple threads can have
/// concurrent, non-blocking access.
///
/// `Read` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Read` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Read<P, D>>()` as an `Arc<D>`.
pub struct Read<P, D> {
    data: Arc<D>
}

/// Middleware for data that persists between Requests for data which mostly
/// needs to be written instead of read.
///
/// The data is stored behind a `Mutex`, so only one request at a time can
/// access the data. This is more performant than `State` in the case where
/// most uses of the data require a write lock.
///
/// `Write` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Write` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Write<P, D>>()` as an `Arc<Mutex<D>>`.
pub struct Write<P, D> {
    data: Arc<Mutex<D>>
}

impl<P, D: Send + Sync> Clone for Read<P, D> {
    fn clone(&self) -> Read<P, D> {
        Read { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for State<P, D> {
    fn clone(&self) -> State<P, D> {
        State { data: self.data.clone() }
    }
}

impl<P, D: Send> Clone for Write<P, D> {
    fn clone(&self) -> Write<P, D> {
        Write { data: self.data.clone() }
    }
}

impl<P, D:'static> Assoc<Arc<RWLock<D>>> for State<P, D> where P: Assoc<D> {}
impl<P, D:'static> Assoc<Arc<D>> for Read<P, D> where P: Assoc<D> {}
impl<P, D:'static> Assoc<Arc<Mutex<D>>> for Write<P, D> where P: Assoc<D> {}

impl<P, D> PluginFor<Request, Arc<RWLock<D>>> for State<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<State<P, D>>) -> Option<Arc<RWLock<D>>> {
        req.extensions.get::<State<P, D>, Arc<RWLock<D>>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<D>> for Read<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<Read<P, D>>) -> Option<Arc<D>> {
        req.extensions.get::<Read<P, D>, Arc<D>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<Mutex<D>>> for Write<P, D>
    where D: Send,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<Write<P, D>>) -> Option<Arc<Mutex<D>>> {
        req.extensions.get::<Write<P, D>, Arc<Mutex<D>>>()
            .map(|x| x.clone())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for State<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for State<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Read<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Read<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send, P: Assoc<D>> BeforeMiddleware for Write<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send, P: Assoc<D>> AfterMiddleware for Write<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<P, D> State<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `State` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (State<P, D>, State<P, D>) {
        let x = State { data: Arc::new(RWLock::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `State` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> State<P, D> {
        State { data: Arc::new(RWLock::new(start)) }
    }
}

impl<P, D> Read<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `Read` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Read<P, D>, Read<P, D>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }

    /// Construct a new `Read` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Read<P, D> {
        Read { data: Arc::new(start) }
    }
}

impl<P, D> Write<P, D> where D: Send, P: Assoc<D> {
    /// Construct a new pair of `Write` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Write<P, D>, Write<P, D>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `Write` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Write<P, D> {
        Write { data: Arc::new(Mutex::new(start)) }
    }
}
<commit_msg>(fix) Remove unused attributes.<commit_after>#![deny(missing_docs, warnings)]
#![feature(default_type_params)]

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use iron::typemap::Assoc;
use std::sync::{Arc, RWLock, Mutex};
use plugin::{PluginFor, Phantom};

/// Middleware for data that persists between requests with read and write capabilities.
///
/// The data is stored behind a `RWLock`, so multiple read locks
/// can be taken out concurrently.
///
/// If most threads need to take out a write lock, you may want to
/// consider `Write`, which stores the data behind a `Mutex`, which
/// has a faster locking speed.
///
/// `State` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `State` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<State<P, D>>()` as an `Arc<RWLock<D>>`.
pub struct State<P, D> {
    data: Arc<RWLock<D>>
}

/// Middleware for data that persists between Requests with read-only capabilities.
///
/// The data is stored behind an Arc, so multiple threads can have
/// concurrent, non-blocking access.
///
/// `Read` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Read` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Read<P, D>>()` as an `Arc<D>`.
pub struct Read<P, D> {
    data: Arc<D>
}

/// Middleware for data that persists between Requests for data which mostly
/// needs to be written instead of read.
///
/// The data is stored behind a `Mutex`, so only one request at a time can
/// access the data. This is more performant than `State` in the case where
/// most uses of the data require a write lock.
///
/// `Write` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Write` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Write<P, D>>()` as an `Arc<Mutex<D>>`.
pub struct Write<P, D> {
    data: Arc<Mutex<D>>
}

impl<P, D: Send + Sync> Clone for Read<P, D> {
    fn clone(&self) -> Read<P, D> {
        Read { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for State<P, D> {
    fn clone(&self) -> State<P, D> {
        State { data: self.data.clone() }
    }
}

impl<P, D: Send> Clone for Write<P, D> {
    fn clone(&self) -> Write<P, D> {
        Write { data: self.data.clone() }
    }
}

impl<P, D:'static> Assoc<Arc<RWLock<D>>> for State<P, D> where P: Assoc<D> {}
impl<P, D:'static> Assoc<Arc<D>> for Read<P, D> where P: Assoc<D> {}
impl<P, D:'static> Assoc<Arc<Mutex<D>>> for Write<P, D> where P: Assoc<D> {}

impl<P, D> PluginFor<Request, Arc<RWLock<D>>> for State<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<State<P, D>>) -> Option<Arc<RWLock<D>>> {
        req.extensions.get::<State<P, D>, Arc<RWLock<D>>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<D>> for Read<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<Read<P, D>>) -> Option<Arc<D>> {
        req.extensions.get::<Read<P, D>, Arc<D>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<Mutex<D>>> for Write<P, D>
    where D: Send,
          P: Assoc<D> {
    fn eval(req: &mut Request, _: Phantom<Write<P, D>>) -> Option<Arc<Mutex<D>>> {
        req.extensions.get::<Write<P, D>, Arc<Mutex<D>>>()
            .map(|x| x.clone())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for State<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for State<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Read<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Read<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send, P: Assoc<D>> BeforeMiddleware for Write<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send, P: Assoc<D>> AfterMiddleware for Write<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<P, D> State<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `State` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (State<P, D>, State<P, D>) {
        let x = State { data: Arc::new(RWLock::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `State` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> State<P, D> {
        State { data: Arc::new(RWLock::new(start)) }
    }
}

impl<P, D> Read<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `Read` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Read<P, D>, Read<P, D>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }

    /// Construct a new `Read` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Read<P, D> {
        Read { data: Arc::new(start) }
    }
}

impl<P, D> Write<P, D> where D: Send, P: Assoc<D> {
    /// Construct a new pair of `Write` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Write<P, D>, Write<P, D>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `Write` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Write<P, D> {
        Write { data: Arc::new(Mutex::new(start)) }
    }
}
<|endoftext|>