I fail to see how hiding self.send() inside of IntoFuture makes anything simpler.
StorageRequest::new().set_debug(true).send().await?;
vs
StorageRequest::new().set_debug(true).await?;
Just reading the later variant makes me wonder "What are we (a)waiting for here? For set_debug to succeed?". I'd definitely stick to the former variant.
Perhaps, it's just not the best example and there are better usages than the one chosen to illustrate it.
foo::some_func(foo::SomeFuncArgs{
a: 8,
b: Some(false),
..Default::default()
})
Personally I would be really happy if `..` could default to `..Default::default()` which would make this a lot cleaner. But even then needing to name a type for the argument struct is noisy. Language-integrated keyword arguments would make this a lot cleaner: foo::some_func(
a=8,
b=Some(false)) foo::some_func({
.a = 8,
.b = false
});
(I view this and std::span as the only two usable features in C++20, and pretty much everything else can go to the dustbin or the drawing board.)I wouldn't mind if it worked this way "under the hood" but syntax sugar for passing that last argument as keyword arguments would be a fantastic quality of life improvement.
let mut foo = build_foo()
.with_a(8);
if need_to_set_b {
foo = foo.with_b(false);
}
let foo = foo.build();And yes, the example is not the best.
With tooling this would make your resulting type be a StorageResponse. The whole point is that you can have that "request type" be awaitable.
It's simpler for library users, because they don't need to know which particular method finalizes a builder to obtain a future from it, and `.await` just works in more situations.
Say, `for await x in connection.item {}` not real syntax but something similar might be in Rust's future.
Rust lets you have generic types on structs and functions:
// T is a generic type parameter, x has type T
fn foo<T>(x: T) -> {
Rust also lets you have "associated types": trait MyIterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
struct Alternate {
state: i32,
}
impl MyIterator for Alternate {
// because we choose the Item type here...
type Item = i32;
// that determines the type that gets returned down here
fn next(&mut self) -> Option<Self::Item> {
In today's Rust, `type Item` cannot be a generic type: // lifetimes are generics, so if you try this...
trait MyIterator {
type Item<'a>;
// you'll get this error message
error[E0658]: generic associated types are unstable
In the near future, combining these two features will be allowed.https://rust-lang.github.io/generic-associated-types-initiat...