Reputation: 1023
I just encountered this weird struct definition, it is in fcntl.rs from the crate nix.
pub struct OFlag: c_int {
/// Mask for the access mode of the file.
O_ACCMODE;
// other fields are omitted.
}
A normal struct in my perspective will be something like this:
struct Person{
name: String,
age: u8,
}
So, here are my doubts:
what is OFlag: c_int
?
c_int
is an type alias of i32.pub type c_int = i32;
Why don't its fields have any type annotation?
My surmise is that OFlag
is of type c_int
, and the fields are something similar to enum
's fields.(compliant to the open syscall function signature int open(const char *pathname, int flags, mode_t mode)
) But this is just my guesswork, an explanation citing rust official doc would be appreciated.
Upvotes: 1
Views: 152
Reputation: 1116
If you look at the file you can see that the code inside the macro libc_bitflags!
. The definition of the macro is here. There you can see that the macro ::bitflags::bitflags!
is called and that libc_bitflags
almost redirects the full input to bitflags
. You can read more about that crate here.
Now to your questions:
OFlag
will be after macro expansion a struct with a single attribute which is of type c_int
:pub struct OFlag {
bits: c_int,
}
c_int
. The fields will be converted to associated constants:impl OFlag {
pub const O_ACCMODE = Self { bits: libc::O_ACCMODE };
}
You can create an expansion of an example in the playground (Tools
-> Expand macros
)
Upvotes: 1
Reputation: 602115
The code you quoted is not valid Rust code on its own. It's code that gets passed to an internal macro of the nix
crate called libc_bitflags!()
. This macro takes the quoted code as input and transforms it into valid Rust code.
The libc_bitflags!()
macro is a simple wrapper around the bitflags!()
macro from the bitflags crate. The wrapper simplifies creating bitflags structs that take all their values from constants defined in the libc
crate. For example this invocation
libc_bitflags!{
pub struct ProtFlags: libc::c_int {
PROT_NONE;
PROT_READ;
PROT_WRITE;
PROT_EXEC;
}
}
gets expanded to
bitflags!{
pub struct ProtFlags: libc::c_int {
const PROT_NONE = libc::PROT_NONE;
const PROT_READ = libc::PROT_READ;
const PROT_WRITE = libc::PROT_WRITE;
const PROT_EXEC = libc::PROT_EXEC;
}
}
which in turn will be expanded to Rust code by the bitflags!()
macro. The libc::c_int
type is used as the type of the bits
field of the resulting struct. The constants inside will become associated constants of the resulting struct. See the documentation of the bitflags crate for further details.
Upvotes: 3