summaryrefslogtreecommitdiffstats
path: root/src/parse/ast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse/ast.rs')
-rw-r--r--src/parse/ast.rs43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/parse/ast.rs b/src/parse/ast.rs
index 9c99907..92c04ab 100644
--- a/src/parse/ast.rs
+++ b/src/parse/ast.rs
@@ -117,14 +117,14 @@ impl Pipeline {
}
#[derive(Debug, Clone, PartialEq, Eq)]
-struct Exe {
+pub struct Exe {
exe: Word,
args: Vec<Word>,
redirects: Vec<Redirect>,
}
impl Exe {
- async fn eval(self, env: &Env) -> Result<super::Exe> {
+ pub async fn eval(self, env: &Env) -> Result<super::Exe> {
let exe = self.exe.eval(env).await?;
assert_eq!(exe.len(), 1); // TODO
let exe = &exe[0];
@@ -152,6 +152,15 @@ impl Exe {
})
}
+ pub fn parse(s: &str) -> Result<Self, super::Error> {
+ Ok(Self::build_ast(
+ Shell::parse(Rule::exe, s)
+ .map_err(|e| super::Error::new(s.to_string(), e))?
+ .next()
+ .unwrap(),
+ ))
+ }
+
fn build_ast(pair: pest::iterators::Pair<Rule>) -> Self {
assert!(matches!(pair.as_rule(), Rule::subshell | Rule::exe));
if matches!(pair.as_rule(), Rule::subshell) {
@@ -206,6 +215,36 @@ impl Exe {
}
}
+impl<'de> serde::Deserialize<'de> for Exe {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ struct Visitor;
+ impl<'de> serde::de::Visitor<'de> for Visitor {
+ type Value = Exe;
+
+ fn expecting(
+ &self,
+ f: &mut std::fmt::Formatter,
+ ) -> std::fmt::Result {
+ f.write_str("a command")
+ }
+
+ fn visit_str<E>(
+ self,
+ value: &str,
+ ) -> std::result::Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ Exe::parse(value).map_err(serde::de::Error::custom)
+ }
+ }
+ deserializer.deserialize_string(Visitor)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Word {
parts: Vec<WordPart>,