Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers

Moving beyond basic borrowing to master Rust’s powerful ownership tools and design patterns.
Recap: Your Journey So Far

Previous Articles on the same series

https://dev.to/triggerak/rust-ownership-mastery-the-zero-cost-safety-revolution-4p11
https://…


This content originally appeared on DEV Community and was authored by Abhishek Kumar

Moving beyond basic borrowing to master Rust's powerful ownership tools and design patterns.
Recap: Your Journey So Far

Previous Articles on the same series

https://dev.to/triggerak/rust-ownership-mastery-the-zero-cost-safety-revolution-4p11
https://dev.to/triggerak/rust-series-borrow-checker-as-design-partner-understanding-lifetimes-through-analogies-84b
https://dev.to/triggerak/rust-series-borrow-checker-bonus-chapter-non-lexical-lifetimes-15cg
https://dev.to/triggerak/rust-series-borrow-checker-part-2-as-design-partner-the-compilers-mental-model-3en8
https://dev.to/triggerak/rust-series-borrow-checker-part-3-as-design-partner-common-errors-and-battle-tested-2da0

Now - Advanced patterns that make the borrow checker your ally

The Smart Pointer Toolkit

   fn main() {
    println!("=== Smart Pointers: Beyond Basic References ===");
    demonstrate_smart_pointers();

    println!("\n=== Design Patterns: Working WITH the Borrow Checker ===");
    demonstrate_design_patterns();

    println!("\n=== Performance Considerations ===");
    demonstrate_performance_patterns();
}

// SMART POINTERS: Tools for complex ownership scenarios
fn demonstrate_smart_pointers() {
    use std::rc::Rc;
    use std::cell::RefCell;
    use std::sync::Arc;

    println!("=== Box<T>: Heap Allocation ===");
    // CONCEPT: Box moves data to heap and provides ownership
    let expensive_data = Box::new(vec![1; 1000]); // Large data on heap
    let data_ref = &*expensive_data; // Deref to get &Vec<i32>
    println!("Heap data length: {}", data_ref.len());
    println!("Heap data - expensive_data {:?}", expensive_data);
    println!("Heap data - *expensive_data {:?}", *expensive_data);

    println!("Heap data - data_ref  {:?}", data_ref);
    println!("Heap data - *data_ref  {:?}", *data_ref);
    println!("\n=== Rc<T>: Shared Ownership (Single Thread) ===");
    // CONCEPT: Reference counting for multiple owners
    let shared_config = Rc::new("Global Configuration".to_string());
    let user1 = Rc::clone(&shared_config); // Increment ref count
    let user2 = Rc::clone(&shared_config); // Increment ref count

    println!("Config: {}", shared_config);
    println!("User1 sees: {}", user1);
    println!("User2 sees: {}", user2);
    println!("Reference count: {}", Rc::strong_count(&shared_config));

    println!("\n=== RefCell<T>: Interior Mutability ===");
    // CONCEPT: Runtime borrow checking instead of compile-time
    let mutable_in_immutable = RefCell::new(vec![1, 2, 3]);

    {
        let mut borrowed = mutable_in_immutable.borrow_mut();
        borrowed.push(4);
        println!("Modified: {:?}", *borrowed);
    } // Borrow released here

    let read_only = mutable_in_immutable.borrow();
    println!("Read-only view: {:?}", *read_only);

    println!("\n=== Rc<RefCell<T>>: Shared Mutable State ===");
    // CONCEPT: Combine shared ownership with interior mutability
    let shared_counter = Rc::new(RefCell::new(0));

    let incrementer1 = Rc::clone(&shared_counter);
    let incrementer2 = Rc::clone(&shared_counter);

    // Simulate different parts of code modifying shared state
    *incrementer1.borrow_mut() += 10;
    *incrementer2.borrow_mut() += 5;

    println!("Final counter value: {}", shared_counter.borrow());
}

// DESIGN PATTERNS: Architecting around ownership
fn demonstrate_design_patterns() {
    println!("=== Pattern 1: Builder with Ownership Transfer ===");

    struct ConfigBuilder {
        database_url: Option<String>,
        port: Option<u16>,
        debug: bool,
    }

    struct Config {
        database_url: String,
        port: u16,
        debug: bool,
    }

    impl ConfigBuilder {
        fn new() -> Self {
            Self {
                database_url: None,
                port: None,
                debug: false,
            }
        }

        // PATTERN: Consume self and return Self for chaining
        fn database_url(mut self, url: String) -> Self {
            self.database_url = Some(url);
            self // Return owned self
        }

        fn port(mut self, port: u16) -> Self {
            self.port = Some(port);
            self
        }

        fn debug(mut self, debug: bool) -> Self {
            self.debug = debug;
            self
        }

        // PATTERN: Final consumption to create the target type
        fn build(self) -> Result<Config, &'static str> {
            Ok(Config {
                database_url: self.database_url.ok_or("Database URL required")?,
                port: self.port.unwrap_or(5432),
                debug: self.debug,
            })
        }
    }

    let config = ConfigBuilder::new()
        .database_url("postgresql://localhost".to_string())
        .port(5433)
        .debug(true)
        .build()
        .unwrap();

    println!("Built config: {}:{}", config.database_url, config.port);

    println!("\n=== Pattern 2: Resource Manager with RAII ===");

    struct FileManager {
        filename: String,
        is_open: bool,
    }

    impl FileManager {
        fn open(filename: String) -> Self {
            println!("Opening file: {}", filename);
            Self { filename, is_open: true }
        }

        fn write(&mut self, data: &str) {
            if self.is_open {
                println!("Writing to {}: {}", self.filename, data);
            }
        }
    }

    impl Drop for FileManager {
        fn drop(&mut self) {
            if self.is_open {
                println!("Auto-closing file: {}", self.filename);
            }
        }
    }

    {
        let mut file = FileManager::open("data.txt".to_string());
        file.write("Important data");
        // File automatically closed when dropped
    }

    println!("\n=== Pattern 3: Visitor with Lifetime Bounds ===");

    trait Processor {
        fn process(&self, data: &str) -> String;
    }

    struct Logger;
    impl Processor for Logger {
        fn process(&self, data: &str) -> String {
            format!("[LOG] {}", data)
        }
    }

    struct Encryptor;
    impl Processor for Encryptor {
        fn process(&self, data: &str) -> String {
            format!("[ENCRYPTED] {}", data.chars().rev().collect::<String>())
        }
    }

    // PATTERN: Accept any processor without lifetime complications
    fn process_data(data: &str, processor: &dyn Processor) -> String {
        processor.process(data)
    }

    let logger = Logger;
    let encryptor = Encryptor;

    let result1 = process_data("sensitive data", &logger);
    let result2 = process_data("sensitive data", &encryptor);

    println!("Logged: {}", result1);
    println!("Encrypted: {}", result2);
}

// PERFORMANCE: When to use each pattern
fn demonstrate_performance_patterns() {
    println!("=== Performance Pattern 1: Avoid Unnecessary Clones ===");

    // SLOW: Cloning large data
    fn process_slow(data: Vec<String>) -> Vec<String> {
        data.into_iter()
            .map(|s| s.to_uppercase()) // Could avoid allocation here
            .collect()
    }

    // FASTER: Work with references when possible
    fn process_fast(data: &[String]) -> Vec<String> {
        data.iter()
            .map(|s| s.to_uppercase())
            .collect()
    }

    let data = vec!["hello".to_string(), "world".to_string()];
    let result = process_fast(&data); // No ownership transfer needed
    println!("Processed: {:?}", result);
    println!("Original still available: {:?}", data);



}

ADVANCED PATTERNS SUMMARY:

  1. SMART POINTERS:

    • Box: Single ownership, heap allocation
    • Rc: Multiple ownership, single thread
    • Arc: Multiple ownership, multi-thread
    • RefCell: Interior mutability with runtime checks
  2. DESIGN PATTERNS:

    • Builder: Consume and return Self for fluent APIs
    • RAII: Automatic resource cleanup with Drop
    • Visitor: Accept trait objects for flexibility
  3. PERFORMANCE PATTERNS:

    • Reference over ownership when possible
    • Cow for conditional allocation

About Me
https://www.linkedin.com/in/kumarabhishek21/


This content originally appeared on DEV Community and was authored by Abhishek Kumar


Print Share Comment Cite Upload Translate Updates
APA

Abhishek Kumar | Sciencx (2025-07-15T14:19:10+00:00) Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers. Retrieved from https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/

MLA
" » Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers." Abhishek Kumar | Sciencx - Tuesday July 15, 2025, https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/
HARVARD
Abhishek Kumar | Sciencx Tuesday July 15, 2025 » Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers., viewed ,<https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/>
VANCOUVER
Abhishek Kumar | Sciencx - » Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/
CHICAGO
" » Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers." Abhishek Kumar | Sciencx - Accessed . https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/
IEEE
" » Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers." Abhishek Kumar | Sciencx [Online]. Available: https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/. [Accessed: ]
rf:citation
» Rust Series : Borrow Checker Part 4 | As Design Partner – Advanced Patterns and Smart Pointers | Abhishek Kumar | Sciencx | https://www.scien.cx/2025/07/15/rust-series-borrow-checker-part-4-as-design-partner-advanced-patterns-and-smart-pointers/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.