Sharing modules across multiple files and in main.rs

Viewed 374

Good Day fellow earthlings.

I'm trying to do what I think is conceptually simple with Rust but i seem to be fighting the compiler and would like some assistance.

I have a really simple, small project that has effectively 3 files

├── cargo.toml
├── src
     ├── main.rs
     ├── api.rs
     └── state.rs
    

src/state.rs is basically a collection of structs that represent a system state. ie

#[derive(Debug,Serialize)]
pub struct State {
    pub field1: String,
    pub field2: String,
}

This is where things derail a bit.

src/api.rs needs to use the struct(s) defined in src/state.rs

If i try mod state.rs at the top of src/api.rs, the compiler looks for the module in /src/api/state.rs. I can make it look for the module in the correct file by doing:

#[path = "system.rs"]
mod system;

use system::*;
use rocket::State;
use rocket_contrib::json::Json;
use serde_json::Value;
use std::sync::{Arc,RwLock};

#[get("/")]
pub fn get_all(state: State<Arc<RwLock<system::State>>>) -> Json<Value> {
    return Json(json!(&*state.read().unwrap()));
}

pub fn start_api(state: Arc<RwLock<system::State>>) {
    rocket::ignite()
        .manage(state)
        .mount("/", routes![get_all]).launch();
}

And in src/main.rs, the state is built then passed into the start_api() function.

However, the compiler stops this by stating that the types do not match. It says...

mismatched types

expected struct `api::system::State`, found struct `system::State`

note: expected struct `std::sync::Arc<std::sync::RwLock<api::system::State>>`
         found struct `std::sync::Arc<std::sync::RwLock<system::State>>`rustc(E0308)

The state module is brought into main.rs the same as it was in api.rs

#![feature(decl_macro)]

...
extern crate rocket;
extern crate rocket_contrib;

mod system;
mod api;

use std::sync::{Arc,RwLock};
use std::thread;
...

fn main() {
    // Initialise state
    start_api(api_state); // << Type Error Here
}

Where have I derailed? It all works when everything is in the same file. I'm trying to split things out as main.rs was approaching a few hundred lines.

Cheers~!

1 Answers

As stated by LotB, instead of

#[path = "system.rs"]
mod system;

use rocket::State;
...
#[get("/")]
pub fn get_all(state: State<Arc<RwLock<system::State>>>) -> Json<Value> {
    return Json(json!(&*state.read().unwrap()));
}

pub fn start_api(state: Arc<RwLock<system::State>>) {
    rocket::ignite()
        .manage(state)
        .mount("/", routes![get_all]).launch();
}

I needed to replace the mod state with use crate::system::State;

Ending up with:

use crate::system::State;

use rocket::State;
use rocket_contrib::json::Json;
use serde_json::Value;
use std::sync::{Arc,RwLock};

#[get("/")]
pub fn get_all(state: State<Arc<RwLock<State>>>) -> Json<Value> {
    return Json(json!(&*state.read().unwrap()));
}

pub fn start_api(state: Arc<RwLock<State>>) {
    rocket::ignite()
        .manage(state)
        .mount("/", routes![get_all]).launch();
}

Thanks LotB.

Related