Skip to main content

pryty_rustbrowser/
clipboard.rs

1use dioxus::prelude::*;
2use wasm_bindgen_futures::JsFuture;
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum ClipboardError {
6    WindowUnavailable,
7    ClipboardUnavailable,
8    ReadFailed(String),
9    WriteFailed(String),
10}
11
12impl core::fmt::Display for ClipboardError {
13    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14        match self {
15            ClipboardError::WindowUnavailable => write!(f, "window unavailable"),
16            ClipboardError::ClipboardUnavailable => write!(f, "clipboard unavailable"),
17            ClipboardError::ReadFailed(e) => write!(f, "clipboard read failed: {e}"),
18            ClipboardError::WriteFailed(e) => write!(f, "clipboard write failed: {e}"),
19        }
20    }
21}
22
23pub struct Clipboard;
24
25pub fn use_clipboard() -> Clipboard {
26    Clipboard
27}
28
29impl Clipboard {
30    pub fn write(&self, text: &str) -> Callback<()> {
31        let payload = text.to_owned();
32        Callback::new(move |_| {
33            let payload = payload.clone();
34            spawn(async move {
35                let _ = write_clipboard_text(payload).await;
36            });
37        })
38    }
39
40    pub async fn write_async(&self, text: &str) -> Result<(), ClipboardError> {
41        write_clipboard_text(text.to_owned()).await
42    }
43
44    pub async fn read(&self) -> Result<Option<String>, ClipboardError> {
45        let window = web_sys::window().ok_or(ClipboardError::WindowUnavailable)?;
46        let clipboard = window.navigator().clipboard();
47
48        let value = JsFuture::from(clipboard.read_text())
49            .await
50            .map_err(|e| ClipboardError::ReadFailed(format!("{e:?}")))?;
51
52        Ok(value.as_string())
53    }
54}
55
56async fn write_clipboard_text(text: String) -> Result<(), ClipboardError> {
57    let window = web_sys::window().ok_or(ClipboardError::WindowUnavailable)?;
58    let clipboard = window.navigator().clipboard();
59
60    JsFuture::from(clipboard.write_text(&text))
61        .await
62        .map_err(|e| ClipboardError::WriteFailed(format!("{e:?}")))?;
63
64    Ok(())
65}