classDiagram
class Workspace {
+String name
+Array~Crate~ members
}
class Crate {
+String name
+String version
+CrateType type
+String root_file
+Array~Module~ modules
}
class CrateType {
<<enumeration>>
LIBRARY
BINARY
PROC_MACRO
}
class Module {
+String name
+String path
+ModuleDefinition definition_type
+Visibility visibility
+Array~Item~ items
+Array~Module~ submodules
}
class ModuleDefinition {
<<enumeration>>
INLINE
FILE
DIRECTORY
}
class Visibility {
<<enumeration>>
PUBLIC
PRIVATE
CRATE
SUPER
PATH
}
class Item {
+String name
+ItemType type
+Visibility visibility
}
class ItemType {
<<enumeration>>
FUNCTION
STRUCT
ENUM
TRAIT
TYPE_ALIAS
CONSTANT
}
Workspace "1" *-- "many" Crate : contains
Crate "1" *-- "many" Module : defines
Crate -- CrateType : has
Module "1" *-- "many" Module : contains
Module -- ModuleDefinition : defined as
Module -- Visibility : has
Module "1" *-- "many" Item : contains
Item -- ItemType : is a
Item -- Visibility : has
Understanding the Rust Module System Class Diagram
The class diagram represents the Rust module system as a hierarchical structure of related components, each with its own properties and relationships. Here's a breakdown of each element and how they relate to Rust's actual module system:
Core Classes
Workspace
The top-level container in Rust projects, typically containing one or more related crates. This corresponds to a workspace defined in a Cargo.toml file.
Crate
A compilation unit in Rust, which can be a library, binary, or procedural macro. Each crate has its own namespace and internal module structure.
Module
The fundamental organizational unit in Rust code. Modules can contain items and other modules, creating a hierarchy of namespaces.
Item
The actual elements defined inside modules: functions, structs, enums, etc. These are the basic building blocks of Rust code.
Enumeration Classes
CrateType
The possible types a crate can have, affecting how it's compiled and used:
- LIBRARY: A crate that produces a library for others to use
- BINARY: A crate that produces an executable
- PROC_MACRO: A special type of library crate that defines procedural macros
ModuleDefinition
The ways a module can be defined in Rust:
- INLINE: Defined directly in another file using the
modkeyword and curly braces - FILE: Defined in a separate file with the module name
- DIRECTORY: Defined in a directory with a mod.rs file
Visibility
The possible visibility levels for modules and items:
- PUBLIC: Accessible from anywhere (
pub) - PRIVATE: Accessible only within the current module (default)
- CRATE: Accessible within the current crate (
pub(crate)) - SUPER: Accessible in the parent module (
pub(super)) - PATH: Accessible in a specific path (
pub(in path))
ItemType
The kinds of items that can be defined in a module:
- FUNCTION: Code blocks that perform specific tasks
- STRUCT: Custom data types with named fields
- ENUM: Types that can be one of several variants
- TRAIT: Shared behavior across types
- TYPE_ALIAS: Alternative names for existing types
- CONSTANT: Fixed values that cannot change
Relationships
The relationships in the diagram show how these components are connected:
- A Workspace contains many Crates
- A Crate defines many Modules and has a specific CrateType
- A Module can contain many sub-Modules and Items
- A Module is defined using a specific ModuleDefinition method and has a Visibility level
- An Item has a specific ItemType and Visibility level
This structured representation captures both the organizational hierarchy and the key properties that define how Rust's module system works in practice.
Meta representation of code organization as Rust type system
// src/lib.rs - A meta-model of Rust's module system using Rust's own type system
/// Represents a Rust workspace, which is a collection of related crates
pub struct Workspace {
pub name: String,
pub crates: Vec<Crate>,
}
/// The different types of crates in Rust
pub enum CrateType {
Library,
Binary,
ProcMacro,
}
/// Represents a Rust crate, which is a compilation unit
pub struct Crate {
pub name: String,
pub crate_type: CrateType,
pub root_module: Module,
}
/// How a module is defined in Rust source code
pub enum ModuleDefinition {
/// Defined directly in another Rust file with a mod {} block
Inline,
/// Defined in a separate file (module_name.rs)
File,
/// Defined in a directory with a mod.rs file
Directory,
}
/// Visibility levels in Rust
pub enum Visibility {
/// Publicly accessible (pub)
Public,
/// Only accessible within the module (default)
Private,
/// Only accessible within the crate (pub(crate))
Crate,
/// Only accessible in the parent module (pub(super))
Super,
/// Only accessible in a specific path (pub(in path))
Path(String),
}
/// Represents a Rust module, which is a namespace containing items
pub struct Module {
pub name: String,
pub definition: ModuleDefinition,
pub visibility: Visibility,
pub items: Vec<Item>,
pub submodules: Vec<Module>,
}
/// Types of items that can be defined in Rust modules
pub enum ItemType {
Function,
Struct,
Enum,
Trait,
TypeAlias,
Constant,
// Other item types could be added (impl, use, etc.)
}
/// Represents an item defined in a Rust module
pub struct Item {
pub name: String,
pub item_type: ItemType,
pub visibility: Visibility,
}
/// Implementation of core functionality for the workspace
impl Workspace {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
crates: Vec::new(),
}
}
pub fn add_crate(&mut self, crate_item: Crate) {
self.crates.push(crate_item);
}
}
/// Implementation of core functionality for crates
impl Crate {
pub fn new(name: &str, crate_type: CrateType) -> Self {
// Create a root module based on crate type
let root_module_name = match crate_type {
CrateType::Library | CrateType::ProcMacro => "lib",
CrateType::Binary => "main",
};
Self {
name: name.to_string(),
crate_type,
root_module: Module {
name: root_module_name.to_string(),
definition: ModuleDefinition::File,
visibility: Visibility::Private, // Root modules don't have visibility modifiers
items: Vec::new(),
submodules: Vec::new(),
},
}
}
}
/// Implementation of core functionality for modules
impl Module {
pub fn new(name: &str, definition: ModuleDefinition, visibility: Visibility) -> Self {
Self {
name: name.to_string(),
definition,
visibility,
items: Vec::new(),
submodules: Vec::new(),
}
}
pub fn add_submodule(&mut self, module: Module) {
self.submodules.push(module);
}
pub fn add_item(&mut self, item: Item) {
self.items.push(item);
}
}
/// Implementation of core functionality for items
impl Item {
pub fn new(name: &str, item_type: ItemType, visibility: Visibility) -> Self {
Self {
name: name.to_string(),
item_type,
visibility,
}
}
}
// Example usage to model a simple Rust project
pub fn build_example_project() -> Workspace {
let mut workspace = Workspace::new("example_workspace");
// Create a library crate
let mut lib_crate = Crate::new("example_lib", CrateType::Library);
// Add a module to the library crate
let mut module_a = Module::new("module_a", ModuleDefinition::File, Visibility::Public);
// Add items to module_a
module_a.add_item(Item::new("ExampleStruct", ItemType::Struct, Visibility::Public));
module_a.add_item(Item::new("example_function", ItemType::Function, Visibility::Public));
// Add a submodule to module_a
let mut submodule = Module::new(
"submodule",
ModuleDefinition::Directory,
Visibility::Public
);
// Add items to the submodule
submodule.add_item(Item::new("SubStruct", ItemType::Struct, Visibility::Public));
// Add the submodule to module_a
module_a.add_submodule(submodule);
// Add module_a to the lib crate's root module
lib_crate.root_module.add_submodule(module_a);
// Add a binary crate to the workspace
let bin_crate = Crate::new("example_bin", CrateType::Binary);
// Add both crates to the workspace
workspace.add_crate(lib_crate);
workspace.add_crate(bin_crate);
workspace
}