Skip to main content

FileDownload

Struct FileDownload 

Source
pub struct FileDownload { /* private fields */ }
Expand description

A file download in progress with true USB streaming.

This struct wraps the low-level ReceiveStream and provides convenient methods for tracking progress. Data is streamed directly from USB as chunks arrive, without buffering the entire file in memory.

§Important

The MTP session is locked while this download is active. You must either consume the entire download or call cancel() before dropping it. Dropping mid-download without cancelling corrupts the USB session.

§Example

use mtp_rs::mtp::MtpDevice;
use mtp_rs::ObjectHandle;
use tokio::io::AsyncWriteExt;

let mut download = storage.download_stream(handle).await?;
println!("Downloading {} bytes...", download.size());

while let Some(chunk) = download.next_chunk().await {
    let bytes = chunk?;
    file.write_all(&bytes).await?;
    println!("Progress: {:.1}%", download.progress() * 100.0);
}

Implementations§

Source§

impl FileDownload

Source

pub fn size(&self) -> u64

Total file size in bytes.

Source

pub fn bytes_received(&self) -> u64

Bytes received so far.

Source

pub fn progress(&self) -> f64

Progress as a fraction (0.0 to 1.0).

Source

pub async fn cancel(&mut self, idle_timeout: Duration) -> Result<(), Error>

Cancel the in-progress download.

Uses the USB Still Image Class cancel mechanism to stop the transfer and drain remaining data, leaving the session clean for the next operation.

The idle_timeout controls how long to wait during pipe drain before assuming the pipe is clear. 1–2 seconds is typically sufficient.

If the download is already complete, this is a no-op.

Source

pub async fn next_chunk(&mut self) -> Option<Result<Bytes, Error>>

Get the next chunk of data from USB.

Returns None when the download is complete.

Source

pub async fn collect_with_progress<F>( self, on_progress: F, ) -> Result<Vec<u8>, Error>
where F: FnMut(Progress) -> ControlFlow<()>,

Consume the download and iterate with a progress callback.

Calls on_progress after each chunk. Return ControlFlow::Break(()) to cancel the download.

§Example
use mtp_rs::mtp::MtpDevice;
use mtp_rs::ObjectHandle;
use std::ops::ControlFlow;

let download = storage.download_stream(handle).await?;
let data = download.collect_with_progress(|progress| {
    println!("{:.1}%", progress.percent());
    ControlFlow::Continue(())
}).await?;
Source

pub async fn collect(self) -> Result<Vec<u8>, Error>

Collect all remaining data into a Vec<u8>.

This consumes the download and buffers all data in memory.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.