window_clipboard 0.5.1

A library to obtain clipboard access from a `raw-window-handle`
Documentation
use crate::ClipboardProvider;

use raw_window_handle::{HasDisplayHandle, RawDisplayHandle};
use std::error::Error;

#[cfg(feature = "wayland")]
pub use clipboard_wayland as wayland;
#[cfg(feature = "x11")]
pub use clipboard_x11 as x11;

#[derive(Debug)]
struct LinuxClipboardError;

impl std::fmt::Display for LinuxClipboardError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str("This window server's clipboard feature is not enabled")
    }
}

impl Error for LinuxClipboardError {}

pub unsafe fn connect<W: HasDisplayHandle>(
    window: &W,
) -> Result<Box<dyn ClipboardProvider>, Box<dyn Error>> {
    let clipboard = match window.display_handle()?.as_raw() {
        #[cfg(feature = "wayland")]
        RawDisplayHandle::Wayland(handle) => {
            Box::new(wayland::Clipboard::connect(handle.display.as_ptr())) as _
        }
        #[cfg(feature = "x11")]
        RawDisplayHandle::Xlib(_) | RawDisplayHandle::Xcb(_) => {
            Box::new(x11::Clipboard::connect()?) as _
        }
        _ => Err(LinuxClipboardError)?,
    };

    Ok(clipboard)
}

#[cfg(feature = "wayland")]
impl ClipboardProvider for wayland::Clipboard {
    fn read(&self) -> Result<String, Box<dyn Error>> {
        self.read()
    }

    fn read_primary(&self) -> Option<Result<String, Box<dyn Error>>> {
        Some(self.read_primary())
    }

    fn write(&mut self, contents: String) -> Result<(), Box<dyn Error>> {
        self.write(contents)
    }

    fn write_primary(&mut self, contents: String) -> Option<Result<(), Box<dyn Error>>> {
        Some(self.write_primary(contents))
    }
}

#[cfg(feature = "x11")]
impl ClipboardProvider for x11::Clipboard {
    fn read(&self) -> Result<String, Box<dyn Error>> {
        self.read().map_err(Box::from)
    }

    fn read_primary(&self) -> Option<Result<String, Box<dyn Error>>> {
        Some(self.read_primary().map_err(Box::from))
    }

    fn write(&mut self, contents: String) -> Result<(), Box<dyn Error>> {
        self.write(contents).map_err(Box::from)
    }

    fn write_primary(&mut self, contents: String) -> Option<Result<(), Box<dyn Error>>> {
        Some(self.write_primary(contents).map_err(Box::from))
    }
}