How do I erase the type of future in the new future API? - async-await

The following does not compile
#![feature(await_macro, async_await, futures_api)]
use core::future::Future;
async fn foo() {}
trait Bar {
type Output: Future<Output = ()>;
fn bar(&self) -> Self::Output;
}
impl Bar for () {
type Output = Box<dyn Future<Output = ()>>;
fn bar(&self) -> Self::Output {
Box::new(foo())
}
}
async fn buz() {
await!(().bar())
}
error[E0277]: the trait bound `(dyn std::future::Future<Output=()> + 'static): std::marker::Unpin` is not satisfied
--> src/lib.rs:19:15
|
19 | await!(().bar())
| ^^^ the trait `std::marker::Unpin` is not implemented for `(dyn std::future::Future<Output=()> + 'static)`
|
= note: required because of the requirements on the impl of `std::future::Future` for `std::boxed::Box<(dyn std::future::Future<Output=()> + 'static)>`
error[E0277]: the trait bound `dyn std::future::Future<Output=()>: std::marker::Unpin` is not satisfied
--> src/lib.rs:19:5
|
19 | await!(().bar())
| ^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output=()>`
|
= note: required because of the requirements on the impl of `std::future::Future` for `std::boxed::Box<dyn std::future::Future<Output=()>>`
= note: required by `std::future::poll_with_tls_waker`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
How can I set the type Output? I want bar to return some Future by calling foo so I can await! in buz.
In the old days with Future<Item = (), Error = ()>, the above would compile without any problems as we don't have the Unpin constraint, but we also don't have await.

Wrap the Box in a Pin:
impl Bar for () {
type Output = Pin<Box<dyn Future<Output = ()>>>;
fn bar(&self) -> Self::Output {
Box::pin(foo())
}
}

Related

Hi I am new to rust And I tried to setup a matrix rust server... and it always throws me a issue in error.rs

error[E0599]: no method named `map_err` found for type parameter `Self` in the current scope
--> src\server\error.rs:40:24
|
34 | pub trait ResultExt<T>: Sized {
| ----------------------------- method `map_err` not found for this type parameter
...
40 | let res = self.map_err(|_| MatrixError::internal_err());
| ^^^^^^^ method not found in `Self`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following traits define an item `map_err`, perhaps you need to add another supertrait for one of them:
|
34 | pub trait ResultExt<T>: Sized + ServiceFactory {
| ++++++++++++++++
34 | pub trait ResultExt<T>: Sized + TryFutureExt {
| ++++++++++++++
34 | pub trait ResultExt<T>: Sized + TryStreamExt {
| ++++++++++++++
34 | pub trait ResultExt<T>: Sized + actix_service::Service {
| ++++++++++++++++++++++++
For more information about this error, try `rustc --explain E0599`.
warning: `maelstrom` (bin "maelstrom") generated 12 warnings
error: could not compile `maelstrom` due to previous error; 12 warnings emitted
It runs into an error where it says that self.map_err is not defined
I tried to completely delete the error.rs out of the code (it didn't work)
here is the code to mess around with
(oh and yes the matrix server uses actix web)
use actix_web::{http::StatusCode, Error, HttpResponse};
#[derive(Clone, Debug, serde::Serialize)]
pub struct MatrixError {
#[serde(skip)]
pub status: StatusCode,
pub errcode: ErrorCode,
pub error: String,
}
impl MatrixError {
pub fn new(status: StatusCode, errcode: ErrorCode, error: &str) -> Self {
MatrixError {
status,
errcode,
error: error.to_string(),
}
}
pub fn internal_err() -> Self {
Self::new(
StatusCode::INTERNAL_SERVER_ERROR,
ErrorCode::UNKNOWN,
"Internal server error.",
)
}
}
impl From<MatrixError> for Error {
fn from(e: MatrixError) -> Self {
HttpResponse::build(e.status).json(e).into()
}
}
pub trait ResultExt<T>: Sized {
fn with_codes(self, status: StatusCode, code: ErrorCode) -> Result<T, MatrixError>;
fn unknown(self) -> Result<T, MatrixError> {
#[cfg(debug_assertions)] // don't leak ISE info in release mode
let res = self.with_codes(StatusCode::INTERNAL_SERVER_ERROR, ErrorCode::UNKNOWN);
#[cfg(not(debug_assertions))]
let res = self.map_err(|_| MatrixError::internal_err());
res
}
}
impl<T, E> ResultExt<T> for Result<T, E>
where
E: std::fmt::Display,
{
fn with_codes(self, status: StatusCode, code: ErrorCode) -> Result<T, MatrixError> {
self.map_err(|e| MatrixError {
status,
errcode: code,
error: format!("{}", e),
})
}
}

Tauri: Is there some way to access AppHandler or Window in regular struct or state managed one?

I'm tring to use hotwatch to monitor folders for backups.
If any changes happen, expect to emit an event to frontend to update pages.
Then i found that it's not able to access AppHandle or Window in regular struct.
I have tried using lifetime, but as Tauri: accessing-an-apphandle-in-commands mention, it seems there's no way to mantain a long enough life time.
pub struct MonitorHandler<'a> {
pub watcher: Hotwatch;
pub app_handler: Option<&'a AppHandle>
}
impl MonitorHandler<'_> {
pub fn initialize_app_handler(&mut self, handler: AppHandle) {
self.app_handler = Some(&handler);
}
pub fn append_target(path: &str) {
self.watcher.watch(path, |event| {
self.app_handler.emit_all("update");
})
}
}
// whitch shows error
89 | pub fn initialize_app_handler(&mut self, handler: AppHandle) {
| --------- has type `&mut MonitorHandler<'1>`
90 | self.app_handler = Some(&handler);
| ------------------------^^^^^^^^-
| | |
| | borrowed value does not live long enough
| assignment requires that `handler` is borrowed for `'1`
...
93 | }
| - `handler` dropped here while still borrowed
I have tried add app handle when setup, but it still not work, and with the same life time problem.
// main.rs
...
fn main() {
let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
let context = tauri::generate_context!();
tauri::Builder::default()
.manage(store)
.setup(|app| {
store.0.lock().unwrap().initialize_app_handler(app.app_handle());
})
.invoke_handler(tauri::generate_handler![
initialize_app_handler
])
.run(context)
.expect("error while running tauri application");
}
// which will occurs
|
40 | let store = MonitorHandler(Mutex::new(MonitorHandler {
| ----- move occurs because `store` has type `MonitorHandler<'_>`, which does not implement the `Copy` trait
...
51 | .manage(store)
| ----- value moved here
52 | .setup(|app| {
| ^^^^^^^^^^ value used here after move
53 | store.0.lock().unwrap().initialize_app_handler(app.app_handle());
| ------- use occurs due to use in closure
I'm not familiar with rust and tauri, so is there some way to access the AppHandle or Window in my situation? or i have to do this in another way?
Here's my origin code
// handler.rs
// in this case, whether it's AppHandle or Window, the program will just stuck and not able to anything
pub struct MonitorHandler {
pub watcher: Hotwatch;
pub app_handler: Option<AppHandle>
}
impl MonitorHandler {
pub fn initialize_app_handler(&mut self, handler: AppHandle) {
self.app_handler = Some(handler.clone());
}
}
pub struct MonitorHandler(pub Mutex<MonitorHandler>);
// main.rs
use hotwatch::Hotwatch;
use tauri::{ Manager, AppHandle };
use crate::handler::MonitorHandler;
#[tauri::command]
pub fn initialize_app_handler(monitor: State<MonitorHandler>, app_handler: AppHandle) -> bool {
monitor.0.lock().unwrap().initialize_app_handler(app_handler);
true
}
fn main() {
let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
let context = tauri::generate_context!();
tauri::Builder::default()
.manage(store)
.setup()
.invoke_handler(tauri::generate_handler![
initialize_app_handler
])
.run(context)
.expect("error while running tauri application");
}
The reason it get stuck is that the lock action cause a dead lock in the AppHandle since the stored sturct is assigned to the instance of the AppHandle.
How to solve the problem is simple, greet thanks for #FabianLars, here's the discussion Is there some way for backend to emit event actively?
To be brief, just initialize the struct and manage it in setup, like this
// handler.rs
pub struct MonitorHandler {
pub watcher: Hotwatch;
pub app_handler: AppHandle
}
impl MonitorHandler {
pub fn do_something(&self) {
// do something
self.app_handler.emit_all("events", some_payload { ... });
}
}
pub struct MonitorHandler(pub Mutex<MonitorHandler>);
// main.rs
use hotwatch::Hotwatch;
use tauri::{ Manager, AppHandle };
use crate::handler::MonitorHandler;
fn main() {
// let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
// let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor }));
let context = tauri::generate_context!();
tauri::Builder::default()
.setup(move |app| {
let monitor = Hotwatch::new().expect("failed to initialize monitor_handler");
let struct_app_handle = app.handle().clone();
let store = MonitorHandler(Mutex::new(MonitorHandler{ watcher: monitor, app_handler: struct_app_handle }));
app.manage(store);
})
.invoke_handler(tauri::generate_handler![
initialize_app_handler
])
.run(context)
.expect("error while running tauri application");
}

How can I join nested BoxFutures via traits and their associated lifetimes?

I have an AdoptablePet trait that allows you to asynchronously adopt a pet via fn do_adoption(id: &Self::Id) -> BoxFuture<'static, Result<Self, Self::Error>>;.
I have a Dog trait that is adoptable (pub trait Dog: AdoptablePet) and takes an associated AdoptingPerson and an adoption_policy before allowing you to actually adopt the pet. The adoption_policy is just a function that returns an array of boxed futures returning Results.
When I go to create a Pitbull, which implements both Dog and an AdoptablePet, everything works, but as soon as I try to make a default implementation of adoption_policy (as it will be the same for all Pitbulls) I can't get the references right between all the joining of the boxed futures.
When I try to join_all the adoption_policy Vec, it contains references to the boxed futures rather than the boxed futures themselves. When I try to map and dereference them, I get a borrow checker error (see [EXAMPLE B] in the code):
error[E0277]: the trait bound `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>: core::future::future::Future` is not satisfied
--> src/lib.rs:70:13
|
70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| {
| ^^^^^^^^ the trait `core::future::future::Future` is not implemented for `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>`
|
= help: the following implementations were found:
<std::pin::Pin<P> as core::future::future::Future>
= note: required by `futures_util::future::join_all::join_all`
error[E0599]: no method named `then` found for type `futures_util::future::join_all::JoinAll<&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>>` in the current scope
--> src/lib.rs:70:65
|
70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| {
| ^^^^
error[E0277]: the trait bound `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>: core::future::future::Future` is not satisfied
--> src/lib.rs:70:13
|
70 | join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `core::future::future::Future` is not implemented for `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>`
|
= help: the following implementations were found:
<std::pin::Pin<P> as core::future::future::Future>
= note: required by `futures_util::future::join_all::JoinAll`
I'm a bit lost. If I don't join_all in adopt (and merely return Self::do_adoption(id) everything works (see [EXAMPLE A] in the code). What's going on?
The code (also available in a git repo):
#![feature(async_await)]
use futures::future::{self, join_all, BoxFuture};
#[derive(Debug)]
pub struct AdoptionError;
pub trait AdoptablePet
where
Self: Sized,
{
/// The id of the pet to adopt.
type Id;
/// Adopt the pet.
fn do_adoption(id: &Self::Id) -> BoxFuture<'static, Result<Self, AdoptionError>>;
}
pub trait Dog: AdoptablePet
where
// XXX: Are these all needed?
Self: Sized + Send,
<Self as AdoptablePet>::Id: Sync,
Self: 'static,
Self::AdoptingPerson: Sync,
{
/// The Person adopting a dog.
type AdoptingPerson;
/// The policy to check when a person is adopting a particular dog.
fn adoption_policy(
adopter: &Self::AdoptingPerson,
id: &Self::Id,
) -> Vec<BoxFuture<'static, Result<(), AdoptionError>>>;
/// Policy-aware adoption.
fn adopt(
adopter: &Self::AdoptingPerson,
id: &Self::Id,
) -> BoxFuture<'static, Result<Self, AdoptionError>> {
// [EXAMPLE A]
// Doing the following works...
/*
if true {
Self::do_adoption(id)
} else {
Box::pin(future::ready(Err(AdoptionError{})))
}
*/
/* [EXAMPLE B]
But this is what I want to do. This is the error:
--> src/lib.rs:71:13
|
71 | / join_all(
72 | |
73 | |
74 | | --> src/lib.rs:65:13
... |
86 | | Self::adoption_policy(adopter, id).iter(),
87 | | )
| |_____________^ the trait `core::future::future::Future` is not implemented for `&std::pin::Pin<std::boxed::Box<dyn core::future::future::Future<Output = std::result::Result<(), AdoptionError>> + std::marker::Send>>`
|
= help: the following implementations were found:
<std::pin::Pin<P> as core::future::future::Future>
= note: required by `futures_util::future::join_all::JoinAll`
*/
Box::pin(
// Check all the adoption rules in the policy.
join_all(Self::adoption_policy(adopter, id).iter()).then(|policy_results| {
// Depending on the result, do the (async/long-running)
// adoption or return an error.
let has_policy_failure = policy_results.any(|x| x.is_err());
if !has_policy_failure {
Self::do_adoption(id)
} else {
Box::pin(future::ready(Err(AdoptionError {})))
}
}),
)
}
}
/// Implementation.
#[derive(Debug, Clone, PartialEq)]
pub struct DogId(pub String);
pub struct Pitbull {
pub id: DogId,
}
impl AdoptablePet for Pitbull {
type Id = DogId;
fn do_adoption(id: &Self::Id) -> BoxFuture<'static, Result<Self, AdoptionError>> {
Box::pin(future::ready(Ok(Pitbull { id: id.clone() })))
}
}
impl Dog for Pitbull {
type AdoptingPerson = Person;
fn adoption_policy(
_adopter: &Self::AdoptingPerson,
_id: &Self::Id,
) -> Vec<BoxFuture<'static, Result<(), AdoptionError>>> {
vec![
// 1. Check if they have had their shots.
// 2. Check if the adopter has children and if the breed is good with children.
// etc.
]
}
}
pub struct Person {
name: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
futures::executor::block_on(async {
let id = DogId("fluffy123".to_string());
let adopter = Person {
name: "Fred".to_string(),
};
let _ = Pitbull::adopt(&adopter, &id).await.unwrap();
});
}
}
I'm using futures-preview version 0.3.0-alpha.16.
Here is the working version:
fn adopt(
adopter: &Self::AdoptingPerson,
id: &'static Self::Id,
) -> BoxFuture<'static, Result<Self, AdoptionError>> {
Box::pin(
join_all(Self::adoption_policy(adopter, id)).then(move |policy_results| {
let has_policy_failure = policy_results.iter().any(|x| x.is_err());
if !has_policy_failure {
Self::do_adoption(id)
} else {
Box::pin(future::ready(Err(AdoptionError {})))
}
}),
)
}
Changes:
join_all needs to take ownership of the futures, not references to them: join_all(Self::adoption_policy(adopter, id)).
futures::future::FutureExt must be imported to gain access to FutureExt::then.
any is a method on Iterator, not Vec: policy_results.iter().any(/* ... */)
id needs to be 'static due to your bounds: id: &'static Self::Id
id needs to be moved into the closure to prevent a borrow: move |policy_results| { /* ... */ }.
See also:
What is the difference between iter and into_iter?
Why do I need to import a trait to use the methods it defines for a type?

How do I have a trait field in a struct?

I have some code that I want to turn into a crate. But it includes a structure that contains a field that I want to be provided by the user of the crate. But I need functionality from that field, so I want to specify it as a trait.
pub trait RoleTrait {
fn owner<T: RoleTrait>() -> T;
fn order<T: RoleTrait>(&self) -> usize;
}
pub struct RequestInfo<Role: RoleTrait + PartialEq> {
role: Option<Role>,
name: String,
}
impl<Role: RoleTrait> RequestInfo<Role>
where
Role: std::cmp::PartialEq,
{
fn name(&self) -> String {
self.name.to_string()
}
fn role(&self) -> &Option<Role> {
&self.role
}
fn is_owner(&self) -> bool {
if let Some(role) = self.role {
role == Role::owner()
} else {
false
}
}
fn order(&self) -> usize {
if let Some(role) = self.role {
role.order() + 1
} else {
0
}
}
fn from(name: String) -> RequestInfo<Role> {
RequestInfo::<Role> {
role: None,
name: name,
}
}
fn with_role(name: String, role: Role) -> RequestInfo<Role> {
RequestInfo::<Role> {
role: Some(role),
name: name,
}
}
}
With two implementations of RoleTrait:
#[derive(PartialEq)]
pub enum CourseRole {
Professor,
Marker,
Student,
}
impl RoleTrait for CourseRole {
fn owner<T: RoleTrait>() -> T {
CourseRole::Professor
}
fn order<T: RoleTrait>(&self) -> usize {
if *self == CourseRole::Professor {
0
} else {
1
}
}
}
#[derive(PartialEq)]
pub enum BlogRole {
Owner,
Blogger,
}
impl RoleTrait for BlogRole {
fn owner<T: RoleTrait>() -> T {
BlogRole::Owner
}
fn order<T: RoleTrait>(&self) -> usize {
if *self == BlogRole::Owner {
0
} else {
1
}
}
}
I get 3 errors with this.
error[E0282]: type annotations needed
--> src/main.rs:28:18
|
28 | role.order() + 1
| ^^^^^ cannot infer type for `T`
error[E0308]: mismatched types
--> src/main.rs:55:9
|
54 | fn owner<T: RoleTrait>() -> T {
| - expected `T` because of return type
55 | CourseRole::Professor
| ^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `CourseRole`
|
= note: expected type `T`
found type `CourseRole`
error[E0308]: mismatched types
--> src/main.rs:72:9
|
71 | fn owner<T: RoleTrait>() -> T {
| - expected `T` because of return type
72 | BlogRole::Owner
| ^^^^^^^^^^^^^^^ expected type parameter, found enum `BlogRole`
|
= note: expected type `T`
found type `BlogRole`
(and the second error repeated for the other enum)
Frankly, I'm surprised (and pleased!) that some of my code is valid (like the references to owner in the trait). I had a lot more errors when I started writing this question, but I can't figure out these remaining ones since T looks so clear and rustc seems to have already figured out harder things. In the last 2 errors, it's almost like it doesn't realize that there is an implementation of the trait for the enum because it's in the middle of defining that implementation (but it obviously understands that in other places).
Something feels a little "off" with this trait:
pub trait RoleTrait {
fn owner<T: RoleTrait>() -> T;
fn order<T: RoleTrait>(&self) -> usize;
}
The owner method doesn't have a receiver (e.g. self), so it seems unnecessary to introduce a new type parameter; Self will do the same thing.
In order, having a separate T is not exactly the same thing as just using Self - it allows T and Self to be a completely different implementations of RoleTrait. But this feels like quite a strange and unusual requirement, especially since T doesn't appear in the method signature.
Your code can be fixed quite simply by following the more typical pattern:
pub trait RoleTrait {
fn owner() -> Self;
fn order(&self) -> usize;
}
This small change leads to all the type errors being resolved, and just leaving a couple of small borrow errors (playground), which can be quite easily addressed (playground).

Rust: Enum vs Impl Trait vs? [duplicate]

I'm trying to get a random number generator. Since OsRng::new() can fail, I'd like to fall back to thread_rng() if I have to:
extern crate rand; // 0.5.5
use rand::{thread_rng, OsRng, RngCore};
fn rng() -> impl RngCore
{
match OsRng::new() {
Ok(rng) => rng,
Err(e) => thread_rng()
}
}
However, I get this error message which I cannot understand:
error[E0308]: match arms have incompatible types
--> src/lib.rs:6:5
|
6 | / match OsRng::new() {
7 | | Ok(rng) => rng,
8 | | Err(e) => thread_rng(),
| | ------------ match arm with an incompatible type
9 | | }
| |_____^ expected struct `rand::OsRng`, found struct `rand::ThreadRng`
|
= note: expected type `rand::OsRng`
found type `rand::ThreadRng`
Why is the compiler expecting rand::OsRng here instead of an implementation of RngCore? If I remove the match and directly return thread_rng(), I don't get above error message.
I do not believe that this is a duplicate of How do I return an instance of a trait from a method?, as the other question is asking about how one can return a trait from a function, and this question is about why the compiler will not allow me to return a trait but wants me to return an OsRng which is not the return type of the function.
impl Trait is not equivalent to returning an interface or base class object. It's a way of saying "I don't want to write the name of the specific type I'm returning". You're still returning a value of a single, specific type; you just aren't saying which type.
Each of those branches is returning different types, hence the problem. Implementing the same trait is not enough.
What you likely want in this specific case is a trait object like Box<dyn RngCore>.
extern crate rand; // 0.6.5
use rand::{rngs::OsRng, thread_rng, RngCore};
fn rng() -> Box<dyn RngCore> {
match OsRng::new() {
Ok(rng) => Box::new(rng),
Err(_) => Box::new(thread_rng()),
}
}
Note: if you are using a slightly older version of Rust, you may need to remove the dyn keyword. It's optional in the previous (2015) edition of Rust.
DK. has already explained why, but I'd like to provide an alternative workaround.
As mentioned in Conditionally iterate over one of several possible iterators, you can create an enum that implements a trait if both of its component types do. For example:
extern crate rand; // 0.6.5
use rand::{rngs::OsRng, thread_rng, RngCore};
fn rng() -> impl RngCore {
match OsRng::new() {
Ok(rng) => EitherRng::Left(rng),
Err(_) => EitherRng::Right(thread_rng()),
}
}
enum EitherRng<L, R> {
Left(L),
Right(R),
}
impl<L, R> RngCore for EitherRng<L, R>
where
L: RngCore,
R: RngCore,
{
fn next_u32(&mut self) -> u32 {
match self {
EitherRng::Left(l) => l.next_u32(),
EitherRng::Right(r) => r.next_u32(),
}
}
fn next_u64(&mut self) -> u64 {
match self {
EitherRng::Left(l) => l.next_u64(),
EitherRng::Right(r) => r.next_u64(),
}
}
fn fill_bytes(&mut self, b: &mut [u8]) {
match self {
EitherRng::Left(l) => l.fill_bytes(b),
EitherRng::Right(r) => r.fill_bytes(b),
}
}
fn try_fill_bytes(&mut self, b: &mut [u8]) -> Result<(), rand::Error> {
match self {
EitherRng::Left(l) => l.try_fill_bytes(b),
EitherRng::Right(r) => r.try_fill_bytes(b),
}
}
}
The either crate provides a lot of these types of implementations for fundamental traits.
See also:
How do I conditionally return different types of futures?

Resources