use ExitStatus;
use future::{Async, EnvFuture, Poll};
use future_ext::{EnvFutureExt, FlattenedEnvFuture};
use futures::Future;
mod and_or;
mod case;
mod for_cmd;
mod func_exec;
mod if_cmd;
mod local_redirections;
mod loop_cmd;
mod pipeline;
mod rc;
mod sequence;
mod simple;
mod subshell;
mod substitution;
mod swallow_non_fatal;
mod vec_sequence;
pub mod builtin;
#[cfg(feature = "conch-parser")]
pub mod ast_impl;
use self::vec_sequence::{VecSequence, VecSequenceWithLast};
pub use self::and_or::{AndOr, AndOrList, and_or_list};
pub use self::case::{Case, case, PatternBodyPair};
pub use self::for_cmd::{For, ForArgs, for_args, for_loop, for_with_args};
pub use self::func_exec::{Function, function, function_body};
pub use self::if_cmd::{If, if_cmd};
pub use self::local_redirections::{LocalRedirections, spawn_with_local_redirections};
pub use self::loop_cmd::{Loop, loop_cmd};
pub use self::pipeline::{Pipeline, pipeline, SpawnedPipeline};
pub use self::sequence::{Sequence, sequence};
pub use self::simple::{SimpleCommand, simple_command, SpawnedSimpleCommand};
pub use self::subshell::{Subshell, subshell};
pub use self::substitution::{Substitution, SubstitutionEnvFuture, substitution};
pub use self::swallow_non_fatal::{SwallowNonFatal, swallow_non_fatal_errors};
pub trait Spawn<E: ?Sized> {
type EnvFuture: EnvFuture<E, Item = Self::Future, Error = Self::Error>;
type Future: Future<Item = ExitStatus, Error = Self::Error>;
type Error;
fn spawn(self, env: &E) -> Self::EnvFuture;
}
impl<'a, 'b: 'a, T, E: ?Sized> Spawn<E> for &'a &'b T
where &'b T: Spawn<E>
{
type EnvFuture = <&'b T as Spawn<E>>::EnvFuture;
type Future = <&'b T as Spawn<E>>::Future;
type Error = <&'b T as Spawn<E>>::Error;
fn spawn(self, env: &E) -> Self::EnvFuture {
(*self).spawn(env)
}
}
#[cfg_attr(feature = "clippy", allow(boxed_local))]
impl<E: ?Sized, T: Spawn<E>> Spawn<E> for Box<T> {
type EnvFuture = T::EnvFuture;
type Future = T::Future;
type Error = T::Error;
fn spawn(self, env: &E) -> Self::EnvFuture {
(*self).spawn(env)
}
}
#[cfg_attr(feature = "clippy", allow(boxed_local))]
impl<'a, E: ?Sized, T: 'a> Spawn<E> for &'a Box<T>
where &'a T: Spawn<E>,
{
type EnvFuture = <&'a T as Spawn<E>>::EnvFuture;
type Future = <&'a T as Spawn<E>>::Future;
type Error = <&'a T as Spawn<E>>::Error;
fn spawn(self, env: &E) -> Self::EnvFuture {
Spawn::spawn(&**self, env)
}
}
pub trait SpawnRef<E: ?Sized> {
type EnvFuture: EnvFuture<E, Item = Self::Future, Error = Self::Error>;
type Future: Future<Item = ExitStatus, Error = Self::Error>;
type Error;
fn spawn_ref(&self, env: &E) -> Self::EnvFuture;
}
pub trait Ref: Copy {}
impl<'a, T> Ref for &'a T {}
impl<S, E: ?Sized> SpawnRef<E> for S
where S: Spawn<E> + Ref,
{
type EnvFuture = S::EnvFuture;
type Future = S::Future;
type Error = S::Error;
fn spawn_ref(&self, env: &E) -> Self::EnvFuture {
(*self).spawn(env)
}
}
pub type BoxSpawnEnvFuture<'a, E, ERR> = Box<'a + EnvFuture<
E,
Item = BoxStatusFuture<'a, ERR>,
Error = ERR
>>;
pub type BoxStatusFuture<'a, ERR> = Box<'a + Future<Item = ExitStatus, Error = ERR>>;
pub trait SpawnBoxed<E: ?Sized> {
type Error;
fn spawn_boxed<'a>(&'a self, env: &E) -> BoxSpawnEnvFuture<'a, E, Self::Error> where E: 'a;
}
impl<S, ERR, E: ?Sized> SpawnBoxed<E> for S
where for<'a> &'a S: Spawn<E, Error = ERR>,
{
type Error = ERR;
fn spawn_boxed<'a>(&'a self, env: &E) -> BoxSpawnEnvFuture<'a, E, Self::Error> where E: 'a {
Box::from(self.spawn(env).boxed_result())
}
}
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub enum ExitResult<F> {
Pending(F),
Ready(ExitStatus),
}
impl<F> From<ExitStatus> for ExitResult<F> {
fn from(status: ExitStatus) -> Self {
ExitResult::Ready(status)
}
}
impl<F> Future for ExitResult<F>
where F: Future<Item = ExitStatus>
{
type Item = F::Item;
type Error = F::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match *self {
ExitResult::Pending(ref mut f) => f.poll(),
ExitResult::Ready(exit) => Ok(Async::Ready(exit)),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct GuardBodyPair<T> {
pub guard: T,
pub body: T,
}