3

derive-getters is a nice crate that will create getters for you. However, it always generates getters that return a reference, even for Copy types. For example for this struct:

#[derive(Getters)]
pub struct MyCheesyStruct {
    x: i64,
    y: i64,
}

It will generate:

impl MyCheesyStruct {
    pub fn x(&self) -> &i64 {
        &self.x
    }

    pub fn y(&self) -> &i64 {
        &self.y
    }
}

This makes things more cumbersome for users than they need to be, because i64 implements Copy. So I started to wonder if it was possible to do better? But macros operate at the token level, so they don't know anything about types/traits. Is there a way to get this functionality, short of manually annotating members with a directive to specify they should be returned without a borrow? This is the kind of thing type level metaprogramming in C++ excels at.

Joseph Garvin
  • 20,727
  • 18
  • 94
  • 165

1 Answers1

0

So I started to wonder if it was possible to do better?

As partial answer I can say that it is doable for primitive types out of the box. For other types you might require additional annotation on the field something like that:

#[derive(Copy)]
pub struct Point {
  x: i64,
  y: i64,
}

#[derive(Getters)]
pub struct MyCheesyStruct {
    #[noref] // generates non-borrow getter
    point: Point,
}

Or you can make a version of procedural macro that generates non-borrow getters for all fields.

sergeyt
  • 169
  • 2
  • 9
  • You say it's possible for primitive types, but how? – Joseph Garvin Jul 13 '20 at 03:45
  • You would probably have a fixed list of primitive types that implement `Copy` – madlaina Jul 13 '20 at 16:04
  • I think manually having a fixed list goes against the point of the question, which is can you do it in a way that is *aware* of Copy – Joseph Garvin Jul 13 '20 at 20:16
  • Primitives types are also tokens. And since procedural macro receives all tokens of the given structure (aka syntax tree) you can handle them too. I cannot say right now how exactly to change derive-getters to achieve your goal, but it is definitely doable. – sergeyt Jul 14 '20 at 04:48
  • @sergeyt Primitive types are not tokens. `type MyAlias = i32` will defeat any hard coded list. – Joseph Garvin Sep 07 '21 at 01:45