Skip to content

Commit 9a63fb7

Browse files
committed
Introduce Core trait to reduce PhantomData
1 parent 03c3cbe commit 9a63fb7

File tree

5 files changed

+58
-37
lines changed

5 files changed

+58
-37
lines changed

src/core.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use crate::{Future, Stream};
2+
3+
/// The core trait of a [`Sipper`].
4+
///
5+
/// It is used internally for convenience to avoid phantom data, since it
6+
/// has [`Output`] and [`Progress`] as associated types.
7+
pub trait Core: Future<Output = <Self as Core>::Output> + Stream<Item = Self::Progress> {
8+
/// The output of the [`Sipper`].
9+
type Output;
10+
11+
/// The progress of the [`Sipper`].
12+
type Progress;
13+
}
14+
15+
impl<T> Core for T
16+
where
17+
T: Future + Stream,
18+
{
19+
type Output = <T as Future>::Output;
20+
type Progress = T::Item;
21+
}

src/filter_with.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Future, Sipper, Stream};
1+
use crate::{Core, Future, Stream};
22

33
use pin_project_lite::pin_project;
44

@@ -10,16 +10,16 @@ pin_project! {
1010
/// Maps and filters the progress of a [`Sipper`].
1111
///
1212
/// The result of [`Sipper::filter_with`].
13-
pub struct FilterWith<S, Output, Progress, A,F>
13+
pub struct FilterWith<S, F, A>
1414
{
1515
#[pin]
1616
sipper: S,
1717
mapper: F,
18-
_types: PhantomData<(Output, Progress, A)>,
18+
_types: PhantomData<A>,
1919
}
2020
}
2121

22-
impl<S, Output, Progress, A, F> FilterWith<S, Output, Progress, A, F> {
22+
impl<S, F, A> FilterWith<S, F, A> {
2323
pub(crate) fn new(sipper: S, mapper: F) -> Self {
2424
Self {
2525
sipper,
@@ -29,22 +29,22 @@ impl<S, Output, Progress, A, F> FilterWith<S, Output, Progress, A, F> {
2929
}
3030
}
3131

32-
impl<S, Output, Progress, A, F> Future for FilterWith<S, Output, Progress, A, F>
32+
impl<S, F, A> Future for FilterWith<S, F, A>
3333
where
34-
S: Sipper<Output, Progress>,
34+
S: Core,
3535
{
36-
type Output = Output;
36+
type Output = <S as Core>::Output;
3737

3838
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
3939
let this = self.project();
4040
this.sipper.poll(cx)
4141
}
4242
}
4343

44-
impl<S, Output, Progress, A, F> Stream for FilterWith<S, Output, Progress, A, F>
44+
impl<S, F, A> Stream for FilterWith<S, F, A>
4545
where
46-
S: Sipper<Output, Progress>,
47-
F: FnMut(Progress) -> Option<A>,
46+
S: Core,
47+
F: FnMut(S::Progress) -> Option<A>,
4848
{
4949
type Item = A;
5050

src/lib.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,14 @@
263263
//! [`with`]: Sipper::with
264264
//! [`filter_with`]: Sipper::filter_with
265265
//! [`run`]: Sipper::run
266+
mod core;
266267
mod filter_with;
267268
mod run;
268269
mod sender;
269270
mod straw;
270271
mod with;
271272

273+
pub use core::Core;
272274
pub use filter_with::FilterWith;
273275
pub use run::Run;
274276
pub use sender::Sender;
@@ -287,15 +289,16 @@ pub use futures::never::Never;
287289
#[doc(no_inline)]
288290
pub use futures::{Future, FutureExt, Sink, Stream, StreamExt};
289291

290-
/// A sipper is a [`Future`] that can notify progress.
292+
/// A sipper is both a [`Stream`] that produces a bunch of progress
293+
/// and a [`Future`] that produces some final output.
291294
pub trait Sipper<Output, Progress = Output>:
292-
Future<Output = Output> + Stream<Item = Progress>
295+
core::Core<Output = Output, Progress = Progress>
293296
{
294297
/// Maps the progress of the [`Sipper`] with the given closure.
295298
///
296299
/// This is analogous to `map` in many other types; but we use `with`
297300
/// to avoid naming collisions with [`Future`] and [`Stream`].
298-
fn with<F, A>(self, f: F) -> With<Self, Output, Progress, A, F>
301+
fn with<F, A>(self, f: F) -> With<Self, F, A>
299302
where
300303
Self: Sized,
301304
F: FnMut(Progress) -> A,
@@ -307,7 +310,7 @@ pub trait Sipper<Output, Progress = Output>:
307310
///
308311
/// This is analogous to `filter_map` in many other types; but we use `filter_with`
309312
/// to avoid naming collisions with [`Future`] and [`Stream`].
310-
fn filter_with<F, A>(self, f: F) -> FilterWith<Self, Output, Progress, A, F>
313+
fn filter_with<F, A>(self, f: F) -> FilterWith<Self, F, A>
311314
where
312315
Self: Sized,
313316
F: FnMut(Progress) -> Option<A>,
@@ -328,7 +331,7 @@ pub trait Sipper<Output, Progress = Output>:
328331

329332
/// Runs the [`Sipper`], sending any progress through the given [`Sender`] and returning
330333
/// its output at the end.
331-
fn run<S>(self, on_progress: impl Into<Sender<Progress, S>>) -> Run<Self, S, Output, Progress>
334+
fn run<S>(self, on_progress: impl Into<Sender<Progress, S>>) -> Run<Self, S>
332335
where
333336
Self: Sized,
334337
S: Sink<Progress>,
@@ -348,7 +351,7 @@ pub trait Sipper<Output, Progress = Output>:
348351
}
349352

350353
impl<T, Output, Progress> Sipper<Output, Progress> for T where
351-
T: Future<Output = Output> + Stream<Item = Progress>
354+
T: core::Core<Output = Output, Progress = Progress>
352355
{
353356
}
354357

src/run.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use crate::{Future, Sink, Sipper};
1+
use crate::{Core, Future, Sink};
22

33
use pin_project_lite::pin_project;
44

5-
use std::marker::PhantomData;
65
use std::pin::Pin;
76
use std::task;
87

@@ -11,24 +10,22 @@ pin_project! {
1110
/// its output at the end.
1211
///
1312
/// The result of [`Sipper::run`].
14-
pub struct Run<S, Si, Output, Progress>
13+
pub struct Run<S: Core, Si>
1514
{
1615
#[pin]
1716
sipper: S,
1817
#[pin]
1918
on_progress: Si,
20-
state: State<Progress>,
21-
_types: PhantomData<(Output, Progress)>,
19+
state: State<S::Progress>,
2220
}
2321
}
2422

25-
impl<S, Si, Output, Progress> Run<S, Si, Output, Progress> {
23+
impl<S: Core, Si> Run<S, Si> {
2624
pub(crate) fn new(sipper: S, on_progress: Si) -> Self {
2725
Self {
2826
sipper,
2927
on_progress,
3028
state: State::Read,
31-
_types: PhantomData,
3229
}
3330
}
3431
}
@@ -41,12 +38,12 @@ enum State<T> {
4138
Output,
4239
}
4340

44-
impl<S, Si, Output, Progress> Future for Run<S, Si, Output, Progress>
41+
impl<S, Si> Future for Run<S, Si>
4542
where
46-
S: Sipper<Output, Progress>,
47-
Si: Sink<Progress>,
43+
S: Core,
44+
Si: Sink<S::Progress>,
4845
{
49-
type Output = Output;
46+
type Output = <S as Core>::Output;
5047

5148
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
5249
use futures::ready;

src/with.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Future, Sipper, Stream};
1+
use crate::{Core, Future, Stream};
22

33
use pin_project_lite::pin_project;
44

@@ -10,16 +10,16 @@ pin_project! {
1010
/// Maps the progress of a [`Sipper`].
1111
///
1212
/// The result of [`Sipper::with`].
13-
pub struct With<S, Output, Progress, A, F>
13+
pub struct With<S, F, A>
1414
{
1515
#[pin]
1616
sipper: S,
1717
mapper: F,
18-
_types: PhantomData<(Output, Progress, A)>,
18+
_types: PhantomData<A>,
1919
}
2020
}
2121

22-
impl<S, Output, Progress, A, F> With<S, Output, Progress, A, F> {
22+
impl<S, F, A> With<S, F, A> {
2323
pub(crate) fn new(sipper: S, mapper: F) -> Self {
2424
Self {
2525
sipper,
@@ -29,22 +29,22 @@ impl<S, Output, Progress, A, F> With<S, Output, Progress, A, F> {
2929
}
3030
}
3131

32-
impl<S, Output, Progress, A, F> Future for With<S, Output, Progress, A, F>
32+
impl<S, F, A> Future for With<S, F, A>
3333
where
34-
S: Sipper<Output, Progress>,
34+
S: Core,
3535
{
36-
type Output = Output;
36+
type Output = <S as Core>::Output;
3737

3838
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
3939
let this = self.project();
4040
this.sipper.poll(cx)
4141
}
4242
}
4343

44-
impl<S, Output, Progress, A, F> Stream for With<S, Output, Progress, A, F>
44+
impl<S, F, A> Stream for With<S, F, A>
4545
where
46-
S: Sipper<Output, Progress>,
47-
F: FnMut(Progress) -> A,
46+
S: Core,
47+
F: FnMut(S::Progress) -> A,
4848
{
4949
type Item = A;
5050

0 commit comments

Comments
 (0)