Search code examples
rustpathsubdirectory

Linking paths to libraries on Rust


Given the structure

.
├── Cargo.toml
├── readme.txt
├── src
│   ├── config.rs
│   ├── libraries
│   │   ├──> cryptography::primitives::cipher::symmetric::aes::aes_agent as 
│   ├── main.rs
│   └── header.rs

In main.rs:

use libraries::cryptography::primitives::cipher::symmetric::aes::aes_agent as aes_cipher;

mod libraries {
    pub mod cryptography {
      pub mod primitives {
        pub mod cipher {
          pub mod symmetric {
            pub mod aes {
                pub mod aes_agent;
            }
          }
        }
      }
    }
}

mod header;


fn main() {
    let _ = &aes_cipher::print_me();

    println!("Hello, world in main!");
}

however, it does not work in header.rs, giving the error:

Compiling lab_00 v0.1.0 (/home/runner/HelloRust)
error[E0583]: file not found for module aes_agent
 --> src/header.rs:9:17
  |
9 |                 pub mod aes_agent;
  |                 ^^^^^^^^^^^^^^^^^^
  |

The lib code is in libraries/cryptography/primitives/cipher/symmetric/aes/aes_agent. It can be called from main.rs. However, it can't be done in header.rs.

Is there a better means to link the path other than the chunk as shown?


Solution

  • I'll assume you have good reasons for having such a deeply nested singular .rs file.

    You should only have one mod <name>; declaration per <name>.rs file you want to use, so if you have mod aes_agent; in your main.rs, then there should not be a mod aes_agent; in your headers.rs because its already declared in main.rs. Since its already declared, you simply use it:

    // headers.rs
    use crate::libraries::cryptography::primitives::cipher::symmetric::aes::aes_agent;
    //  ^^^^^^^ searching for modules starting from the crate root, which is `main.rs`
    

    Additionally, this is probably a good use of the #[path] attribute. With it you can declare a module by file path directly rather than constructing a module hierarchy to reflect the file hierarchy. In general I heavily advise against using this attribute, but this case may warrant it. It would look like this:

    // main.rs
    #[path = "libraries/cryptography/primitives/cipher/symmetric/aes/aes_agent.rs"]
    mod aes_agent;
    

    The rule above for one mod still apply, but this would make your use from headers.rs much simpler as well: use crate::aes_agent;.