Search code examples
rustrust-cargorust-crates

Importing leading to Circular Modules Imports


My folder structure is:

├── Cargo.toml
├── program
│   ├── Cargo.lock
│   ├── Cargo.toml
│   └── src
│       ├── instruction.rs
│       ├── lib.rs
│       ├── mod.rs
│       └── state.rs
├── program.json
└── src
    └── lib.rs

In the /program/src/lib.rs, I want to use instruction.rs and state.rs.

And in the /src/lib.rs (test file), I am trying to call the program lib.rs

The program lib.rs:

use super::instruction::LiquidityInstruction;
use super::state::LiquidityParams;

And the src lib.rs file:

#[path = "../program/src/lib.rs"]
mod lib;

But it is not working.

For example, running the program lib.rs:

use super::state::LiquidityParams;
  | ^^^^^ there are too many leading `super` keywords

If I change the program lib.rs:

#[path = "./mod.rs"]
pub mod instruction;
pub mod state;

use crate::instruction::instruction::LiquidityInstruction;
use crate::state::LiquidityParams;

Getting error:

error: circular modules: src/lib.rs -> src/./mod.rs -> src/lib.rs
 --> src/./mod.rs:2:1
  |
2 | pub mod lib;
  | ^^^^^^^^^^^^

Its getting quite confusing. Can someone help?

I am expecting to call the instruciton.rs (the LiquidityInstruction enum in the file) and the state.rs (the LiquidityParams in the file) in program lib.rs,and call the program lib.rs in the src lib.rs so that I can access lib, state and instruction from the src lib and do necessary testing.


Solution

  • In your root Cargo.toml, create a path dependency to the program's crate:

    [dependencies]
    program = { path = "./program" }
    

    That way your root lib.rs can access it via program like:

    use program::instruction::LiquidityInstruction;
    use program::state::LiquidityParams;
    

    You generally don't want to use a #[path] attribute to pull in files from another crate - it is very likely to cause bad imports due to wrong crate or super directives.


    In your program crate you'll want to get rid of mod.rs and simply declare your modules in lib.rs like so:

    pub mod instruction;
    pub mod state;
    

    That should be all you need to do assuming nothing else is wrong.