UP | HOME

RustLibrary

Organizing a Rust library

First, the tree will look something like this:

ksl/
├── Cargo.toml
├── src/
│   ├── lib.rs      # Declares and re-exports modules publicly
│   ├── ident.rs    # Code for the 'ident' module
│   └── comm.rs     # Code for the 'comm' module

Then, lib.rs will look something like

//! This is the main documentation for the `ksl` library (optional, but
//! good practice).

pub mod ident;  // Makes the 'ident' module public
pub mod comm;   // Makes the 'comm' module public

// Optionally, re-export items for easier access, e.g.:
// pub use ident::SomeStruct;
// pub use comm::some_function;
  • The pub mod lines tell Rust to include these modules and make them accessible to users of your library.
  • Library-level code can be added here if needed (e.g., common traits or enums).

Then, comm.rs might look like

//! Documentation for the `comm` module.

/// An example function for communication.
pub fn send_message(msg: &str) {
    println!("Sending: {}", msg);
}

// more code follows ...

Other code can use this with

use ksl::ident::Identifier;
use ksl::comm::send_message;

let id = Identifier::new("test");
send_message("Hello");

Testing this is done by putting tests at the end of the file:

// in ident.rs
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_identifier() {
        let id = Identifier::new("foo");
        assert_eq!(id.value, "foo");
    }
}

To expand this out, for example if comm expands, you can break it out into a subdirectory. Now you have src/comm/mod.rs, keeping pub mod comm in the top lib.rs.