chore: refactor stdout capture

This commit is contained in:
Rowan 2025-01-26 23:08:57 -06:00
parent 8032e5014c
commit 0f207cd701
2 changed files with 39 additions and 13 deletions

3
Cargo.lock generated
View file

@ -635,11 +635,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "wmenu" name = "wmenu-rs"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"gag", "gag",
"pangocairo-sys",
"wmenu-sys", "wmenu-sys",
] ]

View file

@ -20,6 +20,36 @@ fn to_c_char(text: &str) -> *mut c_char {
return CString::new(text).unwrap().into_raw(); return CString::new(text).unwrap().into_raw();
} }
enum Output {
Stdout(String),
Stderr(String),
}
struct OutputCapture {
stdout: BufferRedirect,
stderr: BufferRedirect,
}
impl OutputCapture {
pub fn capture() -> std::io::Result<Self> {
Ok(Self {
stdout: BufferRedirect::stdout()?,
stderr: BufferRedirect::stderr()?,
})
}
pub fn get_output(mut self) -> std::io::Result<Output> {
let mut buf = String::new();
if self.stderr.read_to_string(&mut buf)? > 0 {
Ok(Output::Stderr(buf))
} else {
self.stdout.read_to_string(&mut buf)?;
Ok(Output::Stdout(buf))
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct MenuError { pub struct MenuError {
message: String, message: String,
@ -152,19 +182,15 @@ impl Menu {
} }
pub fn run(&self) -> Result<String, MenuError> { pub fn run(&self) -> Result<String, MenuError> {
let output = OutputCapture::capture().unwrap();
unsafe { unsafe {
let mut stdout = BufferRedirect::stdout().unwrap(); match (bindings::menu_run(self.ctx), output.get_output()) {
match bindings::menu_run(self.ctx) { (0, Ok(Output::Stdout(value))) => Ok(value.trim_end().to_string()),
0 => { (n, Ok(Output::Stdout(value) | Output::Stderr(value))) => {
let mut buf = String::new(); Err(MenuError::new(n, value))
stdout.read_to_string(&mut buf).unwrap();
Ok(buf.trim_end().to_string())
}
n => {
let mut buf = String::new();
stdout.read_to_string(&mut buf).unwrap();
Err(MenuError::new(n, buf))
} }
(n, Err(e)) => Err(MenuError::new(n, e.to_string())),
} }
} }
} }
@ -195,6 +221,7 @@ mod tests {
.add_items(&items); .add_items(&items);
let result = menu.run().expect("couldn't get result"); let result = menu.run().expect("couldn't get result");
println!("{:?}", result.as_bytes());
assert!(items.contains(&result.as_str())); assert!(items.contains(&result.as_str()));
} }
} }