Proper handling of C enum/constant-based interfaces


I’m currently working on high-level bindings for ptrace. One of the things that I’m not really sure about is how to handle the fact that ptrace accepts an offset in a user_regs_struct to return a single register. These offsets are defined in sys/user.h as constants: R15, RAX, .... There are a couple of ideas we have:

  1. Contribute the constants to the libc crate and create our own enum in the following way:
pub enum Register {
    R15 = 8 * libc::R15,
    R14 = 8 * libc::R14,
  1. Generate the enum with some kind of macro. I’ve seen such thing in the libc crate but I don’t remember where.
  2. Use the offset_of macro to get the offset in the struct directly and implement the ptrace routines as macros, as in this comment:

The problem that solution 3 avoids is platform-dependence - the enum would have to be defined per-platform (but the interface is platform-dependent anyway). On the other hand, solution 3 seems to overuse the macros.

What do you think? Which one is the most idiomatic in Rust?