Skip to main content

iced_runtime/
clipboard.rs

1//! Access the clipboard.
2use crate::core::clipboard::{Content, Error, Kind};
3use crate::futures::futures::channel::oneshot;
4use crate::task::{self, Task};
5
6use std::path::PathBuf;
7use std::sync::Arc;
8
9/// A clipboard action to be performed by some [`Task`].
10///
11/// [`Task`]: crate::Task
12#[derive(Debug)]
13pub enum Action {
14    /// Read the clipboard and produce `T` with the result.
15    Read {
16        /// The [`Kind`] of [`Content`] to read.
17        kind: Kind,
18        /// The channel to send the read contents.
19        channel: oneshot::Sender<Result<Content, Error>>,
20    },
21
22    /// Write the given contents to the clipboard.
23    Write {
24        /// The [`Content`] to be written.
25        content: Content,
26
27        /// The channel to send the write result.
28        channel: oneshot::Sender<Result<(), Error>>,
29    },
30}
31
32/// Read the given [`Kind`] of [`Content`] from the clipboard.
33pub fn read(kind: Kind) -> Task<Result<Arc<Content>, Error>> {
34    task::oneshot(|channel| crate::Action::Clipboard(Action::Read { kind, channel }))
35        .map(|result| result.map(Arc::new))
36}
37
38/// Read the current text contents of the clipboard.
39pub fn read_text() -> Task<Result<Arc<String>, Error>> {
40    task::oneshot(|channel| {
41        crate::Action::Clipboard(Action::Read {
42            kind: Kind::Text,
43            channel,
44        })
45    })
46    .map(|result| {
47        let Ok(Content::Text(text)) = result else {
48            return Err(Error::ContentNotAvailable);
49        };
50
51        Ok(Arc::new(text))
52    })
53}
54
55/// Read the current HTML contents of the clipboard.
56pub fn read_html() -> Task<Result<Arc<String>, Error>> {
57    task::oneshot(|channel| {
58        crate::Action::Clipboard(Action::Read {
59            kind: Kind::Html,
60            channel,
61        })
62    })
63    .map(|result| {
64        let Ok(Content::Html(html)) = result else {
65            return Err(Error::ContentNotAvailable);
66        };
67
68        Ok(Arc::new(html))
69    })
70}
71
72/// Read the current file paths of the clipboard.
73pub fn read_files() -> Task<Result<Arc<[PathBuf]>, Error>> {
74    task::oneshot(|channel| {
75        crate::Action::Clipboard(Action::Read {
76            kind: Kind::Files,
77            channel,
78        })
79    })
80    .map(|result| {
81        let Ok(Content::Files(files)) = result else {
82            return Err(Error::ContentNotAvailable);
83        };
84
85        Ok(Arc::from(files))
86    })
87}
88
89/// Read the current [`Image`](crate::core::clipboard::Image) of the clipboard.
90#[cfg(feature = "image")]
91pub fn read_image() -> Task<Result<crate::core::clipboard::Image, Error>> {
92    task::oneshot(|channel| {
93        crate::Action::Clipboard(Action::Read {
94            kind: Kind::Image,
95            channel,
96        })
97    })
98    .map(|result| {
99        let Ok(Content::Image(image)) = result else {
100            return Err(Error::ContentNotAvailable);
101        };
102
103        Ok(image)
104    })
105}
106
107/// Write the given [`Content`] to the clipboard.
108pub fn write(content: impl Into<Content>) -> Task<Result<(), Error>> {
109    let content = content.into();
110
111    task::oneshot(|channel| crate::Action::Clipboard(Action::Write { content, channel }))
112}