Introduction to the Composite Pattern in Rust

Introduction

Welcome to the second lesson of our "Structural Patterns in Rust" course! 🎉 In our previous lesson, we explored the Adapter Pattern, which helps incompatible interfaces work together seamlessly. Today, we'll dive into another fundamental structural pattern: the Composite Pattern.

The Composite Pattern enables us to build complex structures by composing objects into tree-like hierarchies representing part-whole relationships. This pattern allows us to treat individual objects and compositions of objects uniformly. It's particularly useful in scenarios like file systems, where directories contain files and other directories, forming a nested structure. Let's explore how to implement this pattern in Rust using a file system example.

Understanding the Composite Pattern

Imagine a file system where directories can contain both files and other directories. This structure naturally forms a tree, with directories acting as composite nodes that can hold leaf nodes (files) or other composite nodes (directories).

Here's how such a file system hierarchy might look:

root
├── file1.txt
├── file2.txt
└── sub_dir
    ├── file3.txt
    └── nested_dir
        └── file4.txt

In this example:

  • Files (Leaf Nodes): Individual files like file1.txt, file2.txt, file3.txt, and file4.txt are the indivisible elements of the hierarchy.
  • Directories (Composite Nodes): Directories like root, sub_dir, and nested_dir can contain files and other directories, allowing us to build a nested, hierarchical structure.

Defining the `FileSystem` Trait

To model this structure in Rust, we start by defining a trait that provides a common interface for both files and directories:

// The FileSystem trait - defines common operations for composite and leaf nodes
pub trait FileSystem {
    fn display(&self, depth: usize);
    fn get_name(&self) -> &str;
}

The FileSystem trait declares two methods:

  • display: Used to print the structure. The depth parameter helps us represent the hierarchy when printing: each level of depth increases the indentation, making it clear which files or directories are nested within others.
  • get_name: Returns the name of the file or directory, useful for operations like removing entries.

Creating Individual Components: The `File` Struct

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal