'How to create a factory method based on static dispatch? [closed]

I want to study design pattern use rust language. From this code it works properly but it uses dynamic dispatch. How can I change the code to use static dispatch? Thanks!

trait Shape {
    fn draw(&self);
}

enum ShapeType {
    Rectangle,
    Circle,
}

struct Rectangle {}

impl Shape for Rectangle {
    fn draw(&self) {
        println!("draw a rectangle!");
    }
}

struct Circle {}

impl Shape for Circle {
    fn draw(&self) {
        println!("draw a circle!");
    }
}

struct ShapeFactory;
impl ShapeFactory {
    fn new_shape(s: &ShapeType) -> Box<dyn Shape> {
        match s {
            ShapeType::Circle => Box::new(Circle {}),
            ShapeType::Rectangle => Box::new(Rectangle {}),
        }
    }
}

fn main() {
    let shape = ShapeFactory::new_shape(&ShapeType::Circle);
    shape.draw(); // output: draw a circle!

    let shape = ShapeFactory::new_shape(&ShapeType::Rectangle);
    shape.draw(); // output: draw a rectangle!
}


Solution 1:[1]

You could do something like this:

trait ShapeFactory {
    type Product: Shape;
    fn new_shape() -> Self::Product;
}

struct CircleFactory;
impl ShapeFactory for CircleFactory {
    type Product = Circle;
    fn new_shape() -> Circle {
        Circle {}
    }
}

// separate method, to demonstrate the factory part a bit better
fn draw_new_shape<F: ShapeFactory>() {
    let shape = F::new_shape();
    shape.draw();
}

fn main() {
    draw_new_shape::<CircleFactory>();
}

(Unlike the enum-approach, this doesn't pre-decide which things could have factory shapes.)

Should you do something like this? Most likely no. I highly doubt the validity of factories as a "design pattern" in Rust.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Caesar