Best way to record operation used to create an instance of a struct?

I am wondering what the best way to keep a record of operations used to create instances of a struct is, especially when creating many instances.

I have a type which I have overloaded some operations and functions, and I want to keep a record of what operation was performed to create each instance.

First method: simply using a str for each operation.

struct Point {
    x: i32,
    y: i32,
    op: &'static str,
}

impl Point {
    fn new(x: i32, y: i32) -> Self {
        Point { 
            x, 
            y,
            op: "INITIALIZE",
        }
    }
}

impl std::ops::Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point { 
            x: self.x + other.x, 
            y: self.y + other.y,
            op: "ADDITION",
        }
    }
}

impl std::ops::Sub for Point {
    type Output = Point;

    fn sub(self, other: Point) -> Point {
        Point { 
            x: self.x - other.x, 
            y: self.y - other.y,
            op: "SUBTRACTION",
        }
    }
}

Second method: using an enum for all the operations.

struct Point {
    x: i32,
    y: i32,
    op: Operation,
}

enum Operation {
    INITIALIZE,
    ADDITION,
    SUBTRACTION,
}

impl Point {
    fn new(x: i32, y: i32) -> Self {
        Point { 
            x, 
            y,
            op: Operation::INITIALIZE,
        }
    }
}

impl std::ops::Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point { 
            x: self.x + other.x, 
            y: self.y + other.y,
            op: Operation::ADDITION,
        }
    }
}

impl std::ops::Sub for Point {
    type Output = Point;

    fn sub(self, other: Point) -> Point {
        Point { 
            x: self.x - other.x, 
            y: self.y - other.y,
            op: Operation::SUBTRACTION,
        }
    }
}

Or possibly another method ?

I would go for the enum.

1 Like

Is there any performance/memory benefit to the enum option ? The only thing I want to use the operation data for is displaying/printing, so I figured the &'static str avoids the need to implement display on the enum. In total there might be about 50 different operations I would implement.

It's not the performance but the clarity of intent. Operations are not freetext.

(But yes, there is a small improvement in size, because &str is two pointers, i.e., 8 or 16 bytes on most modern systems, while an enum with 50 variants can fit in a single byte. But that's not what you should consider first.)

3 Likes

You can derive debug on the enum to automatically get the code to print it. If you need Display, then you can have the Display impl call the Debug impl to reuse it.

3 Likes

@alice @H2CO3 thanks for the advice, enum it is :slight_smile: