rust-patterns 0.1.2

A modern Rust design patterns library with type-safe, efficient implementations
Documentation

Rust Patterns

Crates.io Documentation License: MIT

统一的 Rust 设计模式库,整合 rust-pattern-components(运行时组件)和 rust-pattern-macros(过程宏), 提供类型安全、高效的设计模式实现。

安装

[dependencies]

rust-patterns = "0.1"

单一依赖即可使用所有功能。

支持的设计模式

1. 构建器模式 (Builder)

通过 builder_helper! 宏为构建器类型添加条件设置方法 when_some,避免 if let Some(v) = x {} 样板代码。

使用方式

use rust_patterns::builder_helper;

// Self 版本(消费型)
builder_helper!(Self, MyBuilder);

// &mut Self 版本(可变引用型)
builder_helper!(&mut Self, MyMutBuilder);

// 同时为多个类型实现
builder_helper!(Self, Builder1, Builder2, Builder3);

生成的 when_some 方法签名(Self 版本):

fn when_some<T>(
    self,
    value: Option<T>,
    func: impl FnOnce(Self, T) -> Self,
) -> Self

示例

use rust_patterns::builder_helper;

struct UserBuilder {
    name: Option<String>,
    age: Option<u32>,
}

impl UserBuilder {
    fn new() -> Self {
        Self { name: None, age: None }
    }

    fn name(mut self, name: &str) -> Self {
        self.name = Some(name.to_string());
        self
    }

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

    fn build(self) -> String {
        format!("{} ({})", self.name.unwrap_or_default(), self.age.unwrap_or(0))
    }
}

builder_helper!(Self, UserBuilder);

fn main() {
    let user = UserBuilder::new()
        .name("Alice")
        .when_some(Some(30), |b, age| b.age(age))
        .when_some(None::<u32>, |b, _| b.age(0)) // None 被跳过
        .build();

    assert_eq!(user, "Alice (30)");
}

2. 工厂模式 (Factory)

类型安全的工厂系统,支持编译时注册、多种回退策略和完整错误处理。

核心组件

组件 说明
Factory<T> 工厂 trait,定义 create 方法
SimpleFactory<T> 工厂集合,按 ID 查找并创建对象
FactoryRegistry<T> 工厂注册表,配合 inventory 编译时注册
FactoryFallback 回退策略(First / Last / NoFallback
FactoryError 错误类型
register_factory! 注册工厂的宏

手动使用

use rust_patterns::{Factory, FactoryFallback, FactoryRegistry, FactoryError, register_factory};

trait Product: Send + Sync {
    fn name(&self) -> &str;
}

#[derive(Default)]
struct ProductA;
impl Product for ProductA {
    fn name(&self) -> &str { "Product A" }
}
impl Factory<Product> for ProductA {
    fn create(&self) -> Box<Product> { Box::new(ProductA) }
}

register_factory!(dyn Product, "product_a", ProductA);

fn main() {
    let factory = FactoryRegistry::<dyn Product>::simple_factory();

    match factory.create("product_a", FactoryFallback::NoFallback) {
        Ok(product) => println!("{}", product.name()),
        Err(FactoryError::FactoryNotFound(id)) => {
            println!("未找到工厂: {}", id);
        }
        Err(e) => println!("错误: {}", e),
    }
}

使用 #[simple_factory]

use rust_patterns::{simple_factory, FactoryFallback, FactoryError, register_factory};

#[simple_factory]
pub trait Shape {
    fn draw(&self);
}

#[derive(Default)]
struct Circle;
impl Shape for Circle {
    fn draw(&self) { println!("Circle"); }
}

register_factory!(dyn Shape, "circle", Circle);

fn main() {
    match ShapeFactory::create("circle", FactoryFallback::NoFallback) {
        Ok(shape) => shape.draw(),
        Err(FactoryError::FactoryNotFound(id)) => {
            println!("未找到工厂: {}", id);
        }
        Err(e) => println!("错误: {}", e),
    }
}

回退策略

策略 空 ID 时行为
First 使用第一个工厂
Last 使用最后一个工厂
NoFallback 返回 EmptyIdNoFallback 错误

3. 观察者模式 (Observer)

线程安全的发布-订阅机制,使用弱引用避免循环引用。

核心组件

组件 说明
Observer trait 定义 update 方法
Observable trait 定义 attach / detach 方法
ObserverRegistry<T> 管理弱引用列表,提供 notify / notify_ignore_error

手动实现

use std::sync::Arc;
use rust_patterns::{Observer, Observable, ObserverRegistry};

struct TemperatureSensor {
    registry: ObserverRegistry<Self>,
    temperature: f64,
}

impl TemperatureSensor {
    fn new(temp: f64) -> Self {
        Self {
            registry: ObserverRegistry::new(),
            temperature: temp,
        }
    }

    fn set_temperature(&mut self, temp: f64) {
        self.temperature = temp;
        let _ = self.registry.notify(&self.temperature);
    }
}

impl Observable for TemperatureSensor {
    type State = f64;
    type Error = String;

    fn attach(&mut self, observer: Arc<dyn Observer<Subject = Self>>) {
        self.registry.attach(observer);
    }

    fn detach(&mut self, observer: Arc<dyn Observer<Subject = Self>>) {
        self.registry.detach(observer);
    }
}

struct Display;
impl Observer for Display {
    type Subject = TemperatureSensor;
    fn update(&self, state: &f64) -> Result<(), String> {
        println!("温度: {:.1}°C", state);
        Ok(())
    }
}

fn main() {
    let mut sensor = TemperatureSensor::new(20.0);
    sensor.attach(Arc::new(Display));
    sensor.set_temperature(25.5);
}

使用 #[observable]

use std::sync::Arc;
use rust_patterns::{observable, Observer, Observable};

#[observable(state = f64, error = String)]
struct TemperatureSensor {
    temperature: f64,
}

impl TemperatureSensor {
    fn new(temp: f64) -> Self {
        Self {
            temperature: temp,
            registry: rust_patterns::ObserverRegistry::new(),
        }
    }

    fn set_temperature(&mut self, temp: f64) {
        self.temperature = temp;
        let _ = self.notify(&self.temperature);
    }
}

struct Display;
impl Observer for Display {
    type Subject = TemperatureSensor;
    fn update(&self, state: &f64) -> Result<(), String> {
        println!("温度: {:.1}°C", state);
        Ok(())
    }
}

fn main() {
    let mut sensor = TemperatureSensor::new(20.0);
    sensor.attach(Arc::new(Display));
    sensor.set_temperature(30.0);
}

通知策略

方法 行为
notify(&self, state) 遇到错误立即停止并返回
notify_ignore_error(&self, state) 忽略错误,通知所有观察者

运行测试

# 运行所有测试

cargo test


# 运行特定模块测试

cargo test -- factory

cargo test -- builder

cargo test -- observer

运行示例

cargo run --example simple_factory_example

cargo run --example observable_example

许可证

MIT © Linshan Yang

相关项目