### Run Design Pattern Examples with Cargo Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Demonstrates how to execute individual design pattern examples using Cargo. Each pattern is compiled as a separate binary. Ensure Cargo is installed and the repository is cloned. ```bash # Run any pattern example cargo run --bin strategy cargo run --bin observer cargo run --bin builder cargo run --bin adapter cargo run --bin singleton-lazy # Each pattern has its own Cargo.toml defining the binary # [[bin]] # name = "adapter" # path = "main.rs" ``` -------------------------------- ### Run Visitor Example (Bash) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/visitor/README.md Command to execute the Visitor design pattern example using Cargo. This command builds and runs the binary located in the 'visitor' directory. ```bash cargo run --bin visitor ``` -------------------------------- ### Run Command Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/command/README.md Command-line instruction to execute the provided Rust example project. This assumes the environment is configured with Cargo. ```bash cargo run --bin command ``` -------------------------------- ### Execute Strategy Pattern Examples Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/strategy/README.md Commands to run the conceptual and functional implementations of the Strategy pattern provided in the project. ```bash cargo run --bin strategy ``` ```bash cargo run --bin strategy-func ``` -------------------------------- ### State Transition Example: Stopped to Playing Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Demonstrates the `play` method implementation for `StoppedState`. When called, it starts playback and transitions the player to the `PlayingState`. ```rust fn play(self: Box, player: &mut Player) -> Box { player.play(); // Stopped -> Playing. Box::new(PlayingState) } ``` -------------------------------- ### Run Simple Factory project Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/simple-factory/README.md Command to execute the Simple Factory example using the Rust cargo build tool. ```bash cargo run --bin simple-factory ``` -------------------------------- ### Run Mediator Rc> Example (Bash) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/mediator/README.md Commands to execute the 'mediator-rc-refcell' binary for the Mediator pattern example. This demonstrates the use of Rc> for managing shared mutable state. ```bash cargo run --bin mediator-rc-refcell ``` -------------------------------- ### Run Builder Pattern Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/builder/README.md Command-line instruction to execute the Rust implementation of the Builder design pattern using Cargo. ```bash cargo run --bin builder ``` -------------------------------- ### Execute Facade Pattern Example in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/facade/README.md This command compiles and runs the Rust implementation of the Facade pattern. It demonstrates the interaction between the facade and the underlying complex system components. ```bash cargo run --bin facade ``` -------------------------------- ### Run Flyweight Forest Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/flyweight/README.md Command to execute the Rust Flyweight pattern demonstration using Cargo. This compiles and runs the forest rendering simulation. ```bash cargo run --release ``` -------------------------------- ### Execute Rust project Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/iterator/README.md Command to run the iterator design pattern example using the Cargo build system. ```bash cargo run --bin iterator ``` -------------------------------- ### Run Mediator Pattern Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/mediator/mediator-top-down/README.md Command to execute the mediator pattern implementation using Cargo. ```bash cargo run --bin mediator-top-down ``` -------------------------------- ### Execute Decorator Pattern Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/decorator/README.md Command to compile and run the decorator pattern project using the Cargo build system. ```bash cargo run --bin decorator ``` -------------------------------- ### Execute Memento Examples via Cargo Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/memento/README.md Provides the command-line instructions to run the conceptual and Serde-based Memento pattern implementations using the Rust Cargo build tool. ```bash cargo run --bin memento ``` ```bash cargo run --bin memento-serde ``` -------------------------------- ### State Transition Example: Playing to Paused Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Shows the `play` method implementation for `PlayingState`. If the 'play' button is pressed again while playing, it pauses playback and transitions to the `PausedState`. ```rust fn play(self: Box, player: &mut Player) -> Box { player.pause(); // Playing -> Paused. Box::new(PausedState) } ``` -------------------------------- ### Adapter Pattern: Running the Rust Example (Bash) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/adapter/README.md Provides the command to compile and run the Rust program that implements the Adapter design pattern. This is a standard Cargo command for executing binary targets within a Rust project. ```bash cargo run --bin adapter ``` -------------------------------- ### Executing the Chain of Responsibility Example Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/chain-of-responsibility/README.md Command to compile and run the Chain of Responsibility demonstration project using the Cargo build tool. ```bash cargo run --bin chain-of-responsibility ``` -------------------------------- ### Bridge Pattern in Rust (Remote Control Example) Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Implements the Bridge pattern in Rust, decoupling an abstraction from its implementation. This example uses `Device` and `Remote` traits to separate remote control functionalities from different device types like TV and Radio. ```rust pub trait Device { fn is_enabled(&self) -> bool; fn enable(&mut self); fn disable(&mut self); fn volume(&self) -> u8; fn set_volume(&mut self, percent: u8); fn channel(&self) -> u16; fn set_channel(&mut self, channel: u16); fn print_status(&self); } pub trait HasMutableDevice { fn device(&mut self) -> &mut D; } pub trait Remote: HasMutableDevice { fn power(&mut self) { println!("Remote: power toggle"); if self.device().is_enabled() { self.device().disable(); } else { self.device().enable(); } } fn volume_down(&mut self) { println!("Remote: volume down"); let volume = self.device().volume(); self.device().set_volume(volume - 10); } fn volume_up(&mut self) { println!("Remote: volume up"); let volume = self.device().volume(); self.device().set_volume(volume + 10); } } fn test_device(device: impl Device + Clone) { println!("Tests with basic remote."); let mut basic_remote = BasicRemote::new(device.clone()); basic_remote.power(); basic_remote.device().print_status(); println!("Tests with advanced remote."); let mut advanced_remote = AdvancedRemote::new(device); advanced_remote.power(); advanced_remote.mute(); advanced_remote.device().print_status(); } fn main() { test_device(Tv::default()); test_device(Radio::default()); } ``` -------------------------------- ### Singleton Pattern in Rust (Logger Example) Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Demonstrates the Singleton pattern in Rust for a simple logger. It uses `lazy_static` or `once_cell` implicitly through crate usage to ensure a single instance of the logger is available globally. ```rust use crate::log::{self, Level, Log}; struct SimpleLogger { max_level: Level, } impl Log for SimpleLogger { fn enabled(&self, level: &Level) -> bool { *level <= self.max_level } fn log(&self, level: &Level, message: &str) { println!("[{}] {}", level, message); } } pub fn init(max_level: Level) { log::set_boxed_logger(Box::new(SimpleLogger { max_level })) .expect("Logger has been already set"); } fn main() { info("This log is not going to be displayed"); simple_logger::init(Level::Info); app::run(); // Now logging works } ``` -------------------------------- ### Strategy Pattern Implementation in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Implements the Strategy pattern in Rust using traits for static dispatch. This allows for interchangeable algorithms (strategies) to be selected at compile time. The example demonstrates different routing strategies for a navigator. ```rust /// Defines an injectable strategy for building routes. trait RouteStrategy { fn build_route(&self, from: &str, to: &str); } struct WalkingStrategy; impl RouteStrategy for WalkingStrategy { fn build_route(&self, from: &str, to: &str) { println!("Walking route from {} to {}: 4 km, 30 min", from, to); } } struct PublicTransportStrategy; impl RouteStrategy for PublicTransportStrategy { fn build_route(&self, from: &str, to: &str) { println!("Public transport route from {} to {}: 3 km, 5 min", from, to); } } struct Navigator { route_strategy: T, } impl Navigator { pub fn new(route_strategy: T) -> Self { Self { route_strategy } } pub fn route(&self, from: &str, to: &str) { self.route_strategy.build_route(from, to); } } fn main() { let navigator = Navigator::new(WalkingStrategy); navigator.route("Home", "Club"); navigator.route("Club", "Work"); let navigator = Navigator::new(PublicTransportStrategy); navigator.route("Home", "Club"); navigator.route("Club", "Work"); } // Output: // Walking route from Home to Club: 4 km, 30 min // Walking route from Club to Work: 4 km, 30 min // Public transport route from Home to Club: 3 km, 5 min // Public transport route from Club to Work: 3 km, 5 min ``` -------------------------------- ### Implement Proxy Pattern for Rate Limiting in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Proxy pattern acts as a surrogate for an object to control access. This example demonstrates an Nginx-like server that enforces rate limiting on requests before delegating to the application. ```rust pub trait Server { fn handle_request(&mut self, url: &str, method: &str) -> (u16, String); } pub struct NginxServer { application: Application, max_allowed_requests: u32, rate_limiter: HashMap, } impl NginxServer { pub fn new() -> Self { Self { application: Application, max_allowed_requests: 2, rate_limiter: HashMap::default(), } } pub fn check_rate_limiting(&mut self, url: &str) -> bool { let rate = self.rate_limiter.entry(url.to_string()).or_insert(1); if *rate > self.max_allowed_requests { return false; } *rate += 1; true } } impl Server for NginxServer { fn handle_request(&mut self, url: &str, method: &str) -> (u16, String) { if !self.check_rate_limiting(url) { return (403, "Not Allowed".into()); } self.application.handle_request(url, method) } } ``` -------------------------------- ### Adapter Pattern: Expected Execution Output (Text) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/adapter/README.md Displays the expected output when the Rust Adapter pattern example is executed. This output highlights the successful direct call, the incompatible adaptee's reversed output, and the adapter's successful adaptation. ```text A compatible target can be directly called: 'Ordinary request.' Adaptee is incompatible with client: '.tseuqer cificepS' But with adapter client can call its method: 'Specific request.' ``` -------------------------------- ### Implement Command Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Command pattern encapsulates requests as objects, allowing for parameterization and undoable operations. This example uses a trait to define execution and undo logic within a Cursive application context. ```rust pub trait Command { fn execute(&mut self, app: &mut cursive::Cursive) -> bool; fn undo(&mut self, app: &mut cursive::Cursive); } pub struct CopyCommand; impl Command for CopyCommand { fn execute(&mut self, app: &mut cursive::Cursive) -> bool { true } fn undo(&mut self, app: &mut cursive::Cursive) {} } ``` -------------------------------- ### Implement Decorator Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Decorator pattern attaches additional responsibilities to objects dynamically. This example demonstrates using Rust's standard library BufReader to wrap a data source, adding buffering capabilities. ```rust use std::io::{BufReader, Cursor, Read}; fn main() { let mut buf = [0u8; 10]; let mut input = BufReader::new(Cursor::new("Input data")); input.read(&mut buf).ok(); print!("Read from a buffered reader: "); for byte in buf { print!("{}", char::from(byte)); } println!(); } ``` -------------------------------- ### Rust Example: Train Station Mediator and Component Interaction Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/mediator/README.md Illustrates the instantiation and interaction of `PassengerTrain` and `FreightTrain` components with a `TrainStation` mediator in Rust. The `TrainStation` takes ownership of the trains via its `accept` method and manages departures using train names. This demonstrates the top-down ownership model. ```rust let train1 = PassengerTrain::new("Train 1"); let train2 = FreightTrain::new("Train 2"); // Station has `accept` and `depart` methods, // but it also implements `Mediator`. let mut station = TrainStation::default(); // Station is taking ownership of the trains. station.accept(train1); station.accept(train2); // `train1` and `train2` have been moved inside, // but we can use train names to depart them. station.depart("Train 1"); station.depart("Train 2"); station.depart("Train 3"); ``` -------------------------------- ### Singleton with Local Variables (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/singleton/how-to-create/README.md Implements a Singleton pattern by avoiding global variables and passing state through function arguments. The object is created at the start of the `main` function. ```rust struct SingletonLocal { value: i32, } impl SingletonLocal { fn new() -> Self { println!("Initializing SingletonLocal..."); SingletonLocal { value: 1 } } fn get_value(&self) -> i32 { self.value } } fn main() { let singleton = SingletonLocal::new(); println!("Final state: {}", singleton.get_value()); } ``` -------------------------------- ### Implement Abstract Factory Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Abstract Factory pattern provides an interface for creating families of related objects. This example shows both static dispatch using associated types and dynamic dispatch using trait objects. ```rust pub trait Button { fn press(&self); } pub trait Checkbox { fn switch(&self); } pub trait GuiFactory { type B: Button; type C: Checkbox; fn create_button(&self) -> Self::B; fn create_checkbox(&self) -> Self::C; } pub trait GuiFactoryDynamic { fn create_button(&self) -> Box; fn create_checkbox(&self) -> Box; } ``` -------------------------------- ### Implement Flyweight Pattern for Memory Optimization in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Flyweight pattern reduces memory usage by sharing common object state. This example demonstrates rendering a large forest by sharing tree type data across many tree instances. ```rust const CANVAS_SIZE: u32 = 500; const TREES_TO_DRAW: u32 = 100000; const TREE_TYPES: u32 = 2; fn main() { let forest = &mut Forest::default(); for _ in 0..TREES_TO_DRAW / TREE_TYPES { let mut rng = rand::thread_rng(); forest.plant_tree( rng.gen_range(0..CANVAS_SIZE), rng.gen_range(0..CANVAS_SIZE), TreeColor::Color1, "Summer Oak".into(), "Oak texture stub".into(), ); } let mut canvas = Canvas::new(CANVAS_SIZE, CANVAS_SIZE); forest.draw(&mut canvas); } ``` -------------------------------- ### Music Player State Initialization and Transitions Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Provides a sequence of code demonstrating how to initialize a player in the `StoppedState` and then trigger state transitions using the `play` method. ```rust let state = Box::new(StoppedState); // StoppedState. let state = state.play(&mut player); // StoppedState -> PlayingState. let state = state.play(&mut player); // PlayingState -> PausedState. ``` -------------------------------- ### Adapter Pattern: Instantiating and Using the Adapter (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/adapter/README.md Shows the practical application of the Adapter pattern. It illustrates how an incompatible `specific_target` is wrapped by `TargetAdapter` to conform to the `Target` trait, allowing it to be used with the `call` function. ```rust let target = TargetAdapter::new(specific_target); call(target); ``` -------------------------------- ### Custom `new()` Method for Parameterized Object Creation in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/static-creation-method/README.md Illustrates how to define a custom `new()` associated function within an `impl` block to create a new object instance with specific parameters. This is a common way to handle custom object initialization in Rust. ```rust impl Rectangle { pub fn new(width: u32, length: u32) -> Rectangle { Self { width, length } } } let rectangle = Rectangle::new(10, 20); ``` -------------------------------- ### Default Trait for No-Parameter Construction in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/static-creation-method/README.md Demonstrates using the `Default` trait to create a new object instance without any parameters. This is achieved either by deriving `Default` or manually implementing the trait. ```rust #[derive(Default)] struct Circle; let circle = Circle::default(); ``` -------------------------------- ### Implement Memento with Serde Serialization in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/memento/README.md Demonstrates how to use the Serde framework to derive Serialize and Deserialize traits for an Originator struct. This approach allows for easy state persistence and restoration by converting objects into formats like JSON. ```rust use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Originator { state: u32, } ``` -------------------------------- ### Singleton with lazy_static (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/singleton/how-to-create/README.md Demonstrates the Singleton pattern using the `lazy_static!` macro for lazy initialization. This approach initializes the static variable upon its first access. ```rust use lazy_static::lazy_static; use std::sync::Mutex; lazy_static! { static ref LAZY_SINGLETON: Mutex = { println!("Initializing LAZY_SINGLETON..."); Mutex::new(0) }; } fn increment_lazy_singleton() { let mut num = LAZY_SINGLETON.lock().unwrap(); *num += 1; println!("Called {}", *num); } fn main() { increment_lazy_singleton(); increment_lazy_singleton(); increment_lazy_singleton(); } ``` -------------------------------- ### Singleton with Mutex (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/singleton/how-to-create/README.md Demonstrates using a global static `Mutex` for a mutable singleton, available since Rust 1.63. This approach allows for `const` initialization of the `Mutex`. ```rust use std::sync::Mutex; static GLOBAL_DATA: Mutex> = Mutex::new(Vec::new()); fn add_to_global(val: i32) { GLOBAL_DATA.lock().unwrap().push(val); } fn main() { for i in 0..3 { add_to_global(1); } println!("Called 3 times: {:?}", GLOBAL_DATA.lock().unwrap()); let mut data = GLOBAL_DATA.lock().unwrap(); data.clear(); data.push(3); data.push(4); data.push(5); println!("New singleton object: {:?}", *data); } ``` -------------------------------- ### Traverse standard collections with Iterators Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/iterator/README.md Demonstrates the idiomatic way to traverse a standard array in Rust using the iter() method and the for_each consumer. ```rust let array = &[1, 2, 3]; let iterator = array.iter(); // Traversal over each element of the vector. iterator.for_each(|e| print!("{}, ", e)); ``` -------------------------------- ### Default State Transitions in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Provides default implementations for `next` and `prev` methods on the `dyn State` trait object. These methods do not change the state and are not intended to be overridden by concrete state types. ```rust impl dyn State { pub fn next(self: Box, player: &mut Player) -> Box { self } pub fn prev(self: Box, player: &mut Player) -> Box { self } } ``` -------------------------------- ### Implement Facade Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Facade pattern provides a simplified interface to a complex set of subsystems. The WalletFacade class encapsulates multiple internal components like Account, SecurityCode, and Ledger to provide a clean API for financial transactions. ```rust pub struct WalletFacade { account: Account, wallet: Wallet, code: SecurityCode, notification: Notification, ledger: Ledger, } impl WalletFacade { pub fn new(account_id: String, code: u32) -> Self { println!("Starting create account"); let this = Self { account: Account::new(account_id), wallet: Wallet::new(), code: SecurityCode::new(code), notification: Notification, ledger: Ledger, }; println!("Account created"); this } pub fn add_money_to_wallet( &mut self, account_id: &String, security_code: u32, amount: u32, ) -> Result<(), String> { println!("Starting add money to wallet"); self.account.check(account_id)?; self.code.check(security_code)?; self.wallet.credit_balance(amount); self.notification.send_wallet_credit_notification(); self.ledger.make_entry(account_id, "credit".into(), amount); Ok(()) } pub fn deduct_money_from_wallet( &mut self, account_id: &String, security_code: u32, amount: u32, ) -> Result<(), String> { println!("Starting debit money from wallet"); self.account.check(account_id)?; self.code.check(security_code)?; self.wallet.debit_balance(amount); self.notification.send_wallet_debit_notification(); self.ledger.make_entry(account_id, "debit".into(), amount); Ok(()) } } fn main() -> Result<(), String> { let mut wallet = WalletFacade::new("abc".into(), 1234); println!(); wallet.add_money_to_wallet(&"abc".into(), 1234, 10)?; println!(); wallet.deduct_money_from_wallet(&"abc".into(), 1234, 5) } ``` -------------------------------- ### Create objects using Simple Factory in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/simple-factory/README.md Demonstrates a factory function that returns a trait object based on a conditional check. This pattern separates the instantiation logic from the object's usage. ```rust fn create_button(random_number: f64) -> Box { if random_number < 0.5 { Box::new(TitleButton::new("Button".to_string())) } else { Box::new(IdButton::new(123)) } } ``` ```rust fn render_dialog(random_number: f64) { // ... let button = create_button(random_number); button.render(); // ... ``` -------------------------------- ### Template Method Pattern in Rust: Algorithm Skeleton Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Demonstrates the Template Method pattern in Rust, defining an algorithm's skeleton in a trait while allowing subclasses to override specific steps. It includes base operations, hooks, and required operations that concrete implementations must provide. ```rust trait TemplateMethod { fn template_method(&self) { self.base_operation1(); self.required_operations1(); self.base_operation2(); self.hook1(); self.required_operations2(); self.base_operation3(); self.hook2(); } fn base_operation1(&self) { println!("TemplateMethod says: I am doing the bulk of the work"); } fn base_operation2(&self) { println!("TemplateMethod says: But I let subclasses override some operations"); } fn base_operation3(&self) { println!("TemplateMethod says: But I am doing the bulk of the work anyway"); } // Optional hooks with default empty implementation fn hook1(&self) {} fn hook2(&self) {} // Required operations that subclasses must implement fn required_operations1(&self); fn required_operations2(&self); } struct ConcreteStruct1; impl TemplateMethod for ConcreteStruct1 { fn required_operations1(&self) { println!("ConcreteStruct1 says: Implemented Operation1") } fn required_operations2(&self) { println!("ConcreteStruct1 says: Implemented Operation2") } } struct ConcreteStruct2; impl TemplateMethod for ConcreteStruct2 { fn required_operations1(&self) { println!("ConcreteStruct2 says: Implemented Operation1") } fn required_operations2(&self) { println!("ConcreteStruct2 says: Implemented Operation2") } } fn client_code(concrete: impl TemplateMethod) { concrete.template_method() } fn main() { println!("Same client code can work with different concrete implementations:"); client_code(ConcreteStruct1); println!(); client_code(ConcreteStruct2); } ``` -------------------------------- ### Concrete State Implementations in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Illustrates the structure for concrete state types like `StoppedState`, `PausedState`, and `PlayingState`. Each concrete state implements the `State` trait to define its behavior and transitions. ```rust pub struct StoppedState; pub struct PausedState; pub struct PlayingState; impl State for StoppedState { // ... implementation ... } impl State for PausedState { // ... implementation ... } impl State for PlayingState { // ... implementation ... } ``` -------------------------------- ### Observer Pattern in Rust: Event Subscription System Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Implements the Observer pattern using a Publisher and Subscriber model in Rust. It allows objects to subscribe to events and be notified when those events occur. Dependencies include `std::collections::HashMap`. It takes an `Event` enum and a `Subscriber` function pointer, and notifies subscribers with a file path. ```rust use std::collections::HashMap; /// An event type. #[derive(PartialEq, Eq, Hash, Clone)] pub enum Event { Load, Save, } /// A subscriber (listener) has type of a callable function. pub type Subscriber = fn(file_path: String); /// Publisher sends events to subscribers (listeners). #[derive(Default)] pub struct Publisher { events: HashMap>, } impl Publisher { pub fn subscribe(&mut self, event_type: Event, listener: Subscriber) { self.events.entry(event_type.clone()).or_default(); self.events.get_mut(&event_type).unwrap().push(listener); } pub fn unsubscribe(&mut self, event_type: Event, listener: Subscriber) { self.events .get_mut(&event_type) .unwrap() .retain(|&x| x != listener); } pub fn notify(&self, event_type: Event, file_path: String) { let listeners = self.events.get(&event_type).unwrap(); for listener in listeners { listener(file_path.clone()); } } } /// Editor has its own logic and utilizes a publisher for events. #[derive(Default)] pub struct Editor { publisher: Publisher, file_path: String, } impl Editor { pub fn events(&mut self) -> &mut Publisher { &mut self.publisher } pub fn load(&mut self, path: String) { self.file_path = path.clone(); self.publisher.notify(Event::Load, path); } pub fn save(&self) { self.publisher.notify(Event::Save, self.file_path.clone()); } } fn save_listener(file_path: String) { let email = "admin@example.com".to_string(); println!("Email to {}: Save file {}", email, file_path); } fn main() { let mut editor = Editor::default(); editor.events().subscribe(Event::Load, |file_path| { let log = "/path/to/log/file.txt".to_string(); println!("Save log to {}: Load file {}", log, file_path); }); editor.events().subscribe(Event::Save, save_listener); editor.load("test1.txt".into()); editor.load("test2.txt".into()); editor.save(); editor.events().unsubscribe(Event::Save, save_listener); editor.save(); // No email notification after unsubscribe } // Output: // Save log to /path/to/log/file.txt: Load file test1.txt // Save log to /path/to/log/file.txt: Load file test2.txt // Email to admin@example.com: Save file test2.txt ``` -------------------------------- ### Implement Strategy via Iterators Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/strategy/README.md Demonstrates how Rust's iterator methods like filter act as an implicit implementation of the Strategy pattern by injecting logic into a collection pipeline. ```rust let a = [0i32, 1, 2]; let mut iter = a.iter().filter(|x| x.is_positive()); ``` -------------------------------- ### Implement Mediator Ownership and Interaction in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/mediator/mediator-top-down/README.md Demonstrates how the TrainStation mediator takes ownership of train components and manages their lifecycle through external API calls. ```rust let train1 = PassengerTrain::new("Train 1"); let train2 = FreightTrain::new("Train 2"); let mut station = TrainStation::default(); station.accept(train1); station.accept(train2); station.depart("Train 1"); station.depart("Train 2"); station.depart("Train 3"); ``` -------------------------------- ### Visitor Pattern in Rust: Algorithm Separation Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Demonstrates the Visitor pattern in Rust, enabling the addition of new operations to existing object structures without modification. It uses a `Visitor` trait with associated types and methods like `visit_vec`. Implementations like `TwoValuesStruct` and `TwoValuesArray` show how to process data and return specific types. ```rust /// Visitor can visit one type, do conversions, and output another type. pub trait Visitor { type Value; /// Visits a vector of integers and outputs a desired type. fn visit_vec(&self, v: Vec) -> Self::Value; } pub struct TwoValuesStruct { pub a: i32, pub b: i32, } pub struct TwoValuesArray { pub ab: [i32; 2], } /// Visitor implementation for a struct of two values. impl Visitor for TwoValuesStruct { type Value = TwoValuesStruct; fn visit_vec(&self, v: Vec) -> Self::Value { TwoValuesStruct { a: v[0], b: v[1] } } } /// Visitor implementation for a struct of values array. impl Visitor for TwoValuesArray { type Value = TwoValuesArray; fn visit_vec(&self, v: Vec) -> Self::Value { let mut ab = [0i32; 2]; ab[0] = v[0]; ab[1] = v[1]; TwoValuesArray { ab } } } ``` -------------------------------- ### Adapter Pattern: Client Call with Target Interface (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/adapter/README.md Demonstrates how a client function `call` expects a `Target` trait. This function is central to showcasing the adapter's role in enabling collaboration between incompatible interfaces. ```rust fn call(target: impl Target); ``` -------------------------------- ### Implement Buffered Reading with Decorator Pattern Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/decorator/README.md This snippet demonstrates the Decorator pattern by wrapping a Cursor with a BufReader. It enables buffered input operations on a data source. ```rust use std::io::{BufReader, Cursor, Read}; let mut buf = [0; 10]; let mut input = BufReader::new(Cursor::new("Input data")); input.read(&mut buf).ok(); ``` -------------------------------- ### Define Command Interface in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/command/README.md Defines the signature for a command execution method. It requires the application context to be passed as a mutable parameter to maintain ownership safety and avoid global state. ```rust fn execute(&mut self, app: &mut cursive::Cursive) -> bool; ``` -------------------------------- ### Singleton with OnceCell (Rust) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/singleton/how-to-create/README.md Implements the Singleton pattern using `once_cell::sync::OnceCell`. This allows for custom initialization at an arbitrary place in the code, unlike `lazy_static!`. ```rust use once_cell::sync::OnceCell; use std::sync::Mutex; static ONCE_SINGLETON: OnceCell>> = OnceCell::new(); fn get_once_singleton() -> &'static Mutex> { ONCE_SINGLETON.get_or_init(|| { println!("Initializing ONCE_SINGLETON..."); Mutex::new(vec![42]) }) } fn main() { let singleton1 = get_once_singleton(); singleton1.lock().unwrap().push(1); println!("{:?}", singleton1.lock().unwrap()); let singleton2 = get_once_singleton(); singleton2.lock().unwrap().push(1); println!("{:?}", singleton2.lock().unwrap()); let singleton3 = get_once_singleton(); singleton3.lock().unwrap().push(1); println!("{:?}", singleton3.lock().unwrap()); } ``` -------------------------------- ### Define Forest API and Internal Cache Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/structural/flyweight/README.md Rust implementation of the Forest structure using a HashSet for caching shared TreeKind objects. It utilizes Rc for memory-efficient reference counting of shared data. ```rust pub fn plant_tree(&mut self, x: u32, y: u32, color: TreeColor, name: String, data: String); #[derive(Default)] pub struct Forest { cache: HashSet>, trees: Vec, } ``` -------------------------------- ### Constructing a Chain of Responsibility with Box Pointers in Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/chain-of-responsibility/README.md Demonstrates how to use Box pointers to link handlers in a chain. This approach avoids the complexity of deep generic type nesting by enabling dynamic dispatch at runtime. ```rust let mut reception = Reception::new(doctor); let mut reception = Reception::new(cashier); ``` -------------------------------- ### Define State Trait for Music Player Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/state/README.md Defines the base `State` trait with `play` and `stop` methods for state transitions in a music player. It uses `Box` to consume the current state and return a new state. ```rust pub trait State { fn play(self: Box, player: &mut Player) -> Box; fn stop(self: Box, player: &mut Player) -> Box; } ``` -------------------------------- ### Mediator Pattern Pseudo-code (Java) Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/mediator/README.md A pseudo-code representation of a typical Mediator implementation in object-oriented languages like Java. It shows how components hold references to a controller and vice versa. ```java Controller controller = new Controller(); // Every component has a link to a mediator (controller). component1.setController(controller); component2.setController(controller); component3.setController(controller); // A mediator has a link to every object. controller.add(component1); controller.add(component2); controller.add(component2); ``` -------------------------------- ### Adapter Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Implements the Adapter pattern in Rust, allowing objects with incompatible interfaces to collaborate. It defines a `Target` trait and uses an `TargetAdapter` to convert the interface of a `SpecificTarget` (adaptee) to match the `Target` trait. ```rust pub trait Target { fn request(&self) -> String; } pub struct OrdinaryTarget; impl Target for OrdinaryTarget { fn request(&self) -> String { "Ordinary request.".into() } } // Adaptee has an incompatible interface pub struct SpecificTarget; impl SpecificTarget { pub fn specific_request(&self) -> String { ".eetpadA eht fo roivaheb laicepS".into() } } /// Converts adaptee's specific interface to a compatible `Target` output. pub struct TargetAdapter { adaptee: SpecificTarget, } impl TargetAdapter { pub fn new(adaptee: SpecificTarget) -> Self { Self { adaptee } } } impl Target for TargetAdapter { fn request(&self) -> String { // Adaptation: reverse the specific output to make it compatible self.adaptee.specific_request().chars().rev().collect() } } fn call(target: impl Target) { println!("'{}'", target.request()); } fn main() { let target = OrdinaryTarget; print!("A compatible target can be directly called: "); call(target); let adaptee = SpecificTarget; println!("Adaptee is incompatible: '{}'", adaptee.specific_request()); let adapter = TargetAdapter::new(adaptee); print!("But with adapter client can call its method: "); call(adapter); } // Output: // A compatible target can be directly called: 'Ordinary request.' // Adaptee is incompatible: '.eetpadA eht fo roivaheb laicepS' // But with adapter client can call its method: 'Special behavior of the Adapter.' ``` -------------------------------- ### Prototype Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Implements the Prototype pattern in Rust using the `Clone` trait to create new objects by copying existing ones. Demonstrates cloning a `Circle` struct and modifying the copy. ```rust #[derive(Clone)] struct Circle { pub x: u32, pub y: u32, pub radius: u32, } fn main() { let circle1 = Circle { x: 10, y: 15, radius: 10, }; // Prototype in action - clone the object let mut circle2 = circle1.clone(); circle2.radius = 77; println!("Circle 1: {}, {}, {}", circle1.x, circle1.y, circle1.radius); println!("Circle 2: {}, {}, {}", circle2.x, circle2.y, circle2.radius); } // Output: // Circle 1: 10, 15, 10 // Circle 2: 10, 15, 77 ``` -------------------------------- ### Implement custom Iterator trait Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/behavioral/iterator/README.md Shows how to define a custom iterator by implementing the Iterator trait. The mandatory next() method allows access to standard iterator adapters like map and fold. ```rust let users = UserCollection::new(); let mut iterator = users.iter(); iterator.next(); ``` ```rust impl Iterator for UserIterator<'_> { fn next(&mut self) -> Option; } ``` -------------------------------- ### Implement Factory Method Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Factory Method pattern defines an interface for creating objects, allowing subclasses to alter the type of objects that will be created. It utilizes trait methods to delegate instantiation to concrete implementations. ```rust pub trait Button { fn render(&self); fn on_click(&self); } pub trait Dialog { fn create_button(&self) -> Box; fn render(&self) { let button = self.create_button(); button.render(); } } ``` -------------------------------- ### Implement Composite Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Composite pattern allows treating individual objects and compositions of objects uniformly. This implementation uses a trait to define a common interface for both files and folders in a tree structure. ```rust pub trait Component { fn search(&self, keyword: &str); } pub struct File { name: String, } impl File { pub fn new(name: &str) -> Self { Self { name: name.into() } } } impl Component for File { fn search(&self, keyword: &str) { println!("Searching for '{}' in file '{}'", keyword, self.name); } } pub struct Folder { name: String, components: Vec>, } impl Folder { pub fn new(name: &str) -> Self { Self { name: name.into(), components: vec![], } } pub fn add(&mut self, component: impl Component + 'static) { self.components.push(Box::new(component)); } } impl Component for Folder { fn search(&self, keyword: &str) { println!("Searching in folder '{}'", self.name); for component in &self.components { component.search(keyword); } } } fn main() { let file1 = File::new("File 1"); let file2 = File::new("File 2"); let file3 = File::new("File 3"); let mut folder1 = Folder::new("Folder 1"); folder1.add(file1); let mut folder2 = Folder::new("Folder 2"); folder2.add(file2); folder2.add(file3); folder2.add(folder1); folder2.search("rose"); } ``` -------------------------------- ### Abstract Factory with Generics (Static Dispatch) - Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/abstract-factory/README.md Implements the Abstract Factory pattern using Rust generics for static dispatch. This approach allows the compiler to optimize the code, avoiding runtime overhead. It defines a `GuiFactory` trait with associated types for buttons and checkboxes. ```rust pub trait GuiFactory { type B: Button; type C: Checkbox; fn create_button(&self) -> Self::B; fn create_checkbox(&self) -> Self::C; } ``` -------------------------------- ### Implement State Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The State pattern allows an object to change its behavior when its internal state changes. This implementation uses trait objects and Box to manage ownership during transitions between states like Stopped, Playing, and Paused. ```rust pub struct StoppedState; pub struct PausedState; pub struct PlayingState; /// State trait with ownership transfer via `self: Box`. pub trait State { fn play(self: Box, player: &mut Player) -> Box; fn stop(self: Box, player: &mut Player) -> Box; fn render(&self, player: &Player, view: &mut TextView); } impl State for StoppedState { fn play(self: Box, player: &mut Player) -> Box { player.play(); Box::new(PlayingState) } fn stop(self: Box, _: &mut Player) -> Box { self } fn render(&self, _: &Player, view: &mut TextView) { view.set_content("[Stopped] Press 'Play'") } } impl State for PlayingState { fn play(self: Box, player: &mut Player) -> Box { player.pause(); Box::new(PausedState) } fn stop(self: Box, player: &mut Player) -> Box { player.pause(); player.rewind(); Box::new(StoppedState) } fn render(&self, player: &Player, view: &mut TextView) { view.set_content(format!("[Playing] {} - {} sec", player.track().title, player.track().duration)) } } ``` -------------------------------- ### Abstract Factory with Dynamic Dispatch - Rust Source: https://github.com/refactoringguru/design-patterns-rust/blob/main/creational/abstract-factory/README.md Implements the Abstract Factory pattern using dynamic dispatch with `Box` pointers in Rust. This is suitable when the concrete type of the factory is not known at compile time. It defines a `GuiFactoryDynamic` trait that returns boxed trait objects. ```rust pub trait GuiFactoryDynamic { fn create_button(&self) -> Box; fn create_checkbox(&self) -> Box; } ``` -------------------------------- ### Implement Builder Pattern in Rust Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt The Builder pattern separates the construction of a complex object from its representation. This implementation uses a trait to define construction steps and a Director struct to encapsulate specific assembly logic. ```rust use crate::components::{CarType, Engine, GpsNavigator, Transmission}; pub trait Builder { type OutputType; fn set_car_type(&mut self, car_type: CarType); fn set_seats(&mut self, seats: u16); fn set_engine(&mut self, engine: Engine); fn set_transmission(&mut self, transmission: Transmission); fn set_gps_navigator(&mut self, gps_navigator: GpsNavigator); fn build(self) -> Self::OutputType; } pub struct Director; impl Director { pub fn construct_sports_car(builder: &mut impl Builder) { builder.set_car_type(CarType::SportsCar); builder.set_seats(2); builder.set_engine(Engine::new(3.0, 0.0)); builder.set_transmission(Transmission::SemiAutomatic); builder.set_gps_navigator(GpsNavigator::new()); } } ``` -------------------------------- ### Chain of Responsibility Pattern in Rust: Hospital Patient Processing Source: https://context7.com/refactoringguru/design-patterns-rust/llms.txt Demonstrates the Chain of Responsibility pattern in Rust, simulating patient processing through a hospital's departments. Each department handles the patient or passes them to the next in line. It requires a `Patient` struct and `Department` trait. The `execute` method processes the patient, and `handle` defines the specific department's action. ```rust use crate::patient::Patient; /// A single role of objects that make up a chain. pub trait Department { fn execute(&mut self, patient: &mut Patient) { self.handle(patient); if let Some(next) = &mut self.next() { next.execute(patient); } } fn handle(&mut self, patient: &mut Patient); fn next(&mut self) -> &mut Option>; } /// Helps to wrap an object into a boxed type. pub fn into_next(department: impl Department + Sized + 'static) -> Option> { Some(Box::new(department)) } // Patient structure with state tracking #[derive(Default)] pub struct Patient { pub name: String, pub registration_done: bool, pub doctor_check_up_done: bool, pub medicine_done: bool, pub payment_done: bool, } fn main() { // Build the chain: Reception -> Doctor -> Medical -> Cashier let cashier = Cashier::default(); let medical = Medical::new(cashier); let doctor = Doctor::new(medical); let mut reception = Reception::new(doctor); let mut patient = Patient { name: "John".into(), ..Patient::default() }; // Reception handles a patient passing him to the next link in the chain reception.execute(&mut patient); println!("\nThe patient has been already handled:\n"); reception.execute(&mut patient); // Will skip already completed steps } ```