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 - matrix

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),
})
}
}

Related

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 to extract fields from a struct within an enum (irrefutable if-let pattern)

I am trying to make an S3 client library but since there are many actions (API_Operations) I decided to use an enum to define all the posible actions in the hope that could be more easy to maintain (any advice/comments/feedback?), for example this is the enum Actions::ListObjectsV2 snippet for listing the contents of a bucket:
pub enum Actions {
// missing options, POC for now
ListObjectsV2 {
continuation_token: Option<String>,
delimiter: Option<String>,
fetch_owner: Option<bool>,
prefix: Option<String>,
start_after: Option<String>,
},
}
Is used with something like this:
let s3 = S3::new(&bucket, &credentials, &region);
let action = Actions::ListObjectsV2 {
continuation_token: None,
delimiter: None,
fetch_owner: None,
prefix: Some(String::from("foo")),
start_after: None,
};
if let Ok(objects) = s3.list_objects(action).await {
println!("objects: {:#?}", objects);
}
The s3.list_objects(action) method looks like this:
pub async fn list_objects(
&self,
action: Actions,
) -> Result<ListBucketResult, Box<dyn error::Error>> {
let mut url = Url::parse(&format!("https://{}/{}", self.host, self.bucket))?;
url.query_pairs_mut().append_pair("list-type", "2");
if let Actions::ListObjectsV2 {
continuation_token,
delimiter,
fetch_owner,
prefix,
start_after,
} = action.clone()
{
if let Some(token) = continuation_token {
url.query_pairs_mut()
.append_pair("continuation-token", &token);
}
if let Some(delimiter) = delimiter {
url.query_pairs_mut().append_pair("delimiter", &delimiter);
}
if fetch_owner.is_some() {
url.query_pairs_mut().append_pair("fetch-owner", "true");
}
if let Some(prefix) = prefix {
url.query_pairs_mut().append_pair("prefix", &prefix);
}
if let Some(sa) = start_after {
url.query_pairs_mut().append_pair("start-after", &sa);
}
}
...
It works but I get this warning: irrefutable if-let pattern
warning: irrefutable if-let pattern
--> src/s3/mod.rs:49:9
|
49 | / if let Actions::ListObjectsV2 {
50 | | continuation_token,
51 | | delimiter,
52 | | fetch_owner,
... |
72 | | }
73 | | }
| |_________^
|
= note: `#[warn(irrefutable_let_patterns)]` on by default
I could remove the warning by adding to that block:
#[allow(irrefutable_let_patterns)]
But instead, I would like to know if there are better ways to fix this, I tried some options from this post (https://users.rust-lang.org/t/how-do-i-get-rid-of-this-pattern-of-extracting-a-value-from-an-enum/12555/7), but I can't figure out how to implement this pattern:
impl From<> for Option<>
Any ideas?

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).

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

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())
}
}

Resources