<commit_before>#![feature(macro_rules)]
#![feature(globs)]

extern crate semver;
extern crate conduit;

use std::iter;
use std::io::net::ip::IpAddr;
use std::collections::hashmap::{HashMap, Entries};

use conduit::{Method, Scheme, Host, Extensions, Headers, Request};

pub trait RequestDelegator {
    fn request<'a>(&'a self) -> &'a Request;
    fn mut_request<'a>(&'a mut self) -> &'a mut Request;

    fn http_version(&self) -> semver::Version {
        self.request().http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.request().conduit_version()
    }

    fn method(&self) -> Method {
        self.request().method()
    }

    fn scheme(&self) -> Scheme {
        self.request().scheme()
    }

    fn host<'a>(&'a self) -> Host<'a> {
        self.request().host()
    }

    fn virtual_root<'a>(&'a self) -> Option<&'a str> {
        self.request().virtual_root()
    }

    fn path<'a>(&'a self) -> &'a str {
        self.request().path()
    }

    fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.request().query_string()
    }

    fn remote_ip(&self) -> IpAddr {
        self.request().remote_ip()
    }

    fn content_length(&self) -> Option<uint> {
        self.request().content_length()
    }

    fn headers<'a>(&'a self) -> &'a Headers {
        self.request().headers()
    }

    fn body<'a>(&'a mut self) -> &'a mut Reader {
        self.mut_request().body()
    }

    fn extensions<'a>(&'a self) -> &'a Extensions {
        self.request().extensions()
    }

    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
        self.mut_request().mut_extensions()
    }
}

impl<'a> Request for &'a mut RequestDelegator + 'a {
    fn http_version(&self) -> semver::Version {
        self.http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.conduit_version()
    }

    fn method(&self) -> Method {
        self.method()
    }

    fn scheme(&self) -> Scheme {
        self.scheme()
    }

    fn host<'a>(&'a self) -> Host<'a> {
        self.host()
    }

    fn virtual_root<'a>(&'a self) -> Option<&'a str> {
        self.virtual_root()
    }

    fn path<'a>(&'a self) -> &'a str {
        self.path()
    }

    fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.query_string()
    }

    fn remote_ip(&self) -> IpAddr {
        self.remote_ip()
    }

    fn content_length(&self) -> Option<uint> {
        self.content_length()
    }

    fn headers<'a>(&'a self) -> &'a Headers {
        self.headers()
    }

    fn body<'a>(&'a mut self) -> &'a mut Reader {
        self.body()
    }

    fn extensions<'a>(&'a self) -> &'a Extensions {
        self.extensions()
    }

    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
        self.mut_extensions()
    }
}

type RawHeaders = HashMap<String, Vec<String>>;
type InHeader<'a> = (&'a String, &'a Vec<String>);
type OutHeader<'a> = (String, &'a Vec<String>);

#[deriving(PartialEq, Clone, Show)]
pub struct HeaderMap(HashMap<String, Vec<String>>);

impl HeaderMap {
    fn normalize(headers: HashMap<String, Vec<String>>) -> HeaderMap {
        let headers = headers.into_iter().map(|(k,v)| (to_lower(&k), v)).collect();
        HeaderMap(headers)
    }

    fn iter<'a>(&'a self) -> iter::Map<'a, InHeader<'a>, OutHeader<'a>, Entries<'a, String, Vec<String>>> {
        self.as_ref().iter().map(|(k,v)| (to_lower(k), v))
    }

    fn as_ref<'a>(&'a self) -> &'a HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref map) => map
        }
    }

    fn as_mut<'a>(&'a mut self) -> &'a mut HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref mut map) => map
        }
    }

    pub fn len(&self) -> uint {
        self.as_ref().len()
    }
    pub fn clear(&mut self) {
        self.as_mut().clear()
    }
    pub fn find<'a, S: Str>(&'a self, key: &S) -> Option<&'a Vec<String>> {
        self.as_ref().find(&to_lower(key))
    }
    pub fn insert<S: Str>(&mut self, k: S, v: Vec<String>) -> Option<Vec<String>> {
        self.as_mut().swap(to_lower(&k), v)
    }
    pub fn remove<S: Str>(&mut self, k: &S) -> Option<Vec<String>> {
        self.as_mut().pop(&to_lower(k))
    }

    pub fn find_mut<'a, S: Str>(&'a mut self, k: &S) -> Option<&'a mut Vec<String>> {
        self.as_mut().find_mut(&to_lower(k))
    }
}

fn to_lower<S: Str>(string: &S) -> String {
    string.as_slice().chars().map(|c| c.to_lowercase()).collect()
}

#[cfg(test)]
mod tests {
    extern crate "conduit-test" as test;

    use {RequestDelegator, HeaderMap};

    use std::collections::HashMap;
    use conduit;
    use conduit::{Request, Method};

    struct OverrideRequest<'a> {
        request: &'a mut Request + 'a
    }

    impl<'a> RequestDelegator for OverrideRequest<'a> {
        fn request<'a>(&'a self) -> &'a Request {
            let req: &Request = self.request; req
        }

        fn mut_request<'a>(&'a mut self) -> &'a mut Request {
            let req: &mut Request = self.request; req
        }

        fn method(&self) -> Method {
            conduit::Get
        }
    }

    #[test]
    fn test_delegate() {
        let request = &mut test::MockRequest::new(conduit::Head, "/hello") as &mut Request;
        let new = OverrideRequest { request: request };

        assert_eq!(new.method(), conduit::Get);
        assert_eq!(new.path(), "/hello");
    }

    #[test]
    fn test_header_map() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));
        map.insert("location".to_string(), vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())))
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())))
    }

    #[test]
    fn test_header_map_with_static_inserts() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())))
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())))
    }

    #[test]
    fn test_normalize() {
        let mut map = HashMap::new();
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));

        let headers = HeaderMap::normalize(map);
        assert_eq!(headers.find(&"Content-Type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"Content-Type"), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"content-type"), Some(&vec!("text/html".to_string())))
    }

    #[test]
    fn test_iterate() {
        let mut headers = HeaderMap(HashMap::new());
        headers.insert("Content-Type", vec!("text/html".to_string()));
        headers.insert("location", vec!("http://example.com".to_string()));

        assert!(headers.iter().any(|t| t == ("content-type".to_string(), &vec!("text/html".to_string()))));
        assert!(headers.iter().any(|t| t == ("location".to_string(), &vec!("http://example.com".to_string()))));
        assert!(headers.iter().count() == 2);
    }
}
<commit_msg>Update to rust master<commit_after>#![feature(macro_rules)]
#![feature(globs)]

extern crate semver;
extern crate conduit;

use std::iter;
use std::io::net::ip::IpAddr;
use std::collections::hash_map::{HashMap, Entries};

use conduit::{Method, Scheme, Host, Extensions, Headers, Request};

pub trait RequestDelegator {
    fn request<'a>(&'a self) -> &'a Request;
    fn mut_request<'a>(&'a mut self) -> &'a mut Request;

    fn http_version(&self) -> semver::Version {
        self.request().http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.request().conduit_version()
    }

    fn method(&self) -> Method {
        self.request().method()
    }

    fn scheme(&self) -> Scheme {
        self.request().scheme()
    }

    fn host<'a>(&'a self) -> Host<'a> {
        self.request().host()
    }

    fn virtual_root<'a>(&'a self) -> Option<&'a str> {
        self.request().virtual_root()
    }

    fn path<'a>(&'a self) -> &'a str {
        self.request().path()
    }

    fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.request().query_string()
    }

    fn remote_ip(&self) -> IpAddr {
        self.request().remote_ip()
    }

    fn content_length(&self) -> Option<uint> {
        self.request().content_length()
    }

    fn headers<'a>(&'a self) -> &'a Headers {
        self.request().headers()
    }

    fn body<'a>(&'a mut self) -> &'a mut Reader {
        self.mut_request().body()
    }

    fn extensions<'a>(&'a self) -> &'a Extensions {
        self.request().extensions()
    }

    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
        self.mut_request().mut_extensions()
    }
}

impl<'a> Request for &'a mut RequestDelegator + 'a {
    fn http_version(&self) -> semver::Version {
        self.http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.conduit_version()
    }

    fn method(&self) -> Method {
        self.method()
    }

    fn scheme(&self) -> Scheme {
        self.scheme()
    }

    fn host<'a>(&'a self) -> Host<'a> {
        self.host()
    }

    fn virtual_root<'a>(&'a self) -> Option<&'a str> {
        self.virtual_root()
    }

    fn path<'a>(&'a self) -> &'a str {
        self.path()
    }

    fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.query_string()
    }

    fn remote_ip(&self) -> IpAddr {
        self.remote_ip()
    }

    fn content_length(&self) -> Option<uint> {
        self.content_length()
    }

    fn headers<'a>(&'a self) -> &'a Headers {
        self.headers()
    }

    fn body<'a>(&'a mut self) -> &'a mut Reader {
        self.body()
    }

    fn extensions<'a>(&'a self) -> &'a Extensions {
        self.extensions()
    }

    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
        self.mut_extensions()
    }
}

type RawHeaders = HashMap<String, Vec<String>>;
type InHeader<'a> = (&'a String, &'a Vec<String>);
type OutHeader<'a> = (String, &'a Vec<String>);

#[deriving(PartialEq, Clone, Show)]
pub struct HeaderMap(HashMap<String, Vec<String>>);

impl HeaderMap {
    fn normalize(headers: HashMap<String, Vec<String>>) -> HeaderMap {
        let headers = headers.into_iter().map(|(k,v)| (to_lower(&k), v)).collect();
        HeaderMap(headers)
    }

    fn iter<'a>(&'a self) -> iter::Map<'a, InHeader<'a>, OutHeader<'a>, Entries<'a, String, Vec<String>>> {
        self.as_ref().iter().map(|(k,v)| (to_lower(k), v))
    }

    fn as_ref<'a>(&'a self) -> &'a HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref map) => map
        }
    }

    fn as_mut<'a>(&'a mut self) -> &'a mut HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref mut map) => map
        }
    }

    pub fn len(&self) -> uint {
        self.as_ref().len()
    }
    pub fn clear(&mut self) {
        self.as_mut().clear()
    }
    pub fn find<'a, S: Str>(&'a self, key: &S) -> Option<&'a Vec<String>> {
        self.as_ref().find(&to_lower(key))
    }
    pub fn insert<S: Str>(&mut self, k: S, v: Vec<String>) -> Option<Vec<String>> {
        self.as_mut().swap(to_lower(&k), v)
    }
    pub fn remove<S: Str>(&mut self, k: &S) -> Option<Vec<String>> {
        self.as_mut().pop(&to_lower(k))
    }

    pub fn find_mut<'a, S: Str>(&'a mut self, k: &S) -> Option<&'a mut Vec<String>> {
        self.as_mut().find_mut(&to_lower(k))
    }
}

fn to_lower<S: Str>(string: &S) -> String {
    string.as_slice().chars().map(|c| c.to_lowercase()).collect()
}

#[cfg(test)]
mod tests {
    extern crate "conduit-test" as test;

    use {RequestDelegator, HeaderMap};

    use std::collections::HashMap;
    use conduit;
    use conduit::{Request, Method};

    struct OverrideRequest<'a> {
        request: &'a mut Request + 'a
    }

    impl<'a> RequestDelegator for OverrideRequest<'a> {
        fn request<'a>(&'a self) -> &'a Request {
            let req: &Request = self.request; req
        }

        fn mut_request<'a>(&'a mut self) -> &'a mut Request {
            let req: &mut Request = self.request; req
        }

        fn method(&self) -> Method {
            conduit::Get
        }
    }

    #[test]
    fn test_delegate() {
        let request = &mut test::MockRequest::new(conduit::Head, "/hello") as &mut Request;
        let new = OverrideRequest { request: request };

        assert_eq!(new.method(), conduit::Get);
        assert_eq!(new.path(), "/hello");
    }

    #[test]
    fn test_header_map() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));
        map.insert("location".to_string(), vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())))
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())))
    }

    #[test]
    fn test_header_map_with_static_inserts() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())))
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())))
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())))
    }

    #[test]
    fn test_normalize() {
        let mut map = HashMap::new();
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));

        let headers = HeaderMap::normalize(map);
        assert_eq!(headers.find(&"Content-Type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"Content-Type"), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())))
        assert_eq!(headers.find(&"content-type"), Some(&vec!("text/html".to_string())))
    }

    #[test]
    fn test_iterate() {
        let mut headers = HeaderMap(HashMap::new());
        headers.insert("Content-Type", vec!("text/html".to_string()));
        headers.insert("location", vec!("http://example.com".to_string()));

        assert!(headers.iter().any(|t| t == ("content-type".to_string(), &vec!("text/html".to_string()))));
        assert!(headers.iter().any(|t| t == ("location".to_string(), &vec!("http://example.com".to_string()))));
        assert!(headers.iter().count() == 2);
    }
}
<|endoftext|>


<commit_before>pub trait Array<T>
{
    // taken from the slice impl
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool;
    fn first(&self) -> Option<&T>;
    fn first_mut(&mut self) -> Option<&mut T>;
    fn last(&self) -> Option<&T>;
    fn last_mut(&mut self) -> Option<&mut T>;
    fn get(&self, index: usize) -> Option<&T>;
    fn get_mut(&mut self, index: usize) -> Option<&mut T>;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
    // convenience methods
    fn as_slice(&self) -> &[T];
    fn as_mut_slice(&mut self) -> &mut [T];
    fn map<F>(self, f: F) -> Self where T: Copy, F: FnMut(T) -> T;
    fn foldl<A, F>(self, acc: A, f: F) -> A where T: Copy, F: FnMut(A, T) -> A;
    fn foldr<A, F>(self, acc: A, f: F) -> A where T: Copy, F: FnMut(A, T) -> A;
    fn from_fn<F>(f: F) -> Self where F: FnMut(usize) -> T;
    fn from_iter<I: Iterator<Item=T>>(iter: I) -> Option<Self> where Self: Sized;
}

// for arrays with 1+ elements
macro_rules! impl_array
{
    (@replace $a:expr, $sub:expr) => ($sub);

    (@do_impl $count:tt $($idx:tt)+) => {
        impl<T> $crate::Array<T> for [T; $count]
        {
            fn len(&self) -> usize { $count }
            fn is_empty(&self) -> bool { false }
            fn first(&self) -> Option<&T> { Some(&self[0]) }
            fn first_mut(&mut self) -> Option<&mut T> { Some(&mut self[0]) }
            fn last(&self) -> Option<&T> { Some(&self[$count - 1]) }
            fn last_mut(&mut self) -> Option<&mut T> { Some(&mut self[$count - 1]) }
            fn get(&self, index: usize) -> Option<&T> { if index < $count { Some(&self[index]) } else { None } }
            fn get_mut(&mut self, index: usize) -> Option<&mut T> { if index < $count { Some(&mut self[index]) } else { None } }
            fn as_ptr(&self) -> *const T { &self[0] }
            fn as_mut_ptr(&mut self) -> *mut T { &mut self[0] }
            fn as_slice(&self) -> &[T] { self }
            fn as_mut_slice(&mut self) -> &mut [T] { self }
            fn map<F>(self, mut f: F) -> Self where T: Copy, F: FnMut(T) -> T { [$( f(self[$count - $idx - 1]) ),+] }
            fn foldl<A, F>(self, mut acc: A, mut f: F) -> A where T: Copy, F: FnMut(A, T) -> A { $( acc = f(acc, self[$count - $idx - 1]); )+ acc }
            fn foldr<A, F>(self, mut acc: A, mut f: F) -> A where T: Copy, F: FnMut(A, T) -> A { $( acc = f(acc, self[$idx]); )+ acc }
            fn from_fn<F>(mut f: F) -> Self where F: FnMut(usize) -> T { [$( f($count - $idx - 1) ),+] }
            fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> Option<Self>
            {
                Some([$( impl_array!(@replace $idx, match iter.next() { Some(v) => v, None => return None }) ),+])
            }
        }
    };

    ($count:tt $idx:tt) => { impl_array!(@do_impl $count $idx); };
    ($head:tt $($tail:tt)+) => { impl_array!(@do_impl $head $($tail)+); impl_array!($($tail)+); };
}

// implement sizes from 32 to 1
impl_array!(32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0);

// special case for the empty array
impl<T> Array<T> for [T; 0]
{
    fn len(&self) -> usize { 0 }
    fn is_empty(&self) -> bool { true }
    fn first(&self) -> Option<&T> { None }
    fn first_mut(&mut self) -> Option<&mut T> { None }
    fn last(&self) -> Option<&T> { None }
    fn last_mut(&mut self) -> Option<&mut T> { None }
    fn get(&self, _index: usize) -> Option<&T> { None }
    fn get_mut(&mut self, _index: usize) -> Option<&mut T> { None }
    fn as_ptr(&self) -> *const T { self as _ }
    fn as_mut_ptr(&mut self) -> *mut T { get_mut_ptr(self) }
    fn as_slice(&self) -> &[T] { self }
    fn as_mut_slice(&mut self) -> &mut [T] { self }
    fn map<F>(self, _f: F) -> Self where T: Copy, F: FnMut(T) -> T { self }
    fn foldl<A, F>(self, acc: A, _f: F) -> A where T: Copy, F: FnMut(A, T) -> A { acc }
    fn foldr<A, F>(self, acc: A, _f: F) -> A where T: Copy, F: FnMut(A, T) -> A { acc }
    fn from_fn<F>(_f: F) -> Self where F: FnMut(usize) -> T { [] }
    fn from_iter<I: Iterator<Item=T>>(_iter: I) -> Option<Self> { Some([]) }
}

// workaround to not being able to cast `&mut [T; 0]` to `*mut T` directly
fn get_mut_ptr<T>(a: &mut [T; 0]) -> *mut T { a.as_mut_ptr() }

#[cfg(test)]
mod tests;
<commit_msg>added doc comments<commit_after>//! Extra functionality for Rust arrays.

/// Generic array type.
///
/// This trait allows passing arrays by value in a generic way without turning them into slices,
/// so the functions get monomorphized for a specific size.
///
/// # Examples
/// ```
/// use array_ext::Array;
///
/// fn average<T: Array<f32>>(arr: T) -> f32
/// {
///     let n = arr.len() as f32;
///     arr.foldl(0.0, |acc, val| acc + val) / n
/// }
///
/// assert_eq!(average([8.96, 3.14, 17.9]), 10.0);
/// ```
pub trait Array<T>
{
    /// Returns the number of elements in the array.
    fn len(&self) -> usize;
    /// Returns true if the array has a length of 0
    fn is_empty(&self) -> bool;
    /// Returns the first element of the array, or `None` if it is empty.
    fn first(&self) -> Option<&T>;
    /// Returns a mutable pointer to the first element of the array, or `None` if it is empty.
    fn first_mut(&mut self) -> Option<&mut T>;
    /// Returns the last element of the array, or `None` if it is empty.
    fn last(&self) -> Option<&T>;
    /// Returns a mutable pointer to the last element of the array, or `None` if it is empty.
    fn last_mut(&mut self) -> Option<&mut T>;
    /// Returns the element of an array at the given index, or `None` if the index is out of bounds.
    fn get(&self, index: usize) -> Option<&T>;
    /// Returns a mutable reference to the element at the given index, or `None` if the index is out of bounds.
    fn get_mut(&mut self, index: usize) -> Option<&mut T>;
    /// Returns an raw pointer to the array's buffer.
    fn as_ptr(&self) -> *const T;
    /// Returns an unsafe mutable pointer to the array's buffer.
    fn as_mut_ptr(&mut self) -> *mut T;
    /// Extracts a slice containing the entire array.
    fn as_slice(&self) -> &[T];
    /// Extracts a mutable slice of the entire array.
    fn as_mut_slice(&mut self) -> &mut [T];
    /// Takes a closure and creates a new array by calling that closure on each element.
    fn map<F>(self, f: F) -> Self where T: Copy, F: FnMut(T) -> T;
    /// Applies a function over the entire array, producing a single final value.
    fn foldl<A, F>(self, acc: A, f: F) -> A where T: Copy, F: FnMut(A, T) -> A;
    /// Applies a function over the entire array (in reverse order), producing a single final value.
    fn foldr<A, F>(self, acc: A, f: F) -> A where T: Copy, F: FnMut(A, T) -> A;
    /// Creates a new array using the provided closure.
    fn from_fn<F>(f: F) -> Self where F: FnMut(usize) -> T;
    /// Creates an array by extracting elements from the provided iterator.
    fn from_iter<I: Iterator<Item=T>>(iter: I) -> Option<Self> where Self: Sized;
}

// for arrays with 1+ elements
macro_rules! impl_array
{
    (@replace $a:expr, $sub:expr) => ($sub);

    (@do_impl $count:tt $($idx:tt)+) => {
        impl<T> $crate::Array<T> for [T; $count]
        {
            fn len(&self) -> usize { $count }
            fn is_empty(&self) -> bool { false }
            fn first(&self) -> Option<&T> { Some(&self[0]) }
            fn first_mut(&mut self) -> Option<&mut T> { Some(&mut self[0]) }
            fn last(&self) -> Option<&T> { Some(&self[$count - 1]) }
            fn last_mut(&mut self) -> Option<&mut T> { Some(&mut self[$count - 1]) }
            fn get(&self, index: usize) -> Option<&T> { if index < $count { Some(&self[index]) } else { None } }
            fn get_mut(&mut self, index: usize) -> Option<&mut T> { if index < $count { Some(&mut self[index]) } else { None } }
            fn as_ptr(&self) -> *const T { &self[0] }
            fn as_mut_ptr(&mut self) -> *mut T { &mut self[0] }
            fn as_slice(&self) -> &[T] { self }
            fn as_mut_slice(&mut self) -> &mut [T] { self }
            fn map<F>(self, mut f: F) -> Self where T: Copy, F: FnMut(T) -> T { [$( f(self[$count - $idx - 1]) ),+] }
            fn foldl<A, F>(self, mut acc: A, mut f: F) -> A where T: Copy, F: FnMut(A, T) -> A { $( acc = f(acc, self[$count - $idx - 1]); )+ acc }
            fn foldr<A, F>(self, mut acc: A, mut f: F) -> A where T: Copy, F: FnMut(A, T) -> A { $( acc = f(acc, self[$idx]); )+ acc }
            fn from_fn<F>(mut f: F) -> Self where F: FnMut(usize) -> T { [$( f($count - $idx - 1) ),+] }
            fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> Option<Self>
            {
                Some([$( impl_array!(@replace $idx, match iter.next() { Some(v) => v, None => return None }) ),+])
            }
        }
    };

    ($count:tt $idx:tt) => { impl_array!(@do_impl $count $idx); };
    ($head:tt $($tail:tt)+) => { impl_array!(@do_impl $head $($tail)+); impl_array!($($tail)+); };
}

// implement sizes from 32 to 1
impl_array!(32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0);

// special case for the empty array
impl<T> Array<T> for [T; 0]
{
    fn len(&self) -> usize { 0 }
    fn is_empty(&self) -> bool { true }
    fn first(&self) -> Option<&T> { None }
    fn first_mut(&mut self) -> Option<&mut T> { None }
    fn last(&self) -> Option<&T> { None }
    fn last_mut(&mut self) -> Option<&mut T> { None }
    fn get(&self, _index: usize) -> Option<&T> { None }
    fn get_mut(&mut self, _index: usize) -> Option<&mut T> { None }
    fn as_ptr(&self) -> *const T { self as _ }
    fn as_mut_ptr(&mut self) -> *mut T { get_mut_ptr(self) }
    fn as_slice(&self) -> &[T] { self }
    fn as_mut_slice(&mut self) -> &mut [T] { self }
    fn map<F>(self, _f: F) -> Self where T: Copy, F: FnMut(T) -> T { self }
    fn foldl<A, F>(self, acc: A, _f: F) -> A where T: Copy, F: FnMut(A, T) -> A { acc }
    fn foldr<A, F>(self, acc: A, _f: F) -> A where T: Copy, F: FnMut(A, T) -> A { acc }
    fn from_fn<F>(_f: F) -> Self where F: FnMut(usize) -> T { [] }
    fn from_iter<I: Iterator<Item=T>>(_iter: I) -> Option<Self> { Some([]) }
}

// workaround to not being able to cast `&mut [T; 0]` to `*mut T` directly
fn get_mut_ptr<T>(a: &mut [T; 0]) -> *mut T { a.as_mut_ptr() }

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>extern crate pnet;
extern crate pnet_datalink;

use std::env;
use std::io::{self, Write};
use std::net::{AddrParseError, IpAddr, Ipv4Addr};
use std::process;

use pnet_datalink::{Channel, MacAddr, NetworkInterface};

use pnet::packet::arp::{ArpHardwareTypes, ArpOperations};
use pnet::packet::arp::{ArpPacket, MutableArpPacket};
use pnet::packet::ethernet::EtherTypes;
use pnet::packet::ethernet::MutableEthernetPacket;
use pnet::packet::{MutablePacket, Packet};

fn get_mac_through_arp(interface: NetworkInterface, target_ip: Ipv4Addr) -> MacAddr {
    let source_ip = interface
        .ips
        .iter()
        .find(|ip| ip.is_ipv4())
        .map(|ip| match ip.ip() {
            IpAddr::V4(ip) => ip,
            _ => unreachable!(),
        })
        .unwrap();

    let (mut sender, mut receiver) = match pnet_datalink::channel(&interface, Default::default()) {
        Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("Unknown channel type"),
        Err(e) => panic!("Error happened {}", e),
    };

    let mut ethernet_buffer = [0u8; 42];
    let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();

    ethernet_packet.set_destination(MacAddr::broadcast());
    ethernet_packet.set_source(interface.mac_address());
    ethernet_packet.set_ethertype(EtherTypes::Arp);

    let mut arp_buffer = [0u8; 28];
    let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap();

    arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet);
    arp_packet.set_protocol_type(EtherTypes::Ipv4);
    arp_packet.set_hw_addr_len(6);
    arp_packet.set_proto_addr_len(4);
    arp_packet.set_operation(ArpOperations::Request);
    arp_packet.set_sender_hw_addr(interface.mac_address());
    arp_packet.set_sender_proto_addr(source_ip);
    arp_packet.set_target_hw_addr(MacAddr::zero());
    arp_packet.set_target_proto_addr(target_ip);

    ethernet_packet.set_payload(arp_packet.packet_mut());

    sender
        .send_to(ethernet_packet.packet(), None)
        .unwrap()
        .unwrap();

    println!("Sent ARP request");

    let buf = receiver.next().unwrap();

    let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();

    println!("Received reply");

    arp.get_sender_hw_addr()
}

fn main() {
    let mut args = env::args().skip(1);
    let iface_name = match args.next() {
        Some(n) => n,
        None => {
            writeln!(
                io::stderr(),
                "USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
            )
            .unwrap();
            process::exit(1);
        }
    };

    let target_ip: Result<Ipv4Addr, AddrParseError> = match args.next() {
        Some(n) => n.parse(),
        None => {
            writeln!(
                io::stderr(),
                "USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
            )
            .unwrap();
            process::exit(1);
        }
    };

    let interfaces = pnet_datalink::interfaces();
    let interface = interfaces
        .into_iter()
        .find(|iface| iface.name == iface_name)
        .unwrap();
    let _source_mac = interface.mac_address();

    let target_mac = get_mac_through_arp(interface, target_ip.unwrap());

    println!("Target MAC address: {}", target_mac);
}
<commit_msg>Update import path and remove deprecated api<commit_after>extern crate pnet;

use std::env;
use std::io::{self, Write};
use std::net::{AddrParseError, IpAddr, Ipv4Addr};
use std::process;

use pnet::datalink::{Channel, MacAddr, NetworkInterface};

use pnet::packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPacket};
use pnet::packet::ethernet::EtherTypes;
use pnet::packet::ethernet::MutableEthernetPacket;
use pnet::packet::{MutablePacket, Packet};

fn get_mac_through_arp(interface: NetworkInterface, target_ip: Ipv4Addr) -> MacAddr {
    let source_ip = interface
        .ips
        .iter()
        .find(|ip| ip.is_ipv4())
        .map(|ip| match ip.ip() {
            IpAddr::V4(ip) => ip,
            _ => unreachable!(),
        })
        .unwrap();

    let (mut sender, mut receiver) = match pnet::datalink::channel(&interface, Default::default()) {
        Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("Unknown channel type"),
        Err(e) => panic!("Error happened {}", e),
    };

    let mut ethernet_buffer = [0u8; 42];
    let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();

    ethernet_packet.set_destination(MacAddr::broadcast());
    ethernet_packet.set_source(interface.mac.unwrap());
    ethernet_packet.set_ethertype(EtherTypes::Arp);

    let mut arp_buffer = [0u8; 28];
    let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap();

    arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet);
    arp_packet.set_protocol_type(EtherTypes::Ipv4);
    arp_packet.set_hw_addr_len(6);
    arp_packet.set_proto_addr_len(4);
    arp_packet.set_operation(ArpOperations::Request);
    arp_packet.set_sender_hw_addr(interface.mac.unwrap());
    arp_packet.set_sender_proto_addr(source_ip);
    arp_packet.set_target_hw_addr(MacAddr::zero());
    arp_packet.set_target_proto_addr(target_ip);

    ethernet_packet.set_payload(arp_packet.packet_mut());

    sender
        .send_to(ethernet_packet.packet(), None)
        .unwrap()
        .unwrap();

    println!("Sent ARP request");

    let buf = receiver.next().unwrap();

    let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();

    println!("Received reply");

    arp.get_sender_hw_addr()
}

fn main() {
    let mut args = env::args().skip(1);
    let iface_name = match args.next() {
        Some(n) => n,
        None => {
            writeln!(
                io::stderr(),
                "USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
            )
            .unwrap();
            process::exit(1);
        }
    };

    let target_ip: Result<Ipv4Addr, AddrParseError> = match args.next() {
        Some(n) => n.parse(),
        None => {
            writeln!(
                io::stderr(),
                "USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
            )
            .unwrap();
            process::exit(1);
        }
    };

    let interfaces = pnet::datalink::interfaces();
    let interface = interfaces
        .into_iter()
        .find(|iface| iface.name == iface_name)
        .unwrap();
    let _source_mac = interface.mac.unwrap();

    let target_mac = get_mac_through_arp(interface, target_ip.unwrap());

    println!("Target MAC address: {}", target_mac);
}<|endoftext|>


<commit_before>#![deny(warnings)]
#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
#![cfg_attr(feature = "cargo-clippy", allow(explicit_iter_loop))]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate glob;
extern crate hex;
extern crate libc;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate toml;
extern crate url;
#[cfg(windows)]
extern crate winapi;

#[macro_use]
mod support;

mod alt_registry;
mod bad_config;
mod bad_manifest_path;
mod bench;
mod build;
mod build_auth;
mod build_lib;
mod build_plan;
mod build_script;
mod build_script_env;
mod cargo_alias_config;
mod cargo_command;
mod cargo_features;
mod cfg;
mod check;
mod clean;
mod concurrent;
mod config;
mod corrupt_git;
mod cross_compile;
mod cross_publish;
mod custom_target;
mod death;
mod dep_info;
mod directory;
mod doc;
mod edition;
mod features;
mod fetch;
mod fix;
mod freshness;
mod generate_lockfile;
mod git;
mod init;
mod install;
mod jobserver;
mod local_registry;
mod lockfile_compat;
mod login;
mod metabuild;
mod metadata;
mod net_config;
mod new;
mod out_dir;
mod overrides;
mod package;
mod patch;
mod path;
mod plugins;
mod proc_macro;
mod profile_config;
mod profile_overrides;
mod profile_targets;
mod profiles;
mod publish;
mod read_manifest;
mod registry;
mod rename_deps;
mod required_features;
mod resolve;
mod run;
mod rustc;
mod rustc_info_cache;
mod rustdoc;
mod rustdocflags;
mod rustflags;
mod search;
mod shell_quoting;
mod small_fd_limits;
mod test;
mod tool_paths;
mod update;
mod verify_project;
mod version;
mod warn_on_failure;
mod workspaces;
<commit_msg>Run the cross-compile disable check ASAP<commit_after>#![deny(warnings)]
#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
#![cfg_attr(feature = "cargo-clippy", allow(explicit_iter_loop))]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate glob;
extern crate hex;
extern crate libc;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate toml;
extern crate url;
#[cfg(windows)]
extern crate winapi;

#[macro_use]
mod support;

mod alt_registry;
mod bad_config;
mod bad_manifest_path;
mod bench;
mod build;
mod build_auth;
mod build_lib;
mod build_plan;
mod build_script;
mod build_script_env;
mod cargo_alias_config;
mod cargo_command;
mod cargo_features;
mod cfg;
mod check;
mod clean;
mod concurrent;
mod config;
mod corrupt_git;
mod cross_compile;
mod cross_publish;
mod custom_target;
mod death;
mod dep_info;
mod directory;
mod doc;
mod edition;
mod features;
mod fetch;
mod fix;
mod freshness;
mod generate_lockfile;
mod git;
mod init;
mod install;
mod jobserver;
mod local_registry;
mod lockfile_compat;
mod login;
mod metabuild;
mod metadata;
mod net_config;
mod new;
mod out_dir;
mod overrides;
mod package;
mod patch;
mod path;
mod plugins;
mod proc_macro;
mod profile_config;
mod profile_overrides;
mod profile_targets;
mod profiles;
mod publish;
mod read_manifest;
mod registry;
mod rename_deps;
mod required_features;
mod resolve;
mod run;
mod rustc;
mod rustc_info_cache;
mod rustdoc;
mod rustdocflags;
mod rustflags;
mod search;
mod shell_quoting;
mod small_fd_limits;
mod test;
mod tool_paths;
mod update;
mod verify_project;
mod version;
mod warn_on_failure;
mod workspaces;

#[test]
fn aaa_trigger_cross_compile_disabled_check() {
    // This triggers the cross compile disabled check to run ASAP, see #5141
    support::cross_compile::disabled();
}
<|endoftext|>


<commit_before>/*!

*/

/*!

*/
#![feature(specialization)]

mod deps;
pub mod extension;

use std::any::Any;
use std::fmt;
use std::slice;
use std::convert;
use std::result;
use std::error;
use std::vec;
pub use deps::{ Deps, Scope };

pub struct Collection<T> {
    items: Vec<T>,
}

impl<T> fmt::Debug for Collection<T> where T: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.items.iter()).finish()
    }
}

impl<T> Collection<T> {
    pub fn new() -> Collection<T> {
        Collection {
            items: Vec::new()
        }
    }

    pub fn push(&mut self, item: T) {
        self.items.push(item)
    }
}

impl<T> convert::AsRef<[T]> for Collection<T> {
    fn as_ref(&self) -> &[T] {
        &self.items
    }
}

pub struct CollectionIter<'a, T: 'a> {
    inner: slice::Iter<'a, T>,
}

impl<'a, T: 'a> Iterator for CollectionIter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        self.inner.next()
    }
}

impl<'a, T> IntoIterator for &'a Collection<T> {
    type IntoIter = CollectionIter<'a, T>;
    type Item = &'a T;

    fn into_iter(self) -> CollectionIter<'a, T> {
        CollectionIter { inner: self.items.iter() }
    }
}

impl<T> IntoIterator for Collection<T> {
    type IntoIter = vec::IntoIter<T>;
    type Item = T;

    fn into_iter(self) -> vec::IntoIter<T> {
        self.items.into_iter()
    }
}

impl<T> Into<Vec<T>> for Collection<T> {
    fn into(self) -> Vec<T> {
        self.items
    }
}

pub struct Expect<T: Any> {
    response: Option<T>,
}

impl<T: Any> Expect<T> {
    pub fn load(deps: &Deps) -> Result<T> {
        let expectation = Expect::<T> {
            response: None,
        };
        let maybe_fullfilled = try!(deps.create(expectation)).explode();
        match maybe_fullfilled.response {
            Some(value) => Ok(value),
            None => Err(Box::new(Error::ExpectedDependencyNotFound)),
        }
    }

    pub fn replace(&mut self, value: T) -> Result<()> {
        if let Some(_) = self.response {
            return Err(Box::new(Error::ExpectedDependencyWasAlreadyFullfilled));
        }

        self.response = Some(value);

        Ok(())
    }
}

pub fn load_from<T: Any>(deps: &Deps) -> Result<T> {
    Expect::load(deps)
}

#[derive(Debug)]
pub enum Error {
    ExpectedDependencyNotFound,
    ExpectedDependencyWasAlreadyFullfilled,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::ExpectedDependencyNotFound => "Expected dependency not found".fmt(f),
            Error::ExpectedDependencyWasAlreadyFullfilled => "Expected dependency was already fullfilled".fmt(f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &'static str {
        match *self {
            Error::ExpectedDependencyNotFound => "expected dependency not found",
            Error::ExpectedDependencyWasAlreadyFullfilled => "expected dependency was already fullfilled",
        }
    }
}

pub type Result<T> = result::Result<T, Box<error::Error>>;
<commit_msg>Mutable iter for collection.<commit_after>/*!

*/

/*!

*/
#![feature(specialization)]

mod deps;
pub mod extension;

use std::any::Any;
use std::fmt;
use std::slice;
use std::convert;
use std::result;
use std::error;
use std::vec;
pub use deps::{ Deps, Scope };

pub struct Collection<T> {
    items: Vec<T>,
}

impl<T> fmt::Debug for Collection<T> where T: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.items.iter()).finish()
    }
}

impl<T> Collection<T> {
    pub fn new() -> Collection<T> {
        Collection {
            items: Vec::new()
        }
    }

    pub fn push(&mut self, item: T) {
        self.items.push(item)
    }
}

impl<T> convert::AsRef<[T]> for Collection<T> {
    fn as_ref(&self) -> &[T] {
        &self.items
    }
}

impl<'a, T> IntoIterator for &'a Collection<T> {
    type IntoIter = slice::Iter<'a, T>;
    type Item = &'a T;

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

impl<'a, T> IntoIterator for &'a mut Collection<T> {
    type IntoIter = slice::IterMut<'a, T>;
    type Item = &'a mut T;

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

impl<T> IntoIterator for Collection<T> {
    type IntoIter = vec::IntoIter<T>;
    type Item = T;

    fn into_iter(self) -> vec::IntoIter<T> {
        self.items.into_iter()
    }
}

impl<T> Into<Vec<T>> for Collection<T> {
    fn into(self) -> Vec<T> {
        self.items
    }
}

pub struct Expect<T: Any> {
    response: Option<T>,
}

impl<T: Any> Expect<T> {
    pub fn load(deps: &Deps) -> Result<T> {
        let expectation = Expect::<T> {
            response: None,
        };
        let maybe_fullfilled = try!(deps.create(expectation)).explode();
        match maybe_fullfilled.response {
            Some(value) => Ok(value),
            None => Err(Box::new(Error::ExpectedDependencyNotFound)),
        }
    }

    pub fn replace(&mut self, value: T) -> Result<()> {
        if let Some(_) = self.response {
            return Err(Box::new(Error::ExpectedDependencyWasAlreadyFullfilled));
        }

        self.response = Some(value);

        Ok(())
    }
}

pub fn load_from<T: Any>(deps: &Deps) -> Result<T> {
    Expect::load(deps)
}

#[derive(Debug)]
pub enum Error {
    ExpectedDependencyNotFound,
    ExpectedDependencyWasAlreadyFullfilled,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::ExpectedDependencyNotFound => "Expected dependency not found".fmt(f),
            Error::ExpectedDependencyWasAlreadyFullfilled => "Expected dependency was already fullfilled".fmt(f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &'static str {
        match *self {
            Error::ExpectedDependencyNotFound => "expected dependency not found",
            Error::ExpectedDependencyWasAlreadyFullfilled => "expected dependency was already fullfilled",
        }
    }
}

pub type Result<T> = result::Result<T, Box<error::Error>>;
<|endoftext|>


<commit_before>// Copyright 2016 Doug Goldstein
//
// 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.

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level. Additionally it supports the
//! ability to provide timestamps at different granularities.
//!
//! ## Simple Use Case
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().module(module_path!()).init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```
//!
//! ## docopt Example
//!
//! ```rust
//! extern crate docopt;
//! #[macro_use]
//! extern crate log;
//! extern crate rustc_serialize;
//! extern crate stderrlog;
//!
//! use docopt::Docopt;
//!
//! const USAGE: &'static str = "
//! Usage: program [-q] [-v...]
//! ";
//!
//! #[derive(Debug, RustcDecodable)]
//! struct Args {
//!     flag_q: bool,
//!     flag_v: usize,
//! }
//!
//! fn main() {
//!     let args: Args = Docopt::new(USAGE)
//!                             .and_then(|d| d.decode())
//!                             .unwrap_or_else(|e| e.exit());
//!
//!     stderrlog::new()
//!             .module(module_path!())
//!             .quiet(args.flag_q)
//!             .timestamp(stderrlog::Timestamp::Second)
//!             .verbosity(args.flag_v)
//!             .init()
//!             .unwrap();
//!     trace!("trace message");
//!     debug!("debug message");
//!     info!("info message");
//!     warn!("warn message");
//!     error!("error message");
//!
//!     // ...
//! }
//! ```
//!
//! # clap Example
//!
//! ```
//! #[macro_use]
//! extern crate clap;
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let m = App::new("stderrlog example")
//!         .version(crate_version!())
//!         .arg(Arg::with_name("verbosity")
//!              .short("v")
//!              .multiple(true)
//!              .help("Increase message verbosity"))
//!         .arg(Arg::with_name("quiet")
//!              .short("q")
//!              .help("Silence all output"))
//!         .arg(Arg::with_name("timestamp")
//!              .short("t")
//!              .help("prepend log lines with a timestamp")
//!              .takes_value(true)
//!              .possible_values(&["none", "sec", "ms", "ns"]))
//!         .get_matches();
//!
//!     let verbose = m.occurrences_of("verbosity") as usize;
//!     let quiet = m.is_present("quiet");
//!     let ts = match m.value_of("timestamp") {
//!         Some("ns") => stderrlog::Timestamp::Nanosecond,
//!         Some("ms") => stderrlog::Timestamp::Microsecond,
//!         Some("sec") => stderrlog::Timestamp::Second,
//!         Some("none") | None => stderrlog::Timestamp::Off,
//!         Some(_) => clap::Error {
//!             message: "invalid value for 'timestamp'".into(),
//!             kind: clap::ErrorKind::InvalidValue,
//!             info: None,
//!         }.exit(),
//!     };
//!
//!     stderrlog::new()
//!         .module(module_path!())
//!         .quiet(quiet)
//!         .verbosity(verbose)
//!         .timestamp(ts)
//!         .init()
//!         .unwrap();
//!     trace!("trace message");
//!     debug!("debug message");
//!     info!("info message");
//!     warn!("warn message");
//!     error!("error message");
//! }
//! ```

extern crate chrono;
extern crate log;
extern crate thread_local;

use chrono::Local;
use log::{LogLevelFilter, LogMetadata};
use std::cell::RefCell;
use std::io::{self, Write};
use std::fmt;
use thread_local::CachedThreadLocal;

/// State of the timestampping in the logger.
#[derive(Clone, Copy, Debug)]
pub enum Timestamp {
    /// Disable timestamping of log messages
    Off,
    /// Timestamp with second granularity
    Second,
    /// Timestamp with microsecond granularity
    Microsecond,
    /// Timestamp with nanosecond granularity
    Nanosecond,
}

pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
    timestamp: Timestamp,
    modules: Vec<String>,
    writer: CachedThreadLocal<RefCell<io::LineWriter<io::Stderr>>>,
}

impl fmt::Debug for StdErrLog {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("StdErrLog")
            .field("verbosity", &self.verbosity)
            .field("quiet", &self.quiet)
            .field("timestamp", &self.timestamp)
            .field("modules", &self.modules)
            .field("writer", &"stderr")
            .finish()
    }
}

impl Clone for StdErrLog {
    fn clone(&self) -> StdErrLog {
        StdErrLog {
            verbosity: self.verbosity,
            quiet: self.quiet,
            timestamp: self.timestamp,
            modules: self.modules.clone(),
            writer: CachedThreadLocal::new(),
        }
    }
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level_filter()
    }

    fn log(&self, record: &log::LogRecord) {

        // if logging isn't enabled for this level do a quick out
        if !self.enabled(record.metadata()) {
            return;
        }

        // module we are logging for
        let curr_mod = record.location().module_path();

        // this logger only logs the requested modules unless the
        // vector of modules is empty
        // modules will have module::file in the module_path
        if self.includes_module(curr_mod) {
            let writer =
                self.writer.get_or(|| Box::new(RefCell::new(io::LineWriter::new(io::stderr()))));
            let mut writer = writer.borrow_mut();
            match self.timestamp {
                Timestamp::Second => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Microsecond => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%.6f%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Nanosecond => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%.9f%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Off => {},
            }
            let _ = writeln!(writer, "{} - {}", record.level(), record.args());
        }
    }
}

impl StdErrLog {
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
            timestamp: Timestamp::Off,
            modules: Vec::new(),
            writer: CachedThreadLocal::new(),
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    /// Enables or disables the use of timestamps in log messages
    pub fn timestamp(&mut self, timestamp: Timestamp) -> &mut StdErrLog {
        self.timestamp = timestamp;
        self
    }

    pub fn module<T: Into<String>>(&mut self, module: T) -> &mut StdErrLog {
        let to_insert = module.into();
        // If Ok, the module was already found
        if let Err(i) = self.modules.binary_search(&to_insert) {
            self.modules.insert(i, to_insert);
        }
        self
    }

    pub fn modules<T: Into<String>, I: IntoIterator<Item = T>>(&mut self,
                                                               modules: I)
                                                               -> &mut StdErrLog {
        for module in modules {
            self.module(module);
        }
        self
    }

    fn log_level_filter(&self) -> LogLevelFilter {
        if self.quiet {
            LogLevelFilter::Off
        } else {
            self.verbosity
        }
    }

    fn includes_module(&self, module_path: &str) -> bool {
        // If modules is empty, include all module paths
        if self.modules.is_empty() {
            return true;
        }
        // if a prefix of module_path is in `self.modules`, it must
        // be located at the first location before
        // where module_path would be.
        match self.modules.binary_search_by(|module| module.as_str().cmp(&module_path)) {
            Ok(_) => {
                // Found exact module: return true
                true
            }
            Err(0) => {
                // if there's no item which would be located before module_path, no prefix is there
                false
            }
            Err(i) => {
                module_path.starts_with(&self.modules[i - 1])
            }
        }
    }

    pub fn init(&self) -> Result<(), log::SetLoggerError> {
        log::set_logger(|max_log_level| {
                            max_log_level.set(self.log_level_filter());

                            Box::new(self.clone())
                        })
    }
}

pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().module(module_path!()).init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<commit_msg>document all methods and provide impl Default<commit_after>// Copyright 2016 Doug Goldstein
//
// 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.

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level. Additionally it supports the
//! ability to provide timestamps at different granularities.
//!
//! ## Simple Use Case
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().module(module_path!()).init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```
//!
//! ## docopt Example
//!
//! ```rust
//! extern crate docopt;
//! #[macro_use]
//! extern crate log;
//! extern crate rustc_serialize;
//! extern crate stderrlog;
//!
//! use docopt::Docopt;
//!
//! const USAGE: &'static str = "
//! Usage: program [-q] [-v...]
//! ";
//!
//! #[derive(Debug, RustcDecodable)]
//! struct Args {
//!     flag_q: bool,
//!     flag_v: usize,
//! }
//!
//! fn main() {
//!     let args: Args = Docopt::new(USAGE)
//!                             .and_then(|d| d.decode())
//!                             .unwrap_or_else(|e| e.exit());
//!
//!     stderrlog::new()
//!             .module(module_path!())
//!             .quiet(args.flag_q)
//!             .timestamp(stderrlog::Timestamp::Second)
//!             .verbosity(args.flag_v)
//!             .init()
//!             .unwrap();
//!     trace!("trace message");
//!     debug!("debug message");
//!     info!("info message");
//!     warn!("warn message");
//!     error!("error message");
//!
//!     // ...
//! }
//! ```
//!
//! # clap Example
//!
//! ```
//! #[macro_use]
//! extern crate clap;
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let m = App::new("stderrlog example")
//!         .version(crate_version!())
//!         .arg(Arg::with_name("verbosity")
//!              .short("v")
//!              .multiple(true)
//!              .help("Increase message verbosity"))
//!         .arg(Arg::with_name("quiet")
//!              .short("q")
//!              .help("Silence all output"))
//!         .arg(Arg::with_name("timestamp")
//!              .short("t")
//!              .help("prepend log lines with a timestamp")
//!              .takes_value(true)
//!              .possible_values(&["none", "sec", "ms", "ns"]))
//!         .get_matches();
//!
//!     let verbose = m.occurrences_of("verbosity") as usize;
//!     let quiet = m.is_present("quiet");
//!     let ts = match m.value_of("timestamp") {
//!         Some("ns") => stderrlog::Timestamp::Nanosecond,
//!         Some("ms") => stderrlog::Timestamp::Microsecond,
//!         Some("sec") => stderrlog::Timestamp::Second,
//!         Some("none") | None => stderrlog::Timestamp::Off,
//!         Some(_) => clap::Error {
//!             message: "invalid value for 'timestamp'".into(),
//!             kind: clap::ErrorKind::InvalidValue,
//!             info: None,
//!         }.exit(),
//!     };
//!
//!     stderrlog::new()
//!         .module(module_path!())
//!         .quiet(quiet)
//!         .verbosity(verbose)
//!         .timestamp(ts)
//!         .init()
//!         .unwrap();
//!     trace!("trace message");
//!     debug!("debug message");
//!     info!("info message");
//!     warn!("warn message");
//!     error!("error message");
//! }
//! ```

extern crate chrono;
extern crate log;
extern crate thread_local;

use chrono::Local;
use log::{LogLevelFilter, LogMetadata};
use std::cell::RefCell;
use std::io::{self, Write};
use std::fmt;
use thread_local::CachedThreadLocal;

/// State of the timestampping in the logger.
#[derive(Clone, Copy, Debug)]
pub enum Timestamp {
    /// Disable timestamping of log messages
    Off,
    /// Timestamp with second granularity
    Second,
    /// Timestamp with microsecond granularity
    Microsecond,
    /// Timestamp with nanosecond granularity
    Nanosecond,
}

/// Data specific to this logger
pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
    timestamp: Timestamp,
    modules: Vec<String>,
    writer: CachedThreadLocal<RefCell<io::LineWriter<io::Stderr>>>,
}

impl fmt::Debug for StdErrLog {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("StdErrLog")
            .field("verbosity", &self.verbosity)
            .field("quiet", &self.quiet)
            .field("timestamp", &self.timestamp)
            .field("modules", &self.modules)
            .field("writer", &"stderr")
            .finish()
    }
}

impl Clone for StdErrLog {
    fn clone(&self) -> StdErrLog {
        StdErrLog {
            verbosity: self.verbosity,
            quiet: self.quiet,
            timestamp: self.timestamp,
            modules: self.modules.clone(),
            writer: CachedThreadLocal::new(),
        }
    }
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level_filter()
    }

    fn log(&self, record: &log::LogRecord) {

        // if logging isn't enabled for this level do a quick out
        if !self.enabled(record.metadata()) {
            return;
        }

        // module we are logging for
        let curr_mod = record.location().module_path();

        // this logger only logs the requested modules unless the
        // vector of modules is empty
        // modules will have module::file in the module_path
        if self.includes_module(curr_mod) {
            let writer =
                self.writer.get_or(|| Box::new(RefCell::new(io::LineWriter::new(io::stderr()))));
            let mut writer = writer.borrow_mut();
            match self.timestamp {
                Timestamp::Second => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Microsecond => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%.6f%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Nanosecond => {
                    let fmt = "%Y-%m-%dT%H:%M:%S%.9f%:z";
                    let _ = write!(writer, "{} - ", Local::now().format(fmt));
                },
                Timestamp::Off => {},
            }
            let _ = writeln!(writer, "{} - {}", record.level(), record.args());
        }
    }
}

impl StdErrLog {
    /// creates a new stderr logger
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
            timestamp: Timestamp::Off,
            modules: Vec::new(),
            writer: CachedThreadLocal::new(),
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    /// silence all output, no matter the value of verbosity
    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    /// Enables or disables the use of timestamps in log messages
    pub fn timestamp(&mut self, timestamp: Timestamp) -> &mut StdErrLog {
        self.timestamp = timestamp;
        self
    }

    /// specify a module to allow to log to stderr
    pub fn module<T: Into<String>>(&mut self, module: T) -> &mut StdErrLog {
        let to_insert = module.into();
        // If Ok, the module was already found
        if let Err(i) = self.modules.binary_search(&to_insert) {
            self.modules.insert(i, to_insert);
        }
        self
    }

    /// specifiy modules to allow to log to stderr
    pub fn modules<T: Into<String>, I: IntoIterator<Item = T>>(&mut self,
                                                               modules: I)
                                                               -> &mut StdErrLog {
        for module in modules {
            self.module(module);
        }
        self
    }

    fn log_level_filter(&self) -> LogLevelFilter {
        if self.quiet {
            LogLevelFilter::Off
        } else {
            self.verbosity
        }
    }

    fn includes_module(&self, module_path: &str) -> bool {
        // If modules is empty, include all module paths
        if self.modules.is_empty() {
            return true;
        }
        // if a prefix of module_path is in `self.modules`, it must
        // be located at the first location before
        // where module_path would be.
        match self.modules.binary_search_by(|module| module.as_str().cmp(&module_path)) {
            Ok(_) => {
                // Found exact module: return true
                true
            }
            Err(0) => {
                // if there's no item which would be located before module_path, no prefix is there
                false
            }
            Err(i) => {
                module_path.starts_with(&self.modules[i - 1])
            }
        }
    }

    /// sets the the logger as active
    pub fn init(&self) -> Result<(), log::SetLoggerError> {
        log::set_logger(|max_log_level| {
                            max_log_level.set(self.log_level_filter());

                            Box::new(self.clone())
                        })
    }
}

impl Default for StdErrLog {
    fn default() -> Self {
        StdErrLog::new()
    }
}

/// creates a new stderr logger
pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().module(module_path!()).init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<|endoftext|>


<commit_before>#![feature(slicing_syntax)]
extern crate test;

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{Writer, Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
use ograph::{
    EdgeType,
};

pub use self::EdgeDirection::{Outgoing, Incoming};

mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, S: Writer> Hash<S> for Ptr<'b, T>
{
    fn hash(&self, st: &mut S)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Dijkstra's shortest path algorithm.
pub fn dijkstra<'a, Graph, N, K, F, Edges>(graph: &'a Graph,
                                           start: N,
                                           goal: Option<N>,
                                           mut edges: F) -> HashMap<N, K> where
    Graph: Visitable<N>,
    N: Copy + Clone + Eq + Hash + fmt::Show,
    K: Default + Add<Output=K> + Copy + PartialOrd + fmt::Show,
    F: FnMut(&'a Graph, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
    <Graph as Visitable<N>>::Map: VisitMap<N>,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.contains(&node) {
            continue
        }
        for (next, edge) in edges(graph, node) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(&next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next, node);
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next, node);
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        visited.visit(node);
    }
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({})", self.0.get())
    }
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait IntoNeighbors<N> : Copy {
    type Iter: Iterator<Item=N>;
    fn neighbors(self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> IntoNeighbors<N> for &'a Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> IntoNeighbors<N> for &'a DiGraph<N, E>
where N: Copy + Clone + Hash + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E, ETy: EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a OGraph<N, E, ETy>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct Undirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> IntoNeighbors< ograph::NodeIndex> for &'a Undirected<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_both(self.0, n)
    }
}

impl<'a, 'b, N, E, ETy: EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a Reversed<&'b OGraph<N, E, ETy>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable<N> {
    type Map: VisitMap<N>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, ETy> Visitable<ograph::NodeIndex> for OGraph<N, E, ETy> where
    ETy: ograph::EdgeType,
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Undirected<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Reversed<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G: 'a, N> Iterator for BreadthFirst<'a, G, N> where
    &'a G: IntoNeighbors<N>,
    N: Copy + Eq + Hash,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// A depth first traversal of a graph.
#[derive(Clone)]
pub struct DepthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: Vec<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> DepthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> DepthFirst<'a, G, N>
    {
        DepthFirst{
            graph: graph,
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl<'a, G, N> Iterator for DepthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub fn depth_first_search<'a, G, N, F>(graph: &'a G, start: N, mut f: F) -> bool where
    G: 'a + Visitable<N>,
    &'a G: IntoNeighbors<N>,
    N: Clone,
    <&'a G as IntoNeighbors<N>>::Iter: Iterator<Item=N>,
    <G as Visitable<N>>::Map: VisitMap<N>,
    F: FnMut(N) -> bool,
{
    let mut stack = Vec::new();
    let mut visited = graph.visit_map();

    stack.push(start);
    while let Some(node) = stack.pop() {
        if !visited.visit(node.clone()) {
            continue;
        }

        for succ in graph.neighbors(node.clone()) {
            if !visited.contains(&succ) {
                stack.push(succ);
            }
        }

        if !f(node) {
            return false
        }
    }
    true
}

/// Run a DFS over an **OGraph**, passing a mutable ref to the graph to the
/// iteration function on each step.
///
/// **Note:** The algorithm will not behave correctly if nodes are removed
/// during iteration. It will not necessarily visit added nodes or edges.
pub fn depth_first_search_mut<'a, N, E, ETy, F>(graph: &'a mut OGraph<N, E, ETy>,
                                                start: ograph::NodeIndex,
                                                mut f: F) -> bool where
    ETy: ograph::EdgeType,
    F: FnMut(&mut OGraph<N, E, ETy>, ograph::NodeIndex) -> bool,
{
    let mut stack = Vec::new();
    let mut visited = graph.visit_map();

    stack.push(start);
    while let Some(node) = stack.pop() {
        if !visited.visit(node) {
            continue;
        }

        for succ in graph.neighbors(node) {
            if !visited.contains(&succ.0) {
                stack.push(succ);
            }
        }

        if !f(graph, node) {
            return false
        }
    }
    true
}

<commit_msg>Add a "loose Dfs" object for manual graph search<commit_after>#![feature(slicing_syntax)]
extern crate test;

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{Writer, Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
use ograph::{
    EdgeType,
};

pub use self::EdgeDirection::{Outgoing, Incoming};

mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, S: Writer> Hash<S> for Ptr<'b, T>
{
    fn hash(&self, st: &mut S)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Dijkstra's shortest path algorithm.
pub fn dijkstra<'a, Graph, N, K, F, Edges>(graph: &'a Graph,
                                           start: N,
                                           goal: Option<N>,
                                           mut edges: F) -> HashMap<N, K> where
    Graph: Visitable<N>,
    N: Copy + Clone + Eq + Hash + fmt::Show,
    K: Default + Add<Output=K> + Copy + PartialOrd + fmt::Show,
    F: FnMut(&'a Graph, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
    <Graph as Visitable<N>>::Map: VisitMap<N>,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.contains(&node) {
            continue
        }
        for (next, edge) in edges(graph, node) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(&next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next, node);
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next, node);
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        visited.visit(node);
    }
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({})", self.0.get())
    }
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait IntoNeighbors<N> : Copy {
    type Iter: Iterator<Item=N>;
    fn neighbors(self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> IntoNeighbors<N> for &'a Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> IntoNeighbors<N> for &'a DiGraph<N, E>
where N: Copy + Clone + Hash + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E, ETy: EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a OGraph<N, E, ETy>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct Undirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> IntoNeighbors< ograph::NodeIndex> for &'a Undirected<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_both(self.0, n)
    }
}

impl<'a, 'b, N, E, ETy: EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a Reversed<&'b OGraph<N, E, ETy>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable<N> {
    type Map: VisitMap<N>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, ETy> Visitable<ograph::NodeIndex> for OGraph<N, E, ETy> where
    ETy: ograph::EdgeType,
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Undirected<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Reversed<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G: 'a, N> Iterator for BreadthFirst<'a, G, N> where
    &'a G: IntoNeighbors<N>,
    N: Copy + Eq + Hash,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
#[derive(Clone)]
pub struct DepthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub dfs: Dfs<N, HashSet<N>>,
}

/// A depth first traversal of a graph.
#[derive(Clone)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub visited: VM,
}

impl<N> Dfs<N, HashSet<N>> where N: Hash + Eq
{
    /// Create a new **Dfs**.
    fn new_with_hashset(start: N) -> Self
    {
        Dfs {
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl Dfs<(), ()>
{
    /// Create a new **Dfs**, using the graph's visitor map.
    ///
    /// **Note:** Does not borrow the graph.
    pub fn new<N, G>(graph: &G, start: N)
            -> Dfs<N, <G as Visitable<N>>::Map> where
        G: Visitable<N>,
    {
        Dfs {
            stack: vec![start],
            visited: graph.visit_map(),
        }
    }
}

impl<'a, G, N> DepthFirst<'a, G, N> where
    N: Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> DepthFirst<'a, G, N>
    {
        DepthFirst {
            graph: graph,
            dfs: Dfs::new_with_hashset(start)
        }
    }
}

impl<N, VM> Dfs<N, VM> where N: Clone, VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next_node<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        &'a G: IntoNeighbors< N>,
        <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.visit(node.clone()) {
                continue;
            }

            for succ in graph.neighbors(node.clone()) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

impl<'a, G, N> Iterator for DepthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Clone + Eq + Hash,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        self.dfs.next_node(self.graph)
    }
}

pub fn depth_first_search<'a, G, N, F>(graph: &'a G, start: N, mut f: F) -> bool where
    G: 'a + Visitable<N>,
    &'a G: IntoNeighbors<N>,
    N: Clone,
    <&'a G as IntoNeighbors<N>>::Iter: Iterator<Item=N>,
    <G as Visitable<N>>::Map: VisitMap<N>,
    F: FnMut(N) -> bool,
{
    let mut stack = Vec::new();
    let mut visited = graph.visit_map();

    stack.push(start);
    while let Some(node) = stack.pop() {
        if !visited.visit(node.clone()) {
            continue;
        }

        for succ in graph.neighbors(node.clone()) {
            if !visited.contains(&succ) {
                stack.push(succ);
            }
        }

        if !f(node) {
            return false
        }
    }
    true
}

/// Run a DFS over an **OGraph**, passing a mutable ref to the graph to the
/// iteration function on each step.
///
/// **Note:** The algorithm will not behave correctly if nodes are removed
/// during iteration. It will not necessarily visit added nodes or edges.
pub fn depth_first_search_mut<'a, N, E, ETy, F>(graph: &'a mut OGraph<N, E, ETy>,
                                                start: ograph::NodeIndex,
                                                mut f: F) -> bool where
    ETy: ograph::EdgeType,
    F: FnMut(&mut OGraph<N, E, ETy>, ograph::NodeIndex) -> bool,
{
    let mut dfs = Dfs::new(&*graph, start);
    while let Some(node) = dfs.next_node(&*graph) {
        if !f(graph, node) {
            return false
        }
    }
    true
}

<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use futures::stream::Stream;
use lazy_static::lazy_static;
use regex::Regex;

pub struct Entity {
    pub identifier: String,
}

pub enum Object {
    Entity(Entity),
    Literal(Literal),
}

pub enum Literal {
    LangLiteral(LangLiteral),
    StringLiteral(String),
    BooleanLiteral(bool),
    LongLiteral(i64),
    DoubleLiteral(f64),
}

pub struct LangLiteral {
    pub value: String,
    pub lang_tag: String,
}

pub struct Predicate {
    pub predicate: String,
}

pub enum Range {
    LangLiteralRange(LangLiteral, LangLiteral),
    StringLiteralRange(String, String),
    LongLiteralRange(i64, i64),
    DoubleLiteralRange(f64, f64),
}

pub struct Statement {
    pub subject: Entity,
    pub predicate: Predicate,
    pub object: Object,
    pub context: Entity,
}

pub struct CollectionName {
    pub name: String,
}

pub trait LigatureStore {
    fn read_tx(&self) -> Box<dyn ReadTx>;
    fn write_tx(&self) -> Box<dyn WriteTx>;

    /**
     * Close connection with the Store.
     */
    fn close(&self);

    fn is_open(&self) -> bool;
}

pub trait ReadTx {
    /**
     * Returns a Stream of all existing collections.
     */
    fn collections(&self) -> dyn Stream<Item = CollectionName>;

    /**
     * Returns a Stream of all existing collections that start with the given prefix.
     */
    fn collections_prefix(&self, prefix: CollectionName) -> dyn Stream<Item = CollectionName>;

    /**
     * Returns a Stream of all existing collections that are within the given range.
     * `from` is inclusive and `to` is exclusive.
     */
    fn collections_range(
        &self,
        from: CollectionName,
        to: CollectionName,
    ) -> dyn Stream<Item = CollectionName>;

    /**
     * Accepts nothing but returns a Stream of all Statements in the Collection.
     */
    fn all_statements(&self, collection: CollectionName) -> dyn Stream<Item = Statement>;

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements(
        &self,
        collection: CollectionName,
        subject: Option<Entity>,
        predicate: Option<Predicate>,
        object: Option<Object>,
        context: Option<Entity>,
    ) -> dyn Stream<Item = Statement>;

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements_range(
        &self,
        collection: CollectionName,
        subject: Option<Entity>,
        predicate: Option<Predicate>,
        range: Option<Range>,
        context: Option<Entity>,
    ) -> dyn Stream<Item = Statement>;

    /**
     * Cancels this transaction.
     */
    fn cancel(&self);

    fn is_open(&self) -> bool;
}

pub trait WriteTx {
    /**
     * Creates a collection with the given name or does nothing if the collection already exists.
     * Only useful for creating an empty collection.
     */
    fn create_collection(&self, collection: CollectionName);

    /**
     * Deletes the collection of the name given and does nothing if the collection doesn't exist.
     */
    fn delete_collection(&self, collection: CollectionName);

    /**
     * Returns a new, unique to this collection identifier in the form _:NUMBER
     */
    fn new_entity(&self, collection: CollectionName) -> Entity;
    fn remove_entity(&self, collection: CollectionName, entity: Entity);
    fn add_statement(&self, collection: CollectionName, statement: Statement);
    fn remove_statement(&self, collection: CollectionName, statement: Statement);

    /**
     * Commits this transaction.
     */
    fn commit(&self);

    /**
     * Cancels this transaction.
     */
    fn cancel(&self);

    fn is_open(&self) -> bool;
}

/**
 * Accepts a String representing an identifier and returns true or false depending on if it is valid.
 */
pub fn valid_predicate(identifier: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new("^[a-zA-Z_][^\\s\\(\\)\\[\\]\\{\\}'\"`<>\\\\]*$").unwrap();
    }

    return RE.is_match(identifier);
}

/**
 * Accepts a String representing a lang tag and returns true or false depending on if it is valid.
 */
pub fn valid_lang_tag(lang_tag: &str) -> bool {
    lazy_static! {
        static ref RE: Regex = Regex::new("^[a-zA-Z]+(-[a-zA-Z0-9]+)*$").unwrap();
    }

    return RE.is_match(lang_tag);
}

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

    #[test]
    fn valid_identifier_tests() {
        assert_eq!(valid_predicate(""), false);
        assert_eq!(valid_predicate("http://localhost/people/7"), true);
        assert_eq!(valid_predicate("http://localhost(/people/7"), false);
        assert_eq!(valid_predicate("http://localhost /people/7"), false);
        assert_eq!(valid_predicate("hello"), true);
        assert_eq!(valid_predicate("_:"), true);
        assert_eq!(valid_predicate("_:valid"), true);
        assert_eq!(valid_predicate("_:1"), true);
        assert_eq!(valid_predicate("_:1344"), true);
    }

    #[test]
    fn valid_lang_tag_tests() {
        assert_eq!(valid_lang_tag(""), false);
        assert_eq!(valid_lang_tag("en"), true);
        assert_eq!(valid_lang_tag("en-"), false);
        assert_eq!(valid_lang_tag("en-fr"), true);
        assert_eq!(valid_lang_tag("en-fr-"), false);
        assert_eq!(valid_lang_tag("en-fr-sp"), true);
        assert_eq!(
            valid_lang_tag("ennnenefnk-dkfjkjfl-dfakjelfkjalkf-fakjeflkajlkfj"),
            true
        );
        assert_eq!(valid_lang_tag("en-fr-ef "), false);
    }
}
<commit_msg>fixing clippy compliant and returning references<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use futures::stream::Stream;
use lazy_static::lazy_static;
use regex::Regex;

pub struct Entity {
    pub identifier: String,
}

pub enum Object {
    Entity(Entity),
    Literal(Literal),
}

pub enum Literal {
    LangLiteral(LangLiteral),
    StringLiteral(String),
    BooleanLiteral(bool),
    LongLiteral(i64),
    DoubleLiteral(f64),
}

pub struct LangLiteral {
    pub value: String,
    pub lang_tag: String,
}

pub struct Predicate {
    pub predicate: String,
}

pub enum Range {
    LangLiteralRange(LangLiteral, LangLiteral),
    StringLiteralRange(String, String),
    LongLiteralRange(i64, i64),
    DoubleLiteralRange(f64, f64),
}

pub struct Statement {
    pub subject: Entity,
    pub predicate: Predicate,
    pub object: Object,
    pub context: Entity,
}

pub struct CollectionName {
    pub name: String,
}

pub trait LigatureStore {
    fn read_tx(&self) -> &dyn ReadTx;
    fn write_tx(&self) -> &dyn WriteTx;

    /**
     * Close connection with the Store.
     */
    fn close(&self);

    fn is_open(&self) -> bool;
}

pub trait ReadTx {
    /**
     * Returns a Stream of all existing collections.
     */
    fn collections(&self) -> &dyn Stream<Item = CollectionName>;

    /**
     * Returns a Stream of all existing collections that start with the given prefix.
     */
    fn collections_prefix(&self, prefix: CollectionName) -> &dyn Stream<Item = CollectionName>;

    /**
     * Returns a Stream of all existing collections that are within the given range.
     * `from` is inclusive and `to` is exclusive.
     */
    fn collections_range(
        &self,
        from: CollectionName,
        to: CollectionName,
    ) -> &dyn Stream<Item = CollectionName>;

    /**
     * Accepts nothing but returns a Stream of all Statements in the Collection.
     */
    fn all_statements(&self, collection: CollectionName) -> &dyn Stream<Item = Statement>;

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements(
        &self,
        collection: CollectionName,
        subject: Option<Entity>,
        predicate: Option<Predicate>,
        object: Option<Object>,
        context: Option<Entity>,
    ) -> &dyn Stream<Item = Statement>;

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements_range(
        &self,
        collection: CollectionName,
        subject: Option<Entity>,
        predicate: Option<Predicate>,
        range: Option<Range>,
        context: Option<Entity>,
    ) -> &dyn Stream<Item = Statement>;

    /**
     * Cancels this transaction.
     */
    fn cancel(&self);

    fn is_open(&self) -> bool;
}

pub trait WriteTx {
    /**
     * Creates a collection with the given name or does nothing if the collection already exists.
     * Only useful for creating an empty collection.
     */
    fn create_collection(&self, collection: CollectionName);

    /**
     * Deletes the collection of the name given and does nothing if the collection doesn't exist.
     */
    fn delete_collection(&self, collection: CollectionName);

    /**
     * Returns a new, unique to this collection identifier in the form _:NUMBER
     */
    fn new_entity(&self, collection: CollectionName) -> Entity;
    fn remove_entity(&self, collection: CollectionName, entity: Entity);
    fn add_statement(&self, collection: CollectionName, statement: Statement);
    fn remove_statement(&self, collection: CollectionName, statement: Statement);

    /**
     * Commits this transaction.
     */
    fn commit(&self);

    /**
     * Cancels this transaction.
     */
    fn cancel(&self);

    fn is_open(&self) -> bool;
}

/**
 * Accepts a String representing an identifier and returns true or false depending on if it is valid.
 */
pub fn valid_predicate(identifier: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new("^[a-zA-Z_][^\\s\\(\\)\\[\\]\\{\\}'\"`<>\\\\]*$").unwrap();
    }
    RE.is_match(identifier)
}

/**
 * Accepts a String representing a lang tag and returns true or false depending on if it is valid.
 */
pub fn valid_lang_tag(lang_tag: &str) -> bool {
    lazy_static! {
        static ref RE: Regex = Regex::new("^[a-zA-Z]+(-[a-zA-Z0-9]+)*$").unwrap();
    }
    RE.is_match(lang_tag)
}

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

    #[test]
    fn valid_identifier_tests() {
        assert_eq!(valid_predicate(""), false);
        assert_eq!(valid_predicate("http://localhost/people/7"), true);
        assert_eq!(valid_predicate("http://localhost(/people/7"), false);
        assert_eq!(valid_predicate("http://localhost /people/7"), false);
        assert_eq!(valid_predicate("hello"), true);
        assert_eq!(valid_predicate("_:"), true);
        assert_eq!(valid_predicate("_:valid"), true);
        assert_eq!(valid_predicate("_:1"), true);
        assert_eq!(valid_predicate("_:1344"), true);
    }

    #[test]
    fn valid_lang_tag_tests() {
        assert_eq!(valid_lang_tag(""), false);
        assert_eq!(valid_lang_tag("en"), true);
        assert_eq!(valid_lang_tag("en-"), false);
        assert_eq!(valid_lang_tag("en-fr"), true);
        assert_eq!(valid_lang_tag("en-fr-"), false);
        assert_eq!(valid_lang_tag("en-fr-sp"), true);
        assert_eq!(
            valid_lang_tag("ennnenefnk-dkfjkjfl-dfakjelfkjalkf-fakjeflkajlkfj"),
            true
        );
        assert_eq!(valid_lang_tag("en-fr-ef "), false);
    }
}
<|endoftext|>