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
StreamExtis required to usetry_next().For use-cases where holding the entire ByteStream in memory is unnecessary, use the
Streamimplementation: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
Bytesenabling 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
SdkBodydirectly: 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 Streams
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