0

I'm sure I am misunderstanding something here but I am trying to use Routes for a Rocket application like the below

use rocket;
use crate::endpoint::routes as endpoint_routes;

/* REDACTED */

let routes = endpoint_routes::new_routes();

let rocket_build = rocket_build
    .mount("/index", rocket::routes![index])
    .mount("/other", rocket::routes![routes.other]);

/* REDACTED */

#[rocket::get("/")]
fn index() -> &'static str {
    return "Index";
}

The one for index works fine, but the one that is being used from a crate is failing and I think it is because I'm doing something wrong with the attribute when trying to use it inside of an implementation

/endpoint/routes.rs

use rocket;

pub struct Routes {
    bigfatdata:String
}

pub fn new_routes() -> Routes {
    let routes = Routes {
        bigfatdata:String::from("Nothing")
    };
    return routes;
}

impl Routes {
    #[rocket::get("/")]
    pub fn other(&self) -> &'static str {
        println!("{:?}", self.bigfatdata);
        return "other";
    }
}

I'm getting a few compile errors

error: expected `,`
    .mount("/testTest", rocket::routes![routes.test])
                                              ^
error: handler arguments must be of the form `ident: Type`
    pub fn test(&self) -> &'static str {
                ^

error[E0277]: the trait bound `Vec<Route>: From<()>` is not satisfied

    .mount("/other", rocket::routes![routes.other])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `Vec<Route>`

If I remove the #[rocket::get("/")] and call it like normal

let routes = endpoint_routes::new_routes();
println!("{}", routes.test());

I get the expected output as "Nothing"

Modified Reproducible Example

I'm adding a modified version that can be done in one file just to better show what I'm trying to achieve (hopefully).

use rocket;

////
// only for testing
////

#[rocket::get("/")]
fn index() -> &'static str {
    return "Index";
}

////
// routes
////

struct Routes { bigfatdata:String }

fn new_routes() -> Routes {
    // handle new route instance
    let routes = Routes { bigfatdata:String::new() };
    return routes;
}

impl Routes {
    // update state for bigfatdata
    pub fn update_bigfatdata(&mut self, bigfatdata:&str) {
        self.bigfatdata = String::from(bigfatdata);
    }
    // route to execute
    pub fn handle_get(&self) -> &'static str {
        println!("{:?}", self.bigfatdata);
        return "handle_get";
    }
}

////
// main
////

#[tokio::main]
async fn main() {

    let figment = rocket::Config::figment().merge(("address", "0.0.0.0")).merge(("port", 31));

    // create group of routes for A
    let mut routes_a = new_routes();
    routes_a.update_bigfatdata("Routes A");
    routes_a.handle_get();

    // create group of routes for B
    let mut routes_b = new_routes();
    routes_b.update_bigfatdata("Routes B");
    routes_b.handle_get();

    let rocket_build = rocket::custom(figment)
        // hoping to use the routes as mounts
        //.mount("/routesA", routes_a.handle_get())
        //.mount("/routesB", routes_b.handle_get())
        .mount("/", rocket::routes![index]);

    let _rocket_ignite = rocket_build.launch().await.expect("ERROR");

}
TheLovelySausage
  • 3,838
  • 15
  • 56
  • 106
  • 2
    Can you please copy and paste your [mre]? your error and second example are talking about a `test` method that never is defined anywhere in your example. – cafce25 Mar 01 '23 at 15:32
  • I had to change it quite a bit to remove all of the fluff – TheLovelySausage Mar 01 '23 at 19:12
  • You can do so in a fresh project and make sure the error message is the one you expect, because with the code you posted you can't get that error message which is confusing for everyone reading it. You should never edit the code on StackOverflow itself because it leads to typos and wrong (for different reasons than asked about) code here. – cafce25 Mar 01 '23 at 19:17
  • Yeah the updated code at the bottom is a completely separate project, I just didn't delete the one from the original post for context – TheLovelySausage Mar 01 '23 at 19:18

1 Answers1

1

You can't make a method a GET handler with the get attribute macro or use it inside an impl block because:

This and all other route attributes can only be applied to free functions

And even if you could you can't refer to a method by dropping the parentheses like this object.method_name only by using the fully qualified path Type::method_name.

cafce25
  • 15,907
  • 4
  • 25
  • 31