0

i try to create new response without sucess this is what i got :

use std::{future::{ready, Ready}, intrinsics::mir::StaticMut};

use actix_http::{header::{self, HeaderName, HeaderValue}};
use actix_web::{
    dev::{self, Service, ServiceRequest, ServiceResponse, Transform},
    Error,http::Method, HttpResponseBuilder, HttpResponse
};
use futures_util::future::LocalBoxFuture;
//use crate::constants;

pub struct Heartbeat;

impl<S, B> Transform<S, ServiceRequest> for Heartbeat
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = HeartMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(HeartMiddleware { service }))
    }
}

pub struct HeartMiddleware<S> {
    service: S,
}


impl<S, B> Service<ServiceRequest> for HeartMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    dev::forward_ready!(service);

    fn call(&self, req: ServiceRequest) -> Self::Future {
        
        let CONTANT_TYPE: &'static str = "content-type";
        let TEXT_PLAIN: &'static str = "text/plain";
        
        let condition = (Method::POST == req.method() || 
                 Method::GET  == req.method()  ||
                 Method::HEAD == req.method()) && req.path() == "/ping";  

        
        
        let fut = self.service.call(req);
        Box::pin(async move {
            
            let mut res = fut.await?;
            let r = res.into_parts().0;
        
            let headers = res.headers_mut();
            headers.insert(
                 HeaderName::from_static(CONTANT_TYPE), HeaderValue::from_static(TEXT_PLAIN)
            );

            
            if condition {

                let response = HttpResponseBuilder::new(res.status()).body("body test");
                let service_res = ServiceResponse::new(r,response);

                return Ok(service_res)
            }          
            Err(actix_web::error::ErrorImATeapot("Tea"))
        })
    }
}

// main.rs
use actix_web::{get,web,http,Result,App,HttpServer,HttpRequest, Responder, HttpResponse};
use serde::{Deserialize,Serialize};
use actix_cors::Cors;

mod heartbeat;

static PORT :u16 = 9091;

#[get("/")]
async fn index()->impl Responder {
    
    HttpResponse::Ok().body("template")
}

 

#[derive(Serialize)]
pub struct Response {
    pub message: String,
}

async fn not_found() ->Result<HttpResponse> {
    let response = Response {
        message: "Resource not found".to_string(),
    };
    Ok(HttpResponse::NotFound().json(response))
}


#[actix_web::main]
async fn main()-> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "debug");
    env_logger::init();
    HttpServer::new(|| App::new()
    .wrap(
        Cors::default()
            .allowed_origin("http://*") // Allow all http origins
            .allowed_origin("https://*") // Allow all https origins
            .allowed_methods(vec!["GET","POST","PUT","DELETE","OPTIONS"])
            .allowed_headers(vec![http::header::AUTHORIZATION,http::header::CONTENT_TYPE,
                http::header::ACCEPT,http::header::LINK])
            .allowed_header("X-CSRF-TOKEN")
            .supports_credentials()
            .max_age(300)
    )
    .wrap(heartbeat::Heartbeat)
    .service(index)
    .service(web::resource("/ping"))
    .default_service(web::route().to(not_found)))
    .bind(("127.0.0.1",PORT))?
    .run()
    .await        
}


 

but im getting the error :

error[E0658]: use of unstable library feature 'custom_mir': MIR is an implementation detail and extremely unstable
 --> src\heartbeat.rs:1:35
  |
1 | use std::{future::{ready, Ready}, intrinsics::mir::StaticMut};
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0271]: expected `[async block@src\heartbeat.rs:59:18: 78:10]` to be a future that resolves to `Result<ServiceResponse<B>, Error>`, but it resolves to `Result<ServiceResponse, Error>`
  --> src\heartbeat.rs:59:9
   |
35 |   impl<S, B> Service<ServiceRequest> for HeartMiddleware<S>
   |           - this type parameter
...
59 | /         Box::pin(async move {
60 | |
61 | |             let mut res = fut.await?;
62 | |             let r = res.into_parts().0;
...  |
77 | |             Err(actix_web::error::ErrorImATeapot("Tea"))
78 | |         })
   | |__________^ expected `Result<ServiceResponse<B>, Error>`, found `Result<ServiceResponse, Error>`
   |
   = note: expected enum `Result<ServiceResponse<B>, _>`
              found enum `Result<ServiceResponse<BoxBody>, _>`
   = note: required for the cast from `Pin<Box<[async block@src\heartbeat.rs:59:18: 78:10]>>` to `Pin<Box<(dyn futures_util::Future<Output = Result<ServiceResponse<B>, actix_web::Error>> + 'static)>>`

Some errors have detailed explanations: E0271, E0658.
For more information about an error, try `rustc --explain E0271`.
warning: `broker-service` (bin "broker-service") generated 5 warnings
error: could not compile `broker-service` (bin "broker-service") due to 2 previous errors; 5 warnings emitted

all i want is to return custom response

user63898
  • 29,839
  • 85
  • 272
  • 514
  • 1
    1. Do not use `mir`, as the error message tells you. This is definitively not the right way to do whatever you wanted to do with it. 2. Please post a minimal, reproducible error. Currently, the second error involves pieces of code that you have not posted. – jthulhu Sep 01 '23 at 06:11
  • i updated the post , what is mir ? – user63898 Sep 01 '23 at 06:15
  • 2
    [`std::intrinsics::mir`](https://doc.rust-lang.org/stable/std/intrinsics/mir/index.html) part of your imports. It's also not used at all in the code you shared. – cafce25 Sep 01 '23 at 06:16
  • Mir stands for Medium (or Middle, I don't remember) Intermediate Representation and, as the name suggests, it's one of the representation of your code the Rust compiler uses internally. – jthulhu Sep 01 '23 at 06:16
  • @jthulhu MIR stands for Middle (or Mid-level), since HIR stands for High-level. – Chayim Friedman Sep 01 '23 at 10:43
  • Well, you essentially ignore the response of the inner service and give your own of a different type, so you need to specify this type (bare `ServiceResponse`). – Chayim Friedman Sep 01 '23 at 13:13
  • ok and how i can't understand how this pre request mechanism work here – user63898 Sep 01 '23 at 13:24

0 Answers0