Skip to content

Commit

Permalink
fix(serialization): redirect with fd panicked (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Jan 26, 2024
1 parent 196c2d0 commit 9636c11
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 13 deletions.
44 changes: 34 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ monch = "0.5.0"
[dev-dependencies]
parking_lot = "0.12.1"
pretty_assertions = "1"
serde_json = "1.0.111"
tempfile = "3.8.1"
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.73.0"
channel = "1.75.0"
components = ["clippy", "rustfmt"]
124 changes: 123 additions & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ pub enum WordPart {
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
#[cfg_attr(
feature = "serialization",
serde(rename_all = "camelCase", tag = "kind")
serde(rename_all = "camelCase", tag = "kind", content = "fd")
)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RedirectFd {
Expand Down Expand Up @@ -1556,4 +1556,126 @@ mod test {
"echo 1 1> stdout.txt | cat",
);
}

#[cfg(feature = "serialization")]
#[test]
fn serializes_command_to_json() {
assert_json_equals(
serialize_to_json("./example > output.txt"),
serde_json::json!({
"items": [{
"isAsync": false,
"sequence": {
"inner": {
"inner": {
"args": [[{
"kind": "text",
"value": "./example"
}]],
"envVars": [],
"kind": "simple"
},
"kind": "command",
"redirect": {
"ioFile": [{
"kind": "text",
"value": "output.txt"
}],
"maybeFd": null,
"op": "redirect"
}
},
"kind": "pipeline",
"negated": false
}
}]
}),
);
assert_json_equals(
serialize_to_json("./example 2> output.txt"),
serde_json::json!({
"items": [{
"isAsync": false,
"sequence": {
"inner": {
"inner": {
"args": [[{
"kind": "text",
"value": "./example"
}]],
"envVars": [],
"kind": "simple"
},
"kind": "command",
"redirect": {
"ioFile": [{
"kind": "text",
"value": "output.txt"
}],
"maybeFd": {
"kind": "fd",
"fd": 2,
},
"op": "redirect"
}
},
"kind": "pipeline",
"negated": false
}
}]
}),
);
assert_json_equals(
serialize_to_json("./example &> output.txt"),
serde_json::json!({
"items": [{
"isAsync": false,
"sequence": {
"inner": {
"inner": {
"args": [[{
"kind": "text",
"value": "./example"
}]],
"envVars": [],
"kind": "simple"
},
"kind": "command",
"redirect": {
"ioFile": [{
"kind": "text",
"value": "output.txt"
}],
"maybeFd": {
"kind": "stdoutStderr"
},
"op": "redirect"
}
},
"kind": "pipeline",
"negated": false
}
}]
}),
);
}

#[cfg(feature = "serialization")]
#[track_caller]
fn assert_json_equals(
actual: serde_json::Value,
expected: serde_json::Value,
) {
if actual != expected {
let actual = serde_json::to_string_pretty(&actual).unwrap();
let expected = serde_json::to_string_pretty(&expected).unwrap();
assert_eq!(actual, expected);
}
}

#[cfg(feature = "serialization")]
fn serialize_to_json(text: &str) -> serde_json::Value {
let command = parse(text).unwrap();
serde_json::to_value(command).unwrap()
}
}
2 changes: 1 addition & 1 deletion src/shell/commands/unset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl ShellCommand for UnsetCommand {
}

fn parse_names(mut args: Vec<String>) -> Result<Vec<String>> {
match args.get(0) {
match args.first() {
None => {
// Running the actual `unset` with no argument completes with success.
Ok(args)
Expand Down

0 comments on commit 9636c11

Please sign in to comment.