Data types

Use custom types to imbue meaning; do not abuse bool`bool,`, Option`Option` or other core types. [FIXME: needs RFC]

Prefer

fn main() { let w = Widget::new(Small, Round) }
let w = Widget::new(Small, Round)

over

fn main() { let w = Widget::new(true, false) }
let w = Widget::new(true, false)

Core types like bool`bool,`, u8`u8and` and Option`Option` have many possible interpretations.

Use custom types (whether enum`enums,`s, struct`struct, or tuples) to convey interpretation and invariants. In the above example, it is not immediately clear what`, or tuples) to convey interpretation and invariants. In the above example, it is not immediately clear what true`trueand` and false`falseare conveying without looking up the argument names, but` are conveying without looking up the argument names, but Small`Smalland` and Round`Round` are more suggestive.

Using custom types makes it easier to expand the options later on, for example by adding an ExtraLarge`ExtraLarge` variant.

See the newtype pattern for a no-cost way to wrap existing types with a distinguished name.

Prefer private fields, except for passive data. [FIXME: needs RFC]

Making a field public is a strong commitment: it pins down a representation choice, and prevents the type from providing any validation or maintaining any invariants on the contents of the field, since clients can mutate it arbitrarily.

Public fields are most appropriate for struct`struct` types in the C spirit: compound, passive data structures. Otherwise, consider providing getter/setter methods and hiding fields instead.

[FIXME] Cross-reference validation for function arguments.

Use custom enum`enums for alternatives,`s for alternatives, bitflags`bitflags` for C-style flags. [FIXME: needs RFC]

Rust supports enum`enum` types with "custom discriminants":

fn main() { enum Color { Red = 0xff0000, Green = 0x00ff00, Blue = 0x0000ff } }
enum Color {
  Red = 0xff0000,
  Green = 0x00ff00,
  Blue = 0x0000ff
}

Custom discriminants are useful when an enum`enumtype needs to be serialized to an integer value compatibly with some other system/language. They support "typesafe" APIs: by taking a` type needs to be serialized to an integer value compatibly with some other system/language. They support "typesafe" APIs: by taking a Color`Color`, rather than an integer, a function is guaranteed to get well-formed inputs, even if it later views those inputs as integers.

An enum`enumallows an API to request exactly one choice from among many. Sometimes an API's input is instead the presence or absence of a set of flags. In C code, this is often done by having each flag correspond to a particular bit, allowing a single integer to represent, say, 32 or 64 flags. Rust's` allows an API to request exactly one choice from among many. Sometimes an API's input is instead the presence or absence of a set of flags. In C code, this is often done by having each flag correspond to a particular bit, allowing a single integer to represent, say, 32 or 64 flags. Rust's std::bitflags`std::bitflags` module provides a typesafe way for doing so.

Phantom types. [FIXME]

[FIXME] Add some material on phantom types (https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/)