1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use conch_parser::ast;
use env::{AsyncIoEnvironment, ExecutableEnvironment, ExportedVariableEnvironment,
FileDescEnvironment, FunctionEnvironment, SetArgumentsEnvironment,
UnsetVariableEnvironment, WorkingDirectoryEnvironment};
use error::{CommandError, RedirectionError};
use eval::{RedirectEval, RedirectOrCmdWord, RedirectOrVarAssig, WordEval};
use io::FileDescWrapper;
use spawn::{ExitResult, Spawn, SimpleCommand, simple_command, SpawnedSimpleCommand};
use std::borrow::Borrow;
use std::hash::Hash;
use std::vec::IntoIter;
pub type SimpleCommandEnvFuture<R, V, W, E> = SimpleCommand<
R, V, W,
IntoIter<RedirectOrVarAssig<R, V, W>>,
IntoIter<RedirectOrCmdWord<R, W>>,
E
>;
impl<V, W, R, S, E: ?Sized> Spawn<E> for ast::SimpleCommand<V, W, R>
where R: RedirectEval<E, Handle = E::FileHandle>,
R::Error: From<RedirectionError>,
V: Hash + Eq + Borrow<String>,
W: WordEval<E>,
S: Clone + Spawn<E>,
S::Error: From<CommandError> + From<RedirectionError> + From<R::Error> + From<W::Error>,
E: AsyncIoEnvironment
+ ExecutableEnvironment
+ ExportedVariableEnvironment
+ FileDescEnvironment
+ FunctionEnvironment<Fn = S>
+ SetArgumentsEnvironment
+ UnsetVariableEnvironment
+ WorkingDirectoryEnvironment,
E::Arg: From<W::EvalResult>,
E::Args: From<Vec<E::Arg>>,
E::FileHandle: FileDescWrapper,
E::FnName: From<W::EvalResult>,
E::VarName: Borrow<String> + Clone + From<V>,
E::Var: Borrow<String> + Clone + From<W::EvalResult>,
{
type EnvFuture = SimpleCommandEnvFuture<R, V, W, E>;
type Future = ExitResult<SpawnedSimpleCommand<E::Future, S::Future>>;
type Error = S::Error;
fn spawn(self, env: &E) -> Self::EnvFuture {
let vars: Vec<_> = self.redirects_or_env_vars.into_iter().map(Into::into).collect();
let words: Vec<_> = self.redirects_or_cmd_words.into_iter().map(Into::into).collect();
simple_command(vars, words, env)
}
}
impl<'a, V, W, R, S, E: ?Sized> Spawn<E> for &'a ast::SimpleCommand<V, W, R>
where &'a R: RedirectEval<E, Handle = E::FileHandle>,
<&'a R as RedirectEval<E>>::Error: From<RedirectionError>,
V: Hash + Eq + Borrow<String> + Clone,
&'a W: WordEval<E>,
S: Clone + Spawn<E>,
S::Error: From<CommandError>
+ From<RedirectionError>
+ From<<&'a R as RedirectEval<E>>::Error>
+ From<<&'a W as WordEval<E>>::Error>,
E: AsyncIoEnvironment
+ ExecutableEnvironment
+ ExportedVariableEnvironment
+ FileDescEnvironment
+ FunctionEnvironment<Fn = S>
+ SetArgumentsEnvironment
+ UnsetVariableEnvironment
+ WorkingDirectoryEnvironment,
E::Arg: From<<&'a W as WordEval<E>>::EvalResult>,
E::Args: From<Vec<E::Arg>>,
E::FileHandle: FileDescWrapper,
E::FnName: From<<&'a W as WordEval<E>>::EvalResult>,
E::VarName: Borrow<String> + Clone + From<V>,
E::Var: Borrow<String> + Clone + From<<&'a W as WordEval<E>>::EvalResult>,
{
type EnvFuture = SimpleCommandEnvFuture<&'a R, V, &'a W, E>;
type Future = ExitResult<SpawnedSimpleCommand<E::Future, S::Future>>;
type Error = S::Error;
fn spawn(self, env: &E) -> Self::EnvFuture {
let vars: Vec<_> = self.redirects_or_env_vars.iter()
.map(|v| {
use self::ast::RedirectOrEnvVar::*;
match *v {
Redirect(ref r) => RedirectOrVarAssig::Redirect(r),
EnvVar(ref v, ref w) => RedirectOrVarAssig::VarAssig(v.clone(), w.as_ref()),
}
})
.collect();
let words: Vec<_> = self.redirects_or_cmd_words.iter()
.map(|w| match *w {
ast::RedirectOrCmdWord::Redirect(ref r) => RedirectOrCmdWord::Redirect(r),
ast::RedirectOrCmdWord::CmdWord(ref w) => RedirectOrCmdWord::CmdWord(w),
})
.collect();
simple_command(vars, words, env)
}
}