Implement Clone trait for a structure at a different crate

Hello people,I have a structure which is auto generated, it doesn't implement clone trait.I want to use this structure at a different place I have imported the structure with use.now i want to implement clone here.How do i achieve this?
I have tried impl Clone for mystruct{} this is giving following error.

`x::y::z::mystruct` is not defined in the current crate
    |     impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

You can't implement a foreign trait (Clone from the standard library) on a foreign type (x::y::z::mystruct from the x crate).

Easiest would probably be to auto-generate the struct with a Clone implementation (if you can control that or ask someone who has control to add it).

Otherwise you have to wrap mystruct in a different type and implement Clone on that one. This is commonly referred to as the newtype pattern:

struct MyStruct(x::y::z::mystruct);

impl Clone for MyStruct {
    fn clone(&self) -> Self {
        // clone x::y::z::mystruct here and return MyStruct(clone)
    }
}

Or you could create your own trait that works like Clone and implement that on x::y::z::mystruct:

trait MyClone {
    fn my_clone(&self) -> Self;
}

impl MyClone for x::y::z::mystruct {
    fn my_clone(&self) -> Self {
        todo!()
    }
}

Here an example for the mentioned newtype pattern:

mod othercrate {
    #[derive(Debug)]
    pub struct NotCloneable {
        pub name: String,
    }
}

pub struct Foo(pub othercrate::NotCloneable);

impl Clone for Foo {
    fn clone(&self) -> Foo {
        Foo(othercrate::NotCloneable {
            name: self.0.name.clone(),
        })
    }
}

fn main() {
    let nc = othercrate::NotCloneable {
        name: "Hello World!".to_string(),
    };
    //let nc2 = nc.clone(); // fails
    let wrapped = Foo(nc);
    let wrapped2 = wrapped.clone();
    let wrapped3 = wrapped.clone();
    let wrapped4 = wrapped.clone();
    let nc: othercrate::NotCloneable = wrapped.0;
    let nc2: othercrate::NotCloneable = wrapped2.0;
    let nc3: othercrate::NotCloneable = wrapped3.0;
    let nc4: othercrate::NotCloneable = wrapped4.0;
    println!("{nc:?}");
    println!("{nc2:?}");
    println!("{nc3:?}");
    println!("{nc4:?}");
}

(Playground)

Thank you for the explanation.
I have one more issue in regards this, now i want to implement clone for Vec<MyStruct>. i have already implemented custom clone (fn clone2(&self)->Self) for MyStruct (since MyStruct is defined else where and i can't derive clone),now how can i achieve clone for Vec<MyStruct>?

You could implement your custom MyClone for Vec<MyStruct> as well. Or even better, make it generic over T where T: MyClone:

impl<T: MyClone> MyClone for Vec<T> {
    fn my_clone(&self) -> Self {
        self.iter().map(|x| x.my_clone()).collect()
    }
}
2 Likes

Why doesn't it implement close? You can still use derive even with autogenerated structs.

1 Like

This worked,thanks!

1 Like

The structs are generated everytime i build, I can't disclose further but yeah i can't change the generated structures.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.