Can I make "name" Copy?

I have a struct

#[derive(Clone, Debug)]
struct Foo {
    name: String,
    index: usize
}

Name is a computed string, never more than 30 characters long, that doesn't change once it's created. It's used in a gazillion places in my code, some of which the borrow checker doesn't like unless I clone it. It's annoying seeing .clone() scattered throughout my code like dandruff on a black shirt.

I tried using &str, but I got into lifetime hell. I looked at several of the crates that deal with small strings, but I didn't find one that implements Copy. Instances of Foo come and go, so I'm loathe to use a 'static lifetime. I'm currently using [char; 30], but I needed custom serialization/deserialization to make my trace records work with our tools.

It's not a performance problem, says the curmudgeon; it's a visual cruft problem.

[char; 30] also has the problem of using up much more space; each char takes up 4 bytes.

Have you considered using an interning library, like internship? That'd make clone cheap, but you don't have to deal with the lifetimes yourself.

1 Like
5 Likes

I'll check out arrayvec. It looks like a more comprehensive implementation of what I wrote. The key will be how it serializes. I'll try it when (if) I ever get out of meetings.

Thanks @josh for the pointer to the internship crate. Unfortunately, it doesn't implement Copy, so it doesn't solve my visual cruft problem. However, I have other places where it will be usefl.

I realize that it doesn't remove the occasional .clone(). It does make those not actually do a string copy, though.

Whew! I finally got out of meetings and tried arrayvec::ArrayString. Even though I see in the arrayvec source code that ArrayString derives Copy, the compiler tells me that ArrayString does not.

use arrayvec::ArrayString;
#[derive(Debug, Copy, Clone)]
pub struct CellID {
    name: ArrayString<u8>,
    index: usize
}

name: ArrayString<u8>,
----------------------- this field does not implement `Copy`

I tried char instead of u8 with the same result. I have no clue what I'm doing wrong.

It should be ArrayString<[u8;30]>

Doh. Too many meetings rots the brain.