pub struct ByteStream(/* private fields */);
Expand description
Stream of binary data
ByteStream
wraps a stream of binary data for ease of use.
§Getting data out of a ByteStream
ByteStream
provides two primary mechanisms for accessing the data:
-
With
.collect()
:.collect()
reads the complete ByteStream into memory and stores it inAggregatedBytes
, a non-contiguous ByteBuffer.use aws_smithy_http::byte_stream::{ByteStream, AggregatedBytes}; use aws_smithy_http::body::SdkBody; use bytes::Buf; async fn example() { let stream = ByteStream::new(SdkBody::from("hello! This is some data")); // Load data from the stream into memory: let data = stream.collect().await.expect("error reading data"); // collect returns a `bytes::Buf`: println!("first chunk: {:?}", data.chunk()); }
-
Via
impl Stream
:Note: An import of
StreamExt
is required to usetry_next()
.For use-cases where holding the entire ByteStream in memory is unnecessary, use the
Stream
implementation:use aws_smithy_http::byte_stream::{ByteStream, AggregatedBytes, Error}; use aws_smithy_http::body::SdkBody; use tokio_stream::StreamExt; async fn example() -> Result<(), Error> { let mut stream = ByteStream::from(vec![1, 2, 3, 4, 5, 99]); let mut digest = crc32::Digest::new(); while let Some(bytes) = stream.try_next().await? { digest.write(&bytes); } println!("digest: {}", digest.finish()); Ok(()) }
§Getting data into a ByteStream
ByteStreams can be created in one of three ways:
-
From in-memory binary data: ByteStreams created from in-memory data are always retryable. Data will be converted into
Bytes
enabling a cheap clone during retries.use bytes::Bytes; use aws_smithy_http::byte_stream::ByteStream; let stream = ByteStream::from(vec![1,2,3]); let stream = ByteStream::from(Bytes::from_static(b"hello!"));
-
From a file: ByteStreams created from a path can be retried. A new file descriptor will be opened if a retry occurs.
#[cfg(feature = "tokio-rt")] use aws_smithy_http::byte_stream::ByteStream; let stream = ByteStream::from_path("big_file.csv");
-
From an
SdkBody
directly: For more advanced / custom use cases, a ByteStream can be created directly from an SdkBody. When created from an SdkBody, care must be taken to ensure retriability. An SdkBody is retryable when constructed from in-memory data or when usingSdkBody::retryable
.use aws_smithy_http::byte_stream::ByteStream; use aws_smithy_http::body::SdkBody; use bytes::Bytes; let (mut tx, channel_body) = hyper::Body::channel(); // this will not be retryable because the SDK has no way to replay this stream let stream = ByteStream::new(SdkBody::from(channel_body)); tx.send_data(Bytes::from_static(b"hello world!")); tx.send_data(Bytes::from_static(b"hello again!")); // NOTE! You must ensure that `tx` is dropped to ensure that EOF is sent
Implementations§
Source§impl ByteStream
impl ByteStream
pub fn new(body: SdkBody) -> ByteStream
pub fn from_static(bytes: &'static [u8]) -> ByteStream
Sourcepub fn into_inner(self) -> SdkBody
pub fn into_inner(self) -> SdkBody
Consumes the ByteStream, returning the wrapped SdkBody
Sourcepub async fn collect(self) -> Result<AggregatedBytes, Error>
pub async fn collect(self) -> Result<AggregatedBytes, Error>
Read all the data from this ByteStream
into memory
If an error in the underlying stream is encountered, ByteStreamError
is returned.
Data is read into an AggregatedBytes
that stores data non-contiguously as it was received
over the network. If a contiguous slice is required, use into_bytes()
.
use bytes::Bytes;
use aws_smithy_http::body;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::byte_stream::{ByteStream, Error};
async fn get_data() {
let stream = ByteStream::new(SdkBody::from("hello!"));
let data: Result<Bytes, Error> = stream.collect().await.map(|data| data.into_bytes());
}
Sourcepub async fn from_path(path: impl AsRef<Path>) -> Result<ByteStream, Error>
pub async fn from_path(path: impl AsRef<Path>) -> Result<ByteStream, Error>
Create a ByteStream that streams data from the filesystem
This function creates a retryable ByteStream for a given path
. The returned ByteStream
will provide a size hint when used as an HTTP body. If the request fails, the read will
begin again by reloading the file handle.
§Warning
The contents of the file MUST not change during retries. The length & checksum of the file will be cached. If the contents of the file change, the operation will almost certainly fail.
Furthermore, a partial write MAY seek in the file and resume from the previous location.
§Examples
use aws_smithy_http::byte_stream::ByteStream;
use std::path::Path;
async fn make_bytestream() -> ByteStream {
ByteStream::from_path("docs/rows.csv").await.expect("file should be readable")
}
Sourcepub async fn from_file(file: File) -> Result<ByteStream, Error>
pub async fn from_file(file: File) -> Result<ByteStream, Error>
Create a ByteStream from a file
NOTE: This will NOT result in a retryable ByteStream. For a ByteStream that can be retried in the case of
upstream failures, use ByteStream::from_path
Trait Implementations§
Source§impl Debug for ByteStream
impl Debug for ByteStream
Source§impl Default for ByteStream
impl Default for ByteStream
Source§fn default() -> ByteStream
fn default() -> ByteStream
Source§impl From<Bytes> for ByteStream
Construct a retryable ByteStream from bytes::Bytes
impl From<Bytes> for ByteStream
Construct a retryable ByteStream from bytes::Bytes
Source§fn from(input: Bytes) -> ByteStream
fn from(input: Bytes) -> ByteStream
Source§impl From<SdkBody> for ByteStream
impl From<SdkBody> for ByteStream
Source§fn from(inp: SdkBody) -> ByteStream
fn from(inp: SdkBody) -> ByteStream
Source§impl From<Vec<u8>> for ByteStream
Construct a retryable ByteStream from a Vec<u8>
.
impl From<Vec<u8>> for ByteStream
Construct a retryable ByteStream from a Vec<u8>
.
This will convert the Vec<u8>
into bytes::Bytes
to enable efficient
retries.
Source§impl Stream for ByteStream
impl Stream for ByteStream
Source§fn poll_next(
self: Pin<&mut ByteStream>,
cx: &mut Context<'_>,
) -> Poll<Option<<ByteStream as Stream>::Item>>
fn poll_next( self: Pin<&mut ByteStream>, cx: &mut Context<'_>, ) -> Poll<Option<<ByteStream as Stream>::Item>>
None
if the stream is exhausted. Read moreimpl<'pin> Unpin for ByteStreamwhere
<PinnedFieldsOfHelperStruct<__ByteStream<'pin>> as PinnedFieldsOfHelperTrait>::Actual: Unpin,
Auto Trait Implementations§
impl !Freeze for ByteStream
impl !RefUnwindSafe for ByteStream
impl Send for ByteStream
impl Sync for ByteStream
impl !UnwindSafe for ByteStream
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> StreamExt for T
impl<T> StreamExt for T
Source§fn next(&mut self) -> Next<'_, Self>where
Self: Unpin,
fn next(&mut self) -> Next<'_, Self>where
Self: Unpin,
Source§fn into_future(self) -> StreamFuture<Self>
fn into_future(self) -> StreamFuture<Self>
Source§fn map<T, F>(self, f: F) -> Map<Self, F>
fn map<T, F>(self, f: F) -> Map<Self, F>
Source§fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
Source§fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
Source§fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
Source§fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
Source§fn collect<C>(self) -> Collect<Self, C>
fn collect<C>(self) -> Collect<Self, C>
Source§fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
Source§fn concat(self) -> Concat<Self>
fn concat(self) -> Concat<Self>
Source§fn count(self) -> Count<Self>where
Self: Sized,
fn count(self) -> Count<Self>where
Self: Sized,
Source§fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
Source§fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
true
if any element in stream satisfied a predicate. Read moreSource§fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
true
if all element in stream satisfied a predicate. Read moreSource§fn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
Source§fn flatten_unordered(
self,
limit: impl Into<Option<usize>>,
) -> FlattenUnorderedWithFlowController<Self, ()>
fn flatten_unordered( self, limit: impl Into<Option<usize>>, ) -> FlattenUnorderedWithFlowController<Self, ()>
Source§fn flat_map_unordered<U, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> FlatMapUnordered<Self, U, F>
fn flat_map_unordered<U, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> FlatMapUnordered<Self, U, F>
StreamExt::map
but flattens nested Stream
s
and polls them concurrently, yielding items in any order, as they made
available. Read moreSource§fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
StreamExt::fold
that holds internal state
and produces a new stream. Read moreSource§fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
true
. Read moreSource§fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
true
. Read moreSource§fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
Source§fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
Source§fn for_each_concurrent<Fut, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> ForEachConcurrent<Self, Fut, F>
fn for_each_concurrent<Fut, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> ForEachConcurrent<Self, Fut, F>
Source§fn take(self, n: usize) -> Take<Self>where
Self: Sized,
fn take(self, n: usize) -> Take<Self>where
Self: Sized,
n
items of the underlying stream. Read moreSource§fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
n
items of the underlying stream. Read moreSource§fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
Source§fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
Source§fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>where
Self: Sized + 'a,
fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>where
Self: Sized + 'a,
Source§fn buffered(self, n: usize) -> Buffered<Self>
fn buffered(self, n: usize) -> Buffered<Self>
Source§fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
Source§fn zip<St>(self, other: St) -> Zip<Self, St>
fn zip<St>(self, other: St) -> Zip<Self, St>
Source§fn peekable(self) -> Peekable<Self>where
Self: Sized,
fn peekable(self) -> Peekable<Self>where
Self: Sized,
peek
method. Read moreSource§fn chunks(self, capacity: usize) -> Chunks<Self>where
Self: Sized,
fn chunks(self, capacity: usize) -> Chunks<Self>where
Self: Sized,
Source§fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>where
Self: Sized,
fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>where
Self: Sized,
Source§fn inspect<F>(self, f: F) -> Inspect<Self, F>
fn inspect<F>(self, f: F) -> Inspect<Self, F>
Source§fn left_stream<B>(self) -> Either<Self, B>
fn left_stream<B>(self) -> Either<Self, B>
Source§fn right_stream<B>(self) -> Either<B, Self>
fn right_stream<B>(self) -> Either<B, Self>
Source§fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>where
Self: Unpin,
fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>where
Self: Unpin,
Stream::poll_next
on Unpin
stream types.Source§fn select_next_some(&mut self) -> SelectNextSome<'_, Self>where
Self: Unpin + FusedStream,
fn select_next_some(&mut self) -> SelectNextSome<'_, Self>where
Self: Unpin + FusedStream,
Source§impl<S> TryStreamExt for S
impl<S> TryStreamExt for S
Source§fn err_into<E>(self) -> ErrInto<Self, E>
fn err_into<E>(self) -> ErrInto<Self, E>
Source§fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
Source§fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
Source§fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
f
. Read moreSource§fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
f
. Read moreSource§fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
Source§fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
Source§fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
Source§fn try_next(&mut self) -> TryNext<'_, Self>where
Self: Unpin,
fn try_next(&mut self) -> TryNext<'_, Self>where
Self: Unpin,
Source§fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
Source§fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
true
. Read moreSource§fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
true
. Read moreSource§fn try_for_each_concurrent<Fut, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> TryForEachConcurrent<Self, Fut, F>
fn try_for_each_concurrent<Fut, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> TryForEachConcurrent<Self, Fut, F>
Source§fn try_collect<C>(self) -> TryCollect<Self, C>
fn try_collect<C>(self) -> TryCollect<Self, C>
Source§fn try_chunks(self, capacity: usize) -> TryChunks<Self>where
Self: Sized,
fn try_chunks(self, capacity: usize) -> TryChunks<Self>where
Self: Sized,
Source§fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>where
Self: Sized,
fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>where
Self: Sized,
Source§fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
Source§fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
Source§fn try_flatten_unordered(
self,
limit: impl Into<Option<usize>>,
) -> TryFlattenUnordered<Self>
fn try_flatten_unordered( self, limit: impl Into<Option<usize>>, ) -> TryFlattenUnordered<Self>
Source§fn try_flatten(self) -> TryFlatten<Self>
fn try_flatten(self) -> TryFlatten<Self>
Source§fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
Source§fn try_concat(self) -> TryConcat<Self>
fn try_concat(self) -> TryConcat<Self>
Source§fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
Source§fn try_buffered(self, n: usize) -> TryBuffered<Self>
fn try_buffered(self, n: usize) -> TryBuffered<Self>
Source§fn try_poll_next_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Self::Ok, Self::Error>>>where
Self: Unpin,
fn try_poll_next_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Self::Ok, Self::Error>>>where
Self: Unpin,
TryStream::try_poll_next
on Unpin
stream types.Source§fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
Err
is encountered or if an Ok
item is found
that does not satisfy the predicate. Read more