fast-down-api
A convenient, high-level wrapper around fast-down
that turns the pull/push engine into a few lines of async code: spawn a download,
drain progress events, resume after interruption, and cancel cooperatively.
- Concurrent, resumable downloads powered by the
fast-downengine (work-stealing, range requests). - Two layers of entry points: the fire-and-forget
download/resumewrappers, and the lower-levelplan/plan_resumepair that prefetches the remote and inspects the disk without writing a single byte — so you can preview the outcome and decide before committing. - Event stream: a single channel carries prefetch, disk allocation, per-worker progress, resume, rename, and lifecycle events. Every run ends with exactly one
Event::Terminated(TerminationReason). - Cooperative cancellation: cancelling mid-flight preserves the
.part/.fdfiles so you can resume later. - Configurable: threads, chunk size, write method (
Mmap/Std), proxies, headers, retries, disk pre-allocation, and more viaPartialConfig.
Quick start
use ;
use PathBuf;
use Url;
async
Resuming an interrupted download
resume targets the existing .part file. The url argument is optional: pass
None to re-use the initial URL already recorded in the .fd state file, so you
can resume purely from the .part path. If the download cannot be continued (no
.fd state, no range support, or the remote file changed) it emits
Event::ResumeError and does not silently restart — unlike download, which
auto-resumes when it can and otherwise falls back to a fresh download. With
url = None and no resolvable URL available it reports StateError::NoUrl.
use ;
use Url;
let url = parse?;
let config = default;
let = create_channel;
let token = create_cancellation_token;
resume;
# Ok::
Cancelling cooperatively
use create_cancellation_token;
let token = create_cancellation_token;
token.cancel; // stops fetching, keeps .part / .fd so you can resume later
Two-phase planning (inspect before you commit)
plan and plan_resume do everything download / resume do except touch
the disk: they prefetch the remote metadata, resolve the output path, and probe
the .fd / .part pair left by a previous run. The returned [DownloadPlan]
tells you what starting it would do — [DownloadPlan::resume_outcome] reports
Resumable, Fresh, or Mismatch — and nothing is created until you call one
of its start methods. Dropping the plan abandons the download with no side
effects.
use ;
use Url;
#
# async
plan_resume takes a .part path instead of a URL and hard-refuses a
Mismatch (sending Event::ResumeError + TerminationReason::Failed) rather
than restarting — because the caller asked to continue one specific file, not to
fetch it again. Pass a url to re-fetch the metadata, or None to reuse the URL
recorded in the .fd.
API overview
| Item | Purpose |
|---|---|
download |
Start a download; auto-resume when a valid .fd + .part exist, else fresh. Observe completion by draining the Rx from create_channel until it disconnects. |
resume |
Resume a specific .part file; hard-error (Event::ResumeError) if it can't. Completion is observed the same way, by draining Rx. |
plan |
Prefetch + probe the disk and return a DownloadPlan without writing anything; start it only when ready. |
plan_resume |
Like plan but targets a specific .part; refuses a Mismatch instead of re-downloading. |
DownloadPlan |
A prepared, not-yet-started download. Inspect with resume_outcome, then call start / start_fresh / start_forced_resume. |
create_channel |
Create the (Tx, Rx) event channel. |
create_cancellation_token |
Create a CancellationToken for cooperative cancellation. |
Event |
The event enum delivered over the channel. |
PartialConfig |
Layered, optional configuration for a download. |
StateError |
Errors surfaced via Event::ResumeError. |
How resume works
During a download the engine periodically persists a .fd state file next to
the .part partial file. That state records the byte ranges already written
(downloaded_chunk) and the remote file identity (etag / last_modified /
size). On the next run:
downloadloads the.fd, validates it still matches the remote (size + identity), and — if the.partfile is present — emitsEvent::Resumedand continues from the recorded offset.- If validation fails (remote changed) or there is no
.part, it starts fresh. resumeapplies the same checks but, instead of falling back, reportsEvent::ResumeError.
Cancellation leaves both files in place, so a later resume (or download) can pick up exactly where it stopped.
Every run — whether it completes, is cancelled, stops incomplete, or fails —
ends with exactly one Event::Terminated(TerminationReason) as the last event
on the channel, so draining Rx until Terminated is the reliable way to know
a run has finished.
License
MIT — see LICENSE.