#![crate_name = "arboard"]
#![crate_type = "lib"]
mod common;
pub use common::Error;
#[cfg(feature = "image-data")]
pub use common::ImageData;
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),))]
pub(crate) mod common_linux;
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),))]
pub mod x11_clipboard;
#[cfg(all(
unix,
not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),
feature = "wayland-data-control"
))]
pub mod wayland_data_control_clipboard;
#[cfg(windows)]
pub mod windows_clipboard;
#[cfg(target_os = "macos")]
pub mod osx_clipboard;
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),))]
type PlatformClipboard = common_linux::LinuxClipboard;
#[cfg(windows)]
type PlatformClipboard = windows_clipboard::WindowsClipboardContext;
#[cfg(target_os = "macos")]
type PlatformClipboard = osx_clipboard::OSXClipboardContext;
#[cfg(all(
unix,
not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),
))]
pub use common_linux::{ClipboardExtLinux, LinuxClipboardKind};
pub struct Clipboard {
pub(crate) platform: PlatformClipboard,
}
impl Clipboard {
pub fn new() -> Result<Self, Error> {
Ok(Clipboard { platform: PlatformClipboard::new()? })
}
pub fn get_text(&mut self) -> Result<String, Error> {
self.platform.get_text()
}
pub fn set_text(&mut self, text: String) -> Result<(), Error> {
self.platform.set_text(text)
}
#[cfg(feature = "image-data")]
pub fn get_image(&mut self) -> Result<ImageData<'static>, Error> {
self.platform.get_image()
}
#[cfg(feature = "image-data")]
pub fn set_image(&mut self, image: ImageData) -> Result<(), Error> {
self.platform.set_image(image)
}
}
#[cfg(test)]
#[test]
fn all_tests() {
let _ = env_logger::builder().is_test(true).try_init();
{
let mut ctx = Clipboard::new().unwrap();
let text = "some string";
ctx.set_text(text.to_owned()).unwrap();
assert_eq!(ctx.get_text().unwrap(), text);
drop(ctx);
use std::time::Duration;
std::thread::sleep(Duration::from_millis(100));
let mut ctx = Clipboard::new().unwrap();
assert_eq!(ctx.get_text().unwrap(), text);
}
{
let mut ctx = Clipboard::new().unwrap();
let text = "Some utf8: 🤓 ∑φ(n)<ε 🐔";
ctx.set_text(text.to_owned()).unwrap();
assert_eq!(ctx.get_text().unwrap(), text);
}
#[cfg(feature = "image-data")]
{
let mut ctx = Clipboard::new().unwrap();
#[rustfmt::skip]
let bytes = [
255, 100, 100, 255,
100, 255, 100, 100,
100, 100, 255, 100,
0, 0, 0, 255,
];
let img_data = ImageData { width: 2, height: 2, bytes: bytes.as_ref().into() };
ctx.set_image(img_data.clone()).unwrap();
assert!(matches!(ctx.get_text(), Err(Error::ContentNotAvailable)));
ctx.set_text("clipboard test".into()).unwrap();
assert!(matches!(ctx.get_image(), Err(Error::ContentNotAvailable)));
ctx.set_image(img_data.clone()).unwrap();
let got = ctx.get_image().unwrap();
assert_eq!(img_data.bytes, got.bytes);
#[rustfmt::skip]
let big_bytes = vec![
255, 100, 100, 255,
100, 255, 100, 100,
100, 100, 255, 100,
0, 1, 2, 255,
0, 1, 2, 255,
0, 1, 2, 255,
];
let bytes_cloned = big_bytes.clone();
let big_img_data = ImageData { width: 3, height: 2, bytes: big_bytes.into() };
ctx.set_image(big_img_data).unwrap();
let got = ctx.get_image().unwrap();
assert_eq!(bytes_cloned.as_slice(), got.bytes.as_ref());
}
#[cfg(all(
unix,
not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),
))]
{
use crate::{ClipboardExtLinux, LinuxClipboardKind};
let mut ctx = Clipboard::new().unwrap();
const TEXT1: &str = "I'm a little teapot,";
const TEXT2: &str = "short and stout,";
const TEXT3: &str = "here is my handle";
ctx.set_text_with_clipboard(TEXT1.to_string(), LinuxClipboardKind::Clipboard).unwrap();
ctx.set_text_with_clipboard(TEXT2.to_string(), LinuxClipboardKind::Primary).unwrap();
if !cfg!(feature = "wayland-data-control") || std::env::var_os("WAYLAND_DISPLAY").is_none()
{
ctx.set_text_with_clipboard(TEXT3.to_string(), LinuxClipboardKind::Secondary).unwrap();
}
assert_eq!(TEXT1, &ctx.get_text_with_clipboard(LinuxClipboardKind::Clipboard).unwrap());
assert_eq!(TEXT2, &ctx.get_text_with_clipboard(LinuxClipboardKind::Primary).unwrap());
if !cfg!(feature = "wayland-data-control") || std::env::var_os("WAYLAND_DISPLAY").is_none()
{
assert_eq!(TEXT3, &ctx.get_text_with_clipboard(LinuxClipboardKind::Secondary).unwrap());
}
}
}