use inset_foundation::{App, Task};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClipboardData {
pub text: Option<String>,
}
impl ClipboardData {
pub fn new(text: impl Into<String>) -> ClipboardData {
ClipboardData {
text: Some(text.into()),
}
}
}
pub struct Clipboard;
impl Clipboard {
pub const K_TEXT_PLAIN: &'static str = "text/plain";
pub fn set_data(app: &App, data: ClipboardData) -> Task<()> {
let written = data.text.as_deref().and_then(|text| {
app.platform()
.clipboard()
.map(|clipboard| clipboard.set_text(text))
});
match written {
Some(written) => app.spawn(async move |_cx| written.await),
None => Task::ready(()),
}
}
pub fn get_data(app: &App, format: &str) -> Task<Option<ClipboardData>> {
let text = app
.platform()
.clipboard()
.filter(|_| format == Self::K_TEXT_PLAIN)
.map(|clipboard| clipboard.text());
match text {
Some(text) => app.spawn(async move |_cx| text.await.map(ClipboardData::new)),
None => Task::ready(None),
}
}
pub fn has_strings(app: &App) -> Task<bool> {
let has_strings = app
.platform()
.clipboard()
.map(|clipboard| clipboard.has_strings());
match has_strings {
Some(has_strings) => app.spawn(async move |_cx| has_strings.await),
None => Task::ready(false),
}
}
}
#[cfg(test)]
mod tests {
use std::cell::RefCell;
use std::rc::Rc;
use inset_foundation::AppCell;
use inset_test::{MockClipboard, TestPlatform};
use super::*;
fn app_with(clipboard: &Rc<MockClipboard>) -> Rc<AppCell> {
let clipboard: Rc<dyn inset_embedder::Clipboard> = Rc::clone(clipboard) as _;
AppCell::with_platform(Rc::new(TestPlatform::new().with_clipboard(clipboard)))
}
fn awaited<T: 'static>(cell: &Rc<AppCell>, task: Task<T>) -> Option<T> {
let answer = Rc::new(RefCell::new(None));
let out = Rc::clone(&answer);
cell.borrow()
.spawn(async move |_cx| *out.borrow_mut() = Some(task.await));
cell.checkpoint();
answer.take()
}
#[test]
fn get_data_returns_text() {
let mock_clipboard = Rc::new(MockClipboard::new());
let cell = app_with(&mock_clipboard);
mock_clipboard.set_clipboard_data(Some("Hello world".to_owned()));
let data = Clipboard::get_data(&cell.borrow(), Clipboard::K_TEXT_PLAIN);
let data = awaited(&cell, data).expect("the read completed");
assert_eq!(data, Some(ClipboardData::new("Hello world")));
}
#[test]
fn get_data_returns_none() {
let mock_clipboard = Rc::new(MockClipboard::new());
let cell = app_with(&mock_clipboard);
mock_clipboard.set_clipboard_data(None);
let data = Clipboard::get_data(&cell.borrow(), Clipboard::K_TEXT_PLAIN);
let data = awaited(&cell, data).expect("the read completed");
assert_eq!(data, None);
}
#[test]
fn set_data_sets_text() {
let mock_clipboard = Rc::new(MockClipboard::new());
let cell = app_with(&mock_clipboard);
let written = Clipboard::set_data(&cell.borrow(), ClipboardData::new("Hello world"));
awaited(&cell, written).expect("the write completed");
assert_eq!(
mock_clipboard.clipboard_data().as_deref(),
Some("Hello world")
);
}
}