Crate async_ops

Source
Expand description

std:ops traits for Future

This crate provides a way to use some std::ops traits with futures. To be able to use a std::ops trait with a Future, first you need to wrap the Future with Async using async_ops::on. Then, as long the Future::Output type implements a supported std::ops trait, then the same std::ops trait will be implemented by the Async instance.

Another option is to wrap a Future with Async using assignable! to enable usage of the Assign variants of std::ops traits on the Future.

§Example

When writing async code it is common to do operations that are supported through std::ops. For example, adding to numbers might look like this:

use futures_executor::block_on;

// Immediately returning a number is done for simplicity and production code
// wouldn't just immediately return a value.
let a = async { 40 };
let b = async { 2 };

let result = async { a.await + b.await };

assert_eq!(42, block_on(result));

Actually, the above code is not optimally implemented because a and b are await-ed sequentially, instead of concurrently. The appropriate solution is to use join! to be able to concurrently await both values like this:


use futures_util::join;

let result = async {
  let (a, b) = join!(a, b);
  a + b
};

assert_eq!(42, block_on(result));

Or, just use async_ops::on to do the same thing like the above example in one line:


let result = async { (async_ops::on(a) + b).await };

assert_eq!(42, block_on(result));

Note that the async_ops::on example will also concurrently await both values.

§Supported std::ops traits

§Add

Async implements Add<Rhs> where Rhs: Future when the wrapped Future::Output type implements Add<Rhs::Output>. The resulting type of the addition is Async<impl Future<Output = <Future::Output as Add<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 40 };
let b = async { 2 };

let result = async { (async_ops::on(a) + b).await };

assert_eq!(42, block_on(result));

§AddAssign

Async implements AddAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Add<Rhs>>::Output>, which in turn requires the Future::Output type to implement Add<Rhs::Output>.

use futures_executor::block_on;

let a = async { 40 };
let b = async { 2 };

let result = async {
  async_ops::assignable!(a);
  a += b;
  a.await
};

assert_eq!(42, block_on(result));

§BitAnd

Async implements BitAnd<Rhs> where Rhs: Future when the wrapped Future::Output type implements BitAnd<Rhs::Output>. The resulting type of the bitwise and is Async<impl Future<Output = <Future::Output as BitAnd<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 110 };
let b = async { 59 };

let result = async { (async_ops::on(a) & b).await };

assert_eq!(42, block_on(result));

§BitAndAssign

Async implements BitAndAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as BitAnd<Rhs>>::Output>, which in turn requires the Future::Output type to implement BitAnd<Rhs::Output>.

use futures_executor::block_on;

let a = async { 110 };
let b = async { 59 };

let result = async {
  async_ops::assignable!(a);
  a &= b;
  a.await
};

assert_eq!(42, block_on(result));

§BitOr

Async implements BitOr<Rhs> where Rhs: Future when the wrapped Future::Output type implements BitOr<Rhs::Output>. The resulting type of the bitwise or is Async<impl Future<Output = <Future::Output as BitOr<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 40 };
let b = async { 10 };

let result = async { (async_ops::on(a) | b).await };

assert_eq!(42, block_on(result));

§BitOrAssign

Async implements BitOrAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as BitOr<Rhs>>::Output>, which in turn requires the Future::Output type to implement BitOr<Rhs::Output>.

use futures_executor::block_on;

let a = async { 40 };
let b = async { 10 };

let result = async {
  async_ops::assignable!(a);
  a |= b;
  a.await
};

assert_eq!(42, block_on(result));

§BitXor

Async implements BitXor<Rhs> where Rhs: Future when the wrapped Future::Output type implements BitXor<Rhs::Output>. The resulting type of the bitwise xor is Async<impl Future<Output = <Future::Output as BitXor<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 38 };
let b = async { 12 };

let result = async { (async_ops::on(a) ^ b).await };

assert_eq!(42, block_on(result));

§BitXorAssign

Async implements BitXorAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as BitXor<Rhs>>::Output>, which in turn requires the Future::Output type to implement BitXor<Rhs::Output>.

use futures_executor::block_on;

let a = async { 38 };
let b = async { 12 };

let result = async {
  async_ops::assignable!(a);
  a ^= b;
  a.await
};

assert_eq!(42, block_on(result));

§Div

Async implements Div<Rhs> where Rhs: Future when the wrapped Future::Output type implements Div<Rhs::Output>. The resulting type of the division is Async<impl Future<Output = <Future::Output as Div<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 84 };
let b = async { 2 };

let result = async { (async_ops::on(a) / b).await };

assert_eq!(42, block_on(result));

§DivAssign

Async implements DivAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Div<Rhs>>::Output>, which in turn requires the Future::Output type to implement Div<Rhs::Output>.

use futures_executor::block_on;

let a = async { 84 };
let b = async { 2 };

let result = async {
  async_ops::assignable!(a);
  a /= b;
  a.await
};

assert_eq!(42, block_on(result));

§Mul

Async implements Mul<Rhs> where Rhs: Future when the wrapped Future::Output type implements Mul<Rhs::Output>. The resulting type of the multiplication is Async<impl Future<Output = <Future::Output as Mul<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 21 };
let b = async { 2 };

let result = async { (async_ops::on(a) * b).await };

assert_eq!(42, block_on(result));

§MulAssign

Async implements MulAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Mul<Rhs>>::Output>, which in turn requires the Future::Output type to implement Mul<Rhs::Output>.

use futures_executor::block_on;

let a = async { 21 };
let b = async { 2 };

let result = async {
  async_ops::assignable!(a);
  a *= b;
  a.await
};

assert_eq!(42, block_on(result));

§Neg

Async implements Neg when the wrapped Future::Output type implements Neg. The resulting type of the negation is Async<impl Future<Output = <Future::Output as Neg>::Output>>.

use futures_executor::block_on;

let a = async { -42 };

let result = async { (-async_ops::on(a)).await };

assert_eq!(42, block_on(result));

§Not

Async implements Not when the wrapped Future::Output type implements Not. The resulting type of the logical negation is Async<impl Future<Output = <Future::Output as Not>::Output>>.

use futures_executor::block_on;

let a = async { 213_u8 };

let result = async { (!async_ops::on(a)).await };

assert_eq!(42, block_on(result));

§Rem

Async implements Rem<Rhs> where Rhs: Future when the wrapped Future::Output type implements Rem<Rhs::Output>. The resulting type of the reminder operation is Async<impl Future<Output = <Future::Output as Rem<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 42 };
let b = async { 5 };

let result = async { (async_ops::on(a) % b).await };

assert_eq!(2, block_on(result));

§RemAssign

Async implements RemAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Rem<Rhs>>::Output>, which in turn requires the Future::Output type to implement Rem<Rhs::Output>.

use futures_executor::block_on;

let a = async { 42 };
let b = async { 5 };

let result = async {
  async_ops::assignable!(a);
  a %= b;
  a.await
};

assert_eq!(2, block_on(result));

§Shl

Async implements Shl<Rhs> where Rhs: Future when the wrapped Future::Output type implements Shl<Rhs::Output>. The resulting type of the left shift is Async<impl Future<Output = <Future::Output as Shl<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 21 };
let b = async { 1 };

let result = async { (async_ops::on(a) << b).await };

assert_eq!(42, block_on(result));

§ShlAssign

Async implements ShlAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Shl<Rhs>>::Output>, which in turn requires the Future::Output type to implement Shl<Rhs::Output>.

use futures_executor::block_on;

let a = async { 21 };
let b = async { 1 };

let result = async {
  async_ops::assignable!(a);
  a <<= b;
  a.await
};

assert_eq!(42, block_on(result));

§Shr

Async implements Shr<Rhs> where Rhs: Future when the wrapped Future::Output type implements Shr<Rhs::Output>. The resulting type of the right shift is Async<impl Future<Output = <Future::Output as Shr<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 168 };
let b = async { 2 };

let result = async { (async_ops::on(a) >> b).await };

assert_eq!(42, block_on(result));

§ShrAssign

Async implements ShrAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Shr<Rhs>>::Output>, which in turn requires the Future::Output type to implement Shr<Rhs::Output>.

use futures_executor::block_on;

let a = async { 168 };
let b = async { 2 };

let result = async {
  async_ops::assignable!(a);
  a >>= b;
  a.await
};

assert_eq!(42, block_on(result));

§Sub

Async implements Sub<Rhs> where Rhs: Future when the wrapped Future::Output type implements Sub<Rhs::Output>. The resulting type of the subtraction is Async<impl Future<Output = <Future::Output as Sub<Rhs::Output>>::Output>>.

use futures_executor::block_on;

let a = async { 44 };
let b = async { 2 };

let result = async { (async_ops::on(a) - b).await };

assert_eq!(42, block_on(result));

§SubAssign

Async implements SubAssign<Rhs> where Rhs: Future when the wrapped Future type implements Assignable<<Async<Future> as Sub<Rhs>>::Output>, which in turn requires the Future::Output type to implement Sub<Rhs::Output>.

use futures_executor::block_on;

let a = async { 44 };
let b = async { 2 };

let result = async {
  async_ops::assignable!(a);
  a -= b;
  a.await
};

assert_eq!(42, block_on(result));

Macros§

assignable
Wraps the given Future with Async so that the result can be used with the Assign variants of std::ops traits.

Structs§

Add
A Binary operation that will concurrently resolve two Futures and add their results.
Async
A wrapper class for a Future that enables usage of some std::ops traits.
BitAnd
A Binary operation that will concurrently resolve two Futures and bitand their results.
BitOr
A Binary operation that will concurrently resolve two Futures and bitor their results.
BitXor
A Binary operation that will concurrently resolve two Futures and bitxor their results.
Div
A Binary operation that will concurrently resolve two Futures and div their results.
Mul
A Binary operation that will concurrently resolve two Futures and mul their results.
Neg
A Unary operation that will concurrently resolve a Future and neg its result.
Not
A Unary operation that will concurrently resolve a Future and not its result.
Rem
A Binary operation that will concurrently resolve two Futures and rem their results.
Shl
A Binary operation that will concurrently resolve two Futures and shl their results.
Shr
A Binary operation that will concurrently resolve two Futures and shr their results.
Sub
A Binary operation that will concurrently resolve two Futures and sub their results.

Traits§

Assignable
Trait for types that can be used with the Binary::op_assign to assign the result of the Binary operation to the left-hand operand.
Binary
Trait that represents a binary operation on the left-hand operand of type Lhs and the right-hand operand of type Rhs that returns the result of type Output.
Unary
Trait that represents an unary operation on the operand of type Operand that returns the result of type Output.

Functions§

add
Returns a Future that will concurrently resolve given Futures and add their results.
assignableDeprecated
Wraps the given Future with Async so that the result can be used with the Assign variants of std::ops traits.
bitand
Returns a Future that will concurrently resolve given Futures and bitand their results.
bitor
Returns a Future that will concurrently resolve given Futures and bitor their results.
bitxor
Returns a Future that will concurrently resolve given Futures and bitxor their results.
div
Returns a Future that will concurrently resolve given Futures and div their results.
mul
Returns a Future that will concurrently resolve given Futures and mul their results.
neg
Returns a Future that will resolve the given Future and neg its result.
not
Returns a Future that will resolve the given Future and not its result.
on
Wraps the given Future with Async.
rem
Returns a Future that will concurrently resolve given Futures and rem their results.
shl
Returns a Future that will concurrently resolve given Futures and shl their results.
shr
Returns a Future that will concurrently resolve given Futures and shr their results.
sub
Returns a Future that will concurrently resolve given Futures and sub their results.