use super::ClipboardError;
use crate::input::{DataFormat, IAsyncDataTransferItem, LocalBoxFuture};
use std::any::Any;
use std::cell::RefCell;
use std::rc::Rc;
pub trait PlatformAsyncDataTransferItemImpl {
fn provide_formats(&self) -> Result<Vec<DataFormat>, ClipboardError>;
fn try_get_raw_core_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>>;
}
pub struct PlatformAsyncDataTransferItem {
formats: RefCell<Option<Rc<[DataFormat]>>>,
platform_impl: Box<dyn PlatformAsyncDataTransferItemImpl>,
}
impl PlatformAsyncDataTransferItem {
pub fn new(platform_impl: impl PlatformAsyncDataTransferItemImpl + 'static) -> Rc<PlatformAsyncDataTransferItem> {
Rc::new(PlatformAsyncDataTransferItem { formats: RefCell::new(None), platform_impl: Box::new(platform_impl) })
}
#[track_caller]
pub fn formats(&self) -> Rc<[DataFormat]> {
match self.try_formats() {
Ok(formats) => formats,
Err(error) => panic!("{error}"),
}
}
pub fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
if let Some(formats) = self.formats.borrow().as_ref() {
return Ok(formats.clone());
}
let formats: Rc<[DataFormat]> = Rc::from(self.platform_impl.provide_formats()?);
*self.formats.borrow_mut() = Some(formats.clone());
Ok(formats)
}
#[track_caller]
pub fn contains(&self, format: &DataFormat) -> bool {
self.formats().iter().any(|candidate| candidate == format)
}
pub fn try_get_raw_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>> {
match self.try_formats() {
Ok(formats) if formats.iter().any(|candidate| candidate == format) => {
self.platform_impl.try_get_raw_core_async(format)
}
Ok(_) => Box::pin(std::future::ready(Ok(None))),
Err(error) => Box::pin(std::future::ready(Err(error))),
}
}
}
impl IAsyncDataTransferItem for PlatformAsyncDataTransferItem {
fn formats(&self) -> Rc<[DataFormat]> {
PlatformAsyncDataTransferItem::formats(self)
}
fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
PlatformAsyncDataTransferItem::try_formats(self)
}
fn try_get_raw_async(&self, format: &DataFormat) -> LocalBoxFuture<Result<Option<Rc<dyn Any>>, ClipboardError>> {
PlatformAsyncDataTransferItem::try_get_raw_async(self, format)
}
}