Naming conventions

General conventions

Item Convention
Crates snake_case (but prefer single word)
Modules snake_case
Types CamelCase
Traits CamelCase; prefer transitive verbs, nouns, and then adjectives; avoid suffixes (like able)
Enum variants CamelCase
Functions snake_case
Conversions as_foo/to_foo/into_foo (see below)
Methods snake_case
General constructors new or new_with_more_details
Conversion constructors from_some_other_type
Local variables snake_case
Static variables SCREAMING_SNAKE_CASE
Type parameters single uppercase letter: T
Lifetimes short, lowercase: 'a

In CamelCase, acronyms count as one word: use Uuid rather than UUID.

Referring to types in function/method names [OPEN]

Avoid redundant prefixes [RFC]

Names of items within a module should not be prefixed with that module's name, since clients can always reference the item qualified by the module name.

Prefer

mod foo {
    pub struct Bar { ... }
}

over

mod foo {
    pub struct FooBar { ... }
}

Ownership variants

Functions often come in multiple variants: immutably borrowed, mutably borrowed, and owned.

The right default depends on the function in question. Variants should be marked through suffixes.

Immutably borrowed by default

If foo uses/produces an immutable borrow by default, use:

Owned by default

If foo uses/produces owned data by default, use:

Exceptions

For mutably borrowed variants, if the mut qualifier is part of a type name (e.g. as_mut_slice), it should appear as it would appear in the type.

Fallible functions [OPEN]

[OPEN] Should we have a standard marker for functions that can cause task failure?

See https://github.com/mozilla/rust/issues/13159

Unwrapping, extracting, taking [OPEN]

Containers, wrappers, and cells all provide ways to access the data they enclose. Accessor methods often have variants to access the data by value, by reference, and by mutable reference.

In general, the get family of methods is used to access contained data without any risk of task failure; they return Option as appropriate. This name is chosen rather than names like find or lookup because it is appropriate for a wider range of container types.

Containers

For a container with keys/indexes of type K and elements of type V:

// Look up element without failing
fn get(&self, key: K) -> Option<&V>
fn get_mut(&mut self, key: K) -> Option<&mut V>

// Convenience for .get(key).map(|elt| elt.clone())
fn get_clone(&self, key: K) -> Option<V>

// Lookup element, failing if it is not found:
impl Index<K, V> for Container { ... }
impl IndexMut<K, V> for Container { ... }

Wrappers/Cells

Prefer specific conversion functions like as_bytes or into_vec whenever possible. Otherwise, use:

// Extract contents without failing
fn get(&self) -> &V
fn get_mut(&mut self) -> &mut V
fn unwrap(self) -> V

Wrappers/Cells around Copy data

// Extract contents without failing
fn get(&self) -> V

Option and Result

Finally, we have the cases of the Option and Result type, which play a special role for failure.

For Option<V>:

// Extract contents or fail if not available
fn assert(self) -> V
fn expect(self, &str) -> V

For Result<V, E>:

// Extract the contents of Ok variant; fail if Err
fn assert(self) -> V

// Extract the contents of Err variant; fail if Ok
fn assert_err(self) -> E

Getter/setter methods [OPEN]

[OPEN] Need a naming and signature convention here.

Escape hatches [OPEN]

[OPEN] Should we standardize a convention for functions that may break API guarantees? e.g. ToCStr::to_c_str_unchecked

Conversions

[OPEN] Should we provide standard traits for conversions? Doing so nicely will require trait reform to land.

Conversions should be provided as methods, with names prefixed as follows:

Prefix Cost Consumes convertee
as_ Free No
to_ Expensive No
into_ Variable Yes

For example:

Conversions prefixed as_ and into_ typically decrease abstraction, either exposing a view into the underlying representation (as) or deconstructing data into its underlying representation (into). Conversions prefixed to_, on the other hand, typically stay at the same level of abstraction but do some work to change one representation into another.

[OPEN] The distinctions between conversion methods does not work so well for from_ conversion constructors. Is that a problem?

Iterators

Method names

For a container with elements of type U, iterator methods should be named:

fn iter(&self) -> T           // where T implements Iterator<&U>
fn iter_mut(&mut self) -> T   // where T implements Iterator<&mut U>
fn iter_owned(self) -> T      // where T implements Iterator<U>

The default iterator variant yields shared references &U.

Type names

Iterators require introducing and exporting new types. These types should use the following naming convention:

Predicates