Skip to content

Commit 3bf5ac9

Browse files
authored
Merge pull request #2128 from Diggsey/snip
Refactor to reduce the amount of unsafe and duplicated code.
2 parents 32005e3 + 1b44548 commit 3bf5ac9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+2692
-5001
lines changed

futures-util/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ memchr = { version = "2.2", optional = true }
4646
futures_01 = { version = "0.1.25", optional = true, package = "futures" }
4747
tokio-io = { version = "0.1.9", optional = true }
4848
pin-utils = "0.1.0"
49+
pin-project = "0.4.8"
4950

5051
[dev-dependencies]
5152
futures = { path = "../futures", version = "0.3.4", features = ["async-await", "thread-pool"] }

futures-util/src/fns.rs

Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
use core::marker::PhantomData;
2+
use core::fmt::{self, Debug};
3+
4+
pub trait FnOnce1<A> {
5+
type Output;
6+
fn call_once(self, arg: A) -> Self::Output;
7+
}
8+
9+
impl<T, A, R> FnOnce1<A> for T
10+
where
11+
T: FnOnce(A) -> R
12+
{
13+
type Output = R;
14+
fn call_once(self, arg: A) -> R {
15+
self(arg)
16+
}
17+
}
18+
19+
pub trait FnMut1<A>: FnOnce1<A> {
20+
fn call_mut(&mut self, arg: A) -> Self::Output;
21+
}
22+
23+
impl<T, A, R> FnMut1<A> for T
24+
where
25+
T: FnMut(A) -> R
26+
{
27+
fn call_mut(&mut self, arg: A) -> R {
28+
self(arg)
29+
}
30+
}
31+
32+
// Not used, but present for completeness
33+
#[allow(unreachable_pub)]
34+
pub trait Fn1<A>: FnMut1<A> {
35+
fn call(&self, arg: A) -> Self::Output;
36+
}
37+
38+
impl<T, A, R> Fn1<A> for T
39+
where
40+
T: Fn(A) -> R
41+
{
42+
fn call(&self, arg: A) -> R {
43+
self(arg)
44+
}
45+
}
46+
47+
macro_rules! trivial_fn_impls {
48+
($name:ident <$($arg:ident),*> $t:ty = $debug:literal) => {
49+
impl<$($arg),*> Copy for $t {}
50+
impl<$($arg),*> Clone for $t {
51+
fn clone(&self) -> Self { *self }
52+
}
53+
impl<$($arg),*> Debug for $t {
54+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55+
f.write_str($debug)
56+
}
57+
}
58+
impl<$($arg,)* A> FnMut1<A> for $t where Self: FnOnce1<A> {
59+
fn call_mut(&mut self, arg: A) -> Self::Output {
60+
self.call_once(arg)
61+
}
62+
}
63+
impl<$($arg,)* A> Fn1<A> for $t where Self: FnOnce1<A> {
64+
fn call(&self, arg: A) -> Self::Output {
65+
self.call_once(arg)
66+
}
67+
}
68+
pub(crate) fn $name<$($arg),*>() -> $t {
69+
Default::default()
70+
}
71+
}
72+
}
73+
74+
pub struct OkFn<E>(PhantomData<fn(E)>);
75+
76+
impl<E> Default for OkFn<E> {
77+
fn default() -> Self {
78+
OkFn(PhantomData)
79+
}
80+
}
81+
82+
impl<A, E> FnOnce1<A> for OkFn<E> {
83+
type Output = Result<A, E>;
84+
fn call_once(self, arg: A) -> Self::Output {
85+
Ok(arg)
86+
}
87+
}
88+
89+
trivial_fn_impls!(ok_fn <T> OkFn<T> = "Ok");
90+
91+
#[derive(Debug, Copy, Clone, Default)]
92+
pub struct ChainFn<F, G>(F, G);
93+
94+
impl<F, G, A> FnOnce1<A> for ChainFn<F, G>
95+
where
96+
F: FnOnce1<A>,
97+
G: FnOnce1<F::Output>,
98+
{
99+
type Output = G::Output;
100+
fn call_once(self, arg: A) -> Self::Output {
101+
self.1.call_once(self.0.call_once(arg))
102+
}
103+
}
104+
impl<F, G, A> FnMut1<A> for ChainFn<F, G>
105+
where
106+
F: FnMut1<A>,
107+
G: FnMut1<F::Output>,
108+
{
109+
fn call_mut(&mut self, arg: A) -> Self::Output {
110+
self.1.call_mut(self.0.call_mut(arg))
111+
}
112+
}
113+
impl<F, G, A> Fn1<A> for ChainFn<F, G>
114+
where
115+
F: Fn1<A>,
116+
G: Fn1<F::Output>,
117+
{
118+
fn call(&self, arg: A) -> Self::Output {
119+
self.1.call(self.0.call(arg))
120+
}
121+
}
122+
pub(crate) fn chain_fn<F, G>(f: F, g: G) -> ChainFn<F, G> {
123+
ChainFn(f, g)
124+
}
125+
126+
#[derive(Default)]
127+
pub struct MergeResultFn;
128+
129+
impl<T> FnOnce1<Result<T, T>> for MergeResultFn {
130+
type Output = T;
131+
fn call_once(self, arg: Result<T, T>) -> Self::Output {
132+
match arg {
133+
Ok(x) => x,
134+
Err(x) => x,
135+
}
136+
}
137+
}
138+
trivial_fn_impls!(merge_result_fn <> MergeResultFn = "merge_result");
139+
140+
#[derive(Debug, Copy, Clone, Default)]
141+
pub struct InspectFn<F>(F);
142+
143+
impl<F, A> FnOnce1<A> for InspectFn<F>
144+
where
145+
F: for<'a> FnOnce1<&'a A, Output=()>,
146+
{
147+
type Output = A;
148+
fn call_once(self, arg: A) -> Self::Output {
149+
self.0.call_once(&arg);
150+
arg
151+
}
152+
}
153+
impl<F, A> FnMut1<A> for InspectFn<F>
154+
where
155+
F: for<'a> FnMut1<&'a A, Output=()>,
156+
{
157+
fn call_mut(&mut self, arg: A) -> Self::Output {
158+
self.0.call_mut(&arg);
159+
arg
160+
}
161+
}
162+
impl<F, A> Fn1<A> for InspectFn<F>
163+
where
164+
F: for<'a> Fn1<&'a A, Output=()>,
165+
{
166+
fn call(&self, arg: A) -> Self::Output {
167+
self.0.call(&arg);
168+
arg
169+
}
170+
}
171+
pub(crate) fn inspect_fn<F>(f: F) -> InspectFn<F> {
172+
InspectFn(f)
173+
}
174+
175+
#[derive(Debug, Copy, Clone, Default)]
176+
pub struct MapOkFn<F>(F);
177+
178+
impl<F, T, E> FnOnce1<Result<T, E>> for MapOkFn<F>
179+
where
180+
F: FnOnce1<T>,
181+
{
182+
type Output = Result<F::Output, E>;
183+
fn call_once(self, arg: Result<T, E>) -> Self::Output {
184+
arg.map(|x| self.0.call_once(x))
185+
}
186+
}
187+
impl<F, T, E> FnMut1<Result<T, E>> for MapOkFn<F>
188+
where
189+
F: FnMut1<T>,
190+
{
191+
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
192+
arg.map(|x| self.0.call_mut(x))
193+
}
194+
}
195+
impl<F, T, E> Fn1<Result<T, E>> for MapOkFn<F>
196+
where
197+
F: Fn1<T>,
198+
{
199+
fn call(&self, arg: Result<T, E>) -> Self::Output {
200+
arg.map(|x| self.0.call(x))
201+
}
202+
}
203+
pub(crate) fn map_ok_fn<F>(f: F) -> MapOkFn<F> {
204+
MapOkFn(f)
205+
}
206+
207+
#[derive(Debug, Copy, Clone, Default)]
208+
pub struct MapErrFn<F>(F);
209+
210+
impl<F, T, E> FnOnce1<Result<T, E>> for MapErrFn<F>
211+
where
212+
F: FnOnce1<E>,
213+
{
214+
type Output = Result<T, F::Output>;
215+
fn call_once(self, arg: Result<T, E>) -> Self::Output {
216+
arg.map_err(|x| self.0.call_once(x))
217+
}
218+
}
219+
impl<F, T, E> FnMut1<Result<T, E>> for MapErrFn<F>
220+
where
221+
F: FnMut1<E>,
222+
{
223+
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
224+
arg.map_err(|x| self.0.call_mut(x))
225+
}
226+
}
227+
impl<F, T, E> Fn1<Result<T, E>> for MapErrFn<F>
228+
where
229+
F: Fn1<E>,
230+
{
231+
fn call(&self, arg: Result<T, E>) -> Self::Output {
232+
arg.map_err(|x| self.0.call(x))
233+
}
234+
}
235+
pub(crate) fn map_err_fn<F>(f: F) -> MapErrFn<F> {
236+
MapErrFn(f)
237+
}
238+
239+
#[derive(Debug, Copy, Clone)]
240+
pub struct InspectOkFn<F>(F);
241+
242+
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectOkFn<F>
243+
where
244+
F: FnOnce1<&'a T, Output=()>
245+
{
246+
type Output = ();
247+
fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
248+
if let Ok(x) = arg { self.0.call_once(x) }
249+
}
250+
}
251+
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectOkFn<F>
252+
where
253+
F: FnMut1<&'a T, Output=()>,
254+
{
255+
fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
256+
if let Ok(x) = arg { self.0.call_mut(x) }
257+
}
258+
}
259+
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectOkFn<F>
260+
where
261+
F: Fn1<&'a T, Output=()>,
262+
{
263+
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
264+
if let Ok(x) = arg { self.0.call(x) }
265+
}
266+
}
267+
pub(crate) fn inspect_ok_fn<F>(f: F) -> InspectOkFn<F> {
268+
InspectOkFn(f)
269+
}
270+
271+
#[derive(Debug, Copy, Clone)]
272+
pub struct InspectErrFn<F>(F);
273+
274+
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectErrFn<F>
275+
where
276+
F: FnOnce1<&'a E, Output=()>
277+
{
278+
type Output = ();
279+
fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
280+
if let Err(x) = arg { self.0.call_once(x) }
281+
}
282+
}
283+
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectErrFn<F>
284+
where
285+
F: FnMut1<&'a E, Output=()>,
286+
{
287+
fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
288+
if let Err(x) = arg { self.0.call_mut(x) }
289+
}
290+
}
291+
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectErrFn<F>
292+
where
293+
F: Fn1<&'a E, Output=()>,
294+
{
295+
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
296+
if let Err(x) = arg { self.0.call(x) }
297+
}
298+
}
299+
pub(crate) fn inspect_err_fn<F>(f: F) -> InspectErrFn<F> {
300+
InspectErrFn(f)
301+
}
302+
303+
pub(crate) type MapOkOrElseFn<F, G> = ChainFn<MapOkFn<F>, ChainFn<MapErrFn<G>, MergeResultFn>>;
304+
pub(crate) fn map_ok_or_else_fn<F, G>(f: F, g: G) -> MapOkOrElseFn<F, G> {
305+
chain_fn(map_ok_fn(f), chain_fn(map_err_fn(g), merge_result_fn()))
306+
}
307+
308+
#[derive(Debug, Copy, Clone, Default)]
309+
pub struct UnwrapOrElseFn<F>(F);
310+
311+
impl<F, T, E> FnOnce1<Result<T, E>> for UnwrapOrElseFn<F>
312+
where
313+
F: FnOnce1<E, Output=T>,
314+
{
315+
type Output = T;
316+
fn call_once(self, arg: Result<T, E>) -> Self::Output {
317+
arg.unwrap_or_else(|x| self.0.call_once(x))
318+
}
319+
}
320+
impl<F, T, E> FnMut1<Result<T, E>> for UnwrapOrElseFn<F>
321+
where
322+
F: FnMut1<E, Output=T>,
323+
{
324+
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
325+
arg.unwrap_or_else(|x| self.0.call_mut(x))
326+
}
327+
}
328+
impl<F, T, E> Fn1<Result<T, E>> for UnwrapOrElseFn<F>
329+
where
330+
F: Fn1<E, Output=T>,
331+
{
332+
fn call(&self, arg: Result<T, E>) -> Self::Output {
333+
arg.unwrap_or_else(|x| self.0.call(x))
334+
}
335+
}
336+
pub(crate) fn unwrap_or_else_fn<F>(f: F) -> UnwrapOrElseFn<F> {
337+
UnwrapOrElseFn(f)
338+
}
339+
340+
pub struct IntoFn<T>(PhantomData<fn() -> T>);
341+
342+
impl<T> Default for IntoFn<T> {
343+
fn default() -> Self {
344+
IntoFn(PhantomData)
345+
}
346+
}
347+
impl<A, T> FnOnce1<A> for IntoFn<T> where A: Into<T> {
348+
type Output = T;
349+
fn call_once(self, arg: A) -> Self::Output {
350+
arg.into()
351+
}
352+
}
353+
354+
trivial_fn_impls!(into_fn <T> IntoFn<T> = "Into::into");

0 commit comments

Comments
 (0)