When implementing the Add trait (and a few others, like Mul, Sub, etc.) for a simple struct one has to fully consume the struct value, thus its later use is  not possible.
At the same time, built in primitives (u8, usize, etc.) implement Add while allowing using it after add was called.
How can I implement Add for my structs to be able to use it after calling add?
use std::ops::Add;
struct I(usize);
impl Add for I {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {
        I(self.0 + rhs.0)
    }
}
fn main() {
    let a = 123;
    let b = a + a; // no error
    let a1 = I(123);
    let b1 = a1 + a1;
    println!("b={}", b);
}
error[E0382]: use of moved value: `a1`
  --> src/main.rs:16:19
   |
15 |     let a1 = I(123);
   |         -- move occurs because `a1` has type `I`, which does not implement the `Copy` trait
16 |     let b1 = a1 + a1;
   |              --   ^^ value used here after move
   |              |
   |              value moved here
 
     
     
    