selectic 0.1.0

Selectic is a Rust library that provides a cross-platform way to retrieve user-selected content from the operating system. Currently, it focuses on obtaining selected text, but it is designed to be extensible to handle other types of selected content like images and files in the future.
Documentation
use crate::{Selection, SelectionError, Selector};
use std::io::Read;
use std::time::Duration;
use wl_clipboard_rs::paste::{get_contents, ClipboardType, MimeType, Seat};
use wl_clipboard_rs::utils::is_primary_selection_supported;
use x11_clipboard::Clipboard;

pub struct LinuxSelector;

impl LinuxSelector {
    pub fn new() -> Self {
        LinuxSelector
    }
}

impl Default for LinuxSelector {
    fn default() -> Self {
        Self::new()
    }
}

impl Selector for LinuxSelector {
    fn get_selection(&self) -> Result<Selection, SelectionError> {
        match std::env::var("XDG_SESSION_TYPE") {
            Ok(session_type) => match session_type.as_str() {
                "x11" => self.get_selection_on_x11(),
                "wayland" => self.get_selection_on_wayland(),
                _ => Err(SelectionError::UnsupportedPlatform),
            },
            Err(_) => Err(SelectionError::UnsupportedPlatform),
        }
    }
}

impl LinuxSelector {
    fn get_selection_on_x11(&self) -> Result<Selection, SelectionError> {
        let clipboard = Clipboard::new().map_err(|_| {
            SelectionError::ClipboardError("Failed to create clipboard".to_string())
        })?;
        let primary = clipboard
            .load(
                clipboard.getter.atoms.primary,
                clipboard.getter.atoms.utf8_string,
                clipboard.getter.atoms.property,
                Duration::from_millis(100),
            )
            .map_err(|_| {
                SelectionError::ClipboardError("Failed to load clipboard data".to_string())
            })?;

        let result = String::from_utf8_lossy(&primary)
            .trim_matches('\u{0}')
            .trim()
            .to_string();

        Ok(Selection::new_text(result))
    }

    fn get_selection_on_wayland(&self) -> Result<Selection, SelectionError> {
        if let Ok(support) = is_primary_selection_supported() {
            if !support {
                return self.get_selection_on_x11();
            }
        } else {
            return self.get_selection_on_x11();
        }

        let (mut pipe, _) = get_contents(ClipboardType::Primary, Seat::Unspecified, MimeType::Text)
            .map_err(|_| {
                SelectionError::ClipboardError("Failed to get contents from Wayland".to_string())
            })?;
        let mut contents = vec![];
        pipe.read_to_end(&mut contents)
            .map_err(|_| SelectionError::ClipboardError("Failed to read contents".to_string()))?;

        let contents = String::from_utf8_lossy(&contents)
            .trim_matches('\u{0}')
            .trim()
            .to_string();

        Ok(Selection::new_text(contents))
    }
}