Files
voidpin/crates/voidpin/src/copy.rs
kjuulh 838cd9d6b1
All checks were successful
continuous-integration/drone/push Build is passing
feat: replace output spawn with native tokio method
2025-08-03 13:03:57 +02:00

95 lines
2.6 KiB
Rust

use std::process::Stdio;
use anyhow::Context;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use crate::state::State;
#[derive(Default)]
pub struct LocalCopier {}
impl LocalCopier {
pub fn new() -> Self {
Self {}
}
pub async fn copy(&self, input: &[u8]) -> anyhow::Result<()> {
// FIXME: hardcode for macos
#[cfg(target_os = "macos")]
let mut copy_process = {
tokio::process::Command::new("pbcopy")
.stdin(Stdio::piped())
.spawn()?
};
#[cfg(target_os = "linux")]
let mut copy_process = {
tokio::process::Command::new("wl-copy")
.stdin(Stdio::piped())
.spawn()?
};
#[cfg(target_os = "windows")]
let mut copy_process = {
todo!("windows not supported yet");
};
if let Some(mut stdin_handle) = copy_process.stdin.take() {
stdin_handle
.write_all(input)
.await
.context("failed to write input to copy process")?;
stdin_handle
.flush()
.await
.context("failed to flush to program")?;
}
let status = copy_process.wait().await?;
tracing::info!("copy process ended with status: {:?}", status);
Ok(())
}
pub async fn paste(&self) -> anyhow::Result<Vec<u8>> {
// FIXME: hardcode for macos
#[cfg(target_os = "macos")]
let paste_process = {
tokio::process::Command::new("pbpaste")
.stdin(Stdio::piped())
.spawn()?
};
#[cfg(target_os = "linux")]
let mut paste_process = {
tokio::process::Command::new("wl-paste")
.stdin(Stdio::piped())
.spawn()?
};
#[cfg(target_os = "windows")]
let mut paste_process = {
todo!("windows not supported yet");
};
let output = paste_process.wait_with_output().await?;
if !output.status.success() {
anyhow::bail!(
"output failed with: {}, {}, exit_code: {}",
std::str::from_utf8(&output.stdout).unwrap_or_default(),
std::str::from_utf8(&output.stderr).unwrap_or_default(),
output.status.code().unwrap_or_default(),
)
}
Ok(output.stdout)
}
}
pub trait LocalCopierState {
fn local_copier(&self) -> LocalCopier;
}
impl LocalCopierState for State {
fn local_copier(&self) -> LocalCopier {
LocalCopier::new()
}
}