mod bookmark;
use std::sync::Arc;
use crate::api::{PickOptions, SaveOptions};
use crate::error::{AccessError, PickerError};
use crate::future::{deliver, new_pick_future};
use crate::token::{
FileAccessToken, PermissionStatus, ReadSeek, TokenInner, WriteSeek,
};
pub(crate) async fn pick_open_single(
options: PickOptions,
) -> Result<Option<FileAccessToken>, PickerError> {
let urls = present_picker(&options, false).await?;
match urls.into_iter().next() {
None => Ok(None),
Some(url) => {
let token = bookmark::token_from_url(&url)?;
Ok(Some(token))
}
}
}
pub(crate) async fn pick_open_multi(
options: PickOptions,
) -> Result<Vec<FileAccessToken>, PickerError> {
let urls = present_picker(&options, true).await?;
urls.iter()
.map(|url| bookmark::token_from_url(url))
.collect()
}
pub(crate) async fn pick_save(
options: SaveOptions,
) -> Result<Option<FileAccessToken>, PickerError> {
let url = present_save_picker(&options).await?;
match url {
None => Ok(None),
Some(u) => {
let token = bookmark::token_from_url(&u)?;
Ok(Some(token))
}
}
}
pub(crate) fn open_read(inner: &TokenInner) -> Result<Box<dyn ReadSeek>, AccessError> {
match inner {
TokenInner::Ios { bookmark, .. } => bookmark::open_read_bookmark(bookmark),
_ => Err(AccessError::Platform {
message: "non-iOS token on iOS platform".into(),
}),
}
}
pub(crate) fn open_write(inner: &TokenInner) -> Result<Box<dyn WriteSeek>, AccessError> {
match inner {
TokenInner::Ios { bookmark, .. } => bookmark::open_write_bookmark(bookmark),
_ => Err(AccessError::Platform {
message: "non-iOS token on iOS platform".into(),
}),
}
}
pub(crate) fn check_permission(inner: &TokenInner) -> PermissionStatus {
match inner {
TokenInner::Ios { bookmark, .. } => bookmark::check_bookmark(bookmark),
_ => PermissionStatus::Unknown,
}
}
async fn present_picker(
_options: &PickOptions,
_allow_multiple: bool,
) -> Result<Vec<String>, PickerError> {
let (future, state) = new_pick_future::<Vec<String>>();
let state_clone = Arc::clone(&state);
deliver(&state_clone, vec![]);
Ok(future.await)
}
async fn present_save_picker(
_options: &SaveOptions,
) -> Result<Option<String>, PickerError> {
let (future, state) = new_pick_future::<Option<String>>();
let state_clone = Arc::clone(&state);
deliver(&state_clone, None);
Ok(future.await)
}