-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor process spawn for more granular stdio options
- Loading branch information
1 parent
1aa6aef
commit e16c28f
Showing
8 changed files
with
263 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use std::{fmt, process::Stdio, str::FromStr}; | ||
|
||
use itertools::Itertools; | ||
use mlua::prelude::*; | ||
|
||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] | ||
pub enum ProcessSpawnOptionsStdioKind { | ||
// TODO: We need better more obvious names | ||
// for these, but that is a breaking change | ||
#[default] | ||
Default, | ||
Forward, | ||
Inherit, | ||
None, | ||
} | ||
|
||
impl ProcessSpawnOptionsStdioKind { | ||
pub fn all() -> &'static [Self] { | ||
&[Self::Default, Self::Forward, Self::Inherit, Self::None] | ||
} | ||
|
||
pub fn as_stdio(self) -> Stdio { | ||
match self { | ||
Self::None => Stdio::null(), | ||
Self::Forward => Stdio::inherit(), | ||
_ => Stdio::piped(), | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Display for ProcessSpawnOptionsStdioKind { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
let s = match *self { | ||
Self::Default => "default", | ||
Self::Forward => "forward", | ||
Self::Inherit => "inherit", | ||
Self::None => "none", | ||
}; | ||
f.write_str(s) | ||
} | ||
} | ||
|
||
impl FromStr for ProcessSpawnOptionsStdioKind { | ||
type Err = LuaError; | ||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
Ok(match s.trim().to_ascii_lowercase().as_str() { | ||
"default" => Self::Default, | ||
"forward" => Self::Forward, | ||
"inherit" => Self::Inherit, | ||
"none" => Self::None, | ||
_ => { | ||
return Err(LuaError::RuntimeError(format!( | ||
"Invalid spawn options stdio kind - got '{}', expected one of {}", | ||
s, | ||
ProcessSpawnOptionsStdioKind::all() | ||
.iter() | ||
.map(|k| format!("'{k}'")) | ||
.join(", ") | ||
))) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
impl<'lua> FromLua<'lua> for ProcessSpawnOptionsStdioKind { | ||
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { | ||
match value { | ||
LuaValue::Nil => Ok(Self::default()), | ||
LuaValue::String(s) => s.to_str()?.parse(), | ||
_ => Err(LuaError::FromLuaConversionError { | ||
from: value.type_name(), | ||
to: "ProcessSpawnOptionsStdioKind", | ||
message: Some(format!( | ||
"Invalid spawn options stdio kind - expected string, got {}", | ||
value.type_name() | ||
)), | ||
}), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use mlua::prelude::*; | ||
|
||
use super::kind::ProcessSpawnOptionsStdioKind; | ||
|
||
#[derive(Debug, Clone, Default)] | ||
pub struct ProcessSpawnOptionsStdio { | ||
pub stdout: ProcessSpawnOptionsStdioKind, | ||
pub stderr: ProcessSpawnOptionsStdioKind, | ||
pub stdin: Option<Vec<u8>>, | ||
} | ||
|
||
impl From<ProcessSpawnOptionsStdioKind> for ProcessSpawnOptionsStdio { | ||
fn from(value: ProcessSpawnOptionsStdioKind) -> Self { | ||
Self { | ||
stdout: value, | ||
stderr: value, | ||
..Default::default() | ||
} | ||
} | ||
} | ||
|
||
impl<'lua> FromLua<'lua> for ProcessSpawnOptionsStdio { | ||
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> { | ||
match value { | ||
LuaValue::Nil => Ok(Self::default()), | ||
LuaValue::String(s) => { | ||
Ok(ProcessSpawnOptionsStdioKind::from_lua(LuaValue::String(s), lua)?.into()) | ||
} | ||
LuaValue::Table(t) => { | ||
let mut this = Self::default(); | ||
|
||
if let Some(stdin) = t.get("stdin")? { | ||
this.stdin = stdin; | ||
} | ||
|
||
if let Some(stdout) = t.get("stdout")? { | ||
this.stdout = stdout; | ||
} | ||
|
||
if let Some(stderr) = t.get("stderr")? { | ||
this.stderr = stderr; | ||
} | ||
|
||
Ok(this) | ||
} | ||
_ => Err(LuaError::FromLuaConversionError { | ||
from: value.type_name(), | ||
to: "ProcessSpawnOptionsStdio", | ||
message: Some(format!( | ||
"Invalid spawn options stdio - expected string or table, got {}", | ||
value.type_name() | ||
)), | ||
}), | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.