pub struct StreamDownload<P: StorageProvider> { /* private fields */ }
Expand description
Represents content streamed from a remote source. This struct implements read and seek so it can be used as a generic source for libraries and applications that operate on these traits. On creation, an async task is spawned that will immediately start to download the remote content.
Any read attempts that request part of the stream that hasn’t been downloaded yet will block until the requested portion is reached. Any seek attempts that meet the same criteria will result in additional request to restart the stream download from the seek point.
If the stream download hasn’t completed when this struct is dropped, the task will be cancelled.
If the stream stalls for any reason, the download task will attempt to automatically reconnect.
This reconnect interval can be controlled via Settings::retry_timeout
.
Server-side failures are not automatically handled and should be retried by the supplied
SourceStream
implementation if desired.
Implementations§
Source§impl<P: StorageProvider> StreamDownload<P>
impl<P: StorageProvider> StreamDownload<P>
Sourcepub async fn new_http(
url: Url,
storage_provider: P,
settings: Settings<HttpStream<Client>>,
) -> Result<Self, StreamInitializationError<HttpStream<Client>>>
Available on crate feature reqwest
only.
pub async fn new_http( url: Url, storage_provider: P, settings: Settings<HttpStream<Client>>, ) -> Result<Self, StreamInitializationError<HttpStream<Client>>>
reqwest
only.Creates a new StreamDownload
that accesses an HTTP resource at the given URL.
§Example
use std::error::Error;
use std::io::{self, Read};
use std::result::Result;
use stream_download::source::DecodeError;
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut reader = match StreamDownload::new_http(
"https://some-cool-url.com/some-file.mp3".parse()?,
TempStorageProvider::default(),
Settings::default(),
)
.await
{
Ok(reader) => reader,
Err(e) => return Err(e.decode_error().await)?,
};
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok::<_, io::Error>(())
})
.await??;
Ok(())
}
Sourcepub async fn new_http_with_middleware(
url: Url,
storage_provider: P,
settings: Settings<HttpStream<ClientWithMiddleware>>,
) -> Result<Self, StreamInitializationError<HttpStream<ClientWithMiddleware>>>
Available on crate feature reqwest-middleware
only.
pub async fn new_http_with_middleware( url: Url, storage_provider: P, settings: Settings<HttpStream<ClientWithMiddleware>>, ) -> Result<Self, StreamInitializationError<HttpStream<ClientWithMiddleware>>>
reqwest-middleware
only.Creates a new StreamDownload
that accesses an HTTP resource at the given URL.
It uses the reqwest_middleware::ClientWithMiddleware
client instead of the default
reqwest
client. Any global middleware set by Settings::add_default_middleware
will
be automatically applied.
§Example
use std::error::Error;
use std::io::{self, Read};
use std::result::Result;
use reqwest_retry::RetryTransientMiddleware;
use reqwest_retry::policies::ExponentialBackoff;
use stream_download::source::DecodeError;
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
Settings::add_default_middleware(RetryTransientMiddleware::new_with_policy(retry_policy));
let mut reader = match StreamDownload::new_http_with_middleware(
"https://some-cool-url.com/some-file.mp3".parse()?,
TempStorageProvider::default(),
Settings::default(),
)
.await
{
Ok(reader) => reader,
Err(e) => return Err(e.decode_error().await)?,
};
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok::<_, io::Error>(())
})
.await??;
Ok(())
}
Sourcepub async fn new_async_read<T>(
params: AsyncReadStreamParams<T>,
storage_provider: P,
settings: Settings<AsyncReadStream<T>>,
) -> Result<Self, StreamInitializationError<AsyncReadStream<T>>>
Available on crate feature async-read
only.
pub async fn new_async_read<T>( params: AsyncReadStreamParams<T>, storage_provider: P, settings: Settings<AsyncReadStream<T>>, ) -> Result<Self, StreamInitializationError<AsyncReadStream<T>>>
async-read
only.Creates a new StreamDownload
that uses an AsyncRead
resource.
§Example reading from stdin
use std::error::Error;
use std::io::{self, Read};
use std::result::Result;
use stream_download::async_read::AsyncReadStreamParams;
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut reader = StreamDownload::new_async_read(
AsyncReadStreamParams::new(tokio::io::stdin()),
TempStorageProvider::new(),
Settings::default(),
)
.await?;
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok::<_, io::Error>(())
})
.await??;
Ok(())
}
Sourcepub async fn new_process(
params: ProcessStreamParams,
storage_provider: P,
settings: Settings<ProcessStream>,
) -> Result<Self, StreamInitializationError<ProcessStream>>
Available on crate feature process
only.
pub async fn new_process( params: ProcessStreamParams, storage_provider: P, settings: Settings<ProcessStream>, ) -> Result<Self, StreamInitializationError<ProcessStream>>
process
only.Creates a new StreamDownload
that uses a Command
as input.
§Example
use std::error::Error;
use std::io::{self, Read};
use std::result::Result;
use stream_download::process::{Command, ProcessStreamParams};
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut reader = StreamDownload::new_process(
ProcessStreamParams::new(Command::new("cat").args(["./assets/music.mp3"]))?,
TempStorageProvider::new(),
Settings::default(),
)
.await?;
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok::<_, io::Error>(())
})
.await??;
Ok(())
}
Sourcepub async fn new<S>(
params: S::Params,
storage_provider: P,
settings: Settings<S>,
) -> Result<Self, StreamInitializationError<S>>
pub async fn new<S>( params: S::Params, storage_provider: P, settings: Settings<S>, ) -> Result<Self, StreamInitializationError<S>>
Creates a new StreamDownload
that accesses a remote resource at the given URL.
§Example
use std::error::Error;
use std::io::{self, Read};
use std::result::Result;
use reqwest::Client;
use stream_download::http::HttpStream;
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
use crate::stream_download::source::DecodeError;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut reader = match StreamDownload::new::<HttpStream<Client>>(
"https://some-cool-url.com/some-file.mp3".parse()?,
TempStorageProvider::default(),
Settings::default(),
)
.await
{
Ok(reader) => reader,
Err(e) => return Err(e.decode_error().await)?,
};
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok::<_, io::Error>(())
})
.await??;
Ok(())
}
Sourcepub async fn from_stream<S>(
stream: S,
storage_provider: P,
settings: Settings<S>,
) -> Result<Self, StreamInitializationError<S>>
pub async fn from_stream<S>( stream: S, storage_provider: P, settings: Settings<S>, ) -> Result<Self, StreamInitializationError<S>>
Creates a new StreamDownload
from a SourceStream
.
§Example
use std::error::Error;
use std::io::Read;
use std::result::Result;
use reqwest::Client;
use stream_download::http::HttpStream;
use stream_download::storage::temp::TempStorageProvider;
use stream_download::{Settings, StreamDownload};
use crate::stream_download::source::DecodeError;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let stream = HttpStream::new(
Client::new(),
"https://some-cool-url.com/some-file.mp3".parse()?,
)
.await?;
let mut reader = match StreamDownload::from_stream(
stream,
TempStorageProvider::default(),
Settings::default(),
)
.await
{
Ok(reader) => reader,
Err(e) => Err(e.decode_error().await)?,
};
Ok(())
}
Sourcepub fn cancel_download(&self)
pub fn cancel_download(&self)
Cancels the background task that’s downloading the stream content. This has no effect if the download is already completed.
Sourcepub fn cancellation_token(&self) -> CancellationToken
pub fn cancellation_token(&self) -> CancellationToken
Returns the CancellationToken
for the download task.
This can be used to cancel the download task before it completes.
Sourcepub fn handle(&self) -> StreamHandle
pub fn handle(&self) -> StreamHandle
Returns a StreamHandle
that can be used to interact with
the stream remotely.
Sourcepub fn content_length(&self) -> Option<u64>
pub fn content_length(&self) -> Option<u64>
Returns the content length of the stream, if available.
Trait Implementations§
Source§impl<P: Debug + StorageProvider> Debug for StreamDownload<P>
impl<P: Debug + StorageProvider> Debug for StreamDownload<P>
Source§impl<P: StorageProvider> Drop for StreamDownload<P>
impl<P: StorageProvider> Drop for StreamDownload<P>
Source§impl<P: StorageProvider> Read for StreamDownload<P>
impl<P: StorageProvider> Read for StreamDownload<P>
Source§fn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
1.36.0 · Source§fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
read
, except that it reads into a slice of buffers. Read moreSource§fn is_read_vectored(&self) -> bool
fn is_read_vectored(&self) -> bool
can_vector
)1.0.0 · Source§fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
buf
. Read more1.0.0 · Source§fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
buf
. Read more1.6.0 · Source§fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
buf
. Read moreSource§fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
read_buf
)Source§fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
read_buf
)cursor
. Read more1.0.0 · Source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
Read
. Read moreSource§impl<P: StorageProvider> Seek for StreamDownload<P>
impl<P: StorageProvider> Seek for StreamDownload<P>
Source§fn seek(&mut self, relative_position: SeekFrom) -> Result<u64>
fn seek(&mut self, relative_position: SeekFrom) -> Result<u64>
1.55.0 · Source§fn rewind(&mut self) -> Result<(), Error>
fn rewind(&mut self) -> Result<(), Error>
Source§fn stream_len(&mut self) -> Result<u64, Error>
fn stream_len(&mut self) -> Result<u64, Error>
seek_stream_len
)