'How do I implement Copy and Clone for a type that contains a String (or any type that doesn't implement Copy)?

I have an enum in Rust which has one value that takes a String:

#[derive(Clone, Copy)]
enum Simple {
    Error(String),
    Okay,
    Foo([u32; 5]),
}

fn main() {
    let x = Simple::Error(String::from("blah"));
    let y = x.clone();
}

The enum value Foo above represents about 10 other enums I use that take copyable types or arrays of them. The compiler doesn't seem to complain about them, only the Error(String) which causes this:

error[E0204]: the trait `Copy` may not be implemented for this type
 --> src/main.rs:1:17
  |
1 | #[derive(Clone, Copy)]
  |                 ^^^^
2 | enum Simple {
3 |     Error(String),
  |           ------ this field does not implement `Copy`
  |

For some reason, String is not copyable. I don't get this. How do I implement Clone for an enum for just the one type which has a problem while using the default impl for the rest?



Solution 1:[1]

I did some exploring to see what a manual implementation would look like for an enum. I came up with this, but keep in mind you can also do #[derive(Clone)] as stated elsewhere and the compiler will do this for you.

enum Simple {
    Error(String),
    Okay,
    Foo([u32; 5]),
}

impl Clone for Simple {
    fn clone(&self) -> Simple {
        match self {
            Error(a) => Error(a.to_string()),
            Okay => Okay,
            Foo(a) => Foo(a.clone()),
        }
    }
}

Solution 2:[2]

I found a solution using format.

Here, in this example trait Details is implemented for Car struct.

/* 
    Car example
    - implement a trait `Detail` for different car objects (defined in `struct`)

    NOTE: here, the `String` type creates a problem in return

*/

pub trait Detail {
    fn brand(&self) -> String;
    fn color(&self) -> String;
    fn driving_mode(&self) -> bool;
    fn manu_year(&self) -> u16;
}

// NOTE: Even after using Clone in derive attribute, it throws the same error
#[derive(Debug)]            // used for printing via `println!`
struct Car {
    brand: String,
    color: String,
    mode: bool,         // manual: false, automatic: true
    year: u16
}

impl Detail for Car {
    fn brand(&self) -> String {
        // using `format` instead of directly returning the brand bcoz it throws error:
        // "move occurs because `self.brand` has type `String`, which does not implement the `Copy` trait"
        return format!("{}", self.brand);
        // return self.brand;      // throws Error          
    }
    fn color(&self) -> String {
        return format!("{}", self.color);
        // return self.color;      // throws Error          
    }
    fn driving_mode(&self) -> bool {
        return self.mode;
    }
    fn manu_year(&self) -> u16 {
        return self.year;
    }
    
}

fn main() {
    let c1 = Car {
        brand: "BMW".to_string(),
        color: "Dark Blue".to_string(),
        mode: true,
        year: 2012
    };

    println!("Car c1: \n{:#?}", &c1);       // print the whole car c1
    println!("Car c1 brand: {}", &c1.brand());    // only print the c1's brand
}

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 Shepmaster
Solution 2 abhi3700