Implement clipboard store for x11 with xclip

This commit is contained in:
Joe Wilm 2016-12-29 17:57:50 -05:00
parent 818a2f6161
commit f1336ee1c7
1 changed files with 71 additions and 3 deletions

View File

@ -10,8 +10,9 @@
use std::io;
use std::process::{Output, Command};
use std::string::FromUtf8Error;
use std::ffi::OsStr;
use super::Load;
use super::{Load, Store};
/// The x11 clipboard
pub struct Clipboard;
@ -87,12 +88,79 @@ impl Load for Clipboard {
}
}
impl Store for Clipboard {
/// Sets the primary clipboard contents
#[inline]
fn store_primary<S>(&mut self, contents: S) -> Result<(), Self::Err>
where S: Into<String>
{
self.store(contents, &["-i", "-selection", "clipboard"])
}
/// Sets the secondary clipboard contents
#[inline]
fn store_selection<S>(&mut self, contents: S) -> Result<(), Self::Err>
where S: Into<String>
{
self.store(contents, &["-i"])
}
}
impl Clipboard {
fn process_xclip_output(output: Output) -> Result<String, Error> {
if output.status.success() {
String::from_utf8(output.stdout).map_err(::std::convert::From::from)
String::from_utf8(output.stdout)
.map_err(::std::convert::From::from)
} else {
String::from_utf8(output.stderr).map_err(::std::convert::From::from)
String::from_utf8(output.stderr)
.map_err(::std::convert::From::from)
}
}
fn store<C, S>(&mut self, contents: C, args: &[S]) -> Result<(), Error>
where C: Into<String>,
S: AsRef<OsStr>,
{
use std::io::Write;
use std::process::{Command, Stdio};
let contents = contents.into();
let mut child = Command::new("xclip")
.args(args)
.stdin(Stdio::piped())
.spawn()?;
if let Some(mut stdin) = child.stdin.as_mut() {
stdin.write_all(contents.as_bytes())?;
}
// Return error if didn't exit cleanly
let exit_status = child.wait()?;
if exit_status.success() {
Ok(())
} else {
Err(Error::Xclip("xclip returned non-zero exit code".into()))
}
}
}
#[cfg(test)]
mod tests {
use super::Clipboard;
use ::{Load, Store};
#[test]
fn clipboard_works() {
let mut clipboard = Clipboard::new().expect("create clipboard");
let arst = "arst";
let oien = "oien";
clipboard.store_primary(arst).expect("store selection");
clipboard.store_selection(oien).expect("store selection");
let selection = clipboard.load_selection().expect("load selection");
let primary = clipboard.load_primary().expect("load selection");
assert_eq!(arst, primary);
assert_eq!(oien, selection);
}
}