ferroui_base/input/platform/
platform_async_data_transfer_item.rs1use super::ClipboardError;
2use crate::input::{DataFormat, IAsyncDataTransferItem, LocalBoxFuture};
3use std::any::Any;
4use std::cell::RefCell;
5use std::rc::Rc;
6
7pub trait PlatformAsyncDataTransferItemImpl {
10 fn provide_formats(&self) -> Result<Vec<DataFormat>, ClipboardError>;
13
14 fn try_get_raw_core_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>>;
16}
17
18pub struct PlatformAsyncDataTransferItem {
22 formats: RefCell<Option<Rc<[DataFormat]>>>,
23 platform_impl: Box<dyn PlatformAsyncDataTransferItemImpl>,
24}
25
26impl PlatformAsyncDataTransferItem {
27 pub fn new(platform_impl: impl PlatformAsyncDataTransferItemImpl + 'static) -> Rc<PlatformAsyncDataTransferItem> {
29 Rc::new(PlatformAsyncDataTransferItem { formats: RefCell::new(None), platform_impl: Box::new(platform_impl) })
30 }
31
32 #[track_caller]
39 pub fn formats(&self) -> Rc<[DataFormat]> {
40 match self.try_formats() {
41 Ok(formats) => formats,
42 Err(error) => panic!("{error}"),
43 }
44 }
45
46 pub fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
49 if let Some(formats) = self.formats.borrow().as_ref() {
50 return Ok(formats.clone());
51 }
52
53 let formats: Rc<[DataFormat]> = Rc::from(self.platform_impl.provide_formats()?);
54 *self.formats.borrow_mut() = Some(formats.clone());
55 Ok(formats)
56 }
57
58 #[track_caller]
60 pub fn contains(&self, format: &DataFormat) -> bool {
61 self.formats().iter().any(|candidate| candidate == format)
62 }
63
64 pub fn try_get_raw_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>> {
68 match self.try_formats() {
69 Ok(formats) if formats.iter().any(|candidate| candidate == format) => {
70 self.platform_impl.try_get_raw_core_async(format)
71 }
72 Ok(_) => Box::pin(std::future::ready(Ok(None))),
73 Err(error) => Box::pin(std::future::ready(Err(error))),
74 }
75 }
76}
77
78impl IAsyncDataTransferItem for PlatformAsyncDataTransferItem {
79 fn formats(&self) -> Rc<[DataFormat]> {
80 PlatformAsyncDataTransferItem::formats(self)
81 }
82
83 fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
84 PlatformAsyncDataTransferItem::try_formats(self)
85 }
86
87 fn try_get_raw_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>> {
88 PlatformAsyncDataTransferItem::try_get_raw_async(self, format)
89 }
90}