use iroh_docs::{DocTicket, NamespaceId, api::protocol::AddrInfoOptions};
use crate::error::Result;
use super::SyncwebFolder;
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
pub struct ShareOptions {
pub writable: bool,
pub pin: bool,
pub persist: bool,
pub addr_info: AddrInfoOptions,
}
impl ShareOptions {
#[must_use]
pub const fn new(writable: bool) -> Self {
Self {
writable,
pin: false,
persist: false,
addr_info: AddrInfoOptions::RelayAndAddresses,
}
}
#[must_use]
pub const fn with_pin(mut self, pin: bool) -> Self {
self.pin = pin;
self
}
#[must_use]
pub const fn with_persist(mut self, persist: bool) -> Self {
self.persist = persist;
self
}
#[must_use]
pub const fn with_addr_info(mut self, addr_info: AddrInfoOptions) -> Self {
self.addr_info = addr_info;
self
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ShareResult {
pub namespace: NamespaceId,
pub writable: bool,
pub ticket: DocTicket,
pub url: String,
pub pinned: usize,
}
impl ShareResult {
#[must_use]
pub const fn access(&self) -> &'static str {
if self.writable { "write" } else { "read" }
}
}
pub async fn share_folder<F>(folder: &SyncwebFolder, options: ShareOptions, persist: F) -> Result<ShareResult>
where
F: FnOnce(NamespaceId, &str, &DocTicket) -> Result<()>,
{
let pinned = if options.pin {
folder.pin_all_content().await?
} else {
0
};
let ticket = folder.ticket_with_options(options.writable, options.addr_info).await?;
let result = ShareResult {
namespace: folder.namespace_id(),
writable: options.writable,
ticket,
url: String::new(),
pinned,
};
if options.persist {
persist(result.namespace, result.access(), &result.ticket)?;
}
let url = crate::uri::folder_url(result.namespace, &result.ticket);
Ok(ShareResult { url, ..result })
}