Seal FromStream methods with an internal argument (#2894)

This commit is contained in:
Sean McArthur 2020-09-29 07:41:20 -07:00 committed by GitHub
parent dcb11118d2
commit 971ed2c6df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -19,7 +19,7 @@ pin_project! {
{ {
#[pin] #[pin]
stream: T, stream: T,
collection: U::Collection, collection: U::InternalCollection,
} }
} }
@ -42,7 +42,7 @@ where
{ {
pub(super) fn new(stream: T) -> Collect<T, U> { pub(super) fn new(stream: T) -> Collect<T, U> {
let (lower, upper) = stream.size_hint(); let (lower, upper) = stream.size_hint();
let collection = U::initialize(lower, upper); let collection = U::initialize(sealed::Internal, lower, upper);
Collect { stream, collection } Collect { stream, collection }
} }
@ -64,12 +64,12 @@ where
let item = match ready!(me.stream.poll_next(cx)) { let item = match ready!(me.stream.poll_next(cx)) {
Some(item) => item, Some(item) => item,
None => { None => {
return Ready(U::finalize(&mut me.collection)); return Ready(U::finalize(sealed::Internal, &mut me.collection));
} }
}; };
if !U::extend(&mut me.collection, item) { if !U::extend(sealed::Internal, &mut me.collection, item) {
return Ready(U::finalize(&mut me.collection)); return Ready(U::finalize(sealed::Internal, &mut me.collection));
} }
} }
} }
@ -80,32 +80,32 @@ where
impl FromStream<()> for () {} impl FromStream<()> for () {}
impl sealed::FromStreamPriv<()> for () { impl sealed::FromStreamPriv<()> for () {
type Collection = (); type InternalCollection = ();
fn initialize(_lower: usize, _upper: Option<usize>) {} fn initialize(_: sealed::Internal, _lower: usize, _upper: Option<usize>) {}
fn extend(_collection: &mut (), _item: ()) -> bool { fn extend(_: sealed::Internal, _collection: &mut (), _item: ()) -> bool {
true true
} }
fn finalize(_collection: &mut ()) {} fn finalize(_: sealed::Internal, _collection: &mut ()) {}
} }
impl<T: AsRef<str>> FromStream<T> for String {} impl<T: AsRef<str>> FromStream<T> for String {}
impl<T: AsRef<str>> sealed::FromStreamPriv<T> for String { impl<T: AsRef<str>> sealed::FromStreamPriv<T> for String {
type Collection = String; type InternalCollection = String;
fn initialize(_lower: usize, _upper: Option<usize>) -> String { fn initialize(_: sealed::Internal, _lower: usize, _upper: Option<usize>) -> String {
String::new() String::new()
} }
fn extend(collection: &mut String, item: T) -> bool { fn extend(_: sealed::Internal, collection: &mut String, item: T) -> bool {
collection.push_str(item.as_ref()); collection.push_str(item.as_ref());
true true
} }
fn finalize(collection: &mut String) -> String { fn finalize(_: sealed::Internal, collection: &mut String) -> String {
mem::replace(collection, String::new()) mem::replace(collection, String::new())
} }
} }
@ -113,18 +113,18 @@ impl<T: AsRef<str>> sealed::FromStreamPriv<T> for String {
impl<T> FromStream<T> for Vec<T> {} impl<T> FromStream<T> for Vec<T> {}
impl<T> sealed::FromStreamPriv<T> for Vec<T> { impl<T> sealed::FromStreamPriv<T> for Vec<T> {
type Collection = Vec<T>; type InternalCollection = Vec<T>;
fn initialize(lower: usize, _upper: Option<usize>) -> Vec<T> { fn initialize(_: sealed::Internal, lower: usize, _upper: Option<usize>) -> Vec<T> {
Vec::with_capacity(lower) Vec::with_capacity(lower)
} }
fn extend(collection: &mut Vec<T>, item: T) -> bool { fn extend(_: sealed::Internal, collection: &mut Vec<T>, item: T) -> bool {
collection.push(item); collection.push(item);
true true
} }
fn finalize(collection: &mut Vec<T>) -> Vec<T> { fn finalize(_: sealed::Internal, collection: &mut Vec<T>) -> Vec<T> {
mem::replace(collection, vec![]) mem::replace(collection, vec![])
} }
} }
@ -132,18 +132,19 @@ impl<T> sealed::FromStreamPriv<T> for Vec<T> {
impl<T> FromStream<T> for Box<[T]> {} impl<T> FromStream<T> for Box<[T]> {}
impl<T> sealed::FromStreamPriv<T> for Box<[T]> { impl<T> sealed::FromStreamPriv<T> for Box<[T]> {
type Collection = Vec<T>; type InternalCollection = Vec<T>;
fn initialize(lower: usize, upper: Option<usize>) -> Vec<T> { fn initialize(_: sealed::Internal, lower: usize, upper: Option<usize>) -> Vec<T> {
<Vec<T> as sealed::FromStreamPriv<T>>::initialize(lower, upper) <Vec<T> as sealed::FromStreamPriv<T>>::initialize(sealed::Internal, lower, upper)
} }
fn extend(collection: &mut Vec<T>, item: T) -> bool { fn extend(_: sealed::Internal, collection: &mut Vec<T>, item: T) -> bool {
<Vec<T> as sealed::FromStreamPriv<T>>::extend(collection, item) <Vec<T> as sealed::FromStreamPriv<T>>::extend(sealed::Internal, collection, item)
} }
fn finalize(collection: &mut Vec<T>) -> Box<[T]> { fn finalize(_: sealed::Internal, collection: &mut Vec<T>) -> Box<[T]> {
<Vec<T> as sealed::FromStreamPriv<T>>::finalize(collection).into_boxed_slice() <Vec<T> as sealed::FromStreamPriv<T>>::finalize(sealed::Internal, collection)
.into_boxed_slice()
} }
} }
@ -153,18 +154,26 @@ impl<T, U, E> sealed::FromStreamPriv<Result<T, E>> for Result<U, E>
where where
U: FromStream<T>, U: FromStream<T>,
{ {
type Collection = Result<U::Collection, E>; type InternalCollection = Result<U::InternalCollection, E>;
fn initialize(lower: usize, upper: Option<usize>) -> Result<U::Collection, E> { fn initialize(
Ok(U::initialize(lower, upper)) _: sealed::Internal,
lower: usize,
upper: Option<usize>,
) -> Result<U::InternalCollection, E> {
Ok(U::initialize(sealed::Internal, lower, upper))
} }
fn extend(collection: &mut Self::Collection, item: Result<T, E>) -> bool { fn extend(
_: sealed::Internal,
collection: &mut Self::InternalCollection,
item: Result<T, E>,
) -> bool {
assert!(collection.is_ok()); assert!(collection.is_ok());
match item { match item {
Ok(item) => { Ok(item) => {
let collection = collection.as_mut().ok().expect("invalid state"); let collection = collection.as_mut().ok().expect("invalid state");
U::extend(collection, item) U::extend(sealed::Internal, collection, item)
} }
Err(err) => { Err(err) => {
*collection = Err(err); *collection = Err(err);
@ -173,11 +182,11 @@ where
} }
} }
fn finalize(collection: &mut Self::Collection) -> Result<U, E> { fn finalize(_: sealed::Internal, collection: &mut Self::InternalCollection) -> Result<U, E> {
if let Ok(collection) = collection.as_mut() { if let Ok(collection) = collection.as_mut() {
Ok(U::finalize(collection)) Ok(U::finalize(sealed::Internal, collection))
} else { } else {
let res = mem::replace(collection, Ok(U::initialize(0, Some(0)))); let res = mem::replace(collection, Ok(U::initialize(sealed::Internal, 0, Some(0))));
if let Err(err) = res { if let Err(err) = res {
Err(err) Err(err)
@ -191,18 +200,18 @@ where
impl<T: Buf> FromStream<T> for Bytes {} impl<T: Buf> FromStream<T> for Bytes {}
impl<T: Buf> sealed::FromStreamPriv<T> for Bytes { impl<T: Buf> sealed::FromStreamPriv<T> for Bytes {
type Collection = BytesMut; type InternalCollection = BytesMut;
fn initialize(_lower: usize, _upper: Option<usize>) -> BytesMut { fn initialize(_: sealed::Internal, _lower: usize, _upper: Option<usize>) -> BytesMut {
BytesMut::new() BytesMut::new()
} }
fn extend(collection: &mut BytesMut, item: T) -> bool { fn extend(_: sealed::Internal, collection: &mut BytesMut, item: T) -> bool {
collection.put(item); collection.put(item);
true true
} }
fn finalize(collection: &mut BytesMut) -> Bytes { fn finalize(_: sealed::Internal, collection: &mut BytesMut) -> Bytes {
mem::replace(collection, BytesMut::new()).freeze() mem::replace(collection, BytesMut::new()).freeze()
} }
} }
@ -210,18 +219,18 @@ impl<T: Buf> sealed::FromStreamPriv<T> for Bytes {
impl<T: Buf> FromStream<T> for BytesMut {} impl<T: Buf> FromStream<T> for BytesMut {}
impl<T: Buf> sealed::FromStreamPriv<T> for BytesMut { impl<T: Buf> sealed::FromStreamPriv<T> for BytesMut {
type Collection = BytesMut; type InternalCollection = BytesMut;
fn initialize(_lower: usize, _upper: Option<usize>) -> BytesMut { fn initialize(_: sealed::Internal, _lower: usize, _upper: Option<usize>) -> BytesMut {
BytesMut::new() BytesMut::new()
} }
fn extend(collection: &mut BytesMut, item: T) -> bool { fn extend(_: sealed::Internal, collection: &mut BytesMut, item: T) -> bool {
collection.put(item); collection.put(item);
true true
} }
fn finalize(collection: &mut BytesMut) -> BytesMut { fn finalize(_: sealed::Internal, collection: &mut BytesMut) -> BytesMut {
mem::replace(collection, BytesMut::new()) mem::replace(collection, BytesMut::new())
} }
} }
@ -230,17 +239,26 @@ pub(crate) mod sealed {
#[doc(hidden)] #[doc(hidden)]
pub trait FromStreamPriv<T> { pub trait FromStreamPriv<T> {
/// Intermediate type used during collection process /// Intermediate type used during collection process
type Collection; ///
/// The name of this type is internal and cannot be relied upon.
type InternalCollection;
/// Initialize the collection /// Initialize the collection
fn initialize(lower: usize, upper: Option<usize>) -> Self::Collection; fn initialize(
internal: Internal,
lower: usize,
upper: Option<usize>,
) -> Self::InternalCollection;
/// Extend the collection with the received item /// Extend the collection with the received item
/// ///
/// Return `true` to continue streaming, `false` complete collection. /// Return `true` to continue streaming, `false` complete collection.
fn extend(collection: &mut Self::Collection, item: T) -> bool; fn extend(internal: Internal, collection: &mut Self::InternalCollection, item: T) -> bool;
/// Finalize collection into target type. /// Finalize collection into target type.
fn finalize(collection: &mut Self::Collection) -> Self; fn finalize(internal: Internal, collection: &mut Self::InternalCollection) -> Self;
} }
#[allow(missing_debug_implementations)]
pub struct Internal;
} }