<commit_before>use std::ops::Deref;
use std::sync::Arc;

use actix_http::error::{Error, ErrorInternalServerError};
use actix_http::Extensions;
use futures::{Async, Future, IntoFuture, Poll};

use crate::extract::FromRequest;
use crate::service::ServiceFromRequest;

/// Application data factory
pub(crate) trait DataFactory {
    fn construct(&self) -> Box<DataFactoryResult>;
}

pub(crate) trait DataFactoryResult {
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()>;
}

/// Application data.
///
/// Application data is an arbitrary data attached to the app.
/// Application data is available to all routes and could be added
/// during application configuration process
/// with `App::data()` method.
///
/// Applicatin data could be accessed by using `Data<T>`
/// extractor where `T` is data type.
///
/// **Note**: http server accepts an application factory rather than
/// an application instance. Http server constructs an application
/// instance for each thread, thus application data must be constructed
/// multiple times. If you want to share data between different
/// threads, a shared object should be used, e.g. `Arc`. Application
/// data does not need to be `Send` or `Sync`.
///
/// ```rust
/// use std::cell::Cell;
/// use actix_web::{web, App};
///
/// struct MyData {
///     counter: Cell<usize>,
/// }
///
/// /// Use `Data<T>` extractor to access data in handler.
/// fn index(data: web::Data<MyData>) {
///     data.counter.set(data.counter.get() + 1);
/// }
///
/// fn main() {
///     let app = App::new()
///         // Store `MyData` in application storage.
///         .data(MyData{ counter: Cell::new(0) })
///         .service(
///             web::resource("/index.html").route(
///                 web::get().to(index)));
/// }
/// ```
pub struct Data<T>(Arc<T>);

impl<T> Data<T> {
    pub(crate) fn new(state: T) -> Data<T> {
        Data(Arc::new(state))
    }

    /// Get referecnce to inner app data.
    pub fn get_ref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Deref for Data<T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Clone for Data<T> {
    fn clone(&self) -> Data<T> {
        Data(self.0.clone())
    }
}

impl<T: 'static, P> FromRequest<P> for Data<T> {
    type Error = Error;
    type Future = Result<Self, Error>;

    #[inline]
    fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
        if let Some(st) = req.config().extensions().get::<Data<T>>() {
            Ok(st.clone())
        } else {
            Err(ErrorInternalServerError(
                "App data is not configured, to configure use App::data()",
            ))
        }
    }
}

impl<T: 'static> DataFactory for Data<T> {
    fn construct(&self) -> Box<DataFactoryResult> {
        Box::new(DataFut { st: self.clone() })
    }
}

struct DataFut<T> {
    st: Data<T>,
}

impl<T: 'static> DataFactoryResult for DataFut<T> {
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
        extensions.insert(self.st.clone());
        Ok(Async::Ready(()))
    }
}

impl<F, Out> DataFactory for F
where
    F: Fn() -> Out + 'static,
    Out: IntoFuture + 'static,
    Out::Error: std::fmt::Debug,
{
    fn construct(&self) -> Box<DataFactoryResult> {
        Box::new(DataFactoryFut {
            fut: (*self)().into_future(),
        })
    }
}

struct DataFactoryFut<T, F>
where
    F: Future<Item = T>,
    F::Error: std::fmt::Debug,
{
    fut: F,
}

impl<T: 'static, F> DataFactoryResult for DataFactoryFut<T, F>
where
    F: Future<Item = T>,
    F::Error: std::fmt::Debug,
{
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
        match self.fut.poll() {
            Ok(Async::Ready(s)) => {
                extensions.insert(Data::new(s));
                Ok(Async::Ready(()))
            }
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => {
                log::error!("Can not construct application state: {:?}", e);
                Err(())
            }
        }
    }
}

/// Route data.
///
/// Route data is an arbitrary data attached to specific route.
/// Route data could be added to route during route configuration process
/// with `Route::data()` method. Route data is also used as an extractor
/// configuration storage. Route data could be accessed in handler
/// via `RouteData<T>` extractor.
///
/// ```rust
/// # use std::cell::Cell;
/// use actix_web::{web, App};
///
/// struct MyData {
///     counter: Cell<usize>,
/// }
///
/// /// Use `RouteData<T>` extractor to access data in handler.
/// fn index(data: web::RouteData<MyData>) {
///     data.counter.set(data.counter.get() + 1);
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/index.html").route(
///             web::get()
///                // Store `MyData` in route storage
///                .data(MyData{ counter: Cell::new(0) })
///                // Route data could be used as extractor configuration storage,
///                // limit size of the payload
///                .data(web::PayloadConfig::new(4096))
///                // register handler
///                .to(index)
///         ));
/// }
/// ```
///
/// If route data is not set for a handler, using `RouteData` extractor
/// would cause `Internal Server error` response.
pub struct RouteData<T>(Arc<T>);

impl<T> RouteData<T> {
    pub(crate) fn new(state: T) -> RouteData<T> {
        RouteData(Arc::new(state))
    }

    /// Get referecnce to inner data object.
    pub fn get_ref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Deref for RouteData<T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Clone for RouteData<T> {
    fn clone(&self) -> RouteData<T> {
        RouteData(self.0.clone())
    }
}

impl<T: 'static, P> FromRequest<P> for RouteData<T> {
    type Error = Error;
    type Future = Result<Self, Error>;

    #[inline]
    fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
        if let Some(st) = req.route_data::<T>() {
            Ok(st.clone())
        } else {
            Err(ErrorInternalServerError(
                "Route data is not configured, to configure use Route::data()",
            ))
        }
    }
}

#[cfg(test)]
mod tests {
    use actix_service::Service;

    use crate::http::StatusCode;
    use crate::test::{block_on, init_service, TestRequest};
    use crate::{web, App, HttpResponse};

    #[test]
    fn test_data_extractor() {
        let mut srv =
            init_service(App::new().data(10usize).service(
                web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
            ));

        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::OK);

        let mut srv =
            init_service(App::new().data(10u32).service(
                web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
            ));
        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
    }

    #[test]
    fn test_route_data_extractor() {
        let mut srv = init_service(App::new().service(web::resource("/").route(
            web::get().data(10usize).to(|data: web::RouteData<usize>| {
                let _ = data.clone();
                HttpResponse::Ok()
            }),
        )));

        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::OK);

        // different type
        let mut srv = init_service(
            App::new().service(
                web::resource("/").route(
                    web::get()
                        .data(10u32)
                        .to(|_: web::RouteData<usize>| HttpResponse::Ok()),
                ),
            ),
        );
        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
    }
}
<commit_msg>update api doc<commit_after>use std::ops::Deref;
use std::sync::Arc;

use actix_http::error::{Error, ErrorInternalServerError};
use actix_http::Extensions;
use futures::{Async, Future, IntoFuture, Poll};

use crate::extract::FromRequest;
use crate::service::ServiceFromRequest;

/// Application data factory
pub(crate) trait DataFactory {
    fn construct(&self) -> Box<DataFactoryResult>;
}

pub(crate) trait DataFactoryResult {
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()>;
}

/// Application data.
///
/// Application data is an arbitrary data attached to the app.
/// Application data is available to all routes and could be added
/// during application configuration process
/// with `App::data()` method.
///
/// Applicatin data could be accessed by using `Data<T>`
/// extractor where `T` is data type.
///
/// **Note**: http server accepts an application factory rather than
/// an application instance. Http server constructs an application
/// instance for each thread, thus application data must be constructed
/// multiple times. If you want to share data between different
/// threads, a shared object should be used, e.g. `Arc`. Application
/// data does not need to be `Send` or `Sync`.
///
/// If route data is not set for a handler, using `Data<T>` extractor would
/// cause *Internal Server Error* response.
///
/// ```rust
/// use std::cell::Cell;
/// use actix_web::{web, App};
///
/// struct MyData {
///     counter: Cell<usize>,
/// }
///
/// /// Use `Data<T>` extractor to access data in handler.
/// fn index(data: web::Data<MyData>) {
///     data.counter.set(data.counter.get() + 1);
/// }
///
/// fn main() {
///     let app = App::new()
///         // Store `MyData` in application storage.
///         .data(MyData{ counter: Cell::new(0) })
///         .service(
///             web::resource("/index.html").route(
///                 web::get().to(index)));
/// }
/// ```
pub struct Data<T>(Arc<T>);

impl<T> Data<T> {
    pub(crate) fn new(state: T) -> Data<T> {
        Data(Arc::new(state))
    }

    /// Get referecnce to inner app data.
    pub fn get_ref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Deref for Data<T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Clone for Data<T> {
    fn clone(&self) -> Data<T> {
        Data(self.0.clone())
    }
}

impl<T: 'static, P> FromRequest<P> for Data<T> {
    type Error = Error;
    type Future = Result<Self, Error>;

    #[inline]
    fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
        if let Some(st) = req.config().extensions().get::<Data<T>>() {
            Ok(st.clone())
        } else {
            Err(ErrorInternalServerError(
                "App data is not configured, to configure use App::data()",
            ))
        }
    }
}

impl<T: 'static> DataFactory for Data<T> {
    fn construct(&self) -> Box<DataFactoryResult> {
        Box::new(DataFut { st: self.clone() })
    }
}

struct DataFut<T> {
    st: Data<T>,
}

impl<T: 'static> DataFactoryResult for DataFut<T> {
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
        extensions.insert(self.st.clone());
        Ok(Async::Ready(()))
    }
}

impl<F, Out> DataFactory for F
where
    F: Fn() -> Out + 'static,
    Out: IntoFuture + 'static,
    Out::Error: std::fmt::Debug,
{
    fn construct(&self) -> Box<DataFactoryResult> {
        Box::new(DataFactoryFut {
            fut: (*self)().into_future(),
        })
    }
}

struct DataFactoryFut<T, F>
where
    F: Future<Item = T>,
    F::Error: std::fmt::Debug,
{
    fut: F,
}

impl<T: 'static, F> DataFactoryResult for DataFactoryFut<T, F>
where
    F: Future<Item = T>,
    F::Error: std::fmt::Debug,
{
    fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
        match self.fut.poll() {
            Ok(Async::Ready(s)) => {
                extensions.insert(Data::new(s));
                Ok(Async::Ready(()))
            }
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => {
                log::error!("Can not construct application state: {:?}", e);
                Err(())
            }
        }
    }
}

/// Route data.
///
/// Route data is an arbitrary data attached to specific route.
/// Route data could be added to route during route configuration process
/// with `Route::data()` method. Route data is also used as an extractor
/// configuration storage. Route data could be accessed in handler
/// via `RouteData<T>` extractor.
///
/// If route data is not set for a handler, using `RouteData` extractor
/// would cause *Internal Server Error* response.
///
/// ```rust
/// # use std::cell::Cell;
/// use actix_web::{web, App};
///
/// struct MyData {
///     counter: Cell<usize>,
/// }
///
/// /// Use `RouteData<T>` extractor to access data in handler.
/// fn index(data: web::RouteData<MyData>) {
///     data.counter.set(data.counter.get() + 1);
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/index.html").route(
///             web::get()
///                // Store `MyData` in route storage
///                .data(MyData{ counter: Cell::new(0) })
///                // Route data could be used as extractor configuration storage,
///                // limit size of the payload
///                .data(web::PayloadConfig::new(4096))
///                // register handler
///                .to(index)
///         ));
/// }
/// ```
pub struct RouteData<T>(Arc<T>);

impl<T> RouteData<T> {
    pub(crate) fn new(state: T) -> RouteData<T> {
        RouteData(Arc::new(state))
    }

    /// Get referecnce to inner data object.
    pub fn get_ref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Deref for RouteData<T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.0.as_ref()
    }
}

impl<T> Clone for RouteData<T> {
    fn clone(&self) -> RouteData<T> {
        RouteData(self.0.clone())
    }
}

impl<T: 'static, P> FromRequest<P> for RouteData<T> {
    type Error = Error;
    type Future = Result<Self, Error>;

    #[inline]
    fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
        if let Some(st) = req.route_data::<T>() {
            Ok(st.clone())
        } else {
            Err(ErrorInternalServerError(
                "Route data is not configured, to configure use Route::data()",
            ))
        }
    }
}

#[cfg(test)]
mod tests {
    use actix_service::Service;

    use crate::http::StatusCode;
    use crate::test::{block_on, init_service, TestRequest};
    use crate::{web, App, HttpResponse};

    #[test]
    fn test_data_extractor() {
        let mut srv =
            init_service(App::new().data(10usize).service(
                web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
            ));

        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::OK);

        let mut srv =
            init_service(App::new().data(10u32).service(
                web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
            ));
        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
    }

    #[test]
    fn test_route_data_extractor() {
        let mut srv = init_service(App::new().service(web::resource("/").route(
            web::get().data(10usize).to(|data: web::RouteData<usize>| {
                let _ = data.clone();
                HttpResponse::Ok()
            }),
        )));

        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::OK);

        // different type
        let mut srv = init_service(
            App::new().service(
                web::resource("/").route(
                    web::get()
                        .data(10u32)
                        .to(|_: web::RouteData<usize>| HttpResponse::Ok()),
                ),
            ),
        );
        let req = TestRequest::default().to_request();
        let resp = block_on(srv.call(req)).unwrap();
        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
extern crate serialize;
extern crate docopt;
#[phase(plugin)]
extern crate docopt_macros;

use docopt::Docopt;

docopt!(Args, "
Usage: wc [options] [<file>]

Options:
    -c, --bytes  print the byte counts
    -m, --chars  print the character counts
    -l, --lines  print the newline counts
    -w, --words  print the word counts
    -L, --max-line-length  print the length of the longest line
    -h, --help  display this help and exit
    -v, --version  output version information and exit
", arg_file: Option<String>)

fn main() {
    println!("24 days of Rust - docopt (day 4)");
    let docopt = Args::docopt();
    println!("{}", docopt);
    let args: Args = match docopt.decode() {
        Ok(args) => args,
        Err(e) => e.exit(),
    };
    println!("Counting stuff in {}", args.arg_file.unwrap_or("standard input".to_string()));
    if args.flag_bytes {
        println!("Counting bytes!");
    }
    if args.flag_chars {
        println!("Counting characters!");
    }
    if args.flag_lines {
        println!("Counting lines!");
    }
    if args.flag_words {
        println!("Counting words!");
    }
    if args.flag_max_line_length {
        println!("Measuring the longest line!");
    }
}
<commit_msg>docopt cleanup<commit_after>#![feature(phase)]
extern crate serialize;
extern crate docopt;
#[phase(plugin)]
extern crate docopt_macros;

docopt!(Args, "
Usage: wc [options] [<file>]

Options:
    -c, --bytes  print the byte counts
    -m, --chars  print the character counts
    -l, --lines  print the newline counts
    -w, --words  print the word counts
    -L, --max-line-length  print the length of the longest line
    -h, --help  display this help and exit
    -v, --version  output version information and exit
", arg_file: Option<String>)

fn main() {
    println!("24 days of Rust - docopt (day 4)");
    let docopt = Args::docopt();
    println!("{}", docopt);
    let args: Args = docopt.decode().unwrap_or_else(|e| e.exit());
    println!("Counting stuff in {}", args.arg_file.unwrap_or("standard input".to_string()));
    if args.flag_bytes {
        println!("Counting bytes!");
    }
    if args.flag_chars {
        println!("Counting characters!");
    }
    if args.flag_lines {
        println!("Counting lines!");
    }
    if args.flag_words {
        println!("Counting words!");
    }
    if args.flag_max_line_length {
        println!("Measuring the longest line!");
    }
}
<|endoftext|>


<commit_before>use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use {Result, Collection, Scope};

struct Constructed {
    parent: Box<Any>,
    child: Option<Box<Any>>,
}

pub struct Deps {
    /// List of functions that constructs all childs for a type
    /// and returns value wrapped in Any that must live as long as the parent type.
    type_child_constructors: HashMap<TypeId, Vec<Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>>>,
    type_scope_created: HashMap<TypeId, Vec<Box<Fn(&Deps, Box<Any>) -> Result<Box<Any>> + Send + Sync>>>,
}

impl Deps {
    pub fn new() -> Deps {
        Deps {
            type_child_constructors: HashMap::new(),
            type_scope_created: HashMap::new(),
        }
    }

    /// Create dependencies for specified `obj` and return a wrapper `Scope` object.
    ///
    /// The wrapper `Scope` keeps ownership of all children together with parent object.
    pub fn create<P: Any>(&self, obj: P) -> Result<Scope<P>> {
        match self.type_child_constructors.get(&TypeId::of::<P>()) {
            // if there are type child constructors
            Some(list) => {
                let mut parent = Box::new(obj) as Box<Any>;

                // run each child constructor and receive list of objects that will be kept inside
                // the parent scope.
                let mut deps = Vec::new();

                for any_constructor in list {
                    parent = match any_constructor(&self, parent) {
                        Ok(Constructed { parent, child: None }) => parent,
                        Ok(Constructed { parent, child: Some(child) }) => {
                            deps.push(child);
                            parent
                        }
                        Err(any_err) => return Err(any_err),
                    };
                }

                if let Some(actions) = self.type_scope_created.get(&TypeId::of::<P>()) {
                    for action in actions {
                        parent = try!(action(&self, parent));
                    }
                }

                Ok(Scope::new(*parent.downcast().unwrap(), deps))
            }
            // if there are no type childs, wrap the type in scope anyways with empty child list.
            None => Ok(Scope::new(obj, vec![])),
        }
    }

    /// Collect all the items registered as `collectable` into a `Collection` of that type.
    pub fn collect<C: Any>(&self) -> Result<Collection<C>> {
        self.create(Collection::new()).map(|v| v.explode())
    }

    pub fn when_ready<T, F>(&mut self, action: F)
        where T: 'static + Any,
              F: for<'r> Fn(&Deps, &mut T) -> Result<()> + 'static + Send + Sync
    {
        match self.type_scope_created.entry(TypeId::of::<T>()) {
            Entry::Occupied(mut list) => {
                list.get_mut().push(into_action_with_deps(action));
            }
            Entry::Vacant(e) => {
                e.insert(vec![into_action_with_deps(action)]);
            }
        };
    }

    /// Single dependency on a parent.
    pub fn attach<P, C, F>(&mut self, constructor: F)
        where P: 'static + Any, // Parent
              C: 'static + Any, // Child
              F: for<'r> Fn(&Deps, &mut P) -> Result<C> + 'static + Send + Sync
    {
        self.register_child_constructor::<P>(into_constructor_with_child_deps(constructor));
    }

    pub fn collectable<C, F>(&mut self, constructor: F)
        where C: 'static + Any,
              F: for<'r> Fn(&Deps) -> C + 'static + Send + Sync
    {
        self.register_child_constructor::<Collection<C>>(
            into_constructor_without_child_deps(move |deps: &Deps, parent: &mut Collection<C>| {
                parent.push(constructor(deps))
            })
        );
    }

    /// Register child constructor that will be invoked when the parent `P` type is
    /// created.
    fn register_child_constructor<P: Any>(
        &mut self,
        any_constructor: Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    ) {
        match self.type_child_constructors.entry(TypeId::of::<P>()) {
            Entry::Occupied(mut list) => {
                list.get_mut().push(any_constructor);
            }
            Entry::Vacant(e) => {
                e.insert(vec![any_constructor]);
            }
        };
    }
}

fn into_action_with_deps<P, F>(action: F)
                               -> Box<Fn(&Deps, Box<Any>) -> Result<Box<Any>> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> Result<()> + 'static + Send + Sync,
          P: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Box<Any>> {
        {
            let mut concrete_parent = parent.downcast_mut::<P>().unwrap();
            try!(action(deps, &mut concrete_parent));
        }
        Ok(parent)
    })
}

fn into_constructor_with_child_deps<P, C, F>
    (constructor: F)
     -> Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> Result<C> + 'static + Send + Sync,
          P: 'static + Any,
          C: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Constructed> {
        let child = {
            let concrete_parent = parent.downcast_mut::<P>().unwrap();
            try!(deps.create(try!(constructor(deps, concrete_parent))))
        };
        Ok(Constructed {
            parent: parent,
            child: Some(Box::new(child)),
        })
    })
}

fn into_constructor_without_child_deps<P, C, F>
    (constructor: F)
     -> Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> C + 'static + Send + Sync,
          P: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Constructed> {
        {
            let concrete_parent = parent.downcast_mut::<P>().unwrap();
            constructor(deps, concrete_parent);
        }
        Ok(Constructed {
            parent: parent,
            child: None,
        })
    })
}

#[cfg(test)]
mod test {
    use Deps;
    use std::sync::{Arc, Mutex};

    #[derive(Clone)]
    struct A(String);

    #[derive(Clone)]
    struct B(String);

    #[derive(Clone)]
    struct C(String);

    #[test]
    fn creates_dependency() {
        let mut deps = Deps::new();

        // here we want to know what is the state of dependency in closure, hence
        // shared mutable reference to it
        let created_b_ref = Arc::new(Mutex::new(None));

        deps.attach({
            let created_b_ref = created_b_ref.clone();
            move |_: &Deps, a: &mut A| {
                let b = B([&a.0[..], "+B"].concat());
                *created_b_ref.lock().unwrap() = Some(b.clone());
                Ok(b)
            }
        });

        deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hello+B",
                   (*created_b_ref.lock().unwrap()).clone().unwrap().0);
    }

    #[test]
    fn creates_dependency_of_dependency() {
        let mut deps = Deps::new();

        // here we want to know what is the state of dependency in closure, hence
        // shared mutable reference to it
        let created_c_ref = Arc::new(Mutex::new(None));

        deps.attach(|_: &Deps, a: &mut A| Ok(B([&a.0[..], "+B"].concat())));

        deps.attach({
            let created_c_ref = created_c_ref.clone();
            move |_: &Deps, b: &mut B| {
                let c = C([&b.0[..], "+C"].concat());
                *created_c_ref.lock().unwrap() = Some(c.clone());
                Ok(c)
            }
        });

        deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hello+B+C",
                   (*created_c_ref.lock().unwrap()).clone().unwrap().0);
    }

    #[test]
    fn creates_mutable_dependency() {
        let mut deps = Deps::new();

        deps.attach(|_: &Deps, a: &mut A| {
            *a = A("Hi!".into());
            Ok(())
        });

        let a = deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hi!", a.obj.0);
    }
}
<commit_msg>Name current constructors isolated.<commit_after>use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use {Result, Collection, Scope};

struct Constructed {
    parent: Box<Any>,
    child: Option<Box<Any>>,
}

pub struct Deps {
    /// List of functions that constructs all childs for a type
    /// and returns value wrapped in Any that must live as long as the parent type.
    isolated_constructors: HashMap<TypeId, Vec<Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>>>,
    type_scope_created: HashMap<TypeId, Vec<Box<Fn(&Deps, Box<Any>) -> Result<Box<Any>> + Send + Sync>>>,
}

impl Deps {
    pub fn new() -> Deps {
        Deps {
            isolated_constructors: HashMap::new(),
            type_scope_created: HashMap::new(),
        }
    }

    /// Create dependencies for specified `obj` and return a wrapper `Scope` object.
    ///
    /// The wrapper `Scope` keeps ownership of all children together with parent object.
    pub fn create<P: Any>(&self, obj: P) -> Result<Scope<P>> {
        match self.isolated_constructors.get(&TypeId::of::<P>()) {
            // if there are type child constructors
            Some(list) => {
                let mut parent = Box::new(obj) as Box<Any>;

                // run each child constructor and receive list of objects that will be kept inside
                // the parent scope.
                let mut deps = Vec::new();

                for any_constructor in list {
                    parent = match any_constructor(&self, parent) {
                        Ok(Constructed { parent, child: None }) => parent,
                        Ok(Constructed { parent, child: Some(child) }) => {
                            deps.push(child);
                            parent
                        }
                        Err(any_err) => return Err(any_err),
                    };
                }

                if let Some(actions) = self.type_scope_created.get(&TypeId::of::<P>()) {
                    for action in actions {
                        parent = try!(action(&self, parent));
                    }
                }

                Ok(Scope::new(*parent.downcast().unwrap(), deps))
            }
            // if there are no type childs, wrap the type in scope anyways with empty child list.
            None => Ok(Scope::new(obj, vec![])),
        }
    }

    /// Collect all the items registered as `collectable` into a `Collection` of that type.
    pub fn collect<C: Any>(&self) -> Result<Collection<C>> {
        self.create(Collection::new()).map(|v| v.explode())
    }

    pub fn when_ready<T, F>(&mut self, action: F)
        where T: 'static + Any,
              F: for<'r> Fn(&Deps, &mut T) -> Result<()> + 'static + Send + Sync
    {
        match self.type_scope_created.entry(TypeId::of::<T>()) {
            Entry::Occupied(mut list) => {
                list.get_mut().push(into_action_with_deps(action));
            }
            Entry::Vacant(e) => {
                e.insert(vec![into_action_with_deps(action)]);
            }
        };
    }

    /// Single dependency on a parent.
    pub fn attach<P, C, F>(&mut self, constructor: F)
        where P: 'static + Any, // Parent
              C: 'static + Any, // Child
              F: for<'r> Fn(&Deps, &mut P) -> Result<C> + 'static + Send + Sync
    {
        self.register_isolated_constructor::<P>(into_isolated_constructor_with_child_deps(constructor));
    }

    pub fn collectable<C, F>(&mut self, constructor: F)
        where C: 'static + Any,
              F: for<'r> Fn(&Deps) -> C + 'static + Send + Sync
    {
        self.register_isolated_constructor::<Collection<C>>(
            into_isolated_constructor_without_child_deps(move |deps: &Deps, parent: &mut Collection<C>| {
                parent.push(constructor(deps))
            })
        );
    }

    /// Register child constructor that will be invoked when the parent `P` type is
    /// created.
    fn register_isolated_constructor<P: Any>(
        &mut self,
        any_constructor: Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    ) {
        match self.isolated_constructors.entry(TypeId::of::<P>()) {
            Entry::Occupied(mut list) => {
                list.get_mut().push(any_constructor);
            }
            Entry::Vacant(e) => {
                e.insert(vec![any_constructor]);
            }
        };
    }
}

fn into_action_with_deps<P, F>(action: F)
                               -> Box<Fn(&Deps, Box<Any>) -> Result<Box<Any>> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> Result<()> + 'static + Send + Sync,
          P: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Box<Any>> {
        {
            let mut concrete_parent = parent.downcast_mut::<P>().unwrap();
            try!(action(deps, &mut concrete_parent));
        }
        Ok(parent)
    })
}

fn into_isolated_constructor_with_child_deps<P, C, F>
    (constructor: F)
     -> Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> Result<C> + 'static + Send + Sync,
          P: 'static + Any,
          C: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Constructed> {
        let child = {
            let concrete_parent = parent.downcast_mut::<P>().unwrap();
            try!(deps.create(try!(constructor(deps, concrete_parent))))
        };
        Ok(Constructed {
            parent: parent,
            child: Some(Box::new(child)),
        })
    })
}

fn into_isolated_constructor_without_child_deps<P, C, F>
    (constructor: F)
     -> Box<Fn(&Deps, Box<Any>) -> Result<Constructed> + Send + Sync>
    where F: for<'r> Fn(&Deps, &mut P) -> C + 'static + Send + Sync,
          P: 'static + Any
{
    Box::new(move |deps: &Deps, mut parent: Box<Any>| -> Result<Constructed> {
        {
            let concrete_parent = parent.downcast_mut::<P>().unwrap();
            constructor(deps, concrete_parent);
        }
        Ok(Constructed {
            parent: parent,
            child: None,
        })
    })
}

#[cfg(test)]
mod test {
    use Deps;
    use std::sync::{Arc, Mutex};

    #[derive(Clone)]
    struct A(String);

    #[derive(Clone)]
    struct B(String);

    #[derive(Clone)]
    struct C(String);

    #[test]
    fn creates_dependency() {
        let mut deps = Deps::new();

        // here we want to know what is the state of dependency in closure, hence
        // shared mutable reference to it
        let created_b_ref = Arc::new(Mutex::new(None));

        deps.attach({
            let created_b_ref = created_b_ref.clone();
            move |_: &Deps, a: &mut A| {
                let b = B([&a.0[..], "+B"].concat());
                *created_b_ref.lock().unwrap() = Some(b.clone());
                Ok(b)
            }
        });

        deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hello+B",
                   (*created_b_ref.lock().unwrap()).clone().unwrap().0);
    }

    #[test]
    fn creates_dependency_of_dependency() {
        let mut deps = Deps::new();

        // here we want to know what is the state of dependency in closure, hence
        // shared mutable reference to it
        let created_c_ref = Arc::new(Mutex::new(None));

        deps.attach(|_: &Deps, a: &mut A| Ok(B([&a.0[..], "+B"].concat())));

        deps.attach({
            let created_c_ref = created_c_ref.clone();
            move |_: &Deps, b: &mut B| {
                let c = C([&b.0[..], "+C"].concat());
                *created_c_ref.lock().unwrap() = Some(c.clone());
                Ok(c)
            }
        });

        deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hello+B+C",
                   (*created_c_ref.lock().unwrap()).clone().unwrap().0);
    }

    #[test]
    fn creates_mutable_dependency() {
        let mut deps = Deps::new();

        deps.attach(|_: &Deps, a: &mut A| {
            *a = A("Hi!".into());
            Ok(())
        });

        let a = deps.create(A("Hello".into())).unwrap();

        assert_eq!("Hi!", a.obj.0);
    }
}
<|endoftext|>


<commit_before>// Dependency Graph Library in Rust

//! dglr is a Dependency Graph Library in Rust.
//! In short, you register elements and their dependencies, and then
//! ask for the dependencies of any element in an order that satisfies.
//!
//! Elements are simply &str strings.  You register them with
//! register_dependency() or register_dependencies().
//!
//! Dependenies are (currently) just a list of other elements that
//! the element in question depends on.  [In the future, we may add
//! boolean logic, but currently they are all AND-ed together].
//!
//! Then iterate over .iter() to get the ordered dependencies, and
//! the library does the magic and returns an order which will work.
//! It is possible that other orders also work, but the library's
//! algorithm is deterministic, so you'll always get the same
//! particular one.

#![crate_name = "dglr"]
#![crate_type = "lib"]

// Required for log and rustdoc:
#![feature(phase)]
#[phase(plugin, link)]

extern crate log;

use std::collections::hashmap::{HashMap,HashSet,Occupied,Vacant};
use std::iter::{Iterator};
#[allow(unused_imports)]
use std::task;

/// This is the dependency graph.  You can create it yourself, or
/// use the convenience methods of new(), register_dependency() and
/// register_dependencies() to build one up (that must be mutable).
pub struct DepGraph {
    /// List of dependencies.  Key is the element, values are the
    /// other elements that the key element depends upon.
    pub dependencies: HashMap<String,Vec<String>>,

    // (private) target we are trying to satisfy
    target: Option<String>,

    // (private) elements already satisfied
    satisfied: HashSet<String>,

    // (private) current path, for cycle detection
    curpath: HashSet<String>,
}

pub struct DepGraphIterator<'a> {
    depgraph: &'a mut DepGraph
}
pub struct DepGraphSatisfyingIterator<'a> {
    depgraph: &'a mut DepGraph
}

impl DepGraph {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph
    {
        DepGraph {
            dependencies: HashMap::new(),
            target: None,
            curpath: HashSet::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph.  The thing does not need
    /// to pre-exist, nor do the dependency elements.  But if the
    /// thing does pre-exist, the depends_on will be added to its
    /// existing dependency list.
    pub fn register_dependency<'a>( &mut self,
                                thing: &'a str,
                                depends_on: &'a str )
    {
        match self.dependencies.entry( String::from_str(thing) ) {
            Vacant(entry) => { entry.set( vec![String::from_str(depends_on)] ); },
            Occupied(mut entry) => { (*entry.get_mut()).push(String::from_str(depends_on)); },
        }
    }

    /// Add multiple dependencies of one thing to a DepGraph.  The
    /// thing does not need to pre-exist, nor do the dependency elements.
    /// But if the thing does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies<'a>( &mut self,
                                  thing: &'a str,
                                  depends_on: &'a[&'a str] )
    {
        let newvec: Vec<String> = depends_on.iter().map(
            |s| String::from_str(*s)).collect();

        match self.dependencies.entry( String::from_str(thing) ) {
            Vacant(entry) => { entry.set( newvec.clone() ); },
            Occupied(mut entry) => { (*entry.get_mut()).push_all(newvec.as_slice()); },
        }
    }

    pub fn set_target<'a>( &mut self, target: &'a str )
    {
        self.target = Some(String::from_str(target));
    }

    pub fn mark_as_satisfied<'a>( &mut self,
                                   things: &'a[&'a str] )
    {
        for thing in things.iter() {
            self.satisfied.insert(String::from_str(*thing));
        }
    }

    fn get_next_dependency(&mut self, thing: &String) -> String
    {
        if self.curpath.contains(thing) {
            fail!("Circular dependency graph at {}",thing);
        }
        self.curpath.insert(thing.clone());

        let deplist = match self.dependencies.find(thing) {
            None => return thing.clone(),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            if self.satisfied.contains(n) {
                continue;
            }
            return self.get_next_dependency(n);
        }
        // things dependencies are satisfied
        thing.clone()
    }

    pub fn iter<'a>(&'a mut self) -> DepGraphIterator<'a>
    {
        DepGraphIterator {
            depgraph: self
        }
    }

    pub fn satisfying_iter<'a>(&'a mut self) -> DepGraphSatisfyingIterator<'a>
    {
        DepGraphSatisfyingIterator {
            depgraph: self
        }
    }
}

impl<'a> Iterator<String> for DepGraphIterator<'a> {
    fn next(&mut self) -> Option<String>
    {
        let thing = match self.depgraph.target {
            None => return None,
            Some(ref thing) => thing.clone()
        };
        if self.depgraph.satisfied.contains(&thing) {
            return None;
        }
        self.depgraph.curpath.clear();
        Some(self.depgraph.get_next_dependency(&thing))
    }
}

impl<'a> Iterator<String> for DepGraphSatisfyingIterator<'a> {
    fn next(&mut self) -> Option<String>
    {
        let thing = match self.depgraph.target {
            None => return None,
            Some(ref thing) => thing.clone()
        };
        if self.depgraph.satisfied.contains(&thing) {
            return None;
        }
        self.depgraph.curpath.clear();
        let next = self.depgraph.get_next_dependency(&thing);
        self.depgraph.mark_as_satisfied([next.as_slice()]);
        Some(next)
    }
}

#[test]
fn dglr_test_branching() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e","m","g"]);
    depgraph.register_dependency("e","f");
    depgraph.register_dependency("g","h");
    depgraph.register_dependency("h","i");
    depgraph.register_dependencies("i",&["j","k"]);
    depgraph.register_dependencies("k",&["l","m"]);
    depgraph.register_dependency("m","n");

    depgraph.set_target("a");

    let mut results: Vec<String> = Vec::new();

    loop {
        // detect infinite looping bugs
        assert!(results.len() < 30);

        let thing = match depgraph.iter().next() {
            Some(x) => x,
            None => break,
        };
        depgraph.mark_as_satisfied([thing.as_slice()]);
        results.push(thing);
    }

    assert!( results == vec![String::from_str("d"),
                             String::from_str("b"),
                             String::from_str("f"),
                             String::from_str("e"),
                             String::from_str("n"),
                             String::from_str("m"),
                             String::from_str("j"),
                             String::from_str("l"),
                             String::from_str("k"),
                             String::from_str("i"),
                             String::from_str("h"),
                             String::from_str("g"),
                             String::from_str("c"),
                             String::from_str("a")] );
    //info!("Deps of a = {}",results);
}

#[test]
fn dglr_test_satisfying() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e"]);

    depgraph.set_target("a");

    let mut results: Vec<String> = Vec::new();

    for thing in depgraph.satisfying_iter() {
        // detect infinite looping bugs
        assert!(results.len() < 30);
        results.push(thing);
    }

    assert!( results == vec![String::from_str("d"),
                             String::from_str("b"),
                             String::from_str("e"),
                             String::from_str("c"),
                             String::from_str("a")] );
    //info!("Deps of a = {}",results);
}

#[test]
fn dglr_test_circular() {

    let task_result = task::try(proc() {
        let mut depgraph: DepGraph = DepGraph::new();
        depgraph.register_dependency("a","b");
        depgraph.register_dependency("b","c");
        depgraph.register_dependency("c","a");
        depgraph.set_target("a");

        let mut results: Vec<String> = Vec::new();

        loop {
            // Detect infinite looping bugs by
            // breaking out successfully (successful
            // proc() means failed test!)
            if results.len() >= 30 { break; }

            let thing = match depgraph.iter().next() {
                Some(x) => x,
                None => break,
            };
            depgraph.mark_as_satisfied([thing.as_slice()]);
            results.push(thing);
        }
    });
    match task_result {
        Ok(_) => fail!("Should have failed at the circular dependency!"),
        Err(_) => () //info!("Successfully detected the circular dependency (ignore task failure)"),
    };
}

#[test]
fn dglr_test_satisfied_stoppage() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependencies("superconn", []);
    depgraph.register_dependencies("owneruser", ["superconn"]);
    depgraph.register_dependencies("appuser", ["superconn"]);
    depgraph.register_dependencies("database", ["owneruser"]);
    depgraph.register_dependencies("ownerconn", ["database","owneruser"]);
    depgraph.register_dependencies("adminconn", ["database"]);
    depgraph.register_dependencies("extensions", ["database","adminconn"]);
    depgraph.register_dependencies("schema_table", ["database","ownerconn"]);
    depgraph.register_dependencies("schemas", ["ownerconn","extensions","schema_table","appuser"]);
    depgraph.register_dependencies("appconn", ["database","appuser","schemas"]);

    depgraph.set_target("appconn");
    depgraph.mark_as_satisfied(["owneruser","appuser"]);

    let mut results: Vec<String> = Vec::new();

    loop {
        assert!(results.len() < 30);

        let thing = match depgraph.iter().next() {
            Some(x) => x,
            None => break,
        };
        depgraph.mark_as_satisfied([thing.as_slice()]);
        results.push(thing);
    }
    assert!( !results.contains(&String::from_str("superconn")) );
}
<commit_msg>upstream rust: panic! replaces fail!<commit_after>// Dependency Graph Library in Rust

//! dglr is a Dependency Graph Library in Rust.
//! In short, you register elements and their dependencies, and then
//! ask for the dependencies of any element in an order that satisfies.
//!
//! Elements are simply &str strings.  You register them with
//! register_dependency() or register_dependencies().
//!
//! Dependenies are (currently) just a list of other elements that
//! the element in question depends on.  [In the future, we may add
//! boolean logic, but currently they are all AND-ed together].
//!
//! Then iterate over .iter() to get the ordered dependencies, and
//! the library does the magic and returns an order which will work.
//! It is possible that other orders also work, but the library's
//! algorithm is deterministic, so you'll always get the same
//! particular one.

#![crate_name = "dglr"]
#![crate_type = "lib"]

// Required for log and rustdoc:
#![feature(phase)]
#[phase(plugin, link)]

extern crate log;

use std::collections::hashmap::{HashMap,HashSet,Occupied,Vacant};
use std::iter::{Iterator};
#[allow(unused_imports)]
use std::task;

/// This is the dependency graph.  You can create it yourself, or
/// use the convenience methods of new(), register_dependency() and
/// register_dependencies() to build one up (that must be mutable).
pub struct DepGraph {
    /// List of dependencies.  Key is the element, values are the
    /// other elements that the key element depends upon.
    pub dependencies: HashMap<String,Vec<String>>,

    // (private) target we are trying to satisfy
    target: Option<String>,

    // (private) elements already satisfied
    satisfied: HashSet<String>,

    // (private) current path, for cycle detection
    curpath: HashSet<String>,
}

pub struct DepGraphIterator<'a> {
    depgraph: &'a mut DepGraph
}
pub struct DepGraphSatisfyingIterator<'a> {
    depgraph: &'a mut DepGraph
}

impl DepGraph {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph
    {
        DepGraph {
            dependencies: HashMap::new(),
            target: None,
            curpath: HashSet::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph.  The thing does not need
    /// to pre-exist, nor do the dependency elements.  But if the
    /// thing does pre-exist, the depends_on will be added to its
    /// existing dependency list.
    pub fn register_dependency<'a>( &mut self,
                                thing: &'a str,
                                depends_on: &'a str )
    {
        match self.dependencies.entry( String::from_str(thing) ) {
            Vacant(entry) => { entry.set( vec![String::from_str(depends_on)] ); },
            Occupied(mut entry) => { (*entry.get_mut()).push(String::from_str(depends_on)); },
        }
    }

    /// Add multiple dependencies of one thing to a DepGraph.  The
    /// thing does not need to pre-exist, nor do the dependency elements.
    /// But if the thing does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies<'a>( &mut self,
                                  thing: &'a str,
                                  depends_on: &'a[&'a str] )
    {
        let newvec: Vec<String> = depends_on.iter().map(
            |s| String::from_str(*s)).collect();

        match self.dependencies.entry( String::from_str(thing) ) {
            Vacant(entry) => { entry.set( newvec.clone() ); },
            Occupied(mut entry) => { (*entry.get_mut()).push_all(newvec.as_slice()); },
        }
    }

    pub fn set_target<'a>( &mut self, target: &'a str )
    {
        self.target = Some(String::from_str(target));
    }

    pub fn mark_as_satisfied<'a>( &mut self,
                                   things: &'a[&'a str] )
    {
        for thing in things.iter() {
            self.satisfied.insert(String::from_str(*thing));
        }
    }

    fn get_next_dependency(&mut self, thing: &String) -> String
    {
        if self.curpath.contains(thing) {
            panic!("Circular dependency graph at {}",thing);
        }
        self.curpath.insert(thing.clone());

        let deplist = match self.dependencies.find(thing) {
            None => return thing.clone(),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            if self.satisfied.contains(n) {
                continue;
            }
            return self.get_next_dependency(n);
        }
        // things dependencies are satisfied
        thing.clone()
    }

    pub fn iter<'a>(&'a mut self) -> DepGraphIterator<'a>
    {
        DepGraphIterator {
            depgraph: self
        }
    }

    pub fn satisfying_iter<'a>(&'a mut self) -> DepGraphSatisfyingIterator<'a>
    {
        DepGraphSatisfyingIterator {
            depgraph: self
        }
    }
}

impl<'a> Iterator<String> for DepGraphIterator<'a> {
    fn next(&mut self) -> Option<String>
    {
        let thing = match self.depgraph.target {
            None => return None,
            Some(ref thing) => thing.clone()
        };
        if self.depgraph.satisfied.contains(&thing) {
            return None;
        }
        self.depgraph.curpath.clear();
        Some(self.depgraph.get_next_dependency(&thing))
    }
}

impl<'a> Iterator<String> for DepGraphSatisfyingIterator<'a> {
    fn next(&mut self) -> Option<String>
    {
        let thing = match self.depgraph.target {
            None => return None,
            Some(ref thing) => thing.clone()
        };
        if self.depgraph.satisfied.contains(&thing) {
            return None;
        }
        self.depgraph.curpath.clear();
        let next = self.depgraph.get_next_dependency(&thing);
        self.depgraph.mark_as_satisfied([next.as_slice()]);
        Some(next)
    }
}

#[test]
fn dglr_test_branching() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e","m","g"]);
    depgraph.register_dependency("e","f");
    depgraph.register_dependency("g","h");
    depgraph.register_dependency("h","i");
    depgraph.register_dependencies("i",&["j","k"]);
    depgraph.register_dependencies("k",&["l","m"]);
    depgraph.register_dependency("m","n");

    depgraph.set_target("a");

    let mut results: Vec<String> = Vec::new();

    loop {
        // detect infinite looping bugs
        assert!(results.len() < 30);

        let thing = match depgraph.iter().next() {
            Some(x) => x,
            None => break,
        };
        depgraph.mark_as_satisfied([thing.as_slice()]);
        results.push(thing);
    }

    assert!( results == vec![String::from_str("d"),
                             String::from_str("b"),
                             String::from_str("f"),
                             String::from_str("e"),
                             String::from_str("n"),
                             String::from_str("m"),
                             String::from_str("j"),
                             String::from_str("l"),
                             String::from_str("k"),
                             String::from_str("i"),
                             String::from_str("h"),
                             String::from_str("g"),
                             String::from_str("c"),
                             String::from_str("a")] );
    //info!("Deps of a = {}",results);
}

#[test]
fn dglr_test_satisfying() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e"]);

    depgraph.set_target("a");

    let mut results: Vec<String> = Vec::new();

    for thing in depgraph.satisfying_iter() {
        // detect infinite looping bugs
        assert!(results.len() < 30);
        results.push(thing);
    }

    assert!( results == vec![String::from_str("d"),
                             String::from_str("b"),
                             String::from_str("e"),
                             String::from_str("c"),
                             String::from_str("a")] );
    //info!("Deps of a = {}",results);
}

#[test]
fn dglr_test_circular() {

    let task_result = task::try(proc() {
        let mut depgraph: DepGraph = DepGraph::new();
        depgraph.register_dependency("a","b");
        depgraph.register_dependency("b","c");
        depgraph.register_dependency("c","a");
        depgraph.set_target("a");

        let mut results: Vec<String> = Vec::new();

        loop {
            // Detect infinite looping bugs by
            // breaking out successfully (successful
            // proc() means failed test!)
            if results.len() >= 30 { break; }

            let thing = match depgraph.iter().next() {
                Some(x) => x,
                None => break,
            };
            depgraph.mark_as_satisfied([thing.as_slice()]);
            results.push(thing);
        }
    });
    match task_result {
        Ok(_) => panic!("Should have failed at the circular dependency!"),
        Err(_) => () //info!("Successfully detected the circular dependency (ignore task failure)"),
    };
}

#[test]
fn dglr_test_satisfied_stoppage() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependencies("superconn", []);
    depgraph.register_dependencies("owneruser", ["superconn"]);
    depgraph.register_dependencies("appuser", ["superconn"]);
    depgraph.register_dependencies("database", ["owneruser"]);
    depgraph.register_dependencies("ownerconn", ["database","owneruser"]);
    depgraph.register_dependencies("adminconn", ["database"]);
    depgraph.register_dependencies("extensions", ["database","adminconn"]);
    depgraph.register_dependencies("schema_table", ["database","ownerconn"]);
    depgraph.register_dependencies("schemas", ["ownerconn","extensions","schema_table","appuser"]);
    depgraph.register_dependencies("appconn", ["database","appuser","schemas"]);

    depgraph.set_target("appconn");
    depgraph.mark_as_satisfied(["owneruser","appuser"]);

    let mut results: Vec<String> = Vec::new();

    loop {
        assert!(results.len() < 30);

        let thing = match depgraph.iter().next() {
            Some(x) => x,
            None => break,
        };
        depgraph.mark_as_satisfied([thing.as_slice()]);
        results.push(thing);
    }
    assert!( !results.contains(&String::from_str("superconn")) );
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Read;
use std::path::Path;

#[allow(dead_code)]
pub enum Policy {
    Left, Right
}

#[derive(Clone)]
pub struct Dict {
    wlst: Vec<Vec<char>>
}

impl Dict {
    pub fn default_path() -> &'static Path {
        Path::new(
            concat!(env!("CARGO_MANIFEST_DIR"),
                    "/data/tdict-std.txt"))
    }

    pub fn lao_path() -> &'static Path {
        Path::new(
            concat!(env!("CARGO_MANIFEST_DIR"),
                    "/data/laowords.txt"))
    }

    pub fn create<'a>(words: &Vec<String>) -> Result<Dict, &'a str> {
        Ok(Dict{wlst:words.iter().map(|w| w.chars().collect()).collect()})
    }

    pub fn load<'a>(path: &Path) -> Result<Dict, &'a str> {
        let mut f = match File::open(path) {
            Ok(f) => f,
            Err(_) => return Err("Cannot open dict")
        };
        let mut s = String::new();
        match f.read_to_string(&mut s) {
            Ok(_) => (),
            Err(_) => return Err("Cannot read dict")
        };
        let words = s.lines();
        let wlst: Vec<Vec<char>> = words.map(|w| w.chars().collect()).collect();
        Ok(Dict{wlst:wlst})
    }

    pub fn seek(&self, policy: Policy, _l: usize, _r: usize, offset: usize, ch: char) -> Option<usize> {
        let mut ans: usize = 0;
        let mut found = false;
        let mut m: usize;
        let mut l = _l as i64;
        let mut r = _r as i64;

        while l <= r {
            m = ((l + r) / 2) as usize;
            let w = &self.wlst[m];
            let wlen = w.len();
            if wlen <= offset {
                l = (m as i64) + 1;
            } else {
                let ch_ = w[offset];
                if ch_ < ch {
                    l = (m as i64) + 1;
                } else if ch_ > ch {
                    r = (m as i64) - 1;
                } else {
                    ans = m;
                    found = true;
                    match policy {
                        Policy::Left => r = (m as i64) - 1,
                        Policy::Right => l = (m as i64) + 1
                    }
                }
            }
        }
        if found {
            Some(ans)
        } else {
            None
        }
    }

    pub fn is_final(&self, len: usize, m: usize) -> bool {
        let w = &self.wlst[m];
        let wlen = w.len();
        wlen == len
    }

    pub fn r(&self) -> usize {
        self.wlst.len() - 1
    }
}
<commit_msg>use isize instead of i64<commit_after>use std::fs::File;
use std::io::Read;
use std::path::Path;

#[allow(dead_code)]
pub enum Policy {
    Left, Right
}

#[derive(Clone)]
pub struct Dict {
    wlst: Vec<Vec<char>>
}

impl Dict {
    pub fn default_path() -> &'static Path {
        Path::new(
            concat!(env!("CARGO_MANIFEST_DIR"),
                    "/data/tdict-std.txt"))
    }

    pub fn lao_path() -> &'static Path {
        Path::new(
            concat!(env!("CARGO_MANIFEST_DIR"),
                    "/data/laowords.txt"))
    }

    pub fn create<'a>(words: &Vec<String>) -> Result<Dict, &'a str> {
        Ok(Dict{wlst:words.iter().map(|w| w.chars().collect()).collect()})
    }

    pub fn load<'a>(path: &Path) -> Result<Dict, &'a str> {
        let mut f = match File::open(path) {
            Ok(f) => f,
            Err(_) => return Err("Cannot open dict")
        };
        let mut s = String::new();
        match f.read_to_string(&mut s) {
            Ok(_) => (),
            Err(_) => return Err("Cannot read dict")
        };
        let words = s.lines();
        let wlst: Vec<Vec<char>> = words.map(|w| w.chars().collect()).collect();
        Ok(Dict{wlst:wlst})
    }

    pub fn seek(&self, policy: Policy, _l: usize, _r: usize, offset: usize, ch: char) -> Option<usize> {
        let mut ans: usize = 0;
        let mut found = false;
        let mut m: usize;
        let mut l = _l as isize;
        let mut r = _r as isize;

        while l <= r {
            m = ((l + r) / 2) as usize;
            let w = &self.wlst[m];
            let wlen = w.len();
            if wlen <= offset {
                l = (m as isize) + 1;
            } else {
                let ch_ = w[offset];
                if ch_ < ch {
                    l = (m as isize) + 1;
                } else if ch_ > ch {
                    r = (m as isize) - 1;
                } else {
                    ans = m;
                    found = true;
                    match policy {
                        Policy::Left => r = (m as isize) - 1,
                        Policy::Right => l = (m as isize) + 1
                    }
                }
            }
        }
        if found {
            Some(ans)
        } else {
            None
        }
    }

    pub fn is_final(&self, len: usize, m: usize) -> bool {
        let w = &self.wlst[m];
        let wlen = w.len();
        wlen == len
    }

    pub fn r(&self) -> usize {
        self.wlst.len() - 1
    }
}
<|endoftext|>


<commit_before>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use super::UPLO;
use super::convert::*;
use super::diagonal::*;
use super::error::*;
use super::layout::*;
use super::operator::*;
use super::types::*;

/// Eigenvalue decomposition of Hermite matrix
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighMut {
    type EigVal;
    fn eigh_mut(&mut self, UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((Array::from_vec(s), self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let mut a = replicate(self);
        let s = A::eigh(true, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), a))
    }
}

impl<A, S> EighMut for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_mut(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh<EigVal> {
    fn eigvalsh(self, UPLO) -> Result<EigVal>;
}

impl<A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(false, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let mut a = self.to_owned();
        let s = A::eigh(false, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a mut ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh(uplo)?;
        let e_sqrt = Array1::from_iter(e.iter().map(|r| AssociatedReal::inject(r.sqrt())));
        let ev = e_sqrt.into_diagonal().op(&v.t());
        Ok(v.op(&ev))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array1::from_iter(e.iter().map(|r| AssociatedReal::inject(r.sqrt())));
        let ev = e_sqrt.into_diagonal().op(&v.t());
        Ok(v.op(&ev))
    }
}
<commit_msg>Unify implement of Eigh and EigVals<commit_after>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use super::UPLO;
use super::diagonal::*;
use super::error::*;
use super::layout::*;
use super::operator::*;
use super::types::*;

/// Eigenvalue decomposition of Hermite matrix
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighMut {
    type EigVal;
    fn eigh_mut(&mut self, UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_mut(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let a = self.to_owned();
        a.eigh_into(uplo)
    }
}

impl<A, S> EighMut for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_mut(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh {
    type EigVal;
    fn eigvalsh(&self, UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInto {
    type EigVal;
    fn eigvalsh_into(self, UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshMut {
    type EigVal;
    fn eigvalsh_mut(&mut self, UPLO) -> Result<Self::EigVal>;
}

impl<A, S> EigValshInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_into(mut self, uplo: UPLO) -> Result<Self::EigVal> {
        self.eigvalsh_mut(uplo)
    }
}

impl<A, S> EigValsh for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal> {
        let a = self.to_owned();
        a.eigvalsh_into(uplo)
    }
}

impl<A, S> EigValshMut for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_mut(&mut self, uplo: UPLO) -> Result<Self::EigVal> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let a = self.to_owned();
        a.ssqrt_into(uplo)
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array1::from_iter(e.iter().map(|r| AssociatedReal::inject(r.sqrt())));
        let ev = e_sqrt.into_diagonal().op(&v.t());
        Ok(v.op(&ev))
    }
}
<|endoftext|>


<commit_before>//! Free functions that create iterator adaptors or call iterator methods.
//!
//! The benefit of free functions is that they accept any `IntoIterator` as
//! argument, so the resulting code may be easier to read.

use std::fmt::Display;
use std::iter::{self, Zip};
use {
    Itertools,
    Merge,
    KMerge,
    Interleave,
    ZipEq,
};

/// Iterate `iterable` with a running index.
///
/// `IntoIterator` enabled version of `.enumerate()`.
///
/// ```
/// use itertools::enumerate;
///
/// for (i, elt) in enumerate(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
    where I: IntoIterator
{
    iterable.into_iter().enumerate()
}

/// Iterate `iterable` in reverse.
///
/// `IntoIterator` enabled version of `.rev()`.
///
/// ```
/// use itertools::rev;
///
/// for elt in rev(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
    where I: IntoIterator,
          I::IntoIter: DoubleEndedIterator
{
    iterable.into_iter().rev()
}

/// Iterate `i` and `j` in lock step.
///
/// `IntoIterator` enabled version of `i.zip(j)`.
///
/// ```
/// use itertools::free::zip;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip(&data, &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip(j)
}

/// Iterate `i` and `j` in lock step.
///
/// **Panics** if the iterators are not of the same length.
///
/// `IntoIterator` enabled version of `i.zip_eq(j)`.
///
/// ```
/// use itertools::free::zip_eq;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip_eq(j)
}

/// Create an iterator that first iterates `i` and then `j`.
///
/// `IntoIterator` enabled version of `i.chain(j)`.
///
/// ```
/// use itertools::free::chain;
///
/// for elt in chain(&[1, 2, 3], &[4]) {
///     /* loop body */
/// }
/// ```
pub fn chain<I, J>(i: I, j: J) -> iter::Chain<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().chain(j)
}

/// Perform a fold operation over the iterable.
///
/// `IntoIterator` enabled version of `i.fold(init, f)`
///
/// ```
/// use itertools::free::fold;
///
/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
/// ```
pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
    where I: IntoIterator,
          F: FnMut(B, I::Item) -> B
{
    iterable.into_iter().fold(init, f)
}

/// Test whether the predicate holds for all elements in the iterable.
///
/// `IntoIterator` enabled version of `i.all(f)`
///
/// ```
/// use itertools::free::all;
///
/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
/// ```
pub fn all<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().all(f)
}

/// Test whether the predicate holds for any elements in the iterable.
///
/// `IntoIterator` enabled version of `i.any(f)`
///
/// ```
/// use itertools::free::any;
///
/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
/// ```
pub fn any<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().any(f)
}

/// Return the maximum value of the iterable.
///
/// `IntoIterator` enabled version of `i.max()`.
///
/// ```
/// use itertools::free::max;
///
/// assert_eq!(max(0..10), Some(9));
/// ```
pub fn max<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().max()
}

/// Return the minimum value of the iterable.
///
/// `IntoIterator` enabled version of `i.min()`.
///
/// ```
/// use itertools::free::min;
///
/// assert_eq!(min(0..10), Some(0));
/// ```
pub fn min<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().min()
}

/// Create an iterator that interleaves elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.interleave(j)`.
///
/// ```
/// use itertools::free::interleave;
///
/// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn interleave<I, J>(i: I, j: J) -> Interleave<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().interleave(j)
}

/// Create an iterator that merges elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.merge(j)`.
///
/// ```
/// use itertools::free::merge;
///
/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn merge<I, J>(i: I, j: J) -> Merge<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>,
          I::Item: PartialOrd
{
    i.into_iter().merge(j)
}

/// Create an iterator that merges elements of the contained iterators.
///
/// Equivalent to `i.into_iter().kmerge()`.
///
/// ```
/// use itertools::free::kmerge;
///
/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
///     /* loop body */
/// }
/// ```
pub fn kmerge<I>(i: I) -> KMerge<<<I as IntoIterator>::Item as IntoIterator>::IntoIter>
    where I: IntoIterator,
          I::Item: IntoIterator,
          <<I as IntoIterator>::Item as IntoIterator>::Item: Ord,
{
    i.into_iter().kmerge()
}

/// Combine all iterator elements into one String, seperated by `sep`.
///
/// `IntoIterator` enabled version of `iterable.join(sep)`.
///
/// ```
/// use itertools::free::join;
///
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
/// ```
pub fn join<I>(iterable: I, sep: &str) -> String
    where I: IntoIterator,
          I::Item: Display
{
    iterable.into_iter().join(sep)
}

/// Collect all the iterable's elements into a sorted vector in ascending order.
///
/// `IntoIterator` enabled version of `iterable.sorted()`.
///
/// ```
/// use itertools::free::sorted;
/// use itertools::assert_equal;
///
/// assert_equal(sorted("rust".chars()), "rstu".chars());
/// ```
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().sorted()
}
<commit_msg>Workaround regression in current rust nightly<commit_after>//! Free functions that create iterator adaptors or call iterator methods.
//!
//! The benefit of free functions is that they accept any `IntoIterator` as
//! argument, so the resulting code may be easier to read.

use std::fmt::Display;
use std::iter::{self, Zip};
use {
    Interleave,
    Itertools,
    KMerge,
    Merge,
    ZipEq,
};

/// Iterate `iterable` with a running index.
///
/// `IntoIterator` enabled version of `.enumerate()`.
///
/// ```
/// use itertools::enumerate;
///
/// for (i, elt) in enumerate(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
    where I: IntoIterator
{
    iterable.into_iter().enumerate()
}

/// Iterate `iterable` in reverse.
///
/// `IntoIterator` enabled version of `.rev()`.
///
/// ```
/// use itertools::rev;
///
/// for elt in rev(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
    where I: IntoIterator,
          I::IntoIter: DoubleEndedIterator
{
    iterable.into_iter().rev()
}

/// Iterate `i` and `j` in lock step.
///
/// `IntoIterator` enabled version of `i.zip(j)`.
///
/// ```
/// use itertools::free::zip;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip(&data, &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip(j)
}

/// Iterate `i` and `j` in lock step.
///
/// **Panics** if the iterators are not of the same length.
///
/// `IntoIterator` enabled version of `i.zip_eq(j)`.
///
/// ```
/// use itertools::free::zip_eq;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip_eq(j)
}

/*
/// Create an iterator that first iterates `i` and then `j`.
///
/// `IntoIterator` enabled version of `i.chain(j)`.
///
/// ```
/// use itertools::free::chain;
///
/// for elt in chain(&[1, 2, 3], &[4]) {
///     /* loop body */
/// }
/// ```
pub fn chain<I, J>(i: I, j: J) -> iter::Chain<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().chain(j)
}
*/

/// Perform a fold operation over the iterable.
///
/// `IntoIterator` enabled version of `i.fold(init, f)`
///
/// ```
/// use itertools::free::fold;
///
/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
/// ```
pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
    where I: IntoIterator,
          F: FnMut(B, I::Item) -> B
{
    iterable.into_iter().fold(init, f)
}

/// Test whether the predicate holds for all elements in the iterable.
///
/// `IntoIterator` enabled version of `i.all(f)`
///
/// ```
/// use itertools::free::all;
///
/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
/// ```
pub fn all<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().all(f)
}

/// Test whether the predicate holds for any elements in the iterable.
///
/// `IntoIterator` enabled version of `i.any(f)`
///
/// ```
/// use itertools::free::any;
///
/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
/// ```
pub fn any<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().any(f)
}

/// Return the maximum value of the iterable.
///
/// `IntoIterator` enabled version of `i.max()`.
///
/// ```
/// use itertools::free::max;
///
/// assert_eq!(max(0..10), Some(9));
/// ```
pub fn max<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().max()
}

/// Return the minimum value of the iterable.
///
/// `IntoIterator` enabled version of `i.min()`.
///
/// ```
/// use itertools::free::min;
///
/// assert_eq!(min(0..10), Some(0));
/// ```
pub fn min<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().min()
}

/// Create an iterator that interleaves elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.interleave(j)`.
///
/// ```
/// use itertools::free::interleave;
///
/// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().interleave(j)
}

/// Create an iterator that merges elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.merge(j)`.
///
/// ```
/// use itertools::free::merge;
///
/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>,
          I::Item: PartialOrd
{
    i.into_iter().merge(j)
}

/// Create an iterator that merges elements of the contained iterators.
///
/// Equivalent to `i.into_iter().kmerge()`.
///
/// ```
/// use itertools::free::kmerge;
///
/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
///     /* loop body */
/// }
/// ```
pub fn kmerge<I>(i: I) -> KMerge<<<I as IntoIterator>::Item as IntoIterator>::IntoIter>
    where I: IntoIterator,
          I::Item: IntoIterator,
          <<I as IntoIterator>::Item as IntoIterator>::Item: Ord,
{
    i.into_iter().kmerge()
}

/// Combine all iterator elements into one String, seperated by `sep`.
///
/// `IntoIterator` enabled version of `iterable.join(sep)`.
///
/// ```
/// use itertools::free::join;
///
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
/// ```
pub fn join<I>(iterable: I, sep: &str) -> String
    where I: IntoIterator,
          I::Item: Display
{
    iterable.into_iter().join(sep)
}

/// Collect all the iterable's elements into a sorted vector in ascending order.
///
/// `IntoIterator` enabled version of `iterable.sorted()`.
///
/// ```
/// use itertools::free::sorted;
/// use itertools::assert_equal;
///
/// assert_equal(sorted("rust".chars()), "rstu".chars());
/// ```
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().sorted()
}
<|endoftext|>