dove
DocumentationRust core API
Rust API

Build on the same core.

dove-core is the no-terminal-I/O Rust library used by the CLI. These signatures reflect the current public source API.

The transfer seam

pub trait Transfer {
    fn share(&self, req: ShareRequest, progress: &dyn Progress) -> Result<Share>;
    fn get(&self, req: GetRequest, progress: &dyn Progress) -> Result<Fetched>;
    fn list(&self) -> Result<Vec<ShareInfo>>;
    fn revoke(&self, id: &str) -> Result<()>;
    fn status(&self) -> Result<BackendStatus>;
}

Resolve the active backend with dove_core::resolve(&Registry). The built-in self-hosted implementation is complete. Discovery exists for future dove-<kind> helpers, but their subprocess wire protocol is not implemented.

Request and response types

pub struct ShareRequest {
    pub path: PathBuf,
    pub expires: Duration,
    pub encrypt: bool,
    pub downloads: Option<u32>,
    pub pin: Option<String>,
    pub from: Option<String>,
    pub message: Option<String>,
}

pub struct Share { pub id: String, pub link: String, pub size: u64, pub expires_at: u64 }
pub struct GetRequest { pub url: String, pub out: Option<PathBuf>, pub pin: Option<String> }
pub struct Fetched { pub path: PathBuf, pub from: Option<String>, pub message: Option<String> }
pub struct ShareInfo { pub id: String, pub filename: Option<String>, pub expires_at: u64 }
pub struct BackendStatus { pub summary: Vec<(String, String)> }

Share from another Rust interface

use dove_core::{config::Registry, progress::Silent};
use dove_core::transfer::ShareRequest;
use std::{path::PathBuf, time::Duration};

let registry = Registry::load()?;
let backend = dove_core::resolve(&registry)?;
let share = backend.share(
    ShareRequest {
        path: PathBuf::from("report.pdf"),
        expires: Duration::from_secs(3 * 86_400),
        encrypt: true,
        downloads: Some(1),
        pin: None,
        from: Some("Ada".into()),
        message: Some("The final report".into()),
    },
    &Silent,
)?;
println!("{}", share.link);

The returned link may contain secret fragment material. Treat it as sensitive output. Do not put it in telemetry or ordinary logs.

Progress without terminal coupling

pub trait Progress {
    fn step(&self, label: &str);
    fn done(&self, label: &str);
    fn field(&self, key: &str, value: &str);
    fn bytes(&self, uploaded: u64, total: u64);
}

Implement this trait for a desktop progress bar, webview event bridge, test recorder, or structured application log. Use Silent when the caller does not need progress.

Provisioning methods

pub struct ProvisionArgs {
    pub bucket: Option<String>,
    pub region: String,
    pub expire_days: u32,
}

pub fn provision_simple(
    args: &ProvisionArgs,
    profile: Option<String>,
    progress: &dyn Progress,
) -> anyhow::Result<SelfHostedConfig>;

pub fn provision_full(
    args: &ProvisionArgs,
    profile: Option<String>,
    existing: Option<SelfHostedConfig>,
    progress: &dyn Progress,
) -> anyhow::Result<SelfHostedConfig>;

Core provisioning assumes the caller has already selected an AWS profile and confirmed the target account. It returns config; the caller owns persistence. Passing the existing full config is what preserves a custom gate URL and reuses its CloudFront distribution.

Version and stability

The crate is currently 0.1.0. Public types are useful integration seams, but semantic stability before 1.0 is not promised. Pin a compatible version, review release diffs, and compile against the exact source revision you deploy.